1 /** @file hudwidget.cpp  Specialized UI widget for HUD elements.
2  *
3  * @authors Copyright © 2005-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4  * @authors Copyright © 2005-2015 Daniel Swanson <danij@dengine.net>
5  *
6  * @par License
7  * GPL: http://www.gnu.org/licenses/gpl.html
8  *
9  * <small>This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by the
11  * Free Software Foundation; either version 2 of the License, or (at your
12  * option) any later version. This program is distributed in the hope that it
13  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15  * Public License for more details. You should have received a copy of the GNU
16  * General Public License along with this program; if not, write to the Free
17  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301 USA</small>
19  */
20 
21 #include "common.h"
22 #include "hud/hudwidget.h"
23 
24 #include <de/memory.h>
25 #include "hud/widgets/groupwidget.h"  ///< @todo remove me
26 
27 using namespace de;
28 using namespace common;
29 
DENG2_PIMPL_NOREF(HudWidget)30 DENG2_PIMPL_NOREF(HudWidget)
31 {
32     uiwidgetid_t id = 0;              ///< Unique identifier associated with this widget.
33     dint alignFlags = ALIGN_TOPLEFT;  ///< @ref alignmentFlags
34     Size2Raw maxSize{};               ///< Maximum size of this widget in pixels.
35     Rect *geometry = Rect_New();      ///< Geometry of this widget in pixels.
36     dint player = 0;                  ///< Local player number associated with this widget.
37     fontid_t font = 0;                ///< Current font used for text child objects of this widget.
38     dfloat opacity = 1;               ///< Current opacity value for this widget.
39 
40     ~Impl() { Rect_Delete(geometry); }
41 };
42 
HudWidget(void (* updateGeometry)(HudWidget * wi),void (* drawer)(HudWidget * wi,Point2Raw const * offset),dint playerNum,uiwidgetid_t id)43 HudWidget::HudWidget(void (*updateGeometry) (HudWidget *wi),
44                      void (*drawer) (HudWidget *wi, Point2Raw const *offset),
45                      dint playerNum, uiwidgetid_t id)
46     : updateGeometry(updateGeometry)
47     , drawer(drawer)
48     , d(new Impl)
49 {
50     setId(id);
51     setPlayer(playerNum);
52 }
53 
~HudWidget()54 HudWidget::~HudWidget()
55 {}
56 
id() const57 uiwidgetid_t HudWidget::id() const
58 {
59     return d->id;
60 }
61 
setId(uiwidgetid_t newId)62 void HudWidget::setId(uiwidgetid_t newId)
63 {
64     d->id = newId;
65 }
66 
player() const67 int HudWidget::player() const
68 {
69     return d->player;
70 }
71 
setPlayer(int newPlayer)72 void HudWidget::setPlayer(int newPlayer)
73 {
74     d->player = newPlayer;
75 }
76 
geometry() const77 Rect &HudWidget::geometry() const
78 {
79     DENG2_ASSERT(d->geometry);
80     return *d->geometry;
81 }
82 
maximumSize() const83 Size2Raw &HudWidget::maximumSize() const
84 {
85     return d->maxSize;
86 }
87 
setMaximumSize(Size2Raw const & newSize)88 void HudWidget::setMaximumSize(Size2Raw const &newSize)
89 {
90     if(d->maxSize.width == newSize.width &&
91        d->maxSize.height == newSize.height) return;
92     d->maxSize.width  = newSize.width;
93     d->maxSize.height = newSize.height;
94 
95     if(auto *group = maybeAs<GroupWidget>(this))
96     {
97         group->forAllChildren([&newSize] (HudWidget &child)
98         {
99             child.setMaximumSize(newSize);
100             return LoopContinue;
101         });
102     }
103 }
104 
setMaximumHeight(int newMaxHeight)105 void HudWidget::setMaximumHeight(int newMaxHeight)
106 {
107     if(d->maxSize.height == newMaxHeight) return;
108     d->maxSize.height = newMaxHeight;
109 
110     if(auto *group = maybeAs<GroupWidget>(this))
111     {
112         group->forAllChildren([&newMaxHeight] (HudWidget &child)
113         {
114             child.setMaximumHeight(newMaxHeight);
115             return LoopContinue;
116         });
117     }
118 }
119 
setMaximumWidth(int newMaxWidth)120 void HudWidget::setMaximumWidth(int newMaxWidth)
121 {
122     if(d->maxSize.width == newMaxWidth) return;
123     d->maxSize.width = newMaxWidth;
124 
125     if(auto *group = maybeAs<GroupWidget>(this))
126     {
127         group->forAllChildren([&newMaxWidth] (HudWidget &child)
128         {
129             child.setMaximumWidth(newMaxWidth);
130             return LoopContinue;
131         });
132     }
133 }
134 
alignment() const135 int HudWidget::alignment() const
136 {
137     return d->alignFlags;
138 }
139 
setAlignment(int alignFlags)140 HudWidget &HudWidget::setAlignment(int alignFlags)
141 {
142     d->alignFlags = alignFlags;
143     return *this;
144 }
145 
opacity() const146 float HudWidget::opacity() const
147 {
148     return d->opacity;
149 }
150 
setOpacity(float newOpacity)151 HudWidget &HudWidget::setOpacity(float newOpacity)
152 {
153     d->opacity = newOpacity;
154     if(auto *group = maybeAs<GroupWidget>(this))
155     {
156         group->forAllChildren([&newOpacity] (HudWidget &child)
157         {
158             child.setOpacity(newOpacity);
159             return LoopContinue;
160         });
161     }
162     return *this;
163 }
164 
font() const165 fontid_t HudWidget::font() const
166 {
167     return d->font;
168 }
169 
setFont(fontid_t newFont)170 HudWidget &HudWidget::setFont(fontid_t newFont)
171 {
172     d->font = newFont;
173     return *this;
174 }
175