GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/widgets/popup.cpp Lines: 52 118 44.1 %
Date: 2017-11-29 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-2017  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
222
Popup::Popup(const std::string &name,
40
222
             std::string skin) :
41
    Container(nullptr),
42
    MouseListener(),
43
    WidgetListener(),
44
    mPadding(3),
45
    mSkin(nullptr),
46
    mPopupName(name),
47

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

1110
        mSkin = theme->load(skin, "popup.xml");
66
222
        if (mSkin != nullptr)
67
        {
68
666
            setPadding(mSkin->getPadding());
69

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