1 /***************************************************************************
2  *   Copyright (C) 2017-2019 by the fifechan team                               *
3  *   https://github.com/fifengine/fifechan                                 *
4  *   This file is part of fifechan.                                        *
5  *                                                                         *
6  *   fifechan is free software; you can redistribute it and/or             *
7  *   modify it under the terms of the GNU Lesser General Public            *
8  *   License as published by the Free Software Foundation; either          *
9  *   version 2.1 of the License, or (at your option) any later version.    *
10  *                                                                         *
11  *   This library is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
14  *   Lesser General Public License for more details.                       *
15  *                                                                         *
16  *   You should have received a copy of the GNU Lesser General Public      *
17  *   License along with this library; if not, write to the                 *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
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 /*
66  * For comments regarding functions please see the header file.
67  */
68 
69 #include "fifechan/widget.hpp"
70 
71 #include "fifechan/actionevent.hpp"
72 #include "fifechan/actionlistener.hpp"
73 #include "fifechan/deathlistener.hpp"
74 #include "fifechan/defaultfont.hpp"
75 #include "fifechan/event.hpp"
76 #include "fifechan/exception.hpp"
77 #include "fifechan/focushandler.hpp"
78 #include "fifechan/graphics.hpp"
79 #include "fifechan/keyinput.hpp"
80 #include "fifechan/keylistener.hpp"
81 #include "fifechan/mouseinput.hpp"
82 #include "fifechan/mouselistener.hpp"
83 #include "fifechan/visibilityeventhandler.hpp"
84 #include "fifechan/widgetlistener.hpp"
85 
86 #include <algorithm>
87 
88 namespace fcn
89 {
90     Font* Widget::mGlobalFont = NULL;
91     DefaultFont Widget::mDefaultFont;
92     std::list<Widget*> Widget::mWidgetInstances;
93     VisibilityEventHandler* Widget::mVisibilityEventHandler = NULL;
94     DeathListener* Widget::mGuiDeathListener = NULL;
95 
Widget()96     Widget::Widget()
97             : mForegroundColor(0x000000),
98               mBackgroundColor(0xffffff),
99               mBaseColor(0x808090),
100               mSelectionColor(0xc3d9ff),
101               mOutlineColor(0x808090),
102               mBorderColor(0x808090),
103               mFocusHandler(NULL),
104               mInternalFocusHandler(NULL),
105               mParent(NULL),
106               mOutlineSize(0),
107               mBorderSize(0),
108               mSelectionMode(Selection_None),
109               mMarginTop(0),
110               mMarginRight(0),
111               mMarginBottom(0),
112               mMarginLeft(0),
113               mPaddingTop(0),
114               mPaddingRight(0),
115               mPaddingBottom(0),
116               mPaddingLeft(0),
117               mFocusable(false),
118               mVisible(true),
119               mTabIn(true),
120               mTabOut(true),
121               mEnabled(true),
122               mCurrentFont(NULL),
123               mMinSize(0, 0),
124               mMaxSize(50000, 50000),
125               mFixedSize(-1, -1),
126               mIsFixedSize(false),
127               mVExpand(false),
128               mHExpand(false),
129               mLastX(0),
130               mLastY(0)
131     {
132         mWidgetInstances.push_back(this);
133     }
134 
~Widget()135     Widget::~Widget()
136     {
137         if (mParent != NULL)
138             mParent->remove(this);
139 
140         std::list<Widget*>::const_iterator childrenIter;
141         for (childrenIter = mChildren.begin(); childrenIter != mChildren.end(); childrenIter++)
142             (*childrenIter)->_setParent(NULL);
143 
144         std::list<DeathListener*>::const_iterator deathIter;
145         for (deathIter = mDeathListeners.begin(); deathIter != mDeathListeners.end(); ++deathIter)
146         {
147             Event event(this);
148             (*deathIter)->death(event);
149         }
150 
151         if (mGuiDeathListener) {
152             Event event(this);
153             mGuiDeathListener->death(event);
154         }
155 
156         _setFocusHandler(NULL);
157 
158         mWidgetInstances.remove(this);
159     }
160 
drawOutline(Graphics * graphics)161     void Widget::drawOutline(Graphics* graphics)
162     {
163         Color outlineColor = getOutlineColor();
164         Color highlightColor, shadowColor;
165         int alpha = getBaseColor().a;
166         int width = getWidth() + getOutlineSize() * 2 - 1;
167         int height = getHeight() + getOutlineSize() * 2 - 1;
168         highlightColor = outlineColor + 0x303030;
169         highlightColor.a = alpha;
170         shadowColor = outlineColor - 0x303030;
171         shadowColor.a = alpha;
172 
173         unsigned int i;
174         for (i = 0; i < getOutlineSize(); ++i)
175         {
176             graphics->setColor(shadowColor);
177             graphics->drawLine(i,i, width - i, i);
178             graphics->drawLine(i,i + 1, i, height - i - 1);
179             graphics->setColor(highlightColor);
180             graphics->drawLine(width - i,i + 1, width - i, height - i);
181             graphics->drawLine(i,height - i, width - i - 1, height - i);
182         }
183     }
184 
drawBorder(Graphics * graphics)185     void Widget::drawBorder(Graphics* graphics)
186     {
187         Color borderColor = getBorderColor();
188         Color highlightColor, shadowColor;
189         int alpha = getBaseColor().a;
190         int width = getWidth() - 1;
191         int height = getHeight() - 1;
192 
193         highlightColor = borderColor + 0x303030;
194         highlightColor.a = alpha;
195         shadowColor = borderColor - 0x303030;
196         shadowColor.a = alpha;
197 
198         unsigned int i;
199         for (i = 0; i < getBorderSize(); ++i)
200         {
201             graphics->setColor(shadowColor);
202             graphics->drawLine(i, i, width-i, i);
203             graphics->drawLine(i, i+1, i, height-i-1);
204             graphics->setColor(highlightColor);
205             graphics->drawLine(width-i, i+1, width-i, height-i);
206             graphics->drawLine(i, height-i, width-i-1, height-i);
207         }
208     }
209 
drawSelectionFrame(Graphics * graphics)210     void Widget::drawSelectionFrame(Graphics* graphics)
211     {
212         int width = getWidth() - 1;
213         int height = getHeight() - 1;
214         graphics->setColor(getSelectionColor());
215 
216         unsigned int i;
217         // currently border size is used here too, not sure an extra frame size is really needed.
218         for (i = 0; i < getBorderSize(); ++i)
219         {
220             // would be better but causes problems with OpenGL
221             //graphics->drawRectangle(i, i, width - 2 * i, height - 2 * i);
222             graphics->drawLine(i, i, width-i, i);
223             graphics->drawLine(i, i+1, i, height-i-1);
224             graphics->drawLine(width-i, i+1, width-i, height-i);
225             graphics->drawLine(i, height-i, width-i-1, height-i);
226         }
227     }
228 
_setParent(Widget * parent)229     void Widget::_setParent(Widget* parent)
230     {
231         mParent = parent;
232     }
233 
getParent() const234     Widget* Widget::getParent() const
235     {
236         return mParent;
237     }
238 
setWidth(int width)239     void Widget::setWidth(int width)
240     {
241         Rectangle newDimension = mDimension;
242         newDimension.width = width;
243 
244         setDimension(newDimension);
245     }
246 
getWidth() const247     int Widget::getWidth() const
248     {
249         return mDimension.width;
250     }
251 
setHeight(int height)252     void Widget::setHeight(int height)
253     {
254         Rectangle newDimension = mDimension;
255         newDimension.height = height;
256 
257         setDimension(newDimension);
258     }
259 
getHeight() const260     int Widget::getHeight() const
261     {
262         return mDimension.height;
263     }
264 
setX(int x)265     void Widget::setX(int x)
266     {
267         Rectangle newDimension = mDimension;
268         newDimension.x = x;
269 
270         setDimension(newDimension);
271     }
272 
getX() const273     int Widget::getX() const
274     {
275         return mDimension.x;
276     }
277 
setY(int y)278     void Widget::setY(int y)
279     {
280         Rectangle newDimension = mDimension;
281         newDimension.y = y;
282 
283         setDimension(newDimension);
284     }
285 
getY() const286     int Widget::getY() const
287     {
288         return mDimension.y;
289     }
290 
setPosition(int x,int y)291     void Widget::setPosition(int x, int y)
292     {
293         Rectangle newDimension = mDimension;
294         newDimension.x = x;
295         newDimension.y = y;
296 
297         setDimension(newDimension);
298     }
299 
setDimension(const Rectangle & dimension)300     void Widget::setDimension(const Rectangle& dimension)
301     {
302         Rectangle oldDimension = mDimension;
303         mDimension = dimension;
304 
305         if (mDimension.width != oldDimension.width
306             || mDimension.height != oldDimension.height)
307         {
308             calculateSize();
309             if (mDimension.width != oldDimension.width
310                 || mDimension.height != oldDimension.height)
311             {
312                 distributeResizedEvent();
313             }
314         }
315 
316         if (mDimension.x != oldDimension.x
317             || mDimension.y != oldDimension.y)
318         {
319             distributeMovedEvent();
320 
321             std::list<Widget*>::iterator currChild(mChildren.begin());
322             std::list<Widget*>::iterator endChildren(mChildren.end());
323 
324             for(; currChild != endChildren; ++currChild)
325             {
326                 (*currChild)->distributeAncestorMovedEvent(this);
327             }
328         }
329     }
330 
getChildrenCount() const331     unsigned int Widget::getChildrenCount() const
332     {
333         unsigned int childs = 0;
334         std::list<Widget*>::const_iterator currChild(mChildren.begin());
335         std::list<Widget*>::const_iterator endChildren(mChildren.end());
336         for(; currChild != endChildren; ++currChild) {
337             ++childs;
338         }
339         return childs;
340     }
341 
getVisibleChildrenCount() const342     unsigned int Widget::getVisibleChildrenCount() const
343     {
344         unsigned int childs = 0;
345         std::list<Widget*>::const_iterator currChild(mChildren.begin());
346         std::list<Widget*>::const_iterator endChildren(mChildren.end());
347         for(; currChild != endChildren; ++currChild) {
348             if (isVisible()) {
349                 ++childs;
350             }
351         }
352         return childs;
353     }
354 
setMinSize(const Size & size)355     void Widget::setMinSize(const Size& size)
356     {
357         mMinSize = size;
358         calculateSize();
359     }
360 
getMinSize() const361     const Size& Widget::getMinSize() const
362     {
363         return mMinSize;
364     }
365 
setMaxSize(const Size & size)366     void Widget::setMaxSize(const Size& size)
367     {
368         mMaxSize = size;
369         calculateSize();
370     }
371 
getMaxSize() const372     const Size& Widget::getMaxSize() const
373     {
374         return mMaxSize;
375     }
376 
setFixedSize(const Size & size)377     void Widget::setFixedSize(const Size& size)
378     {
379         mFixedSize = size;
380         if (mFixedSize.getWidth() < 0 || mFixedSize.getHeight() < 0) {
381             mIsFixedSize = false;
382         } else {
383             mIsFixedSize = true;
384             calculateSize();
385         }
386     }
387 
getFixedSize() const388     const Size& Widget::getFixedSize() const
389     {
390         return mFixedSize;
391     }
392 
isFixedSize() const393     bool Widget::isFixedSize() const
394     {
395         return mIsFixedSize;
396     }
397 
calculateSize()398     void Widget::calculateSize()
399     {
400         if (isFixedSize()) {
401             mDimension.width = mFixedSize.getWidth();
402             mDimension.height = mFixedSize.getHeight();
403             return;
404         }
405         int minWidth = mMinSize.getWidth();
406         int minHeight = mMinSize.getHeight();
407         int maxWidth = mMaxSize.getWidth();
408         int maxHeight = mMaxSize.getHeight();
409         int currWidth = mDimension.width;
410         int currHeight = mDimension.height;
411 
412         mDimension.width = std::max(std::min(currWidth, maxWidth), minWidth);
413         mDimension.height = std::max(std::min(currHeight, maxHeight), minHeight);
414     }
415 
setVerticalExpand(bool expand)416     void Widget::setVerticalExpand(bool expand)
417     {
418         mVExpand = expand;
419     }
420 
isVerticalExpand() const421     bool Widget::isVerticalExpand() const
422     {
423         return mVExpand;
424     }
425 
setHorizontalExpand(bool expand)426     void Widget::setHorizontalExpand(bool expand)
427     {
428         mHExpand = expand;
429     }
430 
isHorizontalExpand() const431     bool Widget::isHorizontalExpand() const
432     {
433         return mHExpand;
434     }
435 
adaptLayout(bool top)436     void Widget::adaptLayout(bool top)
437     {
438         Widget* widget = this;
439         while (widget->getParent() && top) {
440             Widget* parent = widget->getParent();
441             if (!parent->isLayouted()) {
442                 break;
443             }
444             widget = parent;
445         }
446         widget->resizeToContent();
447         widget->expandContent();
448     }
449 
setOutlineSize(unsigned int size)450     void Widget::setOutlineSize(unsigned int size)
451     {
452         mOutlineSize = size;
453     }
454 
getOutlineSize() const455     unsigned int Widget::getOutlineSize() const
456     {
457         return mOutlineSize;
458     }
459 
setBorderSize(unsigned int size)460     void Widget::setBorderSize(unsigned int size)
461     {
462         mBorderSize = size;
463     }
464 
getBorderSize() const465     unsigned int Widget::getBorderSize() const
466     {
467         return mBorderSize;
468     }
469 
setMargin(int margin)470     void Widget::setMargin(int margin)
471     {
472         mMarginTop = margin;
473         mMarginRight = margin;
474         mMarginBottom = margin;
475         mMarginLeft = margin;
476     }
477 
setMarginTop(int margin)478     void Widget::setMarginTop(int margin)
479     {
480         mMarginTop = margin;
481     }
482 
getMarginTop() const483     int Widget::getMarginTop() const
484     {
485         return mMarginTop;
486     }
487 
setMarginRight(int margin)488     void Widget::setMarginRight(int margin)
489     {
490         mMarginRight = margin;
491     }
492 
getMarginRight() const493     int Widget::getMarginRight() const
494     {
495         return mMarginRight;
496     }
497 
setMarginBottom(int margin)498     void Widget::setMarginBottom(int margin)
499     {
500         mMarginBottom = margin;
501     }
502 
getMarginBottom() const503     int Widget::getMarginBottom() const
504     {
505         return mMarginBottom;
506     }
507 
setMarginLeft(int margin)508     void Widget::setMarginLeft(int margin)
509     {
510         mMarginLeft = margin;
511     }
512 
getMarginLeft() const513     int Widget::getMarginLeft() const
514     {
515         return mMarginLeft;
516     }
517 
setPadding(unsigned int padding)518     void Widget::setPadding(unsigned int padding)
519     {
520         mPaddingTop = padding;
521         mPaddingRight = padding;
522         mPaddingBottom = padding;
523         mPaddingLeft = padding;
524     }
525 
setPaddingTop(unsigned int padding)526     void Widget::setPaddingTop(unsigned int padding)
527     {
528         mPaddingTop = padding;
529     }
530 
getPaddingTop() const531     unsigned int Widget::getPaddingTop() const
532     {
533         return mPaddingTop;
534     }
535 
setPaddingRight(unsigned int padding)536     void Widget::setPaddingRight(unsigned int padding)
537     {
538         mPaddingRight = padding;
539     }
540 
getPaddingRight() const541     unsigned int Widget::getPaddingRight() const
542     {
543         return mPaddingRight;
544     }
545 
setPaddingBottom(unsigned int padding)546     void Widget::setPaddingBottom(unsigned int padding)
547     {
548         mPaddingBottom = padding;
549     }
550 
getPaddingBottom() const551     unsigned int Widget::getPaddingBottom() const
552     {
553         return mPaddingBottom;
554     }
555 
setPaddingLeft(unsigned int padding)556     void Widget::setPaddingLeft(unsigned int padding)
557     {
558         mPaddingLeft = padding;
559     }
560 
getPaddingLeft() const561     unsigned int Widget::getPaddingLeft() const
562     {
563         return mPaddingLeft;
564     }
565 
getDimension() const566     const Rectangle& Widget::getDimension() const
567     {
568         return mDimension;
569     }
570 
getActionEventId() const571     const std::string& Widget::getActionEventId() const
572     {
573         return mActionEventId;
574     }
575 
setActionEventId(const std::string & actionEventId)576     void Widget::setActionEventId(const std::string& actionEventId)
577     {
578         mActionEventId = actionEventId;
579     }
580 
isFocused() const581     bool Widget::isFocused() const
582     {
583         if (!mFocusHandler)
584         {
585             return false;
586         }
587 
588         return (mFocusHandler->isFocused(this));
589     }
590 
setFocusable(bool focusable)591     void Widget::setFocusable(bool focusable)
592     {
593         if (!focusable && isFocused())
594         {
595             mFocusHandler->focusNone();
596         }
597 
598         mFocusable = focusable;
599     }
600 
isFocusable() const601     bool Widget::isFocusable() const
602     {
603         return mFocusable && isVisible() && isEnabled();
604     }
605 
requestFocus()606     void Widget::requestFocus()
607     {
608         if (mFocusHandler == NULL)
609             throw FCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
610 
611         if (isFocusable())
612             mFocusHandler->requestFocus(this);
613     }
614 
requestMoveToTop()615     void Widget::requestMoveToTop()
616     {
617         if (mParent != NULL)
618             mParent->moveToTop(this);
619     }
620 
requestMoveToBottom()621     void Widget::requestMoveToBottom()
622     {
623         if (mParent != NULL)
624             mParent->moveToBottom(this);
625     }
626 
setVisible(bool visible)627     void Widget::setVisible(bool visible)
628     {
629         VisibilityEventHandler *visibilityEventHandler = _getVisibilityEventHandler();
630 
631         if (!visible && isFocused())
632             mFocusHandler->focusNone();
633 
634         if (visible)
635         {
636             visibilityEventHandler->widgetShown(Event(this));
637             distributeShownEvent();
638 
639             std::list<Widget*>::iterator currChild(mChildren.begin());
640             std::list<Widget*>::iterator endChildren(mChildren.end());
641 
642             for(; currChild != endChildren; ++currChild)
643             {
644                 (*currChild)->distributeAncestorShownEvent(this);
645             }
646         }
647         else if(!visible)
648         {
649             visibilityEventHandler->widgetHidden(Event(this));
650             distributeHiddenEvent();
651 
652             std::list<Widget*>::iterator currChild(mChildren.begin());
653             std::list<Widget*>::iterator endChildren(mChildren.end());
654 
655             for(; currChild != endChildren; ++currChild)
656             {
657                 (*currChild)->distributeAncestorHiddenEvent(this);
658             }
659         }
660 
661         mVisible = visible;
662     }
663 
isVisible() const664     bool Widget::isVisible() const
665     {
666         if (getParent() == NULL)
667             return mVisible;
668         else
669             return mVisible && getParent()->isVisible();
670     }
671 
isSetVisible() const672     bool Widget::isSetVisible() const {
673         return mVisible;
674     }
675 
setBaseColor(const Color & color)676     void Widget::setBaseColor(const Color& color)
677     {
678         mBaseColor = color;
679     }
680 
getBaseColor() const681     const Color& Widget::getBaseColor() const
682     {
683         return mBaseColor;
684     }
685 
setForegroundColor(const Color & color)686     void Widget::setForegroundColor(const Color& color)
687     {
688         mForegroundColor = color;
689     }
690 
getForegroundColor() const691     const Color& Widget::getForegroundColor() const
692     {
693         return mForegroundColor;
694     }
695 
setBackgroundColor(const Color & color)696     void Widget::setBackgroundColor(const Color& color)
697     {
698         mBackgroundColor = color;
699     }
700 
getBackgroundColor() const701     const Color& Widget::getBackgroundColor() const
702     {
703         return mBackgroundColor;
704     }
705 
setSelectionColor(const Color & color)706     void Widget::setSelectionColor(const Color& color)
707     {
708         mSelectionColor = color;
709     }
710 
getSelectionColor() const711     const Color& Widget::getSelectionColor() const
712     {
713         return mSelectionColor;
714     }
715 
setOutlineColor(const Color & color)716     void Widget::setOutlineColor(const Color& color)
717     {
718         mOutlineColor = color;
719     }
720 
getOutlineColor() const721     const Color& Widget::getOutlineColor() const
722     {
723         return mOutlineColor;
724     }
725 
setBorderColor(const Color & color)726     void Widget::setBorderColor(const Color& color)
727     {
728         mBorderColor = color;
729     }
730 
getBorderColor() const731     const Color& Widget::getBorderColor() const
732     {
733         return mBorderColor;
734     }
735 
setSelectionMode(SelectionMode mode)736     void Widget::setSelectionMode(SelectionMode mode)
737     {
738         mSelectionMode = mode;
739     }
740 
getSelectionMode() const741     Widget::SelectionMode Widget::getSelectionMode() const
742     {
743         return mSelectionMode;
744     }
745 
_setFocusHandler(FocusHandler * focusHandler)746     void Widget::_setFocusHandler(FocusHandler* focusHandler)
747     {
748         if (mFocusHandler)
749         {
750             releaseModalFocus();
751             if (mFocusHandler->getModalMouseInputFocused() == this) {
752                 releaseModalMouseInputFocus();
753             }
754             mFocusHandler->remove(this);
755         }
756 
757         if (focusHandler)
758             focusHandler->add(this);
759 
760         mFocusHandler = focusHandler;
761 
762         if (mInternalFocusHandler != NULL)
763             return;
764 
765         std::list<Widget*>::const_iterator iter;
766         for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
767         {
768             if (widgetExists(*iter))
769                 (*iter)->_setFocusHandler(focusHandler);
770         }
771     }
772 
_getFocusHandler()773     FocusHandler* Widget::_getFocusHandler()
774     {
775         return mFocusHandler;
776     }
777 
_setVisibilityEventHandler(VisibilityEventHandler * visibilityEventHandler)778     void Widget::_setVisibilityEventHandler(VisibilityEventHandler* visibilityEventHandler)
779     {
780         mVisibilityEventHandler = visibilityEventHandler;
781     }
782 
_getVisibilityEventHandler()783     VisibilityEventHandler* Widget::_getVisibilityEventHandler()
784     {
785         return mVisibilityEventHandler;
786     }
787 
_setGuiDeathListener(DeathListener * deathListener)788     void Widget::_setGuiDeathListener(DeathListener* deathListener)
789     {
790         mGuiDeathListener = deathListener;
791     }
792 
_getGuiDeathListener()793     DeathListener* Widget::_getGuiDeathListener()
794     {
795         return mGuiDeathListener;
796     }
797 
addActionListener(ActionListener * actionListener)798     void Widget::addActionListener(ActionListener* actionListener)
799     {
800         mActionListeners.push_back(actionListener);
801     }
802 
removeActionListener(ActionListener * actionListener)803     void Widget::removeActionListener(ActionListener* actionListener)
804     {
805         mActionListeners.remove(actionListener);
806     }
807 
addDeathListener(DeathListener * deathListener)808     void Widget::addDeathListener(DeathListener* deathListener)
809     {
810         mDeathListeners.push_back(deathListener);
811     }
812 
removeDeathListener(DeathListener * deathListener)813     void Widget::removeDeathListener(DeathListener* deathListener)
814     {
815         mDeathListeners.remove(deathListener);
816     }
817 
addKeyListener(KeyListener * keyListener)818     void Widget::addKeyListener(KeyListener* keyListener)
819     {
820         mKeyListeners.push_back(keyListener);
821     }
822 
removeKeyListener(KeyListener * keyListener)823     void Widget::removeKeyListener(KeyListener* keyListener)
824     {
825         mKeyListeners.remove(keyListener);
826     }
827 
addFocusListener(FocusListener * focusListener)828     void Widget::addFocusListener(FocusListener* focusListener)
829     {
830         mFocusListeners.push_back(focusListener);
831     }
832 
removeFocusListener(FocusListener * focusListener)833     void Widget::removeFocusListener(FocusListener* focusListener)
834     {
835         mFocusListeners.remove(focusListener);
836     }
837 
addMouseListener(MouseListener * mouseListener)838     void Widget::addMouseListener(MouseListener* mouseListener)
839     {
840         mMouseListeners.push_back(mouseListener);
841     }
842 
removeMouseListener(MouseListener * mouseListener)843     void Widget::removeMouseListener(MouseListener* mouseListener)
844     {
845         mMouseListeners.remove(mouseListener);
846     }
847 
addWidgetListener(WidgetListener * widgetListener)848     void Widget::addWidgetListener(WidgetListener* widgetListener)
849     {
850         mWidgetListeners.push_back(widgetListener);
851     }
852 
removeWidgetListener(WidgetListener * widgetListener)853     void Widget::removeWidgetListener(WidgetListener* widgetListener)
854     {
855         mWidgetListeners.remove(widgetListener);
856     }
857 
getAbsolutePosition(int & x,int & y) const858     void Widget::getAbsolutePosition(int& x, int& y) const
859     {
860         if (getParent() == NULL)
861         {
862             if (isLastPositionSet()) {
863                 x = mLastX;
864                 y = mLastY;
865             } else {
866                 x = mDimension.x;
867                 y = mDimension.y;
868             }
869             return;
870         }
871 
872         int parentX;
873         int parentY;
874 
875         getParent()->getAbsolutePosition(parentX, parentY);
876 
877         x = parentX + mDimension.x + getParent()->getChildrenArea().x;
878         y = parentY + mDimension.y + getParent()->getChildrenArea().y;
879     }
880 
getFont() const881     Font* Widget::getFont() const
882     {
883         if (mCurrentFont == NULL)
884         {
885             if (mGlobalFont == NULL)
886                 return &mDefaultFont;
887 
888             return mGlobalFont;
889         }
890 
891         return mCurrentFont;
892     }
893 
setGlobalFont(Font * font)894     void Widget::setGlobalFont(Font* font)
895     {
896         mGlobalFont = font;
897 
898         std::list<Widget*>::iterator iter;
899         for (iter = mWidgetInstances.begin(); iter != mWidgetInstances.end(); ++iter)
900         {
901             if ((*iter)->mCurrentFont == NULL)
902                 (*iter)->fontChanged();
903         }
904     }
905 
setFont(Font * font)906     void Widget::setFont(Font* font)
907     {
908         mCurrentFont = font;
909         fontChanged();
910     }
911 
widgetExists(const Widget * widget)912     bool Widget::widgetExists(const Widget* widget)
913     {
914         std::list<Widget*>::const_iterator iter;
915         for (iter = mWidgetInstances.begin(); iter != mWidgetInstances.end(); ++iter)
916         {
917             if (*iter == widget)
918                 return true;
919         }
920 
921         return false;
922     }
923 
isTabInEnabled() const924     bool Widget::isTabInEnabled() const
925     {
926         return mTabIn;
927     }
928 
setTabInEnabled(bool enabled)929     void Widget::setTabInEnabled(bool enabled)
930     {
931         mTabIn = enabled;
932     }
933 
isTabOutEnabled() const934     bool Widget::isTabOutEnabled() const
935     {
936         return mTabOut;
937     }
938 
setTabOutEnabled(bool enabled)939     void Widget::setTabOutEnabled(bool enabled)
940     {
941         mTabOut = enabled;
942     }
943 
setSize(int width,int height)944     void Widget::setSize(int width, int height)
945     {
946         Rectangle newDimension = mDimension;
947         newDimension.width = width;
948         newDimension.height = height;
949 
950         setDimension(newDimension);
951     }
952 
setEnabled(bool enabled)953     void Widget::setEnabled(bool enabled)
954     {
955         mEnabled = enabled;
956     }
957 
isEnabled() const958     bool Widget::isEnabled() const
959     {
960         return mEnabled && isVisible();
961     }
962 
isModalFocusable() const963     bool Widget::isModalFocusable() const {
964         if (mFocusHandler == NULL) {
965             throw FCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
966             return false;
967         }
968         return mFocusHandler->getModalFocused() == NULL;
969     }
970 
isModalMouseInputFocusable() const971     bool Widget::isModalMouseInputFocusable() const {
972         if (mFocusHandler == NULL) {
973             throw FCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
974             return false;
975         }
976         return mFocusHandler->getModalMouseInputFocused() == NULL;
977     }
978 
requestModalFocus()979     void Widget::requestModalFocus()
980     {
981         if (mFocusHandler == NULL)
982             throw FCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
983 
984         mFocusHandler->requestModalFocus(this);
985     }
986 
requestModalMouseInputFocus()987     void Widget::requestModalMouseInputFocus()
988     {
989         if (mFocusHandler == NULL)
990             throw FCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
991 
992         mFocusHandler->requestModalMouseInputFocus(this);
993     }
994 
releaseModalFocus()995     void Widget::releaseModalFocus()
996     {
997         if (mFocusHandler == NULL)
998             return;
999 
1000         mFocusHandler->releaseModalFocus(this);
1001     }
1002 
releaseModalMouseInputFocus()1003     void Widget::releaseModalMouseInputFocus()
1004     {
1005         if (mFocusHandler == NULL)
1006             return;
1007 
1008         mFocusHandler->releaseModalMouseInputFocus(this);
1009     }
1010 
isModalFocused() const1011     bool Widget::isModalFocused() const
1012     {
1013         if (mFocusHandler == NULL)
1014             throw FCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
1015 
1016         if (getParent() != NULL)
1017         {
1018             return (mFocusHandler->getModalFocused() == this)
1019                 || getParent()->isModalFocused();
1020         }
1021 
1022         return mFocusHandler->getModalFocused() == this;
1023     }
1024 
isModalMouseInputFocused() const1025     bool Widget::isModalMouseInputFocused() const
1026     {
1027         if (mFocusHandler == NULL)
1028             throw FCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
1029 
1030         if (getParent() != NULL)
1031         {
1032             return (mFocusHandler->getModalMouseInputFocused() == this)
1033                 || getParent()->isModalMouseInputFocused();
1034         }
1035 
1036         return mFocusHandler->getModalMouseInputFocused() == this;
1037     }
1038 
getWidgetAt(int x,int y,Widget * exclude)1039     Widget *Widget::getWidgetAt(int x, int y, Widget* exclude)
1040     {
1041         Rectangle r = getChildrenArea();
1042 
1043         if (!r.isContaining(x, y))
1044             return NULL;
1045 
1046         x -= r.x;
1047         y -= r.y;
1048 
1049         std::list<Widget*>::reverse_iterator iter;
1050         for (iter = mChildren.rbegin(); iter != mChildren.rend(); iter++)
1051         {
1052             Widget* widget = (*iter);
1053 
1054             if (widget != exclude && widget->isVisible() && widget->getDimension().isContaining(x, y))
1055                 return widget;
1056         }
1057 
1058         return NULL;
1059     }
1060 
_getMouseListeners()1061     const std::list<MouseListener*>& Widget::_getMouseListeners()
1062     {
1063         return mMouseListeners;
1064     }
1065 
_getKeyListeners()1066     const std::list<KeyListener*>& Widget::_getKeyListeners()
1067     {
1068         return mKeyListeners;
1069     }
1070 
_getFocusListeners()1071     const std::list<FocusListener*>& Widget::_getFocusListeners()
1072     {
1073         return mFocusListeners;
1074     }
1075 
getChildrenArea()1076     Rectangle Widget::getChildrenArea()
1077     {
1078         return Rectangle(0, 0, 0, 0);
1079     }
1080 
_getInternalFocusHandler()1081     FocusHandler* Widget::_getInternalFocusHandler()
1082     {
1083         return mInternalFocusHandler;
1084     }
1085 
setInternalFocusHandler(FocusHandler * focusHandler)1086     void Widget::setInternalFocusHandler(FocusHandler* focusHandler)
1087     {
1088         mInternalFocusHandler = focusHandler;
1089 
1090         std::list<Widget*>::const_iterator iter;
1091         for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
1092         {
1093             if (mInternalFocusHandler == NULL)
1094                 (*iter)->_setFocusHandler(_getFocusHandler());
1095             else
1096                 (*iter)->_setFocusHandler(mInternalFocusHandler);
1097         }
1098     }
1099 
setId(const std::string & id)1100     void Widget::setId(const std::string& id)
1101     {
1102         mId = id;
1103     }
1104 
getId() const1105     const std::string& Widget::getId() const
1106     {
1107         return mId;
1108     }
1109 
distributeResizedEvent()1110     void Widget::distributeResizedEvent()
1111     {
1112         std::list<WidgetListener*>::const_iterator iter;
1113         for (iter = mWidgetListeners.begin(); iter != mWidgetListeners.end(); ++iter)
1114         {
1115             Event event(this);
1116             (*iter)->widgetResized(event);
1117         }
1118     }
1119 
distributeMovedEvent()1120     void Widget::distributeMovedEvent()
1121     {
1122         std::list<WidgetListener*>::const_iterator iter;
1123         for (iter = mWidgetListeners.begin(); iter != mWidgetListeners.end(); ++iter)
1124         {
1125             Event event(this);
1126             (*iter)->widgetMoved(event);
1127         }
1128     }
1129 
distributeHiddenEvent()1130     void Widget::distributeHiddenEvent()
1131     {
1132         std::list<WidgetListener*>::const_iterator iter;
1133         for (iter = mWidgetListeners.begin(); iter != mWidgetListeners.end(); ++iter)
1134         {
1135             Event event(this);
1136             (*iter)->widgetHidden(event);
1137         }
1138     }
1139 
distributeAncestorMovedEvent(Widget * ancestor)1140     void Widget::distributeAncestorMovedEvent(Widget* ancestor)
1141     {
1142         std::list<WidgetListener*>::iterator currWidgetListener(mWidgetListeners.begin());
1143         std::list<WidgetListener*>::iterator endWidgetListeners(mWidgetListeners.end());
1144         Event event(ancestor);
1145 
1146         for(; currWidgetListener != endWidgetListeners; ++currWidgetListener)
1147         {
1148             (*currWidgetListener)->ancestorMoved(event);
1149         }
1150 
1151         std::list<Widget*>::iterator currChild(mChildren.begin());
1152         std::list<Widget*>::iterator endChildren(mChildren.end());
1153 
1154         for(; currChild != endChildren; ++currChild)
1155         {
1156             (*currChild)->distributeAncestorMovedEvent(ancestor);
1157         }
1158     }
1159 
distributeAncestorHiddenEvent(Widget * ancestor)1160     void Widget::distributeAncestorHiddenEvent(Widget* ancestor)
1161     {
1162         // additonal call VisibilityEventHandler, needed to get new focus / MouseEvent::Entered or Exited
1163         _getVisibilityEventHandler()->widgetHidden(Event(this));
1164 
1165         std::list<WidgetListener*>::iterator currWidgetListener(mWidgetListeners.begin());
1166         std::list<WidgetListener*>::iterator endWidgetListeners(mWidgetListeners.end());
1167         Event event(ancestor);
1168 
1169         for(; currWidgetListener != endWidgetListeners; ++currWidgetListener)
1170         {
1171             (*currWidgetListener)->ancestorHidden(event);
1172         }
1173 
1174         std::list<Widget*>::iterator currChild(mChildren.begin());
1175         std::list<Widget*>::iterator endChildren(mChildren.end());
1176 
1177         for(; currChild != endChildren; ++currChild)
1178         {
1179             (*currChild)->distributeAncestorHiddenEvent(ancestor);
1180         }
1181     }
1182 
distributeAncestorShownEvent(Widget * ancestor)1183     void Widget::distributeAncestorShownEvent(Widget* ancestor)
1184     {
1185         // additonal call VisibilityEventHandler, needed to get new focus / MouseEvent::Entered or Exited
1186         _getVisibilityEventHandler()->widgetShown(Event(this));
1187 
1188         std::list<WidgetListener*>::iterator currWidgetListener(mWidgetListeners.begin());
1189         std::list<WidgetListener*>::iterator endWidgetListeners(mWidgetListeners.end());
1190         Event event(ancestor);
1191 
1192         for(; currWidgetListener != endWidgetListeners; ++currWidgetListener)
1193         {
1194             (*currWidgetListener)->ancestorShown(event);
1195         }
1196 
1197         std::list<Widget*>::iterator currChild(mChildren.begin());
1198         std::list<Widget*>::iterator endChildren(mChildren.end());
1199 
1200         for(; currChild != endChildren; ++currChild)
1201         {
1202             (*currChild)->distributeAncestorShownEvent(ancestor);
1203         }
1204     }
1205 
distributeActionEvent()1206     void Widget::distributeActionEvent()
1207     {
1208         std::list<ActionListener*>::const_iterator iter;
1209         for (iter = mActionListeners.begin(); iter != mActionListeners.end(); ++iter)
1210         {
1211             ActionEvent actionEvent(this, mActionEventId);
1212             (*iter)->action(actionEvent);
1213         }
1214     }
1215 
distributeShownEvent()1216     void Widget::distributeShownEvent()
1217     {
1218         std::list<WidgetListener*>::const_iterator iter;
1219         for (iter = mWidgetListeners.begin(); iter != mWidgetListeners.end(); ++iter)
1220         {
1221             Event event(this);
1222             (*iter)->widgetShown(event);
1223         }
1224     }
1225 
showPart(Rectangle rectangle)1226     void Widget::showPart(Rectangle rectangle)
1227     {
1228         if (mParent != NULL)
1229             mParent->showWidgetPart(this, rectangle);
1230     }
1231 
getTop() const1232     Widget* Widget::getTop() const
1233     {
1234         if (getParent() == NULL)
1235             return NULL;
1236 
1237         Widget* widget = getParent();
1238         Widget* parent = getParent()->getParent();
1239 
1240         while (parent != NULL)
1241         {
1242             widget = parent;
1243             parent = parent->getParent();
1244         }
1245 
1246         return widget;
1247     }
1248 
getWidgetsIn(const Rectangle & area,Widget * ignore)1249     std::list<Widget*> Widget::getWidgetsIn(const Rectangle& area,
1250                                             Widget* ignore)
1251     {
1252         std::list<Widget*> result;
1253 
1254         std::list<Widget*>::const_iterator iter;
1255         for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
1256         {
1257             Widget* widget = (*iter);
1258             if (ignore != widget && widget->getDimension().isIntersecting(area))
1259                 result.push_back(widget);
1260         }
1261 
1262         return result;
1263     }
1264 
resizeToChildren()1265     void Widget::resizeToChildren()
1266     {
1267         int w = 0, h = 0;
1268         std::list<Widget*>::const_iterator iter;
1269         for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
1270         {
1271             Widget* widget = (*iter);
1272             if (widget->getX() + widget->getWidth() > w)
1273                 w = widget->getX() + widget->getWidth();
1274 
1275             if (widget->getY() + widget->getHeight() > h)
1276                 h = widget->getY() + widget->getHeight();
1277         }
1278 
1279         setSize(w, h);
1280     }
1281 
findWidgetById(const std::string & id)1282     Widget* Widget::findWidgetById(const std::string& id)
1283     {
1284         std::list<Widget*>::const_iterator iter;
1285         for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
1286         {
1287             Widget* widget = (*iter);
1288 
1289             if (widget->getId() == id)
1290                 return widget;
1291 
1292             Widget *child = widget->findWidgetById(id);
1293 
1294             if (child != NULL)
1295                 return child;
1296         }
1297 
1298         return NULL;
1299     }
1300 
showWidgetPart(Widget * widget,Rectangle area)1301     void Widget::showWidgetPart(Widget* widget, Rectangle area)
1302     {
1303         Rectangle widgetArea = getChildrenArea();
1304 
1305         area.x += widget->getX();
1306         area.y += widget->getY();
1307 
1308         if (area.x + area.width > widgetArea.width)
1309             widget->setX(widget->getX() - area.x - area.width + widgetArea.width);
1310 
1311         if (area.y + area.height > widgetArea.height)
1312             widget->setY(widget->getY() - area.y - area.height + widgetArea.height);
1313 
1314         if (area.x < 0)
1315             widget->setX(widget->getX() - area.x);
1316 
1317         if (area.y < 0)
1318             widget->setY(widget->getY() - area.y);
1319     }
1320 
clear()1321     void Widget::clear()
1322     {
1323         std::list<Widget*>::const_iterator iter;
1324         for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
1325         {
1326             Widget* widget = (*iter);
1327             int x = 0;
1328             int y = 0;
1329             widget->getAbsolutePosition(x, y);
1330             widget->setLastPosition(x, y);
1331             widget->_setFocusHandler(NULL);
1332             widget->_setParent(NULL);
1333             // thats more a hack but needed
1334             if (_getVisibilityEventHandler())
1335                 _getVisibilityEventHandler()->widgetHidden(Event(widget));
1336         }
1337 
1338         mChildren.clear();
1339     }
1340 
remove(Widget * widget)1341     void Widget::remove(Widget* widget)
1342     {
1343         std::list<Widget*>::iterator iter;
1344         for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
1345         {
1346             if (*iter == widget)
1347             {
1348                 int x = 0;
1349                 int y = 0;
1350                 widget->getAbsolutePosition(x, y);
1351                 widget->setLastPosition(x, y);
1352                 mChildren.erase(iter);
1353                 widget->_setFocusHandler(NULL);
1354                 widget->_setParent(NULL);
1355                 // thats more a hack but needed
1356                 if (_getVisibilityEventHandler())
1357                     _getVisibilityEventHandler()->widgetHidden(Event(widget));
1358                 return;
1359             }
1360         }
1361 
1362         throw FCN_EXCEPTION("There is no such widget in this container.");
1363     }
1364 
add(Widget * widget)1365     void Widget::add(Widget* widget)
1366     {
1367         mChildren.push_back(widget);
1368 
1369         if (mInternalFocusHandler == NULL)
1370             widget->_setFocusHandler(_getFocusHandler());
1371         else
1372             widget->_setFocusHandler(mInternalFocusHandler);
1373 
1374         widget->_setParent(this);
1375         setLastPosition(0, 0);
1376         // thats more a hack but needed
1377         if (_getVisibilityEventHandler())
1378             _getVisibilityEventHandler()->widgetShown(Event(widget));
1379     }
1380 
moveToTop(Widget * widget)1381     void Widget::moveToTop(Widget* widget)
1382     {
1383         std::list<Widget*>::iterator iter;
1384         iter = std::find(mChildren.begin(), mChildren.end(), widget);
1385 
1386         if (iter == mChildren.end())
1387             throw FCN_EXCEPTION("There is no such widget in this widget.");
1388 
1389         mChildren.remove(widget);
1390         mChildren.push_back(widget);
1391     }
1392 
moveToBottom(Widget * widget)1393     void Widget::moveToBottom(Widget* widget)
1394     {
1395         std::list<Widget*>::iterator iter;
1396         iter = find(mChildren.begin(), mChildren.end(), widget);
1397 
1398         if (iter == mChildren.end())
1399             throw FCN_EXCEPTION("There is no such widget in this widget.");
1400 
1401         mChildren.remove(widget);
1402         mChildren.push_front(widget);
1403     }
1404 
focusNext()1405     void Widget::focusNext()
1406     {
1407         std::list<Widget*>::const_iterator iter;
1408 
1409         for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
1410         {
1411             if ((*iter)->isFocused())
1412                 break;
1413         }
1414 
1415         std::list<Widget*>::const_iterator end = iter;
1416 
1417         if (iter == mChildren.end())
1418             iter = mChildren.begin();
1419 
1420         iter++;
1421 
1422         for (; iter != end; iter++)
1423         {
1424             if (iter == mChildren.end())
1425                 iter = mChildren.begin();
1426 
1427             if ((*iter)->isFocusable())
1428             {
1429                 (*iter)->requestFocus();
1430                 return;
1431             }
1432         }
1433     }
1434 
focusPrevious()1435     void Widget::focusPrevious()
1436     {
1437         std::list<Widget*>::reverse_iterator iter;
1438 
1439         for (iter = mChildren.rbegin(); iter != mChildren.rend(); iter++)
1440         {
1441             if ((*iter)->isFocused())
1442                 break;
1443         }
1444 
1445         std::list<Widget*>::reverse_iterator end = iter;
1446         iter++;
1447 
1448         if (iter == mChildren.rend())
1449             iter = mChildren.rbegin();
1450 
1451         for (; iter != end; iter++)
1452         {
1453             if (iter == mChildren.rend())
1454                 iter = mChildren.rbegin();
1455 
1456             if ((*iter)->isFocusable())
1457             {
1458                 (*iter)->requestFocus();
1459                 return;
1460             }
1461         }
1462     }
1463 
_draw(Graphics * graphics)1464     void Widget::_draw(Graphics* graphics)
1465     {
1466         if (mOutlineSize > 0)
1467         {
1468             Rectangle rec = mDimension;
1469             rec.x -= mOutlineSize;
1470             rec.y -= mOutlineSize;
1471             rec.width += 2 * mOutlineSize;
1472             rec.height += 2 * mOutlineSize;
1473             graphics->pushClipArea(rec);
1474             drawOutline(graphics);
1475             graphics->popClipArea();
1476         }
1477 
1478         graphics->pushClipArea(mDimension);
1479         draw(graphics);
1480 
1481         if (!mChildren.empty()) {
1482             const Rectangle& childrenArea = getChildrenArea();
1483             graphics->pushClipArea(childrenArea);
1484 
1485             std::list<Widget*>::const_iterator iter;
1486             for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
1487             {
1488                 Widget* widget = (*iter);
1489                 // Only draw a widget if it's visible and if it visible
1490                 // inside the children area.
1491                 //if (widget->isVisible() && childrenArea.isIntersecting(widget->getDimension()))
1492                 if (widget->isVisible())
1493                     widget->_draw(graphics);
1494             }
1495             graphics->popClipArea();
1496         }
1497         graphics->popClipArea();
1498     }
1499 
_logic()1500     void Widget::_logic()
1501     {
1502         logic();
1503 
1504         std::list<Widget*>::const_iterator iter;
1505         for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
1506             (*iter)->_logic();
1507     }
1508 
getChildren() const1509     const std::list<Widget*>& Widget::getChildren() const
1510     {
1511         return mChildren;
1512     }
1513 
getLastPosition(int & x,int & y) const1514     void Widget::getLastPosition(int& x, int& y) const {
1515         x = mLastX;
1516         y = mLastY;
1517     }
1518 
setLastPosition(int x,int y)1519     void Widget::setLastPosition(int x, int y) {
1520         mLastX = x;
1521         mLastY = y;
1522     }
1523 
isLastPositionSet() const1524     bool Widget::isLastPositionSet() const {
1525         return mLastX != 0 || mLastY != 0;
1526     }
1527 }
1528