aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
Diffstat (limited to 'gui')
-rw-r--r--gui/GuiManager.cpp160
-rw-r--r--gui/GuiManager.h20
-rw-r--r--gui/ThemeEngine.cpp207
-rw-r--r--gui/ThemeEngine.h24
-rw-r--r--gui/themebrowser.cpp4
-rw-r--r--gui/themebrowser.h4
6 files changed, 223 insertions, 196 deletions
diff --git a/gui/GuiManager.cpp b/gui/GuiManager.cpp
index 95ab7e9fac..4b84901e7d 100644
--- a/gui/GuiManager.cpp
+++ b/gui/GuiManager.cpp
@@ -81,17 +81,10 @@ GuiManager::~GuiManager() {
delete _theme;
}
-bool GuiManager::loadNewTheme(Common::String filename, ThemeEngine::GraphicsMode gfx) {
- // We currently allow two different ways of theme selection in our config file:
- // 1) Via full path
- // 2) Via a basename, which will need to be translated into a full path
- // This function assures we have a correct path to pass to the ThemeEngine
- // constructor.
- filename = findThemeFile(filename);
-
+bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx) {
// If we are asked to reload the currently active theme, just do nothing
// FIXME: Actually, why? It might be desirable at times to force a theme reload...
- if (_theme && filename == _theme->getThemeId() && gfx == _theme->getGraphicsMode())
+ if (_theme && id == _theme->getThemeId() && gfx == _theme->getGraphicsMode())
return true;
ThemeEngine *newTheme = 0;
@@ -100,7 +93,7 @@ bool GuiManager::loadNewTheme(Common::String filename, ThemeEngine::GraphicsMode
gfx = ThemeEngine::_defaultRendererMode;
// Try to load the new theme
- newTheme = new ThemeEngine(filename, gfx);
+ newTheme = new ThemeEngine(id, gfx);
assert(newTheme);
if (!newTheme->init())
@@ -139,153 +132,6 @@ bool GuiManager::loadNewTheme(Common::String filename, ThemeEngine::GraphicsMode
return true;
}
-namespace {
-
-struct TDComparator {
- const Common::String _id;
- TDComparator(const Common::String &id) : _id(id) {}
-
- bool operator()(const GuiManager::ThemeDescriptor &r) { return _id == r.id; }
-};
-
-} // end of anonymous namespace
-
-void GuiManager::listUsableThemes(Common::List<ThemeDescriptor> &list) {
- ThemeDescriptor th;
- th.name = "ScummVM Classic Theme (Builtin Version)";
- th.id = "builtin";
- th.filename = "builtin";
- list.push_back(th);
-
- if (ConfMan.hasKey("themepath"))
- listUsableThemes(Common::FSNode(ConfMan.get("themepath")), list);
-
-#ifdef DATA_PATH
- listUsableThemes(Common::FSNode(DATA_PATH), list);
-#endif
-
-#ifdef MACOSX
- CFURLRef resourceUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
- if (resourceUrl) {
- char buf[256];
- if (CFURLGetFileSystemRepresentation(resourceUrl, true, (UInt8 *)buf, 256)) {
- Common::FSNode resourcePath(buf);
- listUsableThemes(resourcePath, list);
- }
- CFRelease(resourceUrl);
- }
-#endif
-
- if (ConfMan.hasKey("extrapath"))
- listUsableThemes(Common::FSNode(ConfMan.get("extrapath")), list);
-
- listUsableThemes(Common::FSNode("."), list);
-
- // Now we need to strip all duplicates
- // TODO: It might not be the best idea to strip duplicates. The user might
- // have different versions of a specific theme in his paths, thus this code
- // might show him the wrong version. The problem is we have no ways of checking
- // a theme version currently. Also since we want to avoid saving the full path
- // in the config file we can not do any better currently.
- Common::List<ThemeDescriptor> output;
-
- for (Common::List<ThemeDescriptor>::const_iterator i = list.begin(); i != list.end(); ++i) {
- if (find_if(output.begin(), output.end(), TDComparator(i->id)) == output.end())
- output.push_back(*i);
- }
-
- list = output;
- output.clear();
-}
-
-void GuiManager::listUsableThemes(Common::FSNode node, Common::List<ThemeDescriptor> &list) {
- if (!node.exists() || !node.isReadable() || !node.isDirectory())
- return;
-
- ThemeDescriptor td;
-
- // Check whether we point to a valid theme directory.
- if (ThemeEngine::themeConfigUseable(node, td.name)) {
- td.filename = node.getPath();
- td.id = node.getName();
-
- list.push_back(td);
-
- // A theme directory should never contain any other themes
- // thus we just return to the caller here.
- return;
- }
-
- Common::FSList fileList;
-#ifdef USE_ZLIB
- // Check all files. We need this to find all themes inside ZIP archives.
- if (!node.getChildren(fileList, Common::FSNode::kListFilesOnly))
- return;
-
- for (Common::FSList::iterator i = fileList.begin(); i != fileList.end(); ++i) {
- // We will only process zip files for now
- if (!i->getPath().hasSuffix(".zip"))
- continue;
-
- td.name.clear();
- if (ThemeEngine::themeConfigUseable(*i, td.name)) {
- td.filename = i->getPath();
- td.id = i->getName();
-
- // If the name of the node object also contains
- // the ".zip" suffix, we will strip it.
- if (td.id.hasSuffix(".zip")) {
- for (int j = 0; j < 4; ++j)
- td.id.deleteLastChar();
- }
-
- list.push_back(td);
- }
- }
-
- fileList.clear();
-#endif
-
- // As next step we will search all subdirectories
- if (!node.getChildren(fileList, Common::FSNode::kListDirectoriesOnly))
- return;
-
- for (Common::FSList::iterator i = fileList.begin(); i != fileList.end(); ++i)
- listUsableThemes(*i, list);
-}
-
-Common::String GuiManager::findThemeFile(const Common::String &id) {
- // FIXME: Actually "default" rather sounds like it should use
- // our default theme which would me "scummmodern" instead
- // of the builtin one.
- if (id.equalsIgnoreCase("default"))
- return "builtin";
-
- Common::FSNode node(id);
-
- // If the given id is a full path we'll just use it
- if (node.exists() && (node.isDirectory() || (node.getName().hasSuffix(".zip") && !node.isDirectory())))
- return id;
-
- // FIXME:
- // A very ugly hack to map a id to a filename, this will generate
- // a complete theme list, thus it is slower than it could be.
- // But it is the easiest solution for now.
- Common::List<ThemeDescriptor> list;
- listUsableThemes(list);
-
- for (Common::List<ThemeDescriptor>::const_iterator i = list.begin(); i != list.end(); ++i) {
- if (id.equalsIgnoreCase(i->id))
- return i->filename;
- }
-
- warning("Could not find theme '%s' falling back to builtin", id.c_str());
-
- // If no matching id has been found we will
- // just fall back to the builtin theme
- return "builtin";
-}
-
void GuiManager::redraw() {
int i;
diff --git a/gui/GuiManager.h b/gui/GuiManager.h
index 2f3f3711ab..ecaf680423 100644
--- a/gui/GuiManager.h
+++ b/gui/GuiManager.h
@@ -29,8 +29,6 @@
#include "common/singleton.h"
#include "common/stack.h"
#include "common/str.h"
-#include "common/list.h"
-#include "common/fs.h"
#include "graphics/fontman.h"
@@ -75,7 +73,7 @@ public:
bool isActive() const { return ! _dialogStack.empty(); }
- bool loadNewTheme(Common::String file, ThemeEngine::GraphicsMode gfx = ThemeEngine::kGfxDisabled);
+ bool loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx = ThemeEngine::kGfxDisabled);
ThemeEngine *theme() { return _theme; }
ThemeEval *xmlEval() { return _theme->getEvaluator(); }
@@ -92,17 +90,6 @@ public:
* @return true if the a screen change indeed occurred, false otherwise
*/
bool checkScreenChange();
-
- struct ThemeDescriptor {
- Common::String name;
- Common::String id;
- Common::String filename;
- };
-
- /**
- * Lists all theme files useable.
- */
- static void listUsableThemes(Common::List<ThemeDescriptor> &list);
protected:
enum RedrawStatus {
kRedrawDisabled = 0,
@@ -112,8 +99,6 @@ protected:
kRedrawFull
};
-
-
OSystem *_system;
ThemeEngine *_theme;
@@ -157,9 +142,6 @@ protected:
Dialog *getTopDialog() const;
void screenChange();
-
- Common::String findThemeFile(const Common::String &id);
- static void listUsableThemes(Common::FSNode node, Common::List<ThemeDescriptor> &list);
};
} // End of namespace GUI
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 4d20ef6dd1..4ee8bc2332 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -50,7 +50,7 @@ namespace GUI {
/**********************************************************
* ThemeEngine class
*********************************************************/
-ThemeEngine::ThemeEngine(Common::String fileName, GraphicsMode mode) :
+ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) :
_system(0), _vectorRenderer(0),
_buffering(false), _bytesPerPixel(0), _graphicsMode(kGfxDisabled),
_font(0), _initOk(false), _themeOk(false), _enabled(false), _cursor(0) {
@@ -69,8 +69,17 @@ ThemeEngine::ThemeEngine(Common::String fileName, GraphicsMode mode) :
_texts[i] = 0;
}
+ // We currently allow two different ways of theme selection in our config file:
+ // 1) Via full path
+ // 2) Via a basename, which will need to be translated into a full path
+ // This function assures we have a correct path to pass to the ThemeEngine
+ // constructor.
+ _themeFile = getThemeFile(id);
+ // We will use getThemeId to retrive the theme id from the given filename
+ // here, since the user could have passed a fixed filename as 'id'.
+ _themeId = getThemeId(_themeFile);
+
_graphicsMode = mode;
- _themeId = fileName;
_themeArchive = 0;
_initOk = false;
}
@@ -164,10 +173,10 @@ bool ThemeEngine::init() {
}
// Try to create a Common::Archive with the files of the theme.
- if (!_themeArchive && _themeId != "builtin") {
- Common::FSNode node(_themeId);
+ if (!_themeArchive && !_themeFile.empty()) {
+ Common::FSNode node(_themeFile);
if (node.getName().hasSuffix(".zip") && !node.isDirectory()) {
- #ifdef USE_ZLIB
+#ifdef USE_ZLIB
Common::ZipArchive *zipArchive = new Common::ZipArchive(node);
if (!zipArchive || !zipArchive->isOpen()) {
@@ -176,15 +185,20 @@ bool ThemeEngine::init() {
warning("Failed to open Zip archive '%s'.", node.getPath().c_str());
}
_themeArchive = zipArchive;
-
- #endif
+#else
+ warning("Trying to load theme '%s' in a Zip archive without zLib support", _themeFile.c_str());
+ return false;
+#endif
} else if (node.isDirectory()) {
_themeArchive = new Common::FSDirectory(node);
}
}
// Load the theme
- loadTheme(_themeId);
+ // We pass the theme file here by default, so the user will
+ // have a descriptive error message. The only exception will
+ // be the builtin theme which has no filename.
+ loadTheme(_themeFile.empty() ? _themeId : _themeFile);
return ready();
}
@@ -448,8 +462,6 @@ bool ThemeEngine::loadDefaultXML() {
// file inside the themes directory.
// Use the Python script "makedeftheme.py" to convert a normal XML theme
// into the "default.inc" file, which is ready to be included in the code.
- bool result;
-
#ifdef GUI_ENABLE_BUILTIN_THEME
const char *defaultXML =
#include "themes/default.inc"
@@ -460,8 +472,9 @@ bool ThemeEngine::loadDefaultXML() {
_themeName = "ScummVM Classic Theme (Builtin Version)";
_themeId = "builtin";
+ _themeFile.clear();
- result = _parser->parse();
+ bool result = _parser->parse();
_parser->close();
return result;
@@ -1114,7 +1127,7 @@ bool ThemeEngine::themeConfigParseHeader(Common::String header, Common::String &
return tok.empty();
}
-bool ThemeEngine::themeConfigUseable(const Common::FSNode &node, Common::String &themeName) {
+bool ThemeEngine::themeConfigUsable(const Common::FSNode &node, Common::String &themeName) {
Common::File stream;
bool foundHeader = false;
@@ -1140,5 +1153,175 @@ bool ThemeEngine::themeConfigUseable(const Common::FSNode &node, Common::String
return foundHeader;
}
+namespace {
+
+struct TDComparator {
+ const Common::String _id;
+ TDComparator(const Common::String &id) : _id(id) {}
+
+ bool operator()(const ThemeEngine::ThemeDescriptor &r) { return _id == r.id; }
+};
+
+} // end of anonymous namespace
+
+void ThemeEngine::listUsableThemes(Common::List<ThemeDescriptor> &list) {
+#ifdef GUI_ENABLE_BUILTIN_THEME
+ ThemeDescriptor th;
+ th.name = "ScummVM Classic Theme (Builtin Version)";
+ th.id = "builtin";
+ th.filename = "";
+ list.push_back(th);
+#endif
+
+ if (ConfMan.hasKey("themepath"))
+ listUsableThemes(Common::FSNode(ConfMan.get("themepath")), list);
+
+#ifdef DATA_PATH
+ listUsableThemes(Common::FSNode(DATA_PATH), list);
+#endif
+
+#ifdef MACOSX
+ CFURLRef resourceUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
+ if (resourceUrl) {
+ char buf[256];
+ if (CFURLGetFileSystemRepresentation(resourceUrl, true, (UInt8 *)buf, 256)) {
+ Common::FSNode resourcePath(buf);
+ listUsableThemes(resourcePath, list);
+ }
+ CFRelease(resourceUrl);
+ }
+#endif
+
+ if (ConfMan.hasKey("extrapath"))
+ listUsableThemes(Common::FSNode(ConfMan.get("extrapath")), list);
+
+ listUsableThemes(Common::FSNode("."), list);
+
+ // Now we need to strip all duplicates
+ // TODO: It might not be the best idea to strip duplicates. The user might
+ // have different versions of a specific theme in his paths, thus this code
+ // might show him the wrong version. The problem is we have no ways of checking
+ // a theme version currently. Also since we want to avoid saving the full path
+ // in the config file we can not do any better currently.
+ Common::List<ThemeDescriptor> output;
+
+ for (Common::List<ThemeDescriptor>::const_iterator i = list.begin(); i != list.end(); ++i) {
+ if (find_if(output.begin(), output.end(), TDComparator(i->id)) == output.end())
+ output.push_back(*i);
+ }
+
+ list = output;
+ output.clear();
+}
+
+void ThemeEngine::listUsableThemes(Common::FSNode node, Common::List<ThemeDescriptor> &list) {
+ if (!node.exists() || !node.isReadable() || !node.isDirectory())
+ return;
+
+ ThemeDescriptor td;
+
+ // Check whether we point to a valid theme directory.
+ if (themeConfigUsable(node, td.name)) {
+ td.filename = node.getPath();
+ td.id = node.getName();
+
+ list.push_back(td);
+
+ // A theme directory should never contain any other themes
+ // thus we just return to the caller here.
+ return;
+ }
+
+ Common::FSList fileList;
+#ifdef USE_ZLIB
+ // Check all files. We need this to find all themes inside ZIP archives.
+ if (!node.getChildren(fileList, Common::FSNode::kListFilesOnly))
+ return;
+
+ for (Common::FSList::iterator i = fileList.begin(); i != fileList.end(); ++i) {
+ // We will only process zip files for now
+ if (!i->getPath().hasSuffix(".zip"))
+ continue;
+
+ td.name.clear();
+ if (themeConfigUsable(*i, td.name)) {
+ td.filename = i->getPath();
+ td.id = i->getName();
+
+ // If the name of the node object also contains
+ // the ".zip" suffix, we will strip it.
+ if (td.id.hasSuffix(".zip")) {
+ for (int j = 0; j < 4; ++j)
+ td.id.deleteLastChar();
+ }
+
+ list.push_back(td);
+ }
+ }
+
+ fileList.clear();
+#endif
+
+ // As next step we will search all subdirectories
+ if (!node.getChildren(fileList, Common::FSNode::kListDirectoriesOnly))
+ return;
+
+ for (Common::FSList::iterator i = fileList.begin(); i != fileList.end(); ++i)
+ listUsableThemes(*i, list);
+}
+
+Common::String ThemeEngine::getThemeFile(const Common::String &id) {
+ // FIXME: Actually "default" rather sounds like it should use
+ // our default theme which would mean "scummmodern" instead
+ // of the builtin one.
+ if (id.equalsIgnoreCase("default"))
+ return "";
+
+ Common::FSNode node(id);
+
+ // If the given id is a full path we'll just use it
+ if (node.exists() && (node.isDirectory() || (node.getName().hasSuffix(".zip") && !node.isDirectory())))
+ return id;
+
+ // FIXME:
+ // A very ugly hack to map a id to a filename, this will generate
+ // a complete theme list, thus it is slower than it could be.
+ // But it is the easiest solution for now.
+ Common::List<ThemeDescriptor> list;
+ listUsableThemes(list);
+
+ for (Common::List<ThemeDescriptor>::const_iterator i = list.begin(); i != list.end(); ++i) {
+ if (id.equalsIgnoreCase(i->id))
+ return i->filename;
+ }
+
+ warning("Could not find theme '%s' falling back to builtin", id.c_str());
+
+ // If no matching id has been found we will
+ // just fall back to the builtin theme
+ return "";
+}
+
+Common::String ThemeEngine::getThemeId(const Common::String &filename) {
+ // If no filename has been given we will initialize the builtin theme
+ if (filename.empty())
+ return "builtin";
+
+ Common::FSNode node(filename);
+ if (!node.exists())
+ return "builtin";
+
+ if (node.getName().hasSuffix(".zip")) {
+ Common::String id = node.getName();
+
+ for (int i = 0; i < 4; ++i)
+ id.deleteLastChar();
+
+ return id;
+ } else {
+ return node.getName();
+ }
+}
+
} // end of namespace GUI.
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 1067d11b11..434730da51 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -235,7 +235,7 @@ public:
static const char *findModeConfigName(GraphicsMode mode);
/** Default constructor */
- ThemeEngine(Common::String fileName, GraphicsMode mode);
+ ThemeEngine(Common::String id, GraphicsMode mode);
/** Default destructor */
~ThemeEngine();
@@ -584,15 +584,30 @@ protected:
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 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(Common::FSNode node, Common::List<ThemeDescriptor> &list);
+
+public:
+ /**
* @name LEGACY: Old GUI::Theme API
*/
//@{
- static bool themeConfigUseable(const Common::FSNode &node, Common::String &themeName);
- static bool themeConfigParseHeader(Common::String header, Common::String &themeName);
-
int getTabSpacing() const { return 0; }
int getTabPadding() const { return 3; }
@@ -656,6 +671,7 @@ protected:
Common::String _themeName; //!< Name of the currently loaded theme
Common::String _themeId;
+ Common::String _themeFile;
Common::Archive *_themeArchive;
bool _useCursor;
diff --git a/gui/themebrowser.cpp b/gui/themebrowser.cpp
index b3db9a3405..d20320ad3e 100644
--- a/gui/themebrowser.cpp
+++ b/gui/themebrowser.cpp
@@ -73,7 +73,7 @@ void ThemeBrowser::handleCommand(CommandSender *sender, uint32 cmd, uint32 data)
break;
// TODO:
- // Currently GuiManager::listUseableThemes uses a
+ // Currently ThemeEngine::listUseableThemes uses a
// list. Thus we can not use operator[] here but
// need to iterate through the list. We might want
// to think of changing it, but it should not be
@@ -95,7 +95,7 @@ void ThemeBrowser::handleCommand(CommandSender *sender, uint32 cmd, uint32 data)
void ThemeBrowser::updateListing() {
_themes.clear();
- GuiManager::listUsableThemes(_themes);
+ ThemeEngine::listUsableThemes(_themes);
Common::StringList list;
for (ThemeDescList::const_iterator i = _themes.begin(); i != _themes.end(); ++i)
diff --git a/gui/themebrowser.h b/gui/themebrowser.h
index b6327253ca..32fef16ce0 100644
--- a/gui/themebrowser.h
+++ b/gui/themebrowser.h
@@ -26,7 +26,7 @@
#define GUI_THEMEBROWSER_H
#include "gui/dialog.h"
-#include "gui/GuiManager.h"
+#include "gui/ThemeEngine.h"
#include "common/str.h"
#include "common/list.h"
@@ -48,7 +48,7 @@ private:
ListWidget *_fileList;
Common::String _select;
- typedef Common::List<GuiManager::ThemeDescriptor> ThemeDescList;
+ typedef Common::List<ThemeEngine::ThemeDescriptor> ThemeDescList;
ThemeDescList _themes;
void updateListing();