ScummVM API documentation
panel.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 * Based on the original sources
22 * Faery Tale II -- The Halls of the Dead
23 * (c) 1993-1996 The Wyrmkeep Entertainment Co.
24 */
25
26#ifndef SAGA2_PANEL_H
27#define SAGA2_PANEL_H
28
29#include "saga2/input.h"
30#include "saga2/vdraw.h"
31
32namespace Common {
33struct Event;
34}
35
36namespace Saga2 {
37// Fix problem with DOS's encroachment on name space that should
38// rightfully belong to the application programmer.
39
40#ifdef enable
41#undef enable
42#undef disable
43#endif
44
45/* ===================================================================== *
46 Cursor Cycling Stuff
47 * ===================================================================== */
48
49void cycleCursor();
50
51/* ===================================================================== *
52 Forward declarations
53 * ===================================================================== */
54
55class gPanel;
56class gPanelList;
57class gPanelMessage;
58class gWindow;
59
60/* ===================================================================== *
61 Input dispatching functions
62 * ===================================================================== */
63
64void HandleTimerTick(long newTick);
65void EventLoop(bool &running, bool modal = false);
66
67/* ===================================================================== *
68 Constants
69 * ===================================================================== */
70
71enum gEventType {
72 kEventNone = 0, // no event occurred
73 kEventMouseDown, // left button pressed
74 kEventMouseUp, // left button released
75 kEventRMouseDown, // right button pressed
76 kEventRMouseUp, // right button released
77 kEventMouseMove, // mouse moved
78 kEventMouseDrag, // mouse dragged
79 kEventMouseOutside, // mouse click outside of window
80 kEventKeyDown, // keystroke
81
82 kEventNewValue, // object had new value
83 kEventDoubleClick, // double-clicked on object
84 kEventAltValue, // for multi-function objects
85
86 kEventLast
87};
88
89/* ===================================================================== *
90 gEvent: returns input events to the user
91 * ===================================================================== */
92
93struct gEvent {
94 gPanel *panel; // where event came from
95 gEventType eventType; // type of event that occurred
96 Point16 mouse; // mouse position
97 int32 value; // new value of control
98 gWindow *window; // active window
99};
100
101typedef void AppFunc(gEvent &);
102
103#ifndef __WATCOMC__
104#define APPFUNCDECL __cdecl
105#else
106#define APPFUNCDECL
107#endif
108
109#define APPFUNC(a) void a ( gEvent &ev )
110#define APPFUNCV(a) void a ( gEvent & )
111
112// Note: panels in this system are not, in general, resizeable
113
114/* ===================================================================== *
115 gPanel class: The basic user interface element
116 * ===================================================================== */
117
118class gPanel {
119 friend class gToolBase;
120 friend class gWindow;
121
122 AppFunc *_command; // application function
123protected:
124 gWindow &_window; // window this belongs to
125 Rect16 _extent; // rectangular bounds of the control
126 const char *_title; // title of the panel
127 byte _enabled, // allows disabling the panel
128 _selected, // some panels have a selected state
129 _imageLabel, // button label is image, not text
130 _ghosted, // button is dimmed
131 _wantMousePoll; // send mousemoves even if mouse not moving!
132
133 // window constructor
134 gPanel(gWindow &, const Rect16 &, AppFunc *cmd);
135
136public:
137 uint32 _id; // panel id number
138 void *_userData; // data for this panel
139
140 // constructor
141 gPanel(gPanelList &, const Rect16 &, const char *, uint16, AppFunc *cmd = NULL);
142 gPanel(gPanelList &, const Rect16 &, gPixelMap &, uint16, AppFunc *cmd = NULL);
143
144 gPanel(gPanelList &, const StaticRect &, const char *, uint16, AppFunc *cmd = NULL);
145 virtual ~gPanel(); // destructor
146
147 virtual gPanel *hitTest(const Point16 &p);
148 virtual gPanel *keyTest(int16 key);
149
150protected:
151 virtual void pointerMove(gPanelMessage &msg);
152 virtual bool pointerHit(gPanelMessage &msg);
153 virtual bool pointerRHit(gPanelMessage &msg);
154 virtual void pointerDrag(gPanelMessage &msg);
155 virtual void pointerRelease(gPanelMessage &msg);
156 virtual bool keyStroke(gPanelMessage &msg);
157 virtual void timerTick(gPanelMessage &msg);
158 virtual void onMouseHintDelay();
159
160 void notify(gEventType, int32 value);
161 void notify(gEvent &ev) {
162 if (_command) _command(ev);
163 }
164 void drawTitle(TextPositions placement);
165
166
167public:
168 bool isActive(); // true if we are active panel
169 virtual bool activate(gEventType why); // activate the control
170 virtual void deactivate(); // deactivate the control
171 virtual void draw(); // redraw the panel.
172 virtual void enable(bool abled);
173 virtual void select(uint16 selected);
174 virtual void ghost(bool ghosted);
175 virtual void invalidate(Rect16 *area = nullptr);
176 virtual void setMousePoll(bool abled) {
177 _wantMousePoll = abled ? 1 : 0;
178 }
179
180 // Redraw the panel, but only a small clipped section,
181 // and perhaps drawn onto an off-screen map.
182 virtual void drawClipped(
183 gPort &port,
184 const Point16 &offset,
185 const Rect16 &r);
186
187// void setCommand( AppFunc *func ) { command = func; }
188 gWindow *getWindow() {
189 return &_window;
190 }
191 void makeActive();
192 Rect16 getExtent() {
193 return _extent;
194 }
195 bool isSelected() {
196 return _selected != 0;
197 }
198 bool isGhosted() {
199 return _ghosted != 0;
200 }
201 bool getEnabled() const {
202 return (bool)_enabled;
203 }
204 void show(bool shown = true, bool inval = true) {
205 enable(shown);
206 if (inval)
207 invalidate();
208 }
209
210 void moveToFront(gPanelList &l);
211 void moveToBack(gPanelList &l);
212};
213
214/* ===================================================================== *
215 gPanelMessage class: How user input is distributes to panels
216 * ===================================================================== */
217
219public:
220 Point16 _pickPos, // mouse position relative to panel
221 _pickAbsPos; // mouse position relative to display
222 byte _leftButton, // left button state
223 _rightButton, // right button state
224 _inPanel, // whether mouse is currently in panel
225 _pointerEnter, // set when pointer enters panel
226 _pointerLeave, // set when pointer leaves panel
227 _doubleClick; // set when double click detected
228
229 // For keyboard input
230
231 uint16 _key, // keystroke from keyboard
232 _qualifier; // qualifier from keyboard
233
234 uint32 _timeStamp; // time of message
235
236 gPanelMessage() {
237 _leftButton = 0;
238 _rightButton = 0;
239 _inPanel = 0;
240 _pointerEnter = 0;
241 _pointerLeave = 0;
242 _doubleClick = 0;
243 _key = 0;
244 _qualifier = 0;
245 _timeStamp = 0;
246 }
247};
248
249/* ===================================================================== *
250 gPanelList class: A list of panels
251 * ===================================================================== */
252
253class gControl;
254
255class gPanelList : public gPanel {
256
257 friend class gControl;
258 friend class gToolBase;
259
260 friend void gPanel::moveToFront(gPanelList &l);
261 friend void gPanel::moveToBack(gPanelList &l);
262
263protected:
264
265 Common::List<gPanel *> _contents; // list of panels
266
267 gPanelList(gWindow &, const Rect16 &, char *, uint16, AppFunc *cmd = NULL);
268
269public:
270
272 ~gPanelList();
273
274 gPanel *hitTest(const Point16 &p);
275 gPanel *keyTest(int16 key);
276 void removeControls();
277
278public:
279 void invalidate(Rect16 *area = nullptr);
280 void draw(); // redraw the controls
281 void drawClipped(
282 gPort &port,
283 const Point16 &offset,
284 const Rect16 &r);
285
286 void enable(bool abled); // enable list and all children
287// void setPointer( gPixelMap &map, int x, int y );
288};
289
290inline void gPanel::moveToFront(gPanelList &l) {
291 l._contents.remove(this);
292 l._contents.push_front(this);
293}
294
295inline void gPanel::moveToBack(gPanelList &l) {
296 l._contents.remove(this);
297 l._contents.push_back(this);
298}
299
300/* ===================================================================== *
301 gWindow class: A context for holding panels.
302 * ===================================================================== */
303
304/*
305enum windowFeatures {
306 windowTitleBar = (1<<0), // window has a title bar
307 windowCanDrag = (1<<1), // window is draggable
308// windowVisible = (1<<2), // window is visible
309// windowBackSaved = (1<<3), // backsave data under window
310// windowCloseBox = (1<<4), // create a close box
311// windowNoBorder = (1<<5), // window with no border
312};
313*/
314
315class gWindow : public gPanelList {
316
317 friend class gControl;
318 friend class gPanel;
319 friend class gToolBase;
320
321public:
322 gDisplayPort _windowPort;
323
324 gWindow(const Rect16 &, uint16, const char saveName[], AppFunc *cmd = NULL);
325 ~gWindow();
326
327 operator gPort() {
328 return _windowPort;
329 }
330 void postEvent(gEvent &ev) {
331 gPanel::notify(ev);
332 }
333
334protected:
335 bool _openFlag; // true if window open.
336
337 //gWindowWinInfoInINIFile saver;
338
339private:
340 bool activate(gEventType why); // activate the control
341 void deactivate();
342
343 void pointerMove(gPanelMessage &msg);
344 bool pointerHit(gPanelMessage &msg);
345 void pointerDrag(gPanelMessage &msg);
346 void pointerRelease(gPanelMessage &msg);
347
348 // Dragging modes for window -- private and static!
349
350 enum drag_modes {
351 kDragNone = 0,
352 kDragPosition
353 };
354
355 static int _dragMode; // current dragging mode
356 static StaticRect _dragExtent; // dragging extent
357 static StaticPoint16 _dragOffset; // offset to window origin
358
359 void shadow();
360
361public:
362 void setExtent(const Rect16 &); // set window position and size
363 Rect16 getExtent() {
364 return _extent; // set window position and size
365 }
366protected:
367 void setPos(Point16 pos); // set window position
368 void insert(); // insert window into window list
369 virtual void toFront(); // re-order the windows
370
371public:
372 bool isOpen() {
373 return _openFlag; // true if window is visible
374 }
375 void draw(); // redraw the panel.
376 void drawClipped(
377 gPort &port,
378 const Point16 &offset,
379 const Rect16 &r);
380
381 // Redraw the window, but only a small clipped section,
382 // and perhaps drawn onto an off-screen map.
383// void drawClipped(
384// gPort &port,
385// const Point16 &offset,
386// const Rect16 &r );
387
388 void enable(bool abled);
389 void select(uint16 sel); // activate the window
390
391 virtual bool open();
392 virtual void close();
393 virtual bool isModal();
394
395 // Update a region of a window, and all floaters which
396 // might be above that window.
397 virtual void update(const Rect16 &updateRect) = 0;
398
399// void setPointer( gPixelMap &map, int x, int y );
400};
401
402/* ===================================================================== *
403 gControl class: The basis for buttons and other controls.
404 * ===================================================================== */
405
406class gControl : public gPanel {
407public:
408 uint8 _accelKey;
409 gPanelList *_list;
410
411 gControl(gPanelList &, const Rect16 &, const char *, uint16, AppFunc *cmd = NULL);
412 gControl(gPanelList &, const Rect16 &, gPixelMap &, uint16, AppFunc *cmd = NULL);
413
414 gControl(gPanelList &, const StaticRect &, const char *, uint16, AppFunc *cmd = NULL);
415 ~gControl(); // destructor
416
417 gPanel *keyTest(int16 key);
418
419 void enable(bool abled); // enable the control
420 void select(uint16 sel); // selecte the control
421 void ghost(bool ghosted);
422// virtual void newValue( void );
423
424 void draw(); // redraw the control.
425};
426
427/* ===================================================================== *
428 gGenericControl class: A generic button that notifies everything
429 * ===================================================================== */
430
431class gGenericControl : public gControl {
432 bool _dblClickFlag;
433
434public:
435 gGenericControl(gPanelList &, const Rect16 &, uint16, AppFunc *cmd = NULL);
436
437 // Disable double click for next mouse click
438 void disableDblClick() {
439 _dblClickFlag = true;
440 }
441
442 enum controlValue {
443 kCVEnter = (1 << 0),
444 kCVLeave = (1 << 1)
445 };
446
447protected:
448 bool activate(gEventType why); // activate the control
449 void deactivate();
450
451 void pointerMove(gPanelMessage &msg);
452 bool pointerHit(gPanelMessage &msg);
453 void pointerDrag(gPanelMessage &msg);
454 void pointerRelease(gPanelMessage &msg);
455
456 void draw(); // redraw the control.
457};
458
459
460/* ===================================================================== *
461 gToolBase class: The primary dispatcher for user interface events
462 * ===================================================================== */
463
464void setMouseTextF(char *format, ...);
465void LockUI(bool state);
466
468 friend class gWindow;
469 friend class gPanel;
470 friend void EventLoop(bool &running);
471 friend int16 leftButtonState();
472 friend int16 rightButtonState();
473 friend void StageModeCleanup();
474 friend void TileModeCleanup();
475 friend void dumpGBASE(char *msg);
476
477 // windows
478
479 Common::List<gWindow *> _windowList; // list of windows
480 gWindow *_mouseWindow, // window mouse is in
481 *_activeWindow; // current active window
482 gPanel *_mousePanel, // panel that mouse is in
483 *_activePanel; // panel that has input focus
484 Rect16 _dragRect; // dragging rectangle for windows
485 Point16 _pickPos; // mouse pos relative to panel
486 uint8 _leftDrag, // left-button dragging
487 _rightDrag; // right button dragging
488 gPanelMessage _msg; // message that we send out
489
490 int32 _lastMouseMoveTime; // time of last mouse move
491
492 gMouseState _curMouseState;
493
494public:
495 bool _mouseHintSet; // true if mouse hint is up.
496
497 gToolBase() {
498 _mouseWindow = nullptr;
499 _activeWindow = nullptr;
500 _mousePanel = nullptr;
501 _activePanel = nullptr;
502 _leftDrag = 0;
503 _rightDrag = 0;
504 _lastMouseMoveTime = 0;
505 }
506
507private:
508 void setMsgQ(gPanelMessage &msg_, gPanel *panel) {
509 if (panel == &panel->_window)
510 msg_._pickPos = _pickPos;
511 else {
512 _msg._pickPos.x = (int16)(_pickPos.x - panel->_extent.x);
513 _msg._pickPos.y = (int16)(_pickPos.y - panel->_extent.y);
514 }
515 }
516
517 void setMsg(gPanelMessage &msg_, gPanel *panel) {
518 setMsgQ(msg_, panel);
519 _msg._inPanel = (msg_._pickPos.x >= 0
520 && msg_._pickPos.y >= 0
521 && msg_._pickPos.x < panel->_extent.width
522 && msg_._pickPos.y < panel->_extent.height);
523 // panel->extent.ptInside( pickPos );
524 }
525
526public:
527 void setActive(gPanel *newActive);
528 void leavePanel(); // we're changing windows
529public:
530 void handleMouse(Common::Event &event, uint32 time);
531 void handleKeyStroke(Common::Event &event);
532 void handleTimerTick(int32 tick);
533 Common::List<gWindow *>::iterator topWindowIterator() {
534 return _windowList.end();
535 }
536 Common::List<gWindow *>::iterator bottomWindowIterator() {
537 return _windowList.reverse_begin();
538 }
539 gWindow *topWindow() {
540 return _windowList.front();
541 }
542 gWindow *bottomWindow() {
543 return _windowList.back();
544 }
545 bool isMousePanel(gPanel *p) {
546 return (_mousePanel != NULL) ? (p == _mousePanel) : (p == topWindow());
547 }
548};
549
550/* ===================================================================== *
551 Application functions to call for event handling
552 * ===================================================================== */
553
554void EventLoop(bool &running);
555void initPanels(gDisplayPort &port);
556void cleanupPanels();
557
558//void writeHelpLine( char *msg, ... );
559
560int16 leftButtonState();
561int16 rightButtonState();
562
563// Kludge structure to contain both a mouse event and a time stamp
565 gMouseState st;
566 int32 time;
567};
568
569} // end of namespace Saga2
570
571#endif
Definition: list.h:44
t_T & front()
Definition: list.h:196
iterator reverse_begin()
Definition: list.h:274
t_T & back()
Definition: list.h:206
iterator end()
Definition: list.h:279
Definition: rect.h:42
Definition: rect.h:290
Definition: panel.h:406
Definition: vdraw.h:33
Definition: panel.h:431
Definition: panel.h:118
Definition: panel.h:255
Definition: panel.h:218
Definition: gdraw.h:56
Definition: gdraw.h:178
Definition: panel.h:467
Definition: panel.h:315
Definition: algorithm.h:29
Definition: events.h:218
Definition: list_intern.h:54
Definition: panel.h:564
Definition: rect.h:33
Definition: rect.h:282
Definition: panel.h:93
Definition: input.h:42