ManaPlus
spellshortcutcontainer.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2009 The Mana World Development Team
4  * Copyright (C) 2011-2019 The ManaPlus Developers
5  * Copyright (C) 2009-2021 Andrei Karas
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 
24 
25 #include "dragdrop.h"
26 #include "settings.h"
27 #include "spellmanager.h"
28 
29 #include "gui/viewport.h"
30 
31 #include "gui/fonts/font.h"
32 
35 
36 #include "gui/popups/popupmenu.h"
37 #include "gui/popups/spellpopup.h"
38 
40 
41 #include "debug.h"
42 
44  const unsigned number) :
45  ShortcutContainer(widget),
46  mNumber(number),
47  mSpellClicked(false)
48 {
49  if (spellShortcut != nullptr)
51  else
52  mMaxItems = 0;
53 }
54 
56 {
57 }
58 
59 void SpellShortcutContainer::setSkin(const Widget2 *const widget,
60  Skin *const skin)
61 {
62  ShortcutContainer::setSkin(widget, skin);
64  mForegroundColor2 = getThemeColor(ThemeColorId::TEXT_OUTLINE, 255U);
65 }
66 
68 {
69  if (spellShortcut == nullptr)
70  return;
71 
72  BLOCK_START("SpellShortcutContainer::draw")
73  if (settings.guiAlpha != mAlpha)
74  {
76  if (mBackgroundImg != nullptr)
77  mBackgroundImg->setAlpha(mAlpha);
78  }
79 
80  Font *const font = getFont();
81 
82  const int selectedId = spellShortcut->getSelectedItem();
83  graphics->setColor(mForegroundColor);
84  drawBackground(graphics);
85 
86  // +++ in future need reorder images and string drawing.
87  for (unsigned i = 0; i < mMaxItems; i++)
88  {
89  const int itemX = (i % mGridWidth) * mBoxWidth;
90  const int itemY = (i / mGridWidth) * mBoxHeight;
91 
92  const int itemId = getItemByIndex(i);
93  if (selectedId >= 0 && itemId == selectedId)
94  {
95  graphics->drawRectangle(Rect(itemX + 1, itemY + 1,
96  mBoxWidth - 1, mBoxHeight - 1));
97  }
98 
99  if (spellManager == nullptr)
100  continue;
101 
102  const TextCommand *const spell = spellManager->getSpell(itemId);
103  if (spell != nullptr)
104  {
105  if (!spell->isEmpty())
106  {
107  Image *const image = spell->getImage();
108 
109  if (image != nullptr)
110  {
111  image->setAlpha(1.0F);
112  graphics->drawImage(image,
113  itemX + mImageOffsetX,
114  itemY + mImageOffsetY);
115  }
116  }
117 
118  font->drawString(graphics,
121  spell->getSymbol(),
122  itemX + mTextOffsetX,
123  itemY + mTextOffsetY);
124  }
125  }
126 
127  BLOCK_END("SpellShortcutContainer::draw")
128 }
129 
131 {
132  if (spellShortcut == nullptr)
133  return;
134 
135  BLOCK_START("SpellShortcutContainer::draw")
136  if (settings.guiAlpha != mAlpha)
137  {
139  if (mBackgroundImg != nullptr)
140  mBackgroundImg->setAlpha(mAlpha);
141  }
142 
143  Font *const font = getFont();
144 
145  const int selectedId = spellShortcut->getSelectedItem();
146  graphics->setColor(mForegroundColor);
147  safeDrawBackground(graphics);
148 
149  // +++ in future need reorder images and string drawing.
150  for (unsigned i = 0; i < mMaxItems; i++)
151  {
152  const int itemX = (i % mGridWidth) * mBoxWidth;
153  const int itemY = (i / mGridWidth) * mBoxHeight;
154 
155  const int itemId = getItemByIndex(i);
156  if (selectedId >= 0 && itemId == selectedId)
157  {
158  graphics->drawRectangle(Rect(itemX + 1, itemY + 1,
159  mBoxWidth - 1, mBoxHeight - 1));
160  }
161 
162  if (spellManager == nullptr)
163  continue;
164 
165  const TextCommand *const spell = spellManager->getSpell(itemId);
166  if (spell != nullptr)
167  {
168  if (!spell->isEmpty())
169  {
170  Image *const image = spell->getImage();
171 
172  if (image != nullptr)
173  {
174  image->setAlpha(1.0F);
175  graphics->drawImage(image,
176  itemX + mImageOffsetX,
177  itemY + mImageOffsetY);
178  }
179  }
180 
181  font->drawString(graphics,
184  spell->getSymbol(),
185  itemX + mTextOffsetX,
186  itemY + mTextOffsetY);
187  }
188  }
189 
190  BLOCK_END("SpellShortcutContainer::draw")
191 }
192 
194 {
195  if (event.getButton() == MouseButton::LEFT)
196  {
197  if (dragDrop.isEmpty() && mSpellClicked)
198  {
199  mSpellClicked = false;
200  const int index = getIndexFromGrid(event.getX(), event.getY());
201 
202  if (index == -1)
203  return;
204 
205  const int itemId = getItemByIndex(index);
206  if (itemId < 0)
207  return;
208  event.consume();
209  TextCommand *const spell = spellManager->getSpell(itemId);
210  if (spell != nullptr)
211  {
213  dragDrop.setItem(spell->getId() + SPELL_MIN_ID);
214  }
215  else
216  {
217  dragDrop.clear();
218  mSpellClicked = false;
219  }
220  }
221  }
222 }
223 
225 {
226  const int index = getIndexFromGrid(event.getX(), event.getY());
227 
228  if (index == -1)
229  return;
230 
231  const MouseButtonT eventButton = event.getButton();
232  if (eventButton == MouseButton::LEFT)
233  {
234  const int itemId = getItemByIndex(index);
235  if (itemId > 0)
236  mSpellClicked = true;
237  event.consume();
238  }
239  else if (eventButton == MouseButton::MIDDLE)
240  {
241  if ((spellShortcut == nullptr) || (spellManager == nullptr))
242  return;
243 
244  event.consume();
245  const int itemId = getItemByIndex(index);
246  spellManager->invoke(itemId);
247  }
248 }
249 
251 {
252  if ((spellShortcut == nullptr) || (spellManager == nullptr))
253  return;
254 
255  const int index = getIndexFromGrid(event.getX(), event.getY());
256 
257  if (index == -1)
258  {
259  dragDrop.clear();
260  return;
261  }
262 
263  const int itemId = getItemByIndex(index);
264  const MouseButtonT eventButton = event.getButton();
265 
266  if (eventButton == MouseButton::LEFT)
267  {
268  mSpellClicked = false;
269 
270  if (itemId < 0)
271  return;
272 
273  const int selectedId = spellShortcut->getSelectedItem();
274  event.consume();
275 
276  if (!dragDrop.isEmpty())
277  {
279  {
280  const int oldIndex = dragDrop.getTag();
281  const int idx = mNumber * SPELL_SHORTCUT_ITEMS;
282  spellManager->swap(idx + index, idx + oldIndex);
283  spellManager->save();
284  dragDrop.clear();
285  dragDrop.deselect();
286  }
287  }
288  else
289  {
290  if (selectedId != itemId)
291  {
292  const TextCommand *const
293  spell = spellManager->getSpell(itemId);
294  if ((spell != nullptr) && !spell->isEmpty())
295  {
296  const int num = itemShortcutWindow->getTabIndex();
297  if (num >= 0 && num < CAST_S32(SHORTCUT_TABS)
298  && (itemShortcut[num] != nullptr))
299  {
301  spell->getId() + SPELL_MIN_ID);
302  }
304  }
305  }
306  else
307  {
308  const int num = itemShortcutWindow->getTabIndex();
309  if (num >= 0 && num < CAST_S32(SHORTCUT_TABS)
310  && (itemShortcut[num] != nullptr))
311  {
312  itemShortcut[num]->setItemSelected(-1);
313  }
315  }
316  }
317  }
318  else if (eventButton == MouseButton::RIGHT)
319  {
320  TextCommand *spell = nullptr;
321  if (itemId >= 0)
322  spell = spellManager->getSpell(itemId);
323 
324  if ((spell != nullptr) && (popupMenu != nullptr))
325  {
327  viewport->mMouseY,
328  spell);
329  }
330  }
331 }
332 
333 // Show ItemTooltip
335 {
336  if (spellPopup == nullptr ||
337  spellShortcut == nullptr ||
338  spellManager == nullptr)
339  {
340  return;
341  }
342 
343  const int index = getIndexFromGrid(event.getX(), event.getY());
344 
345  if (index == -1)
346  return;
347 
348  const int itemId = getItemByIndex(index);
350  const TextCommand *const spell = spellManager->getSpell(itemId);
351  if ((spell != nullptr) && !spell->isEmpty())
352  {
353  spellPopup->setItem(spell);
355  }
356  else
357  {
359  }
360 }
361 
363 {
364  if (spellPopup != nullptr)
366 }
367 
369 {
370  if (spellPopup != nullptr)
372 }
373 
374 int SpellShortcutContainer::getItemByIndex(const int index) const
375 {
376  return spellShortcut->getItem(
377  (mNumber * SPELL_SHORTCUT_ITEMS) + index);
378 }
#define CAST_S32
Definition: cast.h:30
DragDropSourceT getSource() const
Definition: dragdrop.h:84
void deselect()
Definition: dragdrop.h:213
void setItem(const int item)
Definition: dragdrop.h:238
void dragCommand(const TextCommand *const command, const DragDropSourceT source, const int tag)
Definition: dragdrop.h:117
bool isEmpty() const
Definition: dragdrop.h:196
int getTag() const
Definition: dragdrop.h:235
void clear()
Definition: dragdrop.h:183
Definition: event.h:79
Definition: font.h:90
void drawString(Graphics *const graphics, Color col, const Color &col2, const std::string &text, const int x, const int y)
Definition: font.cpp:254
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
virtual void setColor(const Color &color)
Definition: graphics.h:320
virtual void drawRectangle(const Rect &rectangle)=0
void setItemSelected(const int itemId)
Definition: itemshortcut.h:126
MouseButtonT getButton() const
Definition: mouseevent.h:116
int getX() const
Definition: mouseevent.h:127
int getY() const
Definition: mouseevent.h:138
void showSpellPopup(const int x, const int y, TextCommand *const cmd)
Definition: popupmenu.cpp:887
Definition: rect.h:74
float guiAlpha
Definition: settings.h:131
virtual void setSkin(const Widget2 *const widget, Skin *const skin)
void drawBackground(Graphics *const g)
void safeDrawBackground(Graphics *const g)
int getIndexFromGrid(const int pointX, const int pointY) const
int getTabIndex() const
Definition: skin.h:37
void swap(const int id1, const int id2)
void invoke(const int spellId) const
TextCommand * getSpell(const int spellId) const
void save() const
void view(const int x, const int y)
Definition: spellpopup.cpp:91
void setItem(const TextCommand *const spell)
Definition: spellpopup.cpp:63
void mouseExited(MouseEvent &event)
SpellShortcutContainer(Widget2 *const widget, const unsigned number)
int getItemByIndex(const int index) const
void draw(Graphics *const graphics)
void mousePressed(MouseEvent &event)
void mouseMoved(MouseEvent &event)
void setSkin(const Widget2 *const widget, Skin *const skin)
void safeDraw(Graphics *const graphics)
void mouseReleased(MouseEvent &event)
void widgetHidden(const Event &event)
void mouseDragged(MouseEvent &event)
int getSelectedItem() const
Definition: spellshortcut.h:70
void setItemSelected(const int itemId)
Definition: spellshortcut.h:58
int getItem(const size_t index) const
Definition: spellshortcut.h:78
static unsigned int getSpellsCount()
int getId() const
Definition: textcommand.h:94
bool isEmpty() const
Definition: textcommand.h:153
std::string getSymbol() const
Definition: textcommand.h:91
Image * getImage() const
Definition: textcommand.h:156
int mMouseX
Definition: viewport.h:154
int mMouseY
Definition: viewport.h:155
Color mForegroundColor2
Definition: widget2.h:113
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:45
void setVisible(Visible visible)
Definition: widget.cpp:225
Color mForegroundColor
Definition: widget.h:1086
Font * getFont() const
Definition: widget.cpp:331
const unsigned int SHORTCUT_TABS
Definition: itemshortcut.h:28
DragDrop dragDrop
Viewport * viewport
Definition: viewport.cpp:36
ItemShortcut * itemShortcut[SHORTCUT_TABS]
#define A_UNUSED
Definition: localconsts.h:160
MouseButton ::T MouseButtonT
Definition: mousebutton.h:78
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
PopupMenu * popupMenu
Definition: popupmenu.cpp:103
Settings settings
Definition: settings.cpp:32
ShortcutWindow * itemShortcutWindow
SpellManager * spellManager
SpellPopup * spellPopup
Definition: spellpopup.cpp:34
const unsigned int SPELL_SHORTCUT_ITEMS
Definition: spells.h:28
const int SPELL_MIN_ID
Definition: spells.h:27
SpellShortcut * spellShortcut
const bool Visible_false
Definition: visible.h:30