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 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (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, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef GRAPHICS_MACGUI_MACWINDOWMANAGER_H 24 #define GRAPHICS_MACGUI_MACWINDOWMANAGER_H 25 26 #include "common/hashmap.h" 27 #include "common/list.h" 28 #include "common/stack.h" 29 #include "common/events.h" 30 31 #include "graphics/font.h" 32 #include "graphics/fontman.h" 33 #include "graphics/macgui/macwindow.h" 34 35 #include "engines/engine.h" 36 37 namespace Common { 38 class Archive; 39 } 40 41 namespace Graphics { 42 43 namespace MacGUIConstants { 44 enum { 45 kDesktopArc = 7 46 }; 47 48 enum { 49 kColorBlack = 0, 50 kColorGray80 = 1, 51 kColorGray88 = 2, 52 kColorGrayEE = 3, 53 kColorWhite = 4, 54 kColorGreen = 5, 55 kColorGreen2 = 6, 56 kColorCount 57 }; 58 59 enum { 60 kPatternSolid = 1, 61 kPatternStripes = 2, 62 kPatternCheckers = 3, 63 kPatternCheckers2 = 4, 64 kPatternLightGray = 5, 65 kPatternDarkGray = 6 66 }; 67 68 enum MacCursorType { 69 kMacCursorArrow, 70 kMacCursorBeam, 71 kMacCursorCrossHair, 72 kMacCursorCrossBar, 73 kMacCursorWatch, 74 kMacCursorCustom, 75 kMacCursorOff 76 }; 77 78 enum { 79 kWMModeNone = 0, 80 kWMModeNoDesktop = (1 << 0), 81 kWMModeAutohideMenu = (1 << 1), 82 kWMModalMenuMode = (1 << 2), 83 kWMModeForceBuiltinFonts= (1 << 3), 84 kWMModeUnicode = (1 << 4), 85 kWMModeManualDrawWidgets= (1 << 5), 86 kWMModeFullscreen = (1 << 6), 87 kWMModeButtonDialogStyle= (1 << 7), 88 kWMMode32bpp = (1 << 8), 89 kWMNoScummVMWallpaper = (1 << 9), 90 kWMModeWin95 = (1 << 10) 91 }; 92 93 } 94 using namespace MacGUIConstants; 95 96 class Cursor; 97 98 class ManagedSurface; 99 100 class MacCursor; 101 class MacMenu; 102 class MacTextWindow; 103 class MacWidget; 104 105 class MacFont; 106 107 class MacFontManager; 108 109 typedef Common::Array<byte *> MacPatterns; 110 111 struct MacPlotData { 112 Graphics::ManagedSurface *surface; 113 Graphics::ManagedSurface *mask; 114 MacPatterns *patterns; 115 uint fillType; 116 int fillOriginX; 117 int fillOriginY; 118 int thickness; 119 uint bgColor; 120 bool invert; 121 122 MacPlotData(Graphics::ManagedSurface *s, Graphics::ManagedSurface *m, MacPatterns *p, uint f, int fx, int fy, int t, uint bg, bool inv = false) : surfaceMacPlotData123 surface(s), mask(m), patterns(p), fillType(f), fillOriginX(fx), fillOriginY(fy), thickness(t), bgColor(bg), invert(inv) { 124 } 125 }; 126 127 struct ZoomBox { 128 Common::Rect start; 129 Common::Rect end; 130 Common::Array<Common::Rect> last; 131 int delay; 132 int step; 133 uint32 startTime; 134 uint32 nextTime; 135 }; 136 137 typedef void (* MacDrawPixPtr)(int, int, int, void *); 138 139 /** 140 * A manager class to handle window creation, destruction, 141 * drawing, moving and event handling. 142 */ 143 class MacWindowManager { 144 public: 145 MacWindowManager(uint32 mode = 0, MacPatterns *patterns = nullptr, Common::Language language = Common::UNK_LANG); 146 ~MacWindowManager(); 147 148 MacDrawPixPtr getDrawPixel(); 149 MacDrawPixPtr getDrawInvertPixel(); 150 151 /** 152 * Mutator to indicate the surface onto which the desktop will be drawn. 153 * Note that this method should be called as soon as the WM is created. 154 * @param screen Surface on which the desktop will be drawn. 155 */ 156 void setScreen(ManagedSurface *screen); 157 158 /** 159 * Mutator to indicate the dimensions of the desktop, when a backing surface is not used. 160 * Note that this method should be called as soon as the WM is created. 161 * @param screen Surface on which the desktop will be drawn. 162 */ 163 void setScreen(int w, int h); 164 165 /** 166 * Create a window with the given parameters. 167 * Note that this method allocates the necessary memory for the window. 168 * @param scrollable True if the window has to be scrollable. 169 * @param resizable True if the window can be resized. 170 * @param editable True if the window can be edited. 171 * @return Pointer to the newly created window. 172 */ 173 MacWindow *addWindow(bool scrollable, bool resizable, bool editable); 174 MacTextWindow *addTextWindow(const MacFont *font, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, MacMenu *menu, bool cursorHandler = true); 175 MacTextWindow *addTextWindow(const Font *font, int fgcolor, int bgcolor, int maxWidth, TextAlign textAlignment, MacMenu *menu, bool cursorHandler = true); 176 void resizeScreen(int w, int h); 177 178 /** 179 * Adds a window that has already been initialized to the registry. 180 * Like addWindow, but this doesn't create/allocate the Window. 181 * @param macWindow the window to be added to the registry 182 */ 183 void addWindowInitialized(MacWindow *macwindow); 184 /** 185 * Returns the last allocated id 186 * @return last allocated window id 187 */ getLastId()188 int getLastId() { return _lastId; } 189 /** 190 * Returns the next available id and the increments the internal counter. 191 * @return next (new) window id that can be used 192 */ getNextId()193 int getNextId() { return _lastId++; } 194 /** 195 * Add the menu to the desktop. 196 * Note that the returned menu is empty, and therefore must be filled 197 * afterwards. 198 * @return Pointer to a new empty menu. 199 */ 200 MacMenu *addMenu(); 201 202 void removeMenu(); 203 void activateMenu(); 204 205 void activateScreenCopy(); 206 void disableScreenCopy(); 207 208 bool isMenuActive(); 209 210 /** 211 * Set hot zone where menu appears (works only with autohide menu) 212 */ setMenuHotzone(const Common::Rect & rect)213 void setMenuHotzone(const Common::Rect &rect) { _menuHotzone = rect; } 214 215 /** 216 * Set delay in milliseconds when menu appears (works only with autohide menu) 217 */ setMenuDelay(int delay)218 void setMenuDelay(int delay) { _menuDelay = delay; } 219 220 /** 221 * Set the desired window state to active. 222 * @param id ID of the window that has to be set to active. 223 */ 224 void setActiveWindow(int id); 225 226 /** 227 * Mark a window for removal. 228 * Note that the window data will be destroyed. 229 * @param target Window to be removed. 230 */ 231 void removeWindow(MacWindow *target); 232 233 /** 234 * Mutator to indicate that the entire desktop must be refreshed. 235 * @param redraw Currently unused. 236 */ setFullRefresh(bool redraw)237 void setFullRefresh(bool redraw) { _fullRefresh = redraw; } 238 239 /** 240 * Method to draw the desktop into the screen, 241 * It will take into accout the contents set as dirty. 242 * Note that this method does not refresh the screen, 243 * g_system must be called separately. 244 */ 245 void draw(); 246 247 /** 248 * Method to process the events from the engine. 249 * Most often this method will be called from the engine's GUI, and 250 * will send the event to the relevant windows for them to process. 251 * @param event The event to be processed. 252 * @return True if the event was processed. 253 */ 254 bool processEvent(Common::Event &event); 255 256 /** 257 * Accessor to retrieve an arbitrary window. 258 * @param id The id of the desired window. 259 * @return Pointer to the requested window, if it exists. 260 */ getWindow(int id)261 BaseMacWindow *getWindow(int id) { return _windows[id]; } 262 263 /** 264 * Retrieve the patterns used to fill surfaces. 265 * @return A MacPatterns object reference with the patterns. 266 */ getPatterns()267 MacPatterns &getPatterns() { return _patterns; } 268 269 /** 270 * Sets an active widget, typically the one which steals the input 271 * It also sends deactivation message to the previous one 272 * @param widget Pointer to the widget to activate, nullptr for no widget 273 */ 274 void setActiveWidget(MacWidget *widget); 275 getBuiltinPatterns()276 MacPatterns &getBuiltinPatterns() { return _builtinPatterns; } 277 getActiveWidget()278 MacWidget *getActiveWidget() { return _activeWidget; } 279 getScreenBounds()280 Common::Rect getScreenBounds() { return _screen ? _screen->getBounds() : _screenDims; } 281 282 void clearWidgetRefs(MacWidget *widget); 283 284 private: 285 void replaceCursorType(MacCursorType type); 286 287 public: 288 MacCursorType getCursorType() const; 289 290 void pushCursor(MacCursorType type, Cursor *cursor = nullptr); 291 void replaceCursor(MacCursorType type, Cursor *cursor = nullptr); 292 293 void pushCustomCursor(const byte *data, int w, int h, int hx, int hy, int transcolor); 294 void replaceCustomCursor(const byte *data, int w, int h, int hx, int hy, int transcolor); 295 void pushCustomCursor(const Graphics::Cursor *cursor); 296 void popCursor(); 297 298 PauseToken pauseEngine(); 299 300 void setMode(uint32 mode); 301 302 void setEngine(Engine *engine); 303 void setEngineRedrawCallback(void *engine, void (*redrawCallback)(void *engine)); 304 305 void passPalette(const byte *palette, uint size); 306 uint findBestColor(byte cr, byte cg, byte cb); 307 uint findBestColor(uint32 color); 308 void decomposeColor(uint32 color, byte &r, byte &g, byte &b); 309 310 uint inverter(uint src); 311 getPalette()312 const byte *getPalette() { return _palette; } getPaletteSize()313 uint getPaletteSize() { return _paletteSize; } 314 315 void renderZoomBox(bool redraw = false); 316 void addZoomBox(ZoomBox *box); 317 318 void removeMarked(); 319 320 void loadDataBundle(); 321 void cleanupDataBundle(); 322 BorderOffsets getBorderOffsets(byte windowType); 323 Common::SeekableReadStream *getBorderFile(byte windowType, uint32 flags); 324 Common::SeekableReadStream *getFile(const Common::String &filename); 325 326 void setTextInClipboard(const Common::U32String &str); 327 /** 328 * get text from WM clipboard or the global clipboard 329 * @param size will change to the length of real text in clipboard 330 * @return the text in clipboard, which may contained the format 331 */ 332 Common::U32String getTextFromClipboard(const Common::U32String &format = Common::U32String(), int *size = nullptr); 333 334 /** 335 * reset events for current widgets. i.e. we reset those variables which are used for handling events for macwidgets. 336 * e.g. we clear the active widget, set mouse down false, clear the hoveredWidget 337 * this function should be called when we are going to other level to handling events. thus wm may not handle events correctly. 338 */ 339 void clearHandlingWidgets(); 340 341 void setMenuItemCheckMark(const Common::String &menuId, const Common::String &itemId, bool checkMark); 342 void setMenuItemCheckMark(int menuId, int itemId, bool checkMark); 343 void setMenuItemEnabled(const Common::String &menuId, const Common::String &itemId, bool enabled); 344 void setMenuItemEnabled(int menuId, int itemId, bool enabled); 345 void setMenuItemName(const Common::String &menuId, const Common::String &itemId, const Common::String &name); 346 void setMenuItemName(int menuId, int itemId, const Common::String &name); 347 void setMenuItemAction(const Common::String &menuId, const Common::String &itemId, int actionId); 348 void setMenuItemAction(int menuId, int itemId, int actionId); 349 350 bool getMenuItemCheckMark(const Common::String &menuId, const Common::String &itemId); 351 bool getMenuItemCheckMark(int menuId, int itemId); 352 bool getMenuItemEnabled(const Common::String &menuId, const Common::String &itemId); 353 bool getMenuItemEnabled(int menuId, int itemId); 354 Common::String getMenuItemName(const Common::String &menuId, const Common::String &itemId); 355 Common::String getMenuItemName(int menuId, int itemId); 356 int getMenuItemAction(const Common::String &menuId, const Common::String &itemId); 357 int getMenuItemAction(int menuId, int itemId); 358 359 public: 360 MacFontManager *_fontMan; 361 uint32 _mode; 362 Common::Language _language; 363 364 Common::Point _lastClickPos; 365 Common::Point _lastMousePos; 366 Common::Rect _menuHotzone; 367 368 bool _menuTimerActive; 369 bool _mouseDown; 370 371 uint32 _colorBlack, _colorGray80, _colorGray88, _colorGrayEE, _colorWhite, _colorGreen, _colorGreen2; 372 373 MacWidget *_hoveredWidget; 374 375 // we use it to indicate whether we are clicking the hilite-able widget. 376 // In list style button mode, we will highlight the subsequent buttons only when we've clicked the hilite-able button initially 377 bool _hilitingWidget; 378 379 private: 380 void loadDesktop(); 381 void drawDesktop(); 382 383 void removeFromStack(BaseMacWindow *target); 384 void removeFromWindowList(BaseMacWindow *target); 385 386 void zoomBoxInner(Common::Rect &r, Graphics::MacPlotData &pd); haveZoomBox()387 bool haveZoomBox() { return !_zoomBoxes.empty(); } 388 389 void adjustDimensions(const Common::Rect &clip, const Common::Rect &dims, int &adjWidth, int &adjHeight); 390 391 public: 392 TransparentSurface *_desktopBmp; 393 ManagedSurface *_desktop; 394 PixelFormat _pixelformat; 395 396 ManagedSurface *_screen; 397 ManagedSurface *_screenCopy; 398 Common::Rect _screenDims; 399 400 private: 401 Common::List<BaseMacWindow *> _windowStack; 402 Common::HashMap<uint, BaseMacWindow *> _windows; 403 404 Common::List<BaseMacWindow *> _windowsToRemove; 405 bool _needsRemoval; 406 407 int _lastId; 408 int _activeWindow; 409 410 bool _fullRefresh; 411 412 bool _inEditableArea; 413 414 MacPatterns _patterns; 415 MacPatterns _builtinPatterns; 416 byte *_palette; 417 uint _paletteSize; 418 419 MacMenu *_menu; 420 uint32 _menuDelay; 421 422 Engine *_engineP; 423 void *_engineR; 424 void (*_redrawEngineCallback)(void *engine); 425 426 MacCursorType _tempType; 427 Common::Stack<MacCursorType> _cursorTypeStack; 428 Cursor *_cursor; 429 430 MacWidget *_activeWidget; 431 432 PauseToken *_screenCopyPauseToken; 433 434 Common::Array<ZoomBox *> _zoomBoxes; 435 Common::HashMap<uint, uint> _colorHash; 436 Common::HashMap<uint, uint> _invertColorHash; 437 438 Common::Archive *_dataBundle; 439 440 Common::U32String _clipboard; 441 }; 442 443 } // End of namespace Graphics 444 445 #endif 446