Mana
Loading...
Searching...
No Matches
button.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "gui/widgets/button.h"
23
24#include "graphics.h"
25
26#include "gui/gui.h"
27#include "gui/textpopup.h"
28
29#include "resources/image.h"
30#include "resources/theme.h"
31
32#include <guichan/exception.hpp>
33#include <guichan/font.hpp>
34
36
37enum {
42 BUTTON_COUNT // 4 - Must be last.
43};
44
46{
47 init();
48 adjustSize();
49}
50
51Button::Button(const std::string &caption, const std::string &actionEventId,
52 gcn::ActionListener *listener):
53 gcn::Button(caption)
54{
55 init();
56 setActionEventId(actionEventId);
57
58 if (listener)
59 addActionListener(listener);
60
61 adjustSize();
62}
63
64Button::~Button() = default;
65
66bool Button::setButtonIcon(const std::string &iconFile)
67{
68 // We clean up possible older references.
70
71 // If nothing relevant was set, we can quit now.
72 if (iconFile.empty())
73 return false;
74
75 // Load the icon frames.
76 auto btnIcons = Theme::getImageFromTheme(iconFile);
77 if (!btnIcons)
78 return false;
79
80 // Compute the sub images size.
81 const int frameWidth = btnIcons->getWidth() / 4;
82 const int frameHeight = btnIcons->getHeight();
83
84 if (frameWidth > 0 && frameHeight > 0)
85 {
87
88 for (int mode = 0; mode < BUTTON_COUNT; ++mode)
89 {
90 mButtonIcon[mode].reset(
91 btnIcons->getSubImage(mode * frameWidth, 0, frameWidth, frameHeight));
92 }
93
94 adjustSize();
95 }
96
97 return !mButtonIcon.empty();
98}
99
101{
102 if (mButtonIcon.empty())
103 return;
104
105 mButtonIcon.clear();
106 adjustSize();
107}
108
110{
111 auto &skin = gui->getTheme()->getSkin(SkinType::Button);
112 setFrameSize(skin.frameSize);
113 setSpacing(skin.padding);
114
115 // Create the tooltip popup. It is shared by all buttons and will get
116 // deleted by the WindowContainer.
117 if (!mTextPopup)
118 mTextPopup = new TextPopup;
119}
120
121void Button::draw(gcn::Graphics *graphics)
122{
123 WidgetState widgetState(this);
124 if (mHasMouse)
125 widgetState.flags |= STATE_HOVERED;
126 if (isPressed())
127 widgetState.flags |= STATE_SELECTED;
128
129 auto g = static_cast<Graphics *>(graphics);
130 auto &skin = gui->getTheme()->getSkin(SkinType::Button);
131 skin.draw(g, widgetState);
132
133 auto skinState = skin.getState(widgetState.flags);
134 auto font = (skinState && skinState->textFormat.bold) ? boldFont : getFont();
135
136 int mode;
137
138 if (widgetState.flags & STATE_DISABLED)
139 mode = BUTTON_DISABLED;
140 else if (widgetState.flags & STATE_SELECTED)
141 mode = BUTTON_PRESSED;
142 else if (widgetState.flags & (STATE_HOVERED | STATE_FOCUSED))
143 mode = BUTTON_HIGHLIGHTED;
144 else
145 mode = BUTTON_STANDARD;
146
147 Image *icon = mButtonIcon.empty() ? nullptr : mButtonIcon[mode].get();
148 int textX = 0;
149 int textY = getHeight() / 2 - font->getHeight() / 2;
150 int btnIconX = 0;
151 int btnIconY = getHeight() / 2 - (icon ? icon->getHeight() / 2 : 0);
152 int btnIconWidth = icon ? icon->getWidth() : 0;
153
154 switch (getAlignment())
155 {
156 case gcn::Graphics::LEFT:
157 if (btnIconWidth)
158 {
159 btnIconX = 4;
160 textX = btnIconX + icon->getWidth() + 2;
161 }
162 else
163 {
164 textX = 4;
165 }
166 break;
167 case gcn::Graphics::CENTER:
168 if (btnIconWidth)
169 {
170 btnIconX = (getWidth() - font->getWidth(mCaption) - icon->getWidth() - 2) / 2;
171 textX = (getWidth() + icon->getWidth()) / 2 + 2;
172 }
173 else
174 {
175 textX = getWidth() / 2;
176 }
177 break;
178 case gcn::Graphics::RIGHT:
179 if (btnIconWidth)
180 btnIconX = getWidth() - 4 - font->getWidth(mCaption) - 2;
181 textX = getWidth() - 4;
182 break;
183 default:
184 throw GCN_EXCEPTION("Button::draw(). Unknown alignment.");
185 }
186
187 if (isPressed())
188 {
189 textX++; textY++;
190 btnIconX++; btnIconY++;
191 }
192
193 if (btnIconWidth)
194 g->drawImage(icon, btnIconX, btnIconY);
195
196 if (auto skinState = skin.getState(widgetState.flags))
197 {
198 g->drawText(getCaption(),
199 textX,
200 textY,
201 getAlignment(),
202 font,
203 skinState->textFormat);
204 }
205}
206
208{
209 // Size of the image button.
210 int iconWidth = 0, iconHeight = 0;
211 if (!mButtonIcon.empty())
212 {
213 for (int mode = 0; mode < BUTTON_COUNT; ++mode)
214 {
215 const Image *icon = mButtonIcon[mode].get();
216 iconWidth = std::max(iconWidth, icon->getWidth() + 2);
217 iconHeight = std::max(iconHeight, icon->getHeight());
218 }
219 }
220
221 setWidth(std::max(getFont()->getWidth(mCaption) + iconWidth + 2, iconWidth)
222 + 2 * mSpacing);
223 setHeight(std::max(getFont()->getHeight(), iconHeight) + 2 * mSpacing);
224}
225
226void Button::setCaption(const std::string& caption)
227{
228 mCaption = caption;
229 adjustSize();
230}
231
232void Button::mouseMoved(gcn::MouseEvent &event)
233{
234 gcn::Button::mouseMoved(event);
235
236 int x = event.getX();
237 int y = event.getY();
238
239 if (event.getSource() == this && !mPopupText.empty())
240 {
241 if (mParent)
242 {
243 x += mParent->getX();
244 y += mParent->getY();
245 }
246
247 mTextPopup->show(x + getX(), y + getY(), mPopupText);
248 }
249 else
250 {
251 mTextPopup->setVisible(false);
252 }
253}
254
255void Button::mouseExited(gcn::MouseEvent &event)
256{
257 gcn::Button::mouseExited(event);
258
259 mTextPopup->setVisible(false);
260}
@ BUTTON_HIGHLIGHTED
Definition button.cpp:39
@ BUTTON_DISABLED
Definition button.cpp:41
@ BUTTON_COUNT
Definition button.cpp:42
@ BUTTON_STANDARD
Definition button.cpp:38
@ BUTTON_PRESSED
Definition button.cpp:40
Button widget.
Definition button.h:38
static TextPopup * mTextPopup
The buttons popup.
Definition button.h:95
void setCaption(const std::string &caption)
Definition button.cpp:226
Button()
Default constructor.
Definition button.cpp:45
void init()
Definition button.cpp:109
bool setButtonIcon(const std::string &iconFile)
Set the icons available next to the text.
Definition button.cpp:66
void draw(gcn::Graphics *graphics) override
Draws the button.
Definition button.cpp:121
void removeButtonIcon()
Definition button.cpp:100
void adjustSize()
Definition button.cpp:207
std::vector< std::unique_ptr< Image > > mButtonIcon
Button Icons graphics.
Definition button.h:89
std::string mPopupText
the current button text
Definition button.h:96
~Button() override
void mouseExited(gcn::MouseEvent &event) override
Definition button.cpp:255
void mouseMoved(gcn::MouseEvent &event) override
Definition button.cpp:232
A central point of control for graphics.
Definition graphics.h:78
Theme * getTheme() const
The global GUI theme.
Definition gui.h:138
Defines a class for loading and storing images.
Definition image.h:45
int getHeight() const
Returns the height of the image.
Definition image.h:89
int getWidth() const
Returns the width of the image.
Definition image.h:83
void draw(Graphics *graphics, const WidgetState &state) const
Definition theme.cpp:122
A popup that displays information about an item.
Definition textpopup.h:36
void show(int x, int y, const std::string &str1, const std::string &str2=std::string())
Sets the text to be displayed.
Definition textpopup.cpp:54
const Skin & getSkin(SkinType skinType) const
Definition theme.cpp:434
static ResourceRef< Image > getImageFromTheme(const std::string &path)
Definition theme.cpp:308
Graphics * graphics
Definition client.cpp:104
Gui * gui
The GUI system.
Definition gui.cpp:50
gcn::Font * boldFont
Bolded text font.
Definition gui.cpp:54
uint8_t flags
Definition theme.h:150
@ STATE_HOVERED
Definition theme.h:105
@ STATE_DISABLED
Definition theme.h:107
@ STATE_FOCUSED
Definition theme.h:108
@ STATE_SELECTED
Definition theme.h:106