1 /*
2  *  The ManaPlus Client
3  *  Copyright (C) 2011-2019  The ManaPlus Developers
4  *  Copyright (C) 2019-2021  Andrei Karas
5  *
6  *  This file is part of The ManaPlus Client.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 /*      _______   __   __   __   ______   __   __   _______   __   __
23  *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
24  *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
25  *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
26  *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
27  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
28  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
29  *
30  * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
31  *
32  *
33  * Per Larsson a.k.a finalman
34  * Olof Naessén a.k.a jansem/yakslem
35  *
36  * Visit: http://guichan.sourceforge.net
37  *
38  * License: (BSD)
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in
46  *    the documentation and/or other materials provided with the
47  *    distribution.
48  * 3. Neither the name of Guichan nor the names of its contributors may
49  *    be used to endorse or promote products derived from this software
50  *    without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
53  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
54  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
55  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
56  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
57  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
58  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
59  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
60  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
61  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63  */
64 
65 #ifndef GUI_WIDGETS_WIDGET_H
66 #define GUI_WIDGETS_WIDGET_H
67 
68 #include "enums/simpletypes/visible.h"
69 
70 #include "gui/rect.h"
71 
72 #include "gui/widgets/widget2.h"
73 
74 #include <list>
75 
76 #include "localconsts.h"
77 
78 class ActionListener;
79 class WidgetDeathListener;
80 class FocusHandler;
81 class FocusListener;
82 class Font;
83 class Graphics;
84 class KeyListener;
85 class MouseListener;
86 class WidgetListener;
87 
88 /**
89   * Abstract class for widgets of Guichan. It contains basic functions
90   * every widget should have.
91   *
92   * NOTE: Functions begining with underscore "_" should not
93   *       be overloaded unless you know what you are doing
94   *
95   * @author Olof Naessén
96   * @author Per Larsson.
97   */
98 class Widget notfinal : public Widget2
99 {
100     public:
101         friend class BasicContainer;
102 
103         /**
104           * Constructor. Resets member variables. Noteable, a widget is not
105           * focusable as default, therefore, widgets that are supposed to be
106           * focusable should overide this default in their own constructor.
107           */
108         explicit Widget(const Widget2 *const widget);
109 
110         A_DELETE_COPY(Widget)
111 
112         /**
113           * Default destructor.
114           */
115         ~Widget() override;
116 
117         /**
118           * Draws the widget. It is called by the parent widget when it is time
119           * for the widget to draw itself. The graphics object is set up so
120           * that all drawing is relative to the widget, i.e coordinate (0,0) is
121           * the top left corner of the widget. It is not possible to draw
122           * outside of a widget's dimension.
123           *
124           * @param graphics aA graphics object to draw with.
125           */
126         virtual void draw(Graphics *const graphics) A_NONNULL(2) = 0;
127 
128         virtual void safeDraw(Graphics *const graphics) A_NONNULL(2) = 0;
129 
130         /**
131           * Called when a widget is given a chance to draw a frame around itself.
132           * The frame is not considered a part of the widget, it only allows a frame
133           * to be drawn around the widget, thus a frame will never be included when
134           * calculating if a widget should receive events from user input. Also
135           * a widget's frame will never be included when calculating a widget's
136           * position.
137           *
138           * The size of the frame is calculated using the widget's frame size.
139           * If a widget has a frame size of 10 pixels than the area the drawFrame
140           * function can draw to will be the size of the widget with an additional
141           * extension of 10 pixels in each direction.
142           *
143           * An example when drawFrame is a useful function is if a widget needs
144           * a glow around itself.
145           *
146           * @param graphics A graphics object to draw with.
147           * @see setFrameSize, getFrameSize
148           */
drawFrame(Graphics * graphics A_UNUSED)149         virtual void drawFrame(Graphics* graphics A_UNUSED) A_NONNULL(2)
150         { }
151 
safeDrawFrame(Graphics * graphics A_UNUSED)152         virtual void safeDrawFrame(Graphics* graphics A_UNUSED) A_NONNULL(2)
153         { }
154 
155         /**
156           * Sets the size of the widget's frame. The frame is not considered a part of
157           * the widget, it only allows a frame to be drawn around the widget, thus a frame
158           * will never be included when calculating if a widget should receive events
159           * from user input. Also a widget's frame will never be included when calculating
160           * a widget's position.
161           *
162           * A frame size of 0 means that the widget has no frame. The default frame size
163           * is 0.
164           *
165           * @param frameSize The size of the widget's frame.
166           * @see getFrameSize, drawFrame
167           */
setFrameSize(const unsigned int frameSize)168         void setFrameSize(const unsigned int frameSize) noexcept2
169         { mFrameSize = frameSize; }
170 
171         /**
172           * Gets the size of the widget's frame. The frame is not considered a part of
173           * the widget, it only allows a frame to be drawn around the widget, thus a frame
174           * will never be included when calculating if a widget should receive events
175           * from user input. Also a widget's frame will never be included when calculating
176           * a widget's position.
177           *
178           * A frame size of 0 means that the widget has no frame. The default frame size
179           * is 0.
180           *
181           * @return The size of the widget's frame.
182           * @see setFrameSize, drawFrame
183           */
getFrameSize()184         unsigned int getFrameSize() const noexcept2 A_WARN_UNUSED
185         { return mFrameSize; }
186 
187         /**
188           * Called for all widgets in the gui each time Gui::logic is called.
189           * You can do logic stuff here like playing an animation.
190           *
191           * @see Gui::logic
192           */
logic()193         virtual void logic()
194         { }
195 
196         /**
197           * Gets the widget's parent container.
198           *
199           * @return The widget's parent container. NULL if the widget
200           *         has no parent.
201           */
getParent()202         Widget* getParent() const noexcept2 A_WARN_UNUSED
203         { return mParent; }
204 
205         /**
206           * Sets the width of the widget.
207           *
208           * @param width The width of the widget.
209           * @see getWidth, setHeight, getHeight, setSize,
210           *      setDimension, getDimensi
211           */
212         void setWidth(const int width);
213 
214         /**
215           * Gets the width of the widget.
216           *
217           * @return The width of the widget.
218           * @see setWidth, setHeight, getHeight, setSize,
219           *      setDimension, getDimension
220           */
getWidth()221         int getWidth() const noexcept2 A_WARN_UNUSED
222         { return mDimension.width; }
223 
224         /**
225           * Sets the height of the widget.
226           *
227           * @param height The height of the widget.
228           * @see getHeight, setWidth, getWidth, setSize,
229           *      setDimension, getDimension
230           */
231         void setHeight(const int height);
232 
233         /**
234           * Gets the height of the widget.
235           *
236           * @return The height of the widget.
237           * @see setHeight, setWidth, getWidth, setSize,
238           *      setDimension, getDimension
239           */
getHeight()240         int getHeight() const noexcept2 A_WARN_UNUSED
241         { return mDimension.height; }
242 
243         /**
244           * Sets the size of the widget.
245           *
246           * @param width The width of the widget.
247           * @param height The height of the widget.
248           * @see setWidth, setHeight, getWidth, getHeight,
249           *      setDimension, getDimension
250           */
251         void setSize(const int width, const int height);
252 
253         /**
254           * Sets the x coordinate of the widget. The coordinate is
255           * relateive to the widget's parent.
256           *
257           * @param x The x coordinate of the widget.
258           * @see getX, setY, getY, setPosition, setDimension, getDimension
259           */
260         void setX(const int x);
261 
262         /**
263           * Gets the x coordinate of the widget. The coordinate is
264           * relative to the widget's parent.
265           *
266           * @return The x coordinate of the widget.
267           * @see setX, setY, getY, setPosition, setDimension, getDimension
268           */
getX()269         int getX() const noexcept2 A_WARN_UNUSED
270         { return mDimension.x; }
271 
272         /**
273           * Sets the y coordinate of the widget. The coordinate is
274           * relative to the widget's parent.
275           *
276           * @param y The y coordinate of the widget.
277           * @see setY, setX, getX, setPosition, setDimension, getDimension
278           */
279         void setY(const int y);
280 
281         /**
282           * Gets the y coordinate of the widget. The coordinate is
283           * relative to the widget's parent.
284           *
285           * @return The y coordinate of the widget.
286           * @see setY, setX, getX, setPosition, setDimension, getDimension
287           */
getY()288         int getY() const noexcept2 A_WARN_UNUSED
289         { return mDimension.y; }
290 
291         /**
292           * Sets position of the widget. The position is relative
293           * to the widget's parent.
294           *
295           * @param x The x coordinate of the widget.
296           * @param y The y coordinate of the widget.
297           * @see setX, getX, setY, getY, setDimension, getDimension
298           */
299         void setPosition(const int x, const int y);
300 
301         /**
302           * Sets the dimension of the widget. The dimension is
303           * relative to the widget's parent.
304           *
305           * @param dimension The dimension of the widget.
306           * @see getDimension, setX, getX, setY, getY, setPosition
307           */
308         void setDimension(const Rect& dimension);
309 
310         /**
311           * Gets the dimension of the widget. The dimension is
312           * relative to the widget's parent.
313           *
314           * @return The dimension of the widget.
315           * @see getDimension, setX, getX, setY, getY, setPosition
316           */
getDimension()317         const Rect& getDimension() const noexcept2 A_WARN_UNUSED
318         { return mDimension; }
319 
320         /**
321           * Sets the widget to be fosusable, or not.
322           *
323           * @param focusable True if the widget should be focusable,
324           *                  false otherwise.
325           * @see isFocusable
326           */
327         void setFocusable(const bool focusable);
328 
329           /**
330           * Checks if a widget is focsable.
331           *
332           * @return True if the widget should be focusable, false otherwise.
333           * @see setFocusable
334           */
335         bool isFocusable() const A_WARN_UNUSED;
336 
337         /**
338           * Checks if the widget is focused.
339           *
340           * @return True if the widget is focused, false otherwise.
341           */
342         virtual bool isFocused() const A_WARN_UNUSED;
343 
344         /**
345           * Sets the widget to enabled, or not. A disabled
346           * widget will never recieve mouse or key events.
347           *
348           * @param enabled True if widget should be enabled,
349           *                false otherwise.
350           * @see isEnabled
351           */
setEnabled(const bool enabled)352         void setEnabled(const bool enabled) noexcept2
353         { mEnabled = enabled; }
354 
355         /**
356           * Checks if the widget is enabled. A disabled
357           * widget will never recieve mouse or key events.
358           *
359           * @return True if widget is enabled, false otherwise.
360           * @see setEnabled
361           */
362         bool isEnabled() const A_WARN_UNUSED;
363 
364         /**
365           * Sets the widget to be visible, or not.
366           *
367           * @param visible True if widget should be visible, false otherwise.
368           * @see isVisible
369           */
370         void setVisible(Visible visible);
371 
372         /**
373           * Checks if the widget is visible.
374           *
375           * @return True if widget is be visible, false otherwise.
376           * @see setVisible
377           */
isVisible()378         bool isVisible() const A_WARN_UNUSED
379         {
380             return mVisible == Visible_true &&
381                 ((mParent == nullptr) || mParent->isVisible());
382         }
383 
384         /**
385           * Sets the base color of the widget.
386           *
387           * @param color The baseground color.
388           * @see getBaseColor
389           */
setBaseColor(const Color & color)390         void setBaseColor(const Color& color) noexcept2
391         { mBaseColor = color; }
392 
393         /**
394           * Gets the base color.
395           *
396           * @return The base color.
397           * @see setBaseColor
398           */
getBaseColor()399         const Color& getBaseColor() const noexcept2 A_WARN_UNUSED
400         { return mBaseColor; }
401 
402         /**
403           * Sets the foreground color.
404           *
405           * @param color The foreground color.
406           * @see getForegroundColor
407           */
setForegroundColor(const Color & color)408         void setForegroundColor(const Color& color) noexcept2
409         { mForegroundColor = color; }
410 
411         /**
412           * Gets the foreground color.
413           *
414           * @see setForegroundColor
415           */
getForegroundColor()416         const Color& getForegroundColor() const noexcept2 A_WARN_UNUSED
417         { return mForegroundColor; }
418 
419         /**
420           * Sets the background color.
421           *
422           * @param color The background Color.
423           * @see setBackgroundColor
424           */
setBackgroundColor(const Color & color)425         void setBackgroundColor(const Color &color) noexcept2
426         { mBackgroundColor = color; }
427 
428         /**
429           * Gets the background color.
430           *
431           * @see setBackgroundColor
432           */
getBackgroundColor()433         const Color &getBackgroundColor() const noexcept2 A_WARN_UNUSED
434         { return mBackgroundColor; }
435 
436         /**
437           * Requests focus for the widget. A widget will only recieve focus
438           * if it is focusable.
439           */
440         virtual void requestFocus();
441 
442         /**
443           * Requests a move to the top in the parent widget.
444           */
445         virtual void requestMoveToTop();
446 
447         /**
448           * Requests a move to the bottom in the parent widget.
449           */
450         virtual void requestMoveToBottom();
451 
452         /**
453           * Sets the focus handler to be used.
454           *
455           * WARNING: This function is used internally and should not
456           *          be called or overloaded unless you know what you
457           *          are doing.
458           *
459           * @param focusHandler The focus handler to use.
460           * @see getFocusHandler
461           */
462         virtual void setFocusHandler(FocusHandler *const focusHandler);
463 
464         /**
465           * Gets the focus handler used.
466           *
467           * WARNING: This function is used internally and should not
468           *          be called or overloaded unless you know what you
469           *          are doing.
470           *
471           * @return The focus handler used.
472           * @see setFocusHandler
473           */
getFocusHandler()474         FocusHandler* getFocusHandler() noexcept2 A_WARN_UNUSED
475         { return mFocusHandler; }
476 
477         /**
478           * Adds an action listener to the widget. When an action event
479           * is fired by the widget the action listeners of the widget
480           * will get notified.
481           *
482           * @param actionListener The action listener to add.
483           * @see removeActionListener
484           */
485         void addActionListener(ActionListener *const actionListener);
486 
487         /**
488           * Removes an added action listener from the widget.
489           *
490           * @param actionListener The action listener to remove.
491           * @see addActionListener
492           */
493         void removeActionListener(ActionListener *const actionListener);
494 
495         /**
496           * Adds a death listener to the widget. When a death event is
497           * fired by the widget the death listeners of the widget will
498           * get notified.
499           *
500           * @param deathListener The death listener to add.
501           * @see removeDeathListener
502           */
503         void addDeathListener(WidgetDeathListener *const deathListener);
504 
505         /**
506           * Removes an added death listener from the widget.
507           *
508           * @param deathListener The death listener to remove.
509           * @see addDeathListener
510           */
511         void removeDeathListener(WidgetDeathListener *const deathListener);
512 
513         /**
514           * Adds a mouse listener to the widget. When a mouse event is
515           * fired by the widget the mouse listeners of the widget will
516           * get notified.
517           *
518           * @param mouseListener The mouse listener to add.
519           * @see removeMouseListener
520           */
521         void addMouseListener(MouseListener *const mouseListener);
522 
523         /**
524           * Removes an added mouse listener from the widget.
525           *
526           * @param mouseListener The mouse listener to remove.
527           * @see addMouseListener
528           */
529         void removeMouseListener(MouseListener *const mouseListener);
530 
531         /**
532           * Adds a key listener to the widget. When a key event is
533           * fired by the widget the key listeners of the widget will
534           * get notified.
535           *
536           * @param keyListener The key listener to add.
537           * @see removeKeyListener
538           */
539         void addKeyListener(KeyListener *const keyListener);
540 
541         /**
542           * Removes an added key listener from the widget.
543           *
544           * @param keyListener The key listener to remove.
545           * @see addKeyListener
546           */
547         void removeKeyListener(KeyListener *const keyListener);
548 
549         /**
550           * Adds a focus listener to the widget. When a focus event is
551           * fired by the widget the key listeners of the widget will
552           * get notified.
553           *
554           * @param focusListener The focus listener to add.
555           * @see removeFocusListener
556           */
557         void addFocusListener(FocusListener *const focusListener);
558 
559         /**
560           * Removes an added focus listener from the widget.
561           *
562           * @param focusListener The focus listener to remove.
563           * @see addFocusListener
564           */
565         void removeFocusListener(FocusListener *const focusListener);
566 
567         /**
568           * Adds a widget listener to the widget. When a widget event is
569           * fired by the widget the key listeners of the widget will
570           * get notified.
571           *
572           * @param widgetListener The widget listener to add.
573           * @see removeWidgetListener
574           */
575         void addWidgetListener(WidgetListener *const widgetListener);
576 
577         /**
578           * Removes an added widget listener from the widget.
579           *
580           * @param widgetListener The widget listener to remove.
581           * @see addWidgetListener
582           */
583         void removeWidgetListener(WidgetListener *const widgetListener);
584 
585         /**
586           * Sets the action event identifier of the widget. The identifier is
587           * used to be able to identify which action has occured.
588           *
589           * NOTE: An action event identifier should not be used to identify a
590           *       certain widget but rather a certain event in your application.
591           *       Several widgets can have the same action event identifer.
592           *
593           * @param actionEventId The action event identifier.
594           * @see getActionEventId
595           */
setActionEventId(const std::string & actionEventId)596         void setActionEventId(const std::string &actionEventId) noexcept2
597         { mActionEventId = actionEventId; }
598 
599         /**
600           * Gets the action event identifier of the widget.
601           *
602           * @return The action event identifier of the widget.
603           * @see setActionEventId
604           */
getActionEventId()605         const std::string &getActionEventId() const noexcept2
606         { return mActionEventId; }
607 
608         /**
609           * Gets the absolute position on the screen for the widget.
610           *
611           * @param x The absolute x coordinate will be stored in this parameter.
612           * @param y The absolute y coordinate will be stored in this parameter.
613           */
614         virtual void getAbsolutePosition(int& x, int& y) const;
615 
616         /**
617           * Sets the parent of the widget. A parent must be a BasicContainer.
618           *
619           * WARNING: This function is used internally and should not
620           *          be called or overloaded unless you know what you
621           *          are doing.
622           *
623           * @param parent The parent of the widget.
624           * @see getParent
625           */
setParent(Widget * parent)626         virtual void setParent(Widget* parent)
627         { mParent = parent; }
628 
629         /**
630           * Gets the font set for the widget. If no font has been set,
631           * the global font will be returned. If no global font has been set,
632           * the default font will be returend.
633           *
634           * @return The font set for the widget.
635           * @see setFont, setGlobalFont
636           */
637         Font *getFont() const RETURNS_NONNULL A_WARN_UNUSED;
638 
639         /**
640           * Sets the global font to be used by default for all widgets.
641           *
642           * @param font The global font.
643           * @see getGlobalFont
644           */
645         static void setGlobalFont(Font *const font);
646 
getGloablFont()647         static Font *getGloablFont()
648         { return mGlobalFont; }
649 
cleanGlobalFont()650         static void cleanGlobalFont()
651         { mGlobalFont = nullptr; }
652 
653         /**
654           * Sets the font for the widget. If NULL is passed, the global font
655           * will be used.
656           *
657           * @param font The font to set for the widget.
658           * @see getFont
659           */
660         void setFont(Font *const font);
661 
662         /**
663           * Called when the font has changed. If the change is global,
664           * this function will only be called if the widget doesn't have a
665           * font already set.
666           */
fontChanged()667         virtual void fontChanged()
668         { }
669 
670         /**
671           * Checks if a widget exists or not, that is if it still exists
672           * an instance of the object.
673           *
674           * @param widget The widget to check.
675           * @return True if an instance of the widget exists, false otherwise.
676           */
677         static bool widgetExists(const Widget *const widget) A_WARN_UNUSED;
678 
679         /**
680           * Checks if tab in is enabled. Tab in means that you can set focus
681           * to this widget by pressing the tab button. If tab in is disabled
682           * then the focus handler will skip this widget and focus the next
683           * in its focus order.
684           *
685           * @return True if tab in is enabled, false otherwise.
686           * @see setTabInEnabled
687           */
isTabInEnabled()688         bool isTabInEnabled() const noexcept2 A_WARN_UNUSED
689         { return mTabIn; }
690 
691         /**
692           * Sets tab in enabled, or not. Tab in means that you can set focus
693           * to this widget by pressing the tab button. If tab in is disabled
694           * then the FocusHandler will skip this widget and focus the next
695           * in its focus order.
696           *
697           * @param enabled True if tab in should be enabled, false otherwise.
698           * @see isTabInEnabled
699           */
setTabInEnabled(const bool enabled)700         void setTabInEnabled(const bool enabled) noexcept2
701         { mTabIn = enabled; }
702 
703         /**
704           * Checks if tab out is enabled. Tab out means that you can lose
705           * focus to this widget by pressing the tab button. If tab out is
706           * disabled then the FocusHandler ignores tabbing and focus will
707           * stay with this widget.
708           *
709           * @return True if tab out is enabled, false otherwise.
710           * @see setTabOutEnabled
711           */
isTabOutEnabled()712         bool isTabOutEnabled() const noexcept2 A_WARN_UNUSED
713         { return mTabOut; }
714 
715         /**
716           * Sets tab out enabled. Tab out means that you can lose
717           * focus to this widget by pressing the tab button. If tab out is
718           * disabled then the FocusHandler ignores tabbing and focus will
719           * stay with this widget.
720           *
721           * @param enabled True if tab out should be enabled, false otherwise.
722           * @see isTabOutEnabled
723           */
setTabOutEnabled(const bool enabled)724         void setTabOutEnabled(const bool enabled) noexcept2
725         { mTabOut = enabled; }
726 
727         /**
728           * Requests modal focus. When a widget has modal focus, only that
729           * widget and it's children may recieve input.
730           *
731           * @throws Exception if another widget already has modal focus.
732           * @see releaseModalFocus, isModalFocused
733           */
734         void requestModalFocus();
735 
736         /**
737           * Requests modal mouse input focus. When a widget has modal input focus
738           * that widget will be the only widget receiving input even if the input
739           * occurs outside of the widget and no matter what the input is.
740           *
741           * @throws Exception if another widget already has modal focus.
742           * @see releaseModalMouseInputFocus, isModalMouseInputFocused
743           */
744         virtual void requestModalMouseInputFocus();
745 
746         /**
747           * Releases modal focus. Modal focus will only be released if the
748           * widget has modal focus.
749           *
750           * @see requestModalFocus, isModalFocused
751           */
752         virtual void releaseModalFocus();
753 
754         /**
755           * Releases modal mouse input focus. Modal mouse input focus will only
756           * be released if the widget has modal mouse input focus.
757           *
758           * @see requestModalMouseInputFocus, isModalMouseInputFocused
759           */
760         virtual void releaseModalMouseInputFocus();
761 
762         /**
763           * Checks if the widget or it's parent has modal focus.
764           *
765           * @return True if the widget has modal focus, false otherwise.
766           * @see requestModalFocus, releaseModalFocus
767           */
768         virtual bool isModalFocused() const A_WARN_UNUSED;
769 
770         /**
771           * Checks if the widget or it's parent has modal mouse input focus.
772           *
773           * @return True if the widget has modal mouse input focus, false
774           *         otherwise.
775           * @see requestModalMouseInputFocus, releaseModalMouseInputFocus
776           */
777         virtual bool isModalMouseInputFocused() const A_WARN_UNUSED;
778 
779         /**
780           * Gets a widget from a certain position in the widget.
781           * This function is used to decide which gets mouse input,
782           * thus it can be overloaded to change that behaviour.
783           *
784           * NOTE: This always returns NULL if the widget is not
785           *       a container.
786           *
787           * @param x The x coordinate of the widget to get.
788           * @param y The y coordinate of the widget to get.
789           * @return The widget at the specified coodinate, NULL
790           *         if no widget is found.
791           */
getWidgetAt(int x A_UNUSED,int y A_UNUSED)792         virtual Widget *getWidgetAt(int x A_UNUSED,
793                                     int y A_UNUSED) A_WARN_UNUSED
794         { return nullptr; }
795 
796         /**
797           * Gets the mouse listeners of the widget.
798           *
799           * @return The mouse listeners of the widget.
800           */
801         const std::list<MouseListener*>& getMouseListeners() const
802                                          A_CONST A_WARN_UNUSED;
803 
804         /**
805           * Gets the key listeners of the widget.
806           *
807           * @return The key listeners of the widget.
808           */
809         const std::list<KeyListener*>& getKeyListeners() const
810                                        A_CONST A_WARN_UNUSED;
811 
812         /**
813           * Gets the focus listeners of the widget.
814           *
815           * @return The focus listeners of the widget.
816           */
817         const std::list<FocusListener*>& getFocusListeners() const
818                                          A_CONST A_WARN_UNUSED;
819 
820         /**
821           * Gets the area of the widget occupied by the widget's children.
822           * By default this method returns an empty rectangle as not all
823           * widgets are containers. If you want to make a container this
824           * method should return the area where the children resides. This
825           * method is used when drawing children of a widget when computing
826           * clip rectangles for the children.
827           *
828           * An example of a widget that overloads this method is ScrollArea.
829           * A ScrollArea has a view of its contant and that view is the
830           * children area. The size of a ScrollArea's children area might
831           * vary depending on if the scroll bars of the ScrollArea is shown
832           * or not.
833           *
834           * @return The area of the widget occupied by the widget's children.
835           * @see BasicContainer
836           * @see BasicContainer::getChildrenArea
837           * @see BasicContainer::drawChildren
838           */
839         virtual Rect getChildrenArea() A_WARN_UNUSED;
840 
841         /**
842           * Gets the internal focus handler used.
843           *
844           * @return the internalFocusHandler used. If no internal focus handler
845           *         is used, NULL will be returned.
846           * @see setInternalFocusHandler
847           */
848         virtual FocusHandler* getInternalFocusHandler() A_WARN_UNUSED;
849 
850         /**
851           * Sets the internal focus handler. An internal focus handler is
852           * needed if both a widget in the widget and the widget itself
853           * should be foucsed at the same time.
854           *
855           * @param focusHandler The internal focus handler to be used.
856           * @see getInternalFocusHandler
857           */
858         void setInternalFocusHandler(FocusHandler *const internalFocusHandler);
859 
860         /**
861           * Moves a widget to the top of this widget. The moved widget will be
862           * drawn above all other widgets in this widget.
863           *
864           * @param widget The widget to move to the top.
865           * @see moveToBottom
866           */
moveToTop(Widget * widget A_UNUSED)867         virtual void moveToTop(Widget* widget A_UNUSED)
868         { }
869 
870         /**
871           * Moves a widget in this widget to the bottom of this widget.
872           * The moved widget will be drawn below all other widgets in this widget.
873           *
874           * @param widget The widget to move to the bottom.
875           * @see moveToTop
876           */
moveToBottom(Widget * widget A_UNUSED)877         virtual void moveToBottom(Widget* widget A_UNUSED)
878         { }
879 
880         /**
881           * Focuses the next widget in the widget.
882           *
883           * @see moveToBottom
884           */
focusNext()885         virtual void focusNext()
886         { }
887 
888         /**
889           * Focuses the previous widget in the widget.
890           *
891           * @see moveToBottom
892           */
focusPrevious()893         virtual void focusPrevious()
894         { }
895 
896         /**
897           * Tries to show a specific part of a widget by moving it. Used if the
898           * widget should act as a container.
899           *
900           * @param widget The target widget.
901           * @param area The area to show.
902           */
showWidgetPart(Widget * const widget A_UNUSED,const Rect & area A_UNUSED)903         virtual void showWidgetPart(Widget *const widget A_UNUSED,
904                                     const Rect &area A_UNUSED)
905         { }
906 
907         /**
908           * Sets an id of a widget. An id can be useful if a widget needs to be
909           * identified in a container. For example, if widgets are created by an
910           * XML document, a certain widget can be retrieved given that the widget
911           * has an id.
912           *
913           * @param id The id to set to the widget.
914           * @see getId
915           */
setId(const std::string & id)916         void setId(const std::string& id)
917         { mId = id; }
918 
getId()919         const std::string& getId() const noexcept2 A_WARN_UNUSED
920         { return mId; }
921 
922         /**
923           * Shows a certain part of a widget in the widget's parent.
924           * Used when widgets want a specific part to be visible in
925           * its parent. An example is a TextArea that wants a specific
926           * part of its text to be visible when a TextArea is a child
927           * of a ScrollArea.
928           *
929           * @param rectangle The rectangle to be shown.
930           */
931         virtual void showPart(const Rect &rectangle);
932 
isAllowLogic()933         bool isAllowLogic() const noexcept2 A_WARN_UNUSED
934         { return mAllowLogic; }
935 
setMouseConsume(const bool b)936         void setMouseConsume(const bool b) noexcept2
937         { mMouseConsume = b; }
938 
isMouseConsume()939         bool isMouseConsume() const noexcept2 A_WARN_UNUSED
940         { return mMouseConsume; }
941 
setRedraw(const bool b)942         void setRedraw(const bool b) noexcept2
943         { mRedraw = b; }
944 
isSelectable()945         virtual bool isSelectable() const noexcept2 A_WARN_UNUSED
946         { return mSelectable; }
947 
setSelectable(const bool selectable)948         void setSelectable(const bool selectable) noexcept2
949         { mSelectable = selectable; }
950 
951         static void distributeWindowResizeEvent();
952 
953         void windowResized();
954 
955         static Widget *callPostInit(Widget *const widget) RETURNS_NONNULL;
956 
postInit()957         virtual void postInit()
958         { }
959 
960         /**
961           * True if the widget visible, false otherwise.
962           */
963         Visible mVisible;
964 
965     protected:
966         /**
967           * Distributes an action event to all action listeners
968           * of the widget.
969           */
970         void distributeActionEvent();
971 
972         /**
973           * Distributes resized events to all of the widget's listeners.
974           */
975         void distributeResizedEvent();
976 
977         /**
978           * Distributes moved events to all of the widget's listeners.
979           */
980         void distributeMovedEvent();
981 
982         /**
983           * Distributes hidden events to all of the widget's listeners.
984           *
985           * @author Olof Naessén
986           */
987         void distributeHiddenEvent();
988 
989         /**
990           * Distributes shown events to all of the widget's listeners.
991           *
992           * @author Olof Naessén
993           */
994         void distributeShownEvent();
995 
996         /**
997           * Typdef.
998           */
999         typedef std::list<MouseListener*> MouseListenerList;
1000 
1001         /**
1002           * Typdef.
1003           */
1004         typedef MouseListenerList::iterator MouseListenerIterator;
1005 
1006         /**
1007           * Holds the mouse listeners of the widget.
1008           */
1009         MouseListenerList mMouseListeners;
1010 
1011         /**
1012           * Typdef.
1013           */
1014         typedef std::list<KeyListener*> KeyListenerList;
1015 
1016         /**
1017           * Holds the key listeners of the widget.
1018           */
1019         KeyListenerList mKeyListeners;
1020 
1021         /**
1022           * Typdef.
1023           */
1024         typedef KeyListenerList::iterator KeyListenerIterator;
1025 
1026         /**
1027           * Typdef.
1028           */
1029         typedef std::list<ActionListener*> ActionListenerList;
1030 
1031         /**
1032           * Holds the action listeners of the widget.
1033           */
1034         ActionListenerList mActionListeners;
1035 
1036         /**
1037           * Typdef.
1038           */
1039         typedef ActionListenerList::iterator ActionListenerIterator;
1040 
1041         /**
1042           * Typdef.
1043           */
1044         typedef std::list<WidgetDeathListener*> WidgetDeathListenerList;
1045 
1046         /**
1047           * Holds the death listeners of the widget.
1048           */
1049         WidgetDeathListenerList mDeathListeners;
1050 
1051         /**
1052           * Typdef.
1053           */
1054         typedef WidgetDeathListenerList::iterator WidgetDeathListenerIterator;
1055 
1056         /**
1057           * Typdef.
1058           */
1059         typedef std::list<FocusListener*> FocusListenerList;
1060 
1061         /**
1062           * Holds the focus listeners of the widget.
1063           */
1064         FocusListenerList mFocusListeners;
1065 
1066         /**
1067           * Typdef.
1068           */
1069         typedef FocusListenerList::iterator FocusListenerIterator;
1070 
1071         typedef std::list<WidgetListener*> WidgetListenerList;
1072 
1073         /**
1074           * Holds the widget listeners of the widget.
1075           */
1076         WidgetListenerList mWidgetListeners;
1077 
1078         /**
1079           * Typdef.
1080           */
1081         typedef WidgetListenerList::iterator WidgetListenerIterator;
1082 
1083         /**
1084           * Holds the foreground color of the widget.
1085           */
1086         Color mForegroundColor;
1087 
1088         /**
1089           * Holds the background color of the widget.
1090           */
1091         Color mBackgroundColor;
1092 
1093         /**
1094           * Holds the base color of the widget.
1095           */
1096         Color mBaseColor;
1097 
1098         /**
1099           * Holds the dimension of the widget.
1100           */
1101         Rect mDimension;
1102 
1103         /**
1104           * Holds the action event of the widget.
1105           */
1106         std::string mActionEventId;
1107 
1108         /**
1109           * Holds the id of the widget.
1110           */
1111         std::string mId;
1112 
1113         /**
1114           * Holds the focus handler used by the widget.
1115           */
1116         FocusHandler* mFocusHandler;
1117 
1118         /**
1119           * Holds the focus handler used by the widget. NULL
1120           * if no internal focus handler is used.
1121           */
1122         FocusHandler* mInternalFocusHandler;
1123 
1124         /**
1125           * Holds the parent of the widget. NULL if the widget
1126           * has no parent.
1127           */
1128         Widget* mParent;
1129 
1130         /**
1131           * Holds the font used by the widget.
1132           */
1133         Font* mCurrentFont;
1134 
1135         /**
1136           * Holds the frame size of the widget.
1137           */
1138         unsigned int mFrameSize;
1139 
1140         /**
1141           * True if the widget focusable, false otherwise.
1142           */
1143         bool mFocusable;
1144 
1145         /**
1146           * True if the widget has tab in enabled, false otherwise.
1147           */
1148         bool mTabIn;
1149 
1150         /**
1151           * True if the widget has tab in enabled, false otherwise.
1152           */
1153         bool mTabOut;
1154 
1155         /**
1156           * True if the widget is enabled, false otherwise.
1157           */
1158         bool mEnabled;
1159 
1160         bool mAllowLogic;
1161 
1162         bool mMouseConsume;
1163 
1164         bool mRedraw;
1165 
1166         bool mSelectable;
1167 
1168         /**
1169           * Holds the global font used by the widget.
1170           */
1171         static Font* mGlobalFont;
1172 
1173     private:
1174         /**
1175           * Holds a list of all instances of widgets.
1176           */
1177         static std::list<Widget*> mAllWidgets;
1178 
1179         static std::set<Widget*> mAllWidgetsSet;
1180 };
1181 
1182 #endif  // GUI_WIDGETS_WIDGET_H
1183