Skip to content

Commit

Permalink
GUI: Unify clip and non-clip draw calls
Browse files Browse the repository at this point in the history
  • Loading branch information
bgK committed Apr 19, 2018
1 parent dcfac42 commit 4d29ce2
Show file tree
Hide file tree
Showing 18 changed files with 156 additions and 573 deletions.
479 changes: 50 additions & 429 deletions gui/ThemeEngine.cpp

Large diffs are not rendered by default.

108 changes: 36 additions & 72 deletions gui/ThemeEngine.h
Expand Up @@ -376,74 +376,56 @@ class ThemeEngine {

//@}

/**
* Set the clipping rect to be used by the widget drawing methods defined below.
*
* Widgets are not drawn outside of the clipping rect. Widgets that overlap the
* clipping rect are drawn partially.
*
* @param newRect The new clipping rect
* @return The previous clipping rect
*/
Common::Rect swapClipRect(const Common::Rect &newRect);

/** @name WIDGET DRAWING METHODS */
//@{

void drawWidgetBackground(const Common::Rect &r, uint16 hints,
WidgetBackground background = kWidgetBackgroundPlain, WidgetStateInfo state = kStateEnabled);
void drawWidgetBackgroundClip(const Common::Rect &r, const Common::Rect &clippingArea, uint16 hints,
WidgetBackground background = kWidgetBackgroundPlain, WidgetStateInfo state = kStateEnabled);

void drawButton(const Common::Rect &r, const Common::String &str,
WidgetStateInfo state = kStateEnabled, uint16 hints = 0);
void drawButtonClip(const Common::Rect &r, const Common::Rect &clippingRect, const Common::String &str,
WidgetStateInfo state = kStateEnabled, uint16 hints = 0);
void drawWidgetBackground(const Common::Rect &r, uint16 hints, WidgetBackground background = kWidgetBackgroundPlain);

void drawSurface(const Common::Rect &r, const Graphics::Surface &surface,
WidgetStateInfo state = kStateEnabled, int alpha = 255, bool themeTrans = false);
void drawSurfaceClip(const Common::Rect &r, const Common::Rect &clippingRect, const Graphics::Surface &surface,
WidgetStateInfo state = kStateEnabled, int alpha = 255, bool themeTrans = false);
void drawButton(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled,
uint16 hints = 0);

void drawSurface(const Common::Rect &r, const Graphics::Surface &surface, bool themeTrans = false);

void drawSlider(const Common::Rect &r, int width,
WidgetStateInfo state = kStateEnabled);
void drawSliderClip(const Common::Rect &r, const Common::Rect &clippingRect, int width,
WidgetStateInfo state = kStateEnabled);
void drawSlider(const Common::Rect &r, int width, WidgetStateInfo state = kStateEnabled);

void drawCheckbox(const Common::Rect &r, const Common::String &str,
bool checked, WidgetStateInfo state = kStateEnabled);
void drawCheckboxClip(const Common::Rect &r, const Common::Rect &clippingRect, const Common::String &str,
bool checked, WidgetStateInfo state = kStateEnabled);
void drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked,
WidgetStateInfo state = kStateEnabled);

void drawRadiobutton(const Common::Rect &r, const Common::String &str,
bool checked, WidgetStateInfo state = kStateEnabled);
void drawRadiobuttonClip(const Common::Rect &r, const Common::Rect &clippingRect, const Common::String &str,
bool checked, WidgetStateInfo state = kStateEnabled);
void drawRadiobutton(const Common::Rect &r, const Common::String &str, bool checked,
WidgetStateInfo state = kStateEnabled);

void drawTab(const Common::Rect &r, int tabHeight, int tabWidth,
const Common::Array<Common::String> &tabs, int active, uint16 hints,
int titleVPad, WidgetStateInfo state = kStateEnabled);
void drawTabClip(const Common::Rect &r, const Common::Rect &clippingRect, int tabHeight, const Common::Array<int> &tabWidths,
const Common::Array<Common::String> &tabs, int active, uint16 hints,
int titleVPad, WidgetStateInfo state = kStateEnabled);
void drawTab(const Common::Rect &r, int tabHeight, const Common::Array<int> &tabWidths,
const Common::Array<Common::String> &tabs, int active);

void drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight,
ScrollbarState, WidgetStateInfo state = kStateEnabled);
void drawScrollbarClip(const Common::Rect &r, const Common::Rect &clippingRect, int sliderY, int sliderHeight,
ScrollbarState scrollState, WidgetStateInfo state = kStateEnabled);
void drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, ScrollbarState scrollState);

void drawPopUpWidget(const Common::Rect &r, const Common::String &sel,
int deltax, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignLeft);
void drawPopUpWidgetClip(const Common::Rect &r, const Common::Rect &clippingArea, const Common::String &sel,
int deltax, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignLeft);
void drawPopUpWidget(const Common::Rect &r, const Common::String &sel, int deltax,
WidgetStateInfo state = kStateEnabled);

void drawCaret(const Common::Rect &r, bool erase,
WidgetStateInfo state = kStateEnabled);
void drawCaretClip(const Common::Rect &r, const Common::Rect &clip, bool erase,
WidgetStateInfo state = kStateEnabled);
void drawCaret(const Common::Rect &r, bool erase);

void drawLineSeparator(const Common::Rect &r, WidgetStateInfo state = kStateEnabled);
void drawLineSeparatorClip(const Common::Rect &r, const Common::Rect &clippingArea, WidgetStateInfo state = kStateEnabled);
void drawLineSeparator(const Common::Rect &r);

void drawDialogBackground(const Common::Rect &r, DialogBackground type, WidgetStateInfo state = kStateEnabled);
void drawDialogBackgroundClip(const Common::Rect &r, const Common::Rect &clip, DialogBackground type, WidgetStateInfo state = kStateEnabled);
void drawDialogBackground(const Common::Rect &r, DialogBackground type);

void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
void drawTextClip(const Common::Rect &r, const Common::Rect &clippingArea, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true, const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled,
Graphics::TextAlign align = Graphics::kTextAlignCenter,
TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true,
FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true,
const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));

void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state = kStateEnabled, FontColor color = kFontColorNormal);
void drawCharClip(const Common::Rect &r, const Common::Rect &clippingArea, byte ch, const Graphics::Font *font, WidgetStateInfo state = kStateEnabled, FontColor color = kFontColorNormal);
void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, FontColor color = kFontColorNormal);

//@}

Expand Down Expand Up @@ -605,15 +587,6 @@ class ThemeEngine {
int getGraphicsMode() const { return _graphicsMode; }

protected:
/**
* Initializes the drawing screen surfaces, _screen and _backBuffer.
* If the surfaces already exist, they are cleared and re-initialized.
*
* @param backBuffer Sets whether the _backBuffer surface should be initialized.
* @template PixelType C type which specifies the size of each pixel.
* Defaults to uint16 (2 BPP for the surfaces)
*/
template<typename PixelType> void screenInit(bool backBuffer = true);

/**
* Loads the given theme into the ThemeEngine.
Expand Down Expand Up @@ -656,20 +629,11 @@ class ThemeEngine {
* These functions are called from all the Widget drawing methods.
*/
void drawDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool forceRestore = false);
void drawDDClip(DrawData type, const Common::Rect &r, const Common::Rect &clippingRect, uint32 dynamic = 0,
bool forceRestore = false);
void drawDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft,
TextAlignVertical alignV = kTextAlignVTop, int deltax = 0,
const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
void drawDDTextClip(TextData type, TextColor color, const Common::Rect &r, const Common::Rect &clippingRect,
const Common::String &text, bool restoreBg,
bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft,
TextAlignVertical alignV = kTextAlignVTop, int deltax = 0,
const Common::Rect &drawableTextArea = Common::Rect(0, 0, 0, 0));
void drawBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha);
void drawBitmapClip(const Graphics::Surface *bitmap, const Common::Rect &clippingRect, const Common::Rect &r,
bool alpha);
void drawBitmap(const Graphics::Surface *bitmap, const Common::Rect &clippingRect, bool alpha);

/**
* DEBUG: Draws a white square and writes some text next to it.
Expand Down Expand Up @@ -730,7 +694,6 @@ class ThemeEngine {
GraphicsMode _graphicsMode;

/** Font info. */
Common::String _fontName;
const Graphics::Font *_font;

/**
Expand Down Expand Up @@ -771,10 +734,11 @@ class ThemeEngine {
MAX_CURS_COLORS = 255
};
byte *_cursor;
bool _needPaletteUpdates;
uint _cursorWidth, _cursorHeight;
byte _cursorPal[3 * MAX_CURS_COLORS];
byte _cursorPalSize;

Common::Rect _clip;
};

} // End of namespace GUI.
Expand Down
3 changes: 2 additions & 1 deletion gui/Tooltip.cpp
Expand Up @@ -64,7 +64,8 @@ void Tooltip::drawDialog(DrawLayer layerToDraw) {

for (Common::StringArray::const_iterator i = _wrappedLines.begin(); i != _wrappedLines.end(); ++i, ++num) {
g_gui.theme()->drawText(
Common::Rect(_x + 1, _y + 1 + num * h, _x + 1 +_w, _y + 1+ (num + 1) * h), *i,
Common::Rect(_x + 1, _y + 1 + num * h, _x + 1 + _w, _y + 1 + (num + 1) * h),
*i,
ThemeEngine::kStateEnabled,
Graphics::kTextAlignLeft,
ThemeEngine::kTextInversionNone,
Expand Down
4 changes: 3 additions & 1 deletion gui/about.cpp
Expand Up @@ -242,7 +242,9 @@ void AboutDialog::drawDialog(DrawLayer layerToDraw) {
str++;

if (*str)
g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()), str, state, align, ThemeEngine::kTextInversionNone, 0, false, ThemeEngine::kFontStyleBold, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()),
str, state, align, ThemeEngine::kTextInversionNone, 0, false,
ThemeEngine::kFontStyleBold, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
y += _lineHeight;
}
}
Expand Down
2 changes: 1 addition & 1 deletion gui/console.cpp
Expand Up @@ -712,7 +712,7 @@ void ConsoleDialog::drawCaret(bool erase) {
int y = _y + _topPadding + displayLine * kConsoleLineHeight;

_caretVisible = !erase;
g_gui.theme()->drawCaret(Common::Rect(x, y, x+1, y+kConsoleLineHeight), erase);
g_gui.theme()->drawCaret(Common::Rect(x, y, x + 1, y + kConsoleLineHeight), erase);
}

void ConsoleDialog::scrollToCurrent() {
Expand Down
2 changes: 1 addition & 1 deletion gui/dialog.cpp
Expand Up @@ -167,7 +167,7 @@ void Dialog::drawDialog(DrawLayer layerToDraw) {
return;

g_gui.theme()->_layerToDraw = layerToDraw;
g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x+_w, _y+_h), _backgroundType);
g_gui.theme()->drawDialogBackground(Common::Rect(_x, _y, _x + _w, _y + _h), _backgroundType);

markWidgetsAsDirty();
drawWidgets();
Expand Down
4 changes: 4 additions & 0 deletions gui/object.cpp
Expand Up @@ -67,4 +67,8 @@ void GuiObject::removeWidget(Widget *del) {
}
}

Common::Rect GuiObject::getClipRect() const {
return Common::Rect(getAbsX(), getAbsY(), getAbsX() + getWidth(), getAbsY() + getHeight());
}

} // End of namespace GUI
5 changes: 5 additions & 0 deletions gui/object.h
Expand Up @@ -95,6 +95,11 @@ class GuiObject : public CommandReceiver {
return (x >= _x && x < (_x + _w) && (y >= _y) && (y < _y + _h));
}

/**
* Returns the clipping rect to be used when drawing the children widgets of this object
*/
virtual Common::Rect getClipRect() const;

protected:
virtual void releaseFocus() = 0;
};
Expand Down
56 changes: 17 additions & 39 deletions gui/widget.cpp
Expand Up @@ -54,31 +54,6 @@ void Widget::init() {
_needsRedraw = true;
}

Common::Rect Widget::getBossClipRect() const {
int bx = _boss->getAbsX();
int by = _boss->getAbsY();
Common::Rect result = Common::Rect(bx, by, bx + _boss->getWidth(), by + _boss->getHeight());
bool needsClipping = false;

//check whether clipping area is inside the screen
if (result.left < 0 && (needsClipping = true))
warning("Widget <%s> has clipping area x < 0 (%d)", _name.c_str(), result.left);
if (result.left >= g_gui.getWidth() && (needsClipping = true))
warning("Widget <%s> has clipping area x > %d (%d)", _name.c_str(), g_gui.getWidth(), result.left);
if (result.right > g_gui.getWidth() && (needsClipping = true))
warning("Widget <%s> has clipping area x + w > %d (%d)", _name.c_str(), g_gui.getWidth(), result.right);
if (result.top < 0 && (needsClipping = true))
warning("Widget <%s> has clipping area y < 0 (%d)", _name.c_str(), result.top);
if (result.top >= g_gui.getHeight() && (needsClipping = true))
warning("Widget <%s> has clipping area y > %d (%d)", _name.c_str(), g_gui.getHeight(), result.top);
if (result.bottom > g_gui.getHeight() && (needsClipping = true))
warning("Widget <%s> has clipping area y + h > %d (%d)", _name.c_str(), g_gui.getHeight(), result.bottom);

if (needsClipping)
result.clip(g_gui.getWidth(), g_gui.getHeight());
return result;
}

Widget::~Widget() {
delete _next;
_next = 0;
Expand Down Expand Up @@ -134,9 +109,12 @@ void Widget::draw() {
_x = getAbsX();
_y = getAbsY();

Common::Rect oldClip = g_gui.theme()->swapClipRect(_boss->getClipRect());

// Draw border
if (_flags & WIDGET_BORDER) {
g_gui.theme()->drawWidgetBackgroundClip(Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(), 0, ThemeEngine::kWidgetBackgroundBorder);
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h), 0,
ThemeEngine::kWidgetBackgroundBorder);
_x += 4;
_y += 4;
_w -= 8;
Expand All @@ -146,6 +124,8 @@ void Widget::draw() {
// Now perform the actual widget draw
drawWidget();

g_gui.theme()->swapClipRect(oldClip);

// Restore x/y
if (_flags & WIDGET_BORDER) {
_x -= 4;
Expand Down Expand Up @@ -318,9 +298,9 @@ void StaticTextWidget::setAlign(Graphics::TextAlign align) {


void StaticTextWidget::drawWidget() {
g_gui.theme()->drawTextClip(
Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(),
_label, _state, _align, ThemeEngine::kTextInversionNone, 0, true, _font
g_gui.theme()->drawText(
Common::Rect(_x, _y, _x + _w, _y + _h),
_label, _state, _align, ThemeEngine::kTextInversionNone, 0, true, _font
);
}

Expand Down Expand Up @@ -360,10 +340,7 @@ void ButtonWidget::handleMouseDown(int x, int y, int button, int clickCount) {
}

void ButtonWidget::drawWidget() {
g_gui.theme()->drawButtonClip(
Common::Rect(_x, _y, _x + _w, _y + _h), getBossClipRect(),
_label, _state, getFlags()
);
g_gui.theme()->drawButton(Common::Rect(_x, _y, _x + _w, _y + _h), _label, _state, getFlags());
}

void ButtonWidget::setLabel(const Common::String &label) {
Expand Down Expand Up @@ -491,7 +468,7 @@ void PicButtonWidget::drawWidget() {
const int x = _x + (_w - gfx->w) / 2;
const int y = _y + (_h - gfx->h) / 2;

g_gui.theme()->drawSurfaceClip(Common::Rect(x, y, x + gfx->w, y + gfx->h), getBossClipRect(), *gfx, _state, _alpha, _transparency);
g_gui.theme()->drawSurface(Common::Rect(x, y, x + gfx->w, y + gfx->h), *gfx, _transparency);
}
}

Expand Down Expand Up @@ -526,7 +503,7 @@ void CheckboxWidget::setState(bool state) {
}

void CheckboxWidget::drawWidget() {
g_gui.theme()->drawCheckboxClip(Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(), _label, _state, Widget::_state);
g_gui.theme()->drawCheckbox(Common::Rect(_x, _y, _x + _w, _y + _h), _label, _state, Widget::_state);
}

#pragma mark -
Expand Down Expand Up @@ -595,7 +572,7 @@ void RadiobuttonWidget::setState(bool state, bool setGroup) {
}

void RadiobuttonWidget::drawWidget() {
g_gui.theme()->drawRadiobuttonClip(Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(), _label, _state, Widget::_state);
g_gui.theme()->drawRadiobutton(Common::Rect(_x, _y, _x + _w, _y + _h), _label, _state, Widget::_state);
}

#pragma mark -
Expand Down Expand Up @@ -663,7 +640,7 @@ void SliderWidget::handleMouseWheel(int x, int y, int direction) {
}

void SliderWidget::drawWidget() {
g_gui.theme()->drawSliderClip(Common::Rect(_x, _y, _x + _w, _y + _h), getBossClipRect(), valueToBarWidth(_value), _state);
g_gui.theme()->drawSlider(Common::Rect(_x, _y, _x + _w, _y + _h), valueToBarWidth(_value), _state);
}

int SliderWidget::valueToBarWidth(int value) {
Expand Down Expand Up @@ -742,7 +719,7 @@ void GraphicsWidget::drawWidget() {
const int x = _x + (_w - _gfx.w) / 2;
const int y = _y + (_h - _gfx.h) / 2;

g_gui.theme()->drawSurfaceClip(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), getBossClipRect(), _gfx, _state, _alpha, _transparency);
g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _transparency);
}
}

Expand Down Expand Up @@ -783,7 +760,8 @@ void ContainerWidget::removeWidget(Widget *widget) {
}

void ContainerWidget::drawWidget() {
g_gui.theme()->drawWidgetBackgroundClip(Common::Rect(_x, _y, _x + _w, _y + _h), getBossClipRect(), 0, ThemeEngine::kWidgetBackgroundBorder);
g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h), 0,
ThemeEngine::kWidgetBackgroundBorder);
}

} // End of namespace GUI
1 change: 0 additions & 1 deletion gui/widget.h
Expand Up @@ -123,7 +123,6 @@ class Widget : public GuiObject {

virtual int16 getAbsX() const { return _x + _boss->getChildX(); }
virtual int16 getAbsY() const { return _y + _boss->getChildY(); }
virtual Common::Rect getBossClipRect() const;

virtual void setPos(int x, int y) { _x = x; _y = y; }
virtual void setSize(int w, int h) { _w = w; _h = h; }
Expand Down
6 changes: 4 additions & 2 deletions gui/widgets/editable.cpp
Expand Up @@ -289,7 +289,7 @@ void EditableWidget::drawCaret(bool erase) {
x += getAbsX();
y += getAbsY();

g_gui.theme()->drawCaretClip(Common::Rect(x, y, x + 1, y + editRect.height()), getBossClipRect(), erase);
g_gui.theme()->drawCaret(Common::Rect(x, y, x + 1, y + editRect.height()), erase);

if (erase) {
GUI::EditableWidget::String character;
Expand Down Expand Up @@ -318,7 +318,9 @@ void EditableWidget::drawCaret(bool erase) {
// possible glitches due to different methods used.
width = MIN(editRect.width() - caretOffset, width);
if (width > 0) {
g_gui.theme()->drawTextClip(Common::Rect(x, y, x + width, y + editRect.height()), getBossClipRect(), character, _state, Graphics::kTextAlignLeft, _inversion, 0, false, _font, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
g_gui.theme()->drawText(Common::Rect(x, y, x + width, y + editRect.height()), character,
_state, Graphics::kTextAlignLeft, _inversion, 0, false, _font,
ThemeEngine::kFontColorNormal, true, _textDrawableArea);
}
}

Expand Down

0 comments on commit 4d29ce2

Please sign in to comment.