diff --git a/invesalius/gui/task_navigator.py b/invesalius/gui/task_navigator.py index c939189..f1eb418 100644 --- a/invesalius/gui/task_navigator.py +++ b/invesalius/gui/task_navigator.py @@ -24,6 +24,7 @@ import numpy as np import wx import wx.lib.hyperlink as hl import wx.lib.masked.numctrl +import wx.lib.foldpanelbar as fpb from wx.lib.pubsub import pub as Publisher import invesalius.constants as const @@ -33,7 +34,6 @@ import invesalius.data.coregistration as dcr import invesalius.data.trackers as dt import invesalius.data.trigger as trig import invesalius.gui.dialogs as dlg -import invesalius.gui.widgets.foldpanelbar as fpb import invesalius.gui.widgets.colourselect as csel class TaskPanel(wx.Panel): @@ -132,7 +132,7 @@ class InnerFoldPanel(wx.Panel): ntw = NeuronavigationPanel(item) fold_panel.ApplyCaptionStyle(item, style) - fold_panel.AddFoldPanelWindow(item, ntw, Spacing= 0, + fold_panel.AddFoldPanelWindow(item, ntw, spacing= 0, leftSpacing=0, rightSpacing=0) fold_panel.Expand(fold_panel.GetFoldPanel(0)) @@ -141,7 +141,7 @@ class InnerFoldPanel(wx.Panel): mtw = MarkersPanel(item) fold_panel.ApplyCaptionStyle(item, style) - fold_panel.AddFoldPanelWindow(item, mtw, Spacing= 0, + fold_panel.AddFoldPanelWindow(item, mtw, spacing= 0, leftSpacing=0, rightSpacing=0) @@ -798,4 +798,4 @@ class MarkersPanel(wx.Panel): while len(selection) != self.lc.GetSelectedItemCount(): index = self.lc.GetNextSelected(index) selection.append(index) - return selection \ No newline at end of file + return selection diff --git a/invesalius/gui/task_slice.py b/invesalius/gui/task_slice.py index cb71a8d..20cb893 100644 --- a/invesalius/gui/task_slice.py +++ b/invesalius/gui/task_slice.py @@ -23,6 +23,7 @@ import os import wx import wx.lib.hyperlink as hl import wx.lib.platebtn as pbtn +import wx.lib.foldpanelbar as fpb from wx.lib.pubsub import pub as Publisher import invesalius.data.mask as mask @@ -30,7 +31,6 @@ import invesalius.data.slice_ as slice_ import invesalius.constants as const import invesalius.gui.dialogs as dlg import invesalius.gui.widgets.gradient as grad -import invesalius.gui.widgets.foldpanelbar as fpb import invesalius.gui.widgets.colourselect as csel from invesalius.project import Project @@ -268,7 +268,7 @@ class InnerFoldPanel(wx.Panel): self.mask_prop_panel = MaskProperties(item) fold_panel.ApplyCaptionStyle(item, style) - fold_panel.AddFoldPanelWindow(item, self.mask_prop_panel, Spacing= 0, + fold_panel.AddFoldPanelWindow(item, self.mask_prop_panel, spacing= 0, leftSpacing=0, rightSpacing=0) # Fold 2 - Advanced edition tools @@ -276,7 +276,7 @@ class InnerFoldPanel(wx.Panel): etw = EditionTools(item) fold_panel.ApplyCaptionStyle(item, style) - fold_panel.AddFoldPanelWindow(item, etw, Spacing= 0, + fold_panel.AddFoldPanelWindow(item, etw, spacing= 0, leftSpacing=0, rightSpacing=0) self.__id_editor = item.GetId() self.last_panel_opened = None @@ -286,7 +286,7 @@ class InnerFoldPanel(wx.Panel): wtw = WatershedTool(item) fold_panel.ApplyCaptionStyle(item, style) - fold_panel.AddFoldPanelWindow(item, wtw, Spacing= 0, + fold_panel.AddFoldPanelWindow(item, wtw, spacing= 0, leftSpacing=0, rightSpacing=0) self.__id_watershed = item.GetId() diff --git a/invesalius/gui/task_surface.py b/invesalius/gui/task_surface.py index fc6ff8f..f9cf15a 100644 --- a/invesalius/gui/task_surface.py +++ b/invesalius/gui/task_surface.py @@ -22,11 +22,11 @@ import os import wx import wx.lib.hyperlink as hl from wx.lib.pubsub import pub as Publisher +import wx.lib.foldpanelbar as fpb import invesalius.constants as const import invesalius.data.slice_ as slice_ import invesalius.gui.dialogs as dlg -import invesalius.gui.widgets.foldpanelbar as fpb import invesalius.gui.widgets.colourselect as csel import invesalius.gui.widgets.platebtn as pbtn import invesalius.project as prj @@ -216,13 +216,13 @@ class InnerFoldPanel(wx.Panel): # Fold 1 - Surface properties item = fold_panel.AddFoldPanel(_("Surface properties"), collapsed=True) fold_panel.ApplyCaptionStyle(item, style) - fold_panel.AddFoldPanelWindow(item, SurfaceProperties(item), Spacing= 0, + fold_panel.AddFoldPanelWindow(item, SurfaceProperties(item), spacing= 0, leftSpacing=0, rightSpacing=0) # Fold 2 - Surface tools item = fold_panel.AddFoldPanel(_("Advanced options"), collapsed=True) fold_panel.ApplyCaptionStyle(item, style) - fold_panel.AddFoldPanelWindow(item, SurfaceTools(item), Spacing= 0, + fold_panel.AddFoldPanelWindow(item, SurfaceTools(item), spacing= 0, leftSpacing=0, rightSpacing=0) #fold_panel.AddFoldPanelWindow(item, QualityAdjustment(item), Spacing= 0, diff --git a/invesalius/gui/widgets/foldpanelbar.py b/invesalius/gui/widgets/foldpanelbar.py deleted file mode 100644 index 28b6472..0000000 --- a/invesalius/gui/widgets/foldpanelbar.py +++ /dev/null @@ -1,1937 +0,0 @@ -#-------------------------------------------------------------------------- -# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas -# Copyright: (C) 2001 Centro de Pesquisas Renato Archer -# Homepage: http://www.softwarepublico.gov.br -# Contact: invesalius@cti.gov.br -# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt) -#-------------------------------------------------------------------------- -# Este programa e software livre; voce pode redistribui-lo e/ou -# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme -# publicada pela Free Software Foundation; de acordo com a versao 2 -# da Licenca. -# -# Este programa eh distribuido na expectativa de ser util, mas SEM -# QUALQUER GARANTIA; sem mesmo a garantia implicita de -# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM -# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais -# detalhes. -#-------------------------------------------------------------------------- - -# --------------------------------------------------------------------------- # -# FOLDPANELBAR wxPython IMPLEMENTATION -# Ported From Jorgen Bodde & Julian Smart (Extended Demo) C++ Code By: -# -# Andrea Gavana, @ 23 Mar 2005 -# Latest Revision: 05 Nov 2005, 23.30 CET -# -# -# TODO List -# -# All The C++ TODOs Are Still Alive. I Am Not Able to Read Jorges's Mind -# So I Don't Really Know What Will Be The New Features/Additions He Will -# Make On His Code. At The Moment They Are: -# -# 1. OnPaint Function In CaptionBar Class: -# TODO: Maybe First A Memory Dc Should Draw All, And Then Paint It On The -# Caption. This Way A Flickering Arrow During Resize Is Not Visible. -# -# 2. OnChar Function In CaptionBar Class: -# TODO: This Is Easy To Do But I Don't Have Any Useful Idea On Which Kind -# Of Features To Add. Does Anyone Have An Intelligent Idea? -# -# 3. AddFoldPanelWindow Function In FoldPanelBar Class: -# TODO: Take Old And New Heights, And If Difference, Reposition All The -# Lower Panels. This Is Because The User Can Add New wxWindow Controls -# Somewhere In Between When Other Panels Are Already Present. -# Don't Know What It Means. Probably Is My Poor English... -# -# 4. OnSizePanel Function In FoldPanelBar Class: -# TODO: A Smart Way To Check Wether The Old - New Width Of The -# Panel Changed, If So No Need To Resize The Fold Panel Items -# -# -# DONE List: -# -# 1. Implemented Styles Like FPB_SINGLE_FOLD and FPB_EXCLUSIVE_FOLD -# Thanks To E. A. Tacao For His Nice Suggestions. -# -# 2. Added Some Maquillage To FoldPanelBar: When The Mouse Enters The Icon -# Region, It Is Changed To wx.CURSOR_HAND. -# -# -# For The Original TODO List From Jorgen, Please Refer To: -# http://www.solidsteel.nl/jorg/components/foldpanel/wxFoldPanelBar.php#todo_list -# -# -# -# For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please -# Write To Me At: -# -# andrea.gavana@agip.it -# andrea_gavan@tin.it -# -# Or, Obviously, To The wxPython Mailing List!!! -# -# -# End Of Comments -# --------------------------------------------------------------------------- # - - -""" -The `FoldPanelBar` is a control that contains multiple panels (of type -`FoldPanelItem`) that can be expanded or collapsed. The captionbar of -the FoldPanel can be customized by setting it to a horizontal gradient -style, vertical gradient style, a single color, a rectangle or filled -rectangle. The FoldPanel items can be collapsed in place or to the -bottom of the control. `wx.Window` derived controls can be added -dynamically, and separated by separator lines. FoldPanelBar is -freeware and distributed under the wxPython license. - - -How does it work ----------------- - -The internals of the FoldPanelBar is a list of FoldPanelItem objects. Through -the reference of FoldPanel these panels can be controlled by adding new controls -to a FoldPanel or adding new FoldPanels to the FoldPanelBar. -The CaptionBar fires events to the parent (container of all panel items) when a -sub-panel needs resizing (either folding or expanding). The fold or expand process -is simply a resize of the panel so it looks like all controls on it are gone. All -controls are still child of the FoldPanel they are located on. If they don't -handle the event (and they won't) then the owner of the FoldPanelBar gets the -events. This is what you need to handle the controls. There isn't much to it just -a lot of calculations to see what panel belongs where. There are no sizers -involved in the panels, everything is purely x-y positioning. - - -What can it do and what not? ----------------------------- - - a) What it can do: - * Run-time addition of panels (no deletion just yet) - * Run time addition of controls to the panel (it will be resized accordingly) - * Creating panels in collapsed mode or expanded mode - * Various modes of caption behaviour and filling to make it more appealing - * Panels can be folded and collapsed (or all of them) to allow more space - - b) What it cannot do: - - * Selection of a panel like in a list ctrl - * Dragging and dropping the panels - * Re-ordering the panels (not yet) - - -Supported platforms -------------------- - -FoldPanelBar is supported on the following platforms: - * Windows (Verified on Windows XP, 2000) - * Linux/Unix (GTK2) (Thanks To Toni Brkic And Robin Dunn) - * Mac OSX (Thanks To Robin Dunn For The CaptionBar Size Patch) - - -FoldPanelBar is based upon Jorgen Bodde's C++ implementation. -Latest Revision: Andrea Gavana @ 05 Nov 2005, 23.30 CET - -""" - -import wx - -#---------------------------------------------------------------------- -# Collapsed And Expanded Bitmap Images -# Created With img2py.py -#---------------------------------------------------------------------- -from wx.lib.embeddedimage import PyEmbeddedImage - -CollapsedIcon = PyEmbeddedImage( - "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADdJ" - "REFUOI1jZGRiZqAEMFGke/Ab8P/f3/8D5wKY7YRcQRsXoNuKzxXUdwEu23CJU+wCxtG8wAAA" - "mvUb+vltJD8AAAAASUVORK5CYII=") - -ExpandedIcon = PyEmbeddedImage( - "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAEJJ" - "REFUOI1jZGRiZqAEMFGke1AYwIIu8P/f3/+4FDMyMTNS3QUYBmCzBZ84bQIR3TZcttPOBci2" - "4rOdKi5gHM0LDACevARXGc9htQAAAABJRU5ErkJggg==") - -#---------------------------------------------------------------------- -# FOLDPANELBAR Starts Here -#---------------------------------------------------------------------- - -# CAPTIONBAR STYLES -# -#- CAPTIONBAR_GRADIENT_V: Draws a vertical gradient from top to bottom -#- CAPTIONBAR_GRADIENT_H: Draws a horizontal gradient from left to right -#- CAPTIONBAR_SINGLE: Draws a single filled rectangle to draw the caption -#- CAPTIONBAR_RECTANGLE: Draws a single colour with a rectangle around the caption -#- CAPTIONBAR_FILLED_RECTANGLE: Draws a filled rectangle and a border around it - -CAPTIONBAR_NOSTYLE = 0 -CAPTIONBAR_GRADIENT_V = 1 -CAPTIONBAR_GRADIENT_H = 2 -CAPTIONBAR_SINGLE = 3 -CAPTIONBAR_RECTANGLE = 4 -CAPTIONBAR_FILLED_RECTANGLE = 5 - -FPB_EXTRA_X = 10 -FPB_EXTRA_Y = 4 - -# pixels of the bmp to be aligned from the right filled with space -FPB_BMP_RIGHTSPACE = 2 - -# Now supported! Single fold forces -# other panels to close when they are open, and only opens the current panel. -# This will allow the open panel to gain the full size left in the client area -FPB_SINGLE_FOLD = 0x0001 - -# All panels are stacked to the bottom. When they are expanded again they -# show up at the top -FPB_COLLAPSE_TO_BOTTOM = 0x0002 - -# Now supported! Single fold plus panels -# will be stacked at the bottom -FPB_EXCLUSIVE_FOLD = 0x0004 - -# Orientation Flag -FPB_HORIZONTAL = wx.HORIZONTAL -FPB_VERTICAL = wx.VERTICAL - -# Default Extrastyle of the FoldPanelBar -FPB_DEFAULT_EXTRASTYLE = 0 -# Default style of the FoldPanelBar -FPB_DEFAULT_STYLE = wx.TAB_TRAVERSAL | wx.NO_BORDER - -# FoldPanelItem default settings -FPB_ALIGN_LEFT = 0 -FPB_ALIGN_WIDTH = 1 - -FPB_DEFAULT_LEFTSPACING = 5 -FPB_DEFAULT_RIGHTSPACING = 10 -FPB_DEFAULT_SPACING = 8 - -FPB_DEFAULT_LEFTLINESPACING = 2 -FPB_DEFAULT_RIGHTLINESPACING = 2 - - -# ------------------------------------------------------------------------------ # -# class CaptionBarStyle -# ------------------------------------------------------------------------------ # - -class CaptionBarStyle: - """ - This class encapsulates the styles you wish to set for the - `CaptionBar` (this is the part of the FoldPanel where the caption - is displayed). It can either be applied at creation time be - reapplied when styles need to be changed. - - At construction time, all styles are set to their default - transparency. This means none of the styles will be applied to - the `CaptionBar` in question, meaning it will be created using the - default internals. When setting i.e the color, font or panel - style, these styles become active to be used. - - """ - - def __init__(self): - """ Default constructor for this class.""" - - self.ResetDefaults() - - - def ResetDefaults(self): - """ Resets default CaptionBarStyle.""" - self._firstColourUsed = False - self._secondColourUsed = False - self._textColourUsed = False - self._captionFontUsed = False - self._captionStyleUsed = False - self._captionStyle = CAPTIONBAR_GRADIENT_V - - - # ------- CaptionBar Font ------- - - def SetCaptionFont(self, font): - """ - Sets font for the caption bar. - - If this is not set, the font property is undefined and will - not be used. Use `CaptionFontUsed` to check if this style is - used. - """ - self._captionFont = font - self._captionFontUsed = True - - - def CaptionFontUsed(self): - """ Checks if the caption bar font is set. """ - return self._captionFontUsed - - - def GetCaptionFont(self): - """ - Returns the font for the caption bar. - - Please be warned this will result in an assertion failure when - this property is not previously set. - - :see: `SetCaptionFont`, `CaptionFontUsed` - """ - return self._captionFont - - - # ------- First Colour ------- - - def SetFirstColour(self, colour): - """ - Sets first colour for the caption bar. - - If this is not set, the colour property is undefined and will - not be used. Use `FirstColourUsed` to check if this style is - used. - """ - self._firstColour = colour - self._firstColourUsed = True - - - def FirstColourUsed(self): - """ Checks if the first colour of the caption bar is set.""" - return self._firstColourUsed - - - def GetFirstColour(self): - """ - Returns the first colour for the caption bar. - - Please be warned this will result in an assertion failure when - this property is not previously set. - - :see: `SetFirstColour`, `FirstColourUsed` - """ - return self._firstColour - - - # ------- Second Colour ------- - - def SetSecondColour(self, colour): - """ - Sets second colour for the caption bar. - - If this is not set, the colour property is undefined and will - not be used. Use `SecondColourUsed` to check if this style is - used. - """ - self._secondColour = colour - self._secondColourUsed = True - - - def SecondColourUsed(self): - """ Checks if the second colour of the caption bar is set.""" - return self._secondColourUsed - - - def GetSecondColour(self): - """ - Returns the second colour for the caption bar. - - Please be warned this will result in an assertion failure when - this property is not previously set. - - :see: `SetSecondColour`, `SecondColourUsed` - """ - return self._secondColour - - - # ------- Caption Text Colour ------- - - def SetCaptionColour(self, colour): - """ - Sets caption colour for the caption bar. - - If this is not set, the colour property is undefined and will - not be used. Use `CaptionColourUsed` to check if this style is - used. - """ - self._textColour = colour - self._textColourUsed = True - - - def CaptionColourUsed(self): - """ Checks if the caption colour of the caption bar is set.""" - return self._textColourUsed - - - def GetCaptionColour(self): - """ - Returns the caption colour for the caption bar. - - Please be warned this will result in an assertion failure - when this property is not previously set. - See also SetCaptionColour(), CaptionColourUsed() - """ - return self._textColour - - - # ------- CaptionStyle ------- - - def SetCaptionStyle(self, style): - """ - Sets caption style for the caption bar. - - If this is not set, the property is undefined and will not be - used. Use CaptionStyleUsed() to check if this style is used. - The following styles can be applied: - - * CAPTIONBAR_GRADIENT_V: Draws a vertical gradient from top to bottom - - * CAPTIONBAR_GRADIENT_H: Draws a horizontal gradient from - left to right - - * CAPTIONBAR_SINGLE: Draws a single filled rectangle to - draw the caption - - * CAPTIONBAR_RECTANGLE: Draws a single colour with a - rectangle around the caption - - * CAPTIONBAR_FILLED_RECTANGLE: Draws a filled rectangle - and a border around it - - """ - self._captionStyle = style - self._captionStyleUsed = True - - - def CaptionStyleUsed(self): - """ Checks if the caption style of the caption bar is set.""" - return self._captionStyleUsed - - - def GetCaptionStyle(self): - """ - Returns the caption style for the caption bar. - - Please be warned this will result in an assertion failure - when this property is not previously set. - - :see: `SetCaptionStyle`, `CaptionStyleUsed` - """ - return self._captionStyle - - -#-----------------------------------# -# CaptionBarEvent -#-----------------------------------# -wxEVT_CAPTIONBAR = wx.NewEventType() -EVT_CAPTIONBAR = wx.PyEventBinder(wxEVT_CAPTIONBAR, 0) - - -# ---------------------------------------------------------------------------- # -# class CaptionBarEvent -# ---------------------------------------------------------------------------- # - -class CaptionBarEvent(wx.PyCommandEvent): - """ - This event will be sent when a EVT_CAPTIONBAR is mapped in the parent. - It is to notify the parent that the bar is now in collapsed or expanded - state. The parent should re-arrange the associated windows accordingly - """ - def __init__(self, evtType): - """ Default Constructor For This Class.""" - wx.PyCommandEvent.__init__(self, evtType) - - - def GetFoldStatus(self): - """ - Returns whether the bar is expanded or collapsed. True means - expanded. - """ - return not self._bar.IsCollapsed() - - - def GetBar(self): - """ Returns The CaptionBar Selected.""" - return self._bar - - - def SetTag(self, tag): - """ Assign A Tag To The Selected CaptionBar.""" - self._tag = tag - - - def GetTag(self): - """ Returns The Tag Assigned To The Selected CaptionBar.""" - return self._tag - - - def SetBar(self, bar): - """ - Sets the bar associated with this event. - - Should not used by any other then the originator of the event. - """ - self._bar = bar - - -# -------------------------------------------------------------------------------- # -# class CaptionBar -# -------------------------------------------------------------------------------- # - -class CaptionBar(wx.Window): - """ - This class is a graphical caption component that consists of a - caption and a clickable arrow. - - The CaptionBar fires an event EVT_CAPTIONBAR which is a - `CaptionBarEvent`. This event can be caught and the parent window - can act upon the collapsed or expanded state of the bar (which is - actually just the icon which changed). The parent panel can - reduce size or expand again. - """ - - # Define Empty CaptionBar Style - EmptyCaptionBarStyle = CaptionBarStyle() - - def __init__(self, parent, id, pos, size, caption="", - foldIcons=None, cbstyle=EmptyCaptionBarStyle, - rightIndent=FPB_BMP_RIGHTSPACE, - iconWidth=16, iconHeight=16, collapsed=False): - """ Default Class Constructor.""" - - wx.Window.__init__(self, parent, wx.ID_ANY, pos=pos, - size=(20,20), style=wx.NO_BORDER) - - self._controlCreated = False - self._collapsed = collapsed - self.ApplyCaptionStyle(cbstyle, True) - - if foldIcons is None: - foldIcons = wx.ImageList(16, 16) - - bmp = ExpandedIcon.GetBitmap() - foldIcons.Add(bmp) - bmp = CollapsedIcon.GetBitmap() - foldIcons.Add(bmp) - - # set initial size - if foldIcons: - assert foldIcons.GetImageCount() > 1 - iconWidth, iconHeight = foldIcons.GetSize(0) - - self._caption = caption - self._foldIcons = foldIcons - self._style = cbstyle - self._rightIndent = rightIndent - self._iconWidth = iconWidth - self._iconHeight = iconHeight - self._oldSize = wx.Size(20,20) - - self._controlCreated = True - - self.Bind(wx.EVT_PAINT, self.OnPaint) - self.Bind(wx.EVT_SIZE, self.OnSize) - self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent) - self.Bind(wx.EVT_CHAR, self.OnChar) - - - def ApplyCaptionStyle(self, cbstyle=EmptyCaptionBarStyle, applyDefault=True): - """ Applies the style defined in cbstyle to the CaptionBar.""" - - newstyle = cbstyle - - if applyDefault: - - # get first colour from style or make it default - if not newstyle.FirstColourUsed(): - newstyle.SetFirstColour(wx.WHITE) - - # get second colour from style or make it default - if not newstyle.SecondColourUsed(): - # make the second colour slightly darker then the background - color = self.GetParent().GetBackgroundColour() - r, g, b = int(color.Red()), int(color.Green()), int(color.Blue()) - color = ((r >> 1) + 20, (g >> 1) + 20, (b >> 1) + 20) - newstyle.SetSecondColour(wx.Colour(color[0], color[1], color[2])) - - # get text colour - if not newstyle.CaptionColourUsed(): - newstyle.SetCaptionColour(wx.BLACK) - - # get font colour - if not newstyle.CaptionFontUsed(): - newstyle.SetCaptionFont(self.GetParent().GetFont()) - - # apply caption style - if not newstyle.CaptionStyleUsed(): - newstyle.SetCaptionStyle(CAPTIONBAR_GRADIENT_V) - - self._style = newstyle - - - def SetCaptionStyle(self, cbstyle=EmptyCaptionBarStyle, applyDefault=True): - """ - Sets CaptionBar styles with CapionBarStyle class. - - All styles that are actually set, are applied. If you set - applyDefault to True, all other (not defined) styles will be - set to default. If it is False, the styles which are not set - in the CaptionBarStyle will be ignored. - """ - self.ApplyCaptionStyle(cbstyle, applyDefault) - self.Refresh() - - - def GetCaptionStyle(self): - """ - Returns the current style of the captionbar in a - `CaptionBarStyle` class. - - This can be used to change and set back the changes. - """ - return self._style - - - def IsCollapsed(self): - """ - Returns wether the status of the bar is expanded or collapsed. - """ - return self._collapsed - - - def SetRightIndent(self, pixels): - """ - Sets the amount of pixels on the right from which the bitmap - is trailing. - - If this is 0, it will be drawn all the way to the right, - default is equal to FPB_BMP_RIGHTSPACE. Assign this before - assigning an image list to prevent a redraw. - """ - assert pixels >= 0 - self._rightIndent = pixels - if self._foldIcons: - self.Refresh() - - - def Collapse(self): - """ - This sets the internal state / representation to collapsed. - - This does not trigger a `CaptionBarEvent` to be sent to the - parent. - """ - self._collapsed = True - self.RedrawIconBitmap() - - - def Expand(self): - """ - This sets the internal state / representation to expanded. - - This does not trigger a `CaptionBarEvent` to be sent to the - parent. - """ - self._collapsed = False - self.RedrawIconBitmap() - - - def SetBoldFont(self): - """ Sets the CaptionBarFont weight to BOLD.""" - - self.GetFont().SetWeight(wx.BOLD) - - - def SetNormalFont(self): - """ Sets the CaptionBarFont weight to NORMAL.""" - - self.GetFont().SetWeight(wx.NORMAL) - - - def IsVertical(self): - """ - Returns wether the CaptionBar Has Default Orientation Or Not. - - Default is vertical. - """ - - fld = self.GetParent().GetGrandParent() - if isinstance(fld, FoldPanelBar): - return self.GetParent().GetGrandParent().IsVertical() - else: - raise "ERROR: Wrong Parent " + repr(fld) - - - def OnPaint(self, event): - """ The paint event for flat or gradient fill. """ - - if not self._controlCreated: - event.Skip() - return - - dc = wx.PaintDC(self) - wndRect = self.GetRect() - vertical = self.IsVertical() - - # TODO: Maybe first a memory DC should draw all, and then paint it on - # the caption. This way a flickering arrow during resize is not visible - - self.FillCaptionBackground(dc) - dc.SetFont(self._style.GetCaptionFont()) - dc.SetTextForeground(self._style.GetCaptionColour()) - - if vertical: - dc.DrawText(self._caption, 4, FPB_EXTRA_Y/2) - else: - dc.DrawRotatedText(self._caption, FPB_EXTRA_Y/2, - wndRect.GetBottom() - 4, 90) - - # draw small icon, either collapsed or expanded - # based on the state of the bar. If we have any bmp's - - if self._foldIcons: - - index = self._collapsed - - if vertical: - drw = wndRect.GetRight() - self._iconWidth - self._rightIndent - self._foldIcons.Draw(index, dc, drw, - (wndRect.GetHeight() - self._iconHeight)/2, - wx.IMAGELIST_DRAW_TRANSPARENT) - else: - self._foldIcons.Draw(index, dc, - (wndRect.GetWidth() - self._iconWidth)/2, - self._rightIndent, wx.IMAGELIST_DRAW_TRANSPARENT) - -## event.Skip() - - - def FillCaptionBackground(self, dc): - """ - Fills the background of the caption with either a gradient or - a solid color. - """ - - style = self._style.GetCaptionStyle() - - if style == CAPTIONBAR_GRADIENT_V: - if self.IsVertical(): - self.DrawVerticalGradient(dc, self.GetRect()) - else: - self.DrawHorizontalGradient(dc, self.GetRect()) - - elif style == CAPTIONBAR_GRADIENT_H: - if self.IsVertical(): - self.DrawHorizontalGradient(dc, self.GetRect()) - else: - self.DrawVerticalGradient(dc, self.GetRect()) - - elif style == CAPTIONBAR_SINGLE: - self.DrawSingleColour(dc, self.GetRect()) - elif style == CAPTIONBAR_RECTANGLE or style == CAPTIONBAR_FILLED_RECTANGLE: - self.DrawSingleRectangle(dc, self.GetRect()) - else: - raise "STYLE Error: Undefined Style Selected: " + repr(style) - - - def OnMouseEvent(self, event): - """ - Catches the mouse click-double click. - - If clicked on the arrow (single) or double on the caption we change state - and an event must be fired to let this panel collapse or expand. - """ - - send_event = False - vertical = self.IsVertical() - - if event.LeftDown() and self._foldIcons: - - pt = event.GetPosition() - rect = self.GetRect() - - drw = (rect.GetWidth() - self._iconWidth - self._rightIndent) - if vertical and pt.x > drw or not vertical and \ - pt.y < (self._iconHeight + self._rightIndent): - send_event = True - - elif event.LeftDClick(): - self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) - send_event = True - - elif event.Entering() and self._foldIcons: - pt = event.GetPosition() - rect = self.GetRect() - - drw = (rect.GetWidth() - self._iconWidth - self._rightIndent) - if vertical and pt.x > drw or not vertical and \ - pt.y < (self._iconHeight + self._rightIndent): - self.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) - else: - self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) - - elif event.Leaving(): - self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) - - elif event.Moving(): - pt = event.GetPosition() - rect = self.GetRect() - - drw = (rect.GetWidth() - self._iconWidth - self._rightIndent) - if vertical and pt.x > drw or not vertical and \ - pt.y < (self._iconHeight + self._rightIndent): - self.SetCursor(wx.StockCursor(wx.CURSOR_HAND)) - else: - self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) - - # send the collapse, expand event to the parent - - if send_event: - event = CaptionBarEvent(wxEVT_CAPTIONBAR) - event.SetId(self.GetId()) - event.SetEventObject(self) - event.SetBar(self) - self.GetEventHandler().ProcessEvent(event) - - - def OnChar(self, event): - """ Unused Methods. Any Ideas?!?""" - # TODO: Anything here? - event.Skip() - - - def DoGetBestSize(self): - """ - Returns the best size for this panel, based upon the font - assigned to this window, and the caption string - """ - - if self.IsVertical(): - x, y = self.GetTextExtent(self._caption) - else: - y, x = self.GetTextExtent(self._caption) - - if x < self._iconWidth: - x = self._iconWidth - - if y < self._iconHeight: - y = self._iconHeight - - # TODO: The extra FPB_EXTRA_X constants should be adjustable as well - - return wx.Size(x + FPB_EXTRA_X, y + FPB_EXTRA_Y) - - - def DrawVerticalGradient(self, dc, rect): - """ Gradient fill from colour 1 to colour 2 with top to bottom. """ - - if rect.height < 1 or rect.width < 1: - return - - dc.SetPen(wx.TRANSPARENT_PEN) - - # calculate gradient coefficients - col2 = self._style.GetSecondColour() - col1 = self._style.GetFirstColour() - - r1, g1, b1 = int(col1.Red()), int(col1.Green()), int(col1.Blue()) - r2, g2, b2 = int(col2.Red()), int(col2.Green()), int(col2.Blue()) - - flrect = float(rect.height) - - rstep = float((r2 - r1)) / flrect - gstep = float((g2 - g1)) / flrect - bstep = float((b2 - b1)) / flrect - - rf, gf, bf = 0, 0, 0 - - for y in range(rect.y, rect.y + rect.height): - currCol = (r1 + rf, g1 + gf, b1 + bf) - - dc.SetBrush(wx.Brush(currCol, wx.SOLID)) - dc.DrawRectangle(rect.x, rect.y + (y - rect.y), rect.width, rect.height) - rf = rf + rstep - gf = gf + gstep - bf = bf + bstep - - - def DrawHorizontalGradient(self, dc, rect): - """ Gradient fill from colour 1 to colour 2 with left to right. """ - - if rect.height < 1 or rect.width < 1: - return - - dc.SetPen(wx.TRANSPARENT_PEN) - - # calculate gradient coefficients - col2 = self._style.GetSecondColour() - col1 = self._style.GetFirstColour() - - r1, g1, b1 = int(col1.Red()), int(col1.Green()), int(col1.Blue()) - r2, g2, b2 = int(col2.Red()), int(col2.Green()), int(col2.Blue()) - - flrect = float(rect.width) - - rstep = float((r2 - r1)) / flrect - gstep = float((g2 - g1)) / flrect - bstep = float((b2 - b1)) / flrect - - rf, gf, bf = 0, 0, 0 - - for x in range(rect.x, rect.x + rect.width): - currCol = (r1 + rf, g1 + gf, b1 + bf) - - dc.SetBrush(wx.Brush(currCol, wx.SOLID)) - dc.DrawRectangle(rect.x + (x - rect.x), rect.y, 1, rect.height) - rf = rf + rstep - gf = gf + gstep - bf = bf + bstep - - - def DrawSingleColour(self, dc, rect): - """ Single colour fill. This is the most easy one to find. """ - - if rect.height < 1 or rect.width < 1: - return - - dc.SetPen(wx.TRANSPARENT_PEN) - - # draw simple rectangle - dc.SetBrush(wx.Brush(self._style.GetFirstColour(), wx.SOLID)) - dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height) - - - def DrawSingleRectangle(self, dc, rect): - """ Single rectangle. This is the most easy one to find. """ - - if rect.height < 2 or rect.width < 1: - return - - # single frame, set up internal fill colour - - if self._style.GetCaptionStyle() == CAPTIONBAR_RECTANGLE: - color = self.GetParent().GetBackgroundColour() - br = wx.Brush(color, wx.SOLID) - else: - color = self._style.GetFirstColour() - br = wx.Brush(color, wx.SOLID) - - # setup the pen frame - - pen = wx.Pen(self._style.GetSecondColour()) - dc.SetPen(pen) - dc.SetBrush(br) - dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height - 1) - - bgpen = wx.Pen(self.GetParent().GetBackgroundColour()) - dc.SetPen(bgpen) - dc.DrawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, - rect.y + rect.height - 1) - - - def OnSize(self, event): - """ Handles the size events for the CaptionBar.""" - - if not self._controlCreated: - event.Skip() - return - - size = event.GetSize() - - if self._foldIcons: - - # What I am doing here is simply invalidating the part of the window - # exposed. So when I make a rect with as width the newly exposed part, - # and the x,y of the old window size origin, I don't need a bitmap - # calculation in it, or do I ? The bitmap needs redrawing anyway. - # Leave it like this until I figured it out. - - # set rect to redraw as old bitmap area which is entitled to redraw - - rect = wx.Rect(size.GetWidth() - self._iconWidth - self._rightIndent, 0, - self._iconWidth + self._rightIndent, - self._iconWidth + self._rightIndent) - - # adjust rectangle when more is slided so we need to redraw all - # the old stuff but not all (ugly flickering) - - diffX = size.GetWidth() - self._oldSize.GetWidth() - - if diffX > 1: - - # adjust the rect with all the crap to redraw - - rect.SetWidth(rect.GetWidth() + diffX + 10) - rect.SetX(rect.GetX() - diffX - 10) - - self.RefreshRect(rect) - - else: - - rect = self.GetRect() - self.RefreshRect(rect) - - self._oldSize = size - - - def RedrawIconBitmap(self): - """ Redraws the icons (if they exists). """ - - if self._foldIcons: - - # invalidate the bitmap area and force a redraw - - rect = self.GetRect() - - rect.SetX(rect.GetWidth() - self._iconWidth - self._rightIndent) - rect.SetWidth(self._iconWidth + self._rightIndent) - self.RefreshRect(rect) - - -# ---------------------------------------------------------------------------------- # -# class FoldPanelBar -# ---------------------------------------------------------------------------------- # - -class FoldPanelBar(wx.Panel): - """ - The FoldPanelBar is a class which can maintain a list of - collapsable panels. Once a panel is collapsed, only it's caption - bar is visible to the user. This will provide more space for the - other panels, or allow the user to close panels which are not used - often to get the most out of the work area. - - This control is easy to use. Simply create it as a child for a - panel or sash window, and populate panels with - `AddFoldPanel`. Then use the `AddFoldPanelWindow` to add - `wx.Window` derived controls to the current fold panel. Use - `AddFoldPanelSeparator` to put separators between the groups of - controls that need a visual separator to group them - together. After all is constructed, the user can fold the panels - by doubleclicking on the bar or single click on the arrow, which - will indicate the collapsed or expanded state. - """ - # Define Empty CaptionBar Style - EmptyCaptionBarStyle = CaptionBarStyle() - - def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize, - style=FPB_DEFAULT_STYLE, extraStyle=FPB_DEFAULT_EXTRASTYLE): - """ Default Class Constructor. """ - - self._controlCreated = False - self._extraStyle = extraStyle - - # make sure there is any orientation - if style & FPB_HORIZONTAL != FPB_HORIZONTAL: - style = style | FPB_VERTICAL - - if style & FPB_HORIZONTAL == 4: - self._isVertical = False - else: - self._isVertical = True - - - # create the panel (duh!). This causes a size event, which we are going - # to skip when we are not initialised - - wx.Panel.__init__(self, parent, id, pos, size, style) - - # the fold panel area - - self._foldPanel = wx.Panel(self, wx.ID_ANY, pos, size, - wx.NO_BORDER | wx.TAB_TRAVERSAL) - - self._controlCreated = True - self._panels = [] - - self.Bind(EVT_CAPTIONBAR, self.OnPressCaption) - self.Bind(wx.EVT_SIZE, self.OnSizePanel) - - - def AddFoldPanel(self, caption="", collapsed=False, foldIcons=None, - cbstyle=EmptyCaptionBarStyle): - """ - Adds a fold panel to the list of panels. - - If the flag collapsed is set to True, the panel is collapsed - initially. The FoldPanel item which is returned, can be used - as a reference to perform actions upon the fold panel like - collapsing it, expanding it, or deleting it from the list. - - Use this foldpanel to add windows to it. Please consult - `AddFoldPanelWindow` and `AddFoldPanelSeparator` to know how - to add items derived from `wx.Window` to the panels. - """ - - # create a fold panel item, which is first only the caption. - # the user can now add a panel area which will be folded in - # when pressed. - - if foldIcons is None: - foldIcons = wx.ImageList(16, 16) - - bmp = ExpandedIcon.GetBitmap() - foldIcons.Add(bmp) - bmp = CollapsedIcon.GetBitmap() - foldIcons.Add(bmp) - - item = FoldPanelItem(self._foldPanel, -1, caption=caption, - foldIcons=foldIcons, - collapsed=collapsed, cbstyle=cbstyle) - - pos = 0 - if len(self._panels) > 0: - pos = self._panels[-1].GetItemPos() + self._panels[-1].GetPanelLength() - - item.Reposition(pos) - self._panels.append(item) - - return item - - - def AddFoldPanelWindow(self, panel, window, flags=FPB_ALIGN_WIDTH, - Spacing=FPB_DEFAULT_SPACING, - leftSpacing=FPB_DEFAULT_LEFTLINESPACING, - rightSpacing=FPB_DEFAULT_RIGHTLINESPACING): - """ - Adds a `wx.Window` derived instance to the referenced - FoldPanel. - - IMPORTANT: Make the window be a child of the FoldPanel. See - example that follows. The flags to be used are: - - * FPB_ALIGN_WIDTH: Which means the wxWindow to be added - will be aligned to fit the width of the FoldPanel when - it is resized. Very handy for sizer items, buttons and - text boxes. - - * FPB_ALIGN_LEFT: Aligns left instead of fitting the - width of the child window to be added. Use either this - one or FPB_ALIGN_WIDTH. - - The wx.Window to be added can be slightly indented from left - and right so it is more visibly placed in the FoldPanel. Use - Spacing > 0 to give the control an y offset from the previous - wx.Window added, use leftSpacing to give it a slight indent - from the left, and rightSpacing also reserves a little space - on the right so the wxWindow can be properly placed in the - FoldPanel. - - The following example adds a FoldPanel to the FoldPanelBar and - adds two wx.Window derived controls to the FoldPanel:: - - # create the FoldPanelBar - >>> m_pnl = FoldPanelBar(self, wx.ID_ANY, wx.DefaultPosition, - wx.DefaultSize, FPB_DEFAULT_STYLE, - FPB_COLLAPSE_TO_BOTTOM) - - # add a foldpanel to the control. "Test me" is the caption and it is - # initially not collapsed. - >>> item = m_pnl.AddFoldPanel("Test me", False) - - # now add a button to the fold panel. Mind that the button should be - # made child of the FoldPanel and not of the main form. - >>> m_pnl.AddFoldPanelWindow(item, wx.Button(item, ID_COLLAPSEME, - "Collapse Me")) - - # add a separator between the two controls. This is purely a visual - # line that can have a certain color and also the indents and width - # aligning like a control. - >>> m_pnl.AddFoldPanelSeparator(item) - - # now add a text ctrl. Also very easy. Align this on width so that - # when the control gets wider the text control also sizes along. - >>> m_pnl.AddFoldPanelWindow(item, wx.TextCtrl(item, wx.ID_ANY, "Comment"), - FPB_ALIGN_WIDTH, FPB_DEFAULT_SPACING, 20) - - """ - - try: - item = self._panels.index(panel) - except: - raise "ERROR: Invalid Panel Passed To AddFoldPanelWindow: " + repr(panel) - - panel.AddWindow(window, flags, Spacing, leftSpacing, rightSpacing) - - # TODO: Take old and new height, and if difference, reposition all the lower - # panels this is because the user can add new wxWindow controls somewhere in - # between when other panels are already present. - - return 0 - - - def AddFoldPanelSeparator(self, panel, colour=wx.BLACK, - Spacing=FPB_DEFAULT_SPACING, - leftSpacing=FPB_DEFAULT_LEFTLINESPACING, - rightSpacing=FPB_DEFAULT_RIGHTLINESPACING): - """ - Adds a separator line to the current FoldPanel. - - The seperator is a simple line which is drawn and is no real - component. It can be used to separate groups of controls - which belong to each other. The colour is adjustable, and it - takes the same Spacing, leftSpacing and rightSpacing as - `AddFoldPanelWindow`. - """ - - try: - item = self._panels.index(panel) - except: - raise "ERROR: Invalid Panel Passed To AddFoldPanelSeparator: " + repr(panel) - - panel.AddSeparator(colour, Spacing, leftSpacing, rightSpacing) - return 0 - - - def OnSizePanel(self, event): - """ Handles the EVT_SIZE event for the FoldPanelBar. """ - - # skip all stuff when we are not initialised yet - - if not self._controlCreated: - event.Skip() - return - - foldrect = self.GetRect() - - # fold panel itself. If too little space, - # don't show it - - foldrect.SetX(0) - foldrect.SetY(0) - - self._foldPanel.SetSize(foldrect[2:]) - - if self._extraStyle & FPB_COLLAPSE_TO_BOTTOM or self._extraStyle & FPB_EXCLUSIVE_FOLD: - rect = self.RepositionCollapsedToBottom() - vertical = self.IsVertical() - if vertical and rect.GetHeight() > 0 or not vertical and rect.GetWidth() > 0: - self.RefreshRect(rect) - - # TODO: A smart way to check wether the old - new width of the - # panel changed, if so no need to resize the fold panel items - - self.RedisplayFoldPanelItems() - - - def OnPressCaption(self, event): - """ Handles the EVT_CAPTIONBAR event in the FoldPanelBar. """ - - # act upon the folding or expanding status of the bar - # to expand or collapse the panel(s) - - if event.GetFoldStatus(): - self.Collapse(event.GetTag()) - else: - self.Expand(event.GetTag()) - - #event.Skip() - - - def RefreshPanelsFrom(self, item): - """ Refreshes all the panels from given index down to last one. """ - - try: - i = self._panels.index(item) - except: - raise "ERROR: Invalid Panel Passed To RefreshPanelsFrom: " + repr(item) - - self.Freeze() - - # if collapse to bottom is on, the panels that are not expanded - # should be drawn at the bottom. All panels that are expanded - # are drawn on top. The last expanded panel gets all the extra space - - if self._extraStyle & FPB_COLLAPSE_TO_BOTTOM or self._extraStyle & FPB_EXCLUSIVE_FOLD: - - offset = 0 - - for panels in self._panels: - - if panels.IsExpanded(): - offset = offset + panels.Reposition(offset) - - # put all non collapsed panels at the bottom where there is space, - # else put them right behind the expanded ones - - self.RepositionCollapsedToBottom() - - else: - - pos = self._panels[i].GetItemPos() + self._panels[i].GetPanelLength() - for j in range(i+1, len(self._panels)): - pos = pos + self._panels[j].Reposition(pos) - - self.Thaw() - - - def RedisplayFoldPanelItems(self): - """ Resizes the fold panels so they match the width. """ - # resize them all. No need to reposition - for panels in self._panels: - panels.ResizePanel() - panels.Refresh() - - - def RepositionCollapsedToBottom(self): - """ - Repositions all the collapsed panels to the bottom. - - When it is not possible to align them to the bottom, stick - them behind the visible panels. The Rect holds the slack area - left between last repositioned panel and the bottom - panels. This needs to get a refresh. - """ - - value = wx.Rect(0,0,0,0) - vertical = self.IsVertical() - - # determine wether the number of panels left - # times the size of their captions is enough - # to be placed in the left over space - - expanded = 0 - collapsed = 0 - collapsed, expanded, values = self.GetPanelsLength(collapsed, expanded) - - # if no room stick them behind the normal ones, else - # at the bottom - - if (vertical and [self.GetSize().GetHeight()] or \ - [self.GetSize().GetWidth()])[0] - expanded - collapsed < 0: - offset = expanded - else: - - # value is the region which is left unpainted - # I will send it back as 'slack' so it does not need to - # be recalculated. - - value.SetHeight(self.GetSize().GetHeight()) - value.SetWidth(self.GetSize().GetWidth()) - - if vertical: - value.SetY(expanded) - value.SetHeight(value.GetHeight() - expanded) - else: - value.SetX(expanded) - value.SetWidth(value.GetWidth() - expanded) - - offset = (vertical and [self.GetSize().GetHeight()] or \ - [self.GetSize().GetWidth()])[0] - collapsed - - - # go reposition - - for panels in self._panels: - if not panels.IsExpanded(): - offset = offset + panels.Reposition(offset) - - return value - - - def GetPanelsLength(self, collapsed, expanded): - """ - Returns the length of the panels that are expanded and - collapsed. - - This is useful to determine quickly what size is used to - display, and what is left at the bottom (right) to align the - collapsed panels. - """ - - value = 0 - - # assumed here that all the panels that are expanded - # are positioned after each other from 0,0 to end. - - for j in range(0, len(self._panels)): - offset = self._panels[j].GetPanelLength() - value = value + offset - if self._panels[j].IsExpanded(): - expanded = expanded + offset - else: - collapsed = collapsed + offset - - return collapsed, expanded, value - - - def Collapse(self, foldpanel): - """ - Collapses the given FoldPanel reference, and updates the - foldpanel bar. - - In the FPB_COLLAPSE_TO_BOTTOM style, all collapsed captions - are put at the bottom of the control. In the normal mode, they - stay where they are. - """ - - try: - item = self._panels.index(foldpanel) - except: - raise "ERROR: Invalid Panel Passed To Collapse: " + repr(foldpanel) - - foldpanel.Collapse() - self.RefreshPanelsFrom(foldpanel) - - - def Expand(self, foldpanel): - """ - Expands the given FoldPanel reference, and updates the - foldpanel bar. - - In the FPB_COLLAPSE_TO_BOTTOM style, they will be removed from - the bottom and the order where the panel originally was placed - is restored. - """ - - fpbextrastyle = 0 - - if self._extraStyle & FPB_SINGLE_FOLD or self._extraStyle & FPB_EXCLUSIVE_FOLD: - fpbextrastyle = 1 - for panel in self._panels: - panel.Collapse() - - foldpanel.Expand() - - if fpbextrastyle: - if self._extraStyle & FPB_EXCLUSIVE_FOLD: - self.RepositionCollapsedToBottom() - self.RefreshPanelsFrom(self._panels[0]) - else: - self.RefreshPanelsFrom(foldpanel) - - - def ApplyCaptionStyle(self, foldpanel, cbstyle): - """ - Sets the style of the caption bar (`CaptionBar`) of the - FoldPanel. - - The changes are applied immediately. All styles not set in the - CaptionBarStyle class are not applied. Use the CaptionBar - reference to indicate what captionbar you want to apply the - style to. To apply one style to all CaptionBar items, use - `ApplyCaptionStyleAll` - """ - foldpanel.ApplyCaptionStyle(cbstyle) - - - def ApplyCaptionStyleAll(self, cbstyle): - """ - Sets the style of all the caption bars of the FoldPanel. - - The changes are applied immediately. - """ - for panels in self._panels: - self.ApplyCaptionStyle(panels, cbstyle) - - - def GetCaptionStyle(self, foldpanel): - """ - Returns the currently used caption style for the FoldPanel. - - It is returned as a CaptionBarStyle class. After modifying it, - it can be set again. - """ - return foldpanel.GetCaptionStyle() - - - def IsVertical(self): - """ - Returns whether the CaptionBar has default orientation or not. - - Default is vertical. - """ - return self._isVertical - - - def GetFoldPanel(self, item): - """ - Returns the panel associated with the index "item". - - See the example at the bottom of the module, especially the events - for the "Collapse Me" and "Expand Me" buttons. - """ - try: - ind = self._panels[item] - return self._panels[item] - except: - raise "ERROR: List Index Out Of Range Or Bad Item Passed: " + repr(item) + \ - ". Item Should Be An Integer Between " + repr(0) + " And " + \ - repr(len(self._panels)) - - - def GetCount(self): - """ Returns the number of panels in the FoldPanelBar. """ - - try: - return len(self._panels) - except: - raise "ERROR: No Panels Have Been Added To FoldPanelBar" - - - -# --------------------------------------------------------------------------------- # -# class FoldPanelItem -# --------------------------------------------------------------------------------- # - -class FoldPanelItem(wx.Panel): - """ - This class is a child sibling of the `FoldPanelBar` class. It will - contain a `CaptionBar` class for receiving of events, and a the - rest of the area can be populated by a `wx.Panel` derived class. - """ - # Define Empty CaptionBar Style - EmptyCaptionBarStyle = CaptionBarStyle() - - def __init__(self, parent, id=wx.ID_ANY, caption="", foldIcons=None, - collapsed=False, cbstyle=EmptyCaptionBarStyle): - """ Default Class Constructor. """ - - wx.Panel.__init__(self, parent, id, wx.Point(0,0), style=wx.CLIP_CHILDREN) - self._controlCreated = False - self._UserSize = 0 - self._PanelSize = 0 - self._LastInsertPos = 0 - self._itemPos = 0 - self._userSized = False - - if foldIcons is None: - foldIcons = wx.ImageList(16, 16) - - bmp = ExpandedIcon.GetBitmap() - foldIcons.Add(bmp) - bmp = CollapsedIcon.GetBitmap() - foldIcons.Add(bmp) - - self._foldIcons = foldIcons - - # create the caption bar, in collapsed or expanded state - - self._captionBar = CaptionBar(self, wx.ID_ANY, wx.Point(0,0), - size=wx.DefaultSize, caption=caption, - foldIcons=foldIcons, cbstyle=cbstyle) - - if collapsed: - self._captionBar.Collapse() - - self._controlCreated = True - - # make initial size for component, if collapsed, the - # size is determined on the panel height and won't change - - size = self._captionBar.GetSize() - - self._PanelSize = (self.IsVertical() and [size.GetHeight()] or \ - [size.GetWidth()])[0] - - self._LastInsertPos = self._PanelSize - self._items = [] - - self.Bind(EVT_CAPTIONBAR, self.OnPressCaption) - self.Bind(wx.EVT_PAINT, self.OnPaint) - - - def AddWindow(self, window, flags=FPB_ALIGN_WIDTH, Spacing=FPB_DEFAULT_SPACING, - leftSpacing=FPB_DEFAULT_LEFTLINESPACING, - rightSpacing=FPB_DEFAULT_RIGHTLINESPACING): - """ - Adds a window item to the list of items on this panel. - - The flags are FPB_ALIGN_LEFT for a non sizing window element, - and FPB_ALIGN_WIDTH for a width aligned item. The Spacing - parameter reserves a number of pixels before the window - element, and leftSpacing is an indent. rightSpacing is only - relevant when the style FPB_ALIGN_WIDTH is chosen. - """ - - wi = FoldWindowItem(self, window, Type="WINDOW", flags=flags, Spacing=Spacing, - leftSpacing=leftSpacing, rightSpacing=rightSpacing) - - self._items.append(wi) - - vertical = self.IsVertical() - - self._Spacing = Spacing - self._leftSpacing = leftSpacing - self._rightSpacing = rightSpacing - - xpos = (vertical and [leftSpacing] or [self._LastInsertPos + Spacing])[0] - ypos = (vertical and [self._LastInsertPos + Spacing] or [leftSpacing])[0] - - window.SetDimensions(xpos, ypos, -1, -1, wx.SIZE_USE_EXISTING) - - self._LastInsertPos = self._LastInsertPos + wi.GetWindowLength(vertical) - self.ResizePanel() - - - def AddSeparator(self, colour=wx.BLACK, Spacing=FPB_DEFAULT_SPACING, - leftSpacing=FPB_DEFAULT_LEFTSPACING, - rightSpacing=FPB_DEFAULT_RIGHTSPACING): - """ - Adds a separator item to the list of items on this panel. """ - - wi = FoldWindowItem(self, window=None, Type="SEPARATOR", - flags=FPB_ALIGN_WIDTH, y=self._LastInsertPos, - colour=colour, Spacing=Spacing, leftSpacing=leftSpacing, - rightSpacing=rightSpacing) - - self._items.append(wi) - self._LastInsertPos = self._LastInsertPos + \ - wi.GetWindowLength(self.IsVertical()) - - self.ResizePanel() - - - def Reposition(self, pos): - """ - Repositions this FoldPanelBar and reports the length occupied - for the next FoldPanelBar in the list. - """ - # NOTE: Call Resize before Reposition when an item is added, because the new - # size needed will be calculated by Resize. Of course the relative position - # of the controls have to be correct in respect to the caption bar - - self.Freeze() - - vertical = self.IsVertical() - xpos = (vertical and [-1] or [pos])[0] - ypos = (vertical and [pos] or [-1])[0] - - self.SetDimensions(xpos, ypos, -1, -1, wx.SIZE_USE_EXISTING) - self._itemPos = pos - - self.Thaw() - - return self.GetPanelLength() - - - def OnPressCaption(self, event): - """ Handles the EVT_CAPTIONBAR event in the FoldPanelItem. """ - - # tell the upper container we are responsible - # for this event, so it can fold the panel item - # and do a refresh - - event.SetTag(self) - event.Skip() - - - def ResizePanel(self): - """ Resizes the panel. """ - - # prevent unnecessary updates by blocking repaints for a sec - - self.Freeze() - - vertical = self.IsVertical() - # force this panel to take the width of the parent panel and the y of the - # user or calculated width (which will be recalculated by the contents here) - - - if self._captionBar.IsCollapsed(): - size = self._captionBar.GetSize() - self._PanelSize = (vertical and [size.GetHeight()] or [size.GetWidth()])[0] - else: - size = self.GetBestSize() - self._PanelSize = (vertical and [size.GetHeight()] or [size.GetWidth()])[0] - - if self._UserSize: - if vertical: - size.SetHeight(self._UserSize) - else: - size.SetWidth(self._UserSize) - - pnlsize = self.GetParent().GetSize() - - if vertical: - size.SetWidth(pnlsize.GetWidth()) - else: - size.SetHeight(pnlsize.GetHeight()) - - # resize caption bar - xsize = (vertical and [size.GetWidth()] or [-1])[0] - ysize = (vertical and [-1] or [size.GetHeight()])[0] - - self._captionBar.SetSize((xsize, ysize)) - - # resize the panel - self.SetSize(size) - - # go by all the controls and call Layout - - for items in self._items: - items.ResizeItem((vertical and [size.GetWidth()] or \ - [size.GetHeight()])[0], vertical) - - self.Thaw() - - - def OnPaint(self, event): - """ Handles the EVT_PAINT event in the FoldPanelItem. """ - - # draw all the items that are lines - - dc = wx.PaintDC(self) - vertical = self.IsVertical() - - for item in self._items: - - if item.GetType() == "SEPARATOR": - pen = wx.Pen(item.GetLineColour(), 1, wx.SOLID) - dc.SetPen(pen) - a = item.GetLeftSpacing() - b = item.GetLineY() + item.GetSpacing() - c = item.GetLineLength() - d = a + c - - if vertical: - dc.DrawLine(a, b, d, b) - else: - dc.DrawLine(b, a, b, d) - - event.Skip() - - - def IsVertical(self): - """ - Returns wether the CaptionBar Has Default Orientation Or Not. - - Default is vertical. - """ - - # grandparent of FoldPanelItem is FoldPanelBar - # default is vertical - - if isinstance(self.GetGrandParent(), FoldPanelBar): - return self.GetGrandParent().IsVertical() - else: - raise "ERROR: Wrong Parent " + repr(self.GetGrandParent()) - - - def IsExpanded(self): - """ - Returns expanded or collapsed status. If the panel is - expanded, True is returned. - """ - - return not self._captionBar.IsCollapsed() - - - def GetItemPos(self): - """ Returns item's position. """ - - return self._itemPos - - - def Collapse(self): - # this should not be called by the user, because it doesn't trigger the - # parent to tell it that we are collapsed or expanded, it only changes - # visual state - - self._captionBar.Collapse() - self.ResizePanel() - - - def Expand(self): - # this should not be called by the user, because it doesn't trigger the - # parent to tell it that we are collapsed or expanded, it only changes - # visual state - - self._captionBar.Expand() - self.ResizePanel() - - - def GetPanelLength(self): - """ Returns size of panel. """ - - if self._captionBar.IsCollapsed(): - return self.GetCaptionLength() - elif self._userSized: - return self._UserSize - - return self._PanelSize - - - def GetCaptionLength(self): - """ - Returns height of caption only. This is for folding - calculation purposes. - """ - - size = self._captionBar.GetSize() - return (self.IsVertical() and [size.GetHeight()] or [size.GetWidth()])[0] - - - def ApplyCaptionStyle(self, cbstyle): - """ Applies the style defined in cbstyle to the CaptionBar.""" - - self._captionBar.SetCaptionStyle(cbstyle) - - - def GetCaptionStyle(self): - """ - Returns the current style of the captionbar in a - CaptionBarStyle class. - - This can be used to change and set back the changes. - """ - - return self._captionBar.GetCaptionStyle() - - -# ----------------------------------------------------------------------------------- # -# class FoldWindowItem -# ----------------------------------------------------------------------------------- # - -class FoldWindowItem: - """ - This class is a child sibling of the `FoldPanelItem` class. It - will contain wx.Window that can be either a separator (a colored - line simulated by a wx.Window) or a wxPython controls (such as a - wx.Button, a wx.ListCtrl etc...). - """ - def __init__(self, parent, window=None, **kw): - """ - Default Class Constructor - - Initialize with:: - - Type = "WINDOW", flags = FPB_ALIGN_WIDTH, - Spacing = FPB_DEFAULT_SPACING, - leftSpacing = FPB_DEFAULT_LEFTSPACING, - rightSpacing = FPB_DEFAULT_RIGHTSPACING - - or:: - - Type = "SEPARATOR" - y, lineColor = wx.BLACK, - flags = FPB_ALIGN_WIDTH, - Spacing = FPB_DEFAULT_SPACING, - leftSpacing = FPB_DEFAULT_LEFTLINESPACING, - rightSpacing = FPB_DEFAULT_RIGHTLINESPACING - """ - - - if not kw.has_key("Type"): - raise 'ERROR: Missing Window Type Information. This Should Be "WINDOW" Or "SEPARATOR"' - - if kw.get("Type") == "WINDOW": - # Window constructor. This initialises the class as a wx.Window Type - - if kw.has_key("flags"): - self._flags = kw.get("flags") - else: - self._flags = FPB_ALIGN_WIDTH - if kw.has_key("Spacing"): - self._Spacing = kw.get("Spacing") - else: - self._Spacing = FPB_DEFAULT_SPACING - if kw.has_key("leftSpacing"): - self._leftSpacing = kw.get("leftSpacing") - else: - self._leftSpacing = FPB_DEFAULT_LEFTSPACING - if kw.has_key("rightSpacing"): - self._rightSpacing = kw.get("rightSpacing") - else: - self._rightSpacing = FPB_DEFAULT_RIGHTSPACING - - self._lineY = 0 - self._sepLineColour = None - self._wnd = window - - - elif kw.get("Type") == "SEPARATOR": - # separator constructor. This initialises the class as a separator type - - if kw.has_key("y"): - self._lineY = kw.get("y") - else: - raise "ERROR: Undefined Y Position For The Separator" - if kw.has_key("lineColour"): - self._sepLineColour = kw.get("lineColour") - else: - self._sepLineColour = wx.BLACK - if kw.has_key("flags"): - self._flags = kw.get("flags") - else: - self._flags = FPB_ALIGN_WIDTH - if kw.has_key("Spacing"): - self._Spacing = kw.get("Spacing") - else: - self._Spacing = FPB_DEFAULT_SPACING - if kw.has_key("leftSpacing"): - self._leftSpacing = kw.get("leftSpacing") - else: - self._leftSpacing = FPB_DEFAULT_LEFTSPACING - if kw.has_key("rightSpacing"): - self._rightSpacing = kw.get("rightSpacing") - else: - self._rightSpacing = FPB_DEFAULT_RIGHTSPACING - - self._wnd = window - - else: - raise "ERROR: Undefined Window Type Selected: " + repr(kw.get("Type")) - - self._type = kw.get("Type") - self._lineLength = 0 - - - def GetType(self): - return self._type - - def GetLineY(self): - return self._lineY - - def GetLineLength(self): - return self._lineLength - - def GetLineColour(self): - return self._sepLineColour - - def GetLeftSpacing(self): - return self._leftSpacing - - def GetRightSpacing(self): - return self._rightSpacing - - def GetSpacing(self): - return self._Spacing - - - def GetWindowLength(self, vertical=True): - """ - Returns space needed by the window if type is FoldWindowItem - "WINDOW" and returns the total size plus the extra spacing. - """ - - value = 0 - if self._type == "WINDOW": - size = self._wnd.GetSize() - value = (vertical and [size.GetHeight()] or [size.GetWidth()])[0] + \ - self._Spacing - - elif self._type == "SEPARATOR": - value = 1 + self._Spacing - - return value - - - def ResizeItem(self, size, vertical=True): - """ - Resizes the element, whatever it is. - - A separator or line will be always aligned by width or height - depending on orientation of the whole panel. - """ - - if self._flags & FPB_ALIGN_WIDTH: - # align by taking full width - mySize = size - self._leftSpacing - self._rightSpacing - - if mySize < 0: - mySize = 10 # can't have negative width - - if self._type == "SEPARATOR": - self._lineLength = mySize - else: - xsize = (vertical and [mySize] or [-1])[0] - ysize = (vertical and [-1] or [mySize])[0] - - self._wnd.SetSize((xsize, ysize)) - -- libgit2 0.21.2