ManaPlus
skilllistbox.h
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus 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 #ifndef GUI_WIDGETS_SKILLLISTBOX_H
24 #define GUI_WIDGETS_SKILLLISTBOX_H
25 
26 #include "const/resources/skill.h"
27 
28 #include "dragdrop.h"
29 
30 #include "gui/skin.h"
31 #include "gui/viewport.h"
32 
33 #include "gui/widgets/listbox.h"
34 
35 #include "gui/fonts/font.h"
36 
37 #include "gui/models/skillmodel.h"
38 
39 #include "gui/popups/popupmenu.h"
40 #include "gui/popups/skillpopup.h"
41 
42 #include "utils/delete2.h"
43 
44 #include "render/graphics.h"
45 
46 #include "localconsts.h"
47 
48 class SkillModel;
49 
50 class SkillListBox final : public ListBox
51 {
52  public:
53  SkillListBox(const Widget2 *const widget,
54  SkillModel *const model) :
55  ListBox(widget, model, "skilllistbox.xml"),
56  mModel(model),
61  mSkin->getOption("textPadding", 34) : 34),
62  mSpacing(mSkin != nullptr ? mSkin->getOption("spacing", 0) : 0),
63  mSkillClicked(false)
64  {
65  mRowHeight = getFont()->getHeight() * 2 + mSpacing + 2 * mPadding;
67 
68  if (mRowHeight < 34)
69  mRowHeight = 34;
70  }
71 
73 
75  {
77  }
78 
80  {
81  const int selected = getSelected();
82  if ((mListModel == nullptr) || selected < 0
83  || selected > mListModel->getNumberOfElements())
84  {
85  return nullptr;
86  }
87 
88  return static_cast<SkillModel*>(mListModel)->getSkillAt(selected);
89  }
90 
91  void draw(Graphics *const graphics) override final A_NONNULL(2)
92  {
93  if (mListModel == nullptr)
94  return;
95 
96  SkillModel *const model = static_cast<SkillModel*>(mListModel);
97  updateAlpha();
98 
99  mHighlightColor.a = CAST_S32(mAlpha * 255.0F);
100  graphics->setColor(mHighlightColor);
101 
102  const int width1 = getWidth();
103  const int usableWidth = width1 - 2 * mPadding;
104 
105  // Draw filled rectangle around the selected list element
106  if (mSelected >= 0)
107  {
108  graphics->fillRectangle(Rect(mPadding, getRowHeight()
109  * mSelected + mPadding, usableWidth,
110  getRowHeight()));
111  }
112 
113  // Draw the list elements
114  Font *const font = getFont();
115  const int space = font->getHeight() + mSpacing;
116  const int width2 = width1 - mPadding;
117 
118  graphics->setColor(mCooldownColor);
119  for (int i = 0, y = 1 + mPadding;
120  i < model->getNumberOfElements();
121  ++i, y += getRowHeight())
122  {
123  SkillInfo *const e = model->getSkillAt(i);
124  if (e != nullptr)
125  {
126  if (e->cooldown != 0)
127  {
128  graphics->fillRectangle(Rect(mPadding, y,
129  usableWidth * 100 / e->cooldown, 10));
130  }
131  }
132  }
133 
134  for (int i = 0, y = 1 + mPadding;
135  i < model->getNumberOfElements();
136  ++i, y += getRowHeight())
137  {
138  SkillInfo *const e = model->getSkillAt(i);
139  if (e != nullptr)
140  {
141  const SkillData *const data = e->data;
142  const std::string &description = data->description;
143  graphics->drawImage(data->icon, mPadding, y);
144  font->drawString(graphics,
145  mTextColor,
146  mTextColor2,
147  data->name,
148  mTextPadding, y);
149  if (!description.empty())
150  {
151  font->drawString(graphics,
152  mTextColor,
153  mTextColor2,
154  description,
155  mTextPadding,
156  y + space);
157  }
158 
159  if (e->skillLevelWidth < 0)
160  {
161  // Add one for padding
162  e->skillLevelWidth = font->getWidth(e->skillLevel) + 1;
163  }
164 
165  font->drawString(graphics,
166  mTextColor,
167  mTextColor2,
168  e->skillLevel,
169  width2 - e->skillLevelWidth,
170  y);
171  }
172  }
173  }
174 
175  void safeDraw(Graphics *const graphics) override final A_NONNULL(2)
176  {
177  SkillListBox::draw(graphics);
178  }
179 
180  unsigned int getRowHeight() const override final
181  { return mRowHeight; }
182 
183  const SkillInfo *getSkillByEvent(const MouseEvent &event) const
184  {
185  const int y = (event.getY() + mPadding) / getRowHeight();
186  if (mModel == nullptr || y >= mModel->getNumberOfElements())
187  return nullptr;
188  const SkillInfo *const skill = mModel->getSkillAt(y);
189  if (skill == nullptr)
190  return nullptr;
191  return skill;
192  }
193 
194  void mouseMoved(MouseEvent &event) override final
195  {
196  ListBox::mouseMoved(event);
197  if ((viewport == nullptr) || !dragDrop.isEmpty())
198  return;
199 
200  const SkillInfo *const skill = getSkillByEvent(event);
201  if (skill == nullptr)
202  return;
203  skillPopup->show(skill,
204  skill->customSelectedLevel,
205  skill->customCastType,
206  skill->customOffsetX,
207  skill->customOffsetY);
209  viewport->mMouseY);
210  }
211 
212  void mouseDragged(MouseEvent &event) override final
213  {
214  if (event.getButton() == MouseButton::LEFT)
215  {
216  if (dragDrop.isEmpty())
217  {
218  if (mSkillClicked)
219  {
220  mSkillClicked = false;
221  const SkillInfo *const skill = getSkillByEvent(event);
222  if (skill == nullptr)
223  return;
225  dragDrop.setItem(skill->id + SKILL_MIN_ID);
226  dragDrop.setItemData(skill->toDataStr());
227  }
228  ListBox::mouseDragged(event);
229  }
230  }
231  else
232  {
233  ListBox::mouseDragged(event);
234  }
235  }
236 
237  void mousePressed(MouseEvent &event) override final
238  {
239  ListBox::mousePressed(event);
240  const MouseButtonT button = event.getButton();
241  if (button == MouseButton::LEFT ||
242  button == MouseButton::RIGHT)
243  {
244  const SkillInfo *const skill = getSkillByEvent(event);
245  if (skill == nullptr)
246  return;
247  event.consume();
248  mSkillClicked = true;
249  SkillModel *const model = static_cast<SkillModel*>(
250  mListModel);
251  if ((model != nullptr) &&
252  mSelected >= 0 &&
253  model->getSkillAt(mSelected) == skill)
254  {
255  skillPopup->hide();
256  if (button == MouseButton::LEFT &&
257  event.getX() >
258  getWidth() - mPadding - skill->skillLevelWidth)
259  {
261  }
262  else if (button == MouseButton::RIGHT)
263  {
264  popupMenu->showSkillPopup(skill);
265  }
266  }
267  }
268  }
269 
270  void mouseReleased(MouseEvent &event) override final
271  {
272  ListBox::mouseReleased(event);
273  }
274 
275  void mouseExited(MouseEvent &event A_UNUSED) override final
276  {
277  skillPopup->hide();
278  }
279 
280  private:
286  int mSpacing;
288 };
289 
290 #endif // GUI_WIDGETS_SKILLLISTBOX_H
#define A_DELETE_COPY(func)
Definition: localconsts.h:52
SkillInfo * getSkillAt(const int i) const
Definition: skillmodel.cpp:38
Font * getFont() const
Definition: widget.cpp:330
unsigned int id
Definition: skillinfo.h:68
int mSelected
Definition: listbox.h:255
Skin * mSkin
Definition: listbox.h:290
int mPadding
Definition: listbox.h:286
int getWidth() const
Definition: widget.h:220
void mouseMoved(MouseEvent &event)
Definition: skilllistbox.h:194
bool skill(InputEvent &event)
Definition: commands.cpp:96
Definition: font.h:88
unsigned int a
Definition: color.h:250
SkillPopup * skillPopup
Definition: skillpopup.cpp:41
void mouseExited(MouseEvent &event)
Definition: skilllistbox.h:275
Color mTextColor2
Definition: skilllistbox.h:283
Definition: rect.h:72
void mouseDragged(MouseEvent &event)
Definition: skilllistbox.h:212
int cooldown
Definition: skillinfo.h:73
CastTypeT customCastType
Definition: skillinfo.h:78
std::string name
Definition: skilldata.h:33
std::string description
Definition: skilldata.h:36
Color mTextColor
Definition: skilllistbox.h:282
#define final
Definition: localconsts.h:45
unsigned int mRowHeight
Definition: listbox.h:288
SkillInfo * getSelectedInfo() const
Definition: skilllistbox.h:79
Color mHighlightColor
Definition: listbox.h:282
DragDrop dragDrop
void mouseDragged(MouseEvent &event)
Definition: listbox.cpp:354
virtual int getNumberOfElements()=0
Color mCooldownColor
Definition: skilllistbox.h:284
int mMouseX
Definition: viewport.h:153
#define delete2(var)
Definition: delete2.h:24
bool isEmpty() const
Definition: dragdrop.h:195
#define A_NONNULL(...)
Definition: localconsts.h:159
int customOffsetY
Definition: skillinfo.h:66
const int SKILL_MIN_ID
Definition: skill.h:24
void show(const SkillInfo *const skill, const int level, const CastTypeT type, const int offsetX, const int offsetY)
Definition: skillpopup.cpp:105
ListModel * mListModel
Definition: listbox.h:260
Image * icon
Definition: skilldata.h:46
void showSkillPopup(const SkillInfo *const info)
Definition: popupmenu.cpp:2263
SkillData * data
Definition: skillinfo.h:62
std::string toDataStr() const
Definition: skillinfo.cpp:198
void hide()
Definition: popup.cpp:262
#define CAST_S32
Definition: cast.h:29
void mousePressed(MouseEvent &event)
Definition: listbox.cpp:303
SkillModel * mModel
Definition: skilllistbox.h:281
void setItemData(const std::string &data)
Definition: dragdrop.h:77
void dragSkill(const SkillInfo *const info, const DragDropSourceT source, const int tag)
Definition: dragdrop.h:151
uint32_t data
PopupMenu * popupMenu
Definition: popupmenu.cpp:102
void position(const int x, const int y)
Definition: popup.cpp:232
void drawString(Graphics *const graphics, Color col, const Color &col2, const std::string &text, const int x, const int y)
Definition: font.cpp:253
void updateAlpha()
Definition: listbox.cpp:153
int getNumberOfElements()
Definition: skillmodel.h:45
int getSelected() const
Definition: listbox.h:167
#define nullptr
Definition: localconsts.h:44
void showSkillLevelPopup(const SkillInfo *const info)
Definition: popupmenu.cpp:2356
int customOffsetX
Definition: skillinfo.h:65
void setItem(const int item)
Definition: dragdrop.h:237
void mouseReleased(MouseEvent &event)
Definition: listbox.cpp:310
static float mAlpha
Definition: listbox.h:291
int customSelectedLevel
Definition: skillinfo.h:64
const SkillInfo * getSkillByEvent(const MouseEvent &event) const
Definition: skilllistbox.h:183
unsigned int getRowHeight() const
Definition: skilllistbox.h:180
int mMouseY
Definition: viewport.h:154
std::string skillLevel
Definition: skillinfo.h:51
SkillListBox(const Widget2 *const widget, SkillModel *const model)
Definition: skilllistbox.h:53
#define A_UNUSED
Definition: localconsts.h:151
void draw(Graphics *const graphics)
Definition: skilllistbox.h:91
int getWidth(const std::string &text) const
Definition: font.cpp:333
int skillLevelWidth
Definition: skillinfo.h:67
void mouseReleased(MouseEvent &event)
Definition: skilllistbox.h:270
void mousePressed(MouseEvent &event)
Definition: skilllistbox.h:237
Definition: color.h:74
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:44
#define override
Definition: localconsts.h:46
int getHeight() const
Definition: font.cpp:360
MouseButton ::T MouseButtonT
Definition: mousebutton.h:77
bool mSkillClicked
Definition: skilllistbox.h:287
virtual void mouseMoved(MouseEvent &event)
Viewport * viewport
Definition: viewport.cpp:35
void safeDraw(Graphics *const graphics)
Definition: skilllistbox.h:175