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
99
PopupList::PopupList(DropDown *const widget,
36
                     ListModel *const listModel,
37
                     const bool isExtended,
38
99
                     const Modal modal) :
39
    Popup("PopupList", "popuplist.xml"),
40
    FocusListener(),
41
    mListModel(listModel),
42




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



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

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

1089
    mModal(modal)
50
{
51
198
    mListBox->setMouseConsume(false);
52
198
    mScrollArea->setMouseConsume(false);
53
99
    mAllowLogic = false;
54
99
    setFocusable(true);
55
56
198
    mListBox->setDistributeMousePressed(true);
57
99
    mScrollArea->setPosition(mPadding, mPadding);
58
99
}
59
60
99
void PopupList::postInit()
61
{
62
198
    Popup::postInit();
63
99
    add(mScrollArea);
64
65
99
    if (gui != nullptr)
66
99
        gui->addGlobalFocusListener(this);
67
68
99
    addKeyListener(mDropDown);
69
99
    addMouseListener(this);
70
99
    adjustSize();
71
99
}
72
73
396
PopupList::~PopupList()
74
{
75
99
    if (mParent != nullptr)
76
99
        mParent->removeFocusListener(this);
77
99
    if (gui != nullptr)
78
99
        gui->removeGlobalFocusListener(this);
79
99
    removeKeyListener(mDropDown);
80
198
}
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
99
void PopupList::widgetResized(const Event &event)
102
{
103
99
    Popup::widgetResized(event);
104
99
    adjustSize();
105
99
}
106
107
204
void PopupList::setSelected(const int selected)
108
{
109
204
    if (mListBox == nullptr)
110
        return;
111
112
204
    mListBox->setSelected(selected);
113
}
114
115
217
int PopupList::getSelected() const
116
{
117
217
    if (mListBox == nullptr)
118
        return -1;
119
120
434
    return mListBox->getSelected();
121
}
122
123
99
void PopupList::setListModel(ListModel *const model)
124
{
125
99
    if (mListBox != nullptr)
126
99
        mListBox->setListModel(model);
127
99
    mListModel = model;
128
99
}
129
130
297
void PopupList::adjustSize()
131
{
132
297
    const int pad2 = 2 * mPadding;
133
297
    const int width = mDimension.width - pad2;
134
297
    mScrollArea->setWidth(width);
135
297
    mScrollArea->setHeight(mDimension.height - pad2);
136
297
    mListBox->adjustSize();
137
297
    mListBox->setWidth(width);
138
297
}
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
}