GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/popuplist.cpp Lines: 55 99 55.6 %
Date: 2021-03-17 Branches: 31 92 33.7 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2012-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/popuplist.h"
23
24
#include "gui/gui.h"
25
26
#include "gui/widgets/createwidget.h"
27
#include "gui/widgets/dropdown.h"
28
#include "gui/widgets/extendedlistbox.h"
29
#include "gui/widgets/scrollarea.h"
30
31
#include "render/graphics.h"
32
33
#include "debug.h"
34
35
95
PopupList::PopupList(DropDown *const widget,
36
                     ListModel *const listModel,
37
                     const bool isExtended,
38
95
                     const Modal modal) :
39
    Popup("PopupList", "popuplist.xml"),
40
    FocusListener(),
41
    mListModel(listModel),
42




287
    mListBox(isExtended ? CREATEWIDGETR(ExtendedListBox,
43
        widget, listModel, "extendedlistbox.xml", 0) :
44



374
        CREATEWIDGETR(ListBox,
45
        widget, listModel, "popuplistbox.xml")),
46

190
    mScrollArea(new ScrollArea(this, mListBox, Opaque_false, std::string())),
47
    mDropDown(widget),
48
    mPressedIndex(-2),
49

1045
    mModal(modal)
50
{
51
190
    mListBox->setMouseConsume(false);
52
190
    mScrollArea->setMouseConsume(false);
53
95
    mAllowLogic = false;
54
95
    setFocusable(true);
55
56
190
    mListBox->setDistributeMousePressed(true);
57
95
    mScrollArea->setPosition(mPadding, mPadding);
58
95
}
59
60
95
void PopupList::postInit()
61
{
62
190
    Popup::postInit();
63
95
    add(mScrollArea);
64
65
95
    if (gui != nullptr)
66
95
        gui->addGlobalFocusListener(this);
67
68
95
    addKeyListener(mDropDown);
69
95
    addMouseListener(this);
70
95
    adjustSize();
71
95
}
72
73
380
PopupList::~PopupList()
74
{
75
95
    if (mParent != nullptr)
76
95
        mParent->removeFocusListener(this);
77
95
    if (gui != nullptr)
78
95
        gui->removeGlobalFocusListener(this);
79
95
    removeKeyListener(mDropDown);
80
190
}
81
82
void PopupList::show(int x, int y)
83
{
84
    int len = mListBox->getHeight() + 8;
85
    if (len > 250)
86
        len = 250;
87
    setContentSize(mListBox->getWidth() + 8, len);
88
    const int width = mDimension.width;
89
    const int height = mDimension.height;
90
    if (mainGraphics->mWidth < (x + width + 5))
91
        x = mainGraphics->mWidth - width;
92
    if (mainGraphics->mHeight < (y + height + 5))
93
        y = mainGraphics->mHeight - height;
94
    setPosition(x, y);
95
    setVisible(Visible_true);
96
    requestMoveToTop();
97
    if (mModal == Modal_true)
98
        requestModalFocus();
99
}
100
101
95
void PopupList::widgetResized(const Event &event)
102
{
103
95
    Popup::widgetResized(event);
104
95
    adjustSize();
105
95
}
106
107
196
void PopupList::setSelected(const int selected)
108
{
109
196
    if (mListBox == nullptr)
110
        return;
111
112
196
    mListBox->setSelected(selected);
113
}
114
115
209
int PopupList::getSelected() const
116
{
117
209
    if (mListBox == nullptr)
118
        return -1;
119
120
418
    return mListBox->getSelected();
121
}
122
123
95
void PopupList::setListModel(ListModel *const model)
124
{
125
95
    if (mListBox != nullptr)
126
95
        mListBox->setListModel(model);
127
95
    mListModel = model;
128
95
}
129
130
285
void PopupList::adjustSize()
131
{
132
285
    const int pad2 = 2 * mPadding;
133
285
    const int width = mDimension.width - pad2;
134
285
    mScrollArea->setWidth(width);
135
285
    mScrollArea->setHeight(mDimension.height - pad2);
136
285
    mListBox->adjustSize();
137
285
    mListBox->setWidth(width);
138
285
}
139
140
void PopupList::mousePressed(MouseEvent& event)
141
{
142
    mPressedIndex = mListBox->getSelectionByMouse(
143
        event.getY() + mPadding);
144
    event.consume();
145
}
146
147
void PopupList::mouseReleased(MouseEvent& event)
148
{
149
    if (mPressedIndex != mListBox->getSelectionByMouse(
150
        event.getY() + mPadding))
151
    {
152
        mPressedIndex = -2;
153
        return;
154
    }
155
156
    mPressedIndex = -2;
157
    if (event.getSource() == mScrollArea)
158
        return;
159
    if (mDropDown != nullptr)
160
        mDropDown->updateSelection();
161
    setVisible(Visible_false);
162
    if (mModal == Modal_true)
163
        releaseModalFocus();
164
}
165
166
5
void PopupList::focusGained(const Event& event)
167
{
168
5
    const Widget *const source = event.getSource();
169

5
    if (mVisible == Visible_false ||
170
        source == this ||
171
        source == mListBox ||
172
        source == mScrollArea ||
173
        source == mDropDown)
174
    {
175
        return;
176
    }
177
178
    if (mDropDown != nullptr)
179
        mDropDown->updateSelection();
180
    setVisible(Visible_false);
181
    if (mModal == Modal_true)
182
        releaseModalFocus();
183
}
184
185
void PopupList::focusLost(const Event& event A_UNUSED)
186
{
187
    if (mDropDown != nullptr)
188
        mDropDown->updateSelection();
189
}