GUI Layout parsing. Work in progress.

svn-id: r33475
This commit is contained in:
Vicent Marti 2008-07-31 17:23:38 +00:00
parent 01cf9174b1
commit e8278c4c68
7 changed files with 231 additions and 26 deletions

View file

@ -41,25 +41,34 @@ bool XMLParser::parserError(const char *errorString, ...) {
int lineCount = 1;
int lineStart = 0;
do {
if (_text[pos] == '\n' || _text[pos] == '\r') {
lineCount++;
if (lineStart == 0)
lineStart = MAX(pos + 1, _pos - 60);
}
} while (pos-- > 0);
if (_fileName == "Memory Stream") {
lineStart = MAX(0, _pos - 35);
lineCount = 0;
} else {
do {
if (_text[pos] == '\n' || _text[pos] == '\r') {
lineCount++;
if (lineStart == 0)
lineStart = MAX(pos + 1, _pos - 60);
}
} while (pos-- > 0);
}
char lineStr[70];
_text.stream()->seek(lineStart, SEEK_SET);
_text.stream()->readLine(lineStr, 70);
for (int i = 0; i < 70; ++i)
if (lineStr[i] == '\n')
lineStr[i] = ' ';
printf(" File <%s>, line %d:\n", _fileName.c_str(), lineCount);
printf("\n File <%s>, line %d:\n", _fileName.c_str(), lineCount);
bool startFull = lineStr[0] == '<';
bool endFull = lineStr[strlen(lineStr) - 1] == '>';
printf("%s%s%s\n", startFull ? "" : "...", endFull ? "" : "...", lineStr);
printf("%s%s%s\n", startFull ? "" : "...", lineStr, endFull ? "" : "...");
int cursor = MIN(_pos - lineStart, 70);
@ -77,7 +86,7 @@ bool XMLParser::parserError(const char *errorString, ...) {
vprintf(errorString, args);
va_end(args);
printf("\n");
printf("\n\n");
return false;
}
@ -123,9 +132,8 @@ bool XMLParser::parseActiveKey(bool closed) {
return false;
}
if (closed) {
if (closed)
delete _activeKey.pop();
}
return true;
}

View file

@ -154,16 +154,29 @@ bool ThemeRenderer::loadDefaultXML() {
"</render_info>"
"<layout_info>"
"<definitions>"
"<def widgetSize = '30' />"
"<def buttonWidth = '120' buttonHeight = '25' />"
"<def sliderWidth = '' sliderHeight = '' />"
"<def lineHeight = 16 fontHeight = 14 />"
"<def />"
"</definitions>"
"<widgets>"
"<widget id = 'scrollbar' />"
"</widgets>"
"<globals>"
"<def var = 'Widget.Size' value = '30' />"
"<def var = 'Line.Height' value = '16' />"
"<def var = 'Font.Height' value = '16' />"
"<widget name = 'Inset' pos = '23, 94' size = '666, 666' />"
"<widget name = 'Button' size = '120, 25' />"
"<widget name = 'Slider' size = '666, 666' />"
"<widget name = 'ListWidget' padding = '7, 5, 5, 5' />"
"<widget name = 'PopUpWidget' padding = '7, 5, 0, 0' />"
"<widget name = 'EditTextWidget' padding = '7, 5, 0, 0' />"
"<widget name = 'Console' padding = '7, 5, 5, 5' />"
"<widget name = 'TabWidget'>"
"<child name = 'Tab' size = '75, 27' />"
"<child name = 'NavButton' size = '15, 18' padding = '0, 3, 4, 0' />"
"</widget>"
"</globals>"
"<dialog name = 'GlobalOptions'>"
"<widget name = 'scrollbar' />"
"</dialog>"
"</layout_info>";
if (!parser()->loadBuffer((const byte*)defaultXML, strlen(defaultXML), false))

81
gui/ThemeEval.h Normal file
View file

@ -0,0 +1,81 @@
/* 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 GUI_THEME_EVAL
#define GUI_THEME_EVAL
#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 "gui/ThemeRenderer.h"
#include "gui/ThemeParser.h"
#include "gui/ThemeEval.h"
namespace GUI {
class ThemeEval {
typedef Common::HashMap<Common::String, int> VariablesMap;
public:
ThemeEval() {}
~ThemeEval() {}
int getVar(const Common::String &s) {
if (!_vars.contains(s)) {
warning("Missing variable: '%s'", s.c_str());
return -1;
}
return _vars[s];
}
int getVar(const Common::String &s, int def) {
return (_vars.contains(s)) ? _vars[s] : def;
}
void setVar(const String &name, int val) { _vars[name] = val; }
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);
}
}
private:
VariablesMap _vars;
};
}
#endif

View file

@ -433,5 +433,55 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
return true;
}
bool ThemeParser::parserCallback_def(ParserNode *node) {
Common::String var = "Globals." + node->values["var"];
int value;
if (!parseIntegerKey(node->values["value"].c_str(), 1, &value))
return parserError("Invalid definition for '%s'.", var.c_str());
_theme->themeEval()->setVar(var, value);
return true;
}
bool ThemeParser::parserCallback_widget(ParserNode *node) {
Common::String var;
int width, height, x, y, paddingL, paddingR, paddingT, paddingB;
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 (node->values.contains("size")) {
if (!parseIntegerKey(node->values["size"].c_str(), 2, &width, &height))
return parserError("Invalid definition for '%sSize'.", var.c_str());
_theme->themeEval()->setVar(var + "Width", width);
_theme->themeEval()->setVar(var + "Height", height);
}
if (node->values.contains("pos")) {
if (!parseIntegerKey(node->values["pos"].c_str(), 2, &x, &y))
return parserError("Invalid definition for '%sPosition'.", var.c_str());
_theme->themeEval()->setVar(var + "X", x);
_theme->themeEval()->setVar(var + "Y", y);
}
if (node->values.contains("padding")) {
if (!parseIntegerKey(node->values["padding"].c_str(), 4, &paddingL, &paddingR, &paddingT, &paddingB))
return parserError("Invalid definition for '%sPadding'.", var.c_str());
_theme->themeEval()->setVar(var + "Padding.Left", paddingL);
_theme->themeEval()->setVar(var + "Padding.Right", paddingR);
_theme->themeEval()->setVar(var + "Padding.Top", paddingT);
_theme->themeEval()->setVar(var + "Padding.Bottom", paddingB);
}
return true;
}
}

View file

@ -406,21 +406,63 @@ protected:
KEY_END() // render_info end
XML_KEY(layout_info)
KEY_END()
XML_KEY(globals)
XML_PROP(resolution, false)
XML_KEY(def)
XML_PROP(var, true)
XML_PROP(value, true)
KEY_END()
XML_KEY(widget)
XML_PROP(name, true)
XML_PROP(size, false)
XML_PROP(pos, false)
XML_PROP(padding, false)
XML_KEY(child)
XML_PROP(name, true)
XML_PROP(size, false)
XML_PROP(padding, false)
KEY_END()
KEY_END()
KEY_END()
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)
KEY_END()
KEY_END()
KEY_END()
} PARSER_END();
/** Render info callbacks */
bool parserCallback_render_info(ParserNode *node);
bool parserCallback_defaults(ParserNode *node);
bool parserCallback_font(ParserNode *node);
bool parserCallback_fonts(ParserNode *node);
bool parserCallback_text(ParserNode *node);
bool parserCallback_render_info(ParserNode *node);
bool parserCallback_layout_info(ParserNode *node);
bool parserCallback_palette(ParserNode *node);
bool parserCallback_color(ParserNode *node);
bool parserCallback_drawstep(ParserNode *node);
bool parserCallback_drawdata(ParserNode *node);
/** Layout info callbacks */
bool parserCallback_layout_info(ParserNode *node);
bool parserCallback_globals(ParserNode *node) { return true; }
bool parserCallback_def(ParserNode *node);
bool parserCallback_widget(ParserNode *node);
bool parserCallback_dialog(ParserNode *node) { return true; }
bool parserCallback_child(ParserNode *node) { return true; }
void cleanup();
Graphics::DrawStep *newDrawStep();

View file

@ -33,6 +33,7 @@
#include "gui/launcher.h"
#include "gui/ThemeRenderer.h"
#include "gui/ThemeEval.h"
#include "graphics/VectorRenderer.h"
namespace GUI {
@ -92,6 +93,7 @@ ThemeRenderer::ThemeRenderer(Common::String themeName, GraphicsMode mode) :
_themeOk(false), _enabled(false), _buffering(false) {
_system = g_system;
_parser = new ThemeParser(this);
_themeEval = new GUI::ThemeEval();
for (int i = 0; i < kDrawDataMAX; ++i) {
_widgets[i] = 0;
@ -284,6 +286,9 @@ bool ThemeRenderer::loadTheme(Common::String themeName) {
}
}
// Debug print all the parsed variables. remove
_themeEval->debugPrint();
_themeOk = true;
return true;
}

View file

@ -35,6 +35,7 @@
#include "gui/dialog.h"
#include "gui/ThemeParser.h"
#include "gui/ThemeEval.h"
#include "graphics/VectorRenderer.h"
namespace GUI {
@ -208,6 +209,8 @@ public:
unloadTheme();
delete _parser;
}
GUI::ThemeEval *themeEval() { return _themeEval; }
/**
* VIRTUAL METHODS
@ -585,6 +588,9 @@ protected:
/** 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;