Design Pattern Examples
Overview of object-oriented design patterns
handlerchain_messagewindow_class.py
Go to the documentation of this file.
10
11from .handlerchain_message_class import MessageType, Message, MessagePosition
12from .handlerchain_class import IMessageHandler, HandlerChain
13
14
18
19 MINIMUM_WIDTH = 4
20
21 MINIMUM_HEIGHT = 4
22
23 # <summary>
24 # Constructor.
25 # </summary>
26 # @param x">X coordinate of upper left corner.
27 # @param y">Y coordinate of upper left corner.
28 # @param width">Width of rectangle.
29 # @param height">Height of rectangle.
30 def __init__(self, x : int, y : int, width : int, height : int) -> None:
31 width = max([width, WindowRectangle.MINIMUM_WIDTH])
32 height = max([height, WindowRectangle.MINIMUM_HEIGHT])
33 self.Left = x;
34 self.Top = y;
35 self.Right = x + width;
36 self.Bottom = y + height;
37
38
46
47
48
54 def PointInside(self, point : MessagePosition) -> bool:
55 isInside = False
56
57 if point.X >= self.Left and point.X < self.Right and \
58 point.Y >= self.Top and point.Y < self.Bottom:
59 isInside = True
60
61 return isInside;
62
63
64
68 def ToString(self) -> str:
69 return "x1={0:2}, y1={1:2}, x2={2:2}, y2={3:2}".format(
70 self.Left, self.Top, self.Right, self.Bottom)
71
72
73#========================================================================
74#========================================================================
75#========================================================================
76
77
86
87
88 CLOSE_WIDTH = 2
89
90 CLOSE_HEIGHT = 2
91
92
93
99 def _PointInWindow(self, position : MessagePosition) -> bool:
100 return self._windowBox.PointInside(position)
101
102
103
111 def _PointInCloseBox(self, position : MessagePosition):
112 return self._closeBox.PointInside(position)
113
114
115
132 def __init__(self, windowId : int, title : str, x : int, y : int, width : int, height : int, handlerChain : HandlerChain) -> None:
133 self._windowId = windowId
134 self._title = title
135 self._windowBox = WindowRectangle(x, y, width, height)
136 self._closeBox = WindowRectangle(self._windowBox.Right - MessageWindow.CLOSE_WIDTH,
137 self._windowBox.Top,
138 MessageWindow.CLOSE_WIDTH,
139 MessageWindow.CLOSE_HEIGHT)
140 self._handlerChain = handlerChain
141 self._selected = False
142 # Construct our lookup table for message handlers.
144 MessageType.ButtonDown : MessageWindowHandlers._HandleButtonDownMessage,
145 MessageType.ButtonUp : MessageWindowHandlers._HandleButtonUpMessage,
146 MessageType.Close : MessageWindowHandlers._HandleCloseMessage
147 }
148
149
168
169
170 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
171 # Implementation of the IMessageHandler interface.
172 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
173
174
175 @property
176 def ID(self) -> int:
177 return self._windowId;
178
179
180
191 def ProcessMessage(self, message : Message) -> bool:
192 messageProcessed = False
193 if message.MessageType in self._messageHandlers:
194 handler = self._messageHandlers[message.MessageType]
195 messageProcessed = handler(self, message)
196 return messageProcessed;
197
198
199
203 def ToString(self) -> str:
204 return "[id={0:2}] \"{1}\" ({2}), selected={3}".format(
205 self.IDID, self._title, self._windowBox.ToString(), self._selected)
206
207
208
211
212
213
219
220 _nextWindowId = 1 # type: int
221
222
250 def CreateWindow(title : str, x : int, y : int, width : int, height : int, handlerChain : HandlerChain) -> MessageWindow:
251 window = MessageWindow(MessageWindowFactory._nextWindowId, title, x, y,
252 width, height, handlerChain)
253 MessageWindowFactory._nextWindowId += 1
254
255 if handlerChain:
256 handlerChain.AddHandler(window)
257 return window
258
259
260
263
264
265
276 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
277 # The message handlers.
278 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
279 # To add a new message handler:
280 # - Add a new message type to the MessageTypes enumeration.
281 # - Add a new handler method here for the new message type.
282 # - Update MessageWindow constructor to add a mapping from the
283 # new message type to the new handler method.
284
285
294 def _HandleButtonDownMessage(window : MessageWindow, message : Message) -> bool:
295 # Note: we are not saying we handled the message here since
296 # we want other windows to get the button down message as
297 # well so they can select or deselect themselves.
298 messageProcessed = False
299
300 if window._PointInWindow(message.Position):
301 if not window._selected:
302 window._selected = True
303 print(" --> Button Down in \"{0}\", window selected".format(window._title))
304 else:
305 if window._selected:
306 window._selected = False
307 print(" --> Button Down not in \"{0}\", window deselected".format(window._title))
308
309 return messageProcessed
310
311
312
321 def _HandleButtonUpMessage(window : MessageWindow, message : Message) -> bool:
322 messageProcessed = False
323 if window._selected:
324 if window._PointInWindow(message.Position):
325 # The Button Up is in the same window as Button Down so
326 # we will handle this message and let no other window see
327 # it.
328 messageProcessed = True
329 if window._PointInCloseBox(message.Position):
330 print(" --> Button Up in \"{0}\" close box, sending Close message".format(window._title))
331 window._handlerChain.SendMessage(Message(MessageType.Close, message.Position))
332 else:
333 print(" --> Button Up in \"{0}\", no further action taken".format(window._title))
334
335 return messageProcessed
336
337
338
347 def _HandleCloseMessage(window : MessageWindow, message : Message) -> bool:
348 messageProcessed = False
349 if window._selected:
350 print(" --> Close in \"{0}\", removing window from handler chain".format(window._title))
351
352 # This window is being closed. We are handling the message
353 # so no other window needs to see it.
354 messageProcessed = True
355 window._handlerChain.RemoveHandler(window)
356 window._selected = False
357 else:
358 print(" --> Close seen in \"{0}\" but this window is not selected, ignoring".format(window._title))
359
360 return messageProcessed
361
int ID(self)
Property getter for the ID of the window: value = o.ID.
MessageWindow CreateWindow(str title, int x, int y, int width, int height, HandlerChain handlerChain)
Creates an instance of the MessageWindow class with the specified attributes and adds the new instanc...
Contains the various message handlers that operate on MessageWindow class instances.
bool _HandleButtonDownMessage(MessageWindow window, Message message)
Helper method to handle the ButtonDown message.
bool _HandleCloseMessage(MessageWindow window, Message message)
Helper method to handle the Close message.
bool _HandleButtonUpMessage(MessageWindow window, Message message)
Helper method to handle the ButtonUp message.
Represents a rectangular region that can handle messages directed to that region.
bool _PointInWindow(self, MessagePosition position)
Determine if the specified point is in this MessageWindow's region.
_selected
Whether this window has been selected (a button click occurred within the window).
def _PointInCloseBox(self, MessagePosition position)
Determine if the specified point is in this MessageWindow's "close" region.
_closeBox
Position of the close window within the window box, although the coordinates are also global coordina...
int ID(self)
Property getter for the ID of the message handler: value = o.ID
None __init__(self, int windowId, str title, int x, int y, int width, int height, HandlerChain handlerChain)
Constructor.
_handlerChain
The HandlerChain to which this window belongs (as an IMessageHandler object).
Represents a rectangular region, with upper left and lower right coordinates.
bool PointInside(self, MessagePosition point)
Determine if the given point is in the rectangle.