[Scummvm-cvs-logs] SF.net SVN: scummvm:[34285] scummvm/branches/gsoc2008-gui

Tanoku at users.sourceforge.net Tanoku at users.sourceforge.net
Tue Sep 2 19:51:17 CEST 2008


Revision: 34285
          http://scummvm.svn.sourceforge.net/scummvm/?rev=34285&view=rev
Author:   Tanoku
Date:     2008-09-02 17:51:08 +0000 (Tue, 02 Sep 2008)

Log Message:
-----------
Massive refactoring/cleanup on the theme engine/parser.

Modified Paths:
--------------
    scummvm/branches/gsoc2008-gui/base/main.cpp
    scummvm/branches/gsoc2008-gui/dists/msvc9/scummvm.vcproj
    scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp
    scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h
    scummvm/branches/gsoc2008-gui/graphics/VectorRendererSpec.cpp
    scummvm/branches/gsoc2008-gui/gui/ThemeEval.cpp
    scummvm/branches/gsoc2008-gui/gui/ThemeEval.h
    scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp
    scummvm/branches/gsoc2008-gui/gui/ThemeParser.h
    scummvm/branches/gsoc2008-gui/gui/module.mk
    scummvm/branches/gsoc2008-gui/gui/newgui.cpp
    scummvm/branches/gsoc2008-gui/gui/newgui.h
    scummvm/branches/gsoc2008-gui/gui/options.cpp
    scummvm/branches/gsoc2008-gui/gui/theme.h

Added Paths:
-----------
    scummvm/branches/gsoc2008-gui/gui/ThemeEngine.cpp
    scummvm/branches/gsoc2008-gui/gui/ThemeEngine.h
    scummvm/branches/gsoc2008-gui/gui/ThemeLayout.cpp
    scummvm/branches/gsoc2008-gui/gui/ThemeLayout.h

Removed Paths:
-------------
    scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.cpp
    scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.h

Modified: scummvm/branches/gsoc2008-gui/base/main.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/base/main.cpp	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/base/main.cpp	2008-09-02 17:51:08 UTC (rev 34285)
@@ -43,7 +43,7 @@
 #include "common/system.h"
 #include "gui/newgui.h"
 #include "gui/message.h"
-#include "gui/ThemeRenderer.h"
+#include "gui/ThemeEngine.h"
 #include "gui/ThemeParser.h"
 
 #if defined(_WIN32_WCE)

Modified: scummvm/branches/gsoc2008-gui/dists/msvc9/scummvm.vcproj
===================================================================
--- scummvm/branches/gsoc2008-gui/dists/msvc9/scummvm.vcproj	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/dists/msvc9/scummvm.vcproj	2008-09-02 17:51:08 UTC (rev 34285)
@@ -1205,6 +1205,26 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\gui\ThemeEngine.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeEngine.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeEval.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeLayout.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\gui\ThemeLayout.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\gui\ThemeParser.cpp"
 				>
 			</File>
@@ -1220,18 +1240,6 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="..\..\gui\ThemeRenderer.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\gui\ThemeEval.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\gui\ThemeRenderer.h"
-				>
-			</File>
-			<File
 				RelativePath="..\..\gui\widget.cpp"
 				>
 			</File>
@@ -1350,6 +1358,14 @@
 					/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath="..\..\graphics\VectorRendererSpec.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\..\graphics\VectorRendererSpec.h"
+				>
+			</File>
 			<Filter
 				Name="scaler"
 				>

Modified: scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp	2008-09-02 17:51:08 UTC (rev 34285)
@@ -30,7 +30,7 @@
 #include "graphics/surface.h"
 #include "graphics/colormasks.h"
 
-#include "gui/ThemeRenderer.h"
+#include "gui/ThemeEngine.h"
 #include "graphics/VectorRenderer.h"
 
 #define VECTOR_RENDERER_FAST_TRIANGLES

Modified: scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.h	2008-09-02 17:51:08 UTC (rev 34285)
@@ -32,7 +32,7 @@
 #include "graphics/surface.h"
 #include "graphics/colormasks.h"
 
-#include "gui/ThemeRenderer.h"
+#include "gui/ThemeEngine.h"
 
 namespace Graphics {
 class VectorRenderer;

Modified: scummvm/branches/gsoc2008-gui/graphics/VectorRendererSpec.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/VectorRendererSpec.cpp	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/graphics/VectorRendererSpec.cpp	2008-09-02 17:51:08 UTC (rev 34285)
@@ -30,7 +30,7 @@
 #include "graphics/surface.h"
 #include "graphics/colormasks.h"
 
-#include "gui/ThemeRenderer.h"
+#include "gui/ThemeEngine.h"
 #include "graphics/VectorRenderer.h"
 #include "graphics/VectorRendererSpec.h"
 
@@ -128,10 +128,10 @@
     
 VectorRenderer *createRenderer(int mode) {
 	switch (mode) {
-	case GUI::ThemeRenderer::kGfxStandard16bit:
+	case GUI::ThemeEngine::kGfxStandard16bit:
 		return new VectorRendererSpec<uint16, ColorMasks<565> >;
 
-	case GUI::ThemeRenderer::kGfxAntialias16bit:
+	case GUI::ThemeEngine::kGfxAntialias16bit:
 		return new VectorRendererAA<uint16, ColorMasks<565> >;
 
 	default:

Copied: scummvm/branches/gsoc2008-gui/gui/ThemeEngine.cpp (from rev 34272, scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.cpp)
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeEngine.cpp	                        (rev 0)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeEngine.cpp	2008-09-02 17:51:08 UTC (rev 34285)
@@ -0,0 +1,1073 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/util.h"
+#include "graphics/surface.h"
+#include "graphics/colormasks.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "common/config-manager.h"
+#include "common/fs.h"
+#include "graphics/imageman.h"
+#include "graphics/cursorman.h"
+#include "gui/launcher.h"
+
+#include "gui/ThemeEngine.h"
+#include "gui/ThemeEval.h"
+#include "graphics/VectorRenderer.h"
+
+#define GUI_ENABLE_BUILTIN_THEME
+
+namespace GUI {
+
+using namespace Graphics;
+
+const char *ThemeEngine::rendererModeLabels[] = {
+	"Disabled GFX",
+	"Stardard Renderer (16bpp)",
+	"Antialiased Renderer (16bpp)"
+};
+
+
+/**********************************************************
+ *	ThemeItem functions for drawing queues.
+ *********************************************************/
+void ThemeItemDrawData::drawSelf(bool draw, bool restore) {
+
+	Common::Rect extendedRect = _area;
+	extendedRect.grow(_engine->kDirtyRectangleThreshold + _data->_backgroundOffset);
+
+	if (restore)
+		_engine->restoreBackground(extendedRect);
+
+	if (draw) {
+		Common::List<Graphics::DrawStep>::const_iterator step;
+		for (step = _data->_steps.begin(); step != _data->_steps.end(); ++step)
+			_engine->renderer()->drawStep(_area, *step, _dynamicData);
+	}
+	
+	_engine->addDirtyRect(extendedRect);
+}
+
+void ThemeItemTextData::drawSelf(bool draw, bool restore) {
+	if (_restoreBg || restore)
+		_engine->restoreBackground(_area);
+	
+	if (draw) {
+		_engine->renderer()->setFgColor(_data->_color.r, _data->_color.g, _data->_color.b);
+		_engine->renderer()->drawString(_data->_fontPtr, _text, _area, _alignH, _alignV, _deltax, _ellipsis);
+	}
+
+	_engine->addDirtyRect(_area);
+}
+
+void ThemeItemBitmap::drawSelf(bool draw, bool restore) {
+	if (restore)
+		_engine->restoreBackground(_area);
+
+	if (draw) {
+		if (_alpha)
+			_engine->renderer()->blitAlphaBitmap(_bitmap, _area);
+		else
+			_engine->renderer()->blitSubSurface(_bitmap, _area);
+	}
+
+	_engine->addDirtyRect(_area);
+}
+
+
+
+/**********************************************************
+ *	Data definitions for theme engine elements
+ *********************************************************/
+const ThemeEngine::DrawDataInfo ThemeEngine::kDrawDataDefaults[] = {
+	{kDDMainDialogBackground, "mainmenu_bg", true, kDDNone},
+	{kDDSpecialColorBackground, "special_bg", true, kDDNone},
+	{kDDPlainColorBackground, "plain_bg", true, kDDNone},
+	{kDDDefaultBackground, "default_bg", true, kDDNone},
+	{kDDTextSelectionBackground, "text_selection", false, kDDNone},
+
+	{kDDWidgetBackgroundDefault, "widget_default", true, kDDNone},
+	{kDDWidgetBackgroundSmall, "widget_small", true, kDDNone},
+	{kDDWidgetBackgroundEditText, "widget_textedit", true, kDDNone},
+	{kDDWidgetBackgroundSlider, "widget_slider", true, kDDNone},
+
+	{kDDButtonIdle, "button_idle", true, kDDWidgetBackgroundSlider},
+	{kDDButtonHover, "button_hover", false, kDDButtonIdle},
+	{kDDButtonDisabled, "button_disabled", true, kDDNone},
+
+	{kDDSliderFull, "slider_full", false, kDDNone},
+	{kDDSliderHover, "slider_hover", false, kDDNone},
+	{kDDSliderDisabled, "slider_disabled", true, kDDNone},
+
+	{kDDCheckboxDefault, "checkbox_default", true, kDDNone},
+	{kDDCheckboxDisabled, "checkbox_disabled", true, kDDNone},
+	{kDDCheckboxSelected, "checkbox_selected", false, kDDCheckboxDefault},
+
+	{kDDTabActive, "tab_active", false, kDDTabInactive},
+	{kDDTabInactive, "tab_inactive", true, kDDNone},
+	{kDDTabBackground, "tab_background", true, kDDNone},
+
+	{kDDScrollbarBase, "scrollbar_base", true, kDDNone},
+	
+	{kDDScrollbarButtonIdle, "scrollbar_button_idle", true, kDDNone},
+	{kDDScrollbarButtonHover, "scrollbar_button_hover", false, kDDScrollbarButtonIdle},
+		
+	{kDDScrollbarHandleIdle, "scrollbar_handle_idle", false, kDDNone},
+	{kDDScrollbarHandleHover, "scrollbar_handle_hover", false, kDDScrollbarBase},
+
+	{kDDPopUpIdle, "popup_idle", true, kDDNone},
+	{kDDPopUpHover, "popup_hover", false, kDDPopUpIdle},
+
+	{kDDCaret, "caret", false, kDDNone},
+	{kDDSeparator, "separator", true, kDDNone},
+};
+
+const ThemeEngine::TextDataInfo ThemeEngine::kTextDataDefaults[] = {
+	{kTextDataDefault, "text_default"},
+	{kTextDataHover, "text_hover"},
+	{kTextDataDisabled, "text_disabled"},
+	{kTextDataInverted, "text_inverted"},
+	{kTextDataButton, "text_button"},
+	{kTextDataButtonHover, "text_button_hover"},
+	{kTextDataNormalFont, "text_normal"}
+};
+
+
+/**********************************************************
+ *	ThemeEngine class
+ *********************************************************/
+ThemeEngine::ThemeEngine(Common::String fileName, GraphicsMode mode) : 
+	_vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled), _font(0),
+	_screen(0), _backBuffer(0), _bytesPerPixel(0), _initOk(false), 
+	_themeOk(false), _enabled(false), _buffering(false), _cursor(0) {
+	_system = g_system;
+	_parser = new ThemeParser(this);
+	_themeEval = new GUI::ThemeEval();
+	
+	_useCursor = false;
+
+	for (int i = 0; i < kDrawDataMAX; ++i) {
+		_widgets[i] = 0;
+	}
+	
+	for (int i = 0; i < kTextDataMAX; ++i) {
+		_texts[i] = 0;
+	}
+
+	_graphicsMode = mode;
+	_themeFileName = fileName;
+	_initOk = false;
+}
+
+ThemeEngine::~ThemeEngine() {
+	freeRenderer();
+	freeScreen();
+	freeBackbuffer();
+	unloadTheme();
+	delete _parser;
+	delete _themeEval;
+	delete[] _cursor;
+	
+	for (ImagesMap::iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i)
+		ImageMan.unregisterSurface(i->_key);
+}
+
+
+/**********************************************************
+ *	Theme setup/initialization
+ *********************************************************/
+bool ThemeEngine::init() {
+	// reset everything and reload the graphics
+	deinit();
+	setGraphicsMode(_graphicsMode);
+
+	if (_screen->pixels && _backBuffer->pixels) {
+		_initOk = true;
+		clearAll();
+		resetDrawArea();
+	}
+	
+	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() {
+	if (_initOk) {
+		_system->hideOverlay();
+		freeRenderer();
+		freeScreen();
+		freeBackbuffer();
+		_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;
+	}
+	
+	for (ImagesMap::iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i)
+		ImageMan.unregisterSurface(i->_key);
+
+	if (_themeFileName.hasSuffix(".zip"))
+		ImageMan.remArchive(_themeFileName);
+		
+	Common::File::resetDefaultDirectories();
+	
+	_themeEval->reset();
+	_themeOk = false;
+}
+
+void ThemeEngine::clearAll() {
+	if (!_initOk)
+		return;
+
+	_system->clearOverlay();
+	_system->grabOverlay((OverlayColor*)_screen->pixels, _screen->w);
+}
+
+void ThemeEngine::refresh() {
+	init();
+	if (_enabled) {
+		_system->showOverlay();
+		
+		if (_useCursor) {
+			CursorMan.replaceCursorPalette(_cursorPal, 0, MAX_CURS_COLORS);
+			CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
+		}
+	}
+}
+
+void ThemeEngine::enable() {
+	init();
+	resetDrawArea();
+	
+	if (_useCursor)
+		setUpCursor();
+	
+	_system->showOverlay();
+	clearAll();
+	_enabled = true;
+}
+
+void ThemeEngine::disable() {
+	_system->hideOverlay();
+	
+	if (_useCursor) {
+		CursorMan.popCursorPalette();
+		CursorMan.popCursor();
+	}
+	
+	_enabled = false;
+}
+
+template<typename PixelType> 
+void ThemeEngine::screenInit(bool backBuffer) {
+	uint32 width = _system->getOverlayWidth();
+	uint32 height = _system->getOverlayHeight();
+	
+	if (backBuffer) {
+		freeBackbuffer();
+		_backBuffer = new Surface;
+		_backBuffer->create(width, height, sizeof(PixelType));
+	}
+	
+	freeScreen();
+	_screen = new Surface;
+	_screen->create(width, height, sizeof(PixelType));
+	_system->clearOverlay();
+}
+
+void ThemeEngine::setGraphicsMode(GraphicsMode mode) {
+	switch (mode) {
+	case kGfxStandard16bit:
+	case kGfxAntialias16bit:
+		_bytesPerPixel = sizeof(uint16);
+		screenInit<uint16>(kEnableBackCaching);
+		break;
+
+	default:
+		error("Invalid graphics mode");
+	}
+
+	freeRenderer();
+	_vectorRenderer = createRenderer(mode);
+	_vectorRenderer->setSurface(_screen);
+}
+
+bool ThemeEngine::isWidgetCached(DrawData type, const Common::Rect &r) {
+	return _widgets[type] && _widgets[type]->_cached &&
+		_widgets[type]->_surfaceCache->w == r.width() && 
+		_widgets[type]->_surfaceCache->h == r.height();
+}
+
+void ThemeEngine::drawCached(DrawData type, const Common::Rect &r) {
+	assert(_widgets[type]->_surfaceCache->bytesPerPixel == _screen->bytesPerPixel);
+	_vectorRenderer->blitSurface(_widgets[type]->_surfaceCache, r);
+}
+
+void ThemeEngine::calcBackgroundOffset(DrawData type) {
+	uint maxShadow = 0;
+	for (Common::List<Graphics::DrawStep>::const_iterator step = _widgets[type]->_steps.begin(); 
+		step != _widgets[type]->_steps.end(); ++step) {
+		if ((step->autoWidth || step->autoHeight) && step->shadow > maxShadow) 
+			maxShadow = step->shadow;
+			
+		if (step->drawingCall == &Graphics::VectorRenderer::drawCallback_BEVELSQ && step->bevel > maxShadow)
+			maxShadow = step->bevel;
+	}
+
+	_widgets[type]->_backgroundOffset = maxShadow;
+}
+
+void ThemeEngine::restoreBackground(Common::Rect r, bool special) {
+	r.clip(_screen->w, _screen->h); // AHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHA... Oh god. :(
+	_vectorRenderer->blitSurface(_backBuffer, r);
+}
+
+
+
+
+/**********************************************************
+ *	Theme elements management
+ *********************************************************/
+void ThemeEngine::addDrawStep(const Common::String &drawDataId, Graphics::DrawStep step) {
+	DrawData id = getDrawDataId(drawDataId);
+	
+	assert(_widgets[id] != 0);
+	_widgets[id]->_steps.push_back(step);
+}
+
+bool ThemeEngine::addTextData(const Common::String &drawDataId, const Common::String &textDataId, TextAlign alignH, TextAlignVertical alignV) {
+	DrawData id = getDrawDataId(drawDataId);
+	TextData textId = getTextDataId(textDataId);
+
+	if (id == -1 || textId == -1 || !_widgets[id])
+		return false;
+	
+	_widgets[id]->_textDataId = textId;
+	_widgets[id]->_textAlignH = alignH;
+	_widgets[id]->_textAlignV = alignV;	
+
+	return true;
+}
+
+bool ThemeEngine::addFont(const Common::String &fontId, const Common::String &file, int r, int g, int b) {
+	TextData textId = getTextDataId(fontId);
+	
+	if (textId == -1)
+		return false;
+		
+	if (_texts[textId] != 0)
+		delete _texts[textId];
+		
+	_texts[textId] = new TextDrawData;
+	
+	if (file == "default") {
+		_texts[textId]->_fontPtr = _font;
+	} else {
+		_texts[textId]->_fontPtr = FontMan.getFontByName(file);
+
+		if (!_texts[textId]->_fontPtr) {
+			_texts[textId]->_fontPtr = loadFont(file.c_str());
+			
+			if (!_texts[textId]->_fontPtr)
+				error("Couldn't load %s font '%s'", fontId.c_str(), file.c_str());
+
+			FontMan.assignFontToName(file, _texts[textId]->_fontPtr);
+		}
+	}
+	
+	_texts[textId]->_color.r = r;
+	_texts[textId]->_color.g = g;
+	_texts[textId]->_color.b = b;
+	return true;
+	
+}
+
+bool ThemeEngine::addBitmap(const Common::String &filename) {
+	if (_bitmaps.contains(filename)) {
+		ImageMan.unregisterSurface(filename);
+	}
+	
+	ImageMan.registerSurface(filename, 0);
+	_bitmaps[filename] = ImageMan.getSurface(filename);
+	
+	return _bitmaps[filename] != 0;
+}
+
+bool ThemeEngine::addDrawData(const Common::String &data, bool cached) {
+	DrawData data_id = getDrawDataId(data);
+
+	if (data_id == -1)
+		return false;
+		
+	if (_widgets[data_id] != 0)
+		delete _widgets[data_id];
+
+	_widgets[data_id] = new WidgetDrawData;
+	_widgets[data_id]->_cached = cached;
+	_widgets[data_id]->_buffer = kDrawDataDefaults[data_id].buffer;
+	_widgets[data_id]->_surfaceCache = 0;
+	_widgets[data_id]->_textDataId = -1;
+
+	return true;
+}
+
+
+/**********************************************************
+ *	Theme XML loading
+ *********************************************************/
+bool ThemeEngine::loadTheme(Common::String fileName) {
+	unloadTheme();
+
+	if (fileName != "builtin") {
+		if (fileName.hasSuffix(".zip"))
+			ImageMan.addArchive(fileName);
+		else 
+			Common::File::addDefaultDirectory(fileName);
+	}
+
+	if (fileName == "builtin") {
+		if (!loadDefaultXML())
+			error("Could not load default embeded theme");
+	}
+	else if (!loadThemeXML(fileName)) {
+		warning("Could not parse custom theme '%s'. Falling back to default theme", fileName.c_str());
+		
+		if (!loadDefaultXML()) // if we can't load the embeded theme, this is a complete failure
+			error("Could not load default embeded theme");
+	}
+
+	for (int i = 0; i < kDrawDataMAX; ++i) {
+		if (_widgets[i] == 0) {
+			warning("Missing data asset: '%s'", kDrawDataDefaults[i].name);
+		} else {
+			calcBackgroundOffset((DrawData)i);
+
+			// TODO: draw the cached widget to the cache surface
+			if (_widgets[i]->_cached) {}
+		}
+	}
+	
+	_themeOk = true;
+	return true;
+}
+
+bool ThemeEngine::loadDefaultXML() {
+	
+	// The default XML theme is included on runtime from a pregenerated
+	// 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.
+
+#ifdef GUI_ENABLE_BUILTIN_THEME
+	const char *defaultXML =
+#include "themes/default.inc"
+	;
+	
+	if (!parser()->loadBuffer((const byte*)defaultXML, strlen(defaultXML), false))
+		return false;
+		
+	_themeName = "ScummVM Classic Theme (Builtin Version)";
+	_themeFileName = "builtin";
+
+	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 ThemeEngine::loadThemeXML(Common::String themeName) {
+	assert(_parser);
+	_themeName.clear();
+	
+	char fileNameBuffer[32];
+	char stxHeader[128];
+	int parseCount = 0;
+	
+#ifdef USE_ZLIB
+	unzFile zipFile = unzOpen((themeName).c_str());
+	
+	if (zipFile && unzGoToFirstFile(zipFile) == UNZ_OK) {
+		while (true) {
+			unz_file_info fileInfo;
+			unzOpenCurrentFile(zipFile);
+			unzGetCurrentFileInfo(zipFile, &fileInfo, fileNameBuffer, 32, NULL, 0, NULL, 0);
+		
+			if (matchString(fileNameBuffer, "*.stx") || !strcmp(fileNameBuffer, "THEMERC")) {
+				uint8 *buffer = new uint8[fileInfo.uncompressed_size+1];
+				assert(buffer);
+				memset(buffer, 0, (fileInfo.uncompressed_size+1)*sizeof(uint8));
+				unzReadCurrentFile(zipFile, buffer, fileInfo.uncompressed_size);
+			
+				Common::MemoryReadStream *stream = new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size+1, true);
+				
+				if (!strcmp(fileNameBuffer, "THEMERC")) {
+					stream->readLine(stxHeader, 128);
+
+					if (!themeConfigParseHeader(stxHeader, _themeName)) {
+						warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str());
+						return false;
+					}
+						
+					delete stream;
+					
+				} else {
+					parseCount++;
+					
+					if (parser()->loadStream(stream) == false || parser()->parse() == false) {
+						warning("Failed to load stream for zipped file '%s'", fileNameBuffer);
+						unzClose(zipFile);
+						return false;
+					}
+				}
+			} 
+		
+			unzCloseCurrentFile(zipFile);
+		
+			if (unzGoToNextFile(zipFile) != UNZ_OK)
+				break;
+		}
+	} else {
+#endif
+        
+        FilesystemNode node(themeName);
+		if (node.exists() && node.isReadable() && node.isDirectory()) {
+			FSList fslist;
+			if (!node.getChildren(fslist, FilesystemNode::kListFilesOnly))
+				return false;
+			
+			for (FSList::const_iterator i = fslist.begin(); i != fslist.end(); ++i) {
+				if (i->getName().hasSuffix(".stx")) {
+					parseCount++;
+					
+					if (parser()->loadFile(*i) == false || parser()->parse() == false) {
+						warning("Failed to parse STX file '%s'", i->getName().c_str());
+						return false;
+					}
+				} else if (i->getName() == "THEMERC") {
+					Common::File f;
+					f.open(*i);
+					f.readLine(stxHeader, 128);
+
+					if (!themeConfigParseHeader(stxHeader, _themeName)) {
+						warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str());
+						return false;
+					}
+				}
+			}
+		}
+#ifdef USE_ZLIB
+	}
+	
+	unzClose(zipFile);
+	
+#endif
+
+
+	return (parseCount > 0 && _themeName.empty() == false);
+}
+
+
+
+/**********************************************************
+ *	Drawing Queue management
+ *********************************************************/
+void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic) {
+	if (_widgets[type] == 0)
+		return;
+		
+	Common::Rect area = r;
+	area.clip(_screen->w, _screen->h);
+
+	ThemeItemDrawData *q = new ThemeItemDrawData(this, _widgets[type], area, dynamic);
+	
+	if (_buffering) {
+		if (_widgets[type]->_buffer) {
+			_bufferQueue.push_back(q);	
+		} else {
+			if (kDrawDataDefaults[type].parent != kDDNone && kDrawDataDefaults[type].parent != type)
+				queueDD(kDrawDataDefaults[type].parent, r);
+			
+			_screenQueue.push_back(q);
+		}
+	} else {
+		q->drawSelf(!_widgets[type]->_buffer, _widgets[type]->_buffer);
+		delete q;
+	}
+}
+
+void ThemeEngine::queueDDText(TextData type, const Common::Rect &r, const Common::String &text, bool restoreBg,
+	bool ellipsis, TextAlign alignH, TextAlignVertical alignV, int deltax) {
+		
+	if (_texts[type] == 0)
+		return;
+
+	Common::Rect area = r;
+	area.clip(_screen->w, _screen->h);
+
+	ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], area, text, alignH, alignV, ellipsis, restoreBg, deltax);
+	
+	if (_buffering) {		
+		_screenQueue.push_back(q);
+	} else {
+		q->drawSelf(true, false);
+		delete q;
+	}
+}
+
+void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha) {
+
+	Common::Rect area = r;
+	area.clip(_screen->w, _screen->h);
+
+	ThemeItemBitmap *q = new ThemeItemBitmap(this, area, bitmap, alpha);
+	
+	if (_buffering) {
+		_bufferQueue.push_back(q);
+	} else {
+		q->drawSelf(true, false);
+		delete q;
+	}
+}
+
+
+
+/**********************************************************
+ *	Widget drawing functions
+ *********************************************************/
+void ThemeEngine::drawButton(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, uint16 hints) {
+	if (!ready())
+		return;
+		
+	DrawData dd = kDDButtonIdle;
+
+	if (state == kStateEnabled)
+		dd = kDDButtonIdle;
+	else if (state == kStateHighlight)
+		dd = kDDButtonHover;
+	else if (state == kStateDisabled)
+		dd = kDDButtonDisabled;
+
+	queueDD(dd, r);
+	queueDDText(getTextData(dd), r, str, false, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV);
+}
+
+void ThemeEngine::drawLineSeparator(const Common::Rect &r, WidgetStateInfo state) {
+	if (!ready())
+		return;
+
+	queueDD(kDDSeparator, r);
+}
+
+void ThemeEngine::drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) {
+	if (!ready())
+		return;
+
+	Common::Rect r2 = r;
+	DrawData dd = kDDCheckboxDefault;
+	
+	if (checked)
+		dd = kDDCheckboxSelected;
+		
+	if (state == kStateDisabled)
+		dd = kDDCheckboxDisabled;
+	
+	TextData td = (state == kStateHighlight) ? kTextDataHover : getTextData(dd);
+	const int checkBoxSize = MIN((int)r.height(), getFontHeight());
+
+	r2.bottom = r2.top + checkBoxSize;
+	r2.right = r2.left + checkBoxSize;
+
+	queueDD(dd, r2);
+	
+	r2.left = r2.right + checkBoxSize;
+	r2.right = r.right;
+	
+	queueDDText(td, r2, str, false, false, _widgets[kDDCheckboxDefault]->_textAlignH, _widgets[dd]->_textAlignV);
+}
+
+void ThemeEngine::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) {
+	if (!ready())
+		return;
+		
+	DrawData dd = kDDSliderFull;
+	
+	if (state == kStateHighlight)
+		dd = kDDSliderHover;
+	else if (state == kStateDisabled)
+		dd = kDDSliderDisabled;
+
+	Common::Rect r2 = r;
+	r2.setWidth(MIN((int16)width, r.width()));
+//	r2.top++; r2.bottom--; r2.left++; r2.right--;
+
+	drawWidgetBackground(r, 0, kWidgetBackgroundSlider, kStateEnabled);
+	
+	if (width > r.width() * 5 / 100)
+		queueDD(dd, r2);
+}
+
+void ThemeEngine::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, ScrollbarState scrollState, WidgetStateInfo state) {
+	if (!ready())
+		return;
+		
+	queueDD(kDDScrollbarBase, r);
+	
+	Common::Rect r2 = r;
+	const int buttonExtra = (r.width() * 120) / 100;
+	
+	r2.bottom = r2.top + buttonExtra;
+	queueDD(scrollState == kScrollbarStateUp ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, Graphics::VectorRenderer::kTriangleUp);
+	
+	r2.translate(0, r.height() - r2.height());
+	queueDD(scrollState == kScrollbarStateDown ? kDDScrollbarButtonHover : kDDScrollbarButtonIdle, r2, Graphics::VectorRenderer::kTriangleDown);
+	
+	r2 = r;
+	r2.left += 1;
+	r2.right -= 1;
+	r2.top += sliderY;
+	r2.bottom = r2.top + sliderHeight - 1;
+	
+	r2.top += r.width() / 5;
+	r2.bottom -= r.width() / 5; 
+	queueDD(scrollState == kScrollbarStateSlider ? kDDScrollbarHandleHover : kDDScrollbarHandleIdle, r2);
+}
+
+void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground bgtype, WidgetStateInfo state) {
+	if (!ready())
+		return;
+		
+	switch (bgtype) {
+		case kDialogBackgroundMain:
+			queueDD(kDDMainDialogBackground, r);
+			break;
+			
+		case kDialogBackgroundSpecial:
+			queueDD(kDDSpecialColorBackground, r);
+			break;
+			
+		case kDialogBackgroundPlain:
+			queueDD(kDDPlainColorBackground, r);
+			break;
+			
+		case kDialogBackgroundDefault:
+			queueDD(kDDDefaultBackground, r);
+			break;
+	}
+}
+
+void ThemeEngine::drawCaret(const Common::Rect &r, bool erase, WidgetStateInfo state) {
+	if (!ready())
+		return;
+	
+	if (erase) {
+		restoreBackground(r);
+		addDirtyRect(r);
+	} else
+		queueDD(kDDCaret, r);
+}
+
+void ThemeEngine::drawPopUpWidget(const Common::Rect &r, const Common::String &sel, int deltax, WidgetStateInfo state, TextAlign align) {
+	if (!ready())
+		return;
+		
+	DrawData dd = (state == kStateHighlight) ? kDDPopUpHover : kDDPopUpIdle;
+	
+	queueDD(dd, r);
+	
+	if (!sel.empty()) {
+		Common::Rect text(r.left, r.top, r.right - 16, r.bottom);
+		queueDDText(getTextData(dd), text, sel, false, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV, deltax);
+	}
+}
+
+void ThemeEngine::drawSurface(const Common::Rect &r, const Graphics::Surface &surface, WidgetStateInfo state, int alpha, bool themeTrans) {
+	if (!ready())
+		return;
+	
+	queueBitmap(&surface, r, themeTrans);
+}
+
+void ThemeEngine::drawWidgetBackground(const Common::Rect &r, uint16 hints, WidgetBackground background, WidgetStateInfo state) {
+	if (!ready())
+		return;
+		
+	switch (background) {
+	case kWidgetBackgroundBorderSmall:
+		queueDD(kDDWidgetBackgroundSmall, r);
+		break;
+		
+	case kWidgetBackgroundEditText:
+		queueDD(kDDWidgetBackgroundEditText, r);
+		break;
+		
+	case kWidgetBackgroundSlider:
+		queueDD(kDDWidgetBackgroundSlider, r);
+		break;
+		
+	default:
+		queueDD(kDDWidgetBackgroundDefault, r);
+		break;
+	}
+}
+
+void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, const Common::Array<Common::String> &tabs, int active, uint16 hints, int titleVPad, WidgetStateInfo state) {
+	if (!ready())
+		return;
+		
+	const int tabOffset = 2;
+	tabWidth -= tabOffset;
+	
+	queueDD(kDDTabBackground, Common::Rect(r.left, r.top, r.right, r.top + tabHeight));
+	
+	for (int i = 0; i < (int)tabs.size(); ++i) {
+		if (i == active)
+			continue;
+	
+		Common::Rect tabRect(r.left + i * (tabWidth + tabOffset), r.top, r.left + i * (tabWidth + tabOffset) + tabWidth, r.top + tabHeight);
+		queueDD(kDDTabInactive, tabRect);
+		queueDDText(getTextData(kDDTabInactive), tabRect, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV);
+	}
+	
+	if (active >= 0) {
+		Common::Rect tabRect(r.left + active * (tabWidth + tabOffset), r.top, r.left + active * (tabWidth + tabOffset) + tabWidth, r.top + tabHeight);
+		const uint16 tabLeft = active * (tabWidth + tabOffset);
+		const uint16 tabRight =  MAX(r.right - tabRect.right, 0);
+		queueDD(kDDTabActive, tabRect, (tabLeft << 16) | (tabRight & 0xFFFF));
+		queueDDText(getTextData(kDDTabActive), tabRect, tabs[active], false, false, _widgets[kDDTabActive]->_textAlignH, _widgets[kDDTabActive]->_textAlignV);
+	}
+}
+
+void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, TextAlign align, bool inverted, int deltax, bool useEllipsis, FontStyle font) {
+	if (!ready())
+		return;	
+		
+	if (inverted) {
+		queueDD(kDDTextSelectionBackground, r);
+		queueDDText(kTextDataInverted, r, str, false, useEllipsis, align, kTextAlignVCenter, deltax);
+		return;
+	}
+	
+	switch (font) {
+		case kFontStyleNormal:
+			queueDDText(kTextDataNormalFont, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax);
+			return;
+			
+		default:
+			break;
+	}
+
+	switch (state) {
+		case kStateDisabled:
+			queueDDText(kTextDataDisabled, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax);
+			return;
+			
+		case kStateHighlight:
+			queueDDText(kTextDataHover, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax);
+			return;
+		
+		case kStateEnabled:
+			queueDDText(kTextDataDefault, r, str, true, useEllipsis, align, kTextAlignVCenter, deltax);
+			return;
+	}
+}
+
+void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state) {
+	if (!ready())
+		return;
+		
+	restoreBackground(r);
+	font->drawChar(_screen, ch, r.left, r.top, 0);
+	addDirtyRect(r);
+}
+
+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);
+}
+
+
+
+/**********************************************************
+ *	Screen/overlay management
+ *********************************************************/
+void ThemeEngine::updateScreen() {
+	ThemeItem *item = 0;
+
+	if (!_bufferQueue.empty()) {
+		_vectorRenderer->setSurface(_backBuffer);
+		
+		for (Common::List<ThemeItem*>::iterator q = _bufferQueue.begin(); q != _bufferQueue.end(); ++q) {
+			(*q)->drawSelf(true, false);
+			delete *q;
+		}
+			
+		_vectorRenderer->setSurface(_screen);
+		_vectorRenderer->blitSurface(_backBuffer, Common::Rect(0, 0, _screen->w, _screen->h));
+		_bufferQueue.clear();
+	}
+	
+	if (!_screenQueue.empty()) {
+		_vectorRenderer->disableShadows();
+		for (Common::List<ThemeItem*>::iterator q = _screenQueue.begin(); q != _screenQueue.end(); ++q) {
+			(*q)->drawSelf(true, false);
+			delete *q;
+		}
+			
+		_vectorRenderer->enableShadows();
+		_screenQueue.clear();
+	}
+		
+	renderDirtyScreen();
+}
+
+void ThemeEngine::renderDirtyScreen() {
+	if (_dirtyScreen.empty())
+		return;
+
+	Common::List<Common::Rect>::const_iterator i, j;
+	for (i = _dirtyScreen.begin(); i != _dirtyScreen.end(); ++i) {
+		for (j = i; j != _dirtyScreen.end(); ++j)
+			if (j != i && i->contains(*j))
+				j = _dirtyScreen.reverse_erase(j);
+
+		_vectorRenderer->copyFrame(_system, *i);
+	}
+		
+	_dirtyScreen.clear();
+}
+
+void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) {
+	if (doBuffer)
+		_buffering = true;
+		
+	if (style != kShadingNone) {
+		_vectorRenderer->applyScreenShading(style);
+		addDirtyRect(Common::Rect(0, 0, _screen->w, _screen->h));
+	}
+
+	_vectorRenderer->setSurface(_backBuffer);
+	_vectorRenderer->blitSurface(_screen, Common::Rect(0, 0, _screen->w, _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);
+}
+
+bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale) {
+	if (!_system->hasFeature(OSystem::kFeatureCursorHasPalette))
+		return false;
+		
+	const Surface *cursor = _bitmaps[filename];
+	
+	if (!cursor)
+		return false;
+		
+	_cursorHotspotX = hotspotX;
+	_cursorHotspotY = hotspotY;
+	_cursorTargetScale = scale;
+
+	_cursorWidth = cursor->w;
+	_cursorHeight = cursor->h;
+
+	uint colorsFound = 0;
+	const OverlayColor *src = (const OverlayColor*)cursor->pixels;
+
+	byte *table = new byte[65536];
+	assert(table);
+	memset(table, 0, sizeof(byte)*65536);
+
+	byte r, g, b;
+
+	uint16 transparency = RGBToColor<ColorMasks<565> >(255, 0, 255);
+
+	delete[] _cursor;
+
+	_cursor = new byte[_cursorWidth * _cursorHeight];
+	assert(_cursor);
+	memset(_cursor, 255, sizeof(byte)*_cursorWidth*_cursorHeight);
+
+	for (uint y = 0; y < _cursorHeight; ++y) {
+		for (uint x = 0; x < _cursorWidth; ++x) {
+			_system->colorToRGB(src[x], r, g, b);
+			uint16 col = RGBToColor<ColorMasks<565> >(r, g, b);
+			if (!table[col] && col != transparency) {
+				table[col] = colorsFound++;
+
+				uint index = table[col];
+				_cursorPal[index * 4 + 0] = r;
+				_cursorPal[index * 4 + 1] = g;
+				_cursorPal[index * 4 + 2] = b;
+				_cursorPal[index * 4 + 3] = 0xFF;
+
+				if (colorsFound > MAX_CURS_COLORS) {
+					warning("Cursor contains too much colors (%d, but only %d are allowed)", colorsFound, MAX_CURS_COLORS);
+					return false;
+				}
+			}
+
+			if (col != transparency) {
+				uint index = table[col];
+				_cursor[y * _cursorWidth + x] = index;
+			}
+		}
+		src += _cursorWidth;
+	}
+
+	_useCursor = true;
+	delete[] table;
+	
+	return true;
+}
+
+} // end of namespace GUI.

Copied: scummvm/branches/gsoc2008-gui/gui/ThemeEngine.h (from rev 34272, scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.h)
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeEngine.h	                        (rev 0)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeEngine.h	2008-09-02 17:51:08 UTC (rev 34285)
@@ -0,0 +1,744 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef THEME_ENGINE_H
+#define THEME_ENGINE_H
+
+#include "common/scummsys.h"
+#include "graphics/surface.h"
+#include "common/system.h"
+
+#include "graphics/surface.h"
+#include "graphics/fontman.h"
+
+#include "gui/dialog.h"
+#include "gui/ThemeParser.h"
+#include "graphics/VectorRenderer.h"
+#include "gui/ThemeEval.h"
+
+
+namespace GUI {
+
+struct WidgetDrawData;
+struct DrawDataInfo;
+class ThemeEval;
+
+struct TextDrawData {
+	const Graphics::Font *_fontPtr;
+	
+	struct { 
+		uint8 r, g, b;
+	} _color;
+};
+
+struct WidgetDrawData {
+	/** List of all the steps needed to draw this widget */
+	Common::List<Graphics::DrawStep> _steps;
+	
+	int _textDataId;
+	GUI::Theme::TextAlign _textAlignH;
+	GUI::Theme::TextAlignVertical _textAlignV;
+
+	/** Extra space that the widget occupies when it's drawn.
+	    E.g. when taking into account rounded corners, drop shadows, etc 
+		Used when restoring the widget background */
+	uint16 _backgroundOffset;
+
+	/** Sets whether the widget is cached beforehand. */
+	bool _cached;
+	bool _buffer;
+
+	/** Texture where the cached widget is stored. */
+	Graphics::Surface *_surfaceCache;
+
+	~WidgetDrawData() {
+		_steps.clear();
+
+		if (_surfaceCache) {
+			_surfaceCache->free();
+			delete _surfaceCache;
+		}
+	}
+};
+
+class ThemeItem {
+	
+public:
+	ThemeItem(ThemeEngine *engine, const Common::Rect &area) : 
+		_engine(engine), _area(area) {}
+
+	virtual void drawSelf(bool doDraw, bool doRestore) = 0;
+
+protected:
+	Common::Rect _area;
+	ThemeEngine *_engine;
+};
+
+class ThemeItemDrawData : public ThemeItem {
+public:
+	ThemeItemDrawData(ThemeEngine *engine, const WidgetDrawData *data, const Common::Rect &area, uint32 dynData) : 
+		ThemeItem(engine, area), _dynamicData(dynData), _data(data) {}
+
+	void drawSelf(bool draw, bool restore);
+
+protected:
+	uint32 _dynamicData;
+	const WidgetDrawData *_data;
+};
+
+class ThemeItemTextData : public ThemeItem {
+public:
+	ThemeItemTextData(ThemeEngine *engine, const TextDrawData *data, const Common::Rect &area, const Common::String &text,
+		GUI::Theme::TextAlign alignH, GUI::Theme::TextAlignVertical alignV,
+		bool ellipsis, bool restoreBg, int deltaX) : 
+		ThemeItem(engine, area), _data(data), _text(text), _alignH(alignH), _alignV(alignV), 
+		_ellipsis(ellipsis), _restoreBg(restoreBg), _deltax(deltaX) {}
+
+	void drawSelf(bool draw, bool restore);
+
+protected:
+	const TextDrawData *_data;
+	Common::String _text;
+	GUI::Theme::TextAlign _alignH;
+	GUI::Theme::TextAlignVertical _alignV;
+	bool _ellipsis;
+	bool _restoreBg;
+	int _deltax;
+};
+
+class ThemeItemBitmap : public ThemeItem {
+public:
+	ThemeItemBitmap(ThemeEngine *engine, const Common::Rect &area, const Graphics::Surface *bitmap, bool alpha) : 
+		ThemeItem(engine, area), _bitmap(bitmap), _alpha(alpha) {}
+
+	void drawSelf(bool draw, bool restore);
+
+protected:
+	const Graphics::Surface *_bitmap;
+	bool _alpha;
+};
+
+
+class ThemeEngine : public Theme {
+protected:
+	typedef Common::String String;
+	typedef GUI::Dialog Dialog;
+	typedef Common::HashMap<Common::String, Graphics::Surface*> ImagesMap;
+
+	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
+	 *	of a widget in a given state.
+	*/
+	enum DrawData {
+		kDDMainDialogBackground,
+		kDDSpecialColorBackground,
+		kDDPlainColorBackground,
+		kDDDefaultBackground,
+		kDDTextSelectionBackground,
+		
+		kDDWidgetBackgroundDefault,
+		kDDWidgetBackgroundSmall,
+		kDDWidgetBackgroundEditText,
+		kDDWidgetBackgroundSlider,
+
+		kDDButtonIdle,
+		kDDButtonHover,
+		kDDButtonDisabled,
+
+		kDDSliderFull,
+		kDDSliderHover,
+		kDDSliderDisabled,
+
+		kDDCheckboxDefault,
+		kDDCheckboxDisabled,
+		kDDCheckboxSelected,
+
+		kDDTabActive,
+		kDDTabInactive,
+		kDDTabBackground,
+
+		kDDScrollbarBase,
+		kDDScrollbarButtonIdle,
+		kDDScrollbarButtonHover,
+		kDDScrollbarHandleIdle,
+		kDDScrollbarHandleHover,
+
+		kDDPopUpIdle,
+		kDDPopUpHover,
+		
+		kDDCaret,
+		kDDSeparator,
+		kDrawDataMAX,
+		kDDNone = -1
+	};
+	
+	/**
+	 * Default values for each DrawData item.
+	 * @see kDrawDataDefaults[] for implementation.
+	 */
+	static const struct DrawDataInfo {
+		DrawData id; 		/** The actual ID of the DrawData item. */
+		const char *name; 	/** The name of the DrawData item as it appears in the Theme Description files */
+		bool buffer; 		/** Sets whether this item is buffered on the backbuffer or drawn directly to the screen. */
+		DrawData parent; 	/** Parent DrawData item, for items that overlay. E.g. kButtonIdle -> kButtonHover */
+	} kDrawDataDefaults[];
+	
+	
+	enum TextData {
+		kTextDataNone = -1,
+		kTextDataDefault = 0,
+		kTextDataHover,
+		kTextDataDisabled,
+		kTextDataInverted,
+		kTextDataButton,
+		kTextDataButtonHover,
+		kTextDataNormalFont,
+		kTextDataMAX
+	};
+	
+	static const struct TextDataInfo {
+		TextData id;
+		const char *name;
+	} kTextDataDefaults[];
+	
+	
+public:
+	/** Graphics mode enumeration.
+	 *	Each item represents a set of BPP and Renderer modes for a given
+	 * surface.
+	 */
+	enum GraphicsMode {
+		kGfxDisabled = 0,	/** No GFX */
+		kGfxStandard16bit,	/** 2BPP with the standard (aliased) renderer. */
+		kGfxAntialias16bit,	/** 2BPP with the optimized AA renderer. */
+		kGfxMAX
+	};
+
+	/** Constant value to expand dirty rectangles, to make sure they are fully copied */
+	static const int kDirtyRectangleThreshold = 1;
+	
+	static const char *rendererModeLabels[];
+	
+	/** Default constructor */
+	ThemeEngine(Common::String fileName, GraphicsMode mode);
+
+	/** Default destructor */
+	~ThemeEngine();
+	
+	GUI::ThemeEval *themeEval() { return _themeEval; }
+
+	/**
+	 *	VIRTUAL METHODS
+	 *	This is the implementation of the GUI::Theme API to allow
+	 *	the ThemeEngine class to be plugged in as any other GUI
+	 *	theme. In fact, the renderer works like any other GUI theme,
+	 *	but supports extensive customization of the drawn widgets.
+	 */
+	bool init();
+	void deinit();
+	void clearAll();
+
+	void refresh();
+	void enable();
+	void disable();
+	
+	/**
+	 *	Implementation of the GUI::Theme API. Called when a
+	 *	new dialog is opened. Note that the boolean parameter
+	 *	meaning has been changed.
+	 *
+	 * @param enableBuffering If set to true, buffering is enabled for
+	 *						  drawing this dialog, and will continue enabled
+	 *						  until disabled.
+	 */
+	void openDialog(bool enableBuffering, ShadingStyle shading = kShadingNone);
+	
+	/**
+	 *	The updateScreen() method is called every frame.
+	 *	It processes all the drawing queues and then copies dirty rects
+	 *	in the current Screen surface to the overlay.
+	 */
+	void updateScreen();
+
+	/** Since the rendering pipeline changes, closing all dialogs causes no effect 
+		TODO: remove this from the original GUI::Theme API */
+	void closeAllDialogs() {}
+	
+	/** Drawing area has been removed: it was too hackish. A workaround is on the works.
+	 	TODO: finish the workaround for the credits dialog
+		TODO: remove this from the original GUI::Theme API */
+	void resetDrawArea() {}
+
+	
+	/**
+	 *	FONT MANAGEMENT METHODS
+	 */
+	
+	TextData fontStyleToData(FontStyle font) const {
+		switch (font) {
+			case kFontStyleNormal:
+				return kTextDataNormalFont;
+			
+			default:
+				return kTextDataDefault;
+		}
+	}
+	
+	const Graphics::Font *getFont(FontStyle font) const { return _texts[fontStyleToData(font)]->_fontPtr; }
+	
+	int getFontHeight(FontStyle font = kFontStyleBold) const { 
+		return ready() ? _texts[fontStyleToData(font)]->_fontPtr->getFontHeight() : 0;
+	}
+	
+	int getStringWidth(const Common::String &str, FontStyle font) const {
+		return ready() ? _texts[fontStyleToData(font)]->_fontPtr->getStringWidth(str) : 0;
+	}
+	
+	int getCharWidth(byte c, FontStyle font) const { 
+		return ready() ? _texts[fontStyleToData(font)]->_fontPtr->getCharWidth(c) : 0; 
+	}
+
+
+	/**
+	 *	WIDGET DRAWING METHODS
+	 */
+	void drawWidgetBackground(const Common::Rect &r, uint16 hints, 
+		WidgetBackground background = kWidgetBackgroundPlain, WidgetStateInfo state = kStateEnabled);
+		
+	void drawButton(const Common::Rect &r, const Common::String &str, 
+		WidgetStateInfo state = kStateEnabled, uint16 hints = 0);
+	
+	void drawSurface(const Common::Rect &r, const Graphics::Surface &surface, 
+		WidgetStateInfo state = kStateEnabled, int alpha = 256, bool themeTrans = false);
+	
+	void drawSlider(const Common::Rect &r, int width, 
+		WidgetStateInfo state = kStateEnabled);
+	
+	void drawCheckbox(const Common::Rect &r, const Common::String &str, 
+		bool checked, WidgetStateInfo state = kStateEnabled);
+	
+	void drawTab(const Common::Rect &r, int tabHeight, int tabWidth, 
+		const Common::Array<Common::String> &tabs, int active, uint16 hints, 
+		int titleVPad, WidgetStateInfo state = kStateEnabled);
+	
+	void drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, 
+		ScrollbarState, WidgetStateInfo state = kStateEnabled);
+	
+	void drawPopUpWidget(const Common::Rect &r, const Common::String &sel, 
+		int deltax, WidgetStateInfo state = kStateEnabled, TextAlign align = kTextAlignLeft);
+	
+	void drawCaret(const Common::Rect &r, bool erase, 
+		WidgetStateInfo state = kStateEnabled);
+	
+	void drawLineSeparator(const Common::Rect &r, WidgetStateInfo state = kStateEnabled);
+
+	void drawDialogBackground(const Common::Rect &r, DialogBackground type, WidgetStateInfo state);
+	
+	void drawText(const Common::Rect &r, const Common::String &str, 
+		WidgetStateInfo state, TextAlign align, bool inverted, int deltax, bool useEllipsis, FontStyle font);
+	
+	void drawChar(const Common::Rect &r, byte ch, 
+		const Graphics::Font *font, WidgetStateInfo state);
+	
+	/**
+	 *	Actual implementation of a Dirty Rect drawing routine.
+	 * 	Dirty rectangles are queued on a list and are later merged/calculated
+	 *	before the actual drawing.
+	 *
+	 *	@param r Area of the dirty rect.
+	 *	@param backup Deprecated.
+	 *	@param special Deprecated.
+	 */
+	bool addDirtyRect(Common::Rect r, bool backup = false, bool special = false) {
+		_dirtyScreen.push_back(r);
+		return true;
+	}
+
+
+	/**
+	 *	Returns the DrawData enumeration value that represents the given string
+	 *	in the DrawDataDefaults enumeration.
+	 *	It's slow, but called sparsely.
+	 *
+	 *	@returns The drawdata enum value, or -1 if not found.
+	 *	@param name The representing name, as found on Theme Description XML files.
+	 *	@see kDrawDataDefaults[]
+	 */
+	DrawData getDrawDataId(const Common::String &name) {
+		for (int i = 0; i < kDrawDataMAX; ++i)
+			if (name.compareToIgnoreCase(kDrawDataDefaults[i].name) == 0)
+				return kDrawDataDefaults[i].id;
+
+		return kDDNone;
+	}
+	
+	TextData getTextDataId(const Common::String &name) {
+		for (int i = 0; i < kTextDataMAX; ++i)
+			if (name.compareToIgnoreCase(kTextDataDefaults[i].name) == 0)
+				return kTextDataDefaults[i].id;
+
+		return kTextDataNone;
+	}
+
+	/**
+	 *	Interface for ThemeParser class: Parsed DrawSteps are added via this function.
+	 *	There is no return type because DrawSteps can always be added, unless something
+	 *	goes horribly wrong.
+	 *	The specified step will be added to the Steps list of the given DrawData id.
+	 *
+	 *	@param drawDataId The representing DrawData name, as found on Theme Description XML files.
+	 *	@param step The actual DrawStep struct to be added.
+	 */
+	void addDrawStep(const Common::String &drawDataId, Graphics::DrawStep step);
+	
+	/**
+	 *	Interfacefor the ThemeParser class: Parsed DrawData sets are added via this function.
+	 *	The goal of the function is to initialize each DrawData set before their DrawSteps can
+	 *	be added, hence this must be called for each DD set before addDrawStep() can be called
+	 *	for that given set.
+	 *
+	 *	@param data The representing DrawData name, as found on Theme Description XML files.
+	 *	@param cached Whether this DD set will be cached beforehand.
+	 */ 
+	bool addDrawData(const Common::String &data, bool cached);
+	
+	
+	/**
+	 *	Interface for the ThemeParser class: Loads a font to use on the GUI from the given
+	 *	filename.
+	 *
+	 *	@param fontName Identifier name for the font.
+	 * 	@param file Name of the font file.
+	 *	@param r, g, b Color of the font.
+	 */
+	bool addFont(const Common::String &fontName, const Common::String &file, int r, int g, int b);
+	
+	
+	/**
+	 *	Interface for the ThemeParser class: Loads a bitmap file to use on the GUI.
+	 * 	The filename is also used as its identifier.
+	 *
+	 *	@param filename Name of the bitmap file.
+	 */
+	bool addBitmap(const Common::String &filename);
+	
+	/**
+	 *	Adds a new TextStep from the ThemeParser. This will be deprecated/removed once the 
+	 *	new Font API is in place.
+	 */
+	bool addTextData(const Common::String &drawDataId, const Common::String &textDataId, TextAlign alignH, TextAlignVertical alignV);
+
+	/** Interface to the new Theme XML parser */
+	ThemeParser *parser() {
+		return _parser;
+	}
+
+	/**
+	 *	Returns if the Theme is ready to draw stuff on screen.
+	 *	Must be called instead of just checking _initOk, because
+	 *	this checks if the renderer is initialized AND if the theme
+	 *	is loaded.
+	 */
+	bool ready() const {
+		return _initOk && _themeOk;
+	}
+
+	/** Custom implementation of the GUI::Theme API, changed to use the XML parser. */
+	bool loadTheme(Common::String themeName);
+	
+	/**
+	 *	Changes the active graphics mode of the GUI; may be used to either
+	 *	initialize the GUI or to change the mode while the GUI is already running.
+	 */
+	void setGraphicsMode(GraphicsMode mode);
+
+
+	/**
+	 *	Finishes buffering: widgets from then on will be drawn straight on the screen
+	 *	without drawing queues.
+	 */
+	void finishBuffering() { _buffering = false; }
+	void startBuffering() { _buffering = true; }
+	
+	ThemeEval *evaluator() { return _themeEval; }
+	VectorRenderer *renderer() { return _vectorRenderer; }
+	
+	bool supportsImages() const { return true; }
+	bool ownCursor() const { return _useCursor; }
+	
+	Graphics::Surface *getBitmap(const Common::String &name) {
+		return _bitmaps.contains(name) ? _bitmaps[name] : 0;
+	}
+	
+	const Graphics::Surface *getImageSurface(const kThemeImages n) const {
+		if (n == kImageLogo)
+			return _bitmaps.contains("logo.bmp") ? _bitmaps["logo.bmp"] : 0;
+			
+		return 0;
+	}
+	
+	/**
+	 *	Interface for the Theme Parser: Creates a new cursor by loading the given
+	 *	bitmap and sets it as the active cursor.
+	 *
+	 *	@param filename File name of the bitmap to load.
+	 * 	@param hotspotX X Coordinate of the bitmap which does the cursor click.
+	 *	@param hotspotY	Y Coordinate of the bitmap which does the cursor click.
+	 *	@param scale	Scale at which the bitmap is supposed to be used.
+	 */
+	bool createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale);
+
+	/**
+	 *	Wrapper for restoring data from the Back Buffer to the screen.
+	 *	The actual processing is done in the VectorRenderer.
+	 *
+	 *	@param r Area to restore.
+	 *	@param special Deprecated.
+	 */
+	void restoreBackground(Common::Rect r, bool special = false);
+
+	/**
+	 *	Checks if a given DrawData set for a widget has been cached beforehand
+	 *	and is ready to be blit into the screen.
+	 *
+	 *	@param type DrawData type of the widget.
+	 *	@param r Size of the widget which is expected to be cached.
+	 */
+	bool isWidgetCached(DrawData type, const Common::Rect &r);
+
+protected:
+
+	const Common::String &getThemeName() const { return _themeName; }
+	const Common::String &getThemeFileName() const { return _themeFileName; }
+	int getGraphicsMode() const { return _graphicsMode; }
+	
+	/**
+	 *	Initializes the drawing screen surfaces, _screen and _backBuffer.
+	 *	If the surfaces already exist, they are cleared and re-initialized.
+	 *
+	 *	@param backBuffer Sets whether the _backBuffer surface should be initialized.
+	 *	@template PixelType C type which specifies the size of each pixel.
+	 *						Defaults to uint16 (2 BPP for the surfaces)
+	 */
+	template<typename PixelType> void screenInit(bool backBuffer = true);
+
+	/**
+	 *	Loads the given theme into the ThemeEngine.
+	 *	Note that ThemeName is an identifier, not a filename.
+	 *
+	 *	@param ThemeName Theme identifier.
+	 *	@returns True if the theme was succesfully loaded.
+	 */
+	bool loadThemeXML(Common::String themeName);
+	
+	/**
+	 *	Loads the default theme file (the embeded XML file found
+	 *	in ThemeDefaultXML.cpp).
+	 *	Called only when no other themes are available.
+	 */
+	bool loadDefaultXML();
+
+	/**
+	 *	Unloads the currently loaded theme so another one can
+	 *	be loaded.
+	 */
+	void unloadTheme();
+
+	/**
+	 * Not implemented yet.
+	 * TODO: reload themes, reload the renderer, recheck everything
+	 */
+	void screenChange() {
+		error("Screen Changes are not supported yet. Fix this!");
+	}
+	
+	/**
+	 *	Actual Dirty Screen handling function.
+	 *	Handles all the dirty squares in the list, merges and optimizes
+	 *	them when possible and draws them to the screen.
+	 *	Called from updateScreen()
+	 */
+	void renderDirtyScreen();
+
+	/**
+	 *	Frees the vector renderer.
+	 */
+	void freeRenderer() {
+		delete _vectorRenderer;
+		_vectorRenderer = 0;
+	}
+	
+	/**
+	 * Frees the Back buffer surface, only if it's available.
+	 */
+	void freeBackbuffer() {
+		if (_backBuffer != 0) {
+			_backBuffer->free();
+			delete _backBuffer;
+			_backBuffer = 0;
+		}
+	}
+
+	/**
+	 * Frees the main screen drawing surface, only if it's available.
+	 */
+	void freeScreen() {
+		if (_screen != 0) {
+			_screen->free();
+			delete _screen;
+			_screen = 0;
+		}
+	}
+	
+	TextData getTextData(DrawData ddId) {
+		return _widgets[ddId] ? (TextData)_widgets[ddId]->_textDataId : kTextDataNone;
+	}
+	
+	/**
+	 * Draws a cached widget directly on the screen. Currently deprecated.
+	 *
+	 * @param type DrawData type of the widget.
+	 * @param r Position on screen to draw the widget.
+	 */
+	void drawCached(DrawData type, const Common::Rect &r);
+	
+	/**
+	 *	Calculates the background threshold offset of a given DrawData item.
+	 *	After fully loading all DrawSteps of a DrawData item, this function must be
+	 *	called in order to calculate if such draw steps would be drawn outside of
+	 *	the actual widget drawing zone (e.g. shadows). If this is the case, a constant
+	 *	value will be added when restoring the background of the widget.
+	 *
+	 *	@param type DrawData type of the widget.
+	 */
+	void calcBackgroundOffset(DrawData type);
+	
+	/**
+	 *	Generates a DrawQueue item and enqueues it so it's drawn to the screen
+	 *	when the drawing queue is processed.
+	 *
+	 *	If Buffering is enabled, the DrawQueue item will be automatically placed
+	 *	on its corresponding queue.
+	 *	If Buffering is disabled, the DrawQueue item will be processed immediately
+	 *	and drawn to the screen.
+	 *
+	 *	This function is called from all the Widget Drawing methods.
+	 */
+	inline void queueDD(DrawData type,  const Common::Rect &r, uint32 dynamic = 0);
+	inline void queueDDText(TextData type, const Common::Rect &r, const Common::String &text, bool restoreBg,
+		bool elipsis, TextAlign alignH = kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0);
+	inline void queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha);
+	
+	/**
+	 *	DEBUG: Draws a white square around the given position and writes the given next to it.
+	 */
+	inline void debugWidgetPosition(const char *name, const Common::Rect &r);
+
+	
+	/**
+	 *	Default values from GUI::Theme
+	 */
+	int getTabSpacing() const { return 0; }
+	int getTabPadding() const { return 3; }
+
+	OSystem *_system; /** Global system object. */
+	
+	/** Vector Renderer object, does the actual drawing on screen */
+	Graphics::VectorRenderer *_vectorRenderer;
+	
+	/** XML Parser, does the Theme parsing instead of the default parser */
+	GUI::ThemeParser *_parser;
+	
+	/** Theme evaluator (changed from GUI::Eval to add functionality) */
+	GUI::ThemeEval *_themeEval;
+
+	/** Main screen surface. This is blitted straight into the overlay. */
+	Graphics::Surface *_screen;
+	
+	/** Backbuffer surface. Stores previous states of the screen to blit back */
+	Graphics::Surface *_backBuffer;
+	
+	/** Sets whether the current drawing is being buffered (stored for later 
+		processing) or drawn directly to the screen. */
+	bool _buffering; 
+
+	/** Bytes per pixel of the Active Drawing Surface (i.e. the screen) */
+	int _bytesPerPixel;
+	
+	/** Current graphics mode */
+	GraphicsMode _graphicsMode;
+
+	/** Font info. */
+	Common::String _fontName;
+	const Graphics::Font *_font;
+
+	/** Array of all the DrawData elements than can be drawn to the screen.
+		Must be full so the renderer can work. */
+	WidgetDrawData *_widgets[kDrawDataMAX];
+	
+	/** Array of all the text fonts that can be drawn. */
+	TextDrawData *_texts[kTextDataMAX];
+	
+	ImagesMap _bitmaps;
+	
+	/** List of all the dirty screens that must be blitted to the overlay. */
+	Common::List<Common::Rect> _dirtyScreen;
+	
+	/** Queue with all the drawing that must be done to the Back Buffer */
+	Common::List<ThemeItem*> _bufferQueue;
+	
+	/** Queue with all the drawing that must be done to the screen */
+	Common::List<ThemeItem*> _screenQueue;
+
+	bool _initOk; /** Class and renderer properly initialized */
+	bool _themeOk; /** Theme data successfully loaded. */
+	bool _enabled; /** Whether the Theme is currently shown on the overlay */
+
+	Common::String _themeName; /** Name of the currently loaded theme */
+	Common::String _themeFileName;
+	
+	/** Custom Cursor Management */
+	void setUpCursor();
+	
+	bool _useCursor;
+	int _cursorHotspotX, _cursorHotspotY;
+	int _cursorTargetScale;
+#define MAX_CURS_COLORS 255
+	byte *_cursor;
+	bool _needPaletteUpdates;
+	uint _cursorWidth, _cursorHeight;
+	byte _cursorPal[4*MAX_CURS_COLORS];
+};
+
+} // end of namespace GUI.
+
+#endif

Modified: scummvm/branches/gsoc2008-gui/gui/ThemeEval.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeEval.cpp	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeEval.cpp	2008-09-02 17:51:08 UTC (rev 34285)
@@ -31,151 +31,12 @@
 #include "common/xmlparser.h"
 #include "graphics/scaler.h"
 
-#include "gui/ThemeRenderer.h"
+#include "gui/ThemeEngine.h"
 #include "gui/ThemeParser.h"
 #include "gui/ThemeEval.h"
 
 namespace GUI {
-	
-bool ThemeLayoutWidget::getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) {
-	if (name == _name) {
-		x = _x; y = _y;
-		w = _w; h = _h;
-		return true;
-	}
-	
-	return false;
-}
 
-bool ThemeLayout::getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) {
-	for (uint i = 0; i < _children.size(); ++i) {
-		if (_children[i]->getWidgetData(name, x, y, w, h))
-			return true;
-	}
-	
-	return false;
-}
-
-void ThemeLayoutMain::reflowLayout() {
-	assert(_children.size() <= 1);
-	
-	if (_children.size()) {
-		_children[0]->resetLayout();
-		_children[0]->setWidth(_w);
-		_children[0]->setHeight(_h);
-		_children[0]->reflowLayout();
-		
-		if (_w == -1)
-			_w = _children[0]->getWidth();
-			
-		if (_h == -1)
-			_h = _children[0]->getHeight();
-		
-		if (_y == -1)
-			_y = (g_system->getOverlayHeight() >> 1) - (_h >> 1);
-		
-		if (_x == -1)
-			_x = (g_system->getOverlayWidth() >> 1) - (_w >> 1);
-	}
-}
-
-void ThemeLayoutVertical::reflowLayout() {
-	int curX, curY;
-	int resize[8];
-	int rescount = 0;
-	
-	curX = _paddingLeft;
-	curY = _paddingTop;
-	_h = _paddingTop + _paddingBottom;
-	
-	for (uint i = 0; i < _children.size(); ++i) {
-	
-		_children[i]->resetLayout();
-		_children[i]->reflowLayout();
-
-		if (_children[i]->getWidth() == -1)
-			_children[i]->setWidth((_w == -1 ? getParentW() : _w) - _paddingLeft - _paddingRight);
-			
-		if (_children[i]->getHeight() == -1) {
-			resize[rescount++] = i;
-			_children[i]->setHeight(0);
-		}
-			
-		_children[i]->setY(curY);
-		
-		if (_centered && _children[i]->getWidth() < _w && _w != -1) {
-			_children[i]->setX((_w >> 1) - (_children[i]->getWidth() >> 1));
-		}
-		else
-			_children[i]->setX(curX);
-
-		curY += _children[i]->getHeight() + _spacing;	
-		_w = MAX(_w, (int16)(_children[i]->getWidth() + _paddingLeft + _paddingRight));
-		_h += _children[i]->getHeight() + _spacing;
-	}
-	
-	_h -= _spacing;
-	
-	if (rescount) {
-		int newh = (getParentH() - _h - _paddingBottom) / rescount;
-		
-		for (int i = 0; i < rescount; ++i) {
-			_children[resize[i]]->setHeight(newh);
-			_h += newh;
-			for (uint j = resize[i] + 1; j < _children.size(); ++j)
-				_children[j]->setY(newh);
-		}
-	}
-}
-
-void ThemeLayoutHorizontal::reflowLayout() {
-	int curX, curY;
-	int resize[8];
-	int rescount = 0;
-
-	curX = _paddingLeft;
-	curY = _paddingTop;
-	_w = _paddingLeft + _paddingRight;
-		
-	for (uint i = 0; i < _children.size(); ++i) {
-	
-		_children[i]->resetLayout();
-		_children[i]->reflowLayout();
-	
-		if (_children[i]->getHeight() == -1)
-			_children[i]->setHeight((_h == -1 ? getParentH() : _h) - _paddingTop - _paddingBottom);
-
-		if (_children[i]->getWidth() == -1) {
-			resize[rescount++] = i;
-			_children[i]->setWidth(0);
-		}
-			
-		_children[i]->setX(curX);
-		
-		if (_centered && _children[i]->getHeight() < _h && _h != -1)
-			_children[i]->setY((_h >> 1) - (_children[i]->getHeight() >> 1));
-		else
-			_children[i]->setY(curY);
-			
-		curX += (_children[i]->getWidth() + _spacing);
-		_w += _children[i]->getWidth() + _spacing;
-		_h = MAX(_h, (int16)(_children[i]->getHeight() + _paddingTop + _paddingBottom));
-	}
-	
-	_w -= _spacing;
-	
-	if (rescount) {
-		int neww = (getParentW() - _w - _paddingRight) / rescount;
-		
-		for (int i = 0; i < rescount; ++i) {
-			_children[resize[i]]->setWidth(neww);
-			_w += neww;
-			for (uint j = resize[i] + 1; j < _children.size(); ++j)
-				_children[j]->setX(neww);
-		}
-	}
-}
-
 ThemeEval::~ThemeEval() {
 	reset();
 }
@@ -199,7 +60,36 @@
 	_builtin["kBigWidgetSize"] = GUI::kBigWidgetSize;
 }
 
+void ThemeEval::reset() {
+	_vars.clear();
+	_curDialog.clear();
+	_curLayout.clear();
+	
+	for (LayoutsMap::iterator i = _layouts.begin(); i != _layouts.end(); ++i)
+		delete i->_value;
+		
+	_layouts.clear();
+}
 
+bool ThemeEval::getWidgetData(const Common::String &widget, int16 &x, int16 &y, uint16 &w, uint16 &h) {
+	Common::StringTokenizer tokenizer(widget, ".");
+	
+	if (widget.hasPrefix("Dialog."))
+		tokenizer.nextToken();
+
+	Common::String dialogName = "Dialog." + tokenizer.nextToken();
+	Common::String widgetName = tokenizer.nextToken();
+	
+	if (!_layouts.contains(dialogName)) 
+		return false;
+
+	if (widgetName.empty())
+		return _layouts[dialogName]->getDialogData(x, y, w, h);
+		
+	return _layouts[dialogName]->getWidgetData(widgetName, x, y, w, h);
+}
+
+
 void ThemeEval::addWidget(const Common::String &name, int w, int h, const Common::String &type, bool enabled) {	
 	int typeW = -1;
 	int typeH = -1;

Modified: scummvm/branches/gsoc2008-gui/gui/ThemeEval.h
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeEval.h	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeEval.h	2008-09-02 17:51:08 UTC (rev 34285)
@@ -33,267 +33,13 @@
 #include "common/hash-str.h"
 #include "common/xmlparser.h"
 
-#include "gui/ThemeRenderer.h"
+#include "gui/ThemeEngine.h"
 #include "gui/ThemeParser.h"
 #include "gui/ThemeEval.h"
+#include "gui/ThemeLayout.h"
 
 namespace GUI {
 	
-class ThemeLayout {
-
-public:
-	enum LayoutType {
-		kLayoutMain,
-		kLayoutVertical,
-		kLayoutHorizontal,
-		kLayoutWidget
-	};
-	
-	ThemeLayout(ThemeLayout *p, const Common::String &name) : 
-		_parent(p), _name(name), _x(0), _y(0), _w(-1), _h(-1),
-		_paddingLeft(0), _paddingRight(0), _paddingTop(0), _paddingBottom(0), 
-		_centered(false), _defaultW(-1), _defaultH(-1) { }
-		
-	virtual ~ThemeLayout() {
-		for (uint i = 0; i < _children.size(); ++i)
-			delete _children[i];
-	}
-		
-	virtual void reflowLayout() = 0;
-	
-	virtual void resetLayout() {
-		_x = 0;
-		_y = 0;
-		_w = _defaultW;
-		_h = _defaultH;
-	}
-	
-	void addChild(ThemeLayout *child) { _children.push_back(child); }
-	
-	void setPadding(int8 left, int8 right, int8 top, int8 bottom) {
-		_paddingLeft = left;
-		_paddingRight = right;
-		_paddingTop = top;
-		_paddingBottom = bottom;
-	}
-	
-	void setSpacing(int8 spacing) {
-		_spacing = spacing;
-	}
-
-	int16 getParentX() { return _parent ? _parent->_x : 0; }
-	int16 getParentY() { return _parent ? _parent->_y : 0; }
-	
-	int16 getParentW() {
-		ThemeLayout *p = _parent;
-		int width = 0;
-		
-		while (p && p->getLayoutType() != kLayoutMain) {
-			width += p->_paddingRight + p->_paddingLeft;
-			if (p->getLayoutType() == kLayoutHorizontal) {
-				for (uint i = 0; i < p->_children.size(); ++i)
-					width += p->_children[i]->getHeight() + p->_spacing;
-			}
-			p = p->_parent;
-		}
-		
-		return p->getWidth() - width;
-	}
-	
-	int16 getParentH() {
-		ThemeLayout *p = _parent;
-		int height = 0;
-		
-		while (p && p->getLayoutType() != kLayoutMain) {
-			height += p->_paddingBottom + p->_paddingTop;
-			if (p->getLayoutType() == kLayoutVertical) {
-				for (uint i = 0; i < p->_children.size(); ++i)
-					height += p->_children[i]->getHeight() + p->_spacing;
-			}
-			p = p->_parent;
-		}
-		
-		return p->getHeight() - height;
-	}
-	
-	int16 getX() { return _x; }
-	int16 getY() { return _y; }
-	int16 getWidth() { return _w; }
-	int16 getHeight() { return _h; }
-	
-	void setX(int newX) {
-		_x += newX;
-		for (uint i = 0; i < _children.size(); ++i)
-			_children[i]->setX(newX);
-	}
-	
-	void setY(int newY) {
-		_y += newY;
-		for (uint i = 0; i < _children.size(); ++i)
-			_children[i]->setY(newY);
-	}
-	
-	void setWidth(int16 width) { _w = width; }
-	void setHeight(int16 height) { _h = height; }
-	
-	void debugDraw(Graphics::Surface *screen, const Graphics::Font *font) {
-		uint16 color = 0xFFFF;
-		font->drawString(screen, getName(), _x, _y, _w, color, Graphics::kTextAlignRight, 0, true);
-		screen->hLine(_x, _y, _x + _w, color);
-		screen->hLine(_x, _y + _h, _x + _w , color);
-		screen->vLine(_x, _y, _y + _h, color);
-		screen->vLine(_x + _w, _y, _y + _h, color);
-
-		for (uint i = 0; i < _children.size(); ++i)
-			_children[i]->debugDraw(screen, font);
-	}
-	
-	virtual LayoutType getLayoutType() = 0;
-	virtual const char *getName() { return _name.c_str(); }
-	
-	virtual bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h);
-
-	virtual bool getDialogData(int16 &x, int16 &y, uint16 &w, uint16 &h) {
-		assert(getLayoutType() == kLayoutMain);
-		x = _x; y = _y;
-		w = _w; h = _h;
-		return true;
-	}
-	
-	virtual ThemeLayout *buildCopy() = 0;
-	
-	void importLayout(ThemeLayout *layout) {
-		assert(layout->getLayoutType() == kLayoutMain);
-		
-		if (layout->_children.size() == 0)
-			return;
-		
-		layout = layout->_children[0];
-		
-		if (getLayoutType() == layout->getLayoutType()) {
-			for (uint i = 0; i < layout->_children.size(); ++i)
-				_children.push_back(layout->_children[i]->buildCopy()); 
-		} else {
-			_children.push_back(layout->buildCopy()); 
-		}
-	}
-	
-protected:
-	int16 _x, _y, _w, _h;
-	int16 _defaultW, _defaultH;
-	int8 _paddingTop, _paddingBottom, _paddingLeft, _paddingRight;
-	int8 _spacing;
-	Common::Array<ThemeLayout*> _children;
-	ThemeLayout *_parent;
-	bool _centered;
-	Common::String _name;
-};
-
-class ThemeLayoutMain : public ThemeLayout {
-public:
-	ThemeLayoutMain(int16 x, int16 y, int16 w, int16 h) : ThemeLayout(0, "") {
-		_w = _defaultW = w;
-		_h = _defaultH = h;
-		_x = _defaultX = x;
-		_y = _defaultY = y;
-	}
-	void reflowLayout();
-	
-	void resetLayout() {
-		ThemeLayout::resetLayout();
-		_x = _defaultX;
-		_y = _defaultY;
-	}
-	
-	const char *getName() { return "Global Layout"; }
-	LayoutType getLayoutType() { return kLayoutMain; }
-	
-	ThemeLayout *buildCopy() { assert(!"Do not copy Main Layouts!"); return 0; }
-	
-protected:
-	int16 _defaultX;
-	int16 _defaultY;
-};	
-
-class ThemeLayoutVertical : public ThemeLayout {
-public:
-	ThemeLayoutVertical(ThemeLayout *p, int spacing, bool center) :
-	 	ThemeLayout(p, "") {
-		_spacing = spacing;
-		_centered = center;
-	}
-		
-	void reflowLayout();
-	const char *getName() { return "Vertical Layout"; }
-	LayoutType getLayoutType() { return kLayoutVertical; }
-	
-	
-	ThemeLayout *buildCopy() { 
-		ThemeLayoutVertical *n = new ThemeLayoutVertical(*this);
-		
-		for (uint i = 0; i < n->_children.size(); ++ i)
-			n->_children[i] = n->_children[i]->buildCopy();
-		
-		return n;
-	}
-};
-
-class ThemeLayoutHorizontal : public ThemeLayout {
-public:
-	ThemeLayoutHorizontal(ThemeLayout *p, int spacing, bool center) : 
-		ThemeLayout(p, "") {
-		_spacing = spacing;
-		_centered = center;
-	}
-		
-	void reflowLayout();
-	const char *getName() { return "Horizontal Layout"; }
-	LayoutType getLayoutType() { return kLayoutHorizontal; }
-	
-	ThemeLayout *buildCopy() { 
-		ThemeLayoutHorizontal *n = new ThemeLayoutHorizontal(*this);
-		
-		for (uint i = 0; i < n->_children.size(); ++ i)
-			n->_children[i] = n->_children[i]->buildCopy();
-		
-		return n;
-	}
-};
-
-class ThemeLayoutWidget : public ThemeLayout {
-public:
-	ThemeLayoutWidget(ThemeLayout *p, const Common::String &name, int16 w, int16 h) : ThemeLayout(p, name) {
-		_w = _defaultW = w;
-		_h = _defaultH = h;
-	}
-	
-	bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h);
-	void reflowLayout() {}
-	LayoutType getLayoutType() { return kLayoutWidget; }
-	
-	ThemeLayout *buildCopy() { return new ThemeLayoutWidget(*this); }
-};
-
-class ThemeLayoutSpacing : public ThemeLayout {
-public:
-	ThemeLayoutSpacing(ThemeLayout *p, int size) : ThemeLayout(p, "") {
-		if (p->getLayoutType() == kLayoutHorizontal) {
-			_w = _defaultW = size;
-			_h = _defaultH = 1;
-		} else if (p->getLayoutType() == kLayoutVertical) {
-			_w = _defaultW = 1;
-			_h = _defaultH = size;
-		}
-	}
-	
-	bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) { return false; }
-	void reflowLayout() {}
-	LayoutType getLayoutType() { return kLayoutWidget; }
-	const char *getName() { return "SPACE"; }
-	
-	ThemeLayout *buildCopy() { return new ThemeLayoutSpacing(*this); }
-};
-	
 class ThemeEval {
 
 	typedef Common::HashMap<Common::String, int> VariablesMap;
@@ -339,55 +85,20 @@
 	bool addImportedLayout(const Common::String &name);
 	void addSpace(int size);
 	
-	void addPadding(int16 l, int16 r, int16 t, int16 b) {
-		_curLayout.top()->setPadding(l, r, t, b);
-	}
+	void addPadding(int16 l, int16 r, int16 t, int16 b) { _curLayout.top()->setPadding(l, r, t, b); }
 	
 	void closeLayout() { _curLayout.pop(); }
 	void closeDialog() { _curLayout.pop()->reflowLayout(); _curDialog.clear(); }
 	
-	bool getWidgetData(const Common::String &widget, int16 &x, int16 &y, uint16 &w, uint16 &h) {
-		Common::StringTokenizer tokenizer(widget, ".");
-		
-		if (widget.hasPrefix("Dialog."))
-			tokenizer.nextToken();
-	
-		Common::String dialogName = "Dialog." + tokenizer.nextToken();
-		Common::String widgetName = tokenizer.nextToken();
-		
-		if (!_layouts.contains(dialogName)) 
-			return false;
+	bool getWidgetData(const Common::String &widget, int16 &x, int16 &y, uint16 &w, uint16 &h);
 
-		if (widgetName.empty())
-			return _layouts[dialogName]->getDialogData(x, y, w, h);
-			
-		return _layouts[dialogName]->getWidgetData(widgetName, x, y, w, h);
-	}
-	
-	void debugPrint() {
-		printf("Debug variable list:\n");
-		
-		VariablesMap::const_iterator i;
-		for (i = _vars.begin(); i != _vars.end(); ++i) {
-			printf("  '%s' = %d\n", i->_key.c_str(), i->_value);
-		}
-	}
-
+#ifdef LAYOUT_DEBUG_DIALOG
 	void debugDraw(Graphics::Surface *screen, const Graphics::Font *font) {
-		_layouts["Dialog.Launcher"]->debugDraw(screen, font);
-//		_layouts["Dialog.GameOptions_Graphics"]->debugDraw(screen, font);
+		_layouts[LAYOUT_DEBUG_DIALOG]->debugDraw(screen, font);
 	}
+#endif
 	
-	void reset() {
-		_vars.clear();
-		_curDialog.clear();
-		_curLayout.clear();
-		
-		for (LayoutsMap::iterator i = _layouts.begin(); i != _layouts.end(); ++i)
-			delete i->_value;
-			
-		_layouts.clear();
-	}
+	void reset();
 	
 private:
 	VariablesMap _vars;

Added: scummvm/branches/gsoc2008-gui/gui/ThemeLayout.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeLayout.cpp	                        (rev 0)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeLayout.cpp	2008-09-02 17:51:08 UTC (rev 34285)
@@ -0,0 +1,227 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+#include "common/util.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "common/xmlparser.h"
+#include "graphics/scaler.h"
+
+#include "gui/ThemeEval.h"
+#include "gui/ThemeLayout.h"
+
+namespace GUI {
+
+void ThemeLayout::importLayout(ThemeLayout *layout) {
+	assert(layout->getLayoutType() == kLayoutMain);
+	
+	if (layout->_children.size() == 0)
+		return;
+	
+	layout = layout->_children[0];
+	
+	if (getLayoutType() == layout->getLayoutType()) {
+		for (uint i = 0; i < layout->_children.size(); ++i)
+			_children.push_back(layout->_children[i]->buildCopy()); 
+	} else {
+		_children.push_back(layout->buildCopy()); 
+	}
+}
+
+bool ThemeLayout::getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) {
+	for (uint i = 0; i < _children.size(); ++i) {
+		if (_children[i]->getWidgetData(name, x, y, w, h))
+			return true;
+	}
+	
+	return false;
+}
+
+int16 ThemeLayout::getParentW() {
+	ThemeLayout *p = _parent;
+	int width = 0;
+	
+	while (p && p->getLayoutType() != kLayoutMain) {
+		width += p->_paddingRight + p->_paddingLeft;
+		if (p->getLayoutType() == kLayoutHorizontal) {
+			for (uint i = 0; i < p->_children.size(); ++i)
+				width += p->_children[i]->getHeight() + p->_spacing;
+		}
+		p = p->_parent;
+	}
+	
+	return p->getWidth() - width;
+}
+
+int16 ThemeLayout::getParentH() {
+	ThemeLayout *p = _parent;
+	int height = 0;
+	
+	while (p && p->getLayoutType() != kLayoutMain) {
+		height += p->_paddingBottom + p->_paddingTop;
+		if (p->getLayoutType() == kLayoutVertical) {
+			for (uint i = 0; i < p->_children.size(); ++i)
+				height += p->_children[i]->getHeight() + p->_spacing;
+		}
+		p = p->_parent;
+	}
+	
+	return p->getHeight() - height;
+}
+
+
+bool ThemeLayoutWidget::getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) {
+	if (name == _name) {
+		x = _x; y = _y;
+		w = _w; h = _h;
+		return true;
+	}
+	
+	return false;
+}
+
+void ThemeLayoutMain::reflowLayout() {
+	assert(_children.size() <= 1);
+	
+	if (_children.size()) {
+		_children[0]->resetLayout();
+		_children[0]->setWidth(_w);
+		_children[0]->setHeight(_h);
+		_children[0]->reflowLayout();
+		
+		if (_w == -1)
+			_w = _children[0]->getWidth();
+			
+		if (_h == -1)
+			_h = _children[0]->getHeight();
+		
+		if (_y == -1)
+			_y = (g_system->getOverlayHeight() >> 1) - (_h >> 1);
+		
+		if (_x == -1)
+			_x = (g_system->getOverlayWidth() >> 1) - (_w >> 1);
+	}
+}
+
+void ThemeLayoutVertical::reflowLayout() {
+	int curX, curY;
+	int resize[8];
+	int rescount = 0;
+	
+	curX = _paddingLeft;
+	curY = _paddingTop;
+	_h = _paddingTop + _paddingBottom;
+	
+	for (uint i = 0; i < _children.size(); ++i) {
+	
+		_children[i]->resetLayout();
+		_children[i]->reflowLayout();
+
+		if (_children[i]->getWidth() == -1)
+			_children[i]->setWidth((_w == -1 ? getParentW() : _w) - _paddingLeft - _paddingRight);
+			
+		if (_children[i]->getHeight() == -1) {
+			resize[rescount++] = i;
+			_children[i]->setHeight(0);
+		}
+			
+		_children[i]->setY(curY);
+		
+		if (_centered && _children[i]->getWidth() < _w && _w != -1) {
+			_children[i]->setX((_w >> 1) - (_children[i]->getWidth() >> 1));
+		}
+		else
+			_children[i]->setX(curX);
+
+		curY += _children[i]->getHeight() + _spacing;	
+		_w = MAX(_w, (int16)(_children[i]->getWidth() + _paddingLeft + _paddingRight));
+		_h += _children[i]->getHeight() + _spacing;
+	}
+	
+	_h -= _spacing;
+	
+	if (rescount) {
+		int newh = (getParentH() - _h - _paddingBottom) / rescount;
+		
+		for (int i = 0; i < rescount; ++i) {
+			_children[resize[i]]->setHeight(newh);
+			_h += newh;
+			for (uint j = resize[i] + 1; j < _children.size(); ++j)
+				_children[j]->setY(newh);
+		}
+	}
+}
+
+void ThemeLayoutHorizontal::reflowLayout() {
+	int curX, curY;
+	int resize[8];
+	int rescount = 0;
+
+	curX = _paddingLeft;
+	curY = _paddingTop;
+	_w = _paddingLeft + _paddingRight;
+		
+	for (uint i = 0; i < _children.size(); ++i) {
+	
+		_children[i]->resetLayout();
+		_children[i]->reflowLayout();
+	
+		if (_children[i]->getHeight() == -1)
+			_children[i]->setHeight((_h == -1 ? getParentH() : _h) - _paddingTop - _paddingBottom);
+
+		if (_children[i]->getWidth() == -1) {
+			resize[rescount++] = i;
+			_children[i]->setWidth(0);
+		}
+			
+		_children[i]->setX(curX);
+		
+		if (_centered && _children[i]->getHeight() < _h && _h != -1)
+			_children[i]->setY((_h >> 1) - (_children[i]->getHeight() >> 1));
+		else
+			_children[i]->setY(curY);
+			
+		curX += (_children[i]->getWidth() + _spacing);
+		_w += _children[i]->getWidth() + _spacing;
+		_h = MAX(_h, (int16)(_children[i]->getHeight() + _paddingTop + _paddingBottom));
+	}
+	
+	_w -= _spacing;
+	
+	if (rescount) {
+		int neww = (getParentW() - _w - _paddingRight) / rescount;
+		
+		for (int i = 0; i < rescount; ++i) {
+			_children[resize[i]]->setWidth(neww);
+			_w += neww;
+			for (uint j = resize[i] + 1; j < _children.size(); ++j)
+				_children[j]->setX(neww);
+		}
+	}
+}
+
+
+}
\ No newline at end of file


Property changes on: scummvm/branches/gsoc2008-gui/gui/ThemeLayout.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/branches/gsoc2008-gui/gui/ThemeLayout.h
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeLayout.h	                        (rev 0)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeLayout.h	2008-09-02 17:51:08 UTC (rev 34285)
@@ -0,0 +1,239 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef THEME_LAYOUT_H
+#define THEME_LAYOUT_H
+
+namespace GUI {
+
+class ThemeLayout {
+
+public:
+	enum LayoutType {
+		kLayoutMain,
+		kLayoutVertical,
+		kLayoutHorizontal,
+		kLayoutWidget
+	};
+	
+	ThemeLayout(ThemeLayout *p, const Common::String &name) : 
+		_parent(p), _name(name), _x(0), _y(0), _w(-1), _h(-1),
+		_paddingLeft(0), _paddingRight(0), _paddingTop(0), _paddingBottom(0), 
+		_centered(false), _defaultW(-1), _defaultH(-1) { }
+		
+	virtual ~ThemeLayout() {
+		for (uint i = 0; i < _children.size(); ++i)
+			delete _children[i];
+	}
+		
+	virtual void reflowLayout() = 0;
+	
+	virtual void resetLayout() { _x = 0; _y = 0; _w = _defaultW; _h = _defaultH; }
+	
+	void addChild(ThemeLayout *child) { _children.push_back(child); }
+	
+	void setPadding(int8 left, int8 right, int8 top, int8 bottom) {
+		_paddingLeft = left;
+		_paddingRight = right;
+		_paddingTop = top;
+		_paddingBottom = bottom;
+	}
+	
+	void setSpacing(int8 spacing) {
+		_spacing = spacing;
+	}
+
+	int16 getParentX() { return _parent ? _parent->_x : 0; }
+	int16 getParentY() { return _parent ? _parent->_y : 0; }
+	int16 getParentW();
+	int16 getParentH();
+	int16 getX() { return _x; }
+	int16 getY() { return _y; }
+	int16 getWidth() { return _w; }
+	int16 getHeight() { return _h; }
+	
+	void setX(int newX) {
+		_x += newX;
+		for (uint i = 0; i < _children.size(); ++i)
+			_children[i]->setX(newX);
+	}
+	
+	void setY(int newY) {
+		_y += newY;
+		for (uint i = 0; i < _children.size(); ++i)
+			_children[i]->setY(newY);
+	}
+	
+	void setWidth(int16 width) { _w = width; }
+	void setHeight(int16 height) { _h = height; }
+	
+#ifdef LAYOUT_DEBUG_DIALOG
+	void debugDraw(Graphics::Surface *screen, const Graphics::Font *font) {
+		uint16 color = 0xFFFF;
+		font->drawString(screen, getName(), _x, _y, _w, color, Graphics::kTextAlignRight, 0, true);
+		screen->hLine(_x, _y, _x + _w, color);
+		screen->hLine(_x, _y + _h, _x + _w , color);
+		screen->vLine(_x, _y, _y + _h, color);
+		screen->vLine(_x + _w, _y, _y + _h, color);
+
+		for (uint i = 0; i < _children.size(); ++i)
+			_children[i]->debugDraw(screen, font);
+	}
+#endif
+	
+	virtual LayoutType getLayoutType() = 0;
+	virtual const char *getName() { return _name.c_str(); }
+	
+	virtual bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h);
+
+	virtual bool getDialogData(int16 &x, int16 &y, uint16 &w, uint16 &h) {
+		assert(getLayoutType() == kLayoutMain);
+		x = _x; y = _y;
+		w = _w; h = _h;
+		return true;
+	}
+	
+	virtual ThemeLayout *buildCopy() = 0;
+	void importLayout(ThemeLayout *layout);
+	
+protected:
+	int16 _x, _y, _w, _h;
+	int16 _defaultW, _defaultH;
+	int8 _paddingTop, _paddingBottom, _paddingLeft, _paddingRight;
+	int8 _spacing;
+	Common::Array<ThemeLayout*> _children;
+	ThemeLayout *_parent;
+	bool _centered;
+	Common::String _name;
+};
+
+class ThemeLayoutMain : public ThemeLayout {
+public:
+	ThemeLayoutMain(int16 x, int16 y, int16 w, int16 h) : ThemeLayout(0, "") {
+		_w = _defaultW = w;
+		_h = _defaultH = h;
+		_x = _defaultX = x;
+		_y = _defaultY = y;
+	}
+	void reflowLayout();
+	
+	void resetLayout() {
+		ThemeLayout::resetLayout();
+		_x = _defaultX;
+		_y = _defaultY;
+	}
+	
+	const char *getName() { return "Global Layout"; }
+	LayoutType getLayoutType() { return kLayoutMain; }
+	
+	ThemeLayout *buildCopy() { assert(!"Do not copy Main Layouts!"); return 0; }
+	
+protected:
+	int16 _defaultX;
+	int16 _defaultY;
+};	
+
+class ThemeLayoutVertical : public ThemeLayout {
+public:
+	ThemeLayoutVertical(ThemeLayout *p, int spacing, bool center) :
+	 	ThemeLayout(p, "") {
+		_spacing = spacing;
+		_centered = center;
+	}
+		
+	void reflowLayout();
+	const char *getName() { return "Vertical Layout"; }
+	LayoutType getLayoutType() { return kLayoutVertical; }
+	
+	
+	ThemeLayout *buildCopy() { 
+		ThemeLayoutVertical *n = new ThemeLayoutVertical(*this);
+		
+		for (uint i = 0; i < n->_children.size(); ++ i)
+			n->_children[i] = n->_children[i]->buildCopy();
+		
+		return n;
+	}
+};
+
+class ThemeLayoutHorizontal : public ThemeLayout {
+public:
+	ThemeLayoutHorizontal(ThemeLayout *p, int spacing, bool center) : 
+		ThemeLayout(p, "") {
+		_spacing = spacing;
+		_centered = center;
+	}
+		
+	void reflowLayout();
+	const char *getName() { return "Horizontal Layout"; }
+	LayoutType getLayoutType() { return kLayoutHorizontal; }
+	
+	ThemeLayout *buildCopy() { 
+		ThemeLayoutHorizontal *n = new ThemeLayoutHorizontal(*this);
+		
+		for (uint i = 0; i < n->_children.size(); ++ i)
+			n->_children[i] = n->_children[i]->buildCopy();
+		
+		return n;
+	}
+};
+
+class ThemeLayoutWidget : public ThemeLayout {
+public:
+	ThemeLayoutWidget(ThemeLayout *p, const Common::String &name, int16 w, int16 h) : ThemeLayout(p, name) {
+		_w = _defaultW = w;
+		_h = _defaultH = h;
+	}
+	
+	bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h);
+	void reflowLayout() {}
+	LayoutType getLayoutType() { return kLayoutWidget; }
+	
+	ThemeLayout *buildCopy() { return new ThemeLayoutWidget(*this); }
+};
+
+class ThemeLayoutSpacing : public ThemeLayout {
+public:
+	ThemeLayoutSpacing(ThemeLayout *p, int size) : ThemeLayout(p, "") {
+		if (p->getLayoutType() == kLayoutHorizontal) {
+			_w = _defaultW = size;
+			_h = _defaultH = 1;
+		} else if (p->getLayoutType() == kLayoutVertical) {
+			_w = _defaultW = 1;
+			_h = _defaultH = size;
+		}
+	}
+	
+	bool getWidgetData(const Common::String &name, int16 &x, int16 &y, uint16 &w, uint16 &h) { return false; }
+	void reflowLayout() {}
+	LayoutType getLayoutType() { return kLayoutWidget; }
+	const char *getName() { return "SPACE"; }
+	
+	ThemeLayout *buildCopy() { return new ThemeLayoutSpacing(*this); }
+};
+
+}
+
+#endif
\ No newline at end of file


Property changes on: scummvm/branches/gsoc2008-gui/gui/ThemeLayout.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeParser.cpp	2008-09-02 17:51:08 UTC (rev 34285)
@@ -30,7 +30,7 @@
 #include "common/hash-str.h"
 #include "common/xmlparser.h"
 
-#include "gui/ThemeRenderer.h"
+#include "gui/ThemeEngine.h"
 #include "gui/ThemeParser.h"
 #include "gui/newgui.h"
 #include "graphics/VectorRenderer.h"
@@ -40,7 +40,7 @@
 using namespace Graphics;
 using namespace Common;
 
-ThemeParser::ThemeParser(ThemeRenderer *parent) : XMLParser() {	
+ThemeParser::ThemeParser(ThemeEngine *parent) : XMLParser() {	
 	
 	_drawFunctions["circle"]  = &Graphics::VectorRenderer::drawCallback_CIRCLE;
 	_drawFunctions["square"]  = &Graphics::VectorRenderer::drawCallback_SQUARE;

Modified: scummvm/branches/gsoc2008-gui/gui/ThemeParser.h
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeParser.h	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeParser.h	2008-09-02 17:51:08 UTC (rev 34285)
@@ -36,19 +36,19 @@
 #include "common/xmlparser.h"
 
 #include "graphics/VectorRenderer.h"
-#include "gui/ThemeRenderer.h"
+#include "gui/ThemeEngine.h"
 
 namespace GUI {
 
 using namespace Graphics;
 using namespace Common;
-class ThemeRenderer;	
+class ThemeEngine;	
 
 class ThemeParser : public XMLParser {
 	typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, const DrawStep &);
 
 public:
-	ThemeParser(GUI::ThemeRenderer *parent);
+	ThemeParser(GUI::ThemeEngine *parent);
 	
 	virtual ~ThemeParser() {
 		delete _defaultStepGlobal;
@@ -69,7 +69,7 @@
 	}
 
 protected:
-	ThemeRenderer *_theme;
+	ThemeEngine *_theme;
 	
 	CUSTOM_XML_PARSER(ThemeParser) {
 		XML_KEY(render_info)

Deleted: scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.cpp	2008-09-02 16:35:16 UTC (rev 34284)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.cpp	2008-09-02 17:51:08 UTC (rev 34285)
@@ -1,1045 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/util.h"
-#include "graphics/surface.h"
-#include "graphics/colormasks.h"
-#include "common/system.h"
-#include "common/events.h"
-#include "common/config-manager.h"
-#include "common/fs.h"
-#include "graphics/imageman.h"
-#include "graphics/cursorman.h"
-#include "gui/launcher.h"
-
-#include "gui/ThemeRenderer.h"
-#include "gui/ThemeEval.h"
-#include "graphics/VectorRenderer.h"
-
-#define GUI_ENABLE_BUILTIN_THEME
-
-namespace GUI {
-
-using namespace Graphics;
-
-const char *ThemeRenderer::rendererModeLabels[] = {
-	"Disabled GFX",
-	"Stardard Renderer (16bpp)",
-	"Antialiased Renderer (16bpp)"
-};
-
-const ThemeRenderer::DrawDataInfo ThemeRenderer::kDrawDataDefaults[] = {
-	{kDDMainDialogBackground, "mainmenu_bg", true, kDDNone},
-	{kDDSpecialColorBackground, "special_bg", true, kDDNone},
-	{kDDPlainColorBackground, "plain_bg", true, kDDNone},
-	{kDDDefaultBackground, "default_bg", true, kDDNone},
-	{kDDTextSelectionBackground, "text_selection", false, kDDNone},
-
-	{kDDWidgetBackgroundDefault, "widget_default", true, kDDNone},
-	{kDDWidgetBackgroundSmall, "widget_small", true, kDDNone},
-	{kDDWidgetBackgroundEditText, "widget_textedit", true, kDDNone},
-	{kDDWidgetBackgroundSlider, "widget_slider", true, kDDNone},
-
-	{kDDButtonIdle, "button_idle", true, kDDWidgetBackgroundSlider},
-	{kDDButtonHover, "button_hover", false, kDDButtonIdle},
-	{kDDButtonDisabled, "button_disabled", true, kDDNone},
-
-	{kDDSliderFull, "slider_full", false, kDDNone},
-	{kDDSliderHover, "slider_hover", false, kDDNone},
-	{kDDSliderDisabled, "slider_disabled", true, kDDNone},
-
-	{kDDCheckboxDefault, "checkbox_default", true, kDDNone},
-	{kDDCheckboxDisabled, "checkbox_disabled", true, kDDNone},
-	{kDDCheckboxSelected, "checkbox_selected", false, kDDCheckboxDefault},
-
-	{kDDTabActive, "tab_active", false, kDDTabInactive},
-	{kDDTabInactive, "tab_inactive", true, kDDNone},
-	{kDDTabBackground, "tab_background", true, kDDNone},
-
-	{kDDScrollbarBase, "scrollbar_base", true, kDDNone},
-	
-	{kDDScrollbarButtonIdle, "scrollbar_button_idle", true, kDDNone},
-	{kDDScrollbarButtonHover, "scrollbar_button_hover", false, kDDScrollbarButtonIdle},
-		
-	{kDDScrollbarHandleIdle, "scrollbar_handle_idle", false, kDDNone},
-	{kDDScrollbarHandleHover, "scrollbar_handle_hover", false, kDDScrollbarBase},
-
-	{kDDPopUpIdle, "popup_idle", true, kDDNone},
-	{kDDPopUpHover, "popup_hover", false, kDDPopUpIdle},
-
-	{kDDCaret, "caret", false, kDDNone},
-	{kDDSeparator, "separator", true, kDDNone},
-};
-
-const ThemeRenderer::TextDataInfo ThemeRenderer::kTextDataDefaults[] = {
-	{kTextDataDefault, "text_default"},
-	{kTextDataHover, "text_hover"},
-	{kTextDataDisabled, "text_disabled"},
-	{kTextDataInverted, "text_inverted"},
-	{kTextDataButton, "text_button"},
-	{kTextDataButtonHover, "text_button_hover"},
-	{kTextDataNormalFont, "text_normal"}
-};
-
-
-ThemeRenderer::ThemeRenderer(Common::String fileName, GraphicsMode mode) : 
-	_vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled), _font(0),
-	_screen(0), _backBuffer(0), _bytesPerPixel(0), _initOk(false), 
-	_themeOk(false), _enabled(false), _buffering(false), _cursor(0) {
-	_system = g_system;
-	_parser = new ThemeParser(this);
-	_themeEval = new GUI::ThemeEval();
-	
-	_useCursor = false;
-
-	for (int i = 0; i < kDrawDataMAX; ++i) {
-		_widgets[i] = 0;
-	}
-	
-	for (int i = 0; i < kTextDataMAX; ++i) {
-		_texts[i] = 0;
-	}
-
-	_graphicsMode = mode;
-	_themeFileName = fileName;
-	_initOk = false;
-}
-
-ThemeRenderer::~ThemeRenderer() {
-	freeRenderer();
-	freeScreen();
-	freeBackbuffer();
-	unloadTheme();
-	delete _parser;
-	delete _themeEval;
-	delete[] _cursor;
-	
-	for (ImagesMap::iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i)
-		ImageMan.unregisterSurface(i->_key);
-}
-
-bool ThemeRenderer::init() {
-	// reset everything and reload the graphics
-	deinit();
-	setGraphicsMode(_graphicsMode);
-
-	if (_screen->pixels && _backBuffer->pixels) {
-		_initOk = true;
-		clearAll();
-		resetDrawArea();
-	}
-	
-	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 ThemeRenderer::deinit() {
-	if (_initOk) {
-		_system->hideOverlay();
-		freeRenderer();
-		freeScreen();
-		freeBackbuffer();
-		_initOk = false;
-	}
-}
-
-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);
-
-	if (_themeFileName.hasSuffix(".zip"))
-		ImageMan.remArchive(_themeFileName);
-		
-	Common::File::resetDefaultDirectories();
-	
-	_themeEval->reset();
-	_themeOk = false;
-}
-
-void ThemeRenderer::clearAll() {
-	if (!_initOk)
-		return;
-
-	_system->clearOverlay();
-	_system->grabOverlay((OverlayColor*)_screen->pixels, _screen->w);
-}
-
-void ThemeRenderer::refresh() {
-	init();
-	if (_enabled) {
-		_system->showOverlay();
-		
-		if (_useCursor) {
-			CursorMan.replaceCursorPalette(_cursorPal, 0, MAX_CURS_COLORS);
-			CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, 255, _cursorTargetScale);
-		}
-	}
-}
-
-void ThemeRenderer::enable() {
-	init();
-	resetDrawArea();
-	
-	if (_useCursor)
-		setUpCursor();
-	
-	_system->showOverlay();
-	clearAll();
-	_enabled = true;
-}
-
-void ThemeRenderer::disable() {
-	_system->hideOverlay();
-	
-	if (_useCursor) {
-		CursorMan.popCursorPalette();
-		CursorMan.popCursor();
-	}
-	
-	_enabled = false;
-}
-
-template<typename PixelType> 
-void ThemeRenderer::screenInit(bool backBuffer) {
-	uint32 width = _system->getOverlayWidth();
-	uint32 height = _system->getOverlayHeight();
-	
-	if (backBuffer) {
-		freeBackbuffer();
-		_backBuffer = new Surface;
-		_backBuffer->create(width, height, sizeof(PixelType));
-	}
-	
-	freeScreen();
-	_screen = new Surface;
-	_screen->create(width, height, sizeof(PixelType));
-	_system->clearOverlay();
-}
-
-void ThemeRenderer::setGraphicsMode(GraphicsMode mode) {
-	switch (mode) {
-	case kGfxStandard16bit:
-	case kGfxAntialias16bit:
-		_bytesPerPixel = sizeof(uint16);
-		screenInit<uint16>(kEnableBackCaching);
-		break;
-
-	default:
-		error("Invalid graphics mode");
-	}
-
-	freeRenderer();
-	_vectorRenderer = createRenderer(mode);
-	_vectorRenderer->setSurface(_screen);
-}
-
-void ThemeRenderer::addDrawStep(const Common::String &drawDataId, Graphics::DrawStep step) {
-	DrawData id = getDrawDataId(drawDataId);
-	
-	assert(_widgets[id] != 0);
-	_widgets[id]->_steps.push_back(step);
-}
-
-bool ThemeRenderer::addTextData(const Common::String &drawDataId, const Common::String &textDataId, TextAlign alignH, TextAlignVertical alignV) {
-	DrawData id = getDrawDataId(drawDataId);
-	TextData textId = getTextDataId(textDataId);
-
-	if (id == -1 || textId == -1 || !_widgets[id])
-		return false;
-	
-	_widgets[id]->_textDataId = textId;
-	_widgets[id]->_textAlignH = alignH;
-	_widgets[id]->_textAlignV = alignV;	
-
-	return true;
-}
-
-bool ThemeRenderer::addFont(const Common::String &fontId, const Common::String &file, int r, int g, int b) {
-	TextData textId = getTextDataId(fontId);
-	
-	if (textId == -1)
-		return false;
-		
-	if (_texts[textId] != 0)
-		delete _texts[textId];
-		
-	_texts[textId] = new TextDrawData;
-	
-	if (file == "default") {
-		_texts[textId]->_fontPtr = _font;
-	} else {
-		_texts[textId]->_fontPtr = FontMan.getFontByName(file);
-
-		if (!_texts[textId]->_fontPtr) {
-			_texts[textId]->_fontPtr = loadFont(file.c_str());
-			
-			if (!_texts[textId]->_fontPtr)
-				error("Couldn't load %s font '%s'", fontId.c_str(), file.c_str());
-
-			FontMan.assignFontToName(file, _texts[textId]->_fontPtr);
-		}
-	}
-	
-	_texts[textId]->_color.r = r;
-	_texts[textId]->_color.g = g;
-	_texts[textId]->_color.b = b;
-	return true;
-	
-}
-
-bool ThemeRenderer::addBitmap(const Common::String &filename) {
-	if (_bitmaps.contains(filename)) {
-		ImageMan.unregisterSurface(filename);
-	}
-	
-	ImageMan.registerSurface(filename, 0);
-	_bitmaps[filename] = ImageMan.getSurface(filename);
-	
-	return _bitmaps[filename] != 0;
-}
-
-bool ThemeRenderer::addDrawData(const Common::String &data, bool cached) {
-	DrawData data_id = getDrawDataId(data);
-
-	if (data_id == -1)
-		return false;
-		
-	if (_widgets[data_id] != 0)
-		delete _widgets[data_id];
-
-	_widgets[data_id] = new WidgetDrawData;
-	_widgets[data_id]->_cached = cached;
-	_widgets[data_id]->_buffer = kDrawDataDefaults[data_id].buffer;
-	_widgets[data_id]->_surfaceCache = 0;
-	_widgets[data_id]->_textDataId = -1;
-
-	return true;
-}
-
-bool ThemeRenderer::loadTheme(Common::String fileName) {
-	unloadTheme();
-
-	if (fileName != "builtin") {
-		if (fileName.hasSuffix(".zip"))
-			ImageMan.addArchive(fileName);
-		else 
-			Common::File::addDefaultDirectory(fileName);
-	}
-
-	if (fileName == "builtin") {
-		if (!loadDefaultXML())
-			error("Could not load default embeded theme");
-	}
-	else if (!loadThemeXML(fileName)) {
-		warning("Could not parse custom theme '%s'. Falling back to default theme", fileName.c_str());
-		
-		if (!loadDefaultXML()) // if we can't load the embeded theme, this is a complete failure
-			error("Could not load default embeded theme");
-	}
-
-	for (int i = 0; i < kDrawDataMAX; ++i) {
-		if (_widgets[i] == 0) {
-			warning("Missing data asset: '%s'", kDrawDataDefaults[i].name);
-		} else {
-			calcBackgroundOffset((DrawData)i);
-
-			// TODO: draw the cached widget to the cache surface
-			if (_widgets[i]->_cached) {}
-		}
-	}
-	
-	_themeOk = true;
-	return true;
-}
-
-bool ThemeRenderer::loadDefaultXML() {
-	
-	// The default XML theme is included on runtime from a pregenerated
-	// 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.
-
-#ifdef GUI_ENABLE_BUILTIN_THEME
-	const char *defaultXML =
-#include "themes/default.inc"
-	;
-	
-	if (!parser()->loadBuffer((const byte*)defaultXML, strlen(defaultXML), false))
-		return false;
-		
-	_themeName = "ScummVM Classic Theme (Builtin Version)";
-	_themeFileName = "builtin";
-
-	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) {
-	assert(_parser);
-	_themeName.clear();
-	
-	char fileNameBuffer[32];
-	char stxHeader[128];
-	int parseCount = 0;
-	
-#ifdef USE_ZLIB
-	unzFile zipFile = unzOpen((themeName).c_str());
-	
-	if (zipFile && unzGoToFirstFile(zipFile) == UNZ_OK) {
-		while (true) {
-			unz_file_info fileInfo;
-			unzOpenCurrentFile(zipFile);
-			unzGetCurrentFileInfo(zipFile, &fileInfo, fileNameBuffer, 32, NULL, 0, NULL, 0);
-		
-			if (matchString(fileNameBuffer, "*.stx") || !strcmp(fileNameBuffer, "THEMERC")) {
-				uint8 *buffer = new uint8[fileInfo.uncompressed_size+1];
-				assert(buffer);
-				memset(buffer, 0, (fileInfo.uncompressed_size+1)*sizeof(uint8));
-				unzReadCurrentFile(zipFile, buffer, fileInfo.uncompressed_size);
-			
-				Common::MemoryReadStream *stream = new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size+1, true);
-				
-				if (!strcmp(fileNameBuffer, "THEMERC")) {
-					stream->readLine(stxHeader, 128);
-
-					if (!themeConfigParseHeader(stxHeader, _themeName)) {
-						warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str());
-						return false;
-					}
-						
-					delete stream;
-					
-				} else {
-					parseCount++;
-					
-					if (parser()->loadStream(stream) == false || parser()->parse() == false) {
-						warning("Failed to load stream for zipped file '%s'", fileNameBuffer);
-						unzClose(zipFile);
-						return false;
-					}
-				}
-			} 
-		
-			unzCloseCurrentFile(zipFile);
-		
-			if (unzGoToNextFile(zipFile) != UNZ_OK)
-				break;
-		}
-	} else {
-#endif
-        
-        FilesystemNode node(themeName);
-		if (node.exists() && node.isReadable() && node.isDirectory()) {
-			FSList fslist;
-			if (!node.getChildren(fslist, FilesystemNode::kListFilesOnly))
-				return false;
-			
-			for (FSList::const_iterator i = fslist.begin(); i != fslist.end(); ++i) {
-				if (i->getName().hasSuffix(".stx")) {
-					parseCount++;
-					
-					if (parser()->loadFile(*i) == false || parser()->parse() == false) {
-						warning("Failed to parse STX file '%s'", i->getName().c_str());
-						return false;
-					}
-				} else if (i->getName() == "THEMERC") {
-					Common::File f;
-					f.open(*i);
-					f.readLine(stxHeader, 128);
-
-					if (!themeConfigParseHeader(stxHeader, _themeName)) {
-						warning("Corrupted 'THEMERC' file in theme '%s'", _themeFileName.c_str());
-						return false;
-					}
-				}
-			}
-		}
-#ifdef USE_ZLIB
-	}
-	
-	unzClose(zipFile);
-	
-#endif
-
-
-	return (parseCount > 0 && _themeName.empty() == false);
-}
-

@@ Diff output truncated at 100000 characters. @@

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