aboutsummaryrefslogtreecommitdiff
path: root/gui/ThemeEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gui/ThemeEngine.cpp')
-rw-r--r--gui/ThemeEngine.cpp173
1 files changed, 90 insertions, 83 deletions
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index ee83ca620c..78ea43ad79 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -24,7 +24,6 @@
*/
#include "common/system.h"
-#include "common/events.h"
#include "common/config-manager.h"
#include "common/file.h"
#include "common/fs.h"
@@ -32,14 +31,13 @@
#include "common/tokenizer.h"
#include "common/translation.h"
-#include "graphics/colormasks.h"
#include "graphics/cursorman.h"
#include "graphics/fontman.h"
#include "graphics/imagedec.h"
#include "graphics/surface.h"
#include "graphics/VectorRenderer.h"
-#include "gui/launcher.h"
+#include "gui/widget.h"
#include "gui/ThemeEngine.h"
#include "gui/ThemeEval.h"
#include "gui/ThemeParser.h"
@@ -69,18 +67,18 @@ struct WidgetDrawData {
/** Extra space that the widget occupies when it's drawn.
E.g. when taking into account rounded corners, drop shadows, etc
- Used when restoring the widget background */
+ Used when restoring the widget background */
uint16 _backgroundOffset;
bool _buffer;
/**
- * Calculates the background threshold offset of a given DrawData item.
- * After fully loading all DrawSteps of a DrawData item, this function must be
- * called in order to calculate if such draw steps would be drawn outside of
- * the actual widget drawing zone (e.g. shadows). If this is the case, a constant
- * value will be added when restoring the background of the widget.
+ * Calculates the background threshold offset of a given DrawData item.
+ * After fully loading all DrawSteps of a DrawData item, this function must be
+ * called in order to calculate if such draw steps would be drawn outside of
+ * the actual widget drawing zone (e.g. shadows). If this is the case, a constant
+ * value will be added when restoring the background of the widget.
*/
void calcBackgroundOffset();
};
@@ -114,8 +112,8 @@ protected:
class ThemeItemTextData : public ThemeItem {
public:
ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const TextColorData *color, const Common::Rect &area, const Common::String &text,
- Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV,
- bool ellipsis, bool restoreBg, int deltaX) :
+ Graphics::TextAlign alignH, GUI::ThemeEngine::TextAlignVertical alignV,
+ bool ellipsis, bool restoreBg, int deltaX) :
ThemeItem(engine, area), _data(data), _color(color), _text(text), _alignH(alignH), _alignV(alignV),
_ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX) {}
@@ -147,71 +145,71 @@ protected:
/**********************************************************
- * Data definitions for theme engine elements
+ * Data definitions for theme engine elements
*********************************************************/
struct DrawDataInfo {
- DrawData id; ///< The actual ID of the DrawData item.
- const char *name; ///< The name of the DrawData item as it appears in the Theme Description files
- bool buffer; ///< Sets whether this item is buffered on the backbuffer or drawn directly to the screen.
- DrawData parent; ///< Parent DrawData item, for items that overlay. E.g. kButtonIdle -> kButtonHover
+ DrawData id; ///< The actual ID of the DrawData item.
+ const char *name; ///< The name of the DrawData item as it appears in the Theme Description files
+ bool buffer; ///< Sets whether this item is buffered on the backbuffer or drawn directly to the screen.
+ DrawData parent; ///< Parent DrawData item, for items that overlay. E.g. kButtonIdle -> kButtonHover
};
/**
* Default values for each DrawData item.
*/
static const DrawDataInfo kDrawDataDefaults[] = {
- {kDDMainDialogBackground, "mainmenu_bg", true, kDDNone},
- {kDDSpecialColorBackground, "special_bg", true, kDDNone},
- {kDDPlainColorBackground, "plain_bg", true, kDDNone},
- {kDDTooltipBackground, "tooltip_bg", true, kDDNone},
- {kDDDefaultBackground, "default_bg", true, kDDNone},
- {kDDTextSelectionBackground, "text_selection", false, kDDNone},
- {kDDTextSelectionFocusBackground, "text_selection_focus", false, kDDNone},
+ {kDDMainDialogBackground, "mainmenu_bg", true, kDDNone},
+ {kDDSpecialColorBackground, "special_bg", true, kDDNone},
+ {kDDPlainColorBackground, "plain_bg", true, kDDNone},
+ {kDDTooltipBackground, "tooltip_bg", true, kDDNone},
+ {kDDDefaultBackground, "default_bg", true, kDDNone},
+ {kDDTextSelectionBackground, "text_selection", false, kDDNone},
+ {kDDTextSelectionFocusBackground, "text_selection_focus", false, kDDNone},
- {kDDWidgetBackgroundDefault, "widget_default", true, kDDNone},
- {kDDWidgetBackgroundSmall, "widget_small", true, kDDNone},
- {kDDWidgetBackgroundEditText, "widget_textedit", true, kDDNone},
- {kDDWidgetBackgroundSlider, "widget_slider", true, kDDNone},
+ {kDDWidgetBackgroundDefault, "widget_default", true, kDDNone},
+ {kDDWidgetBackgroundSmall, "widget_small", true, kDDNone},
+ {kDDWidgetBackgroundEditText, "widget_textedit", true, kDDNone},
+ {kDDWidgetBackgroundSlider, "widget_slider", true, kDDNone},
- {kDDButtonIdle, "button_idle", true, kDDWidgetBackgroundSlider},
- {kDDButtonHover, "button_hover", false, kDDButtonIdle},
- {kDDButtonDisabled, "button_disabled", true, kDDNone},
+ {kDDButtonIdle, "button_idle", true, kDDWidgetBackgroundSlider},
+ {kDDButtonHover, "button_hover", false, kDDButtonIdle},
+ {kDDButtonDisabled, "button_disabled", true, kDDNone},
- {kDDSliderFull, "slider_full", false, kDDNone},
- {kDDSliderHover, "slider_hover", false, kDDNone},
- {kDDSliderDisabled, "slider_disabled", false, kDDNone},
+ {kDDSliderFull, "slider_full", false, kDDNone},
+ {kDDSliderHover, "slider_hover", false, kDDNone},
+ {kDDSliderDisabled, "slider_disabled", false, kDDNone},
- {kDDCheckboxDefault, "checkbox_default", true, kDDNone},
- {kDDCheckboxDisabled, "checkbox_disabled", true, kDDNone},
- {kDDCheckboxSelected, "checkbox_selected", false, kDDCheckboxDefault},
+ {kDDCheckboxDefault, "checkbox_default", true, kDDNone},
+ {kDDCheckboxDisabled, "checkbox_disabled", true, kDDNone},
+ {kDDCheckboxSelected, "checkbox_selected", false, kDDCheckboxDefault},
- {kDDRadiobuttonDefault, "radiobutton_default", true, kDDNone},
- {kDDRadiobuttonDisabled, "radiobutton_disabled", true, kDDNone},
- {kDDRadiobuttonSelected, "radiobutton_selected", false, kDDRadiobuttonDefault},
+ {kDDRadiobuttonDefault, "radiobutton_default", true, kDDNone},
+ {kDDRadiobuttonDisabled, "radiobutton_disabled", true, kDDNone},
+ {kDDRadiobuttonSelected, "radiobutton_selected", false, kDDRadiobuttonDefault},
- {kDDTabActive, "tab_active", false, kDDTabInactive},
- {kDDTabInactive, "tab_inactive", true, kDDNone},
- {kDDTabBackground, "tab_background", true, kDDNone},
+ {kDDTabActive, "tab_active", false, kDDTabInactive},
+ {kDDTabInactive, "tab_inactive", true, kDDNone},
+ {kDDTabBackground, "tab_background", true, kDDNone},
- {kDDScrollbarBase, "scrollbar_base", true, kDDNone},
+ {kDDScrollbarBase, "scrollbar_base", true, kDDNone},
- {kDDScrollbarButtonIdle, "scrollbar_button_idle", true, kDDNone},
- {kDDScrollbarButtonHover, "scrollbar_button_hover", false, kDDScrollbarButtonIdle},
+ {kDDScrollbarButtonIdle, "scrollbar_button_idle", true, kDDNone},
+ {kDDScrollbarButtonHover, "scrollbar_button_hover", false, kDDScrollbarButtonIdle},
- {kDDScrollbarHandleIdle, "scrollbar_handle_idle", false, kDDNone},
- {kDDScrollbarHandleHover, "scrollbar_handle_hover", false, kDDScrollbarBase},
+ {kDDScrollbarHandleIdle, "scrollbar_handle_idle", false, kDDNone},
+ {kDDScrollbarHandleHover, "scrollbar_handle_hover", false, kDDScrollbarBase},
- {kDDPopUpIdle, "popup_idle", true, kDDNone},
- {kDDPopUpHover, "popup_hover", false, kDDPopUpIdle},
- {kDDPopUpDisabled, "popup_disabled", true, kDDNone},
+ {kDDPopUpIdle, "popup_idle", true, kDDNone},
+ {kDDPopUpHover, "popup_hover", false, kDDPopUpIdle},
+ {kDDPopUpDisabled, "popup_disabled", true, kDDNone},
- {kDDCaret, "caret", false, kDDNone},
- {kDDSeparator, "separator", true, kDDNone},
+ {kDDCaret, "caret", false, kDDNone},
+ {kDDSeparator, "separator", true, kDDNone},
};
/**********************************************************
- * ThemeItem functions for drawing queues.
+ * ThemeItem functions for drawing queues.
*********************************************************/
void ThemeItemDrawData::drawSelf(bool draw, bool restore) {
@@ -259,7 +257,7 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) {
/**********************************************************
- * ThemeEngine class
+ * ThemeEngine class
*********************************************************/
ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) :
_system(0), _vectorRenderer(0),
@@ -326,7 +324,7 @@ ThemeEngine::~ThemeEngine() {
/**********************************************************
- * Rendering mode management
+ * Rendering mode management
*********************************************************/
const ThemeEngine::Renderer ThemeEngine::_rendererModes[] = {
{ _s("Disabled GFX"), _sc("Disabled GFX", "lowres"), "none", kGfxDisabled },
@@ -368,13 +366,13 @@ const char *ThemeEngine::findModeConfigName(GraphicsMode mode) {
/**********************************************************
- * Theme setup/initialization
+ * Theme setup/initialization
*********************************************************/
bool ThemeEngine::init() {
// reset everything and reload the graphics
_initOk = false;
- setGraphicsMode(_graphicsMode);
_overlayFormat = _system->getOverlayFormat();
+ setGraphicsMode(_graphicsMode);
if (_screen.pixels && _backBuffer.pixels) {
_initOk = true;
@@ -499,10 +497,10 @@ void ThemeEngine::setGraphicsMode(GraphicsMode mode) {
uint32 height = _system->getOverlayHeight();
_backBuffer.free();
- _backBuffer.create(width, height, _bytesPerPixel);
+ _backBuffer.create(width, height, _overlayFormat);
_screen.free();
- _screen.create(width, height, _bytesPerPixel);
+ _screen.create(width, height, _overlayFormat);
delete _vectorRenderer;
_vectorRenderer = Graphics::createRenderer(mode);
@@ -512,7 +510,7 @@ void ThemeEngine::setGraphicsMode(GraphicsMode mode) {
void WidgetDrawData::calcBackgroundOffset() {
uint maxShadow = 0;
for (Common::List<Graphics::DrawStep>::const_iterator step = _steps.begin();
- step != _steps.end(); ++step) {
+ step != _steps.end(); ++step) {
if ((step->autoWidth || step->autoHeight) && step->shadow > maxShadow)
maxShadow = step->shadow;
@@ -531,7 +529,7 @@ void ThemeEngine::restoreBackground(Common::Rect r) {
/**********************************************************
- * Theme elements management
+ * Theme elements management
*********************************************************/
void ThemeEngine::addDrawStep(const Common::String &drawDataId, const Graphics::DrawStep &step) {
DrawData id = parseDrawDataId(drawDataId);
@@ -659,7 +657,7 @@ bool ThemeEngine::addDrawData(const Common::String &data, bool cached) {
/**********************************************************
- * Theme XML loading
+ * Theme XML loading
*********************************************************/
void ThemeEngine::loadTheme(const Common::String &themeId) {
unloadTheme();
@@ -717,9 +715,9 @@ bool ThemeEngine::loadDefaultXML() {
#ifndef DISABLE_GUI_BUILTIN_THEME
const char *defaultXML =
#include "themes/default.inc"
- ;
+ ;
- if (!_parser->loadBuffer((const byte*)defaultXML, strlen(defaultXML)))
+ if (!_parser->loadBuffer((const byte *)defaultXML, strlen(defaultXML)))
return false;
_themeName = "ScummVM Classic Theme (Builtin Version)";
@@ -793,7 +791,7 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeId) {
/**********************************************************
- * Drawing Queue management
+ * Drawing Queue management
*********************************************************/
void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic, bool restore) {
if (_widgets[type] == 0)
@@ -820,7 +818,7 @@ void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic,
}
void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
- bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax) {
+ bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax) {
if (_texts[type] == 0)
return;
@@ -856,7 +854,7 @@ void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rec
/**********************************************************
- * Widget drawing functions
+ * Widget drawing functions
*********************************************************/
void ThemeEngine::drawButton(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, uint16 hints) {
if (!ready())
@@ -1088,7 +1086,7 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co
}
if (active >= 0 &&
- (r.left + active * tabWidth < r.right) && (r.left + (active + 1) * tabWidth < r.right)) {
+ (r.left + active * tabWidth < r.right) && (r.left + (active + 1) * tabWidth < r.right)) {
Common::Rect tabRect(r.left + active * tabWidth, r.top, r.left + (active + 1) * tabWidth, r.top + tabHeight);
const uint16 tabLeft = active * tabWidth;
const uint16 tabRight = MAX(r.right - tabRect.right, 0);
@@ -1191,25 +1189,25 @@ void ThemeEngine::debugWidgetPosition(const char *name, const Common::Rect &r) {
}
/**********************************************************
- * Screen/overlay management
+ * Screen/overlay management
*********************************************************/
-void ThemeEngine::updateScreen() {
+void ThemeEngine::updateScreen(bool render) {
if (!_bufferQueue.empty()) {
_vectorRenderer->setSurface(&_backBuffer);
- for (Common::List<ThemeItem*>::iterator q = _bufferQueue.begin(); q != _bufferQueue.end(); ++q) {
+ for (Common::List<ThemeItem *>::iterator q = _bufferQueue.begin(); q != _bufferQueue.end(); ++q) {
(*q)->drawSelf(true, false);
delete *q;
}
_vectorRenderer->setSurface(&_screen);
- memcpy(_screen.getBasePtr(0,0), _backBuffer.getBasePtr(0,0), _screen.pitch * _screen.h);
+ memcpy(_screen.getBasePtr(0, 0), _backBuffer.getBasePtr(0, 0), _screen.pitch * _screen.h);
_bufferQueue.clear();
}
if (!_screenQueue.empty()) {
_vectorRenderer->disableShadows();
- for (Common::List<ThemeItem*>::iterator q = _screenQueue.begin(); q != _screenQueue.end(); ++q) {
+ for (Common::List<ThemeItem *>::iterator q = _screenQueue.begin(); q != _screenQueue.end(); ++q) {
(*q)->drawSelf(true, false);
delete *q;
}
@@ -1218,7 +1216,8 @@ void ThemeEngine::updateScreen() {
_screenQueue.clear();
}
- renderDirtyScreen();
+ if (render)
+ renderDirtyScreen();
}
void ThemeEngine::addDirtyRect(Common::Rect r) {
@@ -1231,7 +1230,7 @@ void ThemeEngine::addDirtyRect(Common::Rect r) {
// Check if the new rectangle is contained within another in the list
Common::List<Common::Rect>::iterator it;
- for (it = _dirtyScreen.begin(); it != _dirtyScreen.end(); ) {
+ for (it = _dirtyScreen.begin(); it != _dirtyScreen.end();) {
// If we find a rectangle which fully contains the new one,
// we can abort the search.
if (it->contains(r))
@@ -1270,7 +1269,7 @@ void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) {
addDirtyRect(Common::Rect(0, 0, _screen.w, _screen.h));
}
- memcpy(_backBuffer.getBasePtr(0,0), _screen.getBasePtr(0,0), _screen.pitch * _screen.h);
+ memcpy(_backBuffer.getBasePtr(0, 0), _screen.getBasePtr(0, 0), _screen.pitch * _screen.h);
_vectorRenderer->setSurface(&_screen);
}
@@ -1309,8 +1308,8 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
// Now, scan the bitmap. We have to convert it from 16 bit color mode
// to 8 bit mode, and have to create a suitable palette on the fly.
uint colorsFound = 0;
- Common::HashMap<int, int> colorToIndex;
- const OverlayColor *src = (const OverlayColor*)cursor->pixels;
+ Common::HashMap<int, int> colorToIndex;
+ const OverlayColor *src = (const OverlayColor *)cursor->pixels;
for (uint y = 0; y < _cursorHeight; ++y) {
for (uint x = 0; x < _cursorWidth; ++x) {
byte r, g, b;
@@ -1352,7 +1351,7 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
/**********************************************************
- * Legacy GUI::Theme support functions
+ * Legacy GUI::Theme support functions
*********************************************************/
const Graphics::Font *ThemeEngine::getFont(FontStyle font) const {
@@ -1388,7 +1387,7 @@ DrawData ThemeEngine::parseDrawDataId(const Common::String &name) const {
}
/**********************************************************
- * External data loading
+ * External data loading
*********************************************************/
const Graphics::Font *ThemeEngine::loadFontFromArchive(const Common::String &filename) {
@@ -1497,10 +1496,16 @@ Common::String ThemeEngine::genLocalizedFontFilename(const Common::String &filen
/**********************************************************
- * Static Theme XML functions
+ * Static Theme XML functions
*********************************************************/
bool ThemeEngine::themeConfigParseHeader(Common::String header, Common::String &themeName) {
+ // Check that header is not corrupted
+ if ((byte)header[0] > 127) {
+ warning("Corrupted theme header found");
+ return false;
+ }
+
header.trim();
if (header.empty())
@@ -1583,7 +1588,9 @@ struct TDComparator {
const Common::String _id;
TDComparator(const Common::String &id) : _id(id) {}
- bool operator()(const ThemeEngine::ThemeDescriptor &r) { return _id == r.id; }
+ bool operator()(const ThemeEngine::ThemeDescriptor &r) {
+ return _id == r.id;
+ }
};
} // end of anonymous namespace
@@ -1625,7 +1632,7 @@ void ThemeEngine::listUsableThemes(Common::Archive &archive, Common::List<ThemeD
Common::ArchiveMemberList fileList;
archive.listMatchingMembers(fileList, "*.zip");
for (Common::ArchiveMemberList::iterator i = fileList.begin();
- i != fileList.end(); ++i) {
+ i != fileList.end(); ++i) {
td.name.clear();
if (themeConfigUsable(**i, td.name)) {
td.filename = (*i)->getName();