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