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 |
|
116 |
Popup::Popup(const std::string &name, |
41 |
|
116 |
std::string skin) : |
42 |
|
|
Container(nullptr), |
43 |
|
|
MouseListener(), |
44 |
|
|
WidgetListener(), |
45 |
|
|
mPadding(3), |
46 |
|
|
mSkin(nullptr), |
47 |
|
|
mPopupName(name), |
48 |
✓✗✓✗
|
116 |
mVertexes(new ImageCollection), |
49 |
|
|
mMinWidth(100), |
50 |
|
|
mMinHeight(40), |
51 |
|
116 |
mMaxWidth(mainGraphics->mWidth), |
52 |
|
116 |
mMaxHeight(mainGraphics->mHeight), |
53 |
|
812 |
mInit(false) |
54 |
|
|
{ |
55 |
✓✗ |
116 |
logger->log("Popup::Popup(\"%s\")", name.c_str()); |
56 |
|
|
|
57 |
|
116 |
mWindow = this; |
58 |
|
|
|
59 |
✓✗ |
116 |
addWidgetListener(this); |
60 |
|
|
|
61 |
✗✓ |
116 |
if (skin.empty()) |
62 |
|
|
skin = "popup.xml"; |
63 |
|
|
|
64 |
✓✗ |
116 |
if (theme != nullptr) |
65 |
|
|
{ |
66 |
✓✗✓✗
|
464 |
mSkin = theme->load(skin, |
67 |
|
|
"popup.xml", |
68 |
|
|
true, |
69 |
|
116 |
Theme::getThemePath()); |
70 |
✓✗ |
116 |
if (mSkin != nullptr) |
71 |
|
|
{ |
72 |
|
348 |
setPadding(mSkin->getPadding()); |
73 |
✓✗✓✗
|
580 |
setPalette(mSkin->getOption("palette")); |
74 |
|
|
} |
75 |
|
|
} |
76 |
|
|
|
77 |
✓✗ |
116 |
if (windowContainer != nullptr) |
78 |
✓✗ |
116 |
windowContainer->add(this); |
79 |
|
|
|
80 |
|
|
// Popups are invisible by default |
81 |
✓✗ |
116 |
setVisible(Visible_false); |
82 |
|
116 |
} |
83 |
|
|
|
84 |
|
580 |
Popup::~Popup() |
85 |
|
|
{ |
86 |
|
232 |
logger->log("Popup::~Popup(\"%s\")", mPopupName.c_str()); |
87 |
|
|
|
88 |
✓✗ |
116 |
delete2(mVertexes) |
89 |
|
|
|
90 |
✓✗ |
116 |
if (mSkin != nullptr) |
91 |
|
|
{ |
92 |
✓✗ |
116 |
if (theme != nullptr) |
93 |
|
116 |
theme->unload(mSkin); |
94 |
|
116 |
mSkin = nullptr; |
95 |
|
|
} |
96 |
|
|
|
97 |
✗✓ |
116 |
if (!mInit) |
98 |
|
|
{ |
99 |
|
|
logger->log("error: Popup created without calling postInit(): " |
100 |
|
|
+ mPopupName); |
101 |
|
|
} |
102 |
|
116 |
} |
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 |
|
100 |
void Popup::widgetResized(const Event &event A_UNUSED) |
272 |
|
|
{ |
273 |
|
100 |
mRedraw = true; |
274 |
|
100 |
} |
275 |
|
|
|
276 |
|
|
void Popup::widgetMoved(const Event &event A_UNUSED) |
277 |
|
|
{ |
278 |
|
|
mRedraw = true; |
279 |
|
|
} |