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 ULTIMA0_EVENTS_H
23 #define ULTIMA0_EVENTS_H
24 
25 #include "common/array.h"
26 #include "common/stack.h"
27 #include "graphics/screen.h"
28 #include "ultima/ultima0/messages.h"
29 #include "ultima/ultima0/gfx/gfx_surface.h"
30 
31 namespace Ultima {
32 namespace Ultima0 {
33 
34 #define FRAME_RATE 20
35 #define FRAME_DELAY (1000 / FRAME_RATE)
36 
37 class Events;
38 
44 struct Bounds {
45 private:
46  Common::Rect _bounds;
47  Common::Rect &_innerBounds;
48  int _borderSize = 0;
49 public:
50  const int16 &left;
51  const int16 &top;
52  const int16 &right;
53  const int16 &bottom;
54 public:
55  Bounds(Common::Rect &innerBounds);
56  operator const Common::Rect &() const {
57  return _bounds;
58  }
59  Bounds &operator=(const Common::Rect &r);
60  void setBorderSize(size_t borderSize);
61  size_t borderSize() const {
62  return _borderSize;
63  }
64  int16 width() const {
65  return _bounds.width();
66  }
67  int16 height() const {
68  return _bounds.height();
69  }
70 };
71 
75 class UIElement {
76  friend class Events;
77 private:
78  int _timeoutCtr = 0;
79 protected:
80  UIElement *_parent;
82  Common::Rect _innerBounds;
83  Bounds _bounds;
84  bool _needsRedraw = true;
85  Common::String _name;
86 protected:
90  void delaySeconds(uint seconds);
91 
95  void delayFrames(uint frames);
96 
100  bool isDelayActive() const {
101  return _timeoutCtr != 0;
102  }
103 
107  void cancelDelay() {
108  _timeoutCtr = 0;
109  }
110 
114  virtual void timeout();
115 
116 private:
121  void drawElements();
122 
126  static UIElement *findViewGlobally(const Common::String &name);
127 public:
128  UIElement(const Common::String &name, UIElement *uiParent);
129  UIElement(const Common::String &name);
130  virtual ~UIElement() {
131  }
132 
136  bool needsRedraw() const {
137  return _needsRedraw;
138  }
139 
143  void redraw();
144 
148  void focus();
149 
154  virtual void close();
155 
156  /*
157  * Returns true if the view is focused
158  */
159  bool isFocused() const;
160 
165  return _name;
166  }
167 
171  void replaceView(UIElement *ui, bool replaceAllViews = false);
172  void replaceView(const Common::String &name, bool replaceAllViews = false);
173 
177  void addView(UIElement *ui);
178  void addView(const Common::String &name);
179  void addView();
180  void open() {
181  addView();
182  }
183 
187  int getRandomNumber(int minNumber, int maxNumber);
188  int getRandomNumber(int maxNumber);
189 
193  virtual void setBounds(const Common::Rect &r) {
194  _bounds = r;
195  }
196 
201  return _bounds;
202  }
203 
207  Gfx::GfxSurface getSurface() const;
208 
212  virtual void clearSurface();
213 
217  virtual void draw();
218 
222  virtual bool tick();
223 
227  virtual UIElement *findView(const Common::String &name);
228 
232  // Mouse move only has a minimal implementation for performance reasons
233 protected:
234  virtual bool msgMouseMove(const MouseMoveMessage &msg) {
235  return false;
236  }
237 public:
238  bool send(const MouseMoveMessage &msg) {
239  return msgMouseMove(msg);
240  }
241 
242 #define MESSAGE(NAME) \
243  protected: \
244  virtual bool msg##NAME(const NAME##Message &e) { \
245  for (Common::Array<UIElement *>::iterator it = _children.begin(); \
246  it != _children.end(); ++it) { \
247  if ((*it)->msg##NAME(e)) return true; \
248  } \
249  return false; \
250  } \
251  public: \
252  bool send(const Common::String &viewName, const NAME##Message &msg) { \
253  UIElement *view = UIElement::findViewGlobally(viewName); \
254  assert(view); \
255  return view->msg##NAME(msg); \
256  } \
257  bool send(const NAME##Message &msg) { \
258  return msg##NAME(msg); \
259  } \
260 
261  MESSAGE(Focus);
262  MESSAGE(Unfocus);
263  MESSAGE(MouseEnter);
264  MESSAGE(MouseLeave);
265  MESSAGE(Keypress);
266  MESSAGE(MouseDown);
267  MESSAGE(MouseUp);
268  MESSAGE(Action);
269  MESSAGE(Game);
270  MESSAGE(Value);
271 #undef MESSAGE
272 };
273 
281 class Events : public UIElement {
282 private:
283  Graphics::Screen *_screen = nullptr;
285 protected:
289  void processEvent(Common::Event &ev);
290 
294  virtual bool shouldQuit() const = 0;
295 
299 #define MESSAGE(NAME) \
300  bool msg##NAME(const NAME##Message &e) override { \
301  return !_views.empty() ? focusedView()->msg##NAME(e) : false; \
302  }
303  MESSAGE(Action);
304  MESSAGE(Focus);
305  MESSAGE(Unfocus);
306  MESSAGE(MouseEnter);
307  MESSAGE(MouseLeave);
308  MESSAGE(Keypress);
309  MESSAGE(MouseDown);
310  MESSAGE(MouseUp);
311  MESSAGE(MouseMove);
312 #undef MESSAGE
313 public:
314  Events();
315  virtual ~Events();
316 
320  void runGame();
321 
325  void replaceView(UIElement *ui, bool replaceAllViews = false);
326  void replaceView(const Common::String &name, bool replaceAllViews = false);
327 
331  void addView(UIElement *ui);
332  void addView(const Common::String &name);
333 
337  void clearViews();
338 
342  void popView();
343 
349  void redrawViews();
350 
355  return _views.empty() ? nullptr : _views.top();
356  }
357 
361  UIElement *priorView() const {
362  return _views.size() < 2 ? nullptr :
363  _views[_views.size() - 2];
364  }
365 
370  bool isPresent(const Common::String &name) const;
371 
375  bool isInCombat() const {
376  return isPresent("Combat");
377  }
378 
383  return _screen;
384  }
385 
389  void drawElements() {
390  if (!_views.empty())
391  focusedView()->drawElements();
392  }
393 
397  void addKeypress(const Common::KeyCode kc);
398 
402  void draw() override {
403  }
404 
408  bool tick() override {
409  return !_views.empty() ? focusedView()->tick() : false;
410  }
411 
415  void close() override {
416  focusedView()->close();
417  }
418 };
419 
420 extern Events *g_events;
421 
422 } // namespace Ultima0
423 } // namespace Ultima
424 
425 #endif
void cancelDelay()
Definition: events.h:107
void close() override
Definition: events.h:415
Graphics::Screen * getScreen() const
Definition: events.h:382
bool needsRedraw() const
Definition: events.h:136
Common::Rect getBounds() const
Definition: events.h:200
Definition: str.h:59
Common::String getName() const
Definition: events.h:164
Definition: array.h:52
bool isDelayActive() const
Definition: events.h:100
UIElement * priorView() const
Definition: events.h:361
UIElement * focusedView() const
Definition: events.h:354
Definition: rect.h:524
Definition: events.h:281
bool isInCombat() const
Definition: events.h:375
Definition: screen.h:48
T width() const
Definition: rect.h:217
Definition: messages.h:58
void draw() override
Definition: events.h:402
Definition: events.h:44
Definition: detection.h:27
T height() const
Definition: rect.h:218
Definition: events.h:75
Definition: lobject.h:59
void drawElements()
Definition: events.h:389
Definition: events.h:210
bool tick() override
Definition: events.h:408
virtual void setBounds(const Common::Rect &r)
Definition: events.h:193
Definition: stack.h:102
Definition: gfx_surface.h:33
virtual bool msgMouseMove(const MouseMoveMessage &msg)
Definition: events.h:234