Finished support for theme loading.

Fixed several bugs regarding theme loading.

svn-id: r33728
This commit is contained in:
Vicent Marti 2008-08-09 22:40:05 +00:00
parent 103a4f6681
commit 185dbbe84d
9 changed files with 90 additions and 85 deletions

View file

@ -510,6 +510,8 @@ void ListWidget::reflowLayout() {
_entriesPerPage += (1 << 16); _entriesPerPage += (1 << 16);
_entriesPerPage >>= 16; _entriesPerPage >>= 16;
assert(_entriesPerPage > 0);
delete[] _textWidth; delete[] _textWidth;
_textWidth = new int[_entriesPerPage]; _textWidth = new int[_entriesPerPage];

View file

@ -377,7 +377,7 @@ public:
} }
void debugDraw(Graphics::Surface *screen, const Graphics::Font *font) { void debugDraw(Graphics::Surface *screen, const Graphics::Font *font) {
_layouts["Dialog.Launcher"]->debugDraw(screen, font); _layouts["Dialog.Browser"]->debugDraw(screen, font);
// _layouts["Dialog.GameOptions_Graphics"]->debugDraw(screen, font); // _layouts["Dialog.GameOptions_Graphics"]->debugDraw(screen, font);
} }

View file

@ -95,7 +95,7 @@ const ThemeRenderer::TextDataInfo ThemeRenderer::kTextDataDefaults[] = {
}; };
ThemeRenderer::ThemeRenderer(Common::String themeName, GraphicsMode mode) : ThemeRenderer::ThemeRenderer(Common::String fileName, GraphicsMode mode) :
_vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled), _vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled),
_screen(0), _backBuffer(0), _bytesPerPixel(0), _initOk(false), _screen(0), _backBuffer(0), _bytesPerPixel(0), _initOk(false),
_themeOk(false), _enabled(false), _buffering(false) { _themeOk(false), _enabled(false), _buffering(false) {
@ -119,11 +119,9 @@ ThemeRenderer::ThemeRenderer(Common::String themeName, GraphicsMode mode) :
} else { } else {
_font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont); _font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
} }
ImageMan.addArchive(themeName + ".zip");
_themeFileName = fileName;
_initOk = true; _initOk = true;
_themeName = themeName;
} }
ThemeRenderer::~ThemeRenderer() { ThemeRenderer::~ThemeRenderer() {
@ -134,12 +132,8 @@ ThemeRenderer::~ThemeRenderer() {
delete _parser; delete _parser;
delete _themeEval; delete _themeEval;
for (ImagesMap::iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i) { for (ImagesMap::iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i)
// delete i->_value;
ImageMan.unregisterSurface(i->_key); ImageMan.unregisterSurface(i->_key);
}
ImageMan.remArchive(_stylefile + ".zip");
} }
bool ThemeRenderer::init() { bool ThemeRenderer::init() {
@ -154,7 +148,7 @@ bool ThemeRenderer::init() {
} }
if (isThemeLoadingRequired() || !_themeOk) { if (isThemeLoadingRequired() || !_themeOk) {
loadTheme(_themeName); loadTheme(_themeFileName);
} }
return true; return true;
@ -170,6 +164,30 @@ void ThemeRenderer::deinit() {
} }
} }
void ThemeRenderer::unloadTheme() {
if (!_themeOk)
return;
for (int i = 0; i < kDrawDataMAX; ++i) {
delete _widgets[i];
_widgets[i] = 0;
}
for (int i = 0; i < kTextDataMAX; ++i) {
delete _texts[i];
_texts[i] = 0;
}
for (ImagesMap::iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i)
ImageMan.unregisterSurface(i->_key);
ImageMan.remArchive(_themeFileName + ".zip");
_themeName.clear();
_themeFileName.clear();
_themeOk = false;
}
void ThemeRenderer::clearAll() { void ThemeRenderer::clearAll() {
if (!_initOk) if (!_initOk)
return; return;
@ -281,7 +299,6 @@ bool ThemeRenderer::addFont(const Common::String &fontId, const Common::String &
bool ThemeRenderer::addBitmap(const Common::String &filename) { bool ThemeRenderer::addBitmap(const Common::String &filename) {
if (_bitmaps.contains(filename)) { if (_bitmaps.contains(filename)) {
delete _bitmaps[filename];
ImageMan.unregisterSurface(filename); ImageMan.unregisterSurface(filename);
} }
@ -309,14 +326,28 @@ bool ThemeRenderer::addDrawData(const Common::String &data, bool cached) {
return true; return true;
} }
bool ThemeRenderer::loadTheme(Common::String themeName) { bool ThemeRenderer::loadTheme(Common::String fileName) {
unloadTheme(); unloadTheme();
if (themeName == "builtin" && !loadDefaultXML()) if (fileName != "builtin") {
error("Could not load default embeded theme."); if (ConfMan.hasKey("themepath"))
Common::File::addDefaultDirectory(ConfMan.get("themepath"));
if (!loadThemeXML(themeName)) { #ifdef DATA_PATH
warning("Could not parse custom theme '%s'.\nFalling back to default theme", themeName.c_str()); Common::File::addDefaultDirectoryRecursive(DATA_PATH);
#endif
if (ConfMan.hasKey("extrapath"))
Common::File::addDefaultDirectoryRecursive(ConfMan.get("extrapath"));
ImageMan.addArchive(fileName + ".zip");
}
if (fileName == "builtin") {
if (!loadDefaultXML())
error("Could not load default embeded theme");
}
else if (!loadThemeXML(fileName)) {
warning("Could not parse custom theme '%s'.\nFalling back to default theme", fileName.c_str());
if (!loadDefaultXML()) // if we can't load the embeded theme, this is a complete failure if (!loadDefaultXML()) // if we can't load the embeded theme, this is a complete failure
error("Could not load default embeded theme"); error("Could not load default embeded theme");
@ -333,9 +364,7 @@ bool ThemeRenderer::loadTheme(Common::String themeName) {
} }
} }
// Debug print all the parsed variables. remove _themeName = "DEBUG - A Theme name";
_themeEval->debugPrint();
_themeOk = true; _themeOk = true;
return true; return true;
} }
@ -346,6 +375,8 @@ bool ThemeRenderer::loadDefaultXML() {
// file inside the themes directory. // file inside the themes directory.
// Use the Python script "makedeftheme.py" to convert a normal XML theme // 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. // into the "default.inc" file, which is ready to be included in the code.
#ifdef GUI_ENABLE_BUILTIN_THEME
const char *defaultXML = const char *defaultXML =
#include "themes/default.inc" #include "themes/default.inc"
; ;
@ -354,20 +385,14 @@ bool ThemeRenderer::loadDefaultXML() {
return false; return false;
return parser()->parse(); return parser()->parse();
#else
warning("The built-in theme is not enabled in the current build. Please load an external theme");
return false;
#endif
} }
bool ThemeRenderer::loadThemeXML(Common::String themeName) { bool ThemeRenderer::loadThemeXML(Common::String themeName) {
assert(_parser); assert(_parser);
if (ConfMan.hasKey("themepath"))
Common::File::addDefaultDirectory(ConfMan.get("themepath"));
#ifdef DATA_PATH
Common::File::addDefaultDirectoryRecursive(DATA_PATH);
#endif
if (ConfMan.hasKey("extrapath"))
Common::File::addDefaultDirectoryRecursive(ConfMan.get("extrapath"));
if (!parser()->loadFile(themeName + ".stx")){ if (!parser()->loadFile(themeName + ".stx")){
#ifdef USE_ZLIB #ifdef USE_ZLIB
@ -821,9 +846,9 @@ void ThemeRenderer::updateScreen() {
renderDirtyScreen(); renderDirtyScreen();
// _vectorRenderer->fillSurface(); // _vectorRenderer->fillSurface();
// themeEval()->debugDraw(_screen, _font); // themeEval()->debugDraw(_screen, _font);
// _vectorRenderer->copyWholeFrame(_system); // _vectorRenderer->copyWholeFrame(_system);
} }
void ThemeRenderer::renderDirtyScreen() { void ThemeRenderer::renderDirtyScreen() {

View file

@ -216,7 +216,7 @@ public:
}; };
/** Default constructor */ /** Default constructor */
ThemeRenderer(Common::String themeName, GraphicsMode mode); ThemeRenderer(Common::String fileName, GraphicsMode mode);
/** Default destructor */ /** Default destructor */
~ThemeRenderer(); ~ThemeRenderer();
@ -470,10 +470,11 @@ public:
return 0; return 0;
} }
const Common::String &getThemeName() { return _themeName; }
protected: protected:
const Common::String &getThemeName() const { return _themeName; }
const Common::String &getThemeFileName() const { return _themeFileName; }
/** /**
* Initializes the drawing screen surfaces, _screen and _backBuffer. * Initializes the drawing screen surfaces, _screen and _backBuffer.
@ -505,22 +506,7 @@ protected:
* Unloads the currently loaded theme so another one can * Unloads the currently loaded theme so another one can
* be loaded. * be loaded.
*/ */
void unloadTheme() { void unloadTheme();
if (!_themeOk)
return;
for (int i = 0; i < kDrawDataMAX; ++i) {
delete _widgets[i];
_widgets[i] = 0;
}
for (int i = 0; i < kTextDataMAX; ++i) {
delete _texts[i];
_texts[i] = 0;
}
_themeOk = false;
}
/** /**
* Not implemented yet. * Not implemented yet.
@ -710,6 +696,7 @@ protected:
bool _enabled; /** Whether the Theme is currently shown on the overlay */ bool _enabled; /** Whether the Theme is currently shown on the overlay */
Common::String _themeName; /** Name of the currently loaded theme */ Common::String _themeName; /** Name of the currently loaded theme */
Common::String _themeFileName;
}; };
} // end of namespace GUI. } // end of namespace GUI.

View file

@ -98,7 +98,7 @@ NewGui::NewGui() : _redrawStatus(kRedrawDisabled),
style = "builtin"; style = "builtin";
//DEBUG: //DEBUG:
style = "scummodern"; // style = "scummodern";
loadNewTheme(style); loadNewTheme(style);
@ -110,11 +110,8 @@ NewGui::~NewGui() {
delete _theme; delete _theme;
} }
bool NewGui::loadNewTheme(const Common::String &style) { bool NewGui::loadNewTheme(const Common::String &filename) {
Common::String styleType; Common::String oldTheme = (_theme != 0) ? _theme->getThemeFileName() : "";
Common::ConfigFile cfg;
Common::String oldTheme = (_theme != 0) ? _theme->getThemeName() : "";
if (_theme) if (_theme)
_theme->disable(); _theme->disable();
@ -127,7 +124,7 @@ bool NewGui::loadNewTheme(const Common::String &style) {
delete _theme; delete _theme;
_theme = 0; _theme = 0;
_theme = new ThemeRenderer(style, GUI::ThemeRenderer::kGfxAntialias16bit); _theme = new ThemeRenderer(filename, GUI::ThemeRenderer::kGfxAntialias16bit);
if (!_theme) if (!_theme)
return (!oldTheme.empty() ? loadNewTheme(oldTheme) : false); return (!oldTheme.empty() ? loadNewTheme(oldTheme) : false);

View file

@ -907,7 +907,7 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
if (browser.runModal() > 0) { if (browser.runModal() > 0) {
// User made his choice... // User made his choice...
const Common::String &theme = browser.selected(); const Common::String &theme = browser.selected();
if (0 != theme.compareToIgnoreCase(g_gui.theme()->getStylefileName())) if (0 != theme.compareToIgnoreCase(g_gui.theme()->getThemeFileName()))
if (g_gui.loadNewTheme(theme)) { if (g_gui.loadNewTheme(theme)) {
_curTheme->setLabel(g_gui.theme()->getThemeName()); _curTheme->setLabel(g_gui.theme()->getThemeName());
ConfMan.set("gui_theme", theme); ConfMan.set("gui_theme", theme);

View file

@ -370,12 +370,8 @@ public:
static bool themeConfigUseable(const Common::String &file, const Common::String &style="", Common::String *cStyle=0, Common::ConfigFile *cfg=0); static bool themeConfigUseable(const Common::String &file, const Common::String &style="", Common::String *cStyle=0, Common::ConfigFile *cfg=0);
const Common::String &getStylefileName() const { return _stylefile; } virtual const Common::String &getThemeFileName() const = 0;
virtual const Common::String &getThemeName() const { return _stylename; } virtual const Common::String &getThemeName() const = 0;
virtual bool isDynamic() {
return false;
}
/** /**
* Checks if the theme renderer supports drawing of images. * Checks if the theme renderer supports drawing of images.

View file

@ -43,21 +43,21 @@ enum {
// but for now this simple browser works, // but for now this simple browser works,
// also it will get its own theme config values // also it will get its own theme config values
// and not use 'browser_' anymore // and not use 'browser_' anymore
ThemeBrowser::ThemeBrowser() : Dialog("browser") { ThemeBrowser::ThemeBrowser() : Dialog("Browser") {
_fileList = 0; _fileList = 0;
new StaticTextWidget(this, "browser_headline", "Select a Theme"); new StaticTextWidget(this, "Browser.Headline", "Select a Theme");
// Add file list // Add file list
_fileList = new ListWidget(this, "browser_list"); _fileList = new ListWidget(this, "Browser.List");
_fileList->setNumberingMode(kListNumberingOff); _fileList->setNumberingMode(kListNumberingOff);
_fileList->setEditable(false); _fileList->setEditable(false);
_fileList->setHints(THEME_HINT_PLAIN_COLOR); _fileList->setHints(THEME_HINT_PLAIN_COLOR);
// Buttons // Buttons
new ButtonWidget(this, "browser_cancel", "Cancel", kCloseCmd, 0); new ButtonWidget(this, "Browser.Cancel", "Cancel", kCloseCmd, 0);
new ButtonWidget(this, "browser_choose", "Choose", kChooseCmd, 0); new ButtonWidget(this, "Browser.Choose", "Choose", kChooseCmd, 0);
} }
void ThemeBrowser::open() { void ThemeBrowser::open() {
@ -91,9 +91,8 @@ void ThemeBrowser::updateListing() {
// classic is always build in // classic is always build in
Entry th; Entry th;
th.name = "Classic (Builtin)"; th.name = "Modern Development Theme (Builtin) - WIP";
th.type = "Classic"; th.file = "builtin";
th.file = "Classic (Builtin)";
_themes.push_back(th); _themes.push_back(th);
// we are using only the paths 'themepath', 'extrapath', DATA_PATH and '.' // we are using only the paths 'themepath', 'extrapath', DATA_PATH and '.'
@ -172,10 +171,11 @@ void ThemeBrowser::addDir(ThList &list, const Common::String &dir, int level) {
} }
bool ThemeBrowser::isTheme(const FilesystemNode &node, Entry &out) { bool ThemeBrowser::isTheme(const FilesystemNode &node, Entry &out) {
Common::ConfigFile cfg;
Common::String type;
out.file = node.getName(); out.file = node.getName();
if (!out.file.hasSuffix(".zip") && !out.file.hasSuffix(".stx"))
return false;
for (int i = out.file.size()-1; out.file[i] != '.' && i > 0; --i) { for (int i = out.file.size()-1; out.file[i] != '.' && i > 0; --i) {
out.file.deleteLastChar(); out.file.deleteLastChar();
} }
@ -184,14 +184,13 @@ bool ThemeBrowser::isTheme(const FilesystemNode &node, Entry &out) {
if (out.file.empty()) if (out.file.empty())
return false; return false;
if (!Theme::themeConfigUseable(out.file, "", &type, &cfg)) // TODO: Check if theme is usable.
return false; // if (!Theme::themeConfigUseable(out.file, "", &type, &cfg))
// return false;
out.type = type; // if (cfg.hasKey("name", "theme"))
// cfg.getKey("name", "theme", out.name);
if (cfg.hasKey("name", "theme")) // else
cfg.getKey("name", "theme", out.name);
else
out.name = out.file; out.name = out.file;
return true; return true;

View file

@ -46,7 +46,6 @@ public:
private: private:
struct Entry { struct Entry {
Common::String name; Common::String name;
Common::String type;
Common::String file; Common::String file;
}; };