Mana
Loading...
Searching...
No Matches
emotepopup.cpp
Go to the documentation of this file.
1/*
2 * Extended support for activating emotes
3 * Copyright (C) 2009 Aethyra Development Team
4 * Copyright (C) 2009 The Mana World Development Team
5 * Copyright (C) 2009-2012 The Mana Developers
6 *
7 * This file is part of The Mana Client.
8 *
9 * 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
11 * the Free Software Foundation; either version 2 of the License, or
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include "gui/emotepopup.h"
24
25#include "emoteshortcut.h"
26#include "graphics.h"
27
28#include "gui/gui.h"
29#include "resources/emotedb.h"
30#include "resources/image.h"
31#include "resources/theme.h"
32
33#include <guichan/mouseinput.hpp>
34#include <guichan/selectionlistener.hpp>
35
36static const int MAX_COLUMNS = 6;
37
39{
40 addMouseListener(this);
42 setVisible(true);
43}
44
45EmotePopup::~EmotePopup() = default;
46
47void EmotePopup::draw(gcn::Graphics *graphics)
48{
49 auto *g = static_cast<Graphics*>(graphics);
50
52
53 const int emoteCount = EmoteDB::getEmoteCount();
54
55 auto &slotSkin = gui->getTheme()->getSkin(SkinType::EmoteSlot);
56 WidgetState slotState;
57 slotState.width = slotSkin.width;
58 slotState.height = slotSkin.height;
59
60 for (int i = 0; i < emoteCount ; i++)
61 {
62 int row = i / mColumnCount;
63 int column = i % mColumnCount;
64
65 slotState.x = getPadding() + column * slotSkin.width;
66 slotState.y = getPadding() + row * slotSkin.height;
67
68 // Center the last row when there are less emotes than columns
69 if (row == mRowCount - 1)
70 {
71 const int emotesLeft = emoteCount % mColumnCount;
72 slotState.x += (mColumnCount - emotesLeft) * slotSkin.width / 2;
73 }
74
75 slotState.flags = 0;
76
77 // Draw selection image below hovered item
78 if (i == mHoveredEmoteIndex)
79 slotState.flags |= STATE_HOVERED;
80
81 slotSkin.draw(g, slotState);
82
83 // Draw emote icon
84 if (auto image = EmoteDB::getByIndex(i).image)
85 {
86 image->setAlpha(1.0f);
87 g->drawImage(image,
88 slotState.x + (slotSkin.width - image->getWidth()) / 2,
89 slotState.y + (slotSkin.height - image->getHeight()) / 2);
90 }
91 }
92}
93
94void EmotePopup::mouseExited(gcn::MouseEvent &event)
95{
96 Popup::mouseExited(event);
97
99}
100
101void EmotePopup::mousePressed(gcn::MouseEvent &event)
102{
103 if (event.getButton() != gcn::MouseEvent::LEFT)
104 return;
105
106 const int index = getIndexAt(event.getX(), event.getY());
107 if (index != -1)
108 {
109 const int emoteId = EmoteDB::getByIndex(index).id;
110
111 setSelectedEmoteId(emoteId);
113 }
114}
115
116void EmotePopup::mouseMoved(gcn::MouseEvent &event)
117{
118 Popup::mouseMoved(event);
119
120 mHoveredEmoteIndex = getIndexAt(event.getX(), event.getY());
121}
122
124{
125 return mSelectedEmoteId;
126}
127
129{
130 if (emoteId == mSelectedEmoteId)
131 return;
132
133 mSelectedEmoteId = emoteId;
135}
136
137int EmotePopup::getIndexAt(int x, int y) const
138{
139 if (mColumnCount <= 0)
140 return -1;
141
142 // Take into account the border
143 x -= getPadding();
144 y -= getPadding();
145
146 auto &slotSkin = gui->getTheme()->getSkin(SkinType::EmoteSlot);
147
148 const int row = y / slotSkin.height;
149
150 // Take into account that the last row is centered
151 if (row == mRowCount - 1)
152 {
153 const int emotesLeft = EmoteDB::getEmoteCount() % mColumnCount;
154 const int emotesMissing = mColumnCount - emotesLeft;
155 x -= emotesMissing * slotSkin.width / 2;
156 if (x < 0)
157 return -1;
158 }
159
160 const int column = std::min(x / slotSkin.width, mColumnCount - 1);
161 const int index = column + (row * mColumnCount);
162
163 if (index >= 0 && index < EmoteDB::getEmoteCount())
164 return index;
165
166 return -1;
167}
168
170{
171 const int emoteCount = EmoteDB::getEmoteCount();
172
173 if (emoteCount > 0) {
174 mRowCount = emoteCount / MAX_COLUMNS;
175 if (emoteCount % MAX_COLUMNS > 0)
176 ++mRowCount;
177
178 mColumnCount = std::min(MAX_COLUMNS, emoteCount);
179 } else {
180 mRowCount = 0;
181 mColumnCount = 0;
182 }
183
184 auto &slotSkin = gui->getTheme()->getSkin(SkinType::EmoteSlot);
185 setContentSize(mColumnCount * slotSkin.width, mRowCount * slotSkin.height);
186}
187
189{
190 const gcn::SelectionEvent event(this);
191
192 for (auto &listener : mListeners)
193 listener->valueChanged(event);
194}
int mSelectedEmoteId
Definition emotepopup.h:106
void recalculateSize()
Determine and set the size of the container.
EmotePopup()
Constructor.
void mouseExited(gcn::MouseEvent &event) override
int getIndexAt(int x, int y) const
Returns the index at the specified coordinates.
void mouseMoved(gcn::MouseEvent &event) override
void setSelectedEmoteId(int emoteId)
Sets the index of the currently selected emote.
~EmotePopup() override
void distributeValueChangedEvent()
Sends out selection events to the list of selection listeners.
void draw(gcn::Graphics *graphics) override
Draws the emotes.
int mColumnCount
Definition emotepopup.h:110
void mousePressed(gcn::MouseEvent &event) override
int mHoveredEmoteIndex
Definition emotepopup.h:107
int getSelectedEmoteId() const
Returns the selected emote.
std::list< gcn::SelectionListener * > mListeners
Definition emotepopup.h:112
void setEmoteSelected(int emoteId)
Set the Emote that is selected.
A central point of control for graphics.
Definition graphics.h:78
Theme * getTheme() const
The global GUI theme.
Definition gui.h:138
void mouseMoved(gcn::MouseEvent &event) override
Definition popup.cpp:205
int getPadding() const
Gets the padding of the popup.
Definition popup.h:132
void draw(gcn::Graphics *graphics) override
Draws the popup.
Definition popup.cpp:104
void setContentSize(int width, int height)
Sets the size of this popup.
Definition popup.cpp:127
int height
Definition theme.h:181
const Skin & getSkin(SkinType skinType) const
Definition theme.cpp:434
Graphics * graphics
Definition client.cpp:104
EmoteShortcut * emoteShortcut
Gui * gui
The GUI system.
Definition gui.cpp:50
const Emote & getByIndex(int index)
Definition emotedb.cpp:129
int getEmoteCount()
Definition emotedb.cpp:134
int id
Definition emotedb.h:33
uint8_t flags
Definition theme.h:150
int width
Definition theme.h:148
int height
Definition theme.h:149
@ STATE_HOVERED
Definition theme.h:105