Common:
- Added function to get the active host type as a string. XMLParser: - Added support for ignoring keys while parsing (check documentation). Backwards compatible. - parserError() has been revamped. Shows all kinds of detailed information regarding the error ala Python InterfaceManager/ThemeParser: - DrawData keys and their DrawStep subkeys are now successfully parsed and loaded into structs. That's a win. - Bug fixes. svn-id: r32768
This commit is contained in:
parent
a4b4534a66
commit
8caa7d3f8b
8 changed files with 295 additions and 36 deletions
|
@ -481,6 +481,34 @@ uint32 getEnabledSpecialDebugLevels() {
|
||||||
return gDebugLevelsEnabled;
|
return gDebugLevelsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *getHostPlatformString() {
|
||||||
|
|
||||||
|
#if defined(__SYMBIAN32__)
|
||||||
|
return "symbian";
|
||||||
|
#elif defined(_WIN32_WCE) || defined(_MSC_VER) || defined(__MINGW32__) || defined(UNIX)
|
||||||
|
return "pc";
|
||||||
|
#elif defined(__PALMOS_TRAPS__) || defined (__PALMOS_ARMLET__)
|
||||||
|
return "palmos";
|
||||||
|
#elif defined(__DC__)
|
||||||
|
return "dc";
|
||||||
|
#elif defined(__GP32__)
|
||||||
|
return "gp32";
|
||||||
|
#elif defined(__PLAYSTATION2__)
|
||||||
|
return "ps2";
|
||||||
|
#elif defined(__PSP__)
|
||||||
|
return "psp";
|
||||||
|
#elif defined(__amigaos4__)
|
||||||
|
return "amigaos";
|
||||||
|
#elif defined (__DS__) //NeilM
|
||||||
|
return "nds";
|
||||||
|
#elif defined(__WII__)
|
||||||
|
return "wii";
|
||||||
|
#else
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // End of namespace Common
|
} // End of namespace Common
|
||||||
|
|
||||||
|
@ -694,3 +722,4 @@ Common::String tag2string(uint32 tag) {
|
||||||
str[4] = '\0';
|
str[4] = '\0';
|
||||||
return Common::String(str);
|
return Common::String(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,6 +323,13 @@ const DebugLevelContainer &listSpecialDebugLevels();
|
||||||
uint32 getEnabledSpecialDebugLevels();
|
uint32 getEnabledSpecialDebugLevels();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string containing the name of the currently running host.
|
||||||
|
* E.g. returns "wii" if ScummVM is being run in a Wii, and so on.
|
||||||
|
*/
|
||||||
|
const char *getHostPlatformString();
|
||||||
|
|
||||||
|
|
||||||
} // End of namespace Common
|
} // End of namespace Common
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,35 +36,86 @@ using namespace Graphics;
|
||||||
|
|
||||||
void XMLParser::debug_testEval() {
|
void XMLParser::debug_testEval() {
|
||||||
static const char *debugConfigText =
|
static const char *debugConfigText =
|
||||||
"</* lol this is just a moronic test */drawdata id = \"background_default\" cache = true>\n"
|
"</* lol this is just a moronic test */drawdata id = \"mainmenu_bg\" cache = true>\n"
|
||||||
"<drawstep func = \"roundedsq\" fill = \"gradient\" gradient_start = \"255, 255, 128\" gradient_end = \"128, 128, 128\" size = \"auto\"/>\n"
|
"<drawstep| func = \"roundedsq\" fill = \"gradient\" gradient_start = \"255, 255, 128\" gradient_end = \"128, 128, 128\" size = \"auto\"/>\n"
|
||||||
"//<drawstep func = \"roundedsq\" fill = \"none\" color = /*\"0, 0, 0\"*/\"0, 1, 2\" size = \"auto\"/>\n"
|
"//<drawstep func = \"roundedsq\" fill = \"none\" color = /*\"0, 0, 0\"*/\"0, 1, 2\" size = \"auto\"/>\n"
|
||||||
"</ drawdata>/* lol this is just a simple test*/\n";
|
"</ drawdata>/* lol this is just a simple test*/\n";
|
||||||
|
|
||||||
_text = strdup(debugConfigText);
|
_text = strdup(debugConfigText);
|
||||||
|
_fileName = strdup("test_parse.xml");
|
||||||
|
|
||||||
Common::String test = "12, 125, 125";
|
Common::String test = "12, 125, 125";
|
||||||
|
|
||||||
printf("\n\nRegex result: %s.\n\n", test.regexMatch("^[d]*,[d]*,[d]*$", true) ? "Success." : "Fail");
|
|
||||||
|
|
||||||
parse();
|
parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLParser::parserError(const char *error_string) {
|
void XMLParser::parserError(const char *error_string, ...) {
|
||||||
_state = kParserError;
|
_state = kParserError;
|
||||||
printf("PARSER ERROR: %s\n", error_string);
|
|
||||||
|
int pos = _pos;
|
||||||
|
int line_count = 1;
|
||||||
|
int line_start = -1;
|
||||||
|
int line_width = 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (_text[pos] == '\n' || _text[pos] == '\r') {
|
||||||
|
line_count++;
|
||||||
|
|
||||||
|
if (line_start == -1)
|
||||||
|
line_start = pos;
|
||||||
|
}
|
||||||
|
} while (pos-- > 0);
|
||||||
|
|
||||||
|
line_start = MAX(line_start, _pos - 80);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (_text[line_start + line_width] == '\n' || _text[line_start + line_width] == '\r')
|
||||||
|
break;
|
||||||
|
} while (_text[line_start + line_width++]);
|
||||||
|
|
||||||
|
line_width = MIN(line_width, 80);
|
||||||
|
|
||||||
|
char linestr[81];
|
||||||
|
strncpy(linestr, &_text[line_start] + 1, line_width );
|
||||||
|
linestr[line_width - 1] = 0;
|
||||||
|
|
||||||
|
printf(" File <%s>, line %d:\n", _fileName, line_count);
|
||||||
|
|
||||||
|
printf("%s\n", linestr);
|
||||||
|
for (int i = 1; i < _pos - line_start; ++i)
|
||||||
|
printf(" ");
|
||||||
|
|
||||||
|
printf("^\n");
|
||||||
|
printf("Parser error: ");
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, error_string);
|
||||||
|
vprintf(error_string, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLParser::parseActiveKey(bool closed) {
|
bool XMLParser::parseActiveKey(bool closed) {
|
||||||
if (keyCallback(_activeKey.top()->name) == false) {
|
bool ignore = false;
|
||||||
parserError("Unhandled value inside key.");
|
|
||||||
return;
|
// check if any of the parents must be ignored.
|
||||||
|
// if a parent is ignored, all children are too.
|
||||||
|
for (int i = _activeKey.size() - 1; i >= 0; --i) {
|
||||||
|
if (_activeKey[i]->ignore)
|
||||||
|
ignore = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignore == false && keyCallback(_activeKey.top()->name) == false) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closed) {
|
if (closed) {
|
||||||
delete _activeKey.pop();
|
delete _activeKey.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XMLParser::parseKeyValue(Common::String keyName) {
|
bool XMLParser::parseKeyValue(Common::String keyName) {
|
||||||
|
@ -115,7 +166,7 @@ bool XMLParser::parse() {
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case kParserNeedKey:
|
case kParserNeedKey:
|
||||||
if (_text[_pos++] != '<') {
|
if (_text[_pos++] != '<') {
|
||||||
parserError("Expecting key start.");
|
parserError("Parser expecting key start.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +195,7 @@ bool XMLParser::parse() {
|
||||||
} else {
|
} else {
|
||||||
ParserNode *node = new ParserNode;
|
ParserNode *node = new ParserNode;
|
||||||
node->name = _token;
|
node->name = _token;
|
||||||
|
node->ignore = false;
|
||||||
_activeKey.push(node);
|
_activeKey.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,9 +218,10 @@ bool XMLParser::parse() {
|
||||||
selfClosure = (_text[_pos] == '/');
|
selfClosure = (_text[_pos] == '/');
|
||||||
|
|
||||||
if ((selfClosure && _text[_pos + 1] == '>') || _text[_pos] == '>') {
|
if ((selfClosure && _text[_pos + 1] == '>') || _text[_pos] == '>') {
|
||||||
parseActiveKey(selfClosure);
|
if (parseActiveKey(selfClosure)) {
|
||||||
_pos += selfClosure ? 2 : 1;
|
_pos += selfClosure ? 2 : 1;
|
||||||
_state = kParserNeedKey;
|
_state = kParserNeedKey;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +234,7 @@ bool XMLParser::parse() {
|
||||||
|
|
||||||
case kParserNeedPropertyOperator:
|
case kParserNeedPropertyOperator:
|
||||||
if (_text[_pos++] != '=')
|
if (_text[_pos++] != '=')
|
||||||
parserError("Unexpected character after key name.");
|
parserError("Syntax error after key name.");
|
||||||
else
|
else
|
||||||
_state = kParserNeedPropertyValue;
|
_state = kParserNeedPropertyValue;
|
||||||
|
|
||||||
|
@ -189,7 +242,7 @@ bool XMLParser::parse() {
|
||||||
|
|
||||||
case kParserNeedPropertyValue:
|
case kParserNeedPropertyValue:
|
||||||
if (!parseKeyValue(_token))
|
if (!parseKeyValue(_token))
|
||||||
parserError("Unable to parse key value.");
|
parserError("Invalid key value.");
|
||||||
else
|
else
|
||||||
_state = kParserNeedPropertyName;
|
_state = kParserNeedPropertyName;
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ public:
|
||||||
struct ParserNode {
|
struct ParserNode {
|
||||||
Common::String name;
|
Common::String name;
|
||||||
Common::StringMap values;
|
Common::StringMap values;
|
||||||
|
bool ignore;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool parse();
|
virtual bool parse();
|
||||||
|
@ -103,7 +104,13 @@ protected:
|
||||||
* Remember to leave the node stack _UNCHANGED_ in your own function. Removal
|
* Remember to leave the node stack _UNCHANGED_ in your own function. Removal
|
||||||
* of closed keys is done automatically.
|
* of closed keys is done automatically.
|
||||||
*
|
*
|
||||||
* Return true if the key was properly handled. False otherwise.
|
* When parsing a key, one may chose to skip it, e.g. because it's not needed
|
||||||
|
* on the current configuration. In order to ignore a key, you must set
|
||||||
|
* the "ignore" field of its KeyNode struct to "true": The key and all its children
|
||||||
|
* will then be automatically ignored by the parser.
|
||||||
|
*
|
||||||
|
* Return true if the key was properly handled (this includes the case when the
|
||||||
|
* key is being ignored). False otherwise.
|
||||||
* See the sample implementation in GUI::ThemeParser.
|
* See the sample implementation in GUI::ThemeParser.
|
||||||
*/
|
*/
|
||||||
virtual bool keyCallback(Common::String keyName) {
|
virtual bool keyCallback(Common::String keyName) {
|
||||||
|
@ -120,13 +127,12 @@ protected:
|
||||||
* node stack and calls the keyCallback.
|
* node stack and calls the keyCallback.
|
||||||
* There's no reason to overload this.
|
* There's no reason to overload this.
|
||||||
*/
|
*/
|
||||||
virtual void parseActiveKey(bool closed);
|
virtual bool parseActiveKey(bool closed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints an error message when parsing fails and stops the parser.
|
* Prints an error message when parsing fails and stops the parser.
|
||||||
* TODO: More descriptive error messages.
|
|
||||||
*/
|
*/
|
||||||
virtual void parserError(const char *errorString);
|
virtual void parserError(const char *errorString, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips spaces/whitelines etc. Returns true if any spaces were skipped.
|
* Skips spaces/whitelines etc. Returns true if any spaces were skipped.
|
||||||
|
@ -163,7 +169,7 @@ protected:
|
||||||
|
|
||||||
if (_text[_pos] == '/' && _text[_pos + 1] == '/') {
|
if (_text[_pos] == '/' && _text[_pos + 1] == '/') {
|
||||||
_pos += 2;
|
_pos += 2;
|
||||||
while (_text[_pos] && _text[_pos] != '\n')
|
while (_text[_pos] && _text[_pos] != '\n' && _text[_pos] != '\r')
|
||||||
_pos++;
|
_pos++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -194,6 +200,7 @@ protected:
|
||||||
|
|
||||||
int _pos; /** Current position on the XML buffer. */
|
int _pos; /** Current position on the XML buffer. */
|
||||||
char *_text; /** Buffer with the text being parsed */
|
char *_text; /** Buffer with the text being parsed */
|
||||||
|
char *_fileName;
|
||||||
|
|
||||||
ParserState _state; /** Internal state of the parser */
|
ParserState _state; /** Internal state of the parser */
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,44 @@ namespace GUI {
|
||||||
|
|
||||||
using namespace Graphics;
|
using namespace Graphics;
|
||||||
|
|
||||||
|
const char *InterfaceManager::kDrawDataStrings[] = {
|
||||||
|
"mainmenu_bg",
|
||||||
|
"special_bg",
|
||||||
|
"plain_bg",
|
||||||
|
"default_bg",
|
||||||
|
|
||||||
|
"button_idle",
|
||||||
|
"button_hover",
|
||||||
|
|
||||||
|
"surface",
|
||||||
|
|
||||||
|
"slider_full",
|
||||||
|
"slider_empty",
|
||||||
|
|
||||||
|
"checkbox_enabled",
|
||||||
|
"checkbox_disabled",
|
||||||
|
|
||||||
|
"tab",
|
||||||
|
|
||||||
|
"scrollbar_base",
|
||||||
|
"scrollbar_top",
|
||||||
|
"scrollbar_bottom",
|
||||||
|
"scrollbar_handle",
|
||||||
|
|
||||||
|
"popup",
|
||||||
|
"caret",
|
||||||
|
"separator"
|
||||||
|
};
|
||||||
|
|
||||||
InterfaceManager::InterfaceManager() :
|
InterfaceManager::InterfaceManager() :
|
||||||
_vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled),
|
_vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled),
|
||||||
_screen(0), _bytesPerPixel(0) {
|
_screen(0), _bytesPerPixel(0) {
|
||||||
_system = g_system;
|
_system = g_system;
|
||||||
|
|
||||||
|
for (int i = 0; i < kDrawDataMAX; ++i) {
|
||||||
|
_widgets[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
setGraphicsMode(kGfxStandard16bit);
|
setGraphicsMode(kGfxStandard16bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +111,25 @@ void InterfaceManager::setGraphicsMode(Graphics_Mode mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterfaceManager::addDrawStep(Common::String &drawDataId, Graphics::DrawStep *step) {
|
void InterfaceManager::addDrawStep(Common::String &drawDataId, Graphics::DrawStep *step) {
|
||||||
_widgets[getDrawDataId(drawDataId)]->_steps.push_back(step);
|
DrawData id = getDrawDataId(drawDataId);
|
||||||
|
|
||||||
|
assert(_widgets[id] != 0);
|
||||||
|
_widgets[id]->_steps.push_back(step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterfaceManager::addDrawData(DrawData data_id, bool cached) {
|
||||||
|
assert(data_id >= 0 && data_id < kDrawDataMAX);
|
||||||
|
|
||||||
|
if (_widgets[data_id] != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_widgets[data_id] = new WidgetDrawData;
|
||||||
|
_widgets[data_id]->_cached = cached;
|
||||||
|
_widgets[data_id]->_type = data_id;
|
||||||
|
_widgets[data_id]->_scaled = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool InterfaceManager::init() {
|
bool InterfaceManager::init() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -47,6 +47,8 @@ class InterfaceManager : public Common::Singleton<InterfaceManager> {
|
||||||
friend class Common::Singleton<SingletonBaseType>;
|
friend class Common::Singleton<SingletonBaseType>;
|
||||||
typedef Common::String String;
|
typedef Common::String String;
|
||||||
|
|
||||||
|
static const char *kDrawDataStrings[];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Graphics_Mode {
|
enum Graphics_Mode {
|
||||||
kGfxDisabled = 0,
|
kGfxDisabled = 0,
|
||||||
|
@ -168,10 +170,15 @@ public:
|
||||||
void drawLineSeparator(const Common::Rect &r, WidgetStateInfo state = kStateEnabled);
|
void drawLineSeparator(const Common::Rect &r, WidgetStateInfo state = kStateEnabled);
|
||||||
|
|
||||||
DrawData getDrawDataId(Common::String &name) {
|
DrawData getDrawDataId(Common::String &name) {
|
||||||
return (DrawData)0;
|
for (int i = 0; i < kDrawDataMAX; ++i)
|
||||||
|
if (name.compareToIgnoreCase(kDrawDataStrings[i]) == 0)
|
||||||
|
return (DrawData)i;
|
||||||
|
|
||||||
|
return (DrawData)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDrawStep(Common::String &drawDataId, Graphics::DrawStep *step);
|
void addDrawStep(Common::String &drawDataId, Graphics::DrawStep *step);
|
||||||
|
bool addDrawData(DrawData data_id, bool cached);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<typename PixelType> void screenInit();
|
template<typename PixelType> void screenInit();
|
||||||
|
|
|
@ -42,6 +42,15 @@ using namespace Common;
|
||||||
ThemeParser::ThemeParser() : XMLParser() {
|
ThemeParser::ThemeParser() : XMLParser() {
|
||||||
_callbacks["drawstep"] = &ThemeParser::parserCallback_DRAWSTEP;
|
_callbacks["drawstep"] = &ThemeParser::parserCallback_DRAWSTEP;
|
||||||
_callbacks["drawdata"] = &ThemeParser::parserCallback_DRAWDATA;
|
_callbacks["drawdata"] = &ThemeParser::parserCallback_DRAWDATA;
|
||||||
|
|
||||||
|
_drawFunctions["circle"] = &Graphics::VectorRenderer::drawCallback_CIRCLE;
|
||||||
|
_drawFunctions["square"] = &Graphics::VectorRenderer::drawCallback_SQUARE;
|
||||||
|
_drawFunctions["roundedsq"] = &Graphics::VectorRenderer::drawCallback_ROUNDSQ;
|
||||||
|
_drawFunctions["bevelsq"] = &Graphics::VectorRenderer::drawCallback_BEVELSQ;
|
||||||
|
_drawFunctions["line"] = &Graphics::VectorRenderer::drawCallback_LINE;
|
||||||
|
_drawFunctions["triangle"] = &Graphics::VectorRenderer::drawCallback_TRIANGLE;
|
||||||
|
_drawFunctions["fill"] = &Graphics::VectorRenderer::drawCallback_FILLSURFACE;
|
||||||
|
_drawFunctions["void"] = &Graphics::VectorRenderer::drawCallback_VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThemeParser::keyCallback(Common::String keyName) {
|
bool ThemeParser::keyCallback(Common::String keyName) {
|
||||||
|
@ -73,8 +82,12 @@ Graphics::DrawStep *ThemeParser::newDrawStep() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThemeParser::parserCallback_DRAWSTEP() {
|
bool ThemeParser::parserCallback_DRAWSTEP() {
|
||||||
ParserNode *stepNode = _activeKey.pop();
|
ParserNode *stepNode = _activeKey.top();
|
||||||
ParserNode *drawdataNode = _activeKey.pop();
|
|
||||||
|
// HACK: Any cleaner way to access the second item from
|
||||||
|
// the top without popping? Let's keep it this way and hope
|
||||||
|
// the internal representation doesn't change
|
||||||
|
ParserNode *drawdataNode = _activeKey[_activeKey.size() - 2];
|
||||||
|
|
||||||
assert(stepNode->name == "drawstep");
|
assert(stepNode->name == "drawstep");
|
||||||
assert(drawdataNode->name == "drawdata");
|
assert(drawdataNode->name == "drawdata");
|
||||||
|
@ -85,32 +98,108 @@ bool ThemeParser::parserCallback_DRAWSTEP() {
|
||||||
Common::String functionName = stepNode->values["func"];
|
Common::String functionName = stepNode->values["func"];
|
||||||
|
|
||||||
if (_drawFunctions.contains(functionName) == false) {
|
if (_drawFunctions.contains(functionName) == false) {
|
||||||
parserError("Invalid drawing function in draw step.");
|
parserError("%s is not a valid drawing function name", functionName.c_str());
|
||||||
_activeKey.push(drawdataNode);
|
|
||||||
_activeKey.push(stepNode);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawstep->drawingCall = _drawFunctions[functionName];
|
drawstep->drawingCall = _drawFunctions[functionName];
|
||||||
|
|
||||||
if (stepNode->values.contains("stroke")) {
|
uint32 red, green, blue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper macro to sanitize and assign an integer value from a key
|
||||||
|
* to the draw step.
|
||||||
|
*
|
||||||
|
* @param struct_name Name of the field of a DrawStep struct that must be
|
||||||
|
* assigned.
|
||||||
|
* @param key_name Name as STRING of the key identifier as it appears in the
|
||||||
|
* theme description format.
|
||||||
|
*/
|
||||||
|
#define __PARSER_ASSIGN_INT(struct_name, key_name) \
|
||||||
|
if (stepNode->values.contains(key_name)) { \
|
||||||
|
if (!validateKeyInt(stepNode->values[key_name].c_str())) \
|
||||||
|
return false; \
|
||||||
|
\
|
||||||
|
drawstep->struct_name = atoi(stepNode->values[key_name].c_str()); \
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functionName == "roundedsq") {
|
/**
|
||||||
|
* Helper macro to sanitize and assign a RGB value from a key to the draw
|
||||||
|
* step. RGB values have the following syntax: "R, G, B".
|
||||||
|
*
|
||||||
|
* TODO: Handle also specific name colors such as "red", "green", etc.
|
||||||
|
*
|
||||||
|
* @param struct_name Name of the field of a DrawStep struct that must be
|
||||||
|
* assigned.
|
||||||
|
* @param key_name Name as STRING of the key identifier as it appears in the
|
||||||
|
* theme description format.
|
||||||
|
*/
|
||||||
|
#define __PARSER_ASSIGN_RGB(struct_name, key_name) \
|
||||||
|
if (stepNode->values.contains(key_name)) { \
|
||||||
|
if (sscanf(stepNode->values[key_name].c_str(), "%d, %d, %d", &red, &green, &blue) != 3) \
|
||||||
|
return false; \
|
||||||
|
\
|
||||||
|
drawstep->struct_name.r = red; \
|
||||||
|
drawstep->struct_name.g = green; \
|
||||||
|
drawstep->struct_name.b = blue; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__PARSER_ASSIGN_INT(stroke, "stroke");
|
||||||
|
__PARSER_ASSIGN_INT(shadow, "shadow");
|
||||||
|
__PARSER_ASSIGN_INT(factor, "gradient_factor");
|
||||||
|
|
||||||
|
__PARSER_ASSIGN_RGB(fgColor, "fg_color");
|
||||||
|
__PARSER_ASSIGN_RGB(bgColor, "bg_color");
|
||||||
|
__PARSER_ASSIGN_RGB(gradColor1, "gradient_start");
|
||||||
|
__PARSER_ASSIGN_RGB(gradColor2, "gradient_end");
|
||||||
|
|
||||||
|
if (functionName == "roundedsq" || functionName == "circle") {
|
||||||
|
__PARSER_ASSIGN_INT(radius, "radius");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (functionName == "bevelsq") {
|
||||||
|
__PARSER_ASSIGN_INT(extraData, "bevel");
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef __PARSER_ASSIGN_INT
|
||||||
|
#undef __PARSER_ASSIGN_RGB
|
||||||
|
|
||||||
g_InterfaceManager.addDrawStep(drawdataNode->values["id"], drawstep);
|
g_InterfaceManager.addDrawStep(drawdataNode->values["id"], drawstep);
|
||||||
|
|
||||||
_activeKey.push(drawdataNode);
|
|
||||||
_activeKey.push(stepNode);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThemeParser::parserCallback_DRAWDATA() {
|
bool ThemeParser::parserCallback_DRAWDATA() {
|
||||||
printf("Drawdata callback!\n");
|
ParserNode *drawdataNode = _activeKey.top();
|
||||||
|
bool cached = false;
|
||||||
|
|
||||||
|
if (drawdataNode->values.contains("id") == false) {
|
||||||
|
parserError("DrawData notes must contain an identifier.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
InterfaceManager::DrawData id = g_InterfaceManager.getDrawDataId(drawdataNode->values["id"]);
|
||||||
|
|
||||||
|
if (id == -1) {
|
||||||
|
parserError("%d is not a valid DrawData set identifier.", drawdataNode->values["id"].c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawdataNode->values.contains("cached") && drawdataNode->values["cached"] == "true") {
|
||||||
|
cached = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawdataNode->values.contains("platform")) {
|
||||||
|
if (drawdataNode->values["platform"].compareToIgnoreCase(Common::getHostPlatformString()) != 0) {
|
||||||
|
drawdataNode->ignore = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_InterfaceManager.addDrawData(id, cached) == false) {
|
||||||
|
parserError("Repeated DrawData: Only one set of Drawing Data for a widget may be specified on each platform.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -321,6 +321,24 @@ protected:
|
||||||
bool parserCallback_DRAWSTEP();
|
bool parserCallback_DRAWSTEP();
|
||||||
bool parserCallback_DRAWDATA();
|
bool parserCallback_DRAWDATA();
|
||||||
|
|
||||||
|
bool validateKeyIntSigned(const char *key) {
|
||||||
|
if (!isdigit(*key) && *key != '+' && *key != '-')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return validateKeyInt(key + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validateKeyInt(const char *key) {
|
||||||
|
if (*key == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (*key)
|
||||||
|
if (!isdigit(*key++))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Graphics::DrawStep *newDrawStep();
|
Graphics::DrawStep *newDrawStep();
|
||||||
|
|
||||||
Common::HashMap<Common::String, DrawingFunctionCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _drawFunctions;
|
Common::HashMap<Common::String, DrawingFunctionCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _drawFunctions;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue