ScummVM API documentation
gump.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 ULTIMA8_GUMPS_GUMP_H
23 #define ULTIMA8_GUMPS_GUMP_H
24 
25 #include "common/rect.h"
26 #include "ultima/ultima8/gfx/frame_id.h"
27 #include "ultima/ultima8/kernel/object.h"
28 #include "ultima/ultima8/misc/classtype.h"
29 
30 namespace Ultima {
31 namespace Ultima8 {
32 
33 class RenderSurface;
34 class Shape;
35 class Item;
36 class GumpNotifyProcess;
37 
38 class Gump;
39 typedef bool (*FindGumpPredicate)(const Gump *g);
40 template<class T> inline bool IsOfType(const Gump *g) { return dynamic_cast<const T*>(g) != nullptr; }
41 
46 class Gump : public Object {
47 protected:
48  uint16 _owner; // Owner item
49  Gump *_parent; // Parent gump
50  int32 _x, _y; // Gump's position in parent.
51  // Always the upper left corner!
52 
53  Common::Rect32 _dims; // The dimensions/coord space of the gump
54  uint32 _flags; // Gump flags
55  int32 _layer; // gump ordering layer
56 
57  int32 _index; // 'Index'
58 
59  const Shape *_shape; // The gumps shape (always painted at 0,0)
60  uint32 _frameNum;
61 
64  Common::List<Gump *> _children; // List of all gumps
65  Gump *_focusChild; // The child that has focus
66 
67  uint16 _notifier; // Process to notify when we're closing
68  uint32 _processResult; // Result for the notifier process
69 
70 public:
71  ENABLE_RUNTIME_CLASSTYPE()
72  Gump();
73  Gump(int x, int y, int width, int height, uint16 owner = 0,
74  uint32 flags = 0, int32 layer = LAYER_NORMAL);
75  ~Gump() override;
76 
77 public:
78 
79  virtual void CreateNotifier();
80  void SetNotifyProcess(GumpNotifyProcess *proc);
81  GumpNotifyProcess *GetNotifyProcess();
82  inline uint32 GetResult() {
83  return _processResult;
84  }
85  void SetResult(uint32 res) {
86  _processResult = res;
87  }
88 
90  inline void SetShape(const Shape *shape, uint32 frameNum) {
91  _shape = shape;
92  _frameNum = frameNum;
93  }
94 
95  void SetShape(FrameID frame, bool adjustsize = false);
96 
98  void UpdateDimsFromShape();
99 
101  inline void Set_frameNum(uint32 frameNum) {
102  _frameNum = frameNum;
103  }
104 
109  virtual void InitGump(Gump *newparent, bool take_focus = true);
110 
115  virtual Gump *FindGump(FindGumpPredicate predicate, bool recursive = true);
116 
121  template<class T> Gump *FindGump(bool recursive = true) {
122  return FindGump(&IsOfType<T>, recursive);
123  }
124 
126  template<int T> static bool FindByIndex(const Gump *g) { return g->GetIndex() == T; }
127 
130  virtual Gump *FindGump(int mx, int my);
131 
136  virtual bool GetMouseCursor(int32 mx, int32 my, Shape &shape, int32 &frame);
137 
138  // Notify gumps the render surface changed.
139  virtual void RenderSurfaceChanged();
140 
142  virtual void run();
143 
147  virtual void CloseItemDependents();
148 
151  // \param surf The RenderSurface to paint to
152  // \param lerp_factor The lerp_factor to paint at (0-256)
153  // \param scaled Set if the gump is being drawn scaled.
154  virtual void Paint(RenderSurface *surf, int32 lerp_factor, bool scaled);
155 
158  // \param surf The RenderSurface to paint to
159  // \param lerp_factor The lerp_factor to paint at (0-256)
160  // \param scalex Fixed point scaling factor for x coord
161  // \param scaley Fixed point scaling factor for y coord
162  virtual void PaintCompositing(RenderSurface *surf, int32 lerp_factor, int32 scalex, int32 scaley);
163 
164 protected:
165 
167  // \param surf The RenderSurface to paint to
168  // \param lerp_factor The lerp_factor to paint at (0-256)
169  // \param scaled Set if the gump is being drawn scaled.
170  virtual void PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled);
171 
173  // \param surf The RenderSurface to paint to
174  // \param lerp_factor The lerp_factor to paint at (0-256)
175  // \param scaled Set if the gump is being drawn scaled.
176  virtual void PaintChildren(RenderSurface *surf, int32 lerp_factor, bool scaled);
177 
179  // \param surf The RenderSurface to paint to
180  // \param lerp_factor The lerp_factor to paint at (0-256)
181  // \param scalex Fixed point scaling factor for x coord
182  // \param scaley Fixed point scaling factor for y coord
183  virtual void PaintComposited(RenderSurface *surf, int32 lerp_factor, int32 scalex, int32 scaley);
184 
185  static inline int32 ScaleCoord(int32 c, int32 factor) {
186  return ((c * factor) + (1 << 15)) >> 16;
187  }
188  static inline int32 UnscaleCoord(int32 c, int32 factor) {
189  return (c << 16) / factor;
190  }
191 
192 public:
193 
196  virtual void Close(bool no_del = false);
197 
199  bool IsClosing() const {
200  return (_flags & FLAG_CLOSING) != 0;
201  }
202 
204  virtual void Move(int32 x, int32 y) {
205  _x = x;
206  _y = y;
207  }
208 
210  virtual void MoveRelative(int x, int y) {
211  _x += x;
212  _y += y;
213  }
214 
215  void getLocation(int32 &x, int32 &y) const {
216  x = _x;
217  y = _y;
218  }
219 
220  enum Position {
221  CENTER = 1,
222  TOP_LEFT = 2,
223  TOP_RIGHT = 3,
224  BOTTOM_LEFT = 4,
225  BOTTOM_RIGHT = 5,
226  TOP_CENTER = 6,
227  BOTTOM_CENTER = 7,
228  LEFT_CENTER = 8,
229  RIGHT_CENTER = 9
230  };
231 
233  // \param pos the postition on the parent gump
234  // \param xoffset an offset from the position on the x-axis
235  // \param yoffset an offset from the position on the y-axis
236  virtual void setRelativePosition(Position pos, int xoffset = 0, int yoffset = 0);
237 
238  //
239  // Points and Coords
240  //
241 
243  const Common::Rect32 &getDims() const {
244  return _dims;
245  }
246 
248  void setDims(const Common::Rect32 &d) {
249  _dims = d;
250  }
251 
253  virtual bool PointOnGump(int mx, int my);
254 
255  enum PointRoundDir {
256  ROUND_TOPLEFT = 0,
257  ROUND_BOTTOMRIGHT = 1
258  };
259  enum RectRoundDir {
260  ROUND_INSIDE,
261  ROUND_OUTSIDE
262  };
263 
265  virtual void ScreenSpaceToGump(int32 &sx, int32 &sy,
266  PointRoundDir r = ROUND_TOPLEFT);
267 
269  virtual void GumpToScreenSpace(int32 &gx, int32 &gy,
270  PointRoundDir r = ROUND_TOPLEFT);
271 
273  virtual void ParentToGump(int32 &px, int32 &py,
274  PointRoundDir r = ROUND_TOPLEFT);
275 
277  virtual void GumpToParent(int32 &gx, int32 &gy,
278  PointRoundDir r = ROUND_TOPLEFT);
279 
281  virtual void GumpRectToScreenSpace(Common::Rect32 &gr, RectRoundDir r = ROUND_OUTSIDE);
282 
284  virtual void ScreenSpaceToGumpRect(Common::Rect32 &sr, RectRoundDir r = ROUND_OUTSIDE);
285 
287  virtual uint16 TraceObjId(int32 mx, int32 my);
288 
291  virtual bool GetLocationOfItem(uint16 itemid, int32 &gx, int32 &gy,
292  int32 lerp_factor = 256);
293 
294 
295  //
296  // Some event handlers. In theory they 'should' be able to be mapped to
297  // Usecode classes.
298  //
299  // mx and my are relative to parents position
300  //
301  // onMouseDown returns the Gump that handled the Input, if it was handled.
302  // The MouseUp,MouseDouble events will be sent to the same gump.
303  //
304  // onMouseMotion works like onMouseDown,
305  // but independently of the other methods.
306  //
307  // Unhandled input will be passed down to the next lower gump.
308  //
309  // A mouse click on a gump will make it focus, IF it wants it.
310  //
311  // It is often preferrable to handle both click and double events
312  // rather than only the up event to avoid unintended clicks after
313  // performing intended action.
314 
315  // Return Gump that handled event
316  virtual Gump *onMouseDown(int button, int32 mx, int32 my);
317  virtual void onMouseUp(int button, int32 mx, int32 my) { }
318  virtual void onMouseClick(int button, int32 mx, int32 my) { }
319  virtual void onMouseDouble(int button, int32 mx, int32 my) { }
320  virtual Gump *onMouseMotion(int32 mx, int32 my);
321 
322  // onMouseOver is only call when the mouse first passes over the gump
323  // onMouseLeft is call as the mouse leaves the gump.
324  virtual void onMouseOver() { };
325  virtual void onMouseLeft() { };
326 
327  // Keyboard input gets sent to the FocusGump. Or if there isn't one, it
328  // will instead get sent to the default key handler. TextInput requires
329  // that text mode be enabled. Return true if handled, false if not.
330  // Default, returns false, unless handled by focus child
331  virtual bool OnKeyDown(int key, int mod);
332  virtual bool OnKeyUp(int key);
333  virtual bool OnTextInput(int unicode);
334 
335  // This is for detecting focus changes for keyboard input. Gets called true
336  // when the this gump is being set as the focus focus gump. It is called
337  // false when focus is being taken away.
338  virtual void OnFocus(bool /*gain*/) { }
339 
340  // Makes this gump the focus
341  virtual void MakeFocus();
342 
343  // Is this gump the focus?
344  inline bool IsFocus() {
345  return _parent ? _parent->_focusChild == this : false;
346  }
347 
348  // Get the child in focus
349  inline Gump *GetFocusChild() {
350  return _focusChild;
351  }
352 
353  // Find a new Child to be the focus
354  void FindNewFocusChild();
355 
356 
357  //
358  // Child gump related
359  //
360 
362  virtual void AddChild(Gump *, bool take_focus = true);
363 
365  virtual void RemoveChild(Gump *);
366 
368  virtual void MoveChildToFront(Gump *);
369 
371  inline Gump *GetParent() {
372  return _parent;
373  }
374 
376  Gump *GetRootGump();
377 
380  virtual void ChildNotify(Gump *child, uint32 message) { }
381  void SetIndex(int32 i) {
382  _index = i;
383  }
384  int32 GetIndex() const {
385  return _index;
386  }
387 
390  virtual bool onDragStart(int32 mx, int32 my);
391  virtual void onDragStop(int32 mx, int32 my);
392  virtual void onDrag(int32 mx, int32 my);
393 
396  virtual bool StartDraggingItem(Item *item, int mx, int my) {
397  return false;
398  }
399 
403  virtual bool DraggingItem(Item *item, int mx, int my) {
404  return false;
405  }
406 
408  virtual void DraggingItemLeftGump(Item *item) { }
409 
414  virtual void StopDraggingItem(Item *item, bool moved) { }
415 
421  virtual void DropItem(Item *item, int mx, int my) { }
422 
423 public:
424 
425  //
426  // Gump Flags
427  //
428  enum GumpFlags {
429  FLAG_DRAGGABLE = 0x0001, // When set, the gump can be dragged
430  FLAG_HIDDEN = 0x0002, // When set, the gump will not be drawn
431  FLAG_CLOSING = 0x0004, // When set, the gump is closing
432  FLAG_CLOSE_AND_DEL = 0x0008, // When set, the gump is closing and will be deleted
433  FLAG_ITEM_DEPENDENT = 0x0010, // When set, the gump will be deleted on MapChange
434  FLAG_DONT_SAVE = 0x0020, // When set, don't save this gump. Be very careful with this one!
435  FLAG_CORE_GUMP = 0x0040, // core gump (only children are saved)
436  FLAG_KEEP_VISIBLE = 0x0080, // Keep this gump on-screen. (only for ItemRelativeGumps)
437  FLAG_PREVENT_SAVE = 0x0100 // When set, prevent game from saving
438  };
439 
441  inline bool hasFlags(uint flags) const {
442  return (_flags & flags) != 0;
443  }
444 
445  inline bool IsHidden() const {
446  return (_flags & FLAG_HIDDEN) || (_parent && _parent->IsHidden());
447  }
448  bool IsDraggable() const {
449  return _flags & FLAG_DRAGGABLE;
450  }
451  virtual void HideGump() {
452  _flags |= FLAG_HIDDEN;
453  }
454  virtual void UnhideGump() {
455  _flags &= ~FLAG_HIDDEN;
456  }
457  void SetVisibility(bool visible) {
458  if (visible)
459  UnhideGump();
460  else
461  HideGump();
462  }
463 
464  bool mustSave(bool toplevel) const;
465 
466  //
467  // Gump Layers
468  //
469  enum GumpLayers {
470  LAYER_DESKTOP = -16, // Layer for Desktop 'bottom most'
471  LAYER_GAMEMAP = -8, // Layer for the World Gump
472  LAYER_NORMAL = 0, // Layer for Normal gumps
473  LAYER_ABOVE_NORMAL = 8, // Layer for Always on top Gumps
474  LAYER_MODAL = 12, // Layer for Modal Gumps
475  LAYER_CONSOLE = 16 // Layer for the console
476  };
477 
478  enum Message {
479  GUMP_CLOSING = 0x100
480  };
481 
482  bool loadData(Common::ReadStream *rs, uint32 version);
483  void saveData(Common::WriteStream *ws) override;
484 };
485 
486 } // End of namespace Ultima8
487 } // End of namespace Ultima
488 
489 #endif
virtual void setRelativePosition(Position pos, int xoffset=0, int yoffset=0)
Moves this gump to a relative location on the parent gump.
virtual void Move(int32 x, int32 y)
Move this gump.
Definition: gump.h:204
void setDims(const Common::Rect32 &d)
Set the _dims.
Definition: gump.h:248
virtual bool StartDraggingItem(Item *item, int mx, int my)
Definition: gump.h:396
virtual void DraggingItemLeftGump(Item *item)
Called when an item that was being dragged over the gump left the gump.
Definition: gump.h:408
Definition: gump_notify_process.h:33
Definition: rect.h:526
virtual void InitGump(Gump *newparent, bool take_focus=true)
Definition: stream.h:77
Definition: item.h:42
Definition: list.h:44
virtual void GumpToParent(int32 &gx, int32 &gy, PointRoundDir r=ROUND_TOPLEFT)
Convert a gump point to parent relative point.
virtual void PaintChildren(RenderSurface *surf, int32 lerp_factor, bool scaled)
Paint the Gumps Children (RenderSurface is relative to this)
virtual void PaintCompositing(RenderSurface *surf, int32 lerp_factor, int32 scalex, int32 scaley)
virtual void RemoveChild(Gump *)
Remove a gump from the child list.
Common::List< Gump * > _children
Definition: gump.h:64
Definition: render_surface.h:37
virtual void PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
Overloadable method to Paint just this Gump (RenderSurface is relative to this)
Definition: gump.h:46
virtual void run()
Run the gump.
Definition: detection.h:27
Gump * GetParent()
Get the parent.
Definition: gump.h:371
Definition: object.h:44
void UpdateDimsFromShape()
Update the width/height to match the gump&#39;s current shape frame.
virtual void ParentToGump(int32 &px, int32 &py, PointRoundDir r=ROUND_TOPLEFT)
Convert a parent relative point to a gump point.
virtual void StopDraggingItem(Item *item, bool moved)
Definition: gump.h:414
virtual void AddChild(Gump *, bool take_focus=true)
Add a gump to the child list.
virtual void PaintComposited(RenderSurface *surf, int32 lerp_factor, int32 scalex, int32 scaley)
Overloadable method to Paint just this gumps unscaled components that require compositing (RenderSurf...
Gump * GetRootGump()
Get the root gump (or self)
Gump * FindGump(bool recursive=true)
Definition: gump.h:121
static bool FindByIndex(const Gump *g)
A predicate to find a ui element by its index.
Definition: gump.h:126
virtual void ChildNotify(Gump *child, uint32 message)
Definition: gump.h:380
const Common::Rect32 & getDims() const
Get the _dims.
Definition: gump.h:243
virtual void ScreenSpaceToGump(int32 &sx, int32 &sy, PointRoundDir r=ROUND_TOPLEFT)
Convert a screen space point to a gump point.
virtual void GumpRectToScreenSpace(Common::Rect32 &gr, RectRoundDir r=ROUND_OUTSIDE)
Transform a rectangle to screenspace from gumpspace.
virtual bool DraggingItem(Item *item, int mx, int my)
Definition: gump.h:403
void SetShape(const Shape *shape, uint32 frameNum)
Set the Gump&#39;s shape/frame.
Definition: gump.h:90
virtual bool onDragStart(int32 mx, int32 my)
virtual uint16 TraceObjId(int32 mx, int32 my)
Trace a click, and return ObjId.
bool hasFlags(uint flags) const
Does this gump have any of the given flags mask set.
Definition: gump.h:441
virtual bool GetLocationOfItem(uint16 itemid, int32 &gx, int32 &gy, int32 lerp_factor=256)
virtual void CloseItemDependents()
Definition: frame_id.h:30
virtual void MoveRelative(int x, int y)
Move this gump relative to its current position.
Definition: gump.h:210
virtual void ScreenSpaceToGumpRect(Common::Rect32 &sr, RectRoundDir r=ROUND_OUTSIDE)
Transform a rectangle to gumpspace from screenspace.
Definition: stream.h:385
virtual void GumpToScreenSpace(int32 &gx, int32 &gy, PointRoundDir r=ROUND_TOPLEFT)
Convert a gump point to a screen space point.
Definition: shape.h:36
virtual bool GetMouseCursor(int32 mx, int32 my, Shape &shape, int32 &frame)
virtual void DropItem(Item *item, int mx, int my)
Definition: gump.h:421
virtual void Paint(RenderSurface *surf, int32 lerp_factor, bool scaled)
virtual Gump * FindGump(FindGumpPredicate predicate, bool recursive=true)
virtual void MoveChildToFront(Gump *)
Move child to front (within its layer)
bool IsClosing() const
Check to see if a Gump is Closing.
Definition: gump.h:199
virtual bool PointOnGump(int mx, int my)
Detect if a point is on the gump.
void Set_frameNum(uint32 frameNum)
Set the Gump&#39;s frame.
Definition: gump.h:101
virtual void Close(bool no_del=false)