From 85c36885f5bbf2d47276c7702f1b8ccbf22ecc34 Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Mon, 4 Aug 2008 16:59:55 +0000 Subject: Theme layout parsing. Work in progress. svn-id: r33613 --- common/xmlparser.cpp | 27 ++-- common/xmlparser.h | 12 ++ dists/msvc9/scummvm.vcproj | 4 - graphics/VectorRenderer.cpp | 22 ++-- graphics/VectorRenderer.h | 23 ++-- gui/ThemeEval.h | 291 ++++++++++++++++++++++++++++++++++++++++++++ gui/ThemeParser.cpp | 73 +++++++++-- gui/ThemeParser.h | 37 ++++-- gui/ThemeRenderer.cpp | 7 +- gui/newgui.cpp | 21 +++- gui/themes/default.inc | 2 +- gui/themes/modern.stx | 115 ++++++++++------- 12 files changed, 524 insertions(+), 110 deletions(-) diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp index 5ea10f2278..526e6e6fb1 100644 --- a/common/xmlparser.cpp +++ b/common/xmlparser.cpp @@ -98,22 +98,23 @@ bool XMLParser::parseActiveKey(bool closed) { ParserNode *key = _activeKey.top(); XMLKeyLayout *layout = (_activeKey.size() == 1) ? _XMLkeys : getParentNode(key)->layout; - if (layout->children.contains(key->name) == false) - return parserError("Unexpected key in the active scope: '%s'.", key->name.c_str()); - - key->layout = layout->children[key->name]; + if (layout->children.contains(key->name)) { + key->layout = layout->children[key->name]; - Common::StringMap localMap = key->values; + Common::StringMap localMap = key->values; - for (Common::List::const_iterator i = key->layout->properties.begin(); i != key->layout->properties.end(); ++i) { - if (localMap.contains(i->name)) - localMap.erase(i->name); - else if (i->required) - return parserError("Missing required property '%s' inside key '%s'", i->name.c_str(), key->name.c_str()); - } + for (Common::List::const_iterator i = key->layout->properties.begin(); i != key->layout->properties.end(); ++i) { + if (localMap.contains(i->name)) + localMap.erase(i->name); + else if (i->required) + return parserError("Missing required property '%s' inside key '%s'", i->name.c_str(), key->name.c_str()); + } - if (key->layout->anyProps == false && localMap.empty() == false) - return parserError("Unhandled property inside key '%s': '%s'", key->name.c_str(), localMap.begin()->_key.c_str()); + if (key->layout->anyProps == false && localMap.empty() == false) + return parserError("Unhandled property inside key '%s': '%s'", key->name.c_str(), localMap.begin()->_key.c_str()); + } else if (layout->anyKeys == false) { + return parserError("Unexpected key in the active scope: '%s'.", key->name.c_str()); + } // check if any of the parents must be ignored. // if a parent is ignored, all children are too. diff --git a/common/xmlparser.h b/common/xmlparser.h index 031ee2be14..0510ec0ab6 100644 --- a/common/xmlparser.h +++ b/common/xmlparser.h @@ -183,10 +183,16 @@ namespace Common { #define XML_KEY(keyName) {\ lay = new XMLKeyLayout; \ lay->anyProps = false; \ + lay->anyKeys = false; \ lay->custom = new kLocalParserName::CustomParserCallback; \ ((kLocalParserName::CustomParserCallback*)(lay->custom))->callback = (&kLocalParserName::parserCallback_##keyName); \ layout.top()->children[#keyName] = lay; \ layout.push(lay); + +#define XML_KEY_RECURSIVE(keyName) {\ + layout.top()->children[#keyName] = layout.top();\ + layout.push(layout.top());\ + } #define KEY_END() layout.pop(); } @@ -197,6 +203,9 @@ namespace Common { #define XML_PROP_ANY() {\ layout.top()->anyProps = true; } + +#define XML_KEY_ANY() {\ + layout.top()->anyKeys = true; } #define CUSTOM_XML_PARSER(parserName) \ protected: \ @@ -209,6 +218,8 @@ namespace Common { XMLKeyLayout *lay = 0; \ XMLKeyLayout::XMLKeyProperty prop; \ _XMLkeys = new XMLKeyLayout; \ + _XMLkeys->anyProps = false; \ + _XMLkeys->anyKeys = false; \ layout.push(_XMLkeys); #define PARSER_END() layout.clear(); } @@ -300,6 +311,7 @@ public: Common::List properties; bool anyProps; + bool anyKeys; ChildMap children; ~XMLKeyLayout() { diff --git a/dists/msvc9/scummvm.vcproj b/dists/msvc9/scummvm.vcproj index 3fecfefb90..5da3451ded 100644 --- a/dists/msvc9/scummvm.vcproj +++ b/dists/msvc9/scummvm.vcproj @@ -1220,10 +1220,6 @@ RelativePath="..\..\gui\ThemeClassic.cpp" > - - diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index db9b774857..e3e7174d90 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -69,13 +69,16 @@ void VectorRenderer::drawStep(const Common::Rect &area, const DrawStep &step, ui if (step.fgColor.set) setFgColor(step.fgColor.r, step.fgColor.g, step.fgColor.b); + + if (step.bevelColor.set) + setBevelColor(step.bevelColor.r, step.bevelColor.g, step.bevelColor.b); if (step.gradColor1.set && step.gradColor2.set) setGradientColors(step.gradColor1.r, step.gradColor1.g, step.gradColor1.b, step.gradColor2.r, step.gradColor2.g, step.gradColor2.b); setShadowOffset(_disableShadows ? 0 : step.shadow); - setInnerShadowOffset(_disableShadows ? 0 : step.innerShadow); + setBevel(step.bevel); setGradientFactor(step.factor); setStrokeWidth(step.stroke); setFillMode((FillMode)step.fillMode); @@ -513,8 +516,8 @@ drawRoundedSquare(int x, int y, int r, int w, int h) { break; } - if (Base::_innerShadowOffset) - drawRoundedSquareInnerShadow(x, y, r, w, h, Base::_innerShadowOffset); + if (Base::_bevel) + drawRoundedSquareFakeBevel(x, y, r, w, h, Base::_bevel); } template @@ -945,6 +948,8 @@ drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, Vecto int pitch = Base::surfacePitch(); int sw = 0, sp = 0, hp = h * pitch; +// if (r < 8) r = 3; + PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r); PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r); PixelType *ptr_bl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + h - r); @@ -1160,7 +1165,7 @@ drawRoundedSquareShadow(int x1, int y1, int r, int w, int h, int blur) { template void VectorRendererSpec:: -drawRoundedSquareInnerShadow(int x1, int y1, int r, int w, int h, int blur) { +drawRoundedSquareFakeBevel(int x1, int y1, int r, int w, int h, int amount) { int x, y; int p = Base::surfacePitch(), px, py; int sw = 0, sp = 0; @@ -1169,7 +1174,7 @@ drawRoundedSquareInnerShadow(int x1, int y1, int r, int w, int h, int blur) { uint32 T = 0, oldT; uint8 a1, a2; - PixelType color = RGBToColor(63, 60, 17); + PixelType color = _bevelColor; //RGBToColor(63, 60, 17); PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r); PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r); @@ -1178,7 +1183,7 @@ drawRoundedSquareInnerShadow(int x1, int y1, int r, int w, int h, int blur) { int short_h = h - 2 * r; - while (sw++ < blur) { + while (sw++ < amount) { colorFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color); sp += p; @@ -1188,9 +1193,6 @@ drawRoundedSquareInnerShadow(int x1, int y1, int r, int w, int h, int blur) { while (x > y++) { __WU_ALGORITHM(); - a1 = a1 * 3 / 4; - a2 = a2 * 3 / 4; - blendPixelPtr(ptr_tr + (y) - (px - p), color, a2); blendPixelPtr(ptr_tr + (x - 1) - (py), color, a2); blendPixelPtr(ptr_tl - (x - 1) - (py), color, a2); @@ -1209,7 +1211,7 @@ drawRoundedSquareInnerShadow(int x1, int y1, int r, int w, int h, int blur) { ptr_fill += p * r; while (short_h-- >= 0) { - colorFill(ptr_fill, ptr_fill + blur, color); + colorFill(ptr_fill, ptr_fill + amount, color); ptr_fill += p; } } diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 3756730720..2c5530c07c 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -47,7 +47,8 @@ struct DrawStep { fgColor, /** Foreground color */ bgColor, /** backgroudn color */ gradColor1, /** gradient start*/ - gradColor2; /** gradient end */ + gradColor2, /** gradient end */ + bevelColor; bool autoWidth, autoHeight; int16 x, y, w, h; /** width, height and position, if not measured automatically. @@ -62,7 +63,7 @@ struct DrawStep { kVectorAlignCenter } xAlign, yAlign; - uint8 shadow, stroke, factor, radius, innerShadow; /** Misc options... */ + uint8 shadow, stroke, factor, radius, bevel; /** Misc options... */ uint8 fillMode; /** active fill mode */ uint32 extraData; /** Generic parameter for extra options (orientation/bevel) */ @@ -257,6 +258,8 @@ public: * @param b value of the blue color byte */ virtual void setBgColor(uint8 r, uint8 g, uint8 b) = 0; + + virtual void setBevelColor(uint8 r, uint8 g, uint8 b) = 0; /** * Set the active gradient color. All shapes drawn using kFillGradient @@ -330,9 +333,9 @@ public: _shadowOffset = offset; } - virtual void setInnerShadowOffset(int offset) { - if (offset >= 0) - _innerShadowOffset = offset; + virtual void setBevel(int amount) { + if (amount >= 0) + _bevel = amount; } /** @@ -450,7 +453,7 @@ protected: FillMode _fillMode; /** Defines in which way (if any) are filled the drawn shapes */ int _shadowOffset; /** offset for drawn shadows */ - int _innerShadowOffset; + int _bevel; bool _disableShadows; /** Disables temporarily shadow drawing for overlayed images. */ int _strokeWidth; /** Width of the stroke of all drawn shapes */ uint32 _dynamicData; /** Dynamic data from the GUI Theme that modifies the drawing of the current shape */ @@ -538,6 +541,10 @@ public: void setBgColor(uint8 r, uint8 g, uint8 b) { this->_bgColor = RGBToColor(r, g, b); } + + void setBevelColor(uint8 r, uint8 g, uint8 b) { + this->_bevelColor = RGBToColor(r, g, b); + } /** * @see VectorRenderer::setGradientColors() @@ -737,7 +744,7 @@ protected: */ virtual void drawSquareShadow(int x, int y, int w, int h, int blur); virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int blur); - virtual void drawRoundedSquareInnerShadow(int x, int y, int r, int w, int h, int bur); + virtual void drawRoundedSquareFakeBevel(int x, int y, int r, int w, int h, int amount); /** * Calculates the color gradient on a given point. @@ -846,6 +853,8 @@ protected: PixelType _gradientStart; /** Start color for the fill gradient */ PixelType _gradientEnd; /** End color for the fill gradient */ + + PixelType _bevelColor; }; /** diff --git a/gui/ThemeEval.h b/gui/ThemeEval.h index c5471bb10d..f53dfe2cd1 100644 --- a/gui/ThemeEval.h +++ b/gui/ThemeEval.h @@ -39,9 +39,233 @@ namespace GUI { +class ThemeLayout { +public: + int16 x, y, w, h; + int paddingTop, paddingBottom, paddingLeft, paddingRight; + int spacing; + Common::Array children; + ThemeLayout *parent; + + uint16 debugcolor; + + enum LayoutType { + kLayoutNone, + kLayoutVertical, + kLayoutHorizontal, + kLayoutWidget + }; + + enum LayoutParsing { + kLayoutParseDefault, + kLayoutParseTop2Bottom, + kLayoutParseBottom2Top, + kLayoutParseLeft2Right, + kLayoutParseRight2Left + } parsingMode; + + virtual LayoutType getLayoutType() { return kLayoutNone; } + virtual void reflowLayout() { + assert(children.size() <= 1); + + if (children.size()) { + children[0]->w = w; + children[0]->h = h; + children[0]->reflowLayout(); + children[0]->setX(0); + children[0]->setY(0); + } + } + + virtual const char *getName() { return "Global Layout"; } + + int16 getParentW() { return parent ? parent->w : g_system->getOverlayWidth(); } + int16 getParentH() { return parent ? parent->w : g_system->getOverlayHeight(); } + int16 getParentX() { return parent ? parent->x : 0; } + int16 getParentY() { return parent ? parent->y : 0; } + + 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); + } + + ThemeLayout(ThemeLayout *p) : parent(p), x(0), y(0), w(-1), h(-1) { debugcolor = rand() % 0xFFFF; } + + virtual void debugPrintIndent(int indent) { + while (indent--) + printf(" "); + } + + void debugDraw(Graphics::Surface *screen, const Graphics::Font *font) { + uint16 color = debugcolor; + 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 void debugPrint(int indent = 0) { + debugPrintIndent(indent); + switch (getLayoutType()) { + case kLayoutNone: + printf("Dialog Layout :: "); + break; + + case kLayoutVertical: + printf("Vertical Layout :: "); + break; + + case kLayoutHorizontal: + printf("Horizontal Layout :: "); + break; + + case kLayoutWidget: + printf("WIDGET (%s) :: ", getName()); + break; + } + + printf("X: %d / Y: %d / W: %d / H: %d\n", x, y, w, h); + + for (uint i = 0; i < children.size(); ++i) + children[i]->debugPrint(indent + 1); + } + + virtual ~ThemeLayout() { + children.clear(); + } +}; + +class ThemeLayoutVertical : public ThemeLayout { +public: + LayoutType getLayoutType() { return kLayoutVertical; } + + ThemeLayoutVertical(ThemeLayout *p) : ThemeLayout(p) {} + + const char *getName() { return "Vertical Layout"; } + + void reflowLayout() { + int curX, curY, mul; + + if (parsingMode == kLayoutParseTop2Bottom) { + curX = paddingLeft; + curY = paddingTop; + mul = 1; + } else { + curX = paddingLeft; + curY = getParentH() - paddingBottom; + mul = -1; + } + + h = paddingTop + paddingBottom; + + for (uint i = 0; i < children.size(); ++i) { + assert(children[i]->getLayoutType() != kLayoutVertical); + + children[i]->reflowLayout(); + + if (i != children.size() - 1) + assert(children[i]->h != -1); + + if (i == 0) + assert(children[i]->w != -1); + + children[i]->setX(curX); + children[i]->setY((parsingMode == kLayoutParseBottom2Top) ? curY - children[i]->h : curY); + + if (children[i]->w == -1) + children[i]->w = w - paddingLeft - paddingRight; + + w = MAX(w, (int16)(children[i]->w + paddingLeft + paddingRight)); + + if (children[i]->h == -1) + children[i]->h = 32; + + h += children[i]->h + spacing; + + curY += (children[i]->h + spacing) * mul; + } + + + } +}; + +class ThemeLayoutHorizontal : public ThemeLayout { +public: + LayoutType getLayoutType() { return kLayoutHorizontal; } + + ThemeLayoutHorizontal(ThemeLayout *p) : ThemeLayout(p) {} + + const char *getName() { return "Horizontal Layout"; } + + void reflowLayout() { + int curX, curY, mul; + + if (parsingMode == kLayoutParseLeft2Right) { + curX = paddingLeft; + curY = paddingTop; + mul = 1; + } else { + curX = getParentW() - paddingRight; + curY = paddingTop; + mul = -1; + } + + w = paddingLeft + paddingRight; + + for (uint i = 0; i < children.size(); ++i) { + assert(children[i]->getLayoutType() != kLayoutHorizontal); + + children[i]->reflowLayout(); + + if (i != children.size() - 1) + assert(children[i]->w != -1); + + if (i == 0) + assert(children[i]->h != -1); + + + children[i]->setX((parsingMode == kLayoutParseRight2Left) ? (curX - children[i]->w) : (curX)); + children[i]->setY(curY); + + if (children[i]->h == -1) + children[i]->h = h - paddingTop - paddingBottom; + + h = MAX(h, (int16)(children[i]->h + paddingTop + paddingBottom)); + + curX += (children[i]->w + spacing) * mul; + w += children[i]->w + spacing; + } + } +}; + +class ThemeLayoutWidget : public ThemeLayout { +public: + LayoutType getLayoutType() { return kLayoutWidget; } + void reflowLayout() { + + } + ThemeLayoutWidget(ThemeLayout *p, const Common::String &name) : ThemeLayout(p), widgetName(name) {} + + const char *getName() { return widgetName.c_str(); } + + Common::String widgetName; +}; + class ThemeEval { typedef Common::HashMap VariablesMap; + typedef Common::HashMap LayoutsMap; public: ThemeEval() {} @@ -64,6 +288,67 @@ public: bool hasVar(const Common::String &name) { return _vars.contains(name); } + void addDialog(const Common::String &name) { + ThemeLayout *layout = new ThemeLayout(0); + _layouts[name] = layout; + + layout->x = 0; + layout->y = 0; + layout->w = g_system->getOverlayWidth(); + layout->h = g_system->getOverlayHeight(); + + layout->paddingBottom = getVar("Globals.Padding.Bottom", 0); + layout->paddingTop = getVar("Globals.Padding.Top", 0); + layout->paddingRight = getVar("Globals.Padding.Right", 0); + layout->paddingLeft = getVar("Globals.Padding.Left", 0); + + _curLayout.push(layout); + } + + void addLayout(ThemeLayout::LayoutType type, ThemeLayout::LayoutParsing parsingMode) { + ThemeLayout *layout = 0; + ThemeLayout::LayoutParsing def = ThemeLayout::kLayoutParseDefault; + + if (type == ThemeLayout::kLayoutVertical) { + layout = new ThemeLayoutVertical(_curLayout.top()); + def = ThemeLayout::kLayoutParseTop2Bottom; + } else if (type == ThemeLayout::kLayoutHorizontal) { + layout = new ThemeLayoutHorizontal(_curLayout.top()); + def = ThemeLayout::kLayoutParseLeft2Right; + } + + layout->parsingMode = (parsingMode == ThemeLayout::kLayoutParseDefault) ? def : parsingMode; + layout->paddingBottom = getVar("Globals.Padding.Bottom", 0); + layout->paddingTop = getVar("Globals.Padding.Top", 0); + layout->paddingRight = getVar("Globals.Padding.Right", 0); + layout->paddingLeft = getVar("Globals.Padding.Left", 0); + + layout->spacing = 4; + + _curLayout.top()->children.push_back(layout); + _curLayout.push(layout); + } + + void closeLayout() { + _curLayout.pop(); + } + + void closeDialog() { + _curLayout.top()->reflowLayout(); + printf("DEBUG LAYOUT PRINT:\n"); + + _curLayout.top()->debugPrint(); + } + + void addWidget(const Common::String &name, int w, int h) { + ThemeLayoutWidget *widget = new ThemeLayoutWidget(_curLayout.top(), name); + + widget->w = w; + widget->h = h; + + _curLayout.top()->children.push_back(widget); + } + void debugPrint() { printf("Debug variable list:\n"); @@ -72,9 +357,15 @@ public: printf(" '%s' = %d\n", i->_key.c_str(), i->_value); } } + + void debugDraw(Graphics::Surface *screen, const Graphics::Font *font) { + _curLayout.top()->debugDraw(screen, font); + } private: VariablesMap _vars; + LayoutsMap _layouts; + Common::Stack _curLayout; }; diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index 310d3d880d..530f613fdb 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -88,7 +88,7 @@ Graphics::DrawStep *ThemeParser::defaultDrawStep() { step->fillMode = Graphics::VectorRenderer::kFillDisabled; step->scale = (1 << 16); step->shadow = 0; - step->innerShadow = 0; + step->bevel = 0; step->stroke = 0; step->radius = 0xFF; @@ -307,7 +307,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst } __PARSER_ASSIGN_INT(stroke, "stroke", false); - __PARSER_ASSIGN_INT(innerShadow, "inner_shadow", false); + __PARSER_ASSIGN_INT(bevel, "bevel", false); __PARSER_ASSIGN_INT(shadow, "shadow", false); __PARSER_ASSIGN_INT(factor, "gradient_factor", false); @@ -315,6 +315,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst __PARSER_ASSIGN_RGB(bgColor, "bg_color"); __PARSER_ASSIGN_RGB(gradColor1, "gradient_start"); __PARSER_ASSIGN_RGB(gradColor2, "gradient_end"); + __PARSER_ASSIGN_RGB(bevelColor, "bevel_color"); if (functionSpecific) { assert(stepNode->values.contains("func")); @@ -449,16 +450,35 @@ bool ThemeParser::parserCallback_def(ParserNode *node) { bool ThemeParser::parserCallback_widget(ParserNode *node) { Common::String var; - if (getParentNode(node)->name == "globals") + if (getParentNode(node)->name == "globals") { var = "Globals." + node->values["name"] + "."; - else if (getParentNode(node)->name == "dialog") - var = "Dialog." + getParentNode(node)->values["name"] + "." + node->values["name"] + "."; - else - assert(!"Corruption in XML parser."); - - if (!parseCommonLayoutProps(node, var)) - return parserError("Error when parsing Layout properties of '%s'.", var.c_str()); - + if (!parseCommonLayoutProps(node, var)) + return parserError("Error when parsing Layout properties of '%s'.", var.c_str()); + } else { + var = node->values["name"]; + int width = -1; + int height = -1; + + if (node->values.contains("width")) { + if (_theme->themeEval()->hasVar(node->values["width"]) == true) + width = _theme->themeEval()->getVar(node->values["width"]); + + else if (!parseIntegerKey(node->values["width"].c_str(), 1, &width)) + return parserError("Corrupted width value in key for %s", var.c_str()); + } + + if (node->values.contains("height")) { + if (_theme->themeEval()->hasVar(node->values["height"]) == true) + height = _theme->themeEval()->getVar(node->values["height"]); + + else if (!parseIntegerKey(node->values["height"].c_str(), 1, &height)) + return parserError("Corrupted height value in key for %s", var.c_str()); + } + + _theme->themeEval()->addWidget(var, width, height); + + } + return true; } @@ -474,8 +494,35 @@ bool ThemeParser::parserCallback_child(ParserNode *node) { bool ThemeParser::parserCallback_dialog(ParserNode *node) { Common::String var = "Dialog." + node->values["name"] + "."; - if (!parseCommonLayoutProps(node, var)) - return parserError("Error when parsing Layout properties of '%s'.", var.c_str()); +// if (!parseCommonLayoutProps(node, var)) +// return parserError("Error when parsing Layout properties of '%s'.", var.c_str()); + + _theme->themeEval()->addDialog(var); + + return true; +} + +bool ThemeParser::parserCallback_layout(ParserNode *node) { + + if (!node->values.contains("type")) + return parserError("Layouts need a specific type (vertical or horizontal)."); + + GUI::ThemeLayout::LayoutType type = GUI::ThemeLayout::kLayoutNone; + + if (node->values["type"] == "vertical") + type = GUI::ThemeLayout::kLayoutVertical; + else if (node->values["type"] == "horizontal") + type = GUI::ThemeLayout::kLayoutHorizontal; + + _theme->themeEval()->addLayout(type, GUI::ThemeLayout::kLayoutParseDefault); + return true; +} + +bool ThemeParser::closedKeyCallback(ParserNode *node) { + if (node->name == "layout") + _theme->themeEval()->closeLayout(); + else if (node->name == "dialog") + _theme->themeEval()->closeDialog(); return true; } diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h index ec7f494735..07bb530894 100644 --- a/gui/ThemeParser.h +++ b/gui/ThemeParser.h @@ -351,12 +351,13 @@ protected: XML_KEY(defaults) XML_PROP(stroke, false) XML_PROP(shadow, false) - XML_PROP(inner_shadow, false) + XML_PROP(bevel, false) XML_PROP(factor, false) XML_PROP(fg_color, false) XML_PROP(bg_color, false) XML_PROP(gradient_start, false) XML_PROP(gradient_end, false) + XML_PROP(bevel_color, false) XML_PROP(gradient_factor, false) XML_PROP(fill, false) KEY_END() @@ -368,12 +369,13 @@ protected: XML_KEY(defaults) XML_PROP(stroke, false) XML_PROP(shadow, false) - XML_PROP(inner_shadow, false) + XML_PROP(bevel, false) XML_PROP(factor, false) XML_PROP(fg_color, false) XML_PROP(bg_color, false) XML_PROP(gradient_start, false) XML_PROP(gradient_end, false) + XML_PROP(bevel_color, false) XML_PROP(gradient_factor, false) XML_PROP(fill, false) KEY_END() @@ -382,13 +384,14 @@ protected: XML_PROP(func, true) XML_PROP(stroke, false) XML_PROP(shadow, false) - XML_PROP(inner_shadow, false) + XML_PROP(bevel, false) XML_PROP(factor, false) XML_PROP(fg_color, false) XML_PROP(bg_color, false) XML_PROP(gradient_start, false) XML_PROP(gradient_end, false) XML_PROP(gradient_factor, false) + XML_PROP(bevel_color, false) XML_PROP(fill, false) XML_PROP(bevel, false) XML_PROP(radius, false) @@ -432,15 +435,21 @@ protected: XML_KEY(dialog) XML_PROP(name, true) - XML_PROP(size, false) - XML_PROP(pos, false) - XML_PROP(resolution, false) - - XML_KEY(widget) - XML_PROP(name, true) - XML_PROP(size, false) - XML_PROP(pos, false) - XML_PROP(padding, false) + XML_KEY(layout) + XML_PROP(type, true) + XML_PROP(align, false) + XML_PROP(direction, false) + XML_KEY(widget) + XML_PROP(name, true) + XML_PROP(width, false) + XML_PROP(height, false) + KEY_END() + + XML_KEY(space) + XML_PROP(size, true) + KEY_END() + + XML_KEY_RECURSIVE(layout) KEY_END() KEY_END() KEY_END() @@ -465,6 +474,10 @@ protected: bool parserCallback_widget(ParserNode *node); bool parserCallback_dialog(ParserNode *node); bool parserCallback_child(ParserNode *node); + bool parserCallback_layout(ParserNode *node); + bool parserCallback_space(ParserNode *node) { return true; } + + bool closedKeyCallback(ParserNode *node); void cleanup(); diff --git a/gui/ThemeRenderer.cpp b/gui/ThemeRenderer.cpp index 9a01b18299..f154f018b9 100644 --- a/gui/ThemeRenderer.cpp +++ b/gui/ThemeRenderer.cpp @@ -693,8 +693,11 @@ void ThemeRenderer::updateScreen() { _textQueue.clear(); } - renderDirtyScreen(); -// _vectorRenderer->copyWholeFrame(_system); +// renderDirtyScreen(); + + _vectorRenderer->fillSurface(); + themeEval()->debugDraw(_screen, _font); + _vectorRenderer->copyWholeFrame(_system); } void ThemeRenderer::renderDirtyScreen() { diff --git a/gui/newgui.cpp b/gui/newgui.cpp index b2e9cf43b0..3c58633923 100644 --- a/gui/newgui.cpp +++ b/gui/newgui.cpp @@ -163,6 +163,7 @@ bool NewGui::loadNewTheme(const Common::String &style) { cfg.clear(); */ _theme = new ThemeRenderer(style, GUI::ThemeRenderer::kGfxAntialias16bit); +// _theme = new ThemeRenderer(style, GUI::ThemeRenderer::kGfxStandard16bit); if (!_theme) return (!oldTheme.empty() ? loadNewTheme(oldTheme) : false); @@ -244,6 +245,8 @@ void NewGui::runLoop() { } Common::EventManager *eventMan = _system->getEventManager(); + uint32 lastRedraw = 0; + const uint32 waitTime = 1000 / 45; while (!_dialogStack.empty() && activeDialog == getTopDialog()) { redraw(); @@ -255,9 +258,15 @@ void NewGui::runLoop() { if (_useStdCursor) animateCursor(); - _theme->updateScreen(); - _system->updateScreen(); - +// _theme->updateScreen(); +// _system->updateScreen(); + + if (lastRedraw + waitTime < _system->getMillis()) { + _theme->updateScreen(); + _system->updateScreen(); + lastRedraw = _system->getMillis(); + } + Common::Event event; while (eventMan->pollEvent(event)) { @@ -280,6 +289,12 @@ void NewGui::runLoop() { _redrawStatus = kRedrawFull; redraw(); } + + if (lastRedraw + waitTime < _system->getMillis()) { + _theme->updateScreen(); + _system->updateScreen(); + lastRedraw = _system->getMillis(); + } switch (event.type) { case Common::EVENT_KEYDOWN: diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 20d3e3869f..fb5bd8dcf3 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -1 +1 @@ -" " +" " diff --git a/gui/themes/modern.stx b/gui/themes/modern.stx index dce8495ff8..c26a7856af 100644 --- a/gui/themes/modern.stx +++ b/gui/themes/modern.stx @@ -52,6 +52,9 @@ + @@ -81,7 +84,7 @@ /> - + @@ -314,10 +318,11 @@ radius = '6' stroke = 1 fill = 'gradient' - shadow = 2 - fg_color = 'blandyellow' + shadow = 0 + fg_color = 'shadowcolor' gradient_start = 'brightred' gradient_end = 'darkred' + bevel = 1 /> @@ -329,11 +334,14 @@ @@ -361,7 +369,8 @@ radius = 4 fg_color = 'black' shadow = 0 - inner_shadow = 1 + bevel = 1 + bevel_color = 'shadowcolor' /> @@ -377,8 +386,8 @@ gradient_start = 'brightred' gradient_end = 'darkred' shadow = 0 - stroke = 1 - inner_shadow = 1 + bevel = 1 + bevel_color = 'shadowcolor' /> @@ -392,7 +401,8 @@ radius = 4 fg_color = 'blandyellow' shadow = 0 - inner_shadow = 1 + bevel = 1 + bevel_color = 'shadowcolor' /> @@ -410,9 +420,14 @@ - + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3