ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

widget.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/scummsys.h"
00024 #include "common/system.h"
00025 #include "common/rect.h"
00026 #include "common/textconsole.h"
00027 #include "common/translation.h"
00028 #include "graphics/pixelformat.h"
00029 #include "gui/widget.h"
00030 #include "gui/gui-manager.h"
00031 
00032 #include "gui/ThemeEval.h"
00033 
00034 #include "gui/dialog.h"
00035 #include "gui/widgets/popup.h"
00036 
00037 namespace GUI {
00038 
00039 Widget::Widget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip)
00040     : GuiObject(x, y, w, h), _type(0), _boss(boss), _tooltip(tooltip),
00041       _id(0), _flags(0), _hasFocus(false), _state(ThemeEngine::kStateEnabled) {
00042     init();
00043 }
00044 
00045 Widget::Widget(GuiObject *boss, const Common::String &name, const char *tooltip)
00046     : GuiObject(name), _type(0), _boss(boss), _tooltip(tooltip),
00047       _id(0), _flags(0), _hasFocus(false), _state(ThemeEngine::kStateDisabled) {
00048     init();
00049 }
00050 
00051 void Widget::init() {
00052     // Insert into the widget list of the boss
00053     _next = _boss->_firstWidget;
00054     _boss->_firstWidget = this;
00055     _needsRedraw = true;
00056 }
00057 
00058 Widget::~Widget() {
00059     delete _next;
00060     _next = 0;
00061 }
00062 
00063 void Widget::resize(int x, int y, int w, int h) {
00064     _x = x;
00065     _y = y;
00066     _w = w;
00067     _h = h;
00068 }
00069 
00070 void Widget::setFlags(int flags) {
00071     updateState(_flags, _flags | flags);
00072     _flags |= flags;
00073 }
00074 
00075 void Widget::clearFlags(int flags) {
00076     updateState(_flags, _flags & ~flags);
00077     _flags &= ~flags;
00078 }
00079 
00080 void Widget::updateState(int oldFlags, int newFlags) {
00081     if (newFlags & WIDGET_ENABLED) {
00082         _state = ThemeEngine::kStateEnabled;
00083         if (newFlags & WIDGET_HILITED)
00084             _state = ThemeEngine::kStateHighlight;
00085         if (newFlags & WIDGET_PRESSED)
00086             _state = ThemeEngine::kStatePressed;
00087     } else {
00088         _state = ThemeEngine::kStateDisabled;
00089     }
00090 }
00091 
00092 void Widget::markAsDirty() {
00093     _needsRedraw = true;
00094 
00095     Widget *w = _firstWidget;
00096     while (w) {
00097         w->markAsDirty();
00098         w = w->next();
00099     }
00100 }
00101 
00102 void Widget::draw() {
00103     if (!isVisible() || !_boss->isVisible())
00104         return;
00105 
00106     if (_needsRedraw) {
00107         int oldX = _x, oldY = _y;
00108 
00109         // Account for our relative position in the dialog
00110         _x = getAbsX();
00111         _y = getAbsY();
00112 
00113         Common::Rect oldClip = g_gui.theme()->swapClipRect(_boss->getClipRect());
00114 
00115         // Draw border
00116         if (_flags & WIDGET_BORDER) {
00117             g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h), 0,
00118                                                 ThemeEngine::kWidgetBackgroundBorder);
00119             _x += 4;
00120             _y += 4;
00121             _w -= 8;
00122             _h -= 8;
00123         }
00124 
00125         // Now perform the actual widget draw
00126         drawWidget();
00127 
00128         g_gui.theme()->swapClipRect(oldClip);
00129 
00130         // Restore x/y
00131         if (_flags & WIDGET_BORDER) {
00132             _x -= 4;
00133             _y -= 4;
00134             _w += 8;
00135             _h += 8;
00136         }
00137 
00138         _x = oldX;
00139         _y = oldY;
00140 
00141         _needsRedraw = false;
00142     }
00143 
00144     // Draw all children
00145     Widget *w = _firstWidget;
00146     while (w) {
00147         w->draw();
00148         w = w->_next;
00149     }
00150 }
00151 
00152 Widget *Widget::findWidgetInChain(Widget *w, int x, int y) {
00153     while (w) {
00154         // Stop as soon as we find a widget that contains the point (x,y)
00155         if (x >= w->_x && x < w->_x + w->_w && y >= w->_y && y < w->_y + w->getHeight())
00156             break;
00157         w = w->_next;
00158     }
00159     if (w)
00160         w = w->findWidget(x - w->_x, y - w->_y);
00161     return w;
00162 }
00163 
00164 Widget *Widget::findWidgetInChain(Widget *w, const char *name) {
00165     while (w) {
00166         if (w->_name == name) {
00167             return w;
00168         }
00169         w = w->_next;
00170     }
00171     return 0;
00172 }
00173 
00174 bool Widget::containsWidgetInChain(Widget *w, Widget *search) {
00175     while (w) {
00176         if (w == search || w->containsWidget(search))
00177             return true;
00178         w = w->_next;
00179     }
00180     return false;
00181 }
00182 
00183 void Widget::setEnabled(bool e) {
00184     if ((_flags & WIDGET_ENABLED) != e) {
00185         if (e)
00186             setFlags(WIDGET_ENABLED);
00187         else
00188             clearFlags(WIDGET_ENABLED);
00189 
00190         g_gui.scheduleTopDialogRedraw();
00191     }
00192 }
00193 
00194 bool Widget::isEnabled() const {
00195     if (g_gui.xmlEval()->getVar("Dialog." + _name + ".Enabled", 1) == 0) {
00196         return false;
00197     }
00198     return ((_flags & WIDGET_ENABLED) != 0);
00199 }
00200 
00201 void Widget::setVisible(bool e) {
00202     if (e)
00203         clearFlags(WIDGET_INVISIBLE);
00204     else
00205         setFlags(WIDGET_INVISIBLE);
00206 }
00207 
00208 bool Widget::isVisible() const {
00209     if (g_gui.xmlEval()->getVar("Dialog." + _name + ".Visible", 1) == 0)
00210         return false;
00211 
00212     return !(_flags & WIDGET_INVISIBLE);
00213 }
00214 
00215 uint8 Widget::parseHotkey(const Common::String &label) {
00216     if (!label.contains('~'))
00217         return 0;
00218 
00219     int state = 0;
00220     uint8 hotkey = 0;
00221 
00222     for (uint i = 0; i < label.size() && state != 3; i++) {
00223         switch (state) {
00224         case 0:
00225             if (label[i] == '~')
00226                 state = 1;
00227             break;
00228         case 1:
00229             if (label[i] != '~') {
00230                 state = 2;
00231                 hotkey = label[i];
00232             } else
00233                 state = 0;
00234             break;
00235         case 2:
00236             if (label[i] == '~')
00237                 state = 3;
00238             else
00239                 state = 0;
00240             break;
00241         }
00242     }
00243 
00244     if (state == 3)
00245         return hotkey;
00246 
00247     return 0;
00248 }
00249 
00250 Common::String Widget::cleanupHotkey(const Common::String &label) {
00251     Common::String res;
00252 
00253     for (uint i = 0; i < label.size(); i++)
00254         if (label[i] != '~')
00255             res = res + label[i];
00256 
00257     return res;
00258 }
00259 
00260 #pragma mark -
00261 
00262 StaticTextWidget::StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &text, Graphics::TextAlign align, const char *tooltip, ThemeEngine::FontStyle font)
00263     : Widget(boss, x, y, w, h, tooltip), _align(align) {
00264     setFlags(WIDGET_ENABLED);
00265     _type = kStaticTextWidget;
00266     _label = text;
00267     _font = font;
00268 }
00269 
00270 StaticTextWidget::StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::String &text, const char *tooltip, ThemeEngine::FontStyle font)
00271     : Widget(boss, name, tooltip) {
00272     setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
00273     _type = kStaticTextWidget;
00274     _label = text;
00275 
00276     _align = g_gui.xmlEval()->getWidgetTextHAlign(name);
00277     _font = font;
00278 }
00279 
00280 void StaticTextWidget::setValue(int value) {
00281     _label = Common::String::format("%d", value);
00282 }
00283 
00284 void StaticTextWidget::setLabel(const Common::String &label) {
00285     if (_label != label) {
00286         _label = label;
00287 
00288         markAsDirty();
00289     }
00290 }
00291 
00292 void StaticTextWidget::setAlign(Graphics::TextAlign align) {
00293     if (_align != align){
00294         _align = align;
00295 
00296         markAsDirty();
00297     }
00298 }
00299 
00300 
00301 void StaticTextWidget::drawWidget() {
00302     g_gui.theme()->drawText(
00303             Common::Rect(_x, _y, _x + _w, _y + _h),
00304             _label, _state, _align, ThemeEngine::kTextInversionNone, 0, true, _font
00305     );
00306 }
00307 
00308 #pragma mark -
00309 
00310 ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey)
00311     : StaticTextWidget(boss, x, y, w, h, cleanupHotkey(label), Graphics::kTextAlignCenter, tooltip), CommandSender(boss),
00312       _cmd(cmd), _hotkey(hotkey), _duringPress(false) {
00313 
00314     if (hotkey == 0)
00315         _hotkey = parseHotkey(label);
00316 
00317     setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
00318     _type = kButtonWidget;
00319 }
00320 
00321 ButtonWidget::ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey)
00322     : StaticTextWidget(boss, name, cleanupHotkey(label), tooltip), CommandSender(boss),
00323       _cmd(cmd), _hotkey(hotkey), _duringPress(false) {
00324     if (hotkey == 0)
00325         _hotkey = parseHotkey(label);
00326     setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
00327     _type = kButtonWidget;
00328 }
00329 
00330 void ButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) {
00331     if (isEnabled() && _duringPress && x >= 0 && x < _w && y >= 0 && y < _h) {
00332         setUnpressedState();
00333         sendCommand(_cmd, 0);
00334     }
00335     _duringPress = false;
00336 }
00337 
00338 void ButtonWidget::handleMouseDown(int x, int y, int button, int clickCount) {
00339     _duringPress = true;
00340     setPressedState();
00341 }
00342 
00343 void ButtonWidget::drawWidget() {
00344     g_gui.theme()->drawButton(Common::Rect(_x, _y, _x + _w, _y + _h), _label, _state, getFlags());
00345 }
00346 
00347 void ButtonWidget::setLabel(const Common::String &label) {
00348     StaticTextWidget::setLabel(cleanupHotkey(label));
00349 }
00350 
00351 ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd, int x, int y, int w, int h) {
00352     ButtonWidget *button;
00353 
00354 #ifndef DISABLE_FANCY_THEMES
00355     if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) {
00356         if (!name.empty())
00357             button = new PicButtonWidget(boss, name, _("Clear value"), cmd);
00358         else
00359             button = new PicButtonWidget(boss, x, y, w, h, _("Clear value"), cmd);
00360         ((PicButtonWidget *)button)->useThemeTransparency(true);
00361         ((PicButtonWidget *)button)->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageEraser));
00362     } else
00363 #endif
00364         if (!name.empty())
00365             button = new ButtonWidget(boss, name, "C", _("Clear value"), cmd);
00366         else
00367             button = new ButtonWidget(boss, x, y, w, h, "C", _("Clear value"), cmd);
00368 
00369     return button;
00370 }
00371 
00372 void ButtonWidget::setHighLighted(bool enable) {
00373     (enable) ? setFlags(WIDGET_HILITED) : clearFlags(WIDGET_HILITED);
00374     markAsDirty();
00375 }
00376 
00377 void ButtonWidget::setPressedState() {
00378     setFlags(WIDGET_PRESSED);
00379     clearFlags(WIDGET_HILITED);
00380     markAsDirty();
00381 }
00382 
00383 void ButtonWidget::setUnpressedState() {
00384     clearFlags(WIDGET_PRESSED);
00385     markAsDirty();
00386 }
00387 
00388 #pragma mark -
00389 
00390 DropdownButtonWidget::DropdownButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) :
00391         ButtonWidget(boss, x, y, w, h, label, tooltip, cmd, hotkey) {
00392     setFlags(getFlags() | WIDGET_TRACK_MOUSE);
00393 
00394     reset();
00395 }
00396 
00397 DropdownButtonWidget::DropdownButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) :
00398         ButtonWidget(boss, name, label, tooltip, cmd, hotkey) {
00399     setFlags(getFlags() | WIDGET_TRACK_MOUSE);
00400 
00401     reset();
00402 }
00403 
00404 void DropdownButtonWidget::reset() {
00405     _inDropdown = false;
00406     _inButton   = false;
00407     _dropdownWidth = g_gui.xmlEval()->getVar("Globals.DropdownButton.Width", 13);
00408 }
00409 
00410 bool DropdownButtonWidget::isInDropDown(int x, int y) const {
00411     Common::Rect dropdownRect(_w - _dropdownWidth, 0, _w, _h);
00412     return dropdownRect.contains(x, y);
00413 }
00414 
00415 void DropdownButtonWidget::handleMouseMoved(int x, int y, int button) {
00416     if (_entries.empty()) {
00417         return;
00418     }
00419 
00420     // Detect which part of the button the cursor is over
00421     bool inDropdown = isInDropDown(x, y);
00422     bool inButton   = Common::Rect(_w, _h).contains(x, y) && !inDropdown;
00423 
00424     if (inDropdown != _inDropdown) {
00425         _inDropdown = inDropdown;
00426         markAsDirty();
00427     }
00428 
00429     if (inButton != _inButton) {
00430         _inButton = inButton;
00431         markAsDirty();
00432     }
00433 }
00434 
00435 void DropdownButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) {
00436     if (isEnabled() && !_entries.empty() && _duringPress && isInDropDown(x, y)) {
00437 
00438         PopUpDialog popupDialog(this, "DropdownDialog", x + getAbsX(), y + getAbsY());
00439         popupDialog.setPosition(getAbsX(), getAbsY() + _h);
00440         popupDialog.setLineHeight(_h);
00441         popupDialog.setPadding(_dropdownWidth, _dropdownWidth);
00442 
00443         for (uint i = 0; i < _entries.size(); i++) {
00444             popupDialog.appendEntry(_entries[i].label);
00445         }
00446 
00447         int newSel = popupDialog.runModal();
00448         if (newSel != -1) {
00449             sendCommand(_entries[newSel].cmd, 0);
00450         }
00451 
00452         setUnpressedState();
00453         _duringPress = false;
00454     } else {
00455         ButtonWidget::handleMouseUp(x, y, button, clickCount);
00456     }
00457 }
00458 
00459 void DropdownButtonWidget::reflowLayout() {
00460     ButtonWidget::reflowLayout();
00461 
00462     reset();
00463 }
00464 
00465 void DropdownButtonWidget::appendEntry(const Common::String &label, uint32 cmd) {
00466     Entry e;
00467     e.label = label;
00468     e.cmd = cmd;
00469     _entries.push_back(e);
00470 }
00471 
00472 void DropdownButtonWidget::clearEntries() {
00473     _entries.clear();
00474 }
00475 
00476 void DropdownButtonWidget::drawWidget() {
00477     if (_entries.empty()) {
00478         // Degrade to a regular button
00479         g_gui.theme()->drawButton(Common::Rect(_x, _y, _x + _w, _y + _h), _label, _state);
00480     } else {
00481         g_gui.theme()->drawDropDownButton(Common::Rect(_x, _y, _x + _w, _y + _h), _dropdownWidth, _label,
00482                                           _state, _inButton, _inDropdown);
00483     }
00484 }
00485 
00486 #pragma mark -
00487 
00488 PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey)
00489     : ButtonWidget(boss, x, y, w, h, "", tooltip, cmd, hotkey),
00490       _alpha(255), _transparency(false), _showButton(true) {
00491 
00492     setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
00493     _type = kButtonWidget;
00494 }
00495 
00496 PicButtonWidget::PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd, uint8 hotkey)
00497     : ButtonWidget(boss, name, "", tooltip, cmd, hotkey),
00498       _alpha(255), _transparency(false), _showButton(true) {
00499     setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG);
00500     _type = kButtonWidget;
00501 }
00502 
00503 PicButtonWidget::~PicButtonWidget() {
00504     for (int i = 0; i < kPicButtonStateMax + 1; i++)
00505         _gfx[i].free();
00506 }
00507 
00508 void PicButtonWidget::setGfx(const Graphics::Surface *gfx, int statenum) {
00509     _gfx[statenum].free();
00510 
00511     if (!gfx || !gfx->getPixels())
00512         return;
00513 
00514     if (gfx->format.bytesPerPixel == 1) {
00515         warning("PicButtonWidget::setGfx got paletted surface passed");
00516         return;
00517     }
00518 
00519 
00520     if (gfx->w > _w || gfx->h > _h) {
00521         warning("PicButtonWidget has size %dx%d, but a surface with %dx%d is to be set", _w, _h, gfx->w, gfx->h);
00522         return;
00523     }
00524 
00525     _gfx[statenum].copyFrom(*gfx);
00526 }
00527 
00528 void PicButtonWidget::setGfx(int w, int h, int r, int g, int b, int statenum) {
00529     if (w == -1)
00530         w = _w;
00531     if (h == -1)
00532         h = _h;
00533 
00534     const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
00535 
00536     _gfx[statenum].free();
00537     _gfx[statenum].create(w, h, requiredFormat);
00538     _gfx[statenum].fillRect(Common::Rect(0, 0, w, h), _gfx[statenum].format.RGBToColor(r, g, b));
00539 }
00540 
00541 void PicButtonWidget::drawWidget() {
00542     if (_showButton)
00543         g_gui.theme()->drawButton(Common::Rect(_x, _y, _x + _w, _y + _h), "", _state, getFlags());
00544 
00545     Graphics::Surface *gfx;
00546 
00547     if (_state == ThemeEngine::kStateHighlight)
00548         gfx = &_gfx[kPicButtonHighlight];
00549     else if (_state == ThemeEngine::kStateDisabled)
00550         gfx = &_gfx[kPicButtonStateDisabled];
00551     else if (_state == ThemeEngine::kStatePressed)
00552         gfx = &_gfx[kPicButtonStatePressed];
00553     else
00554         gfx = &_gfx[kPicButtonStateEnabled];
00555 
00556     if (!gfx->getPixels())
00557         gfx = &_gfx[kPicButtonStateEnabled];
00558 
00559     if (gfx->getPixels()) {
00560         // Check whether the set up surface needs to be converted to the GUI
00561         // color format.
00562         const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
00563         if (gfx->format != requiredFormat) {
00564             gfx->convertToInPlace(requiredFormat);
00565         }
00566 
00567         const int x = _x + (_w - gfx->w) / 2;
00568         const int y = _y + (_h - gfx->h) / 2;
00569 
00570         g_gui.theme()->drawSurface(Common::Point(x, y), *gfx, _transparency);
00571     }
00572 }
00573 
00574 #pragma mark -
00575 
00576 CheckboxWidget::CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey)
00577     : ButtonWidget(boss, x, y, w, h, label, tooltip, cmd, hotkey), _state(false) {
00578     setFlags(WIDGET_ENABLED);
00579     _type = kCheckboxWidget;
00580 }
00581 
00582 CheckboxWidget::CheckboxWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey)
00583     : ButtonWidget(boss, name, label, tooltip, cmd, hotkey), _state(false) {
00584     setFlags(WIDGET_ENABLED);
00585     _type = kCheckboxWidget;
00586 }
00587 
00588 void CheckboxWidget::handleMouseUp(int x, int y, int button, int clickCount) {
00589     if (isEnabled() && _duringPress && x >= 0 && x < _w && y >= 0 && y < _h) {
00590         toggleState();
00591     }
00592     _duringPress = false;
00593 }
00594 
00595 void CheckboxWidget::setState(bool state) {
00596     if (_state != state) {
00597         _state = state;
00598         //_flags ^= WIDGET_INV_BORDER;
00599         markAsDirty();
00600     }
00601     sendCommand(_cmd, _state);
00602 }
00603 
00604 void CheckboxWidget::drawWidget() {
00605     g_gui.theme()->drawCheckbox(Common::Rect(_x, _y, _x + _w, _y + _h), _label, _state, Widget::_state);
00606 }
00607 
00608 #pragma mark -
00609 RadiobuttonGroup::RadiobuttonGroup(GuiObject *boss, uint32 cmd) : CommandSender(boss) {
00610     _value = -1;
00611     _cmd = cmd;
00612 }
00613 
00614 void RadiobuttonGroup::setValue(int value) {
00615     Common::Array<RadiobuttonWidget *>::iterator button = _buttons.begin();
00616     while (button != _buttons.end()) {
00617         (*button)->setState((*button)->getValue() == value, false);
00618 
00619         button++;
00620     }
00621 
00622     _value = value;
00623 
00624     sendCommand(_cmd, _value);
00625 }
00626 
00627 void RadiobuttonGroup::setEnabled(bool ena) {
00628     Common::Array<RadiobuttonWidget *>::iterator button = _buttons.begin();
00629     while (button != _buttons.end()) {
00630         (*button)->setEnabled(ena);
00631 
00632         button++;
00633     }
00634 }
00635 
00636 #pragma mark -
00637 
00638 RadiobuttonWidget::RadiobuttonWidget(GuiObject *boss, int x, int y, int w, int h, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip, uint8 hotkey)
00639     : ButtonWidget(boss, x, y, w, h, label, tooltip, 0, hotkey), _state(false), _value(value), _group(group) {
00640     setFlags(WIDGET_ENABLED);
00641     _type = kRadiobuttonWidget;
00642     _group->addButton(this);
00643 }
00644 
00645 RadiobuttonWidget::RadiobuttonWidget(GuiObject *boss, const Common::String &name, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip, uint8 hotkey)
00646     : ButtonWidget(boss, name, label, tooltip, 0, hotkey), _state(false), _value(value), _group(group) {
00647     setFlags(WIDGET_ENABLED);
00648     _type = kRadiobuttonWidget;
00649     _group->addButton(this);
00650 }
00651 
00652 void RadiobuttonWidget::handleMouseUp(int x, int y, int button, int clickCount) {
00653     if (isEnabled() && _duringPress && x >= 0 && x < _w && y >= 0 && y < _h) {
00654         toggleState();
00655     }
00656     _duringPress = false;
00657 }
00658 
00659 void RadiobuttonWidget::setState(bool state, bool setGroup) {
00660     if (setGroup) {
00661         _group->setValue(_value);
00662         return;
00663     }
00664 
00665     if (_state != state) {
00666         _state = state;
00667         //_flags ^= WIDGET_INV_BORDER;
00668         markAsDirty();
00669     }
00670     sendCommand(_cmd, _state);
00671 }
00672 
00673 void RadiobuttonWidget::drawWidget() {
00674     g_gui.theme()->drawRadiobutton(Common::Rect(_x, _y, _x + _w, _y + _h), _label, _state, Widget::_state);
00675 }
00676 
00677 #pragma mark -
00678 
00679 SliderWidget::SliderWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd)
00680     : Widget(boss, x, y, w, h, tooltip), CommandSender(boss),
00681       _cmd(cmd), _value(0), _oldValue(0), _valueMin(0), _valueMax(100), _isDragging(false), _labelWidth(0) {
00682     setFlags(WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG);
00683     _type = kSliderWidget;
00684 }
00685 
00686 SliderWidget::SliderWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd)
00687     : Widget(boss, name, tooltip), CommandSender(boss),
00688       _cmd(cmd), _value(0), _oldValue(0), _valueMin(0), _valueMax(100), _isDragging(false), _labelWidth(0) {
00689     setFlags(WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG);
00690     _type = kSliderWidget;
00691 }
00692 
00693 void SliderWidget::handleMouseMoved(int x, int y, int button) {
00694     if (isEnabled() && _isDragging) {
00695         int newValue = posToValue(x);
00696         if (newValue < _valueMin)
00697             newValue = _valueMin;
00698         else if (newValue > _valueMax)
00699             newValue = _valueMax;
00700 
00701         if (newValue != _value) {
00702             _value = newValue;
00703             markAsDirty();
00704             sendCommand(_cmd, _value);  // FIXME - hack to allow for "live update" in sound dialog
00705         }
00706     }
00707 }
00708 
00709 void SliderWidget::handleMouseDown(int x, int y, int button, int clickCount) {
00710     if (isEnabled()) {
00711         _isDragging = true;
00712         handleMouseMoved(x, y, button);
00713     }
00714 }
00715 
00716 void SliderWidget::handleMouseUp(int x, int y, int button, int clickCount) {
00717     if (isEnabled() && _isDragging) {
00718         sendCommand(_cmd, _value);
00719     }
00720     _isDragging = false;
00721 }
00722 
00723 void SliderWidget::handleMouseWheel(int x, int y, int direction) {
00724     if (isEnabled() && !_isDragging) {
00725         // Increment or decrement by one
00726         int newValue = _value - direction;
00727 
00728         if (newValue < _valueMin)
00729             newValue = _valueMin;
00730         else if (newValue > _valueMax)
00731             newValue = _valueMax;
00732 
00733         if (newValue != _value) {
00734             _value = newValue;
00735             markAsDirty();
00736             sendCommand(_cmd, _value);  // FIXME - hack to allow for "live update" in sound dialog
00737         }
00738     }
00739 }
00740 
00741 void SliderWidget::drawWidget() {
00742     g_gui.theme()->drawSlider(Common::Rect(_x, _y, _x + _w, _y + _h), valueToBarWidth(_value), _state);
00743 }
00744 
00745 int SliderWidget::valueToBarWidth(int value) {
00746     value = CLIP(value, _valueMin, _valueMax);
00747     return (_w * (value - _valueMin) / (_valueMax - _valueMin));
00748 }
00749 
00750 int SliderWidget::valueToPos(int value) {
00751     value = CLIP(value, _valueMin, _valueMax);
00752     return ((_w - 1) * (value - _valueMin + 1) / (_valueMax - _valueMin));
00753 }
00754 
00755 int SliderWidget::posToValue(int pos) {
00756     return (pos) * (_valueMax - _valueMin) / (_w - 1) + _valueMin;
00757 }
00758 
00759 #pragma mark -
00760 
00761 GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip)
00762     : Widget(boss, x, y, w, h, tooltip), _gfx(), _alpha(255), _transparency(false) {
00763     setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
00764     _type = kGraphicsWidget;
00765 }
00766 
00767 GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name, const char *tooltip)
00768     : Widget(boss, name, tooltip), _gfx(), _alpha(255), _transparency(false) {
00769     setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
00770     _type = kGraphicsWidget;
00771 }
00772 
00773 GraphicsWidget::~GraphicsWidget() {
00774     _gfx.free();
00775 }
00776 
00777 void GraphicsWidget::setGfx(const Graphics::Surface *gfx) {
00778     _gfx.free();
00779 
00780     if (!gfx || !gfx->getPixels())
00781         return;
00782 
00783     if (gfx->format.bytesPerPixel == 1) {
00784         warning("GraphicsWidget::setGfx got paletted surface passed");
00785         return;
00786     }
00787 
00788     if (gfx->w > _w || gfx->h > _h) {
00789         warning("GraphicsWidget has size %dx%d, but a surface with %dx%d is to be set", _w, _h, gfx->w, gfx->h);
00790         return;
00791     }
00792 
00793     _gfx.copyFrom(*gfx);
00794 }
00795 
00796 void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
00797     if (w == -1)
00798         w = _w;
00799     if (h == -1)
00800         h = _h;
00801 
00802     const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
00803 
00804     _gfx.free();
00805     _gfx.create(w, h, requiredFormat);
00806     _gfx.fillRect(Common::Rect(0, 0, w, h), _gfx.format.RGBToColor(r, g, b));
00807 }
00808 
00809 void GraphicsWidget::drawWidget() {
00810     if (_gfx.getPixels()) {
00811         // Check whether the set up surface needs to be converted to the GUI
00812         // color format.
00813         const Graphics::PixelFormat &requiredFormat = g_gui.theme()->getPixelFormat();
00814         if (_gfx.format != requiredFormat) {
00815             _gfx.convertToInPlace(requiredFormat);
00816         }
00817 
00818         const int x = _x + (_w - _gfx.w) / 2;
00819         const int y = _y + (_h - _gfx.h) / 2;
00820 
00821         g_gui.theme()->drawSurface(Common::Point(x, y), _gfx, _transparency);
00822     }
00823 }
00824 
00825 #pragma mark -
00826 
00827 ContainerWidget::ContainerWidget(GuiObject *boss, int x, int y, int w, int h) : Widget(boss, x, y, w, h) {
00828     setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
00829     _type = kContainerWidget;
00830 }
00831 
00832 ContainerWidget::ContainerWidget(GuiObject *boss, const Common::String &name) : Widget(boss, name) {
00833     setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
00834     _type = kContainerWidget;
00835 }
00836 
00837 ContainerWidget::~ContainerWidget() {
00838     // We also remove the widget from the boss to avoid segfaults, when the
00839     // deleted widget is an active widget in the boss.
00840     for (Widget *w = _firstWidget; w; w = w->next()) {
00841         _boss->removeWidget(w);
00842     }
00843 }
00844 
00845 bool ContainerWidget::containsWidget(Widget *w) const {
00846     return containsWidgetInChain(_firstWidget, w);
00847 }
00848 
00849 Widget *ContainerWidget::findWidget(int x, int y) {
00850     Widget *w = findWidgetInChain(_firstWidget, x, y);
00851     if (w)
00852         return w;
00853     return this;
00854 }
00855 
00856 void ContainerWidget::removeWidget(Widget *widget) {
00857     // We also remove the widget from the boss to avoid a reference to a
00858     // widget not in the widget chain anymore.
00859     _boss->removeWidget(widget);
00860 
00861     Widget::removeWidget(widget);
00862 }
00863 
00864 void ContainerWidget::drawWidget() {
00865     g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h), 0,
00866                                         ThemeEngine::kWidgetBackgroundBorder);
00867 }
00868 
00869 } // End of namespace GUI


Generated on Sat Feb 22 2020 05:00:55 for ResidualVM by doxygen 1.7.1
curved edge   curved edge