Design Pattern Examples
Overview of object-oriented design patterns
HandlerChain_MessageWindow_Class.h
Go to the documentation of this file.
1
6
7#pragma once
8#ifndef __HANDLECHAIN_MESSAGEWINDOW_CLASS_H__
9#define __HANDLECHAIN_MESSAGEWINDOW_CLASS_H__
10
11#include <iostream>
12#include <map>
13#include <memory>
14#include <string>
15
16#include "helpers/formatstring.h"
17
18#include "HandlerChain_Class.h"
20
22{
23
31 {
32 private:
36 const int MINIMUM_WIDTH = 4;
40 const int MINIMUM_HEIGHT = 4;
41
42 public:
43 int Left;
44 int Top;
45 int Right;
46 int Bottom;
47
55 WindowRectangle(int x, int y, int width, int height)
56 {
57 if (width < MINIMUM_WIDTH)
58 {
59 width = MINIMUM_WIDTH;
60 }
61 if (height < MINIMUM_HEIGHT)
62 {
63 height = MINIMUM_HEIGHT;
64 }
65 Left = x;
66 Top = y;
67 Right = x + width;
68 Bottom = y + height;
69 }
70
77 {
78 bool isInside = false;
79
80 if (point.X >= Left && point.X < Right &&
81 point.Y >= Top && point.Y < Bottom)
82 {
83 isInside = true;
84 }
85
86 return isInside;
87 }
88
93 std::string ToString()
94 {
95 return Helpers::formatstring("x1=%2d, y1=%2d, x2=%2d, y2=%2d", Left, Top, Right, Bottom);
96 }
97 };
98
99
100
101 //========================================================================
102 //========================================================================
103 //========================================================================
104
105
106
118 {
119 public:
120 using shared_ptr_t = std::shared_ptr<MessageWindow>;
121
122 private:
123 // Size of QUIT region in the upper right corner of the region.
124 const int CLOSE_WIDTH = 2;
125 const int CLOSE_HEIGHT = 2;
126
130 using MessageHandler = bool (*)(MessageWindow* window, Message* message);
131
135 std::map<MessageType, MessageHandler> _messageHandlers;
136
141
145 std::string _title;
146
151
158
164
169
173 static int _nextWindowId;
174
175 public:
192 static MessageWindow::shared_ptr_t CreateWindow(std::string title, int x, int y, int width, int height, HandlerChain* handlerChain);
193
194
201 {
202 return _windowBox.PointInside(position);
203 }
204
205
214 {
215 return _closeBox.PointInside(position);
216 }
217
218
231 MessageWindow(int windowId, std::string title, int x, int y, int width, int height, HandlerChain* handlerChain)
232 : _windowId(windowId)
233 , _title(title)
234 , _windowBox(WindowRectangle(x, y, width, height))
236 , _selected(false)
237 , _handlerChain(handlerChain)
238 {
239 // Construct our lookup table for message handlers.
243 }
244
245
246 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
247 // The message handlers.
248 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
249 // To add a new message handler:
250 // - Add a new message type to the MessageTypes enumeration.
251 // - Add a new handler method here for the new message type.
252 // - Update MessageWindow constructor to add a mapping from the
253 // new message type to the new handler method.
254
262 static bool _HandleButtonDownMessage(MessageWindow* window, Message* message);
263
264
272 static bool _HandleButtonUpMessage(MessageWindow* window, Message* message);
273
274
282 static bool _HandleCloseMessage(MessageWindow* window, Message* message);
283
284
285 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
286 // Implementation of the IMessageHandler interface.
287 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
288
292 int ID()
293 {
294 return _windowId;
295 }
296
297
309 bool ProcessMessage(Message* message)
310 {
311 bool messageProcessed = false;
312
313 std::map<MessageType, MessageHandler>::const_iterator foundIter;
314 foundIter = _messageHandlers.find(message->MessageType);
315 if (foundIter != std::cend(_messageHandlers))
316 {
317 MessageHandler handler = foundIter->second;
318 messageProcessed = handler (this, message);
319 }
320
321 return messageProcessed;
322 }
323
324
329 std::string ToString()
330 {
331 return Helpers::formatstring("[id=%2d] \"%s\" (%s), selected=%s", ID(),
332 _title.c_str(), _windowBox.ToString().c_str(),
333 _selected ? "true" : "false");
334 }
335 };
336
337} // end namespace
338
339#endif //__HANDLECHAIN_MESSAGEWINDOW_CLASS_H__
Implementation of the HandlerChain class and declaration of the IMessageHandler interface used in the...
Implementation of the Message and MessagePosition structs used in the HandlerChain Pattern.
Represents a list of handlers that all implement the IMessageHandler interface. This list can be dyna...
Represents a rectangular region that can handle messages directed to that region.
WindowRectangle _closeBox
Position of the close window within the window box, although the coordinates are also global coordina...
static int _nextWindowId
Used for assigning a unique ID to each created window.
bool _PointInWindow(MessagePosition position)
Determine if the specified point is in this MessageWindow's region.
std::map< MessageType, MessageHandler > _messageHandlers
Maps a message type to a handler method of type MessageHandler.
bool ProcessMessage(Message *message)
Processes a message.
std::string ToString()
Convert this handler to a string.
HandlerChain * _handlerChain
The HandlerChain to which this window belongs (as an IMessageHandler object).
bool _selected
Whether this window has been selected (a button click occurred within the window).
bool(*)(MessageWindow *window, Message *message) MessageHandler
Alias for the function that handles the messages.
WindowRectangle _windowBox
Position of this window in global coordinates.
static bool _HandleButtonDownMessage(MessageWindow *window, Message *message)
Helper method to handle the ButtonDown message.
static MessageWindow::shared_ptr_t CreateWindow(std::string 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...
MessageWindow(int windowId, std::string title, int x, int y, int width, int height, HandlerChain *handlerChain)
Constructor.
static bool _HandleButtonUpMessage(MessageWindow *window, Message *message)
Helper method to handle the ButtonUp message.
bool _PointInCloseBox(MessagePosition position)
Determine if the specified point is in this MessageWindow's "close" region.
int ID()
Returns the ID of the message handler.
static bool _HandleCloseMessage(MessageWindow *window, Message *message)
Helper method to handle the Close message.
Represents a rectangular region, with upper left and lower right coordinates.
WindowRectangle(int x, int y, int width, int height)
Constructor.
std::string ToString()
Convert this rectangle to a string.
const int MINIMUM_WIDTH
Minimum width of a window (to accommodate a close box).
const int MINIMUM_HEIGHT
Minimum height of a window (to accommodate a close box).
bool PointInside(MessagePosition point)
Determine if the given point is in the rectangle.
The namespace containing all Design Pattern Examples implemented in C++.
@ ButtonUp
Take an action on the currently selected window.
@ ButtonDown
Selects a window based on position.
@ Close
Window is asked to close itself, generally sent by the window itself in response to a button up in a ...
std::string formatstring(const char *fmt,...)
Use the given string and arguments to return a buffer containing the formatted string....
Represents a handler in a chain of handlers. All objects that participate in the HandlerChain class m...
Represents a message sent to the windows. A message contains a type and a position.
enum MessageType MessageType
Value from the MessageType enumeration indicating the type of this message.
Position of the message in global coordinates (same scope of coordinates as windows)....