GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/spellshortcutcontainer.cpp Lines: 1 158 0.6 %
Date: 2017-11-29 Branches: 0 112 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  Andrei Karas
5
 *  Copyright (C) 2011-2017  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
#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::setWidget2(const Widget2 *const widget)
60
{
61
    Widget2::setWidget2(widget);
62
    mForegroundColor = getThemeColor(ThemeColorId::TEXT);
63
    mForegroundColor2 = getThemeColor(ThemeColorId::TEXT_OUTLINE);
64
}
65
66
void SpellShortcutContainer::draw(Graphics *const graphics)
67
{
68
    if (spellShortcut == nullptr)
69
        return;
70
71
    BLOCK_START("SpellShortcutContainer::draw")
72
    if (settings.guiAlpha != mAlpha)
73
    {
74
        mAlpha = settings.guiAlpha;
75
        if (mBackgroundImg != nullptr)
76
            mBackgroundImg->setAlpha(mAlpha);
77
    }
78
79
    Font *const font = getFont();
80
81
    const int selectedId = spellShortcut->getSelectedItem();
82
    graphics->setColor(mForegroundColor);
83
    drawBackground(graphics);
84
85
    // +++ in future need reorder images and string drawing.
86
    for (unsigned i = 0; i < mMaxItems; i++)
87
    {
88
        const int itemX = (i % mGridWidth) * mBoxWidth;
89
        const int itemY = (i / mGridWidth) * mBoxHeight;
90
91
        const int itemId = getItemByIndex(i);
92
        if (selectedId >= 0 && itemId == selectedId)
93
        {
94
            graphics->drawRectangle(Rect(itemX + 1, itemY + 1,
95
                mBoxWidth - 1, mBoxHeight - 1));
96
        }
97
98
        if (spellManager == nullptr)
99
            continue;
100
101
        const TextCommand *const spell = spellManager->getSpell(itemId);
102
        if (spell != nullptr)
103
        {
104
            if (!spell->isEmpty())
105
            {
106
                Image *const image = spell->getImage();
107
108
                if (image != nullptr)
109
                {
110
                    image->setAlpha(1.0F);
111
                    graphics->drawImage(image, itemX, itemY);
112
                }
113
            }
114
115
            font->drawString(graphics,
116
                mForegroundColor,
117
                mForegroundColor2,
118
                spell->getSymbol(),
119
                itemX + 2, itemY + mBoxHeight / 2);
120
        }
121
    }
122
123
    BLOCK_END("SpellShortcutContainer::draw")
124
}
125
126
void SpellShortcutContainer::safeDraw(Graphics *const graphics)
127
{
128
    if (spellShortcut == nullptr)
129
        return;
130
131
    BLOCK_START("SpellShortcutContainer::draw")
132
    if (settings.guiAlpha != mAlpha)
133
    {
134
        mAlpha = settings.guiAlpha;
135
        if (mBackgroundImg != nullptr)
136
            mBackgroundImg->setAlpha(mAlpha);
137
    }
138
139
    Font *const font = getFont();
140
141
    const int selectedId = spellShortcut->getSelectedItem();
142
    graphics->setColor(mForegroundColor);
143
    safeDrawBackground(graphics);
144
145
    // +++ in future need reorder images and string drawing.
146
    for (unsigned i = 0; i < mMaxItems; i++)
147
    {
148
        const int itemX = (i % mGridWidth) * mBoxWidth;
149
        const int itemY = (i / mGridWidth) * mBoxHeight;
150
151
        const int itemId = getItemByIndex(i);
152
        if (selectedId >= 0 && itemId == selectedId)
153
        {
154
            graphics->drawRectangle(Rect(itemX + 1, itemY + 1,
155
                mBoxWidth - 1, mBoxHeight - 1));
156
        }
157
158
        if (spellManager == nullptr)
159
            continue;
160
161
        const TextCommand *const spell = spellManager->getSpell(itemId);
162
        if (spell != nullptr)
163
        {
164
            if (!spell->isEmpty())
165
            {
166
                Image *const image = spell->getImage();
167
168
                if (image != nullptr)
169
                {
170
                    image->setAlpha(1.0F);
171
                    graphics->drawImage(image, itemX, itemY);
172
                }
173
            }
174
175
            font->drawString(graphics,
176
                mForegroundColor,
177
                mForegroundColor2,
178
                spell->getSymbol(),
179
                itemX + 2, itemY + mBoxHeight / 2);
180
        }
181
    }
182
183
    BLOCK_END("SpellShortcutContainer::draw")
184
}
185
186
void SpellShortcutContainer::mouseDragged(MouseEvent &event)
187
{
188
    if (event.getButton() == MouseButton::LEFT)
189
    {
190
        if (dragDrop.isEmpty() && mSpellClicked)
191
        {
192
            mSpellClicked = false;
193
            const int index = getIndexFromGrid(event.getX(), event.getY());
194
195
            if (index == -1)
196
                return;
197
198
            const int itemId = getItemByIndex(index);
199
            if (itemId < 0)
200
                return;
201
            event.consume();
202
            TextCommand *const spell = spellManager->getSpell(itemId);
203
            if (spell != nullptr)
204
            {
205
                dragDrop.dragCommand(spell, DragDropSource::Spells, index);
206
                dragDrop.setItem(spell->getId() + SPELL_MIN_ID);
207
            }
208
            else
209
            {
210
                dragDrop.clear();
211
                mSpellClicked = false;
212
            }
213
        }
214
    }
215
}
216
217
void SpellShortcutContainer::mousePressed(MouseEvent &event)
218
{
219
    const int index = getIndexFromGrid(event.getX(), event.getY());
220
221
    if (index == -1)
222
        return;
223
224
    const MouseButtonT eventButton = event.getButton();
225
    if (eventButton == MouseButton::LEFT)
226
    {
227
        const int itemId = getItemByIndex(index);
228
        if (itemId > 0)
229
            mSpellClicked = true;
230
        event.consume();
231
    }
232
    else if (eventButton == MouseButton::MIDDLE)
233
    {
234
        if ((spellShortcut == nullptr) || (spellManager == nullptr))
235
            return;
236
237
        event.consume();
238
        const int itemId = getItemByIndex(index);
239
        spellManager->invoke(itemId);
240
    }
241
}
242
243
void SpellShortcutContainer::mouseReleased(MouseEvent &event)
244
{
245
    if ((spellShortcut == nullptr) || (spellManager == nullptr))
246
        return;
247
248
    const int index = getIndexFromGrid(event.getX(), event.getY());
249
250
    if (index == -1)
251
    {
252
        dragDrop.clear();
253
        return;
254
    }
255
256
    const int itemId = getItemByIndex(index);
257
    const MouseButtonT eventButton = event.getButton();
258
259
    if (eventButton == MouseButton::LEFT)
260
    {
261
        mSpellClicked = false;
262
263
        if (itemId < 0)
264
            return;
265
266
        const int selectedId = spellShortcut->getSelectedItem();
267
        event.consume();
268
269
        if (!dragDrop.isEmpty())
270
        {
271
            if (dragDrop.getSource() == DragDropSource::Spells)
272
            {
273
                const int oldIndex = dragDrop.getTag();
274
                const int idx = mNumber * SPELL_SHORTCUT_ITEMS;
275
                spellManager->swap(idx + index, idx + oldIndex);
276
                spellManager->save();
277
                dragDrop.clear();
278
                dragDrop.deselect();
279
            }
280
        }
281
        else
282
        {
283
            if (selectedId != itemId)
284
            {
285
                const TextCommand *const
286
                    spell = spellManager->getSpell(itemId);
287
                if ((spell != nullptr) && !spell->isEmpty())
288
                {
289
                    const int num = itemShortcutWindow->getTabIndex();
290
                    if (num >= 0 && num < CAST_S32(SHORTCUT_TABS)
291
                        && (itemShortcut[num] != nullptr))
292
                    {
293
                        itemShortcut[num]->setItemSelected(
294
                            spell->getId() + SPELL_MIN_ID);
295
                    }
296
                    spellShortcut->setItemSelected(spell->getId());
297
                }
298
            }
299
            else
300
            {
301
                const int num = itemShortcutWindow->getTabIndex();
302
                if (num >= 0 && num < CAST_S32(SHORTCUT_TABS)
303
                    && (itemShortcut[num] != nullptr))
304
                {
305
                    itemShortcut[num]->setItemSelected(-1);
306
                }
307
                spellShortcut->setItemSelected(-1);
308
            }
309
        }
310
    }
311
    else if (eventButton == MouseButton::RIGHT)
312
    {
313
        TextCommand *spell = nullptr;
314
        if (itemId >= 0)
315
            spell = spellManager->getSpell(itemId);
316
317
        if ((spell != nullptr) && (popupMenu != nullptr))
318
        {
319
            popupMenu->showSpellPopup(viewport->mMouseX,
320
                viewport->mMouseY,
321
                spell);
322
        }
323
    }
324
}
325
326
// Show ItemTooltip
327
void SpellShortcutContainer::mouseMoved(MouseEvent &event)
328
{
329
    if (spellPopup == nullptr ||
330
        spellShortcut == nullptr ||
331
        spellManager == nullptr)
332
    {
333
        return;
334
    }
335
336
    const int index = getIndexFromGrid(event.getX(), event.getY());
337
338
    if (index == -1)
339
        return;
340
341
    const int itemId = getItemByIndex(index);
342
    spellPopup->setVisible(Visible_false);
343
    const TextCommand *const spell = spellManager->getSpell(itemId);
344
    if ((spell != nullptr) && !spell->isEmpty())
345
    {
346
        spellPopup->setItem(spell);
347
        spellPopup->view(viewport->mMouseX, viewport->mMouseY);
348
    }
349
    else
350
    {
351
        spellPopup->setVisible(Visible_false);
352
    }
353
}
354
355
void SpellShortcutContainer::mouseExited(MouseEvent &event A_UNUSED)
356
{
357
    if (spellPopup != nullptr)
358
        spellPopup->setVisible(Visible_false);
359
}
360
361
void SpellShortcutContainer::widgetHidden(const Event &event A_UNUSED)
362
{
363
    if (spellPopup != nullptr)
364
        spellPopup->setVisible(Visible_false);
365
}
366
367
int SpellShortcutContainer::getItemByIndex(const int index) const
368
{
369
    return spellShortcut->getItem(
370
        (mNumber * SPELL_SHORTCUT_ITEMS) + index);
371
4
}