]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/EventManager.py
   1 #--------------------------------------------------------------------------- 
   2 # Name:        EventManager.py 
   3 # Purpose:     A module to demonstrate wxPython.lib.evtmgr.EventManager. 
   5 # Author:      Robb Shecter (robb@acm.org) 
   7 # Created:     16-December-2002 
   8 # Copyright:   (c) 2002 by Robb Shecter (robb@acm.org) 
   9 # Licence:     wxWindows license 
  10 #--------------------------------------------------------------------------- 
  13 import  wx
.lib
.evtmgr   
as  em
 
  15 #---------------------------------------------------------------------- 
  17 class TestPanel(wx
.Panel
): 
  18     def __init__(self
, parent
, log
): 
  19         wx
.Panel
.__init
__(self
, parent
, -1) 
  22         fsize    
= self
.GetFont().GetPointSize() 
  23         f1 
= wx
.Font(fsize
+0, wx
.SWISS
, wx
.NORMAL
, wx
.NORMAL
) 
  24         f2 
= wx
.Font(fsize
+2, wx
.SWISS
, wx
.NORMAL
, wx
.BOLD
) 
  25         f3 
= wx
.Font(fsize
+6, wx
.SWISS
, wx
.NORMAL
, wx
.BOLD
) 
  27         title1 
= wx
.StaticText(self
, -1, 'EventManager') 
  30         This demo shows  (1) basic uses and features of the EventManager, as well 
  31         as  (2) how it helps with a real-world task: creating independent, object- 
  32         oriented components.""" 
  33         message0 
= wx
.StaticText(self
, -1, txt
) 
  36         title2 
= wx
.StaticText(self
, -1, 'Event Listeners') 
  40         These objects listen to motion events from the target window, using the ability 
  41         to register one event with multiple listeners.  They also register for mouse events 
  42         on themselves to implement toggle-button functionality.""" 
  43         message1 
= wx
.StaticText(self
, -1, txt
) 
  46         title3 
= wx
.StaticText(self
, -1, 'Target Window') 
  50         A passive window that's used as an event generator.  Move the mouse over it to 
  51         send events to the listeners above.""" 
  52         message2 
= wx
.StaticText(self
, -1, txt
) 
  55         targetPanel 
= Tile(self
, log
, bgColor
=wx
.Colour(80,10,10), active
=0) 
  56         buttonPanel 
= wx
.Panel(self 
,-1) 
  57         sizer       
= wx
.BoxSizer(wx
.HORIZONTAL
) 
  58         target      
= targetPanel
.tile
 
  61         for factor 
in [0.2, 0.3, 0.4, 0.5, 0.6, 0.7]: 
  62             sizer
.Add(Tile(buttonPanel
, log
, factor
-0.05, target
), 0, wx
.ALIGN_CENTER
) 
  64             sizer
.Add(Tile(buttonPanel
, log
, factor
,      target
), 0, wx
.ALIGN_CENTER
) 
  67         buttonPanel
.SetSizer(sizer
) 
  68         sizer
.Fit(buttonPanel
) 
  70         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
  71         sizer
.Add(title1
,      0, wx
.ALIGN_CENTER | wx
.TOP | wx
.BOTTOM
, 6) 
  72         sizer
.Add(message0
,    0, wx
.ALIGN_CENTER | wx
.ALL
, 6) 
  73         sizer
.Add(title2
,      0, wx
.ALIGN_CENTER | wx
.LEFT | wx
.TOP    | wx
.RIGHT
, 16) 
  74         sizer
.Add(message1
,    0, wx
.ALIGN_CENTER | wx
.ALL
, 6) 
  75         sizer
.Add(buttonPanel
, 0, wx
.EXPAND       | wx
.ALL
, 16) 
  76         sizer
.Add(title3
,      0, wx
.ALIGN_CENTER | wx
.LEFT | wx
.RIGHT
, 16) 
  77         sizer
.Add(message2
,    0, wx
.ALIGN_CENTER | wx
.ALL
, 6) 
  78         sizer
.Add(targetPanel
, 2, wx
.EXPAND       | wx
.LEFT | wx
.BOTTOM | wx
.RIGHT
, 16) 
  83 class Tile(wx
.Window
): 
  85     This outer class is responsible for changing 
  86     its border color in response to certain mouse 
  87     events over its contained 'InnerTile'. 
  89     normal 
= wx
.Colour(150,150,150) 
  90     active 
= wx
.Colour(250,245,245) 
  91     hover  
= wx
.Colour(210,220,210) 
  93     def __init__(self
, parent
, log
, factor
=1, thingToWatch
=None, bgColor
=None, active
=1, size
=(38,38), borderWidth
=3): 
  94         wx
.Window
.__init
__(self
, parent
, -1, size
=size
, style
=wx
.CLIP_CHILDREN
) 
  95         self
.tile 
= InnerTile(self
, log
, factor
, thingToWatch
, bgColor
) 
  97         sizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
  98         sizer
.Add(self
.tile
, 1, wx
.EXPAND | wx
.ALL
, borderWidth
) 
 101         em
.eventManager
.Register(self
.doLayout
, wx
.EVT_SIZE
, self
) 
 102         self
.SetBackgroundColour(Tile
.normal
) 
 104             # Register myself for mouse events over self.tile in order to 
 105             # create typical button/hyperlink visual effects. 
 106             em
.eventManager
.Register(self
.setHover
,  wx
.EVT_ENTER_WINDOW
, self
.tile
) 
 107             em
.eventManager
.Register(self
.setNormal
, wx
.EVT_LEAVE_WINDOW
, self
.tile
) 
 108             em
.eventManager
.Register(self
.setActive
, wx
.EVT_LEFT_DOWN
,    self
.tile
) 
 109             em
.eventManager
.Register(self
.setHover
,  wx
.EVT_LEFT_UP
,      self
.tile
) 
 112     def doLayout(self
, event
): 
 116     def setHover(self
, event
): 
 117         self
.SetBackgroundColour(Tile
.hover
) 
 121     def setActive(self
, event
): 
 122         self
.SetBackgroundColour(Tile
.active
) 
 126     def setNormal(self
, event
): 
 127         self
.SetBackgroundColour(Tile
.normal
) 
 132 class InnerTile(wx
.Window
): 
 133     IDLE_COLOR  
= wx
.Colour( 80, 10, 10) 
 134     START_COLOR 
= wx
.Colour(200, 70, 50) 
 135     FINAL_COLOR 
= wx
.Colour( 20, 80,240) 
 136     OFF_COLOR   
= wx
.Colour(185,190,185) 
 137     # Some pre-computation. 
 138     DELTAS            
= map(lambda a
,b
: b
-a
, START_COLOR
.Get(), FINAL_COLOR
.Get()) 
 139     START_COLOR_TUPLE 
= START_COLOR
.Get() 
 142     This inner panel changes its color in reaction to mouse 
 143     events over the 'thingToWatch'. 
 145     def __init__(self
, parent
, log
, factor
, thingToWatch
=None, bgColor
=None): 
 146         wx
.Window
.__init
__(self
, parent
, -1) 
 147         self
.SetMinSize((20,20)) 
 150             self
.SetBackgroundColour(bgColor
) 
 153             self
.thingToWatch 
= thingToWatch
 
 156             # Watch for the mouse click to enable/disable myself. 
 157             em
.eventManager
.Register(self
.toggleOnOff
, wx
.EVT_LEFT_UP
, self
) 
 160     def toggleOnOff(self
, event
=None): 
 161         # Implement being on or off by registering and 
 162         # de-registering self.makeColor() from the event manager. 
 164             em
.eventManager
.DeregisterListener(self
.makeColor
) 
 166             em
.eventManager
.Register(self
.makeColor
, wx
.EVT_MOTION
, self
.thingToWatch
) 
 167         self
.state 
= 1 - self
.state
 
 171     def resetColor(self
, event
=None): 
 173             self
.setColor(InnerTile
.IDLE_COLOR
) 
 175             self
.setColor(InnerTile
.OFF_COLOR
) 
 178     def setColor(self
, color
): 
 179         self
.SetBackgroundColour(color
) 
 183     def makeColor(self
, mouseEvent
): 
 184         self
.makeColorFromTuple(mouseEvent
.GetPositionTuple()) 
 187     def makeColorFromTuple(self
, (x
, y
)): 
 189         scaled  
= min((x 
+ y
) * self
.factor
, MAX
)  # In range [0..MAX] 
 190         percent 
= scaled 
/ MAX
 
 191         r 
= InnerTile
.START_COLOR_TUPLE
[0] + (InnerTile
.DELTAS
[0] * percent
) 
 192         g 
= InnerTile
.START_COLOR_TUPLE
[1] + (InnerTile
.DELTAS
[1] * percent
) 
 193         b 
= InnerTile
.START_COLOR_TUPLE
[2] + (InnerTile
.DELTAS
[2] * percent
) 
 194         self
.setColor(wx
.Colour(int(r
), int(g
), int(b
))) 
 199 #---------------------------------------------------------------------- 
 201 def runTest(frame
, nb
, log
): 
 202     win 
= TestPanel(nb
, log
) 
 205 #---------------------------------------------------------------------- 
 209 overview 
= """<html><body> 
 210 <h2>EventManager</h2> 
 212 <p> The goal of the EventManager is to make wxWindows events more 
 213 'Pythonic' (ie. object-oriented) and easier to work with, without 
 214 impacting performance.  It offers these features: 
 219     <li> Allows any number of listeners to register for a single 
 220     event.  (In addition to the standard wxPython feature of a single 
 221     listener being able to respond to many events.) 
 223     <li> Makes it easy to disconnect and reconnect listeners.  This 
 224     has the effect of reducing the need for case-based branching in 
 227     <li> Has an object-oriented API.  Programmers register to get 
 228     events directly from the objects that generate them, instead of 
 235 <p>The EventManager class has three public methods.  First get a 
 239   from wxPython.lib.evtmgr import eventManager 
 242 <p>...and then invoke any of the following methods.  These methods are 
 243 'safe'; duplicate registrations or de-registrations will have no 
 246 <p><b>Registering a listener:</b> 
 249   eventManager.Register(listener, event, event-source) 
 253 <p><b>De-registering by window:</b> 
 256   eventManager.DeregisterWindow(event-source) 
 260 <p><b>De-registering by listener:</b> 
 263   eventManager.DeregisterListener(listener) 
 266 <p><b>Simple Example:</b> 
 269   from wxPython.lib.evtmgr import eventManager 
 271   aButton = wxButton(somePanel, -1, 'Click me') 
 272   eventManager.Register(self.someMethod, EVT_BUTTON, aButton) 
 275 <p> See the demo code as well as the documentation in the source of 
 276 <tt>wxPython.lib.evtmgr</tt> for more details. 
 280 by Robb Shecter (robb@acm.org) 
 286 if __name__ 
== '__main__': 
 289     run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])