ScummVM API documentation
events.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef MM1_EVENTS_H
23 #define MM1_EVENTS_H
24 
25 #include "common/array.h"
26 #include "common/stack.h"
27 #include "graphics/screen.h"
28 #include "mm/mm1/messages.h"
29 #include "mm/mm1/utils/mouse.h"
30 
31 namespace MM {
32 namespace MM1 {
33 
34 #define FRAME_RATE 20
35 #define FRAME_DELAY (1000 / FRAME_RATE)
36 
37 class Events;
38 
45 struct Bounds {
46 private:
47  Common::Rect _bounds;
48  Common::Rect &_innerBounds;
49  int _borderSize = 0;
50 public:
51  const int16 &left;
52  const int16 &top;
53  const int16 &right;
54  const int16 &bottom;
55 public:
56  Bounds(Common::Rect &innerBounds);
57  operator const Common::Rect &() const { return _bounds; }
58  Bounds &operator=(const Common::Rect &r);
59  void setBorderSize(size_t borderSize);
60  size_t borderSize() const { return _borderSize; }
61  int16 width() const { return _bounds.width(); }
62  int16 height() const { return _bounds.height(); }
63 };
64 
68 class UIElement {
69  friend class Events;
70 private:
71  int _timeoutCtr = 0;
72 protected:
73  UIElement *_parent;
75  Common::Rect _innerBounds;
76  Bounds _bounds;
77  bool _needsRedraw = true;
78  Common::String _name;
79 protected:
80  Common::Rect getLineBounds(int line1, int line2) const {
81  return Common::Rect(0, line1 * 8, 320, (line2 + 1) * 8);
82  }
83 
87  void delaySeconds(uint seconds);
88 
92  void delayFrames(uint frames);
93 
97  bool isDelayActive() const {
98  return _timeoutCtr != 0;
99  }
100 
104  void cancelDelay() {
105  _timeoutCtr = 0;
106  }
107 
111  bool endDelay();
112 
116  virtual void timeout();
117 
118 private:
123  void drawElements();
124 
128  static UIElement *findViewGlobally(const Common::String &name);
129 public:
130  UIElement(const Common::String &name, UIElement *uiParent);
131  virtual ~UIElement() {}
132 
136  bool needsRedraw() const { return _needsRedraw; }
137 
141  void redraw();
142 
146  void focus();
147 
152  virtual void close();
153 
154  /*
155  * Returns true if the view is focused
156  */
157  bool isFocused() const;
158 
162  void replaceView(UIElement *ui, bool replaceAllViews = false);
163  void replaceView(const Common::String &name, bool replaceAllViews = false);
164 
168  void addView(UIElement *ui);
169  void addView(const Common::String &name);
170  void addView();
171  void open() { addView(); }
172 
176  int getRandomNumber(int minNumber, int maxNumber);
177  int getRandomNumber(int maxNumber);
178 
182  Common::String getName() const { return _name; }
183 
187  virtual void setBounds(const Common::Rect &r) {
188  _bounds = r;
189  }
190 
195  return _bounds;
196  }
197 
201  Graphics::ManagedSurface getSurface() const;
202 
206  virtual void clearSurface();
207 
211  virtual void draw();
212 
216  virtual bool tick();
217 
221  virtual UIElement *findView(const Common::String &name);
222 
226  #define MESSAGE(NAME) \
227  protected: \
228  virtual bool msg##NAME(const NAME##Message &e) { \
229  for (Common::Array<UIElement *>::iterator it = _children.begin(); \
230  it != _children.end(); ++it) { \
231  if ((*it)->msg##NAME(e)) return true; \
232  } \
233  return false; \
234  } \
235  public: \
236  bool send(const Common::String &viewName, const NAME##Message &msg) { \
237  UIElement *view = UIElement::findViewGlobally(viewName); \
238  assert(view); \
239  return view->msg##NAME(msg); \
240  } \
241  bool send(const NAME##Message &msg) { \
242  return send("Root", msg); \
243  } \
244 
245  MESSAGE(Focus);
246  MESSAGE(Unfocus);
247  MESSAGE(Keypress);
248  MESSAGE(MouseDown);
249  MESSAGE(MouseUp);
250  MESSAGE(Action);
251  MESSAGE(Game);
252  MESSAGE(Header);
253  MESSAGE(Info);
254  MESSAGE(DrawGraphic);
255  #undef MESSAGE
256 };
257 
258 class ViewsBase {
259 public:
260  ViewsBase() {}
261  virtual ~ViewsBase() {}
262 };
263 
267 class Events : public UIElement, public Mouse {
268 private:
269  Graphics::Screen *_screen = nullptr;
271  bool _enhancedMode;
272 protected:
276  void processEvent(Common::Event &ev);
277 
281  virtual bool shouldQuit() const = 0;
282 
286  #define MESSAGE(NAME) \
287  bool msg##NAME(const NAME##Message &e) override { \
288  return !_views.empty() ? focusedView()->msg##NAME(e) : false; \
289  }
290  MESSAGE(Action);
291  MESSAGE(Focus);
292  MESSAGE(Unfocus);
293  MESSAGE(Keypress);
294  MESSAGE(MouseDown);
295  MESSAGE(MouseUp);
296  MESSAGE(DrawGraphic);
297  #undef MESSAGE
298 public:
299  Events(bool enhancedMode);
300  virtual ~Events();
301 
305  void runGame();
306 
310  void replaceView(UIElement *ui, bool replaceAllViews = false);
311  void replaceView(const Common::String &name, bool replaceAllViews = false);
312 
316  void addView(UIElement *ui);
317  void addView(const Common::String &name);
318 
322  void clearViews();
323 
327  void popView();
328 
334  void redrawViews();
335 
340  return _views.empty() ? nullptr : _views.top();
341  }
342 
346  UIElement *priorView() const {
347  return _views.size() < 2 ? nullptr :
348  _views[_views.size() - 2];
349  }
350 
355  bool isPresent(const Common::String &name) const;
356 
360  bool isInCombat() const {
361  return isPresent("Combat");
362  }
363 
364  Graphics::Screen *getScreen() const {
365  return _screen;
366  }
367 
368  void drawElements() {
369  if (!_views.empty())
370  focusedView()->drawElements();
371  }
372 
376  void addKeypress(const Common::KeyCode kc);
377 
381  void addAction(KeybindingAction action);
382 
386  bool isKeypressPending() const;
387 
388  void draw() override {}
389 
390  bool tick() override {
391  return !_views.empty() ? focusedView()->tick() : false;
392  }
393 
397  void close() override {
398  focusedView()->close();
399  }
400 };
401 
402 extern Events *g_events;
403 
404 } // namespace MM1
405 } // namespace MM
406 
407 #endif
void draw() override
Definition: events.h:388
Definition: managed_surface.h:51
Definition: events.h:258
Definition: str.h:59
void cancelDelay()
Definition: events.h:104
Definition: array.h:52
UIElement * priorView() const
Definition: events.h:346
bool tick() override
Definition: events.h:390
Definition: rect.h:524
bool needsRedraw() const
Definition: events.h:136
Definition: screen.h:48
T width() const
Definition: rect.h:217
Definition: mouse.h:30
T height() const
Definition: rect.h:218
Definition: events.h:267
Definition: events.h:210
Definition: detection.h:27
UIElement * focusedView() const
Definition: events.h:339
bool isInCombat() const
Definition: events.h:360
void close() override
Definition: events.h:397
virtual void setBounds(const Common::Rect &r)
Definition: events.h:187
Common::Rect getBounds() const
Definition: events.h:194
Definition: events.h:68
Definition: events.h:45
Definition: stack.h:102
Common::String getName() const
Definition: events.h:182
bool isDelayActive() const
Definition: events.h:97