]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/EventManager.py
Some little demo tweaks
[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.SetSizer(sizer)
68 sizer.Fit(buttonPanel)
69
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)
79 self.SetSizer(sizer)
80
81
82
83 class Tile(wx.Window):
84 """
85 This outer class is responsible for changing
86 its border color in response to certain mouse
87 events over its contained 'InnerTile'.
88 """
89 normal = wx.Colour(150,150,150)
90 active = wx.Colour(250,245,245)
91 hover = wx.Colour(210,220,210)
92
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)
96 self.log = log
97 sizer = wx.BoxSizer(wx.HORIZONTAL)
98 sizer.Add(self.tile, 1, wx.EXPAND | wx.ALL, borderWidth)
99 self.SetSizer(sizer)
100 self.Layout()
101 em.eventManager.Register(self.doLayout, wx.EVT_SIZE, self)
102 self.SetBackgroundColour(Tile.normal)
103 if active:
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)
110
111
112 def doLayout(self, event):
113 self.Layout()
114
115
116 def setHover(self, event):
117 self.SetBackgroundColour(Tile.hover)
118 self.Refresh()
119
120
121 def setActive(self, event):
122 self.SetBackgroundColour(Tile.active)
123 self.Refresh()
124
125
126 def setNormal(self, event):
127 self.SetBackgroundColour(Tile.normal)
128 self.Refresh()
129
130
131
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()
140
141 """
142 This inner panel changes its color in reaction to mouse
143 events over the 'thingToWatch'.
144 """
145 def __init__(self, parent, log, factor, thingToWatch=None, bgColor=None):
146 wx.Window.__init__(self, parent, -1)
147 self.log=log
148 if bgColor:
149 self.SetBackgroundColour(bgColor)
150 if thingToWatch:
151 self.factor = factor
152 self.thingToWatch = thingToWatch
153 self.state = 0
154 self.toggleOnOff()
155 # Watch for the mouse click to enable/disable myself.
156 em.eventManager.Register(self.toggleOnOff, wx.EVT_LEFT_UP, self)
157
158
159 def toggleOnOff(self, event=None):
160 # Implement being on or off by registering and
161 # de-registering self.makeColor() from the event manager.
162 if self.state:
163 em.eventManager.DeregisterListener(self.makeColor)
164 else:
165 em.eventManager.Register(self.makeColor, wx.EVT_MOTION, self.thingToWatch)
166 self.state = 1 - self.state
167 self.resetColor()
168
169
170 def resetColor(self, event=None):
171 if self.state:
172 self.setColor(InnerTile.IDLE_COLOR)
173 else:
174 self.setColor(InnerTile.OFF_COLOR)
175
176
177 def setColor(self, color):
178 self.SetBackgroundColour(color)
179 self.Refresh()
180
181
182 def makeColor(self, mouseEvent):
183 self.makeColorFromTuple(mouseEvent.GetPositionTuple())
184
185
186 def makeColorFromTuple(self, (x, y)):
187 MAX = 180.0
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)))
194
195
196
197
198 #----------------------------------------------------------------------
199
200 def runTest(frame, nb, log):
201 win = TestPanel(nb, log)
202 return win
203
204 #----------------------------------------------------------------------
205
206
207
208 overview = """<html><body>
209 <h2>EventManager</h2>
210
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:
214
215 <p>
216 <ul>
217
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.)
221
222 <li> Makes it easy to disconnect and reconnect listeners. This
223 has the effect of reducing the need for case-based branching in
224 application code.
225
226 <li> Has an object-oriented API. Programmers register to get
227 events directly from the objects that generate them, instead of
228 using ID numbers.
229
230 </ul>
231
232 <h3>Usage</h3>
233
234 <p>The EventManager class has three public methods. First get a
235 reference to it:
236
237 <PRE>
238 from wxPython.lib.evtmgr import eventManager
239 </PRE>
240
241 <p>...and then invoke any of the following methods. These methods are
242 'safe'; duplicate registrations or de-registrations will have no
243 effect.
244
245 <p><b>Registering a listener:</b>
246
247 <PRE>
248 eventManager.Register(listener, event, event-source)
249 </PRE>
250
251
252 <p><b>De-registering by window:</b>
253
254 <PRE>
255 eventManager.DeregisterWindow(event-source)
256 </PRE>
257
258
259 <p><b>De-registering by listener:</b>
260
261 <PRE>
262 eventManager.DeregisterListener(listener)
263 </PRE>
264
265 <p><b>Simple Example:</b>
266
267 <PRE>
268 from wxPython.lib.evtmgr import eventManager
269
270 aButton = wxButton(somePanel, -1, 'Click me')
271 eventManager.Register(self.someMethod, EVT_BUTTON, aButton)
272 </PRE>
273
274 <p> See the demo code as well as the documentation in the source of
275 <tt>wxPython.lib.evtmgr</tt> for more details.
276
277
278 <p>
279 by Robb Shecter (robb@acm.org)
280 </body></html>
281 """
282
283
284
285 if __name__ == '__main__':
286 import sys,os
287 import run
288 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
289