]> git.saurik.com Git - wxWidgets.git/blame - wxPython/demo/EventManager.py
merge from 2.8 branch
[wxWidgets.git] / wxPython / demo / EventManager.py
CommitLineData
1e4a197e
RD
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
8fa876ca
RD
12import wx
13import wx.lib.evtmgr as em
1e4a197e
RD
14
15#----------------------------------------------------------------------
16
8fa876ca 17class TestPanel(wx.Panel):
1e4a197e 18 def __init__(self, parent, log):
8fa876ca 19 wx.Panel.__init__(self, parent, -1)
1e4a197e
RD
20 self.log = log
21
22 fsize = self.GetFont().GetPointSize()
8fa876ca
RD
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)
1e4a197e 26
8fa876ca 27 title1 = wx.StaticText(self, -1, 'EventManager')
1e4a197e
RD
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."""
8fa876ca 33 message0 = wx.StaticText(self, -1, txt)
1e4a197e
RD
34 message0.SetFont(f1)
35
8fa876ca 36 title2 = wx.StaticText(self, -1, 'Event Listeners')
1e4a197e
RD
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."""
8fa876ca 43 message1 = wx.StaticText(self, -1, txt)
1e4a197e
RD
44 message1.SetFont(f1)
45
8fa876ca 46 title3 = wx.StaticText(self, -1, 'Target Window')
1e4a197e
RD
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."""
8fa876ca 52 message2 = wx.StaticText(self, -1, txt)
1e4a197e
RD
53 message2.SetFont(f1)
54
372bde9b
RD
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)
1e4a197e
RD
58 target = targetPanel.tile
59
fd3f2efe 60 sizer.Add((0,0), 1)
1e4a197e 61 for factor in [0.2, 0.3, 0.4, 0.5, 0.6, 0.7]:
372bde9b 62 sizer.Add(Tile(buttonPanel, log, factor-0.05, target), 0, wx.ALIGN_CENTER)
fd3f2efe 63 sizer.Add((0,0),1)
372bde9b 64 sizer.Add(Tile(buttonPanel, log, factor, target), 0, wx.ALIGN_CENTER)
fd3f2efe 65 sizer.Add((0,0),1)
1e4a197e 66
1e4a197e
RD
67 buttonPanel.SetSizer(sizer)
68 sizer.Fit(buttonPanel)
69
8fa876ca
RD
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)
095315e2 75 sizer.Add(buttonPanel, 0, wx.EXPAND | wx.ALL, 16)
8fa876ca
RD
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)
1e4a197e
RD
79 self.SetSizer(sizer)
80
81
82
78a32590 83class Tile(wx.Window):
1e4a197e
RD
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 """
8fa876ca
RD
89 normal = wx.Colour(150,150,150)
90 active = wx.Colour(250,245,245)
91 hover = wx.Colour(210,220,210)
1e4a197e
RD
92
93 def __init__(self, parent, log, factor=1, thingToWatch=None, bgColor=None, active=1, size=(38,38), borderWidth=3):
78a32590 94 wx.Window.__init__(self, parent, -1, size=size, style=wx.CLIP_CHILDREN)
1e4a197e
RD
95 self.tile = InnerTile(self, log, factor, thingToWatch, bgColor)
96 self.log = log
8fa876ca
RD
97 sizer = wx.BoxSizer(wx.HORIZONTAL)
98 sizer.Add(self.tile, 1, wx.EXPAND | wx.ALL, borderWidth)
1e4a197e
RD
99 self.SetSizer(sizer)
100 self.Layout()
78a32590 101 em.eventManager.Register(self.doLayout, wx.EVT_SIZE, self)
1e4a197e
RD
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.
8fa876ca
RD
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)
1e4a197e
RD
110
111
78a32590
RD
112 def doLayout(self, event):
113 self.Layout()
114
115
1e4a197e
RD
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
78a32590 132class InnerTile(wx.Window):
8fa876ca
RD
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)
1e4a197e
RD
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):
78a32590 146 wx.Window.__init__(self, parent, -1)
095315e2 147 self.SetMinSize((20,20))
1e4a197e
RD
148 self.log=log
149 if bgColor:
150 self.SetBackgroundColour(bgColor)
151 if thingToWatch:
152 self.factor = factor
153 self.thingToWatch = thingToWatch
154 self.state = 0
155 self.toggleOnOff()
156 # Watch for the mouse click to enable/disable myself.
8fa876ca 157 em.eventManager.Register(self.toggleOnOff, wx.EVT_LEFT_UP, self)
1e4a197e
RD
158
159
160 def toggleOnOff(self, event=None):
161 # Implement being on or off by registering and
162 # de-registering self.makeColor() from the event manager.
163 if self.state:
8fa876ca 164 em.eventManager.DeregisterListener(self.makeColor)
1e4a197e 165 else:
8fa876ca 166 em.eventManager.Register(self.makeColor, wx.EVT_MOTION, self.thingToWatch)
1e4a197e
RD
167 self.state = 1 - self.state
168 self.resetColor()
169
170
171 def resetColor(self, event=None):
172 if self.state:
173 self.setColor(InnerTile.IDLE_COLOR)
174 else:
175 self.setColor(InnerTile.OFF_COLOR)
176
177
178 def setColor(self, color):
179 self.SetBackgroundColour(color)
180 self.Refresh()
181
182
183 def makeColor(self, mouseEvent):
184 self.makeColorFromTuple(mouseEvent.GetPositionTuple())
185
186
187 def makeColorFromTuple(self, (x, y)):
188 MAX = 180.0
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)
8fa876ca 194 self.setColor(wx.Colour(int(r), int(g), int(b)))
1e4a197e
RD
195
196
197
198
199#----------------------------------------------------------------------
200
201def runTest(frame, nb, log):
202 win = TestPanel(nb, log)
203 return win
204
205#----------------------------------------------------------------------
206
207
208
209overview = """<html><body>
210<h2>EventManager</h2>
211
212<p> The goal of the EventManager is to make wxWindows events more
213'Pythonic' (ie. object-oriented) and easier to work with, without
214impacting performance. It offers these features:
215
216<p>
217<ul>
218
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.)
222
223 <li> Makes it easy to disconnect and reconnect listeners. This
224 has the effect of reducing the need for case-based branching in
225 application code.
226
227 <li> Has an object-oriented API. Programmers register to get
228 events directly from the objects that generate them, instead of
229 using ID numbers.
230
231</ul>
232
233<h3>Usage</h3>
234
235<p>The EventManager class has three public methods. First get a
236reference to it:
237
238<PRE>
239 from wxPython.lib.evtmgr import eventManager
240</PRE>
241
242<p>...and then invoke any of the following methods. These methods are
243'safe'; duplicate registrations or de-registrations will have no
244effect.
245
246<p><b>Registering a listener:</b>
247
248<PRE>
249 eventManager.Register(listener, event, event-source)
250</PRE>
251
252
253<p><b>De-registering by window:</b>
254
255<PRE>
256 eventManager.DeregisterWindow(event-source)
257</PRE>
258
259
260<p><b>De-registering by listener:</b>
261
262<PRE>
263 eventManager.DeregisterListener(listener)
264</PRE>
265
266<p><b>Simple Example:</b>
267
268<PRE>
269 from wxPython.lib.evtmgr import eventManager
270
271 aButton = wxButton(somePanel, -1, 'Click me')
272 eventManager.Register(self.someMethod, EVT_BUTTON, aButton)
273</PRE>
274
275<p> See the demo code as well as the documentation in the source of
276<tt>wxPython.lib.evtmgr</tt> for more details.
277
278
279<p>
280by Robb Shecter (robb@acm.org)
281</body></html>
282"""
283
284
285
286if __name__ == '__main__':
287 import sys,os
288 import run
8eca4fef 289 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
1e4a197e 290