1 /** @file buttonwidget.cpp Button widget.
2 *
3 * @authors Copyright © 2005-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4 * @authors Copyright © 2005-2014 Daniel Swanson <danij@dengine.net>
5 *
6 * @par License
7 * GPL: http://www.gnu.org/licenses/gpl.html
8 *
9 * <small>This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. This program is distributed in the hope that it
13 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 * Public License for more details. You should have received a copy of the GNU
16 * General Public License along with this program; if not, write to the Free
17 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA</small>
19 */
20
21 #include "common.h"
22 #include "menu/widgets/buttonwidget.h"
23
24 #include "g_defs.h"
25 #include "hu_menu.h" // menu sounds
26 #include "hu_stuff.h"
27 #include "menu/page.h" // mnRendState
28
29 using namespace de;
30
31 namespace common {
32 namespace menu {
33
DENG2_PIMPL_NOREF(ButtonWidget)34 DENG2_PIMPL_NOREF(ButtonWidget)
35 {
36 String text; ///< Label text.
37 patchid_t patch = -1; ///< Used when drawing this instead of text, if set.
38 bool noAltText = false;
39 bool silent = false;
40 };
41
ButtonWidget(String const & text,patchid_t patch)42 ButtonWidget::ButtonWidget(String const &text, patchid_t patch)
43 : Widget()
44 , d(new Impl)
45 {
46 setFont(MENU_FONT2);
47 setColor(MENU_COLOR1);
48
49 setText(text);
50 setPatch(patch);
51 }
52
~ButtonWidget()53 ButtonWidget::~ButtonWidget()
54 {}
55
draw() const56 void ButtonWidget::draw() const
57 {
58 fontid_t const fontId = mnRendState->textFonts[font()];
59 Vector4f const &textColor = mnRendState->textColors[color()];
60 //float t = (isFocused()? 1 : 0);
61
62 const Vector4f color = selectionFlashColor(textColor);
63
64 // // Flash if focused.
65 // if (isFocused() && cfg.common.menuTextFlashSpeed > 0)
66 // {
67 // float const speed = cfg.common.menuTextFlashSpeed / 2.f;
68 // t = (1 + sin(page().timer() / (float)TICSPERSEC * speed * DD_PI)) / 2;
69 // }
70 // Vector4f const color = de::lerp(textColor, Vector4f(Vector3f(cfg.common.menuTextFlashColor), textColor.w), t);
71
72 const float fadeout = scrollingFadeout();
73 if (fadeout < .001f) return;
74
75 FR_SetFont(fontId);
76 FR_SetColorAndAlpha(color.x, color.y, color.z, color.w * fadeout);
77 DGL_Color4f(1, 1, 1, color.w * fadeout);
78
79 if(d->patch >= 0)
80 {
81 String replacement;
82 if(!d->noAltText)
83 {
84 replacement = Hu_ChoosePatchReplacement(patchreplacemode_t(cfg.common.menuPatchReplaceMode), d->patch, d->text);
85 }
86
87 DGL_Enable(DGL_TEXTURE_2D);
88 WI_DrawPatch(d->patch,
89 replacement,
90 geometry().topLeft,
91 ALIGN_TOPLEFT,
92 0,
93 Hu_MenuMergeEffectWithDrawTextFlags(0));
94 DGL_Disable(DGL_TEXTURE_2D);
95
96 return;
97 }
98
99 DGL_Enable(DGL_TEXTURE_2D);
100 FR_DrawTextXY3(d->text.toUtf8().constData(), geometry().topLeft.x, geometry().topLeft.y,
101 ALIGN_TOPLEFT, Hu_MenuMergeEffectWithDrawTextFlags(0));
102 DGL_Disable(DGL_TEXTURE_2D);
103 }
104
handleCommand(menucommand_e cmd)105 int ButtonWidget::handleCommand(menucommand_e cmd)
106 {
107 if (cmd == MCMD_SELECT)
108 {
109 if (!isActive())
110 {
111 setFlags(Active);
112 execAction(Activated);
113 }
114 // We are not going to receive a separate "up event".
115 if (!d->silent)
116 {
117 S_LocalSound(SFX_MENU_ACCEPT, NULL);
118 }
119 setFlags(Active, UnsetFlags);
120 execAction(Deactivated);
121 return true;
122 }
123 return false; // Not eaten.
124 }
125
setSilent(bool silent)126 void ButtonWidget::setSilent(bool silent)
127 {
128 d->silent = silent;
129 }
130
updateGeometry()131 void ButtonWidget::updateGeometry()
132 {
133 String useText = d->text;
134
135 // @todo What if patch replacement is disabled?
136 if(d->patch >= 0)
137 {
138 if(!d->noAltText)
139 {
140 // Use the replacement string?
141 useText = Hu_ChoosePatchReplacement(patchreplacemode_t(cfg.common.menuPatchReplaceMode), d->patch, d->text);
142 }
143
144 if(useText.isEmpty())
145 {
146 // Use the original patch.
147 patchinfo_t info;
148 R_GetPatchInfo(d->patch, &info);
149 geometry().setSize(Vector2ui(info.geometry.size.width, info.geometry.size.height));
150 return;
151 }
152 }
153
154 FR_PushAttrib();
155 Size2Raw size;
156 FR_SetFont(page().predefinedFont(mn_page_fontid_t(font())));
157 FR_TextSize(&size, useText.toUtf8().constData());
158 geometry().setSize(Vector2ui(size.width, size.height));
159 FR_PopAttrib();
160 }
161
text() const162 String ButtonWidget::text() const
163 {
164 return d->text;
165 }
166
setText(String const & newText)167 ButtonWidget &ButtonWidget::setText(String const &newText)
168 {
169 d->text = labelText(newText);
170 return *this;
171 }
172
patch() const173 patchid_t ButtonWidget::patch() const
174 {
175 return d->patch;
176 }
177
setPatch(patchid_t newPatch)178 ButtonWidget &ButtonWidget::setPatch(patchid_t newPatch)
179 {
180 d->patch = newPatch;
181 return *this;
182 }
183
noAltText() const184 bool ButtonWidget::noAltText() const
185 {
186 return d->noAltText;
187 }
188
setNoAltText(bool yes)189 ButtonWidget &ButtonWidget::setNoAltText(bool yes)
190 {
191 d->noAltText = yes;
192 return *this;
193 }
194
195 } // namespace menu
196 } // namespace common
197