GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/popup.cpp Lines: 53 119 44.5 %
Date: 2021-03-17 Branches: 26 66 39.4 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2004-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2019  The ManaPlus Developers
6
 *  Copyright (C) 2019-2021  Andrei Karas
7
 *  Copyright (C) 2009  Aethyra Development Team
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/widgets/popup.h"
26
27
#include "gui/popupmanager.h"
28
#include "gui/skin.h"
29
30
#include "gui/widgets/windowcontainer.h"
31
32
#include "utils/delete2.h"
33
34
#include "render/graphics.h"
35
36
#include "render/vertexes/imagecollection.h"
37
38
#include "debug.h"
39
40
112
Popup::Popup(const std::string &name,
41
112
             std::string skin) :
42
    Container(nullptr),
43
    MouseListener(),
44
    WidgetListener(),
45
    mPadding(3),
46
    mSkin(nullptr),
47
    mPopupName(name),
48

112
    mVertexes(new ImageCollection),
49
    mMinWidth(100),
50
    mMinHeight(40),
51
112
    mMaxWidth(mainGraphics->mWidth),
52
112
    mMaxHeight(mainGraphics->mHeight),
53
784
    mInit(false)
54
{
55
112
    logger->log("Popup::Popup(\"%s\")", name.c_str());
56
57
112
    mWindow = this;
58
59
112
    addWidgetListener(this);
60
61
112
    if (skin.empty())
62
        skin = "popup.xml";
63
64
112
    if (theme != nullptr)
65
    {
66

448
        mSkin = theme->load(skin,
67
            "popup.xml",
68
            true,
69
112
            Theme::getThemePath());
70
112
        if (mSkin != nullptr)
71
        {
72
336
            setPadding(mSkin->getPadding());
73

560
            setPalette(mSkin->getOption("palette"));
74
        }
75
    }
76
77
112
    if (windowContainer != nullptr)
78
112
        windowContainer->add(this);
79
80
    // Popups are invisible by default
81
112
    setVisible(Visible_false);
82
112
}
83
84
560
Popup::~Popup()
85
{
86
224
    logger->log("Popup::~Popup(\"%s\")", mPopupName.c_str());
87
88
112
    delete2(mVertexes)
89
90
112
    if (mSkin != nullptr)
91
    {
92
112
        if (theme != nullptr)
93
112
            theme->unload(mSkin);
94
112
        mSkin = nullptr;
95
    }
96
97
112
    if (!mInit)
98
    {
99
        logger->log("error: Popup created without calling postInit(): "
100
            + mPopupName);
101
    }
102
112
}
103
104
void Popup::setWindowContainer(WindowContainer *const wc)
105
{
106
    windowContainer = wc;
107
}
108
109
void Popup::draw(Graphics *const graphics)
110
{
111
    BLOCK_START("Popup::draw")
112
113
    if (mSkin != nullptr)
114
    {
115
        if (mRedraw)
116
        {
117
            mRedraw = false;
118
            mVertexes->clear();
119
            graphics->calcWindow(mVertexes,
120
                0, 0,
121
                mDimension.width, mDimension.height,
122
                mSkin->getBorder());
123
        }
124
        // need cache or remove calc call.
125
        graphics->finalize(mVertexes);
126
        graphics->drawTileCollection(mVertexes);
127
    }
128
129
    drawChildren(graphics);
130
    BLOCK_END("Popup::draw")
131
}
132
133
void Popup::safeDraw(Graphics *const graphics)
134
{
135
    BLOCK_START("Popup::safeDraw")
136
137
    if (mSkin != nullptr)
138
    {
139
        graphics->drawImageRect(0, 0,
140
            mDimension.width, mDimension.height,
141
            mSkin->getBorder());
142
    }
143
144
    safeDrawChildren(graphics);
145
    BLOCK_END("Popup::safeDraw")
146
}
147
148
Rect Popup::getChildrenArea()
149
{
150
    const int pad2 = mPadding * 2;
151
    return Rect(mPadding, mPadding,
152
        mDimension.width - pad2, mDimension.height - pad2);
153
}
154
155
1
void Popup::setContentSize(int width, int height)
156
{
157
1
    const int pad2 = mPadding * 2;
158
1
    width += pad2;
159
1
    height += pad2;
160
161
1
    if (mMinWidth > width)
162
        width = mMinWidth;
163
1
    else if (mMaxWidth < width)
164
        width = mMaxWidth;
165
1
    if (mMinHeight > height)
166
        height = mMinHeight;
167
1
    else if (mMaxHeight < height)
168
        height = mMaxHeight;
169
170
1
    setSize(width, height);
171
1
    mRedraw = true;
172
1
}
173
174
void Popup::setLocationRelativeTo(const Widget *const widget)
175
{
176
    if (widget == nullptr)
177
        return;
178
179
    int wx;
180
    int wy;
181
    int x;
182
    int y;
183
184
    widget->getAbsolutePosition(wx, wy);
185
    getAbsolutePosition(x, y);
186
187
    setPosition(mDimension.x + (wx + (widget->getWidth()
188
        - mDimension.width) / 2 - x),
189
        mDimension.y + (wy + (widget->getHeight()
190
        - mDimension.height) / 2 - y));
191
    mRedraw = true;
192
}
193
194
1
void Popup::setMinWidth(const int width)
195
{
196
1
    if (mSkin != nullptr)
197
    {
198
2
        mMinWidth = width > mSkin->getMinWidth()
199
1
            ? width : mSkin->getMinWidth();
200
    }
201
    else
202
    {
203
        mMinWidth = width;
204
    }
205
1
}
206
207
5
void Popup::setMinHeight(const int height)
208
{
209
5
    if (mSkin != nullptr)
210
    {
211
10
        mMinHeight = height > mSkin->getMinHeight() ?
212
5
            height : mSkin->getMinHeight();
213
    }
214
    else
215
    {
216
        mMinHeight = height;
217
    }
218
5
}
219
220
void Popup::setMaxWidth(const int width)
221
{
222
    mMaxWidth = width;
223
}
224
225
void Popup::setMaxHeight(const int height)
226
{
227
    mMaxHeight = height;
228
}
229
230
void Popup::scheduleDelete()
231
{
232
    windowContainer->scheduleDelete(this);
233
}
234
235
void Popup::position(const int x, const int y)
236
{
237
    const int distance = 20;
238
239
    const int width = mDimension.width;
240
    const int height = mDimension.height;
241
    int posX = std::max(0, x - width / 2);
242
    int posY = y + distance;
243
244
    if (posX + width > mainGraphics->mWidth)
245
        posX = mainGraphics->mWidth - width;
246
    if (posY + height > mainGraphics->mHeight)
247
        posY = y - height - distance;
248
249
    setPosition(posX, posY);
250
    setVisible(Visible_true);
251
    requestMoveToTop();
252
    mRedraw = true;
253
}
254
255
void Popup::mouseMoved(MouseEvent &event A_UNUSED)
256
{
257
    if (popupManager != nullptr)
258
    {
259
        PopupManager::hideBeingPopup();
260
        PopupManager::hideTextPopup();
261
    }
262
    mRedraw = true;
263
}
264
265
void Popup::hide()
266
{
267
    setVisible(Visible_false);
268
    mRedraw = true;
269
}
270
271
96
void Popup::widgetResized(const Event &event A_UNUSED)
272
{
273
96
    mRedraw = true;
274
96
}
275
276
void Popup::widgetMoved(const Event &event A_UNUSED)
277
{
278
    mRedraw = true;
279
}