[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