From 9aa07d206e679179f939e9beb0d441eb0c1a1fcb Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Sun, 20 Jul 2008 21:47:28 +0000
Subject: Rendering pipeline. Broken WIP.
svn-id: r33152
---
graphics/VectorRenderer.cpp | 8 +-
graphics/VectorRenderer.h | 23 ++--
gui/ThemeDefaultXML.cpp | 17 ++-
gui/ThemeParser.cpp | 73 ++++++++++---
gui/ThemeParser.h | 2 +
gui/ThemeRenderer.cpp | 259 +++++++++++++++++++++++++++-----------------
gui/ThemeRenderer.h | 45 ++++++--
gui/newgui.cpp | 15 +--
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,25 +318,15 @@ 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.
*
@@ -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() {
""
""
""
+
+ ""
+ ""
+ ""
+ ""
+ ""
- ""
+ ""
""
""
@@ -71,7 +77,7 @@ bool ThemeRenderer::loadDefaultXML() {
""
""
- ""
+ ""
""
""
@@ -98,13 +104,18 @@ bool ThemeRenderer::loadDefaultXML() {
""
""
- ""
+ ""
""
""
""
""
""
+
+ ""
+ ""
+ ""
+ ""
""
""
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 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 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::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::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::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::const_iterator q = _screenQueue.begin(); q != _screenQueue.end(); ++q)
+ drawDD(*q, true, false);
+
+ _vectorRenderer->enableShadows();
+ _screenQueue.clear();
+ }
+
+ if (!_textQueue.empty()) {
+ for (Common::List::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 _dirtyScreen;
+
+ Common::List _bufferQueue;
+ Common::List _screenQueue;
+ Common::List _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() {}
/**
--
cgit v1.2.3