aboutsummaryrefslogtreecommitdiff
path: root/gui/ThemeEngine.h
blob: ab77cfcbccb7ca066e0620aab08fcd27b0e1eaaf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef GUI_THEME_ENGINE_H
#define GUI_THEME_ENGINE_H

#include "common/scummsys.h"
#include "common/fs.h"
#include "common/hash-str.h"
#include "common/hashmap.h"
#include "common/list.h"
#include "common/str.h"
#include "common/rect.h"

#include "graphics/surface.h"
#include "graphics/transparent_surface.h"
#include "graphics/font.h"
#include "graphics/pixelformat.h"


#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.25"

class OSystem;

namespace Graphics {
struct DrawStep;
class VectorRenderer;
}

namespace GUI {

struct WidgetDrawData;
struct TextDrawData;
struct TextColorData;
class Dialog;
class GuiObject;
class ThemeEval;
class ThemeParser;

/**
 * DrawData sets enumeration.
 * Each DD set corresponds to the actual looks
 * of a widget in a given state.
 */
enum DrawData {
	kDDMainDialogBackground,
	kDDSpecialColorBackground,
	kDDPlainColorBackground,
	kDDTooltipBackground,
	kDDDefaultBackground,
	kDDTextSelectionBackground,
	kDDTextSelectionFocusBackground,

	kDDWidgetBackgroundDefault,
	kDDWidgetBackgroundSmall,
	kDDWidgetBackgroundEditText,
	kDDWidgetBackgroundSlider,

	kDDButtonIdle,
	kDDButtonHover,
	kDDButtonDisabled,
	kDDButtonPressed,

	kDDSliderFull,
	kDDSliderHover,
	kDDSliderDisabled,

	kDDCheckboxDefault,
	kDDCheckboxDisabled,
	kDDCheckboxSelected,

	kDDRadiobuttonDefault,
	kDDRadiobuttonDisabled,
	kDDRadiobuttonSelected,

	kDDTabActive,
	kDDTabInactive,
	kDDTabBackground,

	kDDScrollbarBase,
	kDDScrollbarButtonIdle,
	kDDScrollbarButtonHover,
	kDDScrollbarHandleIdle,
	kDDScrollbarHandleHover,

	kDDPopUpIdle,
	kDDPopUpHover,
	kDDPopUpDisabled,

	kDDCaret,
	kDDSeparator,
	kDrawDataMAX,
	kDDNone = -1
};

/**
 * Dialog layers.
 * The currently active dialog has two layers, background and foreground.
 * The background layer is drawn to the backbuffer. The foreground layer
 * is drawn to the screen. This allows draw calls to restore the background
 * layer before redrawing a widget.
 */
enum DrawLayer {
	kDrawLayerBackground,
	kDrawLayerForeground
};

// FIXME: TextData is really a bad name, not conveying what this enum is about.
enum TextData {
	kTextDataNone = -1,
	kTextDataDefault = 0,
	kTextDataButton,
	kTextDataNormalFont,
	kTextDataTooltip,
	kTextDataMAX
};

enum TextColor {
	kTextColorNormal = 0,
	kTextColorNormalInverted,
	kTextColorNormalHover,
	kTextColorNormalDisabled,
	kTextColorAlternative,
	kTextColorAlternativeInverted,
	kTextColorAlternativeHover,
	kTextColorAlternativeDisabled,
	kTextColorButton,
	kTextColorButtonHover,
	kTextColorButtonDisabled,
	kTextColorMAX
};

class ThemeEngine {
protected:
	typedef Common::HashMap<Common::String, Graphics::Surface *> ImagesMap;
	typedef Common::HashMap<Common::String, Graphics::TransparentSurface *> AImagesMap;

	friend class GUI::Dialog;
	friend class GUI::GuiObject;

public:
	/// Vertical alignment of the text.
	enum TextAlignVertical {
		kTextAlignVInvalid,
		kTextAlignVBottom,
		kTextAlignVCenter,
		kTextAlignVTop
	};

	/// Widget background type
	enum WidgetBackground {
		kWidgetBackgroundNo,            ///< No background at all
		kWidgetBackgroundPlain,         ///< Simple background, this may not include borders
		kWidgetBackgroundBorder,        ///< Same as kWidgetBackgroundPlain just with a border
		kWidgetBackgroundBorderSmall,   ///< Same as kWidgetBackgroundPlain just with a small border
		kWidgetBackgroundEditText,      ///< Background used for edit text fields
		kWidgetBackgroundSlider         ///< Background used for sliders
	};

	/// Dialog background type
	enum DialogBackground {
		kDialogBackgroundMain,
		kDialogBackgroundSpecial,
		kDialogBackgroundPlain,
		kDialogBackgroundTooltip,
		kDialogBackgroundDefault,
		kDialogBackgroundNone
	};

	/// State of the widget to be drawn
	enum State {
		kStateDisabled,     ///< Indicates that the widget is disabled, that does NOT include that it is invisible
		kStateEnabled,      ///< Indicates that the widget is enabled
		kStateHighlight,    ///< Indicates that the widget is highlighted by the user
		kStatePressed       ///< Indicates that the widget is pressed, currently works for buttons
	};

	typedef State WidgetStateInfo;

	/// Text inversion state of the text to be draw
	enum TextInversionState {
		kTextInversionNone, ///< Indicates that the text should not be drawn inverted
		kTextInversion,     ///< Indicates that the text should be drawn inverted, but not focused
		kTextInversionFocus ///< Indicates that the text should be drawn inverted, and focused
	};

	enum ScrollbarState {
		kScrollbarStateNo,
		kScrollbarStateUp,
		kScrollbarStateDown,
		kScrollbarStateSlider,
		kScrollbarStateSinglePage
	};

	/// Font style selector
	enum FontStyle {
		kFontStyleBold = 0,         ///< A bold font. This is also the default font.
		kFontStyleNormal = 1,       ///< A normal font.
		kFontStyleItalic = 2,       ///< Italic styled font.
		kFontStyleFixedNormal = 3,  ///< Fixed size font.
		kFontStyleFixedBold = 4,    ///< Fixed size bold font.
		kFontStyleFixedItalic = 5,  ///< Fixed size italic font.
		kFontStyleTooltip = 6,      ///< Tiny console font
		kFontStyleMax
	};

	/// Font color selector
	enum FontColor {
		kFontColorNormal = 0,       ///< The default color of the theme
		kFontColorAlternate = 1,    ///< Alternative font color
		kFontColorMax
	};

	/// Function used to process areas other than the current dialog
	enum ShadingStyle {
		kShadingNone,       ///< No special post processing
		kShadingDim,        ///< Dimming unused areas
		kShadingLuminance   ///< Converting colors to luminance for unused areas
	};

	/// AlphaBitmap scale mode selector
	enum AutoScaleMode {
		kAutoScaleNone = 0,		///< Use image dimensions
		kAutoScaleStretch = 1,	///< Stretch image to full widget size
		kAutoScaleFit = 2,		///< Scale image to widget size but keep aspect ratio
		kAutoScaleNinePatch = 3 ///< 9-patch image
	};

	// Special image ids for images used in the GUI
	static const char *const kImageLogo;      ///< ScummVM logo used in the launcher
	static const char *const kImageLogoSmall; ///< ScummVM logo used in the GMM
	static const char *const kImageSearch;    ///< Search tool image used in the launcher
	static const char *const kImageEraser;     ///< Clear input image used in the launcher
	static const char *const kImageDelButton; ///< Delete characters in the predictive dialog
	static const char *const kImageList;      ///< List image used in save/load chooser selection
	static const char *const kImageGrid;      ///< Grid image used in save/load chooser selection
	static const char *const kImageStopButton; ///< Stop recording button in recorder onscreen dialog
	static const char *const kImageEditButton; ///< Edit recording metadata in recorder onscreen dialog
	static const char *const kImageSwitchModeButton; ///< Switch mode button in recorder onscreen dialog
	static const char *const kImageFastReplayButton; ///< Fast playback mode button in recorder onscreen dialog
	static const char *const kImageStopSmallButton; ///< Stop recording button in recorder onscreen dialog (for 320xY)
	static const char *const kImageEditSmallButton; ///< Edit recording metadata in recorder onscreen dialog (for 320xY)
	static const char *const kImageSwitchModeSmallButton; ///< Switch mode button in recorder onscreen dialog (for 320xY)
	static const char *const kImageFastReplaySmallButton; ///< Fast playback mode button in recorder onscreen dialog (for 320xY)
	static const char *const kImageDropboxLogo;      ///< Dropbox logo used in the StorageWizardDialog
	static const char *const kImageOneDriveLogo;      ///< OneDrive logo used in the StorageWizardDialog
	static const char *const kImageGoogleDriveLogo;      ///< Google Drive logo used in the StorageWizardDialog
	static const char *const kImageBoxLogo;      ///< Box logo used in the StorageWizardDialog

	/**
	 * Graphics mode enumeration.
	 * Each item represents a set of BPP and Renderer modes for a given
	 * surface.
	 */
	enum GraphicsMode {
		kGfxDisabled = 0,   ///< No GFX
		kGfxStandard,  ///< Standard (aliased) renderer.
		kGfxAntialias  ///< Optimized AA renderer.
	};

	/** Constant value to expand dirty rectangles, to make sure they are fully copied */
	static const int kDirtyRectangleThreshold = 1;

	struct Renderer {
		const char *name;
		const char *shortname;
		const char *cfg;
		GraphicsMode mode;
	};

	static const Renderer _rendererModes[];
	static const uint _rendererModesSize;

	static const GraphicsMode _defaultRendererMode;

	static GraphicsMode findMode(const Common::String &cfg);
	static const char *findModeConfigName(GraphicsMode mode);

	/** Default constructor */
	ThemeEngine(Common::String id, GraphicsMode mode);

	/** Default destructor */
	~ThemeEngine();

	bool init();
	void clearAll();

	void refresh();
	void enable();

	void showCursor();
	void hideCursor();

	void disable();


	/**
	 * Query the set up pixel format.
	 */
	const Graphics::PixelFormat getPixelFormat() const { return _overlayFormat; }

	/**
	 * Draw full screen shading with the supplied style
	 *
	 * This is used to dim the inactive dialogs so the active one stands out.
	 */
	void applyScreenShading(ShadingStyle shading);

	/**
	 * Sets the active drawing surface to the back buffer.
	 *
	 * All drawing from this point on will be done on that surface.
	 * The back buffer surface needs to be copied to the screen surface
	 * in order to become visible.
	 */
	void drawToBackbuffer();

	/**
	 * Sets the active drawing surface to the screen.
	 *
	 * All drawing from this point on will be done on that surface.
	 */
	void drawToScreen();

	/**
	 * The updateScreen() method is called every frame.
	 * It copies dirty rectangles in the Screen surface to the overlay.
	 */
	void updateScreen();

	/**
	 * Copy the entire backbuffer surface to the screen surface
	 */
	void copyBackBufferToScreen();


	/** @name FONT MANAGEMENT METHODS */
	//@{

	TextData fontStyleToData(FontStyle font) const {
		if (font == kFontStyleNormal)
			return kTextDataNormalFont;
		if (font == kFontStyleTooltip)
			return kTextDataTooltip;
		return kTextDataDefault;
	}

	const Graphics::Font *getFont(FontStyle font = kFontStyleBold) const;

	int getFontHeight(FontStyle font = kFontStyleBold) const;

	int getStringWidth(const Common::String &str, FontStyle font = kFontStyleBold) const;

	int getCharWidth(byte c, FontStyle font = kFontStyleBold) const;

	int getKerningOffset(byte left, byte right, FontStyle font = kFontStyleBold) const;

	//@}

	/**
	 * Set the clipping rect to be used by the widget drawing methods defined below.
	 *
	 * Widgets are not drawn outside of the clipping rect. Widgets that overlap the
	 * clipping rect are drawn partially.
	 *
	 * @param newRect The new clipping rect
	 * @return The previous clipping rect
	 */
	Common::Rect swapClipRect(const Common::Rect &newRect);

	/** @name WIDGET DRAWING METHODS */
	//@{

	void drawWidgetBackground(const Common::Rect &r, uint16 hints, WidgetBackground background = kWidgetBackgroundPlain);

	void drawButton(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled,
	                uint16 hints = 0);

	void drawSurface(const Common::Rect &r, const Graphics::Surface &surface, bool themeTrans = false);

	void drawSlider(const Common::Rect &r, int width, WidgetStateInfo state = kStateEnabled);

	void drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked,
	                  WidgetStateInfo state = kStateEnabled);

	void drawRadiobutton(const Common::Rect &r, const Common::String &str, bool checked,
	                     WidgetStateInfo state = kStateEnabled);

	void drawTab(const Common::Rect &r, int tabHeight, const Common::Array<int> &tabWidths,
	             const Common::Array<Common::String> &tabs, int active);

	void drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, ScrollbarState scrollState);

	void drawPopUpWidget(const Common::Rect &r, const Common::String &sel, int deltax,
	                     WidgetStateInfo state = kStateEnabled);

	void drawCaret(const Common::Rect &r, bool erase);

	void drawLineSeparator(const Common::Rect &r);

	void drawDialogBackground(const Common::Rect &r, DialogBackground type);

	void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled,
	              Graphics::TextAlign align = Graphics::kTextAlignCenter,
	              TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true,
	              FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true,
	              const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));

	void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, FontColor color = kFontColorNormal);

	//@}



	/**
	 * Actual implementation of a dirty rect handling.
	 * Dirty rectangles are queued on a list, merged and optimized
	 * when possible and are later used for the actual drawing.
	 *
	 * @param r Area of the dirty rect.
	 */
	void addDirtyRect(Common::Rect r);


	/**
	 * Returns the DrawData enumeration value that represents the given string
	 * in the DrawDataDefaults enumeration.
	 * It's slow, but called sparsely.
	 *
	 * @returns The drawdata enum value, or -1 if not found.
	 * @param name The representing name, as found on Theme Description XML files.
	 * @see kDrawDataDefaults[]
	 */
	DrawData parseDrawDataId(const Common::String &name) const;

	TextData getTextData(DrawData ddId) const;
	TextColor getTextColor(DrawData ddId) const;


	/**
	 * Interface for ThemeParser class: Parsed DrawSteps are added via this function.
	 * There is no return type because DrawSteps can always be added, unless something
	 * goes horribly wrong.
	 * The specified step will be added to the Steps list of the given DrawData id.
	 *
	 * @param drawDataId The representing DrawData name, as found on Theme Description XML files.
	 * @param step The actual DrawStep struct to be added.
	 */
	void addDrawStep(const Common::String &drawDataId, const Graphics::DrawStep &step);

	/**
	 * Interface for the ThemeParser class: Parsed DrawData sets are added via this function.
	 * The goal of the function is to initialize each DrawData set before their DrawSteps can
	 * be added, hence this must be called for each DD set before addDrawStep() can be called
	 * for that given set.
	 *
	 * @param data The representing DrawData name, as found on Theme Description XML files.
	 * @param cached Whether this DD set will be cached beforehand.
	 */
	bool addDrawData(const Common::String &data, bool cached);


	/**
	 * Interface for the ThemeParser class: Loads a font to use on the GUI from the given
	 * filename.
	 *
	 * @param textId            Identifier name for the font.
	 * @param file              Filename of the non-scalable font version.
	 * @param scalableFile      Filename of the scalable version. (Optional)
	 * @param pointsize         Point size for the scalable font. (Optional)
	 */
	bool addFont(TextData textId, const Common::String &file, const Common::String &scalableFile, const int pointsize);

	/**
	 * Interface for the ThemeParser class: adds a text color value.
	 *
	 * @param colorId Identifier for the color type.
	 * @param r, g, b Color of the font.
	 */
	bool addTextColor(TextColor colorId, int r, int g, int b);


	/**
	 * Interface for the ThemeParser class: Loads a bitmap file to use on the GUI.
	 * The filename is also used as its identifier.
	 *
	 * @param filename Name of the bitmap file.
	 */
	bool addBitmap(const Common::String &filename);

	/**
	 * Interface for the ThemeParser class: Loads a bitmap with transparency file to use on the GUI.
	 * The filename is also used as its identifier.
	 *
	 * @param filename Name of the bitmap file.
	 */
	bool addAlphaBitmap(const Common::String &filename);

	/**
	 * Adds a new TextStep from the ThemeParser. This will be deprecated/removed once the
	 * new Font API is in place. FIXME: Is that so ???
	 */
	bool addTextData(const Common::String &drawDataId, TextData textId, TextColor id, Graphics::TextAlign alignH, TextAlignVertical alignV);

protected:
	/**
	 * Returns if the Theme is ready to draw stuff on screen.
	 * Must be called instead of just checking _initOk, because
	 * this checks if the renderer is initialized AND if the theme
	 * is loaded.
	 */
	bool ready() const {
		return _initOk && _themeOk;
	}

	/** Load the them from the file with the specified name. */
	void loadTheme(const Common::String &themeid);

	/**
	 * Changes the active graphics mode of the GUI; may be used to either
	 * initialize the GUI or to change the mode while the GUI is already running.
	 */
	void setGraphicsMode(GraphicsMode mode);

public:
	inline ThemeEval *getEvaluator() { return _themeEval; }
	inline Graphics::VectorRenderer *renderer() { return _vectorRenderer; }

	inline bool supportsImages() const { return true; }
	inline bool ownCursor() const { return _useCursor; }

	Graphics::Surface *getBitmap(const Common::String &name) {
		return _bitmaps.contains(name) ? _bitmaps[name] : 0;
	}

	Graphics::TransparentSurface *getAlphaBitmap(const Common::String &name) {
		return _abitmaps.contains(name) ? _abitmaps[name] : 0;
	}

	const Graphics::Surface *getImageSurface(const Common::String &name) const {
		return _bitmaps.contains(name) ? _bitmaps[name] : 0;
	}

	const Graphics::TransparentSurface *getAImageSurface(const Common::String &name) const {
		return _abitmaps.contains(name) ? _abitmaps[name] : 0;
	}

	/**
	 * Interface for the Theme Parser: Creates a new cursor by loading the given
	 * bitmap and sets it as the active cursor.
	 *
	 * @param filename File name of the bitmap to load.
	 * @param hotspotX X Coordinate of the bitmap which does the cursor click.
	 * @param hotspotY Y Coordinate of the bitmap which does the cursor click.
	 */
	bool createCursor(const Common::String &filename, int hotspotX, int hotspotY);

	/**
	 * Wrapper for restoring data from the Back Buffer to the screen.
	 * The actual processing is done in the VectorRenderer.
	 *
	 * @param r Area to restore.
	 */
	void restoreBackground(Common::Rect r);

	const Common::String &getThemeName() const { return _themeName; }
	const Common::String &getThemeId() const { return _themeId; }
	int getGraphicsMode() const { return _graphicsMode; }

protected:

	/**
	 * Loads the given theme into the ThemeEngine.
	 *
	 * @param themeId Theme identifier.
	 * @returns true if the theme was successfully loaded.
	 */
	bool loadThemeXML(const Common::String &themeId);

	/**
	 * Loads the default theme file (the embedded XML file found
	 * in ThemeDefaultXML.cpp).
	 * Called only when no other themes are available.
	 */
	bool loadDefaultXML();

	/**
	 * Unloads the currently loaded theme so another one can
	 * be loaded.
	 */
	void unloadTheme();

	const Graphics::Font *loadScalableFont(const Common::String &filename, const Common::String &charset, const int pointsize, Common::String &name);
	const Graphics::Font *loadFont(const Common::String &filename, Common::String &name);
	Common::String genCacheFilename(const Common::String &filename) const;
	const Graphics::Font *loadFont(const Common::String &filename, const Common::String &scalableFilename, const Common::String &charset, const int pointsize, const bool makeLocalizedFont);

	/**
	 * Dirty Screen handling function.
	 * Draws all the dirty rectangles in the list to the overlay.
	 */
	void updateDirtyScreen();

	/**
	 * Draws a GUI element according to a DrawData descriptor.
	 *
	 * Only calls with a DrawData layer attribute matching the active layer
	 * are actually drawn to the active surface.
	 *
	 * These functions are called from all the Widget drawing methods.
	 */
	void drawDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool forceRestore = false);
	void drawDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
	                bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft,
	                TextAlignVertical alignV = kTextAlignVTop, int deltax = 0,
	                const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
	void drawBitmap(const Graphics::Surface *bitmap, const Common::Rect &clippingRect, bool alpha);

	/**
	 * DEBUG: Draws a white square and writes some text next to it.
	 */
	void debugWidgetPosition(const char *name, const Common::Rect &r);

public:
	struct ThemeDescriptor {
		Common::String name;
		Common::String id;
		Common::String filename;
	};

	/**
	 * Lists all theme files useable.
	 */
	static void listUsableThemes(Common::List<ThemeDescriptor> &list);
private:
	static bool themeConfigUsable(const Common::FSNode &node, Common::String &themeName);
	static bool themeConfigUsable(const Common::ArchiveMember &member, Common::String &themeName);
	static bool themeConfigParseHeader(Common::String header, Common::String &themeName);

	static Common::String getThemeFile(const Common::String &id);
	static Common::String getThemeId(const Common::String &filename);
	static void listUsableThemes(const Common::FSNode &node, Common::List<ThemeDescriptor> &list, int depth = -1);
	static void listUsableThemes(Common::Archive &archive, Common::List<ThemeDescriptor> &list);

protected:
	OSystem *_system; /** Global system object. */

	/** Vector Renderer object, does the actual drawing on screen */
	Graphics::VectorRenderer *_vectorRenderer;

	/** XML Parser, does the Theme parsing instead of the default parser */
	GUI::ThemeParser *_parser;

	/** Theme getEvaluator (changed from GUI::Eval to add functionality) */
	GUI::ThemeEval *_themeEval;

	/** Main screen surface. This is blitted straight into the overlay. */
	Graphics::TransparentSurface _screen;

	/** Backbuffer surface. Stores previous states of the screen to blit back */
	Graphics::TransparentSurface _backBuffer;

	/**
	 * Filter the submitted DrawData descriptors according to their layer attribute
	 *
	 * This is used to selectively draw the background or foreground layer
	 * of the dialogs.
	 */
	DrawLayer _layerToDraw;

	/** Bytes per pixel of the Active Drawing Surface (i.e. the screen) */
	int _bytesPerPixel;

	/** Current graphics mode */
	GraphicsMode _graphicsMode;

	/** Font info. */
	const Graphics::Font *_font;

	/**
	 * Array of all the DrawData elements than can be drawn to the screen.
	 * Must be full so the renderer can work.
	 */
	WidgetDrawData *_widgets[kDrawDataMAX];

	/** Array of all the text fonts that can be drawn. */
	TextDrawData *_texts[kTextDataMAX];

	/** Array of all font colors available. */
	TextColorData *_textColors[kTextColorMAX];

	ImagesMap _bitmaps;
	AImagesMap _abitmaps;
	Graphics::PixelFormat _overlayFormat;
#ifdef USE_RGB_COLOR
	Graphics::PixelFormat _cursorFormat;
#endif

	/** List of all the dirty screens that must be blitted to the overlay. */
	Common::List<Common::Rect> _dirtyScreen;

	bool _initOk;  ///< Class and renderer properly initialized
	bool _themeOk; ///< Theme data successfully loaded.
	bool _enabled; ///< Whether the Theme is currently shown on the overlay

	Common::String _themeName; ///< Name of the currently loaded theme
	Common::String _themeId;
	Common::String _themeFile;
	Common::Archive *_themeArchive;
	Common::SearchSet _themeFiles;

	bool _useCursor;
	int _cursorHotspotX, _cursorHotspotY;
	enum {
		MAX_CURS_COLORS = 255
	};
	byte *_cursor;
	uint _cursorWidth, _cursorHeight;
	byte _cursorPal[3 * MAX_CURS_COLORS];
	byte _cursorPalSize;

	Common::Rect _clip;
};

} // End of namespace GUI.

#endif