GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/popups/skillpopup.cpp Lines: 40 125 32.0 %
Date: 2021-03-17 Branches: 29 136 21.3 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2008  The Legend of Mazzeroth Development Team
4
 *  Copyright (C) 2008-2009  The Mana World Development Team
5
 *  Copyright (C) 2009-2010  The Mana Developers
6
 *  Copyright (C) 2011-2019  The ManaPlus Developers
7
 *  Copyright (C) 2019-2021  Andrei Karas
8
 *
9
 *  This file is part of The ManaPlus Client.
10
 *
11
 *  This program is free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  any later version.
15
 *
16
 *  This program is distributed in the hope that it will be useful,
17
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 *  GNU General Public License for more details.
20
 *
21
 *  You should have received a copy of the GNU General Public License
22
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24
25
#include "gui/popups/skillpopup.h"
26
27
#include "gui/gui.h"
28
29
#include "gui/fonts/font.h"
30
31
#include "gui/widgets/label.h"
32
#include "gui/widgets/textbox.h"
33
34
#include "utils/gettext.h"
35
#include "utils/stringutils.h"
36
37
#include "resources/skill/skilldata.h"
38
#include "resources/skill/skillinfo.h"
39
40
#include "debug.h"
41
42
SkillPopup *skillPopup = nullptr;
43
44
2
SkillPopup::SkillPopup() :
45
    Popup("SkillPopup", "skillpopup.xml"),
46

2
    mSkillName(new Label(this)),
47

2
    mSkillDesc(new TextBox(this)),
48

2
    mSkillEffect(new TextBox(this)),
49

2
    mSkillLevel(new TextBox(this)),
50

2
    mSkillCastType(new TextBox(this)),
51
    mCastType(CastType::Default),
52
    mLastId(0U),
53
    mLastLevel(-1),
54
    mOffsetX(0),
55

24
    mOffsetY(0)
56
{
57
2
    mSkillName->setFont(boldFont);
58
2
    mSkillName->setPosition(0, 0);
59
6
    mSkillName->setForegroundColorAll(
60
        getThemeColor(ThemeColorId::POPUP, 255U),
61
2
        getThemeColor(ThemeColorId::POPUP_OUTLINE, 255U));
62
63

2
    const int fontHeight = getFont()->getHeight();
64
65
2
    mSkillDesc->setEditable(false);
66
2
    mSkillDesc->setPosition(0, fontHeight);
67
6
    mSkillDesc->setForegroundColorAll(
68
        getThemeColor(ThemeColorId::POPUP, 255U),
69
2
        getThemeColor(ThemeColorId::POPUP_OUTLINE, 255U));
70
71
2
    mSkillEffect->setEditable(false);
72
2
    mSkillEffect->setPosition(0, 2 * fontHeight);
73
6
    mSkillEffect->setForegroundColorAll(
74
        getThemeColor(ThemeColorId::POPUP, 255U),
75
2
        getThemeColor(ThemeColorId::POPUP_OUTLINE, 255U));
76
77
2
    mSkillLevel->setEditable(false);
78
2
    mSkillLevel->setPosition(0, 3 * fontHeight);
79
6
    mSkillLevel->setForegroundColorAll(
80
        getThemeColor(ThemeColorId::POPUP, 255U),
81
2
        getThemeColor(ThemeColorId::POPUP_OUTLINE, 255U));
82
83
2
    mSkillCastType->setEditable(false);
84
2
    mSkillCastType->setPosition(0, 4 * fontHeight);
85
6
    mSkillCastType->setForegroundColorAll(
86
        getThemeColor(ThemeColorId::POPUP, 255U),
87
2
        getThemeColor(ThemeColorId::POPUP_OUTLINE, 255U));
88
2
}
89
90
2
void SkillPopup::postInit()
91
{
92
4
    Popup::postInit();
93
2
    add(mSkillName);
94
2
    add(mSkillDesc);
95
2
    add(mSkillEffect);
96
2
    add(mSkillLevel);
97
2
    add(mSkillCastType);
98
99
2
    addMouseListener(this);
100
2
}
101
102
2
SkillPopup::~SkillPopup()
103
{
104
2
}
105
106
void SkillPopup::show(const SkillInfo *const skill,
107
                      const int level,
108
                      const CastTypeT castType,
109
                      const int offsetX,
110
                      const int offsetY)
111
{
112
    if ((skill == nullptr) ||
113
        (skill->data == nullptr) ||
114
        (skill->id == mLastId &&
115
        level == mLastLevel &&
116
        castType == mCastType &&
117
        offsetX == mOffsetX &&
118
        offsetY == mOffsetY))
119
    {
120
        return;
121
    }
122
123
    mLastId = skill->id;
124
    mLastLevel = level;
125
    mCastType = castType;
126
    mOffsetX = offsetX;
127
    mOffsetY = offsetY;
128
129
    mSkillName->setCaption(skill->data->dispName);
130
    mSkillName->adjustSize();
131
    mSkillName->setPosition(0, 0);
132
133
    std::string description = skill->data->description;
134
    std::string effect = skill->skillEffect;
135
    if (description.empty())
136
    {
137
        description = effect;
138
        effect.clear();
139
    }
140
    mSkillDesc->setTextWrapped(description, 196);
141
    mSkillEffect->setTextWrapped(effect, 196);
142
    if (level != 0)
143
    {
144
        mSkillLevel->setTextWrapped(strprintf(
145
            // TRANSLATORS: skill level
146
            _("Level: %d / %d"), level, skill->level),
147
            196);
148
    }
149
    else
150
    {
151
        if (skill->level != 0)
152
        {
153
            mSkillLevel->setTextWrapped(strprintf(
154
                // TRANSLATORS: skill level
155
                _("Level: %d"), skill->level),
156
                196);
157
        }
158
        else
159
        {
160
            mSkillLevel->setTextWrapped(
161
                // TRANSLATORS: skill level for tmw fake skills
162
                _("Level: Unknown"),
163
                196);
164
        }
165
    }
166
    std::string castStr;
167
    switch (castType)
168
    {
169
        case CastType::Default:
170
        default:
171
            // TRANSLATORS: skill cast type
172
            castStr = _("Default");
173
            break;
174
        case CastType::Target:
175
            // TRANSLATORS: skill cast type
176
            castStr = _("Target");
177
            break;
178
        case CastType::Position:
179
            // TRANSLATORS: skill cast type
180
            castStr = _("Mouse position");
181
            break;
182
        case CastType::Self:
183
            // TRANSLATORS: skill cast type
184
            castStr = _("Self position");
185
            break;
186
    }
187
    if (offsetX != 0 ||
188
        offsetY != 0)
189
    {
190
        castStr.append(strprintf(" (%+d,%+d)",
191
            offsetX,
192
            offsetY));
193
    }
194
    mSkillCastType->setTextWrapped(strprintf(
195
        // TRANSLATORS: skill cast type
196
        _("Cast type: %s"),
197
        castStr.c_str()), 196);
198
199
    int minWidth = mSkillName->getWidth();
200
201
    if (mSkillName->getWidth() > minWidth)
202
        minWidth = mSkillName->getWidth();
203
    if (mSkillDesc->getMinWidth() > minWidth)
204
        minWidth = mSkillDesc->getMinWidth();
205
    if (mSkillEffect->getMinWidth() > minWidth)
206
        minWidth = mSkillEffect->getMinWidth();
207
    if (mSkillLevel->getMinWidth() > minWidth)
208
        minWidth = mSkillLevel->getMinWidth();
209
    if (mSkillCastType->getMinWidth() > minWidth)
210
        minWidth = mSkillCastType->getMinWidth();
211
212
    const int numRowsDesc = mSkillDesc->getNumberOfRows();
213
    const int numRowsLevel = mSkillLevel->getNumberOfRows();
214
    const int numRowsCast = mSkillCastType->getNumberOfRows();
215
    const int height = getFont()->getHeight();
216
217
    if (skill->skillEffect.empty())
218
    {
219
        setContentSize(minWidth,
220
            (numRowsDesc + numRowsLevel + numRowsCast + 1) * height);
221
        mSkillLevel->setPosition(0, (numRowsDesc + 1) * height);
222
        mSkillCastType->setPosition(0, (numRowsDesc + 2) * height);
223
    }
224
    else
225
    {
226
        const int numRowsEffect = mSkillEffect->getNumberOfRows();
227
        setContentSize(minWidth,
228
            (numRowsDesc + numRowsLevel + numRowsEffect + numRowsCast + 1) *
229
            height);
230
        mSkillEffect->setPosition(0, (numRowsDesc + 1) * height);
231
        mSkillLevel->setPosition(0,
232
            (numRowsDesc + numRowsEffect + 1) * height);
233
        mSkillCastType->setPosition(0,
234
            (numRowsDesc + numRowsEffect + 2) * height);
235
    }
236
237
    mSkillDesc->setPosition(0, 1 * height);
238
}
239
240
void SkillPopup::mouseMoved(MouseEvent &event)
241
{
242
    Popup::mouseMoved(event);
243
244
    // When the mouse moved on top of the popup, hide it
245
    setVisible(Visible_false);
246
    mLastId = 0;
247
}
248
249
void SkillPopup::reset()
250
{
251
    mLastId = 0;
252
    mLastLevel = 0;
253
    mCastType = CastType::Default;
254
    mOffsetX = 0;
255
    mOffsetY = 0;
256
}