📄 foldpanelbar.py
字号:
"""
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 = GetExpandedIconBitmap()
foldIcons.Add(bmp)
bmp = GetCollapsedIconBitmap()
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -