aboutsummaryrefslogtreecommitdiff
path: root/gui/widget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gui/widget.cpp')
-rw-r--r--gui/widget.cpp189
1 files changed, 160 insertions, 29 deletions
diff --git a/gui/widget.cpp b/gui/widget.cpp
index 73d055527c..898d5671c6 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -53,6 +53,31 @@ void Widget::init() {
_boss->_firstWidget = this;
}
+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;
@@ -99,7 +124,7 @@ void Widget::draw() {
// Draw border
if (_flags & WIDGET_BORDER) {
- g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x+_w, _y+_h), 0, ThemeEngine::kWidgetBackgroundBorder);
+ g_gui.theme()->drawWidgetBackgroundClip(Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(), 0, ThemeEngine::kWidgetBackgroundBorder);
_x += 4;
_y += 4;
_w -= 8;
@@ -131,7 +156,7 @@ void Widget::draw() {
Widget *Widget::findWidgetInChain(Widget *w, int x, int y) {
while (w) {
// Stop as soon as we find a widget that contains the point (x,y)
- if (x >= w->_x && x < w->_x + w->_w && y >= w->_y && y < w->_y + w->_h)
+ if (x >= w->_x && x < w->_x + w->_w && y >= w->_y && y < w->_y + w->getHeight())
break;
w = w->_next;
}
@@ -280,7 +305,10 @@ void StaticTextWidget::setAlign(Graphics::TextAlign align) {
void StaticTextWidget::drawWidget() {
- g_gui.theme()->drawText(Common::Rect(_x, _y, _x+_w, _y+_h), _label, _state, _align, ThemeEngine::kTextInversionNone, 0, true, _font);
+ g_gui.theme()->drawTextClip(
+ Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(),
+ _label, _state, _align, ThemeEngine::kTextInversionNone, 0, true, _font
+ );
}
#pragma mark -
@@ -319,7 +347,10 @@ void ButtonWidget::handleMouseDown(int x, int y, int button, int clickCount) {
}
void ButtonWidget::drawWidget() {
- g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), _label, _state, getFlags());
+ g_gui.theme()->drawButtonClip(
+ Common::Rect(_x, _y, _x + _w, _y + _h), getBossClipRect(),
+ _label, _state, getFlags()
+ );
}
void ButtonWidget::setLabel(const Common::String &label) {
@@ -367,25 +398,28 @@ void ButtonWidget::setUnpressedState() {
PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey)
: ButtonWidget(boss, x, y, w, h, "", tooltip, cmd, hotkey),
- _gfx(), _alpha(256), _transparency(false) {
+ _alpha(255), _transparency(false), _showButton(true), _isAlpha(false) {
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
_type = kButtonWidget;
+ _mode = ThemeEngine::kAutoScaleNone;
}
PicButtonWidget::PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd, uint8 hotkey)
: ButtonWidget(boss, name, "", tooltip, cmd, hotkey),
- _gfx(), _alpha(256), _transparency(false) {
+ _alpha(255), _transparency(false), _showButton(true), _isAlpha(false) {
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
_type = kButtonWidget;
+ _mode = ThemeEngine::kAutoScaleNone;
}
PicButtonWidget::~PicButtonWidget() {
- _gfx.free();
+ for (int i = 0; i < kPicButtonStateMax + 1; i++)
+ _gfx[i].free();
}
-void PicButtonWidget::setGfx(const Graphics::Surface *gfx) {
- _gfx.free();
+void PicButtonWidget::setGfx(const Graphics::Surface *gfx, int statenum) {
+ _gfx[statenum].free();
if (!gfx || !gfx->getPixels())
return;
@@ -401,10 +435,27 @@ void PicButtonWidget::setGfx(const Graphics::Surface *gfx) {
return;
}
- _gfx.copyFrom(*gfx);
+ _gfx[statenum].copyFrom(*gfx);
}
-void PicButtonWidget::setGfx(int w, int h, int r, int g, int b) {
+void PicButtonWidget::setAGfx(const Graphics::TransparentSurface *gfx, int statenum, ThemeEngine::AutoScaleMode mode) {
+ _agfx[statenum].free();
+
+ if (!gfx || !gfx->getPixels())
+ return;
+
+ if (gfx->format.bytesPerPixel == 1) {
+ warning("PicButtonWidget::setGfx got paletted surface passed");
+ return;
+ }
+
+ _agfx[statenum].copyFrom(*gfx);
+
+ _isAlpha = true;
+ _mode = mode;
+}
+
+void PicButtonWidget::setGfx(int w, int h, int r, int g, int b, int statenum) {
if (w == -1)
w = _w;
if (h == -1)
@@ -412,26 +463,69 @@ void PicButtonWidget::setGfx(int w, int h, int r, int g, int b) {
const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
- _gfx.free();
- _gfx.create(w, h, requiredFormat);
- _gfx.fillRect(Common::Rect(0, 0, w, h), _gfx.format.RGBToColor(r, g, b));
+ _gfx[statenum].free();
+ _gfx[statenum].create(w, h, requiredFormat);
+ _gfx[statenum].fillRect(Common::Rect(0, 0, w, h), _gfx[statenum].format.RGBToColor(r, g, b));
}
void PicButtonWidget::drawWidget() {
- g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), "", _state, getFlags());
+ if (_showButton)
+ g_gui.theme()->drawButtonClip(Common::Rect(_x, _y, _x + _w, _y + _h), getBossClipRect(), "", _state, getFlags());
+
+ if (!_isAlpha) {
+ Graphics::Surface *gfx;
+
+ if (_state == ThemeEngine::kStateHighlight)
+ gfx = &_gfx[kPicButtonHighlight];
+ else if (_state == ThemeEngine::kStateDisabled)
+ gfx = &_gfx[kPicButtonStateDisabled];
+ else if (_state == ThemeEngine::kStatePressed)
+ gfx = &_gfx[kPicButtonStatePressed];
+ else
+ gfx = &_gfx[kPicButtonStateEnabled];
- if (_gfx.getPixels()) {
+ if (!gfx->getPixels())
+ gfx = &_gfx[kPicButtonStateEnabled];
+
+ if (gfx->getPixels()) {
// Check whether the set up surface needs to be converted to the GUI
// color format.
- const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
- if (_gfx.format != requiredFormat) {
- _gfx.convertToInPlace(requiredFormat);
+ const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
+ if (gfx->format != requiredFormat) {
+ gfx->convertToInPlace(requiredFormat);
+ }
+
+ 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);
}
+ } else {
+ Graphics::TransparentSurface *gfx;
+
+ if (_state == ThemeEngine::kStateHighlight)
+ gfx = &_agfx[kPicButtonHighlight];
+ else if (_state == ThemeEngine::kStateDisabled)
+ gfx = &_agfx[kPicButtonStateDisabled];
+ else if (_state == ThemeEngine::kStatePressed)
+ gfx = &_agfx[kPicButtonStatePressed];
+ else
+ gfx = &_agfx[kPicButtonStateEnabled];
- const int x = _x + (_w - _gfx.w) / 2;
- const int y = _y + (_h - _gfx.h) / 2;
+ if (!gfx->getPixels())
+ gfx = &_agfx[kPicButtonStateEnabled];
+
+ if (gfx->getPixels()) {
+ if (_mode == GUI::ThemeEngine::kAutoScaleNone) {
+ const int x = _x + (_w - gfx->w) / 2;
+ const int y = _y + (_h - gfx->h) / 2;
- g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency);
+ g_gui.theme()->drawASurface(Common::Rect(x, y, x + gfx->w, y + gfx->h), *gfx, _mode, _alpha);
+
+ } else {
+ g_gui.theme()->drawASurface(Common::Rect(_x, _y, _x + _w, _y + _h), *gfx, _mode, _alpha);
+ }
+ }
}
}
@@ -466,7 +560,7 @@ void CheckboxWidget::setState(bool state) {
}
void CheckboxWidget::drawWidget() {
- g_gui.theme()->drawCheckbox(Common::Rect(_x, _y, _x+_w, _y+_h), _label, _state, Widget::_state);
+ g_gui.theme()->drawCheckboxClip(Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(), _label, _state, Widget::_state);
}
#pragma mark -
@@ -535,7 +629,7 @@ void RadiobuttonWidget::setState(bool state, bool setGroup) {
}
void RadiobuttonWidget::drawWidget() {
- g_gui.theme()->drawRadiobutton(Common::Rect(_x, _y, _x+_w, _y+_h), _label, _state, Widget::_state);
+ g_gui.theme()->drawRadiobuttonClip(Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(), _label, _state, Widget::_state);
}
#pragma mark -
@@ -603,7 +697,7 @@ void SliderWidget::handleMouseWheel(int x, int y, int direction) {
}
void SliderWidget::drawWidget() {
- g_gui.theme()->drawSlider(Common::Rect(_x, _y, _x + _w, _y + _h), valueToBarWidth(_value), _state);
+ g_gui.theme()->drawSliderClip(Common::Rect(_x, _y, _x + _w, _y + _h), getBossClipRect(), valueToBarWidth(_value), _state);
}
int SliderWidget::valueToBarWidth(int value) {
@@ -621,13 +715,13 @@ int SliderWidget::posToValue(int pos) {
#pragma mark -
GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip)
- : Widget(boss, x, y, w, h, tooltip), _gfx(), _alpha(256), _transparency(false) {
+ : Widget(boss, x, y, w, h, tooltip), _gfx(), _alpha(255), _transparency(false) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
_type = kGraphicsWidget;
}
GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name, const char *tooltip)
- : Widget(boss, name, tooltip), _gfx(), _alpha(256), _transparency(false) {
+ : Widget(boss, name, tooltip), _gfx(), _alpha(255), _transparency(false) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
_type = kGraphicsWidget;
}
@@ -655,6 +749,26 @@ void GraphicsWidget::setGfx(const Graphics::Surface *gfx) {
_gfx.copyFrom(*gfx);
}
+void GraphicsWidget::setAGfx(const Graphics::TransparentSurface *gfx, ThemeEngine::AutoScaleMode mode) {
+ _agfx.free();
+
+ if (!gfx || !gfx->getPixels())
+ return;
+
+ if (gfx->format.bytesPerPixel == 1) {
+ warning("GraphicsWidget::setGfx got paletted surface passed");
+ return;
+ }
+
+ if ((gfx->w > _w || gfx->h > _h) && mode == ThemeEngine::kAutoScaleNone) {
+ warning("GraphicsWidget has size %dx%d, but a surface with %dx%d is to be set", _w, _h, gfx->w, gfx->h);
+ return;
+ }
+
+ _agfx.copyFrom(*gfx);
+ _mode = mode;
+}
+
void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
if (w == -1)
w = _w;
@@ -680,7 +794,24 @@ void GraphicsWidget::drawWidget() {
const int x = _x + (_w - _gfx.w) / 2;
const int y = _y + (_h - _gfx.h) / 2;
- g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency);
+ g_gui.theme()->drawSurfaceClip(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), getBossClipRect(), _gfx, _state, _alpha, _transparency);
+ } else if (_agfx.getPixels()) {
+ // Check whether the set up surface needs to be converted to the GUI
+ // color format.
+ const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
+ if (_agfx.format != requiredFormat) {
+ _agfx.convertToInPlace(requiredFormat);
+ }
+
+ if (_mode == GUI::ThemeEngine::kAutoScaleNone) {
+ const int x = _x + (_w - _agfx.w) / 2;
+ const int y = _y + (_h - _agfx.h) / 2;
+
+ g_gui.theme()->drawASurface(Common::Rect(x, y, x + _agfx.w, y + _agfx.h), _agfx, _mode, _alpha);
+
+ } else {
+ g_gui.theme()->drawASurface(Common::Rect(_x, _y, _x + _w, _y + _h), _agfx, _mode, _alpha);
+ }
}
}
@@ -717,7 +848,7 @@ void ContainerWidget::removeWidget(Widget *widget) {
}
void ContainerWidget::drawWidget() {
- g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h), 0, ThemeEngine::kWidgetBackgroundBorder);
+ g_gui.theme()->drawWidgetBackgroundClip(Common::Rect(_x, _y, _x + _w, _y + _h), getBossClipRect(), 0, ThemeEngine::kWidgetBackgroundBorder);
}
} // End of namespace GUI