]>
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
.SetAutoLayout(1) 
  68         buttonPanel
.SetSizer(sizer
) 
  69         sizer
.Fit(buttonPanel
) 
  71         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
  72         sizer
.Add(title1
,      0, wx
.ALIGN_CENTER | wx
.TOP | wx
.BOTTOM
, 6) 
  73         sizer
.Add(message0
,    0, wx
.ALIGN_CENTER | wx
.ALL
, 6) 
  74         sizer
.Add(title2
,      0, wx
.ALIGN_CENTER | wx
.LEFT | wx
.TOP    | wx
.RIGHT
, 16) 
  75         sizer
.Add(message1
,    0, wx
.ALIGN_CENTER | wx
.ALL
, 6) 
  76         sizer
.Add(buttonPanel
, 0, wx
.EXPAND       | wx
.LEFT | wx
.BOTTOM | wx
.RIGHT
, 16) 
  77         sizer
.Add(title3
,      0, wx
.ALIGN_CENTER | wx
.LEFT | wx
.RIGHT
, 16) 
  78         sizer
.Add(message2
,    0, wx
.ALIGN_CENTER | wx
.ALL
, 6) 
  79         sizer
.Add(targetPanel
, 2, wx
.EXPAND       | wx
.LEFT | wx
.BOTTOM | wx
.RIGHT
, 16) 
  87     This outer class is responsible for changing 
  88     its border color in response to certain mouse 
  89     events over its contained 'InnerTile'. 
  91     normal 
= wx
.Colour(150,150,150) 
  92     active 
= wx
.Colour(250,245,245) 
  93     hover  
= wx
.Colour(210,220,210) 
  95     def __init__(self
, parent
, log
, factor
=1, thingToWatch
=None, bgColor
=None, active
=1, size
=(38,38), borderWidth
=3): 
  96         wx
.Panel
.__init
__(self
, parent
, -1, size
=size
, style
=wx
.CLIP_CHILDREN
) 
  97         self
.tile 
= InnerTile(self
, log
, factor
, thingToWatch
, bgColor
) 
  99         sizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 100         sizer
.Add(self
.tile
, 1, wx
.EXPAND | wx
.ALL
, borderWidth
) 
 101         self
.SetAutoLayout(1) 
 104         self
.SetBackgroundColour(Tile
.normal
) 
 106             # Register myself for mouse events over self.tile in order to 
 107             # create typical button/hyperlink visual effects. 
 108             em
.eventManager
.Register(self
.setHover
,  wx
.EVT_ENTER_WINDOW
, self
.tile
) 
 109             em
.eventManager
.Register(self
.setNormal
, wx
.EVT_LEAVE_WINDOW
, self
.tile
) 
 110             em
.eventManager
.Register(self
.setActive
, wx
.EVT_LEFT_DOWN
,    self
.tile
) 
 111             em
.eventManager
.Register(self
.setHover
,  wx
.EVT_LEFT_UP
,      self
.tile
) 
 114     def setHover(self
, event
): 
 115         self
.SetBackgroundColour(Tile
.hover
) 
 119     def setActive(self
, event
): 
 120         self
.SetBackgroundColour(Tile
.active
) 
 124     def setNormal(self
, event
): 
 125         self
.SetBackgroundColour(Tile
.normal
) 
 130 class InnerTile(wx
.Panel
): 
 131     IDLE_COLOR  
= wx
.Colour( 80, 10, 10) 
 132     START_COLOR 
= wx
.Colour(200, 70, 50) 
 133     FINAL_COLOR 
= wx
.Colour( 20, 80,240) 
 134     OFF_COLOR   
= wx
.Colour(185,190,185) 
 135     # Some pre-computation. 
 136     DELTAS            
= map(lambda a
,b
: b
-a
, START_COLOR
.Get(), FINAL_COLOR
.Get()) 
 137     START_COLOR_TUPLE 
= START_COLOR
.Get() 
 140     This inner panel changes its color in reaction to mouse 
 141     events over the 'thingToWatch'. 
 143     def __init__(self
, parent
, log
, factor
, thingToWatch
=None, bgColor
=None): 
 144         wx
.Panel
.__init
__(self
, parent
, -1) 
 147             self
.SetBackgroundColour(bgColor
) 
 150             self
.thingToWatch 
= thingToWatch
 
 153             # Watch for the mouse click to enable/disable myself. 
 154             em
.eventManager
.Register(self
.toggleOnOff
, wx
.EVT_LEFT_UP
, self
) 
 157     def toggleOnOff(self
, event
=None): 
 158         # Implement being on or off by registering and 
 159         # de-registering self.makeColor() from the event manager. 
 161             em
.eventManager
.DeregisterListener(self
.makeColor
) 
 163             em
.eventManager
.Register(self
.makeColor
, wx
.EVT_MOTION
, self
.thingToWatch
) 
 164         self
.state 
= 1 - self
.state
 
 168     def resetColor(self
, event
=None): 
 170             self
.setColor(InnerTile
.IDLE_COLOR
) 
 172             self
.setColor(InnerTile
.OFF_COLOR
) 
 175     def setColor(self
, color
): 
 176         self
.SetBackgroundColour(color
) 
 180     def makeColor(self
, mouseEvent
): 
 181         self
.makeColorFromTuple(mouseEvent
.GetPositionTuple()) 
 184     def makeColorFromTuple(self
, (x
, y
)): 
 186         scaled  
= min((x 
+ y
) * self
.factor
, MAX
)  # In range [0..MAX] 
 187         percent 
= scaled 
/ MAX
 
 188         r 
= InnerTile
.START_COLOR_TUPLE
[0] + (InnerTile
.DELTAS
[0] * percent
) 
 189         g 
= InnerTile
.START_COLOR_TUPLE
[1] + (InnerTile
.DELTAS
[1] * percent
) 
 190         b 
= InnerTile
.START_COLOR_TUPLE
[2] + (InnerTile
.DELTAS
[2] * percent
) 
 191         self
.setColor(wx
.Colour(int(r
), int(g
), int(b
))) 
 196 #---------------------------------------------------------------------- 
 198 def runTest(frame
, nb
, log
): 
 199     win 
= TestPanel(nb
, log
) 
 202 #---------------------------------------------------------------------- 
 206 overview 
= """<html><body> 
 207 <h2>EventManager</h2> 
 209 <p> The goal of the EventManager is to make wxWindows events more 
 210 'Pythonic' (ie. object-oriented) and easier to work with, without 
 211 impacting performance.  It offers these features: 
 216     <li> Allows any number of listeners to register for a single 
 217     event.  (In addition to the standard wxPython feature of a single 
 218     listener being able to respond to many events.) 
 220     <li> Makes it easy to disconnect and reconnect listeners.  This 
 221     has the effect of reducing the need for case-based branching in 
 224     <li> Has an object-oriented API.  Programmers register to get 
 225     events directly from the objects that generate them, instead of 
 232 <p>The EventManager class has three public methods.  First get a 
 236   from wxPython.lib.evtmgr import eventManager 
 239 <p>...and then invoke any of the following methods.  These methods are 
 240 'safe'; duplicate registrations or de-registrations will have no 
 243 <p><b>Registering a listener:</b> 
 246   eventManager.Register(listener, event, event-source) 
 250 <p><b>De-registering by window:</b> 
 253   eventManager.DeregisterWindow(event-source) 
 257 <p><b>De-registering by listener:</b> 
 260   eventManager.DeregisterListener(listener) 
 263 <p><b>Simple Example:</b> 
 266   from wxPython.lib.evtmgr import eventManager 
 268   aButton = wxButton(somePanel, -1, 'Click me') 
 269   eventManager.Register(self.someMethod, EVT_BUTTON, aButton) 
 272 <p> See the demo code as well as the documentation in the source of 
 273 <tt>wxPython.lib.evtmgr</tt> for more details. 
 277 by Robb Shecter (robb@acm.org) 
 283 if __name__ 
== '__main__': 
 286     run
.main(['', os
.path
.basename(sys
.argv
[0])])