[Scummvm-cvs-logs] SF.net SVN: scummvm:[35680] scummvm/trunk/gui

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Fri Jan 2 21:03:46 CET 2009


Revision: 35680
          http://scummvm.svn.sourceforge.net/scummvm/?rev=35680&view=rev
Author:   lordhoto
Date:     2009-01-02 20:03:45 +0000 (Fri, 02 Jan 2009)

Log Message:
-----------
- Added support selection of themes via a basename again (This should fix bugs #2473213 "GUI: Theme selection oddities and regressions" and #2219605 "GUI: theme detection")
- Changed default value to "scummmodern" instead of "scummmodern.zip" for "gui_theme"
- Moved theme listing code from ThemeBrowser to GuiManager

Modified Paths:
--------------
    scummvm/trunk/gui/GuiManager.cpp
    scummvm/trunk/gui/GuiManager.h
    scummvm/trunk/gui/themebrowser.cpp
    scummvm/trunk/gui/themebrowser.h

Modified: scummvm/trunk/gui/GuiManager.cpp
===================================================================
--- scummvm/trunk/gui/GuiManager.cpp	2009-01-02 19:10:51 UTC (rev 35679)
+++ scummvm/trunk/gui/GuiManager.cpp	2009-01-02 20:03:45 UTC (rev 35680)
@@ -26,6 +26,7 @@
 #include "common/system.h"
 #include "common/util.h"
 #include "common/config-manager.h"
+#include "common/algorithm.h"
 
 #include "gui/GuiManager.h"
 #include "gui/dialog.h"
@@ -34,6 +35,10 @@
 
 #include "graphics/cursorman.h"
 
+#ifdef MACOSX
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
 DECLARE_SINGLETON(GUI::GuiManager);
 
 namespace GUI {
@@ -56,10 +61,8 @@
 	memset(_cursor, 0xFF, sizeof(_cursor));
 
 
-	ConfMan.registerDefault("gui_theme", "scummmodern.zip");
+	ConfMan.registerDefault("gui_theme", "scummmodern");
 	Common::String themefile(ConfMan.get("gui_theme"));
-	if (themefile.compareToIgnoreCase("default") == 0)
-		themefile = "builtin";
 
 	ConfMan.registerDefault("gui_renderer", ThemeEngine::findModeConfigName(ThemeEngine::_defaultRendererMode));
 	ThemeEngine::GraphicsMode gfxMode = (ThemeEngine::GraphicsMode)ThemeEngine::findMode(ConfMan.get("gui_renderer"));
@@ -80,6 +83,13 @@
 }
 
 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);
+
 	// 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())
@@ -130,6 +140,153 @@
 	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::listUseableThemes(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"))
+		listUseableThemes(Common::FSNode(ConfMan.get("themepath")), list);
+
+#ifdef DATA_PATH
+	listUseableThemes(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);
+			listUseableThemes(resourcePath, list);
+		}
+		CFRelease(resourceUrl);
+	}
+#endif
+
+	if (ConfMan.hasKey("extrapath"))
+		listUseableThemes(Common::FSNode(ConfMan.get("extrapath")), list);
+
+	listUseableThemes(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::listUseableThemes(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)
+		listUseableThemes(*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;
+	listUseableThemes(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;
 

Modified: scummvm/trunk/gui/GuiManager.h
===================================================================
--- scummvm/trunk/gui/GuiManager.h	2009-01-02 19:10:51 UTC (rev 35679)
+++ scummvm/trunk/gui/GuiManager.h	2009-01-02 20:03:45 UTC (rev 35680)
@@ -29,6 +29,9 @@
 #include "common/singleton.h"
 #include "common/stack.h"
 #include "common/str.h"
+#include "common/list.h"
+#include "common/fs.h"
+
 #include "graphics/fontman.h"
 
 #include "gui/widget.h"
@@ -90,6 +93,16 @@
 	 */
 	bool checkScreenChange();
 
+	struct ThemeDescriptor {
+		Common::String name;
+		Common::String id;
+		Common::String filename;
+	};
+
+	/**
+	 * Lists all theme files useable.
+	 */
+	void listUseableThemes(Common::List<ThemeDescriptor> &list);
 protected:
 	enum RedrawStatus {
 		kRedrawDisabled = 0,
@@ -144,6 +157,9 @@
 	Dialog *getTopDialog() const;
 
 	void screenChange();
+
+	Common::String findThemeFile(const Common::String &id);
+	void listUseableThemes(Common::FSNode node, Common::List<ThemeDescriptor> &list);
 };
 
 } // End of namespace GUI

Modified: scummvm/trunk/gui/themebrowser.cpp
===================================================================
--- scummvm/trunk/gui/themebrowser.cpp	2009-01-02 19:10:51 UTC (rev 35679)
+++ scummvm/trunk/gui/themebrowser.cpp	2009-01-02 20:03:45 UTC (rev 35680)
@@ -25,14 +25,7 @@
 #include "gui/themebrowser.h"
 #include "gui/ListWidget.h"
 #include "gui/widget.h"
-#include "common/config-manager.h"
 
-#include "common/fs.h"
-
-#ifdef MACOSX
-#include "CoreFoundation/CoreFoundation.h"
-#endif
-
 namespace GUI {
 
 enum {
@@ -78,7 +71,18 @@
 		int selection = _fileList->getSelected();
 		if (selection < 0)
 			break;
-		_select = _themes[selection].file;
+
+		// TODO: 
+		// Currently GuiManager::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
+		// of high importance anyway.
+		ThemeDescList::const_iterator sel = _themes.begin();
+		for (int i = 0; i < selection; ++i)
+			++sel;
+
+		_select = sel->id;
 		setResult(1);
 		close();
 		break;
@@ -91,43 +95,9 @@
 void ThemeBrowser::updateListing() {
 	_themes.clear();
 
-	// classic is always built-in
-	ThemeDescriptor th;
-	th.name = "ScummVM Classic Theme (Builtin Version)";
-	th.file = "builtin";
-	_themes.push_back(th);
+	g_gui.listUseableThemes(_themes);
 
-	// we are using only the paths 'themepath', 'extrapath', DATA_PATH and '.'
-	// since these are the default locations for the theme files
-	// files in other places are ignored in this dialog
-	// TODO: let the user browse the complete FS too/only the FS?
-	if (ConfMan.hasKey("themepath"))
-		addDir(_themes, Common::FSNode(ConfMan.get("themepath")));
-
-#ifdef DATA_PATH
-	addDir(_themes, Common::FSNode(DATA_PATH));
-#endif
-
-#ifdef MACOSX
-	CFURLRef resourceUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
-	if (resourceUrl) {
-		char buf[256];
-		if (CFURLGetFileSystemRepresentation(resourceUrl, true, (UInt8 *)buf, 256)) {
-			Common::FSNode resourcePath(buf);
-			addDir(_themes, resourcePath);
-		}
-		CFRelease(resourceUrl);
-	}
-#endif
-
-	if (ConfMan.hasKey("extrapath"))
-		addDir(_themes, Common::FSNode(ConfMan.get("extrapath")));
-
-	addDir(_themes, Common::FSNode("."));
-
-	// Populate the ListWidget
 	Common::StringList list;
-
 	for (ThemeDescList::const_iterator i = _themes.begin(); i != _themes.end(); ++i)
 		list.push_back(i->name);
 
@@ -138,52 +108,5 @@
 	draw();
 }
 
-
-void ThemeBrowser::addDir(ThemeDescList &list, const Common::FSNode &node) {
-	if (!node.exists() || !node.isReadable())
-		return;
-
-	// Scan this dir, all files and all subdirs in it for themes
-	Common::FSList fslist;
-	if (!node.getChildren(fslist, Common::FSNode::kListAll))
-		return;
-	fslist.push_back(node);	// Yup, also scan the dir itself
-
-	for (Common::FSList::const_iterator i = fslist.begin(); i != fslist.end(); ++i) {
-
-		ThemeDescriptor th;
-		if (isTheme(*i, th)) {
-			bool add = true;
-
-			for (ThemeDescList::const_iterator p = list.begin(); p != list.end(); ++p) {
-				if (p->name == th.name || p->file == th.file) {
-					add = false;
-					break;
-				}
-			}
-
-			if (add)
-				list.push_back(th);
-		}
-	}
-}
-
-bool ThemeBrowser::isTheme(const Common::FSNode &node, ThemeDescriptor &out) {
-	out.file = node.getPath();
-
-#ifdef USE_ZLIB
-	if (!out.file.hasSuffix(".zip") && !node.isDirectory())
-		return false;
-#else
-	if (!node.isDirectory())
-		return false;
-#endif
-
-	if (!ThemeEngine::themeConfigUseable(node, out.name))
-		return false;
-
-	return true;
-}
-
 } // end of namespace GUI
 

Modified: scummvm/trunk/gui/themebrowser.h
===================================================================
--- scummvm/trunk/gui/themebrowser.h	2009-01-02 19:10:51 UTC (rev 35679)
+++ scummvm/trunk/gui/themebrowser.h	2009-01-02 20:03:45 UTC (rev 35680)
@@ -26,9 +26,10 @@
 #define GUI_THEMEBROWSER_H
 
 #include "gui/dialog.h"
+#include "gui/GuiManager.h"
+
 #include "common/str.h"
-#include "common/fs.h"
-#include "common/array.h"
+#include "common/list.h"
 
 namespace GUI {
 
@@ -44,20 +45,13 @@
 
 	const Common::String &getSelected() const { return _select; }
 private:
-	struct ThemeDescriptor {
-		Common::String name;
-		Common::String file;
-	};
-
 	ListWidget *_fileList;
 	Common::String _select;
-	typedef Common::Array<ThemeDescriptor> ThemeDescList;
+
+	typedef Common::List<GuiManager::ThemeDescriptor> ThemeDescList;
 	ThemeDescList _themes;
 
 	void updateListing();
-
-	void addDir(ThemeDescList &list, const Common::FSNode &node);
-	bool isTheme(const Common::FSNode &node, ThemeDescriptor &out);
 };
 
 } // end of namespace GUI


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list