diff options
-rw-r--r-- | graphics/VectorRenderer.cpp | 8 | ||||
-rw-r--r-- | graphics/VectorRenderer.h | 23 | ||||
-rw-r--r-- | gui/ThemeDefaultXML.cpp | 17 | ||||
-rw-r--r-- | gui/ThemeParser.cpp | 73 | ||||
-rw-r--r-- | gui/ThemeParser.h | 2 | ||||
-rw-r--r-- | gui/ThemeRenderer.cpp | 259 | ||||
-rw-r--r-- | gui/ThemeRenderer.h | 45 | ||||
-rw-r--r-- | gui/newgui.cpp | 15 | ||||
-rw-r--r-- | gui/theme.h | 1 |
9 files changed, 292 insertions, 151 deletions
diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index f2ce0e26b8..70bcc1b2c3 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -65,7 +65,7 @@ void VectorRenderer::drawStep(const Common::Rect &area, const DrawStep &step, ui setGradientColors(step.gradColor1.r, step.gradColor1.g, step.gradColor1.b, step.gradColor2.r, step.gradColor2.g, step.gradColor2.b); - shadowEnable(step.shadow); + setShadowOffset(_disableShadows ? 0 : step.shadow); setGradientFactor(step.factor); setStrokeWidth(step.stroke); setFillMode((FillMode)step.fillMode); @@ -75,11 +75,13 @@ void VectorRenderer::drawStep(const Common::Rect &area, const DrawStep &step, ui (this->*(step.drawingCall))(area, step); } -void VectorRenderer::textStep(const Common::String &text, const Common::Rect &area, const TextStep &step) { +void VectorRenderer::textStep(const Common::String &text, const Common::Rect &area, const TextStep &step, GUI::Theme::TextAlign alignH) { if (step.color.set) setFgColor(step.color.r, step.color.g, step.color.b); - drawString(step.font, text.c_str(), area, step.alignHorizontal, step.alignVertical); + drawString(step.font, text.c_str(), area, + !step.hasAlign ? alignH : step.alignHorizontal, + !step.hasAlign ? GUI::Theme::kTextAlignVTop : step.alignVertical); } /******************************************************************** diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index e5fedd8ef5..c7ba0676b3 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -48,6 +48,7 @@ struct TextStep { GUI::Theme::TextAlign alignHorizontal; GUI::Theme::TextAlignVertical alignVertical; + bool hasAlign; char *text; const Graphics::Font *font; }; @@ -105,7 +106,7 @@ VectorRenderer *createRenderer(int mode); class VectorRenderer { public: VectorRenderer() : _shadowOffset(0), _fillMode(kFillDisabled), - _activeSurface(NULL), _strokeWidth(1), _gradientFactor(1) { + _activeSurface(NULL), _strokeWidth(1), _gradientFactor(1), _disableShadows(false) { } @@ -317,26 +318,16 @@ public: * Enables adding shadows to all drawn primitives. * Shadows are drawn automatically under the shapes. The given offset * controls their intensity and size (the higher the offset, the - * bigger the shadows). + * bigger the shadows). If the offset is 0, no shadows are drawn. * * @param offset Shadow offset. - * @see shadowDisable() */ - virtual void shadowEnable(int offset) { + virtual void setShadowOffset(int offset) { if (offset >= 0) _shadowOffset = offset; } /** - * Disables adding shadows to all drawn primitives. - * - * @see shadowEnable() - */ - virtual void shadowDisable() { - _shadowOffset = 0; - } - - /** * Sets the multiplication factor of the active gradient. * * @see _gradientFactor @@ -490,7 +481,7 @@ public: * @param step Pointer to a DrawStep struct. */ virtual void drawStep(const Common::Rect &area, const DrawStep &step, uint32 extra = 0); - virtual void textStep(const Common::String &text, const Common::Rect &area, const TextStep &step); + virtual void textStep(const Common::String &text, const Common::Rect &area, const TextStep &step, GUI::Theme::TextAlign alignH = GUI::Theme::kTextAlignLeft); /** * Copies the current surface to the system overlay @@ -511,6 +502,9 @@ public: virtual uint32 buildColor(uint8 r, uint8 g, uint8 b) = 0; virtual void drawString(const Graphics::Font *font, const Common::String &text, const Common::Rect &area, GUI::Theme::TextAlign alignH, GUI::Theme::TextAlignVertical alignV) = 0; + + virtual void disableShadows() { _disableShadows = true; } + virtual void enableShadows() { _disableShadows = false; } protected: Surface *_activeSurface; /** Pointer to the surface currently being drawn */ @@ -518,6 +512,7 @@ protected: FillMode _fillMode; /** Defines in which way (if any) are filled the drawn shapes */ int _shadowOffset; /** offset for drawn shadows */ + 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 */ diff --git a/gui/ThemeDefaultXML.cpp b/gui/ThemeDefaultXML.cpp index 8c8f46d2ec..afb559f950 100644 --- a/gui/ThemeDefaultXML.cpp +++ b/gui/ThemeDefaultXML.cpp @@ -46,8 +46,14 @@ bool ThemeRenderer::loadDefaultXML() { "<color name = 'text_hover' rgb = '255, 255, 255' />" "<color name = 'text_disabled' rgb = '128, 128, 128' />" "</palette>" + + "<fonts>" + "<font id = 'default' type = 'default' color = 'text_default' />" + "<font id = 'hover' type = 'default' color = 'text_hover' />" + "<font id = 'disabled' type = 'default' color = 'text_disabled' />" + "</fonts>" - "<default fill = 'gradient' fg_color = '255, 255, 255' />" + "<defaults fill = 'gradient' fg_color = '255, 255, 255' />" "<drawdata id = 'mainmenu_bg' cache = false>" "<drawstep func = 'fill' fill = 'gradient' gradient_start = '214, 113, 8' gradient_end = '240, 200, 25' />" @@ -71,7 +77,7 @@ bool ThemeRenderer::loadDefaultXML() { "<drawstep func = 'tab' radius = '4' stroke = '0' fill = 'foreground' fg_color = '206, 121, 99' shadow = 3 />" "</drawdata>" - "<drawdata id = 'slider_empty' cache = false>" + "<drawdata id = 'widget_slider' cache = false>" "<drawstep func = 'roundedsq' stroke = 1 radius = 8 fill = 'none' fg_color = '0, 0, 0' />" "</drawdata>" @@ -98,13 +104,18 @@ bool ThemeRenderer::loadDefaultXML() { "<drawdata id = 'button_idle' cache = false>" "<text vertical_align = 'center' horizontal_align = 'center' color = '173, 40, 8' />" - "<drawstep func = 'roundedsq' radius = '8' stroke = 0 fill = 'foreground' gradient_start = '206, 121, 99' gradient_end = '173, 40, 8' shadow = 3 />" + "<drawstep func = 'roundedsq' radius = '8' stroke = 0 fill = 'foreground' shadow = 3 />" "</drawdata>" "<drawdata id = 'button_hover' cache = false>" "<text vertical_align = 'center' horizontal_align = 'center' color = '255, 255, 255' />" "<drawstep func = 'roundedsq' radius = '8' stroke = '1' fill = 'gradient' gradient_start = '206, 121, 99' gradient_end = '173, 40, 8' shadow = 3 />" "</drawdata>" + + "<drawdata id = 'button_disabled' cache = false>" + "<text vertical_align = 'center' horizontal_align = 'center' color = '128, 128, 128' />" + "<drawstep func = 'roundedsq' radius = '8' stroke = 0 fill = 'foreground' fg_color = '200, 200, 200' shadow = 3 />" + "</drawdata>" "<drawdata id = 'checkbox_disabled' cache = false>" "<text vertical_align = 'top' horizontal_align = 'left' color = '0,0,0' />" diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index 014ed1fce9..c43da99ac1 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -47,8 +47,10 @@ ThemeParser::ThemeParser(ThemeRenderer *parent) : XMLParser() { _callbacks["color"] = &ThemeParser::parserCallback_color; _callbacks["render_info"] = &ThemeParser::parserCallback_renderInfo; _callbacks["layout_info"] = &ThemeParser::parserCallback_layoutInfo; - _callbacks["default"] = &ThemeParser::parserCallback_defaultSet; + _callbacks["defaults"] = &ThemeParser::parserCallback_defaultSet; _callbacks["text"] = &ThemeParser::parserCallback_text; + _callbacks["fonts"] = &ThemeParser::parserCallback_fonts; + _callbacks["font"] = &ThemeParser::parserCallback_font; _drawFunctions["circle"] = &Graphics::VectorRenderer::drawCallback_CIRCLE; _drawFunctions["square"] = &Graphics::VectorRenderer::drawCallback_SQUARE; @@ -146,6 +148,60 @@ bool ThemeParser::parserCallback_defaultSet() { return parseDrawStep(defNode, step, false); } +bool ThemeParser::parserCallback_font() { + ParserNode *tNode = getActiveNode(); + ParserNode *parentNode = getParentNode(tNode); + + if (parentNode == 0 || parentNode->name != "fonts") + return parserError("Text Steps must be contained inside <fonts> keys."); + + if (!tNode->values.contains("id")) + return parserError("Font definitions need a valid identifier."); + + if (!tNode->values.contains("type")) + return parserError("Font definitions need a valid typename."); + + // TODO: set typename on the drawstep. + + Graphics::TextStep step; + + if (tNode->values.contains("horizontal_align") || tNode->values.contains("vertical_align")) + return parserError("Font definitions cannot contain alignments."); + + int red, green, blue; + + if (tNode->values.contains("color")) { + + if (_palette.contains(tNode->values["color"])) + getPaletteColor(tNode->values["color"], red, green, blue); + else if (!parseIntegerKey(tNode->values["color"].c_str(), 3, &red, &green, &blue)) + return parserError("Error when parsing color value for font definition."); + + } else { + return parserError("Cannot assign color in font definition."); + } + + step.color.r = red; + step.color.g = green; + step.color.b = blue; + step.color.set = true; + step.hasAlign = false; + + if (!_theme->addTextStep(tNode->values["id"], step)) + return parserError("Error when loading Font in theme engine."); + + return true; +} + +bool ThemeParser::parserCallback_fonts() { + ParserNode *tNode = getActiveNode(); + + if (getParentNode(tNode) == 0 || getParentNode(tNode)->name != "render_info") + return parserError("Font definition keys must be contained inside a <render_info> section."); + + return true; +} + bool ThemeParser::parserCallback_text() { ParserNode *tNode = getActiveNode(); ParserNode *parentNode = getParentNode(tNode); @@ -174,24 +230,15 @@ bool ThemeParser::parserCallback_text() { step.alignVertical = GUI::Theme::kTextAlignVBottom; else return parserError("Invalid value for text alignment."); - Common::String paletteColor = "text_default"; int red, green, blue; - if (tNode->name.contains("hover")) - paletteColor = "text_hover"; - - if (tNode->name.contains("disabled")) - paletteColor = "text_disabled"; - if (tNode->values.contains("color")) { if (_palette.contains(tNode->values["color"])) getPaletteColor(tNode->values["color"], red, green, blue); else if (!parseIntegerKey(tNode->values["color"].c_str(), 3, &red, &green, &blue)) - return parserError("Error when parsing color value for text definition"); + return parserError("Error when parsing color value for text definition"); - } else if (_palette.contains(paletteColor)) { - getPaletteColor(paletteColor, red, green, blue); } else { return parserError("Cannot assign color for text drawing."); } @@ -200,9 +247,9 @@ bool ThemeParser::parserCallback_text() { step.color.g = green; step.color.b = blue; step.color.set = true; + step.hasAlign = true; - _theme->addTextStep(parentNode->values["id"], step); - return true; + return _theme->addTextStep(parentNode->values["id"], step); } bool ThemeParser::parserCallback_renderInfo() { diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h index 1e365a9433..59ba188fc1 100644 --- a/gui/ThemeParser.h +++ b/gui/ThemeParser.h @@ -340,6 +340,8 @@ protected: bool parserCallback_layoutInfo(); bool parserCallback_defaultSet(); bool parserCallback_text(); + bool parserCallback_fonts(); + bool parserCallback_font(); void cleanup(); diff --git a/gui/ThemeRenderer.cpp b/gui/ThemeRenderer.cpp index abc05e63ab..6c31dcf7a0 100644 --- a/gui/ThemeRenderer.cpp +++ b/gui/ThemeRenderer.cpp @@ -40,38 +40,36 @@ namespace GUI { using namespace Graphics; const ThemeRenderer::DrawDataInfo ThemeRenderer::kDrawData[] = { - {kDDMainDialogBackground, "mainmenu_bg", true}, - {kDDSpecialColorBackground, "special_bg", true}, - {kDDPlainColorBackground, "plain_bg", true}, - {kDDDefaultBackground, "default_bg", true}, + {kDDMainDialogBackground, "mainmenu_bg", true, kDDNone}, + {kDDSpecialColorBackground, "special_bg", true, kDDNone}, + {kDDPlainColorBackground, "plain_bg", true, kDDNone}, + {kDDDefaultBackground, "default_bg", true, kDDNone}, - {kDDWidgetBackgroundDefault, "widget_default", true}, - {kDDWidgetBackgroundSmall, "widget_small", true}, - {kDDWidgetBackgroundEditText, "widget_textedit", true}, - {kDDWidgetBackgroundSlider, "widget_slider", true}, + {kDDWidgetBackgroundDefault, "widget_default", true, kDDNone}, + {kDDWidgetBackgroundSmall, "widget_small", true, kDDNone}, + {kDDWidgetBackgroundEditText, "widget_textedit", true, kDDNone}, + {kDDWidgetBackgroundSlider, "widget_slider", true, kDDNone}, - {kDDButtonIdle, "button_idle", true}, - {kDDButtonHover, "button_hover", false}, - {kDDButtonDisabled, "button_disabled", true}, + {kDDButtonIdle, "button_idle", true, kDDNone}, + {kDDButtonHover, "button_hover", false, kDDButtonIdle}, + {kDDButtonDisabled, "button_disabled", true, kDDNone}, - {kDDSliderFull,"slider_full", false}, - {kDDSliderEmpty, "slider_empty", true}, + {kDDSliderFull, "slider_full", false, kDDWidgetBackgroundSlider}, - {kDDCheckboxEnabled, "checkbox_enabled", false}, - {kDDCheckboxDisabled, "checkbox_disabled", true}, + {kDDCheckboxEnabled, "checkbox_enabled", false, kDDCheckboxDisabled}, + {kDDCheckboxDisabled, "checkbox_disabled", true, kDDNone}, - {kDDTabActive, "tab_active", false}, - {kDDTabInactive, "tab_inactive", true}, + {kDDTabActive, "tab_active", false, kDDTabInactive}, + {kDDTabInactive, "tab_inactive", true, kDDNone}, - {kDDScrollbarBase, "scrollbar_base", true}, - {kDDScrollbarHandle, "scrollbar_handle", false}, + {kDDScrollbarBase, "scrollbar_base", true, kDDNone}, + {kDDScrollbarHandle, "scrollbar_handle", false, kDDScrollbarBase}, - {kDDPopUpIdle, "popup_idle", true}, - {kDDPopUpHover, "popup_hover", false}, + {kDDPopUpIdle, "popup_idle", true, kDDNone}, + {kDDPopUpHover, "popup_hover", false, kDDPopUpIdle}, - {kDDCaret, "caret", false}, - {kDDSeparator, "separator", true}, - {kDDDefaultText, "default_text", false} + {kDDCaret, "caret", false, kDDNone}, + {kDDSeparator, "separator", true, kDDNone}, }; @@ -196,13 +194,23 @@ void ThemeRenderer::addDrawStep(Common::String &drawDataId, Graphics::DrawStep s bool ThemeRenderer::addTextStep(Common::String &drawDataId, Graphics::TextStep step) { DrawData id = getDrawDataId(drawDataId); - assert(_widgets[id] != 0); - if (_widgets[id]->_hasText == true) - return false; - - _widgets[id]->_textStep = step; - _widgets[id]->_textStep.font = 0; - _widgets[id]->_hasText = true; + if (id != -1) { + assert(_widgets[id] != 0); + if (_widgets[id]->_hasText == true) + return false; + + _widgets[id]->_textStep = step; + _widgets[id]->_textStep.font = 0; + _widgets[id]->_hasText = true; + } else { + if (drawDataId == "default") { + _texts[kTextColorDefault] = step; + } else if (drawDataId == "hover") { + _texts[kTextColorHover] = step; + } else if (drawDataId == "disabled") { + _texts[kTextColorDisabled] = step; + } else return false; + } return true; } @@ -215,15 +223,15 @@ bool ThemeRenderer::addDrawData(DrawData data_id, bool cached) { _widgets[data_id] = new WidgetDrawData; _widgets[data_id]->_cached = cached; - _widgets[data_id]->_buffer = false; + _widgets[data_id]->_buffer = kDrawData[data_id].buffer; _widgets[data_id]->_surfaceCache = 0; _widgets[data_id]->_hasText = false; // TODO: set this only when needed // possibly add an option to the parser to set this // on each drawdata... - if (data_id >= kDDMainDialogBackground && data_id <= kDDWidgetBackgroundSlider) - _widgets[data_id]->_buffer = true; +// if (data_id >= kDDMainDialogBackground && data_id <= kDDWidgetBackgroundSlider) +// _widgets[data_id]->_buffer = true; return true; } @@ -255,19 +263,6 @@ bool ThemeRenderer::loadTheme(Common::String themeName) { } } - int r, g, b; - -#define __LOAD_COLOR(id, name) { \ - if (parser()->getPaletteColor(name, r, g, b))\ - _textColors[id] = _vectorRenderer->buildColor(r, g, b); \ -} - - __LOAD_COLOR(kTextColorDefault, "text_default"); - __LOAD_COLOR(kTextColorHover, "text_hover"); - __LOAD_COLOR(kTextColorDisabled, "text_disabled"); - -#undef __LOAD_COLOR - _themeOk = true; return true; } @@ -302,42 +297,82 @@ void ThemeRenderer::drawCached(DrawData type, const Common::Rect &r) { _vectorRenderer->blitSurface(_widgets[type]->_surfaceCache, r); } -void ThemeRenderer::drawDD(DrawData type, const Common::Rect &r, uint32 dynamicData) { +void ThemeRenderer::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic) { if (_widgets[type] == 0) return; + + DrawQueue q; + q.type = type; + q.area = r; + q.dynData = dynamic; + + if (_buffering) { + warning("Queued up a '%s' for the %s", kDrawData[type].name, _widgets[type]->_buffer ? "buffer" : "screen"); + + if (_widgets[type]->_buffer) + _bufferQueue.push_back(q); + else { + if (kDrawData[type].parent != kDDNone) + queueDD(kDrawData[type].parent, r); - Common::Rect extendedRect = r; - extendedRect.grow(kDirtyRectangleThreshold); - extendedRect.right += _widgets[type]->_backgroundOffset; - extendedRect.bottom += _widgets[type]->_backgroundOffset; - - if (_buffering && _widgets[type]->_buffer) - _vectorRenderer->setSurface(_backBuffer); - else - restoreBackground(extendedRect); + _screenQueue.push_back(q); + } + } else { + warning("Drawing a '%s' directly!", kDrawData[type].name); + drawDD(q, !_widgets[type]->_buffer, _widgets[type]->_buffer); + } +} - addDirtyRect(extendedRect); +void ThemeRenderer::queueDDText(DrawData type, const Common::Rect &r, const Common::String &text, TextColor colorId, TextAlign align) { + if (!hasWidgetText(type)) + return; - if (isWidgetCached(type, r)) { - drawCached(type, r); + DrawQueueText q; + q.type = type; + q.area = r; + q.text = text; + q.colorId = colorId; + q.align = align; + + if (_buffering) { + _textQueue.push_back(q); } else { - for (Common::List<Graphics::DrawStep>::const_iterator step = _widgets[type]->_steps.begin(); - step != _widgets[type]->_steps.end(); ++step) - _vectorRenderer->drawStep(r, *step, dynamicData); + drawDDText(q); } +} - if (_buffering && _widgets[type]->_buffer) { - _vectorRenderer->setSurface(_screen); - memcpy(_screen->pixels, _backBuffer->pixels, _screen->w * _screen->h * _screen->bytesPerPixel); +void ThemeRenderer::drawDD(const DrawQueue &q, bool draw, bool restore) { + Common::Rect extendedRect = q.area; + extendedRect.grow(kDirtyRectangleThreshold); + extendedRect.right += _widgets[q.type]->_backgroundOffset; + extendedRect.bottom += _widgets[q.type]->_backgroundOffset; + + if (restore) + restoreBackground(extendedRect); + + if (draw) { + if (isWidgetCached(q.type, q.area)) { + drawCached(q.type, q.area); + } else { + for (Common::List<Graphics::DrawStep>::const_iterator step = _widgets[q.type]->_steps.begin(); + step != _widgets[q.type]->_steps.end(); ++step) + _vectorRenderer->drawStep(q.area, *step, q.dynData); + } } + + addDirtyRect(extendedRect); } -void ThemeRenderer::drawDDText(DrawData type, const Common::Rect &r, const Common::String &text) { - if (hasWidgetText(type)) { - if (_widgets[type]->_textStep.font == 0) - _widgets[type]->_textStep.font = _font; +void ThemeRenderer::drawDDText(const DrawQueueText &q) { + restoreBackground(q.area); + + if (q.type == kDDNone) { + _vectorRenderer->textStep(q.text, q.area, _texts[q.colorId], q.align); + } else { + if (_widgets[q.type]->_textStep.font == 0) + _widgets[q.type]->_textStep.font = _font; - _vectorRenderer->textStep(text, r, _widgets[type]->_textStep); + _vectorRenderer->textStep(q.text, q.area, _widgets[q.type]->_textStep); } } @@ -381,15 +416,15 @@ void ThemeRenderer::drawButton(const Common::Rect &r, const Common::String &str, else if (state == kStateDisabled) dd = kDDButtonDisabled; - drawDD(dd, r); - drawDDText(dd, r, str); + queueDD(dd, r); + queueDDText(dd, r, str); } void ThemeRenderer::drawLineSeparator(const Common::Rect &r, WidgetStateInfo state) { if (!ready()) return; - drawDD(kDDSeparator, r); + queueDD(kDDSeparator, r); } void ThemeRenderer::drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) { @@ -402,31 +437,29 @@ void ThemeRenderer::drawCheckbox(const Common::Rect &r, const Common::String &st r2.bottom = r2.top + checkBoxSize; r2.right = r2.left + checkBoxSize; - drawDD(checked ? kDDCheckboxEnabled : kDDCheckboxDisabled, r2); + queueDD(checked ? kDDCheckboxEnabled : kDDCheckboxDisabled, r2); r2.left = r2.right + checkBoxSize; r2.right = r.right; - drawDDText(checked ? kDDCheckboxEnabled : kDDCheckboxDisabled, r2, str); + queueDDText(checked ? kDDCheckboxEnabled : kDDCheckboxDisabled, r2, str); } void ThemeRenderer::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) { if (!ready()) return; - drawDD(kDDSliderEmpty, r); - Common::Rect r2 = r; r2.setWidth(MIN((int16)width, r.width())); - drawDD(kDDSliderFull, r2); + queueDD(kDDSliderFull, r2); } void ThemeRenderer::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, ScrollbarState sb_state, WidgetStateInfo state) { if (!ready()) return; - drawDD(kDDScrollbarBase, r); + queueDD(kDDScrollbarBase, r); // TODO: Need to find a scrollbar in the GUI for testing... :p } @@ -435,13 +468,13 @@ void ThemeRenderer::drawDialogBackground(const Common::Rect &r, uint16 hints, Wi return; if (hints & THEME_HINT_MAIN_DIALOG) { - drawDD(kDDMainDialogBackground, r); + queueDD(kDDMainDialogBackground, r); } else if (hints & THEME_HINT_SPECIAL_COLOR) { - drawDD(kDDSpecialColorBackground, r); + queueDD(kDDSpecialColorBackground, r); } else if (hints & THEME_HINT_PLAIN_COLOR) { - drawDD(kDDPlainColorBackground, r); + queueDD(kDDPlainColorBackground, r); } else { - drawDD(kDDDefaultBackground, r); + queueDD(kDDDefaultBackground, r); } } @@ -458,11 +491,11 @@ void ThemeRenderer::drawPopUpWidget(const Common::Rect &r, const Common::String DrawData dd = (state == kStateHighlight) ? kDDPopUpHover : kDDPopUpIdle; - drawDD(dd, r); + queueDD(dd, r); if (!sel.empty()) { Common::Rect text(r.left, r.top, r.right - 16, r.bottom); - drawDDText(dd, text, sel); + queueDDText(dd, text, sel); } } @@ -479,19 +512,19 @@ void ThemeRenderer::drawWidgetBackground(const Common::Rect &r, uint16 hints, Wi switch (background) { case kWidgetBackgroundBorderSmall: - drawDD(kDDWidgetBackgroundSmall, r); + queueDD(kDDWidgetBackgroundSmall, r); break; case kWidgetBackgroundEditText: - drawDD(kDDWidgetBackgroundEditText, r); + queueDD(kDDWidgetBackgroundEditText, r); break; case kWidgetBackgroundSlider: - drawDD(kDDWidgetBackgroundSlider, r); + queueDD(kDDWidgetBackgroundSlider, r); break; default: - drawDD(kDDWidgetBackgroundDefault, r); + queueDD(kDDWidgetBackgroundDefault, r); break; } } @@ -507,16 +540,16 @@ void ThemeRenderer::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, continue; Common::Rect tabRect(r.left + i * (tabWidth + tabOffset), r.top, r.left + i * (tabWidth + tabOffset) + tabWidth, r.top + tabHeight); - drawDD(kDDTabInactive, tabRect); - drawDDText(kDDTabInactive, tabRect, tabs[i]); + queueDD(kDDTabInactive, tabRect); + queueDDText(kDDTabInactive, tabRect, tabs[i]); } 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 = r.right - tabRect.right; - drawDD(kDDTabActive, tabRect, (tabLeft << 16) | (tabRight & 0xFFFF)); - drawDDText(kDDTabActive, tabRect, tabs[active]); + queueDD(kDDTabActive, tabRect, (tabLeft << 16) | (tabRight & 0xFFFF)); + queueDDText(kDDTabActive, tabRect, tabs[active]); } } @@ -524,12 +557,14 @@ void ThemeRenderer::drawText(const Common::Rect &r, const Common::String &str, W if (!_initOk) return; - restoreBackground(r); - getFont(font)->drawString(_screen, str, r.left, r.top, r.width(), getTextColor(state), convertAligment(align), deltax, useEllipsis); - addDirtyRect(r); + // TODO: Queue this up too! + // restoreBackground(r); + // getFont(font)->drawString(_screen, str, r.left, r.top, r.width(), getTextColor(state), convertAligment(align), deltax, useEllipsis); + // addDirtyRect(r); + + queueDDText(kDDNone, r, str, getTextColor(state), align); } - void ThemeRenderer::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); @@ -540,6 +575,34 @@ void ThemeRenderer::debugWidgetPosition(const char *name, const Common::Rect &r) void ThemeRenderer::updateScreen() { // renderDirtyScreen(); + + if (!_bufferQueue.empty()) { + _vectorRenderer->setSurface(_backBuffer); + + for (Common::List<DrawQueue>::const_iterator q = _bufferQueue.begin(); q != _bufferQueue.end(); ++q) + drawDD(*q, true, false); + + _vectorRenderer->setSurface(_screen); + _bufferQueue.clear(); + memcpy(_screen->pixels, _backBuffer->pixels, _screen->w * _screen->h * _screen->bytesPerPixel); + } + + if (!_screenQueue.empty()) { + _vectorRenderer->disableShadows(); + for (Common::List<DrawQueue>::const_iterator q = _screenQueue.begin(); q != _screenQueue.end(); ++q) + drawDD(*q, true, false); + + _vectorRenderer->enableShadows(); + _screenQueue.clear(); + } + + if (!_textQueue.empty()) { + for (Common::List<DrawQueueText>::const_iterator q = _textQueue.begin(); q != _textQueue.end(); ++q) + drawDDText(*q); + + _textQueue.clear(); + } + _vectorRenderer->copyWholeFrame(_system); } diff --git a/gui/ThemeRenderer.h b/gui/ThemeRenderer.h index e01d31e00f..74b9cb0f5b 100644 --- a/gui/ThemeRenderer.h +++ b/gui/ThemeRenderer.h @@ -111,7 +111,6 @@ public: kDDButtonDisabled, kDDSliderFull, - kDDSliderEmpty, kDDCheckboxEnabled, kDDCheckboxDisabled, @@ -127,11 +126,12 @@ public: kDDCaret, kDDSeparator, - kDDDefaultText, - kDrawDataMAX + kDrawDataMAX, + kDDNone = -1 }; enum TextColor { + kTextColorNone = -1, kTextColorDefault, kTextColorHover, kTextColorDisabled, @@ -143,6 +143,21 @@ public: DrawData id; const char *name; bool buffer; + DrawData parent; + }; + + struct DrawQueue { + DrawData type; + Common::Rect area; + uint32 dynData; + }; + + struct DrawQueueText { + DrawData type; + Common::Rect area; + Common::String text; + TextColor colorId; + TextAlign align; }; static const DrawDataInfo kDrawData[]; @@ -205,7 +220,7 @@ public: if (name.compareToIgnoreCase(kDrawData[i].name) == 0) return kDrawData[i].id; - return (DrawData)-1; + return kDDNone; } void addDrawStep(Common::String &drawDataId, Graphics::DrawStep step); @@ -283,8 +298,12 @@ protected: void drawCached(DrawData type, const Common::Rect &r); void calcBackgroundOffset(DrawData type); - inline void drawDD(DrawData type, const Common::Rect &r, uint32 dynamicData = 0); - inline void drawDDText(DrawData type, const Common::Rect &r, const Common::String &text); + inline void drawDD(const DrawQueue &q, bool draw = true, bool restore = false); + inline void drawDDText(const DrawQueueText &q); + inline void queueDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0); + inline void queueDDText(DrawData type, const Common::Rect &r, const Common::String &text, + TextColor colorId = kTextColorNone, TextAlign align = kTextAlignLeft); + inline void debugWidgetPosition(const char *name, const Common::Rect &r); // TODO @@ -298,16 +317,16 @@ protected: return 3; } - uint32 getTextColor(WidgetStateInfo state) { + TextColor getTextColor(WidgetStateInfo state) { switch (state) { case kStateDisabled: - return _textColors[kTextColorDisabled]; + return kTextColorDisabled; case kStateHighlight: - return _textColors[kTextColorHover]; + return kTextColorHover; default: - return _textColors[kTextColorDefault]; + return kTextColorDefault; } } @@ -324,10 +343,14 @@ protected: Common::String _fontName; const Graphics::Font *_font; - uint32 _textColors[kTextColorMAX]; WidgetDrawData *_widgets[kDrawDataMAX]; + Graphics::TextStep _texts[kTextColorMAX]; Common::Array<Common::Rect> _dirtyScreen; + + Common::List<DrawQueue> _bufferQueue; + Common::List<DrawQueue> _screenQueue; + Common::List<DrawQueueText> _textQueue; bool _initOk; bool _themeOk; diff --git a/gui/newgui.cpp b/gui/newgui.cpp index c4fafe7e22..e689617418 100644 --- a/gui/newgui.cpp +++ b/gui/newgui.cpp @@ -193,25 +193,22 @@ void NewGui::redraw() { switch (_redrawStatus) { case kRedrawCloseDialog: case kRedrawFull: + case kRedrawTopDialog: + warning("Full screen redraw. Oops"); _theme->clearAll(); _theme->closeAllDialogs(); - for (i = 0; i < _dialogStack.size(); i++) { - _theme->openDialog(true); + for (i = 0; i < _dialogStack.size() - 1; i++) { _dialogStack[i]->drawDialog(); } - break; case kRedrawOpenDialog: _theme->openDialog(true); + //_theme->startBuffering(); _dialogStack.top()->drawDialog(); _theme->finishBuffering(); - printf("Dialog opened!\n"); - break; - - case kRedrawTopDialog: - _dialogStack.top()->drawDialog(); - printf("Top dialog redraw!\n"); + + warning("Dialog opened"); break; default: diff --git a/gui/theme.h b/gui/theme.h index a55f04b115..e2b0d39fd3 100644 --- a/gui/theme.h +++ b/gui/theme.h @@ -251,6 +251,7 @@ public: * the dialog stack from scratch. */ virtual bool closeDialog() { return false; } + virtual void startBuffering() {} virtual void finishBuffering() {} /** |