Tab widget / tab drawing for the renderer. Improved text handling.

svn-id: r33076
This commit is contained in:
Vicent Marti 2008-07-15 18:53:22 +00:00
parent b44b37d4ca
commit 47119ee8b1
6 changed files with 146 additions and 22 deletions

View file

@ -352,7 +352,7 @@ template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>:: void VectorRendererSpec<PixelType, PixelFormat>::
drawRoundedSquare(int x, int y, int r, int w, int h) { drawRoundedSquare(int x, int y, int r, int w, int h) {
if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h || if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h ||
w <= 0 || h <= 0 || x < 0 || y < 0 || r <= 0 || r > 128 || (r << 1) > w || (r << 1) > h) w <= 0 || h <= 0 || x < 0 || y < 0 || (r << 1) > w || (r << 1) > h)
return; return;
if (Base::_fillMode != kFillDisabled && Base::_shadowOffset if (Base::_fillMode != kFillDisabled && Base::_shadowOffset
@ -390,6 +390,25 @@ drawRoundedSquare(int x, int y, int r, int w, int h) {
} }
} }
template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>::
drawTab(int x, int y, int r, int w, int h) {
if (x + w > Base::_activeSurface->w || y + h > Base::_activeSurface->h ||
w <= 0 || h <= 0 || x < 0 || y < 0 || (r << 1) > w || (r << 1) > h)
return;
switch (Base::_fillMode) {
case kFillDisabled:
return;
case kFillGradient:
case kFillForeground:
case kFillBackground:
drawTabAlg(x, y, w, h, r, (Base::_fillMode == kFillBackground) ? _bgColor : _fgColor, Base::_fillMode);
break;
}
}
template<typename PixelType, typename PixelFormat> template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>:: void VectorRendererSpec<PixelType, PixelFormat>::
drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) { drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) {
@ -421,7 +440,7 @@ drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) {
#ifdef VECTOR_RENDERER_FAST_TRIANGLES #ifdef VECTOR_RENDERER_FAST_TRIANGLES
if (w == h) if (w == h)
drawTriangleFast(x, y, w, (orient == kTriangleDown), color, Base::_fillMode); drawTriangleFast(x, y, w, (orient == kTriangleDown), color, Base::_fillMode);
else else
#endif #endif
drawTriangleVertAlg(x, y, w, h, (orient == kTriangleDown), color, Base::_fillMode); drawTriangleVertAlg(x, y, w, h, (orient == kTriangleDown), color, Base::_fillMode);
break; break;
@ -445,6 +464,54 @@ drawTriangle(int x, int y, int w, int h, TriangleOrientation orient) {
/******************************************************************** /********************************************************************
* Aliased Primitive drawing ALGORITHMS - VectorRendererSpec * Aliased Primitive drawing ALGORITHMS - VectorRendererSpec
********************************************************************/ ********************************************************************/
/** TAB ALGORITHM - NON AA */
template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>::
drawTabAlg(int x1, int y1, int w, int h, int r, PixelType color, VectorRenderer::FillMode fill_m) {
int f, ddF_x, ddF_y;
int x, y, px, py;
int pitch = Base::surfacePitch();
PixelType *ptr_tl = (PixelType *)Base::_activeSurface->getBasePtr(x1 + r, y1 + r);
PixelType *ptr_tr = (PixelType *)Base::_activeSurface->getBasePtr(x1 + w - r, y1 + r);
PixelType *ptr_fill = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
int real_radius = r;
int short_h = h - (r) + 2;
int long_h = h;
__BE_RESET();
PixelType color1, color2;
if (fill_m == kFillForeground || fill_m == kFillBackground)
color1 = color2 = color;
while (x++ < y) {
__BE_ALGORITHM();
if (fill_m == kFillGradient) {
color1 = calcGradient(real_radius - x, long_h);
color2 = calcGradient(real_radius - y, long_h);
}
colorFill(ptr_tl - x - py, ptr_tr + x - py, color2);
colorFill(ptr_tl - y - px, ptr_tr + y - px, color1);
*(ptr_tr + (y) - (px)) = color;
*(ptr_tr + (x) - (py)) = color;
*(ptr_tl - (x) - (py)) = color;
*(ptr_tl - (y) - (px)) = color;
}
ptr_fill += pitch * r;
while (short_h--) {
if (fill_m == kFillGradient)
color = calcGradient(real_radius++, long_h);
colorFill(ptr_fill, ptr_fill + w + 1, color);
ptr_fill += pitch;
}
}
/** SQUARE ALGORITHM **/ /** SQUARE ALGORITHM **/
template<typename PixelType, typename PixelFormat> template<typename PixelType, typename PixelFormat>
void VectorRendererSpec<PixelType, PixelFormat>:: void VectorRendererSpec<PixelType, PixelFormat>::

View file

@ -192,6 +192,19 @@ public:
* @param bevel Amount of bevel. Must be positive. * @param bevel Amount of bevel. Must be positive.
*/ */
virtual void drawBeveledSquare(int x, int y, int w, int h, int bevel) = 0; virtual void drawBeveledSquare(int x, int y, int w, int h, int bevel) = 0;
/**
* Draws a tab-like shape, specially thought for the Tab widget.
* If a radius is given, the tab will have rounded corners. Otherwise,
* the tab will be squared.
*
* @param x Horizontal (X) coordinate for the tab
* @param y Vertical (Y) coordinate for the tab
* @param w Width of the tab
* @param h Height of the tab
* @param r Radius of the corners of the tab (0 for squared tabs).
*/
virtual void drawTab(int x, int y, int r, int w, int h) = 0;
/** /**
* Gets the pixel pitch for the current drawing surface. * Gets the pixel pitch for the current drawing surface.
@ -460,6 +473,12 @@ public:
stepGetPositions(step, area, x, y, w, h); stepGetPositions(step, area, x, y, w, h);
drawBeveledSquare(x, y, w, h, step.extraData); drawBeveledSquare(x, y, w, h, step.extraData);
} }
void drawCallback_TAB(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
drawTab(x, y, stepGetRadius(step, area), w, h);
}
void drawCallback_VOID(const Common::Rect &area, const DrawStep &step) {} void drawCallback_VOID(const Common::Rect &area, const DrawStep &step) {}
@ -553,6 +572,11 @@ public:
* @see VectorRenderer::drawTriangle() * @see VectorRenderer::drawTriangle()
*/ */
void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient); void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient);
/**
* @see VectorRenderer::drawTab()
*/
void drawTab(int x, int y, int r, int w, int h);
void drawBeveledSquare(int x, int y, int w, int h, int bevel) { void drawBeveledSquare(int x, int y, int w, int h, int bevel) {
drawBevelSquareAlg(x, y, w, h, bevel, _fgColor, _bgColor); drawBevelSquareAlg(x, y, w, h, bevel, _fgColor, _bgColor);
@ -739,6 +763,7 @@ protected:
virtual void drawTriangleVertAlg(int x, int y, int w, int h, bool inverted, PixelType color, FillMode fill_m); virtual void drawTriangleVertAlg(int x, int y, int w, int h, bool inverted, PixelType color, FillMode fill_m);
virtual void drawTriangleFast(int x, int y, int size, bool inverted, PixelType color, FillMode fill_m); virtual void drawTriangleFast(int x, int y, int size, bool inverted, PixelType color, FillMode fill_m);
virtual void drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color); virtual void drawBevelSquareAlg(int x, int y, int w, int h, int bevel, PixelType top_color, PixelType bottom_color);
virtual void drawTabAlg(int x, int y, int w, int h, int r, PixelType color, VectorRenderer::FillMode fill_m);
/** /**
* SHADOW DRAWING ALGORITHMS * SHADOW DRAWING ALGORITHMS

View file

@ -61,6 +61,24 @@ bool ThemeRenderer::loadDefaultXML() {
"<drawstep func = 'roundedsq' stroke = 1 radius = 4 fill = 'none' fg_color = '255, 255, 255' />" "<drawstep func = 'roundedsq' stroke = 1 radius = 4 fill = 'none' fg_color = '255, 255, 255' />"
"</drawdata>" "</drawdata>"
"<drawdata id = 'tab_active' cache = false>"
"<text vertical_align = 'center' horizontal_align = 'center' color = '255, 255, 255' />"
"<drawstep func = 'tab' radius = '8' stroke = '0' fill = 'gradient' gradient_start = '206, 121, 99' gradient_end = '173, 40, 8' shadow = 3 />"
"</drawdata>"
"<drawdata id = 'tab_inactive' cache = false>"
"<text vertical_align = 'center' horizontal_align = 'center' color = '255, 255, 255' />"
"<drawstep func = 'tab' radius = '8' stroke = '0' fill = 'foreground' fg_color = '206, 121, 99' shadow = 3 />"
"</drawdata>"
"<drawdata id = 'slider_empty' cache = false>"
"<drawstep func = 'roundedsq' stroke = 1 radius = 8 fill = 'none' fg_color = '0, 0, 0' />"
"</drawdata>"
"<drawdata id = 'slider_full' cache = false>"
"<drawstep func = 'roundedsq' stroke = 1 radius = 8 fill = 'gradient' fg_color = '0, 0, 0' gradient_start = '214, 113, 8' gradient_end = '240, 200, 25' />"
"</drawdata>"
"<drawdata id = 'popup_idle' cache = false>" "<drawdata id = 'popup_idle' cache = false>"
"<drawstep func = 'square' stroke = 0 fg_color = '0, 0, 0' fill = 'gradient' gradient_start = '214, 113, 8' gradient_end = '240, 200, 25' shadow = 3 />" "<drawstep func = 'square' stroke = 0 fg_color = '0, 0, 0' fill = 'gradient' gradient_start = '214, 113, 8' gradient_end = '240, 200, 25' shadow = 3 />"
"<drawstep func = 'triangle' fg_color = '0, 0, 0' fill = 'foreground' width = '12' height = '12' xpos = '-16' ypos = 'center' orientation = 'bottom' />" "<drawstep func = 'triangle' fg_color = '0, 0, 0' fill = 'foreground' width = '12' height = '12' xpos = '-16' ypos = 'center' orientation = 'bottom' />"

View file

@ -57,6 +57,7 @@ ThemeParser::ThemeParser(ThemeRenderer *parent) : XMLParser() {
_drawFunctions["line"] = &Graphics::VectorRenderer::drawCallback_LINE; _drawFunctions["line"] = &Graphics::VectorRenderer::drawCallback_LINE;
_drawFunctions["triangle"] = &Graphics::VectorRenderer::drawCallback_TRIANGLE; _drawFunctions["triangle"] = &Graphics::VectorRenderer::drawCallback_TRIANGLE;
_drawFunctions["fill"] = &Graphics::VectorRenderer::drawCallback_FILLSURFACE; _drawFunctions["fill"] = &Graphics::VectorRenderer::drawCallback_FILLSURFACE;
_drawFunctions["tab"] = &Graphics::VectorRenderer::drawCallback_TAB;
_drawFunctions["void"] = &Graphics::VectorRenderer::drawCallback_VOID; _drawFunctions["void"] = &Graphics::VectorRenderer::drawCallback_VOID;
_defaultStepGlobal = defaultDrawStep(); _defaultStepGlobal = defaultDrawStep();
@ -199,7 +200,7 @@ bool ThemeParser::parserCallback_text() {
step.color.g = green; step.color.g = green;
step.color.b = blue; step.color.b = blue;
step.color.set = true; step.color.set = true;
_theme->addTextStep(parentNode->values["id"], step); _theme->addTextStep(parentNode->values["id"], step);
return true; return true;
} }
@ -407,7 +408,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
assert(stepNode->values.contains("func")); assert(stepNode->values.contains("func"));
Common::String functionName = stepNode->values["func"]; Common::String functionName = stepNode->values["func"];
if (functionName == "roundedsq" || functionName == "circle") { if (functionName == "roundedsq" || functionName == "circle" || functionName == "tab") {
if (stepNode->values.contains("radius") && stepNode->values["radius"] == "auto") { if (stepNode->values.contains("radius") && stepNode->values["radius"] == "auto") {
drawstep->radius = 0xFF; drawstep->radius = 0xFF;
} else { } else {

View file

@ -60,7 +60,8 @@ const char *ThemeRenderer::kDrawDataStrings[] = {
"checkbox_enabled", "checkbox_enabled",
"checkbox_disabled", "checkbox_disabled",
"tab", "tab_active",
"tab_inactive",
"scrollbar_base", "scrollbar_base",
"scrollbar_handle", "scrollbar_handle",
@ -322,7 +323,6 @@ void ThemeRenderer::drawButton(const Common::Rect &r, const Common::String &str,
drawDDText(dd, r, str); drawDDText(dd, r, str);
addDirtyRect(r); addDirtyRect(r);
debugWidgetPosition("BTN", r);
} }
void ThemeRenderer::drawLineSeparator(const Common::Rect &r, WidgetStateInfo state) { void ThemeRenderer::drawLineSeparator(const Common::Rect &r, WidgetStateInfo state) {
@ -331,8 +331,6 @@ void ThemeRenderer::drawLineSeparator(const Common::Rect &r, WidgetStateInfo sta
drawDD(kDDSeparator, r); drawDD(kDDSeparator, r);
addDirtyRect(r); addDirtyRect(r);
debugWidgetPosition("Separator", r);
} }
void ThemeRenderer::drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) { void ThemeRenderer::drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) {
@ -353,7 +351,6 @@ void ThemeRenderer::drawCheckbox(const Common::Rect &r, const Common::String &st
drawDDText(checked ? kDDCheckboxEnabled : kDDCheckboxDisabled, r2, str); drawDDText(checked ? kDDCheckboxEnabled : kDDCheckboxDisabled, r2, str);
addDirtyRect(r); addDirtyRect(r);
debugWidgetPosition("Checkbox", r);
} }
void ThemeRenderer::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) { void ThemeRenderer::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) {
@ -368,7 +365,6 @@ void ThemeRenderer::drawSlider(const Common::Rect &r, int width, WidgetStateInfo
drawDD(kDDSliderFull, r2); drawDD(kDDSliderFull, r2);
addDirtyRect(r); addDirtyRect(r);
debugWidgetPosition("Slider", r);
} }
void ThemeRenderer::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, ScrollbarState sb_state, WidgetStateInfo state) { void ThemeRenderer::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, ScrollbarState sb_state, WidgetStateInfo state) {
@ -376,9 +372,9 @@ void ThemeRenderer::drawScrollbar(const Common::Rect &r, int sliderY, int slider
return; return;
drawDD(kDDScrollbarBase, r); drawDD(kDDScrollbarBase, r);
// TODO: Need to find a scrollbar in the GUI for testing... :p
addDirtyRect(r);
debugWidgetPosition("SCB", r);
} }
void ThemeRenderer::drawDialogBackground(const Common::Rect &r, uint16 hints, WidgetStateInfo state) { void ThemeRenderer::drawDialogBackground(const Common::Rect &r, uint16 hints, WidgetStateInfo state) {
@ -395,7 +391,7 @@ void ThemeRenderer::drawDialogBackground(const Common::Rect &r, uint16 hints, Wi
drawDD(kDDDefaultBackground, r); drawDD(kDDDefaultBackground, r);
} }
debugWidgetPosition("Background", r); addDirtyRect(r);
} }
void ThemeRenderer::drawCaret(const Common::Rect &r, bool erase, WidgetStateInfo state) { void ThemeRenderer::drawCaret(const Common::Rect &r, bool erase, WidgetStateInfo state) {
@ -403,6 +399,7 @@ void ThemeRenderer::drawCaret(const Common::Rect &r, bool erase, WidgetStateInfo
return; return;
debugWidgetPosition("Caret", r); debugWidgetPosition("Caret", r);
addDirtyRect(r);
} }
void ThemeRenderer::drawPopUpWidget(const Common::Rect &r, const Common::String &sel, int deltax, WidgetStateInfo state, TextAlign align) { void ThemeRenderer::drawPopUpWidget(const Common::Rect &r, const Common::String &sel, int deltax, WidgetStateInfo state, TextAlign align) {
@ -418,7 +415,7 @@ void ThemeRenderer::drawPopUpWidget(const Common::Rect &r, const Common::String
drawDDText(dd, text, sel); drawDDText(dd, text, sel);
} }
debugWidgetPosition("Popup Widget", r); addDirtyRect(r);
} }
void ThemeRenderer::drawSurface(const Common::Rect &r, const Graphics::Surface &surface, WidgetStateInfo state, int alpha, bool themeTrans) { void ThemeRenderer::drawSurface(const Common::Rect &r, const Graphics::Surface &surface, WidgetStateInfo state, int alpha, bool themeTrans) {
@ -450,14 +447,29 @@ void ThemeRenderer::drawWidgetBackground(const Common::Rect &r, uint16 hints, Wi
break; break;
} }
debugWidgetPosition("Widget Background", r); addDirtyRect(r);
} }
void ThemeRenderer::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, const Common::Array<Common::String> &tabs, int active, uint16 hints, int titleVPad, WidgetStateInfo state) { void ThemeRenderer::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, const Common::Array<Common::String> &tabs, int active, uint16 hints, int titleVPad, WidgetStateInfo state) {
if (!ready()) if (!ready())
return; return;
const int tabOffset = 1;
for (int i = 0; i < (int)tabs.size(); ++i) {
if (i == active)
continue;
debugWidgetPosition("Tab widget", r); 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]);
}
if (active >= 0) {
Common::Rect tabRect(r.left + active * (tabWidth + tabOffset), r.top, r.left + active * (tabWidth + tabOffset) + tabWidth, r.top + tabHeight);
drawDD(kDDTabActive, tabRect);
drawDDText(kDDTabActive, tabRect, tabs[active]);
}
} }
void ThemeRenderer::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, TextAlign align, bool inverted, int deltax, bool useEllipsis, FontStyle font) { void ThemeRenderer::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, TextAlign align, bool inverted, int deltax, bool useEllipsis, FontStyle font) {
@ -470,11 +482,11 @@ void ThemeRenderer::drawText(const Common::Rect &r, const Common::String &str, W
void ThemeRenderer::debugWidgetPosition(const char *name, const Common::Rect &r) { 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); _font->drawString(_screen, name, r.left, r.top, r.width(), 0xFFFF, Graphics::kTextAlignRight, 0, true);
// _screen->hLine(r.left, r.top, r.right, 0xFFFF); _screen->hLine(r.left, r.top, r.right, 0xFFFF);
// _screen->hLine(r.left, r.bottom, r.right, 0xFFFF); _screen->hLine(r.left, r.bottom, r.right, 0xFFFF);
// _screen->vLine(r.left, r.top, r.bottom, 0xFFFF); _screen->vLine(r.left, r.top, r.bottom, 0xFFFF);
// _screen->vLine(r.right, r.top, r.bottom, 0xFFFF); _screen->vLine(r.right, r.top, r.bottom, 0xFFFF);
} }
void ThemeRenderer::updateScreen() { void ThemeRenderer::updateScreen() {

View file

@ -102,7 +102,8 @@ public:
kDDCheckboxEnabled, kDDCheckboxEnabled,
kDDCheckboxDisabled, kDDCheckboxDisabled,
kDDTab, kDDTabActive,
kDDTabInactive,
kDDScrollbarBase, kDDScrollbarBase,
kDDScrollbarHandle, kDDScrollbarHandle,