]>
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
.LEFT | wx
.BOTTOM | wx
.RIGHT
, 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) 
 149             self
.SetBackgroundColour(bgColor
) 
 152             self
.thingToWatch 
= thingToWatch
 
 155             # Watch for the mouse click to enable/disable myself. 
 156             em
.eventManager
.Register(self
.toggleOnOff
, wx
.EVT_LEFT_UP
, self
) 
 159     def toggleOnOff(self
, event
=None): 
 160         # Implement being on or off by registering and 
 161         # de-registering self.makeColor() from the event manager. 
 163             em
.eventManager
.DeregisterListener(self
.makeColor
) 
 165             em
.eventManager
.Register(self
.makeColor
, wx
.EVT_MOTION
, self
.thingToWatch
) 
 166         self
.state 
= 1 - self
.state
 
 170     def resetColor(self
, event
=None): 
 172             self
.setColor(InnerTile
.IDLE_COLOR
) 
 174             self
.setColor(InnerTile
.OFF_COLOR
) 
 177     def setColor(self
, color
): 
 178         self
.SetBackgroundColour(color
) 
 182     def makeColor(self
, mouseEvent
): 
 183         self
.makeColorFromTuple(mouseEvent
.GetPositionTuple()) 
 186     def makeColorFromTuple(self
, (x
, y
)): 
 188         scaled  
= min((x 
+ y
) * self
.factor
, MAX
)  # In range [0..MAX] 
 189         percent 
= scaled 
/ MAX
 
 190         r 
= InnerTile
.START_COLOR_TUPLE
[0] + (InnerTile
.DELTAS
[0] * percent
) 
 191         g 
= InnerTile
.START_COLOR_TUPLE
[1] + (InnerTile
.DELTAS
[1] * percent
) 
 192         b 
= InnerTile
.START_COLOR_TUPLE
[2] + (InnerTile
.DELTAS
[2] * percent
) 
 193         self
.setColor(wx
.Colour(int(r
), int(g
), int(b
))) 
 198 #---------------------------------------------------------------------- 
 200 def runTest(frame
, nb
, log
): 
 201     win 
= TestPanel(nb
, log
) 
 204 #---------------------------------------------------------------------- 
 208 overview 
= """<html><body> 
 209 <h2>EventManager</h2> 
 211 <p> The goal of the EventManager is to make wxWindows events more 
 212 'Pythonic' (ie. object-oriented) and easier to work with, without 
 213 impacting performance.  It offers these features: 
 218     <li> Allows any number of listeners to register for a single 
 219     event.  (In addition to the standard wxPython feature of a single 
 220     listener being able to respond to many events.) 
 222     <li> Makes it easy to disconnect and reconnect listeners.  This 
 223     has the effect of reducing the need for case-based branching in 
 226     <li> Has an object-oriented API.  Programmers register to get 
 227     events directly from the objects that generate them, instead of 
 234 <p>The EventManager class has three public methods.  First get a 
 238   from wxPython.lib.evtmgr import eventManager 
 241 <p>...and then invoke any of the following methods.  These methods are 
 242 'safe'; duplicate registrations or de-registrations will have no 
 245 <p><b>Registering a listener:</b> 
 248   eventManager.Register(listener, event, event-source) 
 252 <p><b>De-registering by window:</b> 
 255   eventManager.DeregisterWindow(event-source) 
 259 <p><b>De-registering by listener:</b> 
 262   eventManager.DeregisterListener(listener) 
 265 <p><b>Simple Example:</b> 
 268   from wxPython.lib.evtmgr import eventManager 
 270   aButton = wxButton(somePanel, -1, 'Click me') 
 271   eventManager.Register(self.someMethod, EVT_BUTTON, aButton) 
 274 <p> See the demo code as well as the documentation in the source of 
 275 <tt>wxPython.lib.evtmgr</tt> for more details. 
 279 by Robb Shecter (robb@acm.org) 
 285 if __name__ 
== '__main__': 
 288     run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])