ScummVM API documentation
gui.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 /*
23  * Based on
24  * WebVenture (c) 2010, Sean Kasun
25  * https://github.com/mrkite/webventure, http://seancode.com/webventure/
26  *
27  * Used with explicit permission from the author
28  */
29 
30 #ifndef MACVENTURE_GUI_H
31 #define MACVENTURE_GUI_H
32 
33 #include "graphics/macgui/macwindowmanager.h"
34 #include "graphics/macgui/macwindow.h"
35 #include "graphics/macgui/macmenu.h"
36 
37 #include "graphics/font.h"
38 
39 #include "common/timer.h"
40 
41 #include "macventure/macventure.h"
42 #include "macventure/container.h"
43 #include "macventure/image.h"
44 #include "macventure/prebuilt_dialogs.h"
45 #include "macventure/dialog.h"
46 #include "macventure/controls.h"
47 #include "macventure/windows.h"
48 
49 namespace MacVenture {
50 
51 using namespace Graphics::MacGUIConstants;
52 using namespace Graphics::MacWindowConstants;
53 class MacVentureEngine;
54 typedef uint32 ObjID;
55 
56 class Cursor;
57 class ConsoleText;
58 class CommandButton;
59 class ImageAsset;
60 class Dialog;
61 
62 BorderBounds borderBounds(MVWindowType type);
63 Graphics::BorderOffsets borderOffsets(MVWindowType type);
64 
65 enum MenuAction {
66  kMenuActionAbout,
67  kMenuActionNew,
68  kMenuActionOpen,
69  kMenuActionSave,
70  kMenuActionSaveAs,
71  kMenuActionQuit,
72  kMenuActionUndo,
73  kMenuActionCut,
74  kMenuActionCopy,
75  kMenuActionPaste,
76  kMenuActionClear,
77  kMenuActionCleanUp,
78  kMenuActionMessUp,
79 
80  kMenuActionCommand
81 };
82 
83 struct DraggedObj {
84  ObjID id;
85  Common::Point pos;
86  Common::Point mouseOffset;
87  Common::Point startPos;
88  WindowReference startWin;
89  bool hasMoved;
90 };
91 
92 class Gui {
93 
94 public:
95  Gui(MacVentureEngine *engine, Common::MacResManager *resman);
96  ~Gui();
97 
98  void reloadInternals();
99 
100  void draw();
101  void drawMenu();
102  void drawTitle();
103 
104  void loadDiploma();
105 
106  void clearControls();
107  bool processEvent(Common::Event &event);
108  void handleMenuAction(MenuAction action);
109  void updateWindow(WindowReference winID, bool containerOpen);
110  void invertWindowColors(WindowReference winID);
111 
112  WindowReference createInventoryWindow(ObjID objRef);
113  bool tryCloseWindow(WindowReference winID);
114  bool tryCloseWindowRec(WindowReference winID, bool runControl = false);
115  void resetWindows(); // Close and destroy inventory and main game windows
116  void closeAllWindows();
117 
118  void highlightExitButton(ObjID objID);
119 
120  Common::Point getObjMeasures(ObjID obj);
121 
122  WindowReference getObjWindow(ObjID objID);
123  WindowReference findObjWindow(ObjID objID);
124 
125  // Event processors
126  bool processCommandEvents(WindowClick click, Common::Event &event);
127  bool processMainGameEvents(WindowClick click, Common::Event &event);
128  bool processOutConsoleEvents(WindowClick click, Common::Event &event);
129  bool processSelfEvents(WindowClick click, Common::Event &event);
130  bool processExitsEvents(WindowClick click, Common::Event &event);
131  bool processDiplomaEvents(WindowClick click, Common::Event &event);
132  bool processInventoryEvents(WindowReference ref, WindowClick click, Common::Event &event);
133 
134  const WindowData& getWindowData(WindowReference reference);
135  Graphics::MacWindow *findWindow(WindowReference reference);
136 
137  Graphics::MacWindowManager *getMacWindowManager() { return &_wm; }
138  const Graphics::Font& getCurrentFont();
139 
140  // Clicks
141  void select(Common::Point cursorPosition, bool shiftPressed, bool isDoubleClick);
142  void handleSingleClick();
143  void handleDoubleClick();
144 
145  // Modifiers
146  void bringToFront(WindowReference window);
147  void setWindowTitle(WindowReference winID, const Common::String &string);
148  void updateWindowInfo(WindowReference ref, ObjID objID, const Common::Array<ObjID> &children);
149  void ensureInventoryOpen(WindowReference reference, ObjID id);
150 
151  void addChild(WindowReference target, ObjID child);
152  void removeChild(WindowReference target, ObjID child);
153 
154  void clearDraggedObjects();
155 
156  void clearExits();
157  void unselectExits();
158  void updateExit(ObjID id);
159  void resetExitBackgroundPattern();
160 
161  Common::String getConsoleText() const;
162  void setConsoleText(const Common::String &text);
163 
164  void printText(const Common::String &text);
165 
166  //Dialog interactions
167  void showPrebuiltDialog(PrebuiltDialogs type, const Common::String &title = "");
168  bool isDialogOpen();
169 
170  void getTextFromUser(Common::String &title);
171  void setTextInput(const Common::String &str);
172  void closeDialog();
173 
174  void loadGame();
175  void saveGame();
176  void newGame();
177  void quitGame();
178 
179  void createInnerSurface(Graphics::ManagedSurface *innerSurface, Graphics::ManagedSurface *outerSurface, const BorderBounds &borders);
180 
181 private:
182  bool decodeStartupScreen();
183  bool decodeTitleScreen();
184  bool displayTitleScreenAndWait(uint32 ms);
185 
186 private: // Attributes
187 
188  MacVentureEngine *_engine;
189  Common::MacResManager *_resourceManager;
190 
191  Graphics::ManagedSurface _screen;
193 
194  WindowReference _activeWinRef;
195 
196  Common::List<WindowData> *_windowData;
197  Common::Array<CommandButton> *_controlData;
198  Common::Array<CommandButton> *_exitsData;
199 
200  Graphics::MacWindow *_controlsWindow;
201  Graphics::MacWindow *_mainGameWindow;
202  Graphics::MacTextWindow *_outConsoleWindow;
203  Graphics::MacWindow *_selfWindow;
204  Graphics::MacWindow *_exitsWindow;
205  Graphics::MacWindow *_diplomaWindow;
206 
207  struct InventoryWindowData {
208  Graphics::MacWindow *win;
209  WindowReference ref;
210  };
211  Common::Array<InventoryWindowData> _inventoryWindows;
213 
214  Graphics::MacMenu *_menu;
215  Dialog *_dialog;
216 
217  Container *_graphics;
219  ImageAsset *_diplomaImage;
220 
221  Common::Array<DraggedObj> _draggedObjects;
223 
224  Cursor *_cursor;
225 
226  ConsoleText *_consoleText;
227 
228  WindowReference _lassoWinRef;
229  Common::Point _lassoStart;
230  Common::Point _lassoEnd;
231  bool _lassoBeingDrawn;
232 
233 private: // Methods
234 
235  // Initializers
236  void initGUI();
237  void initWindows();
238  void assignObjReferences(); // Mainly guesswork
239 
240  // Loaders
241  bool loadMenus();
242  bool loadWindows();
243  bool loadControls();
244  void loadBorders(Graphics::MacWindow *target, MVWindowType type);
245  void loadBorder(Graphics::MacWindow *target, MVWindowType type, bool active);
246  void loadGraphics();
247  void clearAssets();
248 
249  // Drawers
250  void drawWindows();
251  void drawCommandsWindow();
252  void drawDiplomaWindow();
253  void drawMainGameWindow();
254  void drawSelfWindow();
255  void drawInventories();
256  void drawExitsWindow();
257  void drawConsoleWindow();
258 
259  void drawDraggedObjects();
260  void drawObjectsInWindow(const WindowData &targetData, Graphics::ManagedSurface *surface);
261  void drawWindowTitle(WindowReference target, Graphics::ManagedSurface *surface);
262  void drawDialog();
263 
264  void moveDraggedObjects(Common::Point target);
265 
266  // Finders
267  WindowReference findWindowAtPoint(Common::Point point);
268  Common::Point getGlobalScrolledSurfacePosition(WindowReference reference);
269  WindowData& findWindowData(WindowReference reference);
270 
271  // Utils
272  void checkSelect(const WindowData &data, Common::Point pos, const Common::Rect &clickRect, WindowReference ref, bool shiftPressed, bool isDoubleClick);
273  bool canBeSelected(ObjID obj, const Common::Rect &clickRect, WindowReference ref);
274  bool isRectInsideObject(Common::Rect target, ObjID obj);
275  void selectDraggable(ObjID child, WindowReference origin, Common::Point startPos);
276  void handleDragRelease(bool shiftPressed, bool isDoubleClick);
277  Common::Rect calculateClickRect(Common::Point clickPos, Common::Rect windowBounds);
278  Common::Point localizeTravelledDistance(Common::Point point, WindowReference origin, WindowReference target);
279  void removeInventoryWindow(WindowReference ref);
280 
281  void ensureAssetLoaded(ObjID obj);
282 
283 };
284 
286  Gui *gui;
287  WindowReference ref;
288 };
289 
290 enum ClickState {
291  kCursorIdle = 0,
292  kCursorSCStart = 1,
293  kCursorSCDrag = 2,
294  kCursorDCStart = 3,
295  kCursorDCDo = 4,
296  kCursorSCSink = 5,
297  kCursorStateCount
298 };
299 
300 enum CursorInput { // Columns for the FSM transition table
301  kButtonDownCol = 0,
302  kButtonUpCol = 1,
303  kTickCol = 2,
304  kCursorInputCount
305 };
306 
307 class Cursor {
308 
309 public:
310  Cursor(Gui *gui);
311  ~Cursor();
312 
313  void tick();
314  bool processEvent(const Common::Event &event);
315  Common::Point getPos();
316  bool canSelectDraggable();
317 
318 private:
319 
320  void changeState(CursorInput input);
321  void executeStateIn();
322  void executeStateOut();
323 
324 
325 private:
326  Gui *_gui;
327 
328  Common::Point _pos;
329  ClickState _state;
330 };
331 
332 
333 
334 enum {
335  kConsoleLeftOffset = 2
336 };
337 
338 class ConsoleText {
339 
340 public:
341 
342  ConsoleText(Gui *gui) {
343  _gui = gui;
344  _lines.push_back("");
345  updateScroll();
346  }
347 
348  ~ConsoleText() {
349 
350  }
351 
352  void printLine(const Common::String &str, int maxW) {
353  Common::StringArray wrappedLines;
354  int textW = maxW;
355  const Graphics::Font *font = &_gui->getCurrentFont();
356 
357  font->wordWrapText(str, textW, wrappedLines);
358 
359  if (wrappedLines.empty()) // Sometimes we have empty lines
360  _lines.push_back("");
361 
362  for (Common::StringArray::const_iterator j = wrappedLines.begin(); j != wrappedLines.end(); ++j) {
363  _lines.push_back(*j);
364  }
365 
366  updateScroll();
367  }
368 
369  void renderInto(Graphics::ManagedSurface *target, const BorderBounds borders, int textOffset) {
370  target->fillRect(target->getBounds(), kColorWhite);
371 
372  Graphics::ManagedSurface *composeSurface = new Graphics::ManagedSurface();
373  _gui->createInnerSurface(composeSurface, target, borders);
374  composeSurface->clear(kColorGreen);
375 
376  const Graphics::Font *font = &_gui->getCurrentFont();
377  int y = target->h - font->getFontHeight();
378  for (uint i = _scrollPos; i != 0; i--) {
379  font->drawString(target, _lines[i], textOffset, y, font->getStringWidth(_lines[i]), kColorBlack);
380 
381  if (y < font->getFontHeight()) // Do not draw off-screen
382  break;
383 
384  y -= font->getFontHeight();
385  }
386 
387  Common::Point composePosition = Common::Point(borders.leftOffset, borders.topOffset);
388  target->transBlitFrom(*composeSurface, composePosition, kColorGreen);
389  delete composeSurface;
390  }
391 
392  void updateScroll() {
393  _scrollPos = _lines.size() - 1;
394  }
395 
396  void scrollDown() {
397  if (_scrollPos < (int)(_lines.size() - 1)) {
398  _scrollPos++;
399  }
400  }
401 
402  void scrollUp() {
403  if (_scrollPos > 0) {
404  _scrollPos--;
405  }
406  }
407 
408 
409 private:
410 
411  Gui *_gui;
412 
413  Common::StringArray _lines;
414  int _scrollPos;
415 
416 };
417 
418 } // End of namespace MacVenture
419 
420 #endif
void clear(uint32 color=0)
Definition: managed_surface.h:51
Definition: dialog.h:48
Definition: macresman.h:126
const Common::Rect getBounds() const
Definition: managed_surface.h:328
Definition: str.h:59
Definition: macwindow.h:40
Definition: font.h:83
Definition: gui.h:92
Definition: image.h:63
int wordWrapText(const Common::String &str, int maxWidth, Common::Array< Common::String > &lines, int initWidth=0, uint32 mode=kWordWrapOnExplicitNewLines) const
Definition: macwindow.h:203
Definition: windows.h:83
iterator end()
Definition: array.h:380
iterator begin()
Definition: array.h:375
Definition: mactextwindow.h:30
Definition: list.h:44
Definition: gui.h:338
Definition: macwindowmanager.h:45
Definition: rect.h:524
int getStringWidth(const Common::String &str) const
void fillRect(const Common::Rect &r, uint32 color)
Definition: managed_surface.h:954
Definition: macwindowmanager.h:147
Definition: macwindowborder.h:57
Definition: windows.h:97
int16 & h
Definition: managed_surface.h:135
bool empty() const
Definition: array.h:352
Definition: container.h:48
Definition: atari-cursor.h:35
Definition: events.h:210
Definition: macventure.h:218
Definition: rect.h:144
Definition: macmenu.h:94
Definition: container.h:38
Definition: gui.h:307
void transBlitFrom(const Surface &src, uint32 transColor=0, bool flipped=false, uint32 srcAlpha=0xff, const Palette *srcPalette=nullptr)
Definition: gui.h:83
virtual int getFontHeight() const =0
void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align=kTextAlignLeft, int deltax=0, bool useEllipsis=false) const