ManaPlus
popup.cpp
Go to the documentation of this file.
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 
31 
32 #include "utils/delete2.h"
33 
34 #include "render/graphics.h"
35 
37 
38 #include "debug.h"
39 
40 Popup::Popup(const std::string &name,
41  std::string skin) :
43  MouseListener(),
45  mPadding(3),
46  mSkin(nullptr),
47  mPopupName(name),
48  mVertexes(new ImageCollection),
49  mMinWidth(100),
50  mMinHeight(40),
51  mMaxWidth(mainGraphics->mWidth),
52  mMaxHeight(mainGraphics->mHeight),
53  mInit(false)
54 {
55  logger->log("Popup::Popup(\"%s\")", name.c_str());
56 
57  mWindow = this;
58 
59  addWidgetListener(this);
60 
61  if (skin.empty())
62  skin = "popup.xml";
63 
64  if (theme != nullptr)
65  {
66  mSkin = theme->load(skin,
67  "popup.xml",
68  true,
70  if (mSkin != nullptr)
71  {
73  setPalette(mSkin->getOption("palette"));
74  }
75  }
76 
77  if (windowContainer != nullptr)
78  windowContainer->add(this);
79 
80  // Popups are invisible by default
82 }
83 
85 {
86  logger->log("Popup::~Popup(\"%s\")", mPopupName.c_str());
87 
89 
90  if (mSkin != nullptr)
91  {
92  if (theme != nullptr)
93  theme->unload(mSkin);
94  mSkin = nullptr;
95  }
96 
97  if (!mInit)
98  {
99  logger->log("error: Popup created without calling postInit(): "
100  + mPopupName);
101  }
102 }
103 
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,
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,
141  mSkin->getBorder());
142  }
143 
144  safeDrawChildren(graphics);
145  BLOCK_END("Popup::safeDraw")
146 }
147 
149 {
150  const int pad2 = mPadding * 2;
151  return Rect(mPadding, mPadding,
152  mDimension.width - pad2, mDimension.height - pad2);
153 }
154 
155 void Popup::setContentSize(int width, int height)
156 {
157  const int pad2 = mPadding * 2;
158  width += pad2;
159  height += pad2;
160 
161  if (mMinWidth > width)
162  width = mMinWidth;
163  else if (mMaxWidth < width)
164  width = mMaxWidth;
165  if (mMinHeight > height)
166  height = mMinHeight;
167  else if (mMaxHeight < height)
168  height = mMaxHeight;
169 
170  setSize(width, height);
171  mRedraw = true;
172 }
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);
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 void Popup::setMinWidth(const int width)
195 {
196  if (mSkin != nullptr)
197  {
198  mMinWidth = width > mSkin->getMinWidth()
199  ? width : mSkin->getMinWidth();
200  }
201  else
202  {
203  mMinWidth = width;
204  }
205 }
206 
207 void Popup::setMinHeight(const int height)
208 {
209  if (mSkin != nullptr)
210  {
211  mMinHeight = height > mSkin->getMinHeight() ?
212  height : mSkin->getMinHeight();
213  }
214  else
215  {
216  mMinHeight = height;
217  }
218 }
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 
231 {
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);
252  mRedraw = true;
253 }
254 
256 {
257  if (popupManager != nullptr)
258  {
261  }
262  mRedraw = true;
263 }
264 
266 {
268  mRedraw = true;
269 }
270 
272 {
273  mRedraw = true;
274 }
275 
277 {
278  mRedraw = true;
279 }
virtual void add(Widget *const widget)
virtual void safeDrawChildren(Graphics *const graphics)
virtual void drawChildren(Graphics *const graphics)
Definition: event.h:79
int mWidth
Definition: graphics.h:484
virtual void drawTileCollection(const ImageCollection *const vertCol)=0
int mHeight
Definition: graphics.h:485
virtual void finalize(ImageCollection *const col)
Definition: graphics.h:465
virtual void calcWindow(ImageCollection *const vertCol, const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
virtual void drawImageRect(const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
void log(const char *const log_text,...)
Definition: logger.cpp:269
static void hideTextPopup()
static void hideBeingPopup()
Skin * mSkin
Definition: popup.h:182
void setPadding(int padding)
Definition: popup.h:138
void scheduleDelete()
Definition: popup.cpp:230
void setMaxHeight(const int height)
Definition: popup.cpp:225
~Popup()
Definition: popup.cpp:84
void setMaxWidth(const int width)
Definition: popup.cpp:220
void setLocationRelativeTo(const Widget *const widget)
Definition: popup.cpp:174
void hide()
Definition: popup.cpp:265
int mMinHeight
Definition: popup.h:188
void draw(Graphics *const graphics)
Definition: popup.cpp:109
static void setWindowContainer(WindowContainer *const windowContainer)
Definition: popup.cpp:104
void setMinHeight(const int height)
Definition: popup.cpp:207
void widgetMoved(const Event &event)
Definition: popup.cpp:276
Popup(const std::string &name, std::string skin)
Definition: popup.cpp:40
void setMinWidth(const int width)
Definition: popup.cpp:194
std::string mPopupName
Definition: popup.h:185
void setContentSize(int width, int height)
Definition: popup.cpp:155
void safeDraw(Graphics *const graphics)
Definition: popup.cpp:133
ImageCollection * mVertexes
Definition: popup.h:186
void position(const int x, const int y)
Definition: popup.cpp:235
int mMinWidth
Definition: popup.h:187
Rect getChildrenArea()
Definition: popup.cpp:148
int mMaxWidth
Definition: popup.h:189
void widgetResized(const Event &event)
Definition: popup.cpp:271
void mouseMoved(MouseEvent &event)
Definition: popup.cpp:255
int mMaxHeight
Definition: popup.h:190
int mPadding
Definition: popup.h:181
bool mInit
Definition: popup.h:191
Definition: rect.h:74
int y
Definition: rect.h:214
int width
Definition: rect.h:219
int x
Definition: rect.h:209
int height
Definition: rect.h:224
int getOption(const std::string &name) const
Definition: skin.h:106
int getMinWidth() const
Definition: skin.cpp:129
const ImageRect & getBorder() const
Definition: skin.h:68
int getPadding() const
Definition: skin.h:100
int getMinHeight() const
Definition: skin.cpp:142
void unload(Skin *const skin)
Definition: theme.cpp:250
static std::string getThemePath()
Definition: theme.h:67
Skin * load(const std::string &filename, const std::string &filename2, const bool full, const std::string &defaultPath)
Definition: theme.cpp:179
Widget * mWindow
Definition: widget2.h:112
void setPalette(int palette)
Definition: widget2.h:69
Definition: widget.h:99
void setVisible(Visible visible)
Definition: widget.cpp:225
void setSize(const int width, const int height)
Definition: widget.cpp:367
virtual void getAbsolutePosition(int &x, int &y) const
Definition: widget.cpp:312
virtual void requestMoveToTop()
Definition: widget.cpp:213
Rect mDimension
Definition: widget.h:1101
void addWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:302
bool mRedraw
Definition: widget.h:1164
void setPosition(const int x, const int y)
Definition: widget.cpp:161
int getHeight() const
Definition: widget.h:240
int getWidth() const
Definition: widget.h:221
void scheduleDelete(Widget *const widget)
#define new
Definition: debug_new.h:147
#define delete2(var)
Definition: delete2.h:25
Graphics * mainGraphics
Definition: graphics.cpp:109
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
Logger * logger
Definition: logger.cpp:89
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
PopupManager * popupManager
Theme * theme
Definition: theme.cpp:62
const bool Visible_false
Definition: visible.h:30
const bool Visible_true
Definition: visible.h:30
WindowContainer * windowContainer