]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/EventManager.py
When running samples from the demo standalone you can now add a
[wxWidgets.git] / wxPython / demo / EventManager.py
1 #---------------------------------------------------------------------------
2 # Name: EventManager.py
3 # Purpose: A module to demonstrate wxPython.lib.evtmgr.EventManager.
4 #
5 # Author: Robb Shecter (robb@acm.org)
6 #
7 # Created: 16-December-2002
8 # Copyright: (c) 2002 by Robb Shecter (robb@acm.org)
9 # Licence: wxWindows license
10 #---------------------------------------------------------------------------
11
12 import wx
13 import wx.lib.evtmgr as em
14
15 #----------------------------------------------------------------------
16
17 class TestPanel(wx.Panel):
18 def __init__(self, parent, log):
19 wx.Panel.__init__(self, parent, -1)
20 self.log = log
21
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)
26
27 title1 = wx.StaticText(self, -1, 'EventManager')
28 title1.SetFont(f3)
29 txt = """\
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)
34 message0.SetFont(f1)
35
36 title2 = wx.StaticText(self, -1, 'Event Listeners')
37 title2.SetFont(f2)
38
39 txt = """\
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)
44 message1.SetFont(f1)
45
46 title3 = wx.StaticText(self, -1, 'Target Window')
47 title3.SetFont(f2)
48
49 txt = """\
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)
53 message2.SetFont(f1)
54
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
59
60 sizer.Add((0,0), 1)
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)
63 sizer.Add((0,0),1)
64 sizer.Add(Tile(buttonPanel, log, factor, target), 0, wx.ALIGN_CENTER)
65 sizer.Add((0,0),1)
66
67 buttonPanel.SetAutoLayout(1)
68 buttonPanel.SetSizer(sizer)
69 sizer.Fit(buttonPanel)
70
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)
80 self.SetAutoLayout(1)
81 self.SetSizer(sizer)
82
83
84
85 class Tile(wx.Panel):
86 """
87 This outer class is responsible for changing
88 its border color in response to certain mouse
89 events over its contained 'InnerTile'.
90 """
91 normal = wx.Colour(150,150,150)
92 active = wx.Colour(250,245,245)
93 hover = wx.Colour(210,220,210)
94
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)
98 self.log = log
99 sizer = wx.BoxSizer(wx.HORIZONTAL)
100 sizer.Add(self.tile, 1, wx.EXPAND | wx.ALL, borderWidth)
101 self.SetAutoLayout(1)
102 self.SetSizer(sizer)
103 self.Layout()
104 self.SetBackgroundColour(Tile.normal)
105 if active:
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)
112
113
114 def setHover(self, event):
115 self.SetBackgroundColour(Tile.hover)
116 self.Refresh()
117
118
119 def setActive(self, event):
120 self.SetBackgroundColour(Tile.active)
121 self.Refresh()
122
123
124 def setNormal(self, event):
125 self.SetBackgroundColour(Tile.normal)
126 self.Refresh()
127
128
129
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()
138
139 """
140 This inner panel changes its color in reaction to mouse
141 events over the 'thingToWatch'.
142 """
143 def __init__(self, parent, log, factor, thingToWatch=None, bgColor=None):
144 wx.Panel.__init__(self, parent, -1)
145 self.log=log
146 if bgColor:
147 self.SetBackgroundColour(bgColor)
148 if thingToWatch:
149 self.factor = factor
150 self.thingToWatch = thingToWatch
151 self.state = 0
152 self.toggleOnOff()
153 # Watch for the mouse click to enable/disable myself.
154 em.eventManager.Register(self.toggleOnOff, wx.EVT_LEFT_UP, self)
155
156
157 def toggleOnOff(self, event=None):
158 # Implement being on or off by registering and
159 # de-registering self.makeColor() from the event manager.
160 if self.state:
161 em.eventManager.DeregisterListener(self.makeColor)
162 else:
163 em.eventManager.Register(self.makeColor, wx.EVT_MOTION, self.thingToWatch)
164 self.state = 1 - self.state
165 self.resetColor()
166
167
168 def resetColor(self, event=None):
169 if self.state:
170 self.setColor(InnerTile.IDLE_COLOR)
171 else:
172 self.setColor(InnerTile.OFF_COLOR)
173
174
175 def setColor(self, color):
176 self.SetBackgroundColour(color)
177 self.Refresh()
178
179
180 def makeColor(self, mouseEvent):
181 self.makeColorFromTuple(mouseEvent.GetPositionTuple())
182
183
184 def makeColorFromTuple(self, (x, y)):
185 MAX = 180.0
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)))
192
193
194
195
196 #----------------------------------------------------------------------
197
198 def runTest(frame, nb, log):
199 win = TestPanel(nb, log)
200 return win
201
202 #----------------------------------------------------------------------
203
204
205
206 overview = """<html><body>
207 <h2>EventManager</h2>
208
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:
212
213 <p>
214 <ul>
215
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.)
219
220 <li> Makes it easy to disconnect and reconnect listeners. This
221 has the effect of reducing the need for case-based branching in
222 application code.
223
224 <li> Has an object-oriented API. Programmers register to get
225 events directly from the objects that generate them, instead of
226 using ID numbers.
227
228 </ul>
229
230 <h3>Usage</h3>
231
232 <p>The EventManager class has three public methods. First get a
233 reference to it:
234
235 <PRE>
236 from wxPython.lib.evtmgr import eventManager
237 </PRE>
238
239 <p>...and then invoke any of the following methods. These methods are
240 'safe'; duplicate registrations or de-registrations will have no
241 effect.
242
243 <p><b>Registering a listener:</b>
244
245 <PRE>
246 eventManager.Register(listener, event, event-source)
247 </PRE>
248
249
250 <p><b>De-registering by window:</b>
251
252 <PRE>
253 eventManager.DeregisterWindow(event-source)
254 </PRE>
255
256
257 <p><b>De-registering by listener:</b>
258
259 <PRE>
260 eventManager.DeregisterListener(listener)
261 </PRE>
262
263 <p><b>Simple Example:</b>
264
265 <PRE>
266 from wxPython.lib.evtmgr import eventManager
267
268 aButton = wxButton(somePanel, -1, 'Click me')
269 eventManager.Register(self.someMethod, EVT_BUTTON, aButton)
270 </PRE>
271
272 <p> See the demo code as well as the documentation in the source of
273 <tt>wxPython.lib.evtmgr</tt> for more details.
274
275
276 <p>
277 by Robb Shecter (robb@acm.org)
278 </body></html>
279 """
280
281
282
283 if __name__ == '__main__':
284 import sys,os
285 import run
286 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
287