GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/spellshortcutcontainer.cpp Lines: 1 165 0.6 %
Date: 2021-03-17 Branches: 0 126 0.0 %

Line Branch Exec Source
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
23
#include "gui/widgets/spellshortcutcontainer.h"
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
33
#include "gui/shortcut/itemshortcut.h"
34
#include "gui/shortcut/spellshortcut.h"
35
36
#include "gui/popups/popupmenu.h"
37
#include "gui/popups/spellpopup.h"
38
39
#include "gui/windows/shortcutwindow.h"
40
41
#include "debug.h"
42
43
SpellShortcutContainer::SpellShortcutContainer(Widget2 *const widget,
44
                                               const unsigned number) :
45
    ShortcutContainer(widget),
46
    mNumber(number),
47
    mSpellClicked(false)
48
{
49
    if (spellShortcut != nullptr)
50
        mMaxItems = SpellShortcut::getSpellsCount();
51
    else
52
        mMaxItems = 0;
53
}
54
55
SpellShortcutContainer::~SpellShortcutContainer()
56
{
57
}
58
59
void SpellShortcutContainer::setSkin(const Widget2 *const widget,
60
                                     Skin *const skin)
61
{
62
    ShortcutContainer::setSkin(widget, skin);
63
    mForegroundColor = getThemeColor(ThemeColorId::TEXT, 255U);
64
    mForegroundColor2 = getThemeColor(ThemeColorId::TEXT_OUTLINE, 255U);
65
}
66
67
void SpellShortcutContainer::draw(Graphics *const graphics)
68
{
69
    if (spellShortcut == nullptr)
70
        return;
71
72
    BLOCK_START("SpellShortcutContainer::draw")
73
    if (settings.guiAlpha != mAlpha)
74
    {
75
        mAlpha = settings.guiAlpha;
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,
119
                mForegroundColor,
120
                mForegroundColor2,
121
                spell->getSymbol(),
122
                itemX + mTextOffsetX,
123
                itemY + mTextOffsetY);
124
        }
125
    }
126
127
    BLOCK_END("SpellShortcutContainer::draw")
128
}
129
130
void SpellShortcutContainer::safeDraw(Graphics *const graphics)
131
{
132
    if (spellShortcut == nullptr)
133
        return;
134
135
    BLOCK_START("SpellShortcutContainer::draw")
136
    if (settings.guiAlpha != mAlpha)
137
    {
138
        mAlpha = settings.guiAlpha;
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,
182
                mForegroundColor,
183
                mForegroundColor2,
184
                spell->getSymbol(),
185
                itemX + mTextOffsetX,
186
                itemY + mTextOffsetY);
187
        }
188
    }
189
190
    BLOCK_END("SpellShortcutContainer::draw")
191
}
192
193
void SpellShortcutContainer::mouseDragged(MouseEvent &event)
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
            {
212
                dragDrop.dragCommand(spell, DragDropSource::Spells, index);
213
                dragDrop.setItem(spell->getId() + SPELL_MIN_ID);
214
            }
215
            else
216
            {
217
                dragDrop.clear();
218
                mSpellClicked = false;
219
            }
220
        }
221
    }
222
}
223
224
void SpellShortcutContainer::mousePressed(MouseEvent &event)
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
250
void SpellShortcutContainer::mouseReleased(MouseEvent &event)
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
        {
278
            if (dragDrop.getSource() == DragDropSource::Spells)
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
                    {
300
                        itemShortcut[num]->setItemSelected(
301
                            spell->getId() + SPELL_MIN_ID);
302
                    }
303
                    spellShortcut->setItemSelected(spell->getId());
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
                }
314
                spellShortcut->setItemSelected(-1);
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
        {
326
            popupMenu->showSpellPopup(viewport->mMouseX,
327
                viewport->mMouseY,
328
                spell);
329
        }
330
    }
331
}
332
333
// Show ItemTooltip
334
void SpellShortcutContainer::mouseMoved(MouseEvent &event)
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);
349
    spellPopup->setVisible(Visible_false);
350
    const TextCommand *const spell = spellManager->getSpell(itemId);
351
    if ((spell != nullptr) && !spell->isEmpty())
352
    {
353
        spellPopup->setItem(spell);
354
        spellPopup->view(viewport->mMouseX, viewport->mMouseY);
355
    }
356
    else
357
    {
358
        spellPopup->setVisible(Visible_false);
359
    }
360
}
361
362
void SpellShortcutContainer::mouseExited(MouseEvent &event A_UNUSED)
363
{
364
    if (spellPopup != nullptr)
365
        spellPopup->setVisible(Visible_false);
366
}
367
368
void SpellShortcutContainer::widgetHidden(const Event &event A_UNUSED)
369
{
370
    if (spellPopup != nullptr)
371
        spellPopup->setVisible(Visible_false);
372
}
373
374
int SpellShortcutContainer::getItemByIndex(const int index) const
375
{
376
    return spellShortcut->getItem(
377
        (mNumber * SPELL_SHORTCUT_ITEMS) + index);
378
2
}