diff options
| author | Vicent Marti | 2008-06-24 19:48:01 +0000 |
|---|---|---|
| committer | Vicent Marti | 2008-06-24 19:48:01 +0000 |
| commit | 8caa7d3f8b1146fafc6dff6de4f801eb2e8b61ae (patch) | |
| tree | 896c10a542fd3c4169ac8c0d218552f84834a02b /gui | |
| parent | a4b4534a66bb6f24a66a27e28f7df0d390e1eea8 (diff) | |
| download | scummvm-rg350-8caa7d3f8b1146fafc6dff6de4f801eb2e8b61ae.tar.gz scummvm-rg350-8caa7d3f8b1146fafc6dff6de4f801eb2e8b61ae.tar.bz2 scummvm-rg350-8caa7d3f8b1146fafc6dff6de4f801eb2e8b61ae.zip | |
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
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/InterfaceManager.cpp | 51 | ||||
| -rw-r--r-- | gui/InterfaceManager.h | 9 | ||||
| -rw-r--r-- | gui/ThemeParser.cpp | 111 | ||||
| -rw-r--r-- | gui/ThemeParser.h | 18 |
4 files changed, 176 insertions, 13 deletions
diff --git a/gui/InterfaceManager.cpp b/gui/InterfaceManager.cpp index dc2250a2bd..5ee3a014ed 100644 --- a/gui/InterfaceManager.cpp +++ b/gui/InterfaceManager.cpp @@ -38,11 +38,44 @@ namespace GUI { 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() : _vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled), _screen(0), _bytesPerPixel(0) { _system = g_system; + for (int i = 0; i < kDrawDataMAX; ++i) { + _widgets[i] = 0; + } + setGraphicsMode(kGfxStandard16bit); } @@ -78,9 +111,25 @@ void InterfaceManager::setGraphicsMode(Graphics_Mode mode) { } 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() { return false; diff --git a/gui/InterfaceManager.h b/gui/InterfaceManager.h index f5efb105ec..00441a9efc 100644 --- a/gui/InterfaceManager.h +++ b/gui/InterfaceManager.h @@ -47,6 +47,8 @@ class InterfaceManager : public Common::Singleton<InterfaceManager> { friend class Common::Singleton<SingletonBaseType>; typedef Common::String String; + static const char *kDrawDataStrings[]; + public: enum Graphics_Mode { kGfxDisabled = 0, @@ -168,10 +170,15 @@ public: void drawLineSeparator(const Common::Rect &r, WidgetStateInfo state = kStateEnabled); 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); + bool addDrawData(DrawData data_id, bool cached); protected: template<typename PixelType> void screenInit(); diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index 9f029a874e..afc623c3d8 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -42,6 +42,15 @@ using namespace Common; ThemeParser::ThemeParser() : XMLParser() { _callbacks["drawstep"] = &ThemeParser::parserCallback_DRAWSTEP; _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) { @@ -73,8 +82,12 @@ Graphics::DrawStep *ThemeParser::newDrawStep() { } bool ThemeParser::parserCallback_DRAWSTEP() { - ParserNode *stepNode = _activeKey.pop(); - ParserNode *drawdataNode = _activeKey.pop(); + ParserNode *stepNode = _activeKey.top(); + + // 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(drawdataNode->name == "drawdata"); @@ -85,32 +98,108 @@ bool ThemeParser::parserCallback_DRAWSTEP() { Common::String functionName = stepNode->values["func"]; if (_drawFunctions.contains(functionName) == false) { - parserError("Invalid drawing function in draw step."); - _activeKey.push(drawdataNode); - _activeKey.push(stepNode); + parserError("%s is not a valid drawing function name", functionName.c_str()); return false; } 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()); \ + } + +/** + * 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; \ } - if (functionName == "roundedsq") { + __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"); } - g_InterfaceManager.addDrawStep(drawdataNode->values["id"], drawstep); + if (functionName == "bevelsq") { + __PARSER_ASSIGN_INT(extraData, "bevel"); + } - _activeKey.push(drawdataNode); - _activeKey.push(stepNode); +#undef __PARSER_ASSIGN_INT +#undef __PARSER_ASSIGN_RGB + g_InterfaceManager.addDrawStep(drawdataNode->values["id"], drawstep); return true; } 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; } diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h index 108a7263ba..4103098a63 100644 --- a/gui/ThemeParser.h +++ b/gui/ThemeParser.h @@ -321,6 +321,24 @@ protected: bool parserCallback_DRAWSTEP(); 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(); Common::HashMap<Common::String, DrawingFunctionCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _drawFunctions; |
