GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/popup.cpp Lines: 53 119 44.5 %
Date: 2018-09-20 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-2018  The ManaPlus Developers
6
 *  Copyright (C) 2009  Aethyra Development Team
7
 *
8
 *  This file is part of The ManaPlus Client.
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
#include "gui/widgets/popup.h"
25
26
#include "gui/popupmanager.h"
27
#include "gui/skin.h"
28
29
#include "gui/widgets/windowcontainer.h"
30
31
#include "utils/delete2.h"
32
33
#include "render/graphics.h"
34
35
#include "render/vertexes/imagecollection.h"
36
37
#include "debug.h"
38
39
112
Popup::Popup(const std::string &name,
40
112
             std::string skin) :
41
    Container(nullptr),
42
    MouseListener(),
43
    WidgetListener(),
44
    mPadding(3),
45
    mSkin(nullptr),
46
    mPopupName(name),
47

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

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

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