aboutsummaryrefslogtreecommitdiff
path: root/gui/newgui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gui/newgui.cpp')
-rw-r--r--gui/newgui.cpp72
1 files changed, 45 insertions, 27 deletions
diff --git a/gui/newgui.cpp b/gui/newgui.cpp
index 9ae0db6470..167a281ab0 100644
--- a/gui/newgui.cpp
+++ b/gui/newgui.cpp
@@ -64,7 +64,14 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled),
ConfMan.registerDefault("gui_renderer", ThemeEngine::findModeConfigName(ThemeEngine::_defaultRendererMode));
ThemeEngine::GraphicsMode gfxMode = (ThemeEngine::GraphicsMode)ThemeEngine::findMode(ConfMan.get("gui_renderer"));
- loadNewTheme(themefile, gfxMode);
+ // Try to load the theme
+ if (!loadNewTheme(themefile, gfxMode)) {
+ // Loading the theme failed, try to load the built-in theme
+ if (!loadNewTheme("builtin", gfxMode)) {
+ // Loading the built-in theme failed as well. Bail out
+ error("Failed to load any GUI theme, aborting");
+ }
+ }
_themeChange = false;
}
@@ -73,33 +80,40 @@ GuiManager::~GuiManager() {
}
bool GuiManager::loadNewTheme(Common::String filename, ThemeEngine::GraphicsMode gfx) {
- if (_theme && filename == _theme->getThemeFileName() && gfx == _theme->getGraphicsMode())
+ // 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())
return true;
- Common::String oldTheme = (_theme != 0) ? _theme->getThemeFileName() : "";
+ ThemeEngine *newTheme = 0;
if (gfx == ThemeEngine::kGfxDisabled)
gfx = ThemeEngine::_defaultRendererMode;
+ // Try to load the new theme
+ newTheme = new ThemeEngine(filename, gfx);
+ assert(newTheme);
+
+ if (!newTheme->init())
+ return false;
+
+ //
+ // Disable and delete the old theme
+ //
if (_theme)
_theme->disable();
+ delete _theme;
if (_useStdCursor) {
CursorMan.popCursorPalette();
CursorMan.popCursor();
}
- delete _theme;
- _theme = new ThemeEngine(filename, gfx);
-
- if (!_theme)
- return (!oldTheme.empty() ? loadNewTheme(oldTheme) : false);
-
- _theme->init();
-
- if (!oldTheme.empty())
- screenChange();
-
+ //
+ // Enable the new theme
+ //
+ _theme = newTheme;
+ screenChange();
_themeChange = true;
return true;
@@ -191,8 +205,14 @@ void GuiManager::runLoop() {
}
Common::Event event;
-
while (eventMan->pollEvent(event)) {
+
+ // The top dialog can change during the event loop. In that case, flush all the
+ // dialog-related events since they were probably generated while the old dialog
+ // was still visible, and therefore note intended for the new one.
+ //
+ // This hopefully fixes strange behaviour/crashes with pop-up widgets. (Most easy
+ // to trigger in 3x mode or when running ScummVM under Valgrind.)
if (activeDialog != getTopDialog() && event.type != Common::EVENT_SCREEN_CHANGED)
continue;
@@ -307,19 +327,8 @@ void GuiManager::openDialog(Dialog *dialog) {
// We reflow the dialog just before opening it. If the screen changed
// since the last time we looked, also refresh the loaded theme,
// and reflow all other open dialogs, too.
- int tmpScreenChangeID = _system->getScreenChangeID();
- if (_lastScreenChangeID != tmpScreenChangeID) {
- _lastScreenChangeID = tmpScreenChangeID;
-
- // reinit the whole theme
- _theme->refresh();
- // refresh all dialogs
- for (int i = 0; i < _dialogStack.size(); ++i) {
- _dialogStack[i]->reflowLayout();
- }
- } else {
+ if (!checkScreenChange())
dialog->reflowLayout();
- }
}
void GuiManager::closeTopDialog() {
@@ -371,6 +380,15 @@ void GuiManager::clearDragWidget() {
_dialogStack.top()->_dragWidget = 0;
}
+bool GuiManager::checkScreenChange() {
+ int tmpScreenChangeID = _system->getScreenChangeID();
+ if (_lastScreenChangeID != tmpScreenChangeID) {
+ GuiManager::screenChange();
+ return true;
+ }
+ return false;
+}
+
void GuiManager::screenChange() {
_lastScreenChangeID = _system->getScreenChangeID();