diff options
| author | Max Horn | 2009-01-01 21:41:55 +0000 | 
|---|---|---|
| committer | Max Horn | 2009-01-01 21:41:55 +0000 | 
| commit | 97e9b28c8ac480e7ba9819c5525a1d8bec45d2f4 (patch) | |
| tree | cdf664f30b7df331b6247494d5af5629df67f290 /gui | |
| parent | 9752882f8bbe6070f69638d3c54156a1c0e61204 (diff) | |
| download | scummvm-rg350-97e9b28c8ac480e7ba9819c5525a1d8bec45d2f4.tar.gz scummvm-rg350-97e9b28c8ac480e7ba9819c5525a1d8bec45d2f4.tar.bz2 scummvm-rg350-97e9b28c8ac480e7ba9819c5525a1d8bec45d2f4.zip  | |
Revamping the handling of GUI themes a bit:
* Moved the code which handles fallback to the built-in theme from ThemeEngine to GuiManager
* Changed ThemeEngine::init() to only init&load the theme; no more messing with the overlay
* Commented to a somewhat obscure line in the GuiManager event loop (taking eriktorbjorn's original commit message for that change as comment text)
* Cleaned up the way the Dialog constructor ensures that the current Theme is correctly setup
* Got rid of varios members of ThemeEngine
* Changed ThemeEngine members _screen and _backBuffer from Surface pointers to just plain Surfaces
* Changed ThemeEngine::loadFontFromArchive to use _themeArchive instead of creating an Archive from scratch
* Renamed ThemeEngine::getThemeFileName() to getThemeId() (and some associated tweaks)
* Lots of further cleanup and tweaks
svn-id: r35653
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/ThemeEngine.cpp | 266 | ||||
| -rw-r--r-- | gui/ThemeEngine.h | 48 | ||||
| -rw-r--r-- | gui/dialog.cpp | 5 | ||||
| -rw-r--r-- | gui/newgui.cpp | 72 | ||||
| -rw-r--r-- | gui/newgui.h | 17 | ||||
| -rw-r--r-- | gui/options.cpp | 2 | 
6 files changed, 177 insertions, 233 deletions
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 3b6791d281..b3721011f3 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -51,10 +51,9 @@ namespace GUI {   *	ThemeEngine class   *********************************************************/  ThemeEngine::ThemeEngine(Common::String fileName, GraphicsMode mode) : -	_system(0), _vectorRenderer(0), _screen(0), _backBuffer(0), +	_system(0), _vectorRenderer(0),  	_buffering(false), _bytesPerPixel(0),  _graphicsMode(kGfxDisabled), -	_font(0), _initOk(false), _themeOk(false), _enabled(false), _cursor(0), -	_loadedThemeX(0), _loadedThemeY(0) { +	_font(0), _initOk(false), _themeOk(false), _enabled(false), _cursor(0) {  	_system = g_system;  	_parser = new ThemeParser(this); @@ -71,13 +70,17 @@ ThemeEngine::ThemeEngine(Common::String fileName, GraphicsMode mode) :  	}  	_graphicsMode = mode; -	_themeFileName = fileName; +	_themeId = fileName;  	_themeArchive = 0;  	_initOk = false;  }  ThemeEngine::~ThemeEngine() { -	deinit(); +	delete _vectorRenderer; +	_vectorRenderer = 0; +	_screen.free(); +	_backBuffer.free(); +  	unloadTheme();  	delete _parser;  	delete _themeEval; @@ -133,82 +136,31 @@ const char *ThemeEngine::findModeConfigName(GraphicsMode mode) {   *********************************************************/  bool ThemeEngine::init() {  	// reset everything and reload the graphics -	if (_initOk) -		_system->hideOverlay(); -	deinit(); +	_initOk = false;  	setGraphicsMode(_graphicsMode); -	if (_screen->pixels && _backBuffer->pixels) { +	if (_screen.pixels && _backBuffer.pixels) {  		_initOk = true; -		clearAll();  	} -	if (_screen->w >= 400 && _screen->h >= 300) { +	// TODO: Instead of hard coding the font here, it should be possible +	// to specify the fonts to be used for each resolution in the theme XML. +	if (_screen.w >= 400 && _screen.h >= 300) {  		_font = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);  	} else {  		_font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);  	} -	if (isThemeLoadingRequired() || !_themeOk) { -		loadTheme(_themeFileName); -	} - -	return true; -} - -void ThemeEngine::deinit() { -	delete _vectorRenderer; -	_vectorRenderer = 0; -	if (_screen != 0) { -		_screen->free(); -		delete _screen; -		_screen = 0; -	} -	if (_backBuffer != 0) { -		_backBuffer->free(); -		delete _backBuffer; -		_backBuffer = 0; -	} -	_initOk = false; -} - -void ThemeEngine::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; -	} - -	// Release all graphics surfaces -	for (ImagesMap::iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i) { -		Graphics::Surface *surf = i->_value; -		if (surf) { -			surf->free(); -			delete surf; -		} -	} -	_bitmaps.clear(); +	loadTheme(_themeId); -	delete _themeArchive; -	_themeArchive = 0; - -	_themeEval->reset(); -	_themeOk = false; +	return ready();  }  void ThemeEngine::clearAll() { -	if (!_initOk) -		return; - -	_system->clearOverlay(); -	_system->grabOverlay((OverlayColor *)_screen->pixels, _screen->w); +	if (_initOk) { +		_system->clearOverlay(); +		_system->grabOverlay((OverlayColor *)_screen.pixels, _screen.w); +	}  }  void ThemeEngine::refresh() { @@ -226,8 +178,11 @@ void ThemeEngine::refresh() {  void ThemeEngine::enable() {  	init(); -	if (_useCursor) -		setUpCursor(); +	if (_useCursor) { +		CursorMan.pushCursorPalette(_cursorPal, 0, MAX_CURS_COLORS); +		CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale); +		CursorMan.showMouse(true); +	}  	_system->showOverlay();  	clearAll(); @@ -245,28 +200,6 @@ void ThemeEngine::disable() {  	_enabled = false;  } -template<typename PixelType> -void ThemeEngine::screenInit(bool backBuffer) { -	uint32 width = _system->getOverlayWidth(); -	uint32 height = _system->getOverlayHeight(); - -	if (backBuffer) { -		if (_backBuffer) -			_backBuffer->free(); -		else -			_backBuffer = new Graphics::Surface; -		_backBuffer->create(width, height, sizeof(PixelType)); -	} - - -	if (_screen) -		_screen->free(); -	else -		_screen = new Graphics::Surface; -	_screen->create(width, height, sizeof(PixelType)); -	_system->clearOverlay(); -} -  void ThemeEngine::setGraphicsMode(GraphicsMode mode) {  	switch (mode) {  	case kGfxStandard16bit: @@ -274,16 +207,24 @@ void ThemeEngine::setGraphicsMode(GraphicsMode mode) {  	case kGfxAntialias16bit:  #endif  		_bytesPerPixel = sizeof(uint16); -		screenInit<uint16>(kEnableBackCaching);  		break;  	default:  		error("Invalid graphics mode");  	} +	uint32 width = _system->getOverlayWidth(); +	uint32 height = _system->getOverlayHeight(); + +	_backBuffer.free(); +	_backBuffer.create(width, height, _bytesPerPixel); + +	_screen.free(); +	_screen.create(width, height, _bytesPerPixel); +  	delete _vectorRenderer;  	_vectorRenderer = Graphics::createRenderer(mode); -	_vectorRenderer->setSurface(_screen); +	_vectorRenderer->setSurface(&_screen);  }  bool ThemeEngine::isWidgetCached(DrawData type, const Common::Rect &r) { @@ -293,7 +234,7 @@ bool ThemeEngine::isWidgetCached(DrawData type, const Common::Rect &r) {  }  void ThemeEngine::drawCached(DrawData type, const Common::Rect &r) { -	assert(_widgets[type]->_surfaceCache->bytesPerPixel == _screen->bytesPerPixel); +	assert(_widgets[type]->_surfaceCache->bytesPerPixel == _screen.bytesPerPixel);  	_vectorRenderer->blitSurface(_widgets[type]->_surfaceCache, r);  } @@ -312,23 +253,10 @@ void ThemeEngine::calcBackgroundOffset(DrawData type) {  }  void ThemeEngine::restoreBackground(Common::Rect r) { -	r.clip(_screen->w, _screen->h); // AHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHA... Oh god. :( -	_vectorRenderer->blitSurface(_backBuffer, r); +	r.clip(_screen.w, _screen.h); // AHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHA... Oh god. :( +	_vectorRenderer->blitSurface(&_backBuffer, r);  } -bool ThemeEngine::isThemeLoadingRequired() { -	int x = g_system->getOverlayWidth(), y = g_system->getOverlayHeight(); - -	if (_loadedThemeX == x && _loadedThemeY == y) -		return false; - -	_loadedThemeX = x; -	_loadedThemeY = y; - -	return true; -} - -  /********************************************************** @@ -434,21 +362,19 @@ bool ThemeEngine::addDrawData(const Common::String &data, bool cached) {  /**********************************************************   *	Theme XML loading   *********************************************************/ -bool ThemeEngine::loadTheme(const Common::String &fileName) { +void ThemeEngine::loadTheme(const Common::String &themeid) {  	unloadTheme(); -	bool tryAgain = false; -	if (fileName != "builtin") { +	if (themeid == "builtin") { +		_themeOk = loadDefaultXML(); +	} else {  		// Load the archive containing image and XML data -		if (!loadThemeXML(fileName)) { -			warning("Could not parse custom theme '%s'. Falling back to default theme", fileName.c_str()); -			tryAgain = true;	// Fall back to default builtin theme -		} +		_themeOk = loadThemeXML(themeid);  	} - -	if (fileName == "builtin" || tryAgain) { -		if (!loadDefaultXML()) // if we can't load the embedded theme, this is a complete failure -			error("Could not load default embedded theme"); +	 +	if (!_themeOk) { +		warning("Failed to load theme '%s'", themeid.c_str()); +		return;  	}  	for (int i = 0; i < kDrawDataMAX; ++i) { @@ -461,9 +387,37 @@ bool ThemeEngine::loadTheme(const Common::String &fileName) {  			if (_widgets[i]->_cached) {}  		}  	} +} -	_themeOk = true; -	return true; +void ThemeEngine::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; +	} + +	// Release all graphics surfaces +	for (ImagesMap::iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i) { +		Graphics::Surface *surf = i->_value; +		if (surf) { +			surf->free(); +			delete surf; +		} +	} +	_bitmaps.clear(); + +	delete _themeArchive; +	_themeArchive = 0; + +	_themeEval->reset(); +	_themeOk = false;  }  bool ThemeEngine::loadDefaultXML() { @@ -483,7 +437,7 @@ bool ThemeEngine::loadDefaultXML() {  		return false;  	_themeName = "ScummVM Classic Theme (Builtin Version)"; -	_themeFileName = "builtin"; +	_themeId = "builtin";  	result = _parser->parse();  	_parser->close(); @@ -535,7 +489,7 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeName) {  	Common::String stxHeader = themercFile.readLine();  	if (!themeConfigParseHeader(stxHeader, _themeName) || _themeName.empty()) {  		delete archive; -		warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str()); +		warning("Corrupted 'THEMERC' file in theme '%s'", _themeId.c_str());  		return false;  	} @@ -585,7 +539,7 @@ void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic)  		return;  	Common::Rect area = r; -	area.clip(_screen->w, _screen->h); +	area.clip(_screen.w, _screen.h);  	ThemeItemDrawData *q = new ThemeItemDrawData(this, _widgets[type], area, dynamic); @@ -611,7 +565,7 @@ void ThemeEngine::queueDDText(TextData type, const Common::Rect &r, const Common  		return;  	Common::Rect area = r; -	area.clip(_screen->w, _screen->h); +	area.clip(_screen.w, _screen.h);  	ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], area, text, alignH, alignV, ellipsis, restoreBg, deltax); @@ -626,7 +580,7 @@ void ThemeEngine::queueDDText(TextData type, const Common::Rect &r, const Common  void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha) {  	Common::Rect area = r; -	area.clip(_screen->w, _screen->h); +	area.clip(_screen.w, _screen.h);  	ThemeItemBitmap *q = new ThemeItemBitmap(this, area, bitmap, alpha); @@ -891,22 +845,22 @@ void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font  		return;  	Common::Rect charArea = r; -	charArea.clip(_screen->w, _screen->h); +	charArea.clip(_screen.w, _screen.h);  	Graphics::PixelFormat format = _system->getOverlayFormat();  	uint32 color = Graphics::RGBToColor(_texts[kTextDataDefault]->_color.r, _texts[kTextDataDefault]->_color.g, _texts[kTextDataDefault]->_color.b, format);  	restoreBackground(charArea); -	font->drawChar(_screen, ch, charArea.left, charArea.top, color); +	font->drawChar(&_screen, ch, charArea.left, charArea.top, color);  	addDirtyRect(charArea);  }  void ThemeEngine::debugWidgetPosition(const char *name, const Common::Rect &r) { -	_font->drawString(_screen, name, r.left, r.top, r.width(), 0xFFFF, Graphics::kTextAlignRight, 0, true); -	_screen->hLine(r.left, r.top, r.right, 0xFFFF); -	_screen->hLine(r.left, r.bottom, r.right, 0xFFFF); -	_screen->vLine(r.left, r.top, r.bottom, 0xFFFF); -	_screen->vLine(r.right, r.top, r.bottom, 0xFFFF); +	_font->drawString(&_screen, name, r.left, r.top, r.width(), 0xFFFF, Graphics::kTextAlignRight, 0, true); +	_screen.hLine(r.left, r.top, r.right, 0xFFFF); +	_screen.hLine(r.left, r.bottom, r.right, 0xFFFF); +	_screen.vLine(r.left, r.top, r.bottom, 0xFFFF); +	_screen.vLine(r.right, r.top, r.bottom, 0xFFFF);  } @@ -916,15 +870,15 @@ void ThemeEngine::debugWidgetPosition(const char *name, const Common::Rect &r) {   *********************************************************/  void ThemeEngine::updateScreen() {  	if (!_bufferQueue.empty()) { -		_vectorRenderer->setSurface(_backBuffer); +		_vectorRenderer->setSurface(&_backBuffer);  		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); +		_vectorRenderer->setSurface(&_screen); +		memcpy(_screen.getBasePtr(0,0), _backBuffer.getBasePtr(0,0), _screen.pitch * _screen.h);  		_bufferQueue.clear();  	} @@ -964,17 +918,11 @@ void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) {  	if (style != kShadingNone) {  		_vectorRenderer->applyScreenShading(style); -		addDirtyRect(Common::Rect(0, 0, _screen->w, _screen->h)); +		addDirtyRect(Common::Rect(0, 0, _screen.w, _screen.h));  	} -	memcpy(_backBuffer->getBasePtr(0,0), _screen->getBasePtr(0,0), _screen->pitch * _screen->h); -	_vectorRenderer->setSurface(_screen); -} - -void ThemeEngine::setUpCursor() { -	CursorMan.pushCursorPalette(_cursorPal, 0, MAX_CURS_COLORS); -	CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale); -	CursorMan.showMouse(true); +	memcpy(_backBuffer.getBasePtr(0,0), _screen.getBasePtr(0,0), _screen.pitch * _screen.h); +	_vectorRenderer->setSurface(&_screen);  }  bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale) { @@ -1077,36 +1025,16 @@ ThemeEngine::TextData ThemeEngine::getTextData(DrawData ddId) {   *********************************************************/  const Graphics::Font *ThemeEngine::loadFontFromArchive(const Common::String &filename) { -	Common::Archive *arch = 0; +	Common::SeekableReadStream *stream = 0;  	const Graphics::Font *font = 0; -	Common::FSNode node(getThemeFileName()); - -	if (node.getName().hasSuffix(".zip")) { -#ifdef USE_ZLIB -		Common::ZipArchive *zip = new Common::ZipArchive(node); -		if (!zip || !zip->isOpen()) -			return 0; - -		arch = zip; -#else -		return 0; -#endif -	} else { -		Common::FSDirectory *dir = new Common::FSDirectory(node); -		if (!dir || !dir->getFSNode().isDirectory()) -			return 0; - -		arch = dir; -	} - -	Common::SeekableReadStream *stream(arch->openFile(filename)); +	if (_themeArchive) +		stream = _themeArchive->openFile(filename);  	if (stream) {  		font = Graphics::NewFont::loadFromCache(*stream);  		delete stream;  	} -	delete arch;  	return font;  } diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index b96cc47d7e..1067d11b11 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -57,9 +57,6 @@ protected:  	friend class GUI::Dialog;  	friend class GUI::GuiObject; -	/** Sets whether backcaching is enabled */ -	static const bool kEnableBackCaching = true; -  	/**  	 *	DrawData sets enumeration.  	 *	Each DD set corresponds to the actual looks @@ -244,7 +241,6 @@ public:  	~ThemeEngine();  	bool init(); -	void deinit();  	void clearAll();  	void refresh(); @@ -343,7 +339,7 @@ public:  	 *	@param special Deprecated.  	 */  	bool addDirtyRect(Common::Rect r, bool backup = false, bool special = false) { -		r.clip(_screen->w, _screen->h); +		r.clip(_screen.w, _screen.h);  		_dirtyScreen.push_back(r);  		return true;  	} @@ -422,6 +418,7 @@ public:  	 */  	bool addTextData(const Common::String &drawDataId, const Common::String &textDataId, Graphics::TextAlign alignH, TextAlignVertical alignV); +protected:  	/**  	 *	Returns if the Theme is ready to draw stuff on screen.  	 *	Must be called instead of just checking _initOk, because @@ -433,7 +430,7 @@ public:  	}  	/** Load the them from the file with the specified name. */ -	bool loadTheme(const Common::String &fileName); +	void loadTheme(const Common::String &themeid);  	/**  	 *	Changes the active graphics mode of the GUI; may be used to either @@ -441,7 +438,7 @@ public:  	 */  	void setGraphicsMode(GraphicsMode mode); - +public:  	/**  	 *	Finishes buffering: widgets from then on will be drawn straight on the screen  	 *	without drawing queues. @@ -497,7 +494,7 @@ public:  	bool isWidgetCached(DrawData type, const Common::Rect &r);  	const Common::String &getThemeName() const { return _themeName; } -	const Common::String &getThemeFileName() const { return _themeFileName; } +	const Common::String &getThemeId() const { return _themeId; }  	int getGraphicsMode() const { return _graphicsMode; }  protected: @@ -513,12 +510,11 @@ protected:  	/**  	 *	Loads the given theme into the ThemeEngine. -	 *	Note that ThemeName is an identifier, not a filename.  	 * -	 *	@param ThemeName Theme identifier. +	 *	@param themeId Theme identifier.  	 *	@returns true if the theme was successfully loaded.  	 */ -	bool loadThemeXML(const Common::String &themeName); +	bool loadThemeXML(const Common::String &themeId);  	/**  	 *	Loads the default theme file (the embedded XML file found @@ -533,6 +529,10 @@ protected:  	 */  	void unloadTheme(); +	const Graphics::Font *loadFont(const Common::String &filename); +	const Graphics::Font *loadFontFromArchive(const Common::String &filename); +	Common::String genCacheFilename(const char *filename); +  	/**  	 *	Actual Dirty Screen handling function.  	 *	Handles all the dirty squares in the list, merges and optimizes @@ -586,19 +586,9 @@ protected:  public:  	/** -	 *	LEGACY: Old GUI::Theme API +	 * @name LEGACY: Old GUI::Theme API  	 */ - -	bool needThemeReload() { -		return ((_loadedThemeX != g_system->getOverlayWidth()) || -				(_loadedThemeY != g_system->getOverlayHeight())); -	} - -	const Graphics::Font *loadFont(const Common::String &filename); -	const Graphics::Font *loadFontFromArchive(const Common::String &filename); -	Common::String genCacheFilename(const char *filename); - -	bool isThemeLoadingRequired(); +	//@{  	static bool themeConfigUseable(const Common::FSNode &node, Common::String &themeName);  	static bool themeConfigParseHeader(Common::String header, Common::String &themeName); @@ -606,6 +596,8 @@ public:  	int getTabSpacing() const { return 0; }  	int getTabPadding() const { return 3; } +	//@} +  protected:  	OSystem *_system; /** Global system object. */ @@ -619,10 +611,10 @@ protected:  	GUI::ThemeEval *_themeEval;  	/** Main screen surface. This is blitted straight into the overlay. */ -	Graphics::Surface *_screen; +	Graphics::Surface _screen;  	/** Backbuffer surface. Stores previous states of the screen to blit back */ -	Graphics::Surface *_backBuffer; +	Graphics::Surface _backBuffer;  	/** Sets whether the current drawing is being buffered (stored for later  		processing) or drawn directly to the screen. */ @@ -663,12 +655,9 @@ protected:  	bool _enabled; //!< Whether the Theme is currently shown on the overlay  	Common::String _themeName; //!< Name of the currently loaded theme -	Common::String _themeFileName; +	Common::String _themeId;  	Common::Archive *_themeArchive; -	/** Custom Cursor Management */ -	void setUpCursor(); -  	bool _useCursor;  	int _cursorHotspotX, _cursorHotspotY;  	int _cursorTargetScale; @@ -679,7 +668,6 @@ protected:  	bool _needPaletteUpdates;  	uint _cursorWidth, _cursorHeight;  	byte _cursorPal[4*MAX_CURS_COLORS]; -	int _loadedThemeX, _loadedThemeY;  };  } // end of namespace GUI. diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 1296ef7bbe..ebfdb9d634 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -59,10 +59,7 @@ Dialog::Dialog(const Common::String &name)  	//  	// Fixes bug #1590596: "HE: When 3x graphics are choosen, F5 crashes game"  	// and bug #1595627: "SCUMM: F5 crashes game (640x480)" -	if (g_gui.theme()->needThemeReload()) { -		debug(2, "Theme forced to reload"); -		g_gui.screenChange(); -	} +	g_gui.checkScreenChange();  }  int Dialog::runModal() { 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(); diff --git a/gui/newgui.h b/gui/newgui.h index 948edc3ec2..c6313feedd 100644 --- a/gui/newgui.h +++ b/gui/newgui.h @@ -82,10 +82,20 @@ public:  	int getStringWidth(const Common::String &str, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getStringWidth(str, style); }  	int getCharWidth(byte c, ThemeEngine::FontStyle style = ThemeEngine::kFontStyleBold) const { return _theme->getCharWidth(c, style); } +	// FIXME: clearDragWidget is apparently there for the sake of PopUpWidget::handleMouseDown. +	// This seems to be an ugly hack. At the very least, it should be thoroughly documented. +	// Better would be to replace it with a proper solution.  	void clearDragWidget(); -	void screenChange(); +	/** +	 * Tell the GuiManager to check whether the screen resolution has changed. +	 * If that is the case, the GuiManager will reload/refresh the active theme. +	 * +	 * @return true if the a screen change indeed occurred, false otherwise +	 */ +	bool checkScreenChange(); +protected:  	enum RedrawStatus {  		kRedrawDisabled = 0,  		kRedrawOpenDialog, @@ -94,7 +104,8 @@ public:  		kRedrawFull  	}; -protected: + +  	OSystem			*_system;  	ThemeEngine		*_theme; @@ -136,6 +147,8 @@ protected:  	void animateCursor();  	Dialog *getTopDialog() const; + +	void screenChange();  };  } // End of namespace GUI diff --git a/gui/options.cpp b/gui/options.cpp index 98d8bbea76..d435db85a5 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -849,7 +849,7 @@ void GlobalOptionsDialog::close() {  		if (!ConfMan.get("gui_renderer").equalsIgnoreCase(cfg)) {  			// FIXME: Actually, any changes (including the theme change) should  			// only become active *after* the options dialog has closed. -			g_gui.loadNewTheme(g_gui.theme()->getThemeFileName(), selected); +			g_gui.loadNewTheme(g_gui.theme()->getThemeId(), selected);  			ConfMan.set("gui_renderer", cfg, _domain);  		}  	}  | 
