GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/sliderlist.cpp Lines: 65 112 58.0 %
Date: 2021-03-17 Branches: 36 76 47.4 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2011-2019  The ManaPlus Developers
4
 *  Copyright (C) 2019-2021  Andrei Karas
5
 *
6
 *  This file is part of The ManaPlus Client.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include "gui/widgets/sliderlist.h"
23
24
#include "gui/gui.h"
25
26
#include "gui/fonts/font.h"
27
28
#include "gui/models/listmodel.h"
29
30
#include "gui/widgets/button.h"
31
#include "gui/widgets/label.h"
32
33
#include "debug.h"
34
35
static const int buttonWidth = 27;
36
static const int buttonSpace = 30;
37
static const int sliderHeight = 30;
38
39
26
SliderList::SliderList(const Widget2 *const widget,
40
26
                       ListModel *const listModel) :
41
    Container(widget),
42
    ActionListener(),
43
    MouseListener(),
44
    mButtons(),
45

26
    mLabel(new Label(this)),
46
    mListModel(listModel),
47
    mPrevEventId(),
48
    mNextEventId(),
49
    mOldWidth(0),
50
156
    mSelectedIndex(0)
51
{
52
26
    mAllowLogic = false;
53
26
    setHeight(sliderHeight);
54
26
}
55
56
26
void SliderList::postInit2(ActionListener *const listener,
57
                           const std::string &eventId)
58
{
59
52
    mPrevEventId = eventId + "_prev";
60
52
    mNextEventId = eventId + "_next";
61
62
26
    mButtons[0] = new Button(this,
63
        "<",
64
        mPrevEventId,
65
        BUTTON_SKIN,
66

104
        this);
67
26
    mButtons[1] = new Button(this,
68
        ">",
69
        mNextEventId,
70
        BUTTON_SKIN,
71

104
        this);
72
73
26
    add(mButtons[0]);
74
26
    add(mLabel);
75
26
    add(mButtons[1]);
76
77
26
    if (!eventId.empty())
78
26
        setActionEventId(eventId);
79
80
26
    if (listener != nullptr)
81
26
        addActionListener(listener);
82
83
26
    updateLabel();
84
26
    addMouseListener(this);
85
26
}
86
87
130
SliderList::~SliderList()
88
{
89
52
}
90
91
void SliderList::updateAlpha()
92
{
93
    mButtons[0]->updateAlpha();
94
    mButtons[1]->updateAlpha();
95
}
96
97
void SliderList::mouseWheelMovedUp(MouseEvent& event)
98
{
99
    setSelected(mSelectedIndex - 1);
100
    event.consume();
101
}
102
103
void SliderList::mouseWheelMovedDown(MouseEvent& event)
104
{
105
    setSelected(mSelectedIndex + 1);
106
    event.consume();
107
}
108
109
void SliderList::resize()
110
{
111
    const int width = getWidth();
112
113
    mButtons[0]->setWidth(buttonWidth);
114
    mLabel->setWidth(width - buttonSpace * 2);
115
    mButtons[1]->setPosition(width - buttonSpace + 3, 0);
116
    mButtons[1]->setWidth(buttonWidth);
117
    updateLabel();
118
}
119
120
void SliderList::draw(Graphics *const graphics)
121
{
122
    BLOCK_START("SliderList::draw")
123
    const int width = mDimension.width;
124
    if (mOldWidth != width)
125
    {
126
        resize();
127
        mOldWidth = width;
128
    }
129
    Container::draw(graphics);
130
    BLOCK_END("SliderList::draw")
131
}
132
133
void SliderList::safeDraw(Graphics *const graphics)
134
{
135
    BLOCK_START("SliderList::draw")
136
    const int width = mDimension.width;
137
    if (mOldWidth != width)
138
    {
139
        resize();
140
        mOldWidth = width;
141
    }
142
    Container::draw(graphics);
143
    BLOCK_END("SliderList::draw")
144
}
145
146
78
void SliderList::updateLabel()
147
{
148

234
    if ((mListModel == nullptr) || mSelectedIndex < 0
149

156
        || mSelectedIndex >= mListModel->getNumberOfElements())
150
    {
151
        return;
152
    }
153
154
156
    mLabel->setCaption(mListModel->getElementAt(mSelectedIndex));
155
78
    mLabel->adjustSize();
156
78
    const int space = mDimension.width - buttonSpace * 2;
157
156
    const int labelWidth = mLabel->getWidth();
158
156
    int labelY = (mDimension.height - mLabel->getHeight()) / 2;
159
78
    if (labelY < 0)
160
        labelY = 0;
161
162
78
    if (space < 0 || space < labelWidth)
163
50
        mLabel->setPosition(buttonSpace, labelY);
164
    else
165
28
        mLabel->setPosition(buttonSpace + (space - labelWidth) / 2, labelY);
166
}
167
168
void SliderList::action(const ActionEvent &event)
169
{
170
    if (mListModel == nullptr)
171
        return;
172
173
    const std::string &eventId = event.getId();
174
    if (eventId == mPrevEventId)
175
    {
176
        mSelectedIndex --;
177
        if (mSelectedIndex < 0)
178
            mSelectedIndex = mListModel->getNumberOfElements() - 1;
179
    }
180
    else if (eventId == mNextEventId)
181
    {
182
        mSelectedIndex ++;
183
        if (mSelectedIndex >= mListModel->getNumberOfElements())
184
            mSelectedIndex = 0;
185
    }
186
    updateLabel();
187
    distributeActionEvent();
188
}
189
190
26
void SliderList::setSelectedString(const std::string &str)
191
{
192
26
    if (mListModel == nullptr)
193
        return;
194
195
538
    for (int f = 0; f < mListModel->getNumberOfElements(); f ++)
196
    {
197
560
        if (mListModel->getElementAt(f) == str)
198
        {
199
24
            setSelected(f);
200
24
            break;
201
        }
202
    }
203
}
204
205
std::string SliderList::getSelectedString() const
206
{
207
    if (mListModel == nullptr)
208
        return std::string();
209
210
    return mListModel->getElementAt(mSelectedIndex);
211
}
212
213
26
void SliderList::setSelected(const int idx)
214
{
215
26
    if (mListModel == nullptr)
216
        return;
217
218
26
    mSelectedIndex = idx;
219
26
    const int num = mListModel->getNumberOfElements();
220
26
    if (mSelectedIndex >= num)
221
        mSelectedIndex = 0;
222
26
    if (mSelectedIndex < 0)
223
        mSelectedIndex = num - 1;
224
26
    updateLabel();
225
}
226
227
26
void SliderList::adjustSize()
228
{
229
26
    setWidth(getMaxLabelWidth() + 60);
230
26
    updateLabel();
231
26
}
232
233
26
int SliderList::getMaxLabelWidth() const
234
{
235

26
    if ((mListModel == nullptr) || (gui == nullptr))
236
        return 1;
237
238
26
    int maxWidth = 0;
239
26
    const Font *const font = getFont();
240
241
26
    const int num = mListModel->getNumberOfElements();
242
520
    for (int f = 0; f < num; f ++)
243
    {
244
988
        const int w = font->getWidth(mListModel->getElementAt(f));
245
494
        if (w > maxWidth)
246
50
            maxWidth = w;
247
    }
248
249
    return maxWidth;
250

3
}