Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UI|Client|ToggleWidget: Added ToggleWidget
A simple on/off toggle based on a button. The on/off graphic from the style is stored centrally by GuiRootWidget. Uses a procedural image to draw the state of the toggle.
- Loading branch information
Showing
6 changed files
with
228 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** @file togglewidget.h Toggle widget. | ||
* | ||
* @authors Copyright (c) 2013 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, see: | ||
* http://www.gnu.org/licenses</small> | ||
*/ | ||
|
||
#ifndef DENG_CLIENT_TOGGLEWIDGET_H | ||
#define DENG_CLIENT_TOGGLEWIDGET_H | ||
|
||
#include "buttonwidget.h" | ||
|
||
/** | ||
* Toggle is a specialized button that maintains an on/off state in addition to | ||
* the state of a ButtonWidget. | ||
*/ | ||
class ToggleWidget : public ButtonWidget | ||
{ | ||
public: | ||
enum ToggleState { | ||
Active, | ||
Inactive | ||
}; | ||
|
||
/** | ||
* Audience to be notified whenever the toggle is toggled. | ||
*/ | ||
DENG2_DEFINE_AUDIENCE(Toggle, void toggleStateChanged(ToggleWidget &toggle)) | ||
|
||
public: | ||
ToggleWidget(de::String const &name = ""); | ||
|
||
/** | ||
* Sets the toggle state of the widget. | ||
*/ | ||
void setToggleState(ToggleState state, bool notify = true); | ||
|
||
void setActive(bool activate) { setToggleState(activate? Active : Inactive); } | ||
void setInactive(bool deactivate) { setToggleState(deactivate? Inactive : Active ); } | ||
|
||
ToggleState toggleState() const; | ||
|
||
bool isActive() const { return toggleState() == Active; } | ||
bool isInactive() const { return toggleState() == Inactive; } | ||
|
||
private: | ||
DENG2_PRIVATE(d) | ||
}; | ||
|
||
#endif // DENG_CLIENT_TOGGLEWIDGET_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/** @file togglewidget.cpp Toggle widget. | ||
* | ||
* @authors Copyright (c) 2013 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, see: | ||
* http://www.gnu.org/licenses</small> | ||
*/ | ||
|
||
#include "ui/widgets/togglewidget.h" | ||
#include "ui/widgets/proceduralimage.h" | ||
#include "ui/widgets/guirootwidget.h" | ||
#include "ui/style.h" | ||
#include "clientapp.h" | ||
|
||
#include <de/Animation> | ||
|
||
using namespace de; | ||
|
||
static TimeDelta const SWITCH_ANIM_SPAN = 0.3; | ||
|
||
DENG2_PIMPL(ToggleWidget), | ||
DENG2_OBSERVES(ButtonWidget, Press) | ||
{ | ||
struct ToggleProceduralImage : public ProceduralImage | ||
{ | ||
ToggleProceduralImage(GuiWidget &owner) | ||
: _owner(owner), | ||
_pos(1, Animation::EaseBoth), | ||
_animating(false) | ||
{ | ||
setSize(style().images().image("toggle.onoff").size()); | ||
} | ||
|
||
Style const &style() const { return _owner.style(); } | ||
Atlas &atlas() const { return _owner.root().atlas(); } | ||
|
||
void setState(ToggleState st) | ||
{ | ||
_pos.setValue(st == Inactive? 1 : 0, SWITCH_ANIM_SPAN); | ||
_animating = true; | ||
} | ||
|
||
void update() | ||
{ | ||
if(_animating) | ||
{ | ||
_owner.requestGeometry(); | ||
if(_pos.done()) _animating = false; | ||
} | ||
} | ||
|
||
void glMakeGeometry(DefaultVertexBuf::Builder &verts, Rectanglef const &rect) | ||
{ | ||
ColorBank::Colorf const &textColor = style().colors().colorf("text"); | ||
ColorBank::Colorf const &accentColor = style().colors().colorf("accent"); | ||
|
||
// Background. | ||
ColorBank::Colorf bgColor = style().colors().colorf("background"); | ||
bgColor.w = 1; | ||
verts.makeQuad(rect, accentColor * .5f * _pos + bgColor * (1 - _pos), | ||
atlas().imageRectf(_owner.root().solidWhitePixel()).middle()); | ||
|
||
Id onOff = _owner.root().toggleOnOff(); | ||
|
||
// The on/off background. | ||
verts.makeQuad(rect, accentColor * _pos + textColor * (1 - _pos), | ||
atlas().imageRectf(onOff)); | ||
|
||
// The flipper. | ||
Rectanglef flip = Rectanglef::fromSize(rect.topLeft + | ||
Vector2f(1 + de::round<int>((1 - _pos) * (size().x - size().y)), 1), | ||
Vector2f(size().y, size().y) - Vector2ui(2, 2)); | ||
verts.makeQuad(flip, bgColor, atlas().imageRectf(_owner.root().solidWhitePixel()).middle()); | ||
} | ||
|
||
private: | ||
GuiWidget &_owner; | ||
Animation _pos; | ||
bool _animating; | ||
}; | ||
|
||
ToggleState state; | ||
ToggleProceduralImage *procImage; | ||
|
||
Instance(Public *i) | ||
: Base(i), | ||
state(Inactive), | ||
procImage(new ToggleProceduralImage(self)) | ||
{ | ||
self.setImage(procImage); | ||
|
||
self.audienceForPress += this; | ||
} | ||
|
||
~Instance() | ||
{ | ||
self.audienceForPress -= this; | ||
} | ||
|
||
void buttonPressed(ButtonWidget &) | ||
{ | ||
// Toggle the state. | ||
self.setActive(self.isInactive()); | ||
} | ||
}; | ||
|
||
ToggleWidget::ToggleWidget(String const &name) : ButtonWidget(name), d(new Instance(this)) | ||
{ | ||
setTextAlignment(ui::AlignRight); | ||
setTextLineAlignment(ui::AlignLeft); | ||
} | ||
|
||
void ToggleWidget::setToggleState(ToggleState state, bool notify) | ||
{ | ||
if(d->state != state) | ||
{ | ||
d->state = state; | ||
d->procImage->setState(state); | ||
|
||
if(notify) | ||
{ | ||
DENG2_FOR_AUDIENCE(Toggle, i) i->toggleStateChanged(*this); | ||
} | ||
} | ||
} | ||
|
||
ToggleWidget::ToggleState ToggleWidget::toggleState() const | ||
{ | ||
return d->state; | ||
} |