More updates from Andrea

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42087 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2006-10-17 22:41:17 +00:00
parent 7753ca6bed
commit 61b3549028
2 changed files with 288 additions and 56 deletions

View File

@@ -46,6 +46,7 @@ def GetMondrianIcon():
icon.CopyFromBitmap(GetMondrianBitmap()) icon.CopyFromBitmap(GetMondrianBitmap())
return icon return icon
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class SettingsPanel(wx.MiniFrame): class SettingsPanel(wx.MiniFrame):
@@ -461,7 +462,6 @@ class SettingsPanel(wx.MiniFrame):
self.Destroy() self.Destroy()
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class ButtonPanelDemo(wx.Frame): class ButtonPanelDemo(wx.Frame):
@@ -607,17 +607,22 @@ class ButtonPanelDemo(wx.Frame):
self.SetProperties() self.SetProperties()
self.indices = [] self.indices = []
for count, png in enumerate(self.pngs): for count, png in enumerate(self.pngs):
shortHelp = "Button %d"%(count+1)
if count < 2: if count < 2:
# First 2 buttons are togglebuttons # First 2 buttons are togglebuttons
kind = wx.ITEM_CHECK kind = wx.ITEM_CHECK
longHelp = "ButtonPanel Toggle Button No %d"%(count+1)
else: else:
kind = wx.ITEM_NORMAL kind = wx.ITEM_NORMAL
longHelp = "Simple Button without label No %d"%(count+1)
btn = bp.ButtonInfo(self.titleBar, wx.NewId(), btn = bp.ButtonInfo(self.titleBar, wx.NewId(),
png[0], png[0], kind=kind,
kind=kind) shortHelp=shortHelp, longHelp=longHelp)
self.titleBar.AddButton(btn) self.titleBar.AddButton(btn)
self.Bind(wx.EVT_BUTTON, self.OnButton, id=btn.GetId()) self.Bind(wx.EVT_BUTTON, self.OnButton, id=btn.GetId())
@@ -658,7 +663,8 @@ class ButtonPanelDemo(wx.Frame):
if self.created: if self.created:
sizer = self.mainPanel.GetSizer() sizer = self.mainPanel.GetSizer()
sizer.Detach(0) sizer.Detach(0)
self.titleBar.Destroy() self.titleBar.Hide()
wx.CallAfter(self.titleBar.Destroy)
self.titleBar = bp.ButtonPanel(self.mainPanel, -1, "A Simple Test & Demo", self.titleBar = bp.ButtonPanel(self.mainPanel, -1, "A Simple Test & Demo",
style=self.style, alignment=self.alignment) style=self.style, alignment=self.alignment)
self.SetProperties() self.SetProperties()
@@ -667,6 +673,7 @@ class ButtonPanelDemo(wx.Frame):
# and text # and text
self.indices = [] self.indices = []
for count in xrange(8): for count in xrange(8):
itemImage = random.randint(0, 3) itemImage = random.randint(0, 3)
@@ -865,7 +872,6 @@ class ButtonPanelDemo(wx.Frame):
dlg.Destroy() dlg.Destroy()
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class TestPanel(wx.Panel): class TestPanel(wx.Panel):
@@ -903,4 +909,3 @@ if __name__ == '__main__':

View File

@@ -11,7 +11,7 @@
# Python Code By: # Python Code By:
# #
# Andrea Gavana, @ 02 Oct 2006 # Andrea Gavana, @ 02 Oct 2006
# Latest Revision: 16 Oct 2006, 17.00 GMT # Latest Revision: 17 Oct 2006, 17.00 GMT
# #
# #
# For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please # For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
@@ -45,6 +45,33 @@ classic look).
Usage Usage
----- -----
ButtonPanel supports 4 alignments: left, right, top, bottom, which have a
different meaning and behavior wrt wx.Toolbar. The easiest thing is to try
the demo to understand, but I'll try to explain how it works.
CASE 1: ButtonPanel has a main caption text
Left alignment means ButtonPanel is horizontal, with the text aligned to the
left. When you shrink the demo frame, if there is not enough room for all
the controls to be shown, the controls closest to the text are hidden;
Right alignment means ButtonPanel is horizontal, with the text aligned to the
right. Item layout as above;
Top alignment means ButtonPanel is vertical, with the text aligned to the top.
Item layout as above;
Bottom alignment means ButtonPanel is vertical, with the text aligned to the
bottom. Item layout as above.
CASE 2: ButtonPanel has *no* main caption text
In this case, left and right alignment are the same (as top and bottom are the same),
but the layout strategy changes: now if there is not enough room for all the controls
to be shown, the last added items are hidden ("last" means on the far right for
horizontal ButtonPanels and far bottom for vertical ButtonPanels).
The following example shows a simple implementation that uses ButtonPanel The following example shows a simple implementation that uses ButtonPanel
inside a very simple frame:: inside a very simple frame::
@@ -178,6 +205,9 @@ BP_ALIGN_BOTTOM = 8
BP_DEFAULT_STYLE = 1 BP_DEFAULT_STYLE = 1
BP_USE_GRADIENT = 2 BP_USE_GRADIENT = 2
# Delay used to cancel the longHelp in the statusbar field
_DELAY = 3000
# Check for the new method in 2.7 (not present in 2.6.3.3) # Check for the new method in 2.7 (not present in 2.6.3.3)
if wx.VERSION_STRING < "2.7": if wx.VERSION_STRING < "2.7":
@@ -597,6 +627,25 @@ class BPArt:
bf += bstep bf += bstep
class StatusBarTimer(wx.Timer):
"""Timer used for deleting StatusBar long help after _DELAY seconds."""
def __init__(self, owner):
"""
Default class constructor.
For internal use: do not call it in your code!
"""
wx.Timer.__init__(self)
self._owner = owner
def Notify(self):
"""The timer has expired."""
self._owner.OnStatusBarTimer()
class Control(wx.EvtHandler): class Control(wx.EvtHandler):
def __init__(self, parent, size=wx.Size(-1, -1)): def __init__(self, parent, size=wx.Size(-1, -1)):
@@ -895,7 +944,8 @@ class ButtonPanelText(Control):
class ButtonInfo(Control): class ButtonInfo(Control):
def __init__(self, parent, id=wx.ID_ANY, bmp=wx.NullBitmap, def __init__(self, parent, id=wx.ID_ANY, bmp=wx.NullBitmap,
status="Normal", text="", kind=wx.ITEM_NORMAL): status="Normal", text="", kind=wx.ITEM_NORMAL,
shortHelp="", longHelp=""):
""" """
Default class constructor. Default class constructor.
@@ -903,8 +953,13 @@ class ButtonInfo(Control):
- parent: the parent window (ButtonPanel); - parent: the parent window (ButtonPanel);
- id: the button id; - id: the button id;
- bmp: the associated bitmap; - bmp: the associated bitmap;
- status: button status (pressed, hovered, None). - status: button status (pressed, hovered, normal).
- text to be displayed either below of to the right of the button - text: text to be displayed either below of to the right of the button
- kind: button kind, may be wx.ITEM_NORMAL for standard buttons or
wx.ITEM_CHECK for toggle buttons;
- shortHelp: a short help to be shown in the button tooltip;
- longHelp: this string is shown in the statusbar (if any) of the parent
frame when the mouse pointer is inside the button.
""" """
if id == wx.ID_ANY: if id == wx.ID_ANY:
@@ -916,6 +971,8 @@ class ButtonInfo(Control):
self._kind = kind self._kind = kind
self._toggle = False self._toggle = False
self._textAlignment = BP_BUTTONTEXT_ALIGN_BOTTOM self._textAlignment = BP_BUTTONTEXT_ALIGN_BOTTOM
self._shortHelp = shortHelp
self._longHelp = longHelp
disabledbmp = GrayOut(bmp) disabledbmp = GrayOut(bmp)
@@ -982,7 +1039,7 @@ class ButtonInfo(Control):
""" Checks whether a ButtonPanel repaint is needed or not. Convenience function. """ """ Checks whether a ButtonPanel repaint is needed or not. Convenience function. """
if status == self._status: if status == self._status:
self._parent.Refresh() self._parent.RefreshRect(self.GetRect())
def SetBitmap(self, bmp, status="Normal"): def SetBitmap(self, bmp, status="Normal"):
@@ -1041,7 +1098,7 @@ class ButtonInfo(Control):
status = "Toggled" status = "Toggled"
self._status = status self._status = status
self._parent.Refresh() self._parent.RefreshRect(self.GetRect())
def GetTextAlignment(self): def GetTextAlignment(self):
@@ -1139,6 +1196,30 @@ class ButtonInfo(Control):
return self._kind return self._kind
def SetShortHelp(self, help=""):
""" Sets the help string to be shown in a tootip. """
self._shortHelp = help
def GetShortHelp(self):
""" Returns the help string shown in a tootip. """
return self._shortHelp
def SetLongHelp(self, help=""):
""" Sets the help string to be shown in the statusbar. """
self._longHelp = help
def GetLongHelp(self):
""" Returns the help string shown in the statusbar. """
return self._longHelp
Bitmap = property(GetBitmap, SetBitmap) Bitmap = property(GetBitmap, SetBitmap)
Id = property(GetId, SetId) Id = property(GetId, SetId)
Rect = property(GetRect, SetRect) Rect = property(GetRect, SetRect)
@@ -1171,6 +1252,10 @@ class ButtonPanel(wx.PyPanel):
self._nStyle = style self._nStyle = style
self._alignment = alignment self._alignment = alignment
self._statusTimer = None
self._useHelp = True
self._freezeCount = 0
self._currentButton = -1
self._art = BPArt(style) self._art = BPArt(style)
@@ -1660,17 +1745,35 @@ class ButtonPanel(wx.PyPanel):
""" Handles the wx.EVT_MOTION event for ButtonPanel. """ """ Handles the wx.EVT_MOTION event for ButtonPanel. """
# Check to see if we are hovering a button # Check to see if we are hovering a button
for btn in self._vButtons: tabId, flags = self.HitTest(event.GetPosition())
if flags != BP_HT_BUTTON:
self.RemoveHelp()
self.RepaintOldSelection()
self._currentButton = -1
return
btn = self._vButtons[tabId]
if not btn.IsEnabled(): if not btn.IsEnabled():
continue self.RemoveHelp()
self.RepaintOldSelection()
return
if tabId != self._currentButton:
self.RepaintOldSelection()
if btn.GetRect().Contains(event.GetPosition()): if btn.GetRect().Contains(event.GetPosition()):
btn.SetStatus("Hover") btn.SetStatus("Hover")
else: else:
btn.SetStatus("Normal") btn.SetStatus("Normal")
self.Refresh() if tabId != self._currentButton:
self.RemoveHelp()
self.DoGiveHelp(btn)
self._currentButton = tabId
event.Skip() event.Skip()
@@ -1679,19 +1782,22 @@ class ButtonPanel(wx.PyPanel):
tabId, hit = self.HitTest(event.GetPosition()) tabId, hit = self.HitTest(event.GetPosition())
if hit == BP_HT_BUTTON and self._vButtons[tabId].IsEnabled(): if hit == BP_HT_BUTTON:
btn = self._vButtons[tabId]
self._vButtons[tabId].SetStatus("Pressed") if btn.IsEnabled():
self.Refresh() btn.SetStatus("Pressed")
self._currentButton = tabId
def OnLeftUp(self, event): def OnLeftUp(self, event):
""" Handles the wx.EVT_LEFT_UP event for ButtonPanel. """ """ Handles the wx.EVT_LEFT_UP event for ButtonPanel. """
tabId, flags = self.HitTest(event.GetPosition()) tabId, flags = self.HitTest(event.GetPosition())
hit = self._vButtons[tabId]
if flags == BP_HT_BUTTON: if flags != BP_HT_BUTTON:
return
hit = self._vButtons[tabId]
if hit.GetStatus() == "Disabled": if hit.GetStatus() == "Disabled":
return return
@@ -1710,8 +1816,7 @@ class ButtonPanel(wx.PyPanel):
# Update the button status to be hovered # Update the button status to be hovered
hit.SetStatus("Hover") hit.SetStatus("Hover")
hit.SetFocus() hit.SetFocus()
self._currentButton = tabId
self.Refresh()
def OnMouseLeave(self, event): def OnMouseLeave(self, event):
@@ -1723,14 +1828,107 @@ class ButtonPanel(wx.PyPanel):
continue continue
btn.SetStatus("Normal") btn.SetStatus("Normal")
self.Refresh() self.RemoveHelp()
event.Skip() event.Skip()
def OnMouseEnterWindow(self, event): def OnMouseEnterWindow(self, event):
""" Handles the wx.EVT_ENTER_WINDOW event for ButtonPanel. """ """ Handles the wx.EVT_ENTER_WINDOW event for ButtonPanel. """
tabId, flags = self.HitTest(event.GetPosition())
if flags == BP_HT_BUTTON:
hit = self._vButtons[tabId]
if hit.GetStatus() == "Disabled":
event.Skip() event.Skip()
return
self.DoGiveHelp(hit)
self._currentButton = tabId
event.Skip()
def DoGiveHelp(self, hit):
""" Gives tooltips and help in StatusBar. """
if not self.GetUseHelp():
return
shortHelp = hit.GetShortHelp()
if shortHelp:
self.SetToolTipString(shortHelp)
longHelp = hit.GetLongHelp()
if not longHelp:
return
topLevel = wx.GetTopLevelParent(self)
if isinstance(topLevel, wx.Frame) and topLevel.GetStatusBar():
statusBar = topLevel.GetStatusBar()
if self._statusTimer and self._statusTimer.IsRunning():
self._statusTimer.Stop()
statusBar.PopStatusText(0)
statusBar.PushStatusText(longHelp, 0)
self._statusTimer = StatusBarTimer(self)
self._statusTimer.Start(_DELAY, wx.TIMER_ONE_SHOT)
def RemoveHelp(self):
""" Removes the tooltips and statusbar help (if any) for a button. """
if not self.GetUseHelp():
return
self.SetToolTipString("")
if self._statusTimer and self._statusTimer.IsRunning():
topLevel = wx.GetTopLevelParent(self)
statusBar = topLevel.GetStatusBar()
self._statusTimer.Stop()
statusBar.PopStatusText(0)
self._statusTimer = None
def RepaintOldSelection(self):
""" Repaints the old selected/hovered button. """
current = self._currentButton
if current == -1:
return
btn = self._vButtons[current]
if not btn.IsEnabled():
return
btn.SetStatus("Normal")
def OnStatusBarTimer(self):
""" Handles the timer expiring to delete the longHelp in the StatusBar. """
topLevel = wx.GetTopLevelParent(self)
statusBar = topLevel.GetStatusBar()
statusBar.PopStatusText(0)
def SetUseHelp(self, useHelp=True):
""" Sets whether or not shortHelp and longHelp should be displayed. """
self._useHelp = useHelp
def GetUseHelp(self):
""" Returns whether or not shortHelp and longHelp should be displayed. """
return self._useHelp
def HitTest(self, pt): def HitTest(self, pt):
@@ -1739,8 +1937,6 @@ class ButtonPanel(wx.PyPanel):
a flag (if any). a flag (if any).
""" """
btnIdx = -1
for ii in xrange(len(self._vButtons)): for ii in xrange(len(self._vButtons)):
if not self._vButtons[ii].IsEnabled(): if not self._vButtons[ii].IsEnabled():
continue continue
@@ -1755,3 +1951,34 @@ class ButtonPanel(wx.PyPanel):
return self._art return self._art
def SetBPArt(self, art):
""" Sets a new BPArt to ButtonPanel. Useful only if another BPArt class is used. """
self._art = art
self.Refresh()
if wx.VERSION < (2,7,1,1):
def Freeze(self):
"""Freeze ButtonPanel."""
self._freezeCount = self._freezeCount + 1
wx.PyPanel.Freeze(self)
def Thaw(self):
"""Thaw ButtonPanel."""
if self._freezeCount == 0:
raise "\nERROR: Thawing Unfrozen ButtonPanel?"
self._freezeCount = self._freezeCount - 1
wx.PyPanel.Thaw(self)
def IsFrozen(self):
""" Returns whether a call to Freeze() has been done. """
return self._freezeCount != 0