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 SCI_GRAPHICS_CONTROLS32_H 24 #define SCI_GRAPHICS_CONTROLS32_H 25 26 #include "sci/graphics/text32.h" 27 28 namespace Sci { 29 30 class GfxCache; 31 class GfxScreen; 32 class GfxText32; 33 34 enum MessageBoxStyle { 35 kMessageBoxOK = 0x0, 36 kMessageBoxYesNo = 0x4 37 }; 38 39 struct TextEditor { 40 /** 41 * The bitmap where the editor is rendered. 42 */ 43 reg_t bitmap; 44 45 /** 46 * The width of the editor, in bitmap pixels. 47 */ 48 int16 width; 49 50 /** 51 * The text in the editor. 52 */ 53 Common::String text; 54 55 /** 56 * The rect where text should be drawn into the editor, 57 * in bitmap pixels. 58 */ 59 Common::Rect textRect; 60 61 /** 62 * The color of the border. -1 indicates no border. 63 */ 64 int16 borderColor; 65 66 /** 67 * The text color. 68 */ 69 uint8 foreColor; 70 71 /** 72 * The background color. 73 */ 74 uint8 backColor; 75 76 /** 77 * The transparent color. 78 */ 79 uint8 skipColor; 80 81 /** 82 * The font used to render the text in the editor. 83 */ 84 GuiResourceId fontId; 85 86 /** 87 * The current position of the cursor within the editor. 88 */ 89 uint16 cursorCharPosition; 90 91 /** 92 * Whether or not the cursor is currently drawn to the screen. 93 */ 94 bool cursorIsDrawn; 95 96 /** 97 * The rectangle for drawing the input cursor, in bitmap pixels. 98 */ 99 Common::Rect cursorRect; 100 101 /** 102 * The maximum allowed text length, in characters. 103 */ 104 uint16 maxLength; 105 }; 106 107 /** 108 * A single block of text written to a ScrollWindow. 109 */ 110 struct ScrollWindowEntry { 111 /** 112 * ID of the line. In SSCI this was actually a memory handle for the string 113 * of this line. We use a simple numeric ID instead. 114 */ 115 reg_t id; 116 117 /** 118 * The alignment to use when rendering this line of text. If -1, the default 119 * alignment from the corresponding ScrollWindow will be used. 120 */ 121 TextAlign alignment; 122 123 /** 124 * The color to use to render this line of text. If -1, the default 125 * foreground color from the corresponding ScrollWindow will be used. 126 */ 127 int16 foreColor; 128 129 /** 130 * The font to use to render this line of text. If -1, the default font from 131 * the corresponding ScrollWindow will be used. 132 */ 133 GuiResourceId fontId; 134 135 /** 136 * The text. 137 */ 138 Common::String text; 139 }; 140 141 class ScreenItem; 142 143 /** 144 * A scrollable text window. 145 */ 146 class ScrollWindow { 147 public: 148 ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, const Common::Point &position, const reg_t planeObj, const uint8 defaultForeColor, const uint8 defaultBackColor, const GuiResourceId defaultFontId, const TextAlign defaultAlignment, const int16 defaultBorderColor, const uint16 maxNumEntries); 149 ~ScrollWindow(); 150 151 /** 152 * Adds a new text entry to the window. If `fontId`, `foreColor`, or 153 * `alignment` are `-1`, the ScrollWindow's default values will be used. 154 */ 155 reg_t add(const Common::String &text, const GuiResourceId fontId, const int16 foreColor, const TextAlign alignment, const bool scrollTo); 156 157 /** 158 * Modifies an existing text entry with the given ID. If `fontId`, 159 * `foreColor`, or `alignment` are `-1`, the ScrollWindow's default values 160 * will be used. 161 */ 162 reg_t modify(const reg_t id, const Common::String &text, const GuiResourceId fontId, const int16 foreColor, const TextAlign alignment, const bool scrollTo); 163 164 /** 165 * Shows the ScrollWindow if it is not already visible. 166 */ 167 void show(); 168 169 /** 170 * Hides the ScrollWindow if it is currently visible. 171 */ 172 void hide(); 173 174 /** 175 * Gets the number of lines that the content of a ScrollWindow is scrolled 176 * upward, as a ratio of the total number of lines of content. 177 */ 178 Ratio where() const; 179 180 /** 181 * Scrolls the window to a specific location. 182 */ 183 void go(const Ratio location); 184 185 /** 186 * Scrolls the window to the top. 187 */ 188 void home(); 189 190 /** 191 * Scrolls the window to the bottom. 192 */ 193 void end(); 194 195 /** 196 * Scrolls the window up one line. 197 */ 198 void upArrow(); 199 200 /** 201 * Scrolls the window down one line. 202 */ 203 void downArrow(); 204 205 /** 206 * Scrolls the window up by one page. 207 */ 208 void pageUp(); 209 210 /** 211 * Scrolls the window down by one page. 212 */ 213 void pageDown(); 214 215 /** 216 * Gets a reference to the in-memory bitmap that is used to render the text 217 * in the ScrollWindow. 218 */ getBitmap()219 const reg_t getBitmap() const { return _bitmap; } 220 221 private: 222 SegManager *_segMan; 223 224 typedef Common::Array<ScrollWindowEntry> EntriesList; 225 226 /** 227 * A convenience function that fills a ScrollWindowEntry's properties. 228 */ 229 void fillEntry(ScrollWindowEntry &entry, const Common::String &text, const GuiResourceId fontId, const int16 foreColor, const TextAlign alignment); 230 231 /** 232 * Rescans the entire text of the ScrollWindow when an entry is added or 233 * modified, calculating the character offsets of all line endings, the 234 * total number of lines of text, the height of the viewport (in lines of 235 * text), the last character visible in the viewport (assuming the viewport 236 * is scrolled to the top), and the line index of the bottommost visible 237 * line (assuming the viewport is scrolled to the top). 238 */ 239 void computeLineIndices(); 240 241 /** 242 * Calculates which text is visible within the ScrollWindow's viewport and 243 * renders the text to the internal bitmap. 244 * 245 * If `doFrameOut` is true, the screen will be refreshed immediately instead 246 * of waiting for the next call to `kFrameOut`. 247 */ 248 void update(const bool doFrameOut); 249 250 /** 251 * The text renderer. 252 */ 253 GfxText32 _gfxText32; 254 255 /** 256 * The individual text entries added to the ScrollWindow. 257 */ 258 EntriesList _entries; 259 260 /** 261 * The maximum number of entries allowed. Once this limit is reached, the 262 * oldest entry will be removed when a new entry is added. 263 */ 264 uint _maxNumEntries; 265 266 /** 267 * A mapping from a line index to the line's character offset in `_text`. 268 */ 269 Common::Array<int> _startsOfLines; 270 271 /** 272 * All text added to the window. 273 */ 274 Common::String _text; 275 276 /** 277 * Text that is within the viewport of the ScrollWindow. 278 */ 279 Common::String _visibleText; 280 281 /** 282 * The offset of the first visible character in `_text`. 283 */ 284 int _firstVisibleChar; 285 286 /** 287 * The index of the line that is at the top of the viewport. 288 */ 289 int _topVisibleLine; 290 291 /** 292 * The index of the last visible character in `_text`, or -1 if there is no 293 * text. 294 */ 295 int _lastVisibleChar; 296 297 /** 298 * The index of the line that is at the bottom of the viewport, or -1 if 299 * there is no text. 300 */ 301 int _bottomVisibleLine; 302 303 /** 304 * The total number of lines in the backbuffer. This number may be higher 305 * than the total number of entries if an entry contains newlines. 306 */ 307 int _numLines; 308 309 /** 310 * The number of lines that are currently visible in the text area of the 311 * window. 312 */ 313 int _numVisibleLines; 314 315 /** 316 * The plane in which the ScrollWindow should be rendered. 317 */ 318 reg_t _plane; 319 320 /** 321 * The default text color. 322 */ 323 uint8 _foreColor; 324 325 /** 326 * The default background color of the text bitmap. 327 */ 328 uint8 _backColor; 329 330 /** 331 * The default border color of the text bitmap. If -1, the viewport will 332 * have no border. 333 */ 334 int16 _borderColor; 335 336 /** 337 * The default font used for rendering text into the ScrollWindow. 338 */ 339 GuiResourceId _fontId; 340 341 /** 342 * The default text alignment used for rendering text into the ScrollWindow. 343 */ 344 TextAlign _alignment; 345 346 /** 347 * The visibility of the ScrollWindow. 348 */ 349 bool _visible; 350 351 /** 352 * The dimensions of the text box inside the font bitmap, in text-system 353 * coordinates. 354 */ 355 Common::Rect _textRect; 356 357 /** 358 * The top-left corner of the ScrollWindow's screen item, in game script 359 * coordinates, relative to the parent plane. 360 */ 361 Common::Point _position; 362 363 /** 364 * The height of the default font in screen pixels. All fonts rendered into 365 * the ScrollWindow must have this same height. 366 */ 367 uint8 _pointSize; 368 369 /** 370 * The bitmap used to render text. 371 */ 372 reg_t _bitmap; 373 374 /** 375 * A monotonically increasing ID used to identify text entries added to the 376 * ScrollWindow. 377 */ 378 uint16 _nextEntryId; 379 380 /** 381 * The ScrollWindow's screen item. 382 */ 383 ScreenItem *_screenItem; 384 }; 385 386 /** 387 * Controls class, handles drawing of UI controls in SCI32 games that use kernel 388 * controls instead of custom script controls. 389 */ 390 class GfxControls32 { 391 public: 392 GfxControls32(SegManager *segMan, GfxCache *cache, GfxText32 *text); 393 ~GfxControls32(); 394 395 private: 396 SegManager *_segMan; 397 GfxCache *_gfxCache; 398 GfxText32 *_gfxText32; 399 400 #pragma mark - 401 #pragma mark Text input control 402 public: 403 reg_t kernelEditText(const reg_t controlObject); 404 reg_t kernelInputText(const reg_t textObject, const reg_t titleTextObject, const int16 maxTextLength); 405 406 private: 407 /** 408 * If true, typing will overwrite text that already exists at the text 409 * cursor's current position. 410 */ 411 bool _overwriteMode; 412 413 /** 414 * The tick at which the text cursor should be toggled by `flashCursor`. 415 */ 416 uint32 _nextCursorFlashTick; 417 418 /** 419 * Draws the text cursor for the given editor. 420 */ 421 void drawCursor(TextEditor &editor); 422 423 /** 424 * Erases the text cursor for the given editor. 425 */ 426 void eraseCursor(TextEditor &editor); 427 428 /** 429 * Toggles the text cursor for the given editor to be either drawn or 430 * erased. 431 */ 432 void flashCursor(TextEditor &editor); 433 434 /** 435 * Processes an edit text event during a text box event loop. Returns true if 436 * the event changed the text. 437 */ 438 bool processEditTextEvent(const SciEvent &event, TextEditor &editor, ScreenItem *screenItem, bool &clearTextOnInput); 439 440 #pragma mark - 441 #pragma mark Scrollable window control 442 public: 443 /** 444 * Creates a new scrollable window and returns the ID for the new window, 445 * which is used by game scripts to interact with scrollable windows. 446 */ 447 reg_t makeScrollWindow(const Common::Rect &gameRect, const Common::Point &position, const reg_t plane, const uint8 defaultForeColor, const uint8 defaultBackColor, const GuiResourceId defaultFontId, const TextAlign defaultAlignment, const int16 defaultBorderColor, const uint16 maxNumEntries); 448 449 /** 450 * Gets a registered ScrollWindow instance by ID. 451 */ 452 ScrollWindow *getScrollWindow(const reg_t id); 453 454 /** 455 * Destroys the scroll window with the given ID. 456 */ 457 void destroyScrollWindow(const reg_t id); 458 459 private: 460 typedef Common::HashMap<uint16, ScrollWindow *> ScrollWindowMap; 461 462 /** 463 * Monotonically increasing ID used to identify ScrollWindow instances. 464 */ 465 uint16 _nextScrollWindowId; 466 467 /** 468 * A lookup table for registered ScrollWindow instances. 469 */ 470 ScrollWindowMap _scrollWindows; 471 472 #pragma mark - 473 #pragma mark Message box 474 public: 475 /** 476 * Displays an OS-level message dialog. 477 */ 478 reg_t kernelMessageBox(const Common::String &message, const Common::String &title, const uint16 style); 479 480 private: 481 /** 482 * Convenience function for creating and showing a message box. 483 */ 484 int16 showMessageBox(const Common::U32String &message, const Common::U32String &okLabel, const Common::U32String &altLabel, const int16 okValue, const int16 altValue); 485 }; 486 487 } // End of namespace Sci 488 489 #endif 490