ManaPlus
widget.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2011-2018 The ManaPlus Developers
4  *
5  * This file is part of The ManaPlus Client.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 /* _______ __ __ __ ______ __ __ _______ __ __
22  * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
23  * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
24  * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
25  * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
26  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
27  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
28  *
29  * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
30  *
31  *
32  * Per Larsson a.k.a finalman
33  * Olof Naessén a.k.a jansem/yakslem
34  *
35  * Visit: http://guichan.sourceforge.net
36  *
37  * License: (BSD)
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  * notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  * notice, this list of conditions and the following disclaimer in
45  * the documentation and/or other materials provided with the
46  * distribution.
47  * 3. Neither the name of Guichan nor the names of its contributors may
48  * be used to endorse or promote products derived from this software
49  * without specific prior written permission.
50  *
51  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
52  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
53  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
54  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
55  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
56  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
57  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
58  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
59  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
60  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63 
64 /*
65  * For comments regarding functions please see the header file.
66  */
67 
68 #include "gui/widgets/widget.h"
69 
70 #include "gui/focushandler.h"
71 
75 
76 #include "utils/foreach.h"
77 
78 #include "debug.h"
79 
80 Font* Widget::mGlobalFont = nullptr;
81 std::list<Widget*> Widget::mAllWidgets;
82 std::set<Widget*> Widget::mAllWidgetsSet;
83 
84 Widget::Widget(const Widget2 *const widget) :
85  Widget2(widget),
86  mVisible(Visible_true),
87  mMouseListeners(),
88  mKeyListeners(),
89  mActionListeners(),
90  mDeathListeners(),
91  mFocusListeners(),
92  mWidgetListeners(),
93  mForegroundColor(0x000000),
94  mBackgroundColor(0xffffff),
95  mBaseColor(0x808090),
96  mDimension(),
97  mActionEventId(),
98  mId(),
99  mFocusHandler(nullptr),
100  mInternalFocusHandler(nullptr),
101  mParent(nullptr),
102  mCurrentFont(nullptr),
103  mFrameSize(0),
104  mFocusable(false),
105  mTabIn(true),
106  mTabOut(true),
107  mEnabled(true),
108  mAllowLogic(true),
109  mMouseConsume(true),
110  mRedraw(true),
111  mSelectable(true)
112 {
113  mAllWidgets.push_back(this);
114  mAllWidgetsSet.insert(this);
115 }
116 
118 {
120  {
121  Event event(this);
122  (*iter)->death(event);
123  }
124 
125  // +++ call to virtual member
126  setFocusHandler(nullptr);
127 
128  mAllWidgets.remove(this);
129  mAllWidgetsSet.erase(this);
130 }
131 
132 void Widget::setWidth(const int width)
133 {
134  Rect newDimension = mDimension;
135  newDimension.width = width;
136  setDimension(newDimension);
137 }
138 
139 void Widget::setHeight(const int height)
140 {
141  Rect newDimension = mDimension;
142  newDimension.height = height;
143  setDimension(newDimension);
144 }
145 
146 void Widget::setX(const int x)
147 {
148  Rect newDimension = mDimension;
149  newDimension.x = x;
150  setDimension(newDimension);
151 }
152 
153 void Widget::setY(const int y)
154 {
155  Rect newDimension = mDimension;
156  newDimension.y = y;
157  setDimension(newDimension);
158 }
159 
160 void Widget::setPosition(const int x, const int y)
161 {
162  Rect newDimension = mDimension;
163  newDimension.x = x;
164  newDimension.y = y;
165  setDimension(newDimension);
166 }
167 
168 void Widget::setDimension(const Rect& dimension)
169 {
170  const Rect oldDimension = mDimension;
171  mDimension = dimension;
172 
173  if (mDimension.width != oldDimension.width
174  || mDimension.height != oldDimension.height)
175  {
177  }
178 
179  if (mDimension.x != oldDimension.x || mDimension.y != oldDimension.y)
181 }
182 
183 bool Widget::isFocused() const
184 {
185  if (mFocusHandler == nullptr)
186  return false;
187 
188  return mFocusHandler->isFocused(this);
189 }
190 
191 void Widget::setFocusable(const bool focusable)
192 {
193  if (!focusable && isFocused() && (mFocusHandler != nullptr))
195  mFocusable = focusable;
196 }
197 
199 {
200  return mFocusable && isVisible() && isEnabled();
201 }
202 
204 {
205  if (mFocusHandler == nullptr)
206  return;
207 
208  if (isFocusable())
210 }
211 
213 {
214  if (mParent != nullptr)
215  mParent->moveToTop(this);
216 }
217 
219 {
220  if (mParent != nullptr)
221  mParent->moveToBottom(this);
222 }
223 
225 {
226  if (visible == Visible_false && isFocused() && (mFocusHandler != nullptr))
228 
229  if (visible == Visible_true)
231  else
233 
234  mVisible = visible;
235 }
236 
237 void Widget::setFocusHandler(FocusHandler *const focusHandler)
238 {
239  if (mFocusHandler != nullptr)
240  {
242  mFocusHandler->remove(this);
243  }
244 
245  if (focusHandler != nullptr)
246  focusHandler->add(this);
247 
248  mFocusHandler = focusHandler;
249 }
250 
251 void Widget::addActionListener(ActionListener *const actionListener)
252 {
253  mActionListeners.push_back(actionListener);
254 }
255 
256 void Widget::removeActionListener(ActionListener *const actionListener)
257 {
258  mActionListeners.remove(actionListener);
259 }
260 
262 {
263  mDeathListeners.push_back(deathListener);
264 }
265 
267 {
268  mDeathListeners.remove(deathListener);
269 }
270 
271 void Widget::addKeyListener(KeyListener *const keyListener)
272 {
273  mKeyListeners.push_back(keyListener);
274 }
275 
276 void Widget::removeKeyListener(KeyListener *const keyListener)
277 {
278  mKeyListeners.remove(keyListener);
279 }
280 
281 void Widget::addFocusListener(FocusListener *const focusListener)
282 {
283  mFocusListeners.push_back(focusListener);
284 }
285 
286 void Widget::removeFocusListener(FocusListener *const focusListener)
287 {
288  mFocusListeners.remove(focusListener);
289 }
290 
291 void Widget::addMouseListener(MouseListener *const mouseListener)
292 {
293  mMouseListeners.push_back(mouseListener);
294 }
295 
296 void Widget::removeMouseListener(MouseListener *const mouseListener)
297 {
298  mMouseListeners.remove(mouseListener);
299 }
300 
301 void Widget::addWidgetListener(WidgetListener *const widgetListener)
302 {
303  mWidgetListeners.push_back(widgetListener);
304 }
305 
306 void Widget::removeWidgetListener(WidgetListener *const widgetListener)
307 {
308  mWidgetListeners.remove(widgetListener);
309 }
310 
311 void Widget::getAbsolutePosition(int& x, int& y) const
312 {
313  if (mParent == nullptr)
314  {
315  x = mDimension.x;
316  y = mDimension.y;
317  return;
318  }
319 
320  int parentX;
321  int parentY;
322 
323  mParent->getAbsolutePosition(parentX, parentY);
324 
325  const Rect &rect = mParent->getChildrenArea();
326  x = parentX + mDimension.x + rect.x;
327  y = parentY + mDimension.y + rect.y;
328 }
329 
331 {
332  if (mCurrentFont == nullptr)
333  return mGlobalFont;
334  return mCurrentFont;
335 }
336 
338 {
339  mGlobalFont = font;
340 
341  FOR_EACH (std::list<Widget*>::const_iterator, iter, mAllWidgets)
342  {
343  if ((*iter)->mCurrentFont == nullptr)
344  (*iter)->fontChanged();
345  }
346 }
347 
349 {
350  mCurrentFont = font;
351  fontChanged();
352 }
353 
355 {
356  FOR_EACH (std::list<Widget*>::const_iterator, iter, mAllWidgets)
357  (*iter)->windowResized();
358 }
359 
360 bool Widget::widgetExists(const Widget *const widget)
361 {
362  return mAllWidgetsSet.find(const_cast<Widget*>(widget))
363  != mAllWidgetsSet.end();
364 }
365 
366 void Widget::setSize(const int width, const int height)
367 {
368  Rect newDimension = mDimension;
369  newDimension.width = width;
370  newDimension.height = height;
371  setDimension(newDimension);
372 }
373 
374 bool Widget::isEnabled() const
375 {
376  return mEnabled && isVisible();
377 }
378 
380 {
381  if (mFocusHandler == nullptr)
382  return;
384 }
385 
387 {
388  if (mFocusHandler == nullptr)
389  return;
391 }
392 
394 {
395  if (mFocusHandler == nullptr)
396  return;
398 }
399 
401 {
402  if (mFocusHandler == nullptr)
403  return;
405 }
406 
408 {
409  if (mFocusHandler == nullptr)
410  return false;
411 
412  if (mParent != nullptr)
413  {
414  return (mFocusHandler->getModalFocused() == this)
415  || mParent->isModalFocused();
416  }
417 
418  return mFocusHandler->getModalFocused() == this;
419 }
420 
422 {
423  if (mFocusHandler == nullptr)
424  return false;
425 
426  if (mParent != nullptr)
427  {
428  return (mFocusHandler->getModalMouseInputFocused() == this)
430  }
431 
432  return mFocusHandler->getModalMouseInputFocused() == this;
433 }
434 
435 const std::list<MouseListener*> &Widget::getMouseListeners() const
436 {
437  return mMouseListeners;
438 }
439 
440 const std::list<KeyListener*> &Widget::getKeyListeners() const
441 {
442  return mKeyListeners;
443 }
444 
445 const std::list<FocusListener*> &Widget::getFocusListeners() const
446 {
447  return mFocusListeners;
448 }
449 
451 {
452  return Rect(0, 0, 0, 0);
453 }
454 
456 {
457  return mInternalFocusHandler;
458 }
459 
461 {
462  mInternalFocusHandler = focusHandler;
463 }
464 
466 {
468  {
469  Event event(this);
470  (*iter)->widgetResized(event);
471  }
472 }
473 
475 {
477  {
478  Event event(this);
479  (*iter)->widgetMoved(event);
480  }
481 }
482 
484 {
486  {
487  Event event(this);
488  (*iter)->widgetHidden(event);
489  }
490 }
491 
493 {
495  {
496  ActionEvent actionEvent(this, mActionEventId);
497  (*iter)->action(actionEvent);
498  }
499 }
500 
502 {
504  {
505  Event event(this);
506  (*iter)->widgetShown(event);
507  }
508 }
509 
510 void Widget::showPart(const Rect &rectangle)
511 {
512  if (mParent != nullptr)
513  mParent->showWidgetPart(this, rectangle);
514 }
515 
517 {
518  mRedraw = true;
519 }
520 
522 {
523  if (widget != nullptr)
524  widget->postInit();
525  return widget;
526 }
void setSize(const int width, const int height)
Definition: widget.cpp:366
Font * getFont() const
Definition: widget.cpp:330
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
int width
Definition: rect.h:218
virtual void fontChanged()
Definition: widget.h:666
FocusListenerList mFocusListeners
Definition: widget.h:1063
static std::list< Widget * > mAllWidgets
Definition: widget.h:1176
void setWidth(const int width)
Definition: widget.cpp:132
static std::set< Widget * > mAllWidgetsSet
Definition: widget.h:1178
Definition: font.h:88
void removeDeathListener(WidgetDeathListener *const deathListener)
Definition: widget.cpp:266
void requestModalFocus()
Definition: widget.cpp:379
virtual void releaseModalFocus()
Definition: widget.cpp:393
const bool Visible_true
Definition: visible.h:29
KeyListenerList mKeyListeners
Definition: widget.h:1018
static Widget * callPostInit(Widget *const widget)
Definition: widget.cpp:521
void setY(const int y)
Definition: widget.cpp:153
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:251
void setVisible(Visible visible)
Definition: widget.cpp:224
Definition: rect.h:72
virtual void requestMoveToTop()
Definition: widget.cpp:212
void removeFocusListener(FocusListener *const focusListener)
Definition: widget.cpp:286
static void setGlobalFont(Font *const font)
Definition: widget.cpp:337
void add(Widget *const widget)
void addFocusListener(FocusListener *const focusListener)
Definition: widget.cpp:281
virtual FocusHandler * getInternalFocusHandler()
Definition: widget.cpp:455
Widget * getModalMouseInputFocused() const
bool isFocused(const Widget *const widget) const
void setDimension(const Rect &dimension)
Definition: widget.cpp:168
virtual void releaseModalMouseInputFocus()
Definition: widget.cpp:400
void remove(Widget *const widget)
FocusHandler * mFocusHandler
Definition: widget.h:1115
void requestModalMouseInputFocus(Widget *const widget)
void removeKeyListener(KeyListener *const keyListener)
Definition: widget.cpp:276
virtual bool isFocused() const
Definition: widget.cpp:183
virtual void requestModalMouseInputFocus()
Definition: widget.cpp:386
MouseListenerList mMouseListeners
Definition: widget.h:1008
Visible mVisible
Definition: widget.h:962
void distributeActionEvent()
Definition: widget.cpp:492
virtual bool isModalFocused() const
Definition: widget.cpp:407
int x
Definition: rect.h:208
virtual void showWidgetPart(Widget *const widget, const Rect &area)
Definition: widget.h:902
void requestModalFocus(Widget *const widget)
void removeMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:296
ActionListenerList mActionListeners
Definition: widget.h:1033
virtual void requestFocus()
Definition: widget.cpp:203
void windowResized()
Definition: widget.cpp:516
Font * mCurrentFont
Definition: widget.h:1132
const bool Visible_false
Definition: visible.h:29
Widget * mParent
Definition: widget.h:1127
void setX(const int x)
Definition: widget.cpp:146
bool mFocusable
Definition: widget.h:1142
int y
Definition: rect.h:213
static void distributeWindowResizeEvent()
Definition: widget.cpp:354
#define nullptr
Definition: localconsts.h:44
Widget(const Widget2 *const widget)
Definition: widget.cpp:84
FocusHandler * mInternalFocusHandler
Definition: widget.h:1121
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:291
bool isEnabled() const
Definition: widget.cpp:374
void setPosition(const int x, const int y)
Definition: widget.cpp:160
int height
Definition: rect.h:223
void addKeyListener(KeyListener *const keyListener)
Definition: widget.cpp:271
WidgetListenerList mWidgetListeners
Definition: widget.h:1075
virtual void getAbsolutePosition(int &x, int &y) const
Definition: widget.cpp:311
ActionListenerList::iterator ActionListenerIterator
Definition: widget.h:1038
virtual bool isModalMouseInputFocused() const
Definition: widget.cpp:421
virtual void moveToBottom(Widget *widget)
Definition: widget.h:876
void distributeShownEvent()
Definition: widget.cpp:501
virtual void moveToTop(Widget *widget)
Definition: widget.h:866
void requestFocus(const Widget *const widget)
void setHeight(const int height)
Definition: widget.cpp:139
void addWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:301
void setFocusable(const bool focusable)
Definition: widget.cpp:191
bool isVisible() const
Definition: widget.h:377
Definition: widget.h:97
void setFont(Font *const font)
Definition: widget.cpp:348
virtual void requestMoveToBottom()
Definition: widget.cpp:218
void removeWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:306
static bool widgetExists(const Widget *const widget)
Definition: widget.cpp:360
Widget * getModalFocused() const
Definition: event.h:77
bool mRedraw
Definition: widget.h:1163
bool mEnabled
Definition: widget.h:1157
bool isFocusable() const
Definition: widget.cpp:198
virtual void showPart(const Rect &rectangle)
Definition: widget.cpp:510
WidgetListenerList::iterator WidgetListenerIterator
Definition: widget.h:1080
void distributeResizedEvent()
Definition: widget.cpp:465
std::string mActionEventId
Definition: widget.h:1105
void removeActionListener(ActionListener *const actionListener)
Definition: widget.cpp:256
void addDeathListener(WidgetDeathListener *const deathListener)
Definition: widget.cpp:261
virtual void postInit()
Definition: widget.h:956
void distributeMovedEvent()
Definition: widget.cpp:474
~Widget()
Definition: widget.cpp:117
const std::list< KeyListener * > & getKeyListeners() const A_CONST
Definition: widget.cpp:440
virtual void setFocusHandler(FocusHandler *const focusHandler)
Definition: widget.cpp:237
void releaseModalFocus(Widget *const widget)
WidgetDeathListenerList mDeathListeners
Definition: widget.h:1048
void setInternalFocusHandler(FocusHandler *const internalFocusHandler)
Definition: widget.cpp:460
virtual Rect getChildrenArea()
Definition: widget.cpp:450
Rect mDimension
Definition: widget.h:1100
const std::list< FocusListener * > & getFocusListeners() const A_CONST
Definition: widget.cpp:445
WidgetDeathListenerList::iterator WidgetDeathListenerIterator
Definition: widget.h:1053
void distributeHiddenEvent()
Definition: widget.cpp:483
const std::list< MouseListener * > & getMouseListeners() const A_CONST
Definition: widget.cpp:435
void releaseModalMouseInputFocus(const Widget *const widget)
static Font * mGlobalFont
Definition: widget.h:1170