ManaPlus
label.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2009 Aethyra Development Team
4  * Copyright (C) 2011-2018 The ManaPlus Developers
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 #include "gui/widgets/label.h"
66 
67 #include "gui/gui.h"
68 #include "gui/skin.h"
69 
70 #include "gui/fonts/font.h"
71 
72 #include "debug.h"
73 
74 Skin *Label::mSkin = nullptr;
75 int Label::mInstances = 0;
76 
77 Label::Label(const Widget2 *const widget) :
78  Widget(widget),
81  mCaption(),
82  mTextChunk(),
83  mAlignment(Graphics::LEFT),
84  mPadding(0),
85  mTextChanged(true)
86 {
87  init();
88 }
89 
90 Label::Label(const Widget2 *const widget,
91  const std::string &caption) :
92  Widget(widget),
95  mCaption(caption),
96  mTextChunk(),
98  mPadding(0),
99  mTextChanged(true)
100 {
101  const Font *const font = getFont();
102  setWidth(font->getWidth(caption));
103  setHeight(font->getHeight());
104  init();
105 }
106 
108 {
109  if (mWindow != nullptr)
111 
112  if (gui != nullptr)
113  gui->removeDragged(this);
114 
115  mInstances --;
116  if (mInstances == 0)
117  {
118  if (theme != nullptr)
119  theme->unload(mSkin);
120  }
121  removeMouseListener(this);
123 }
124 
126 {
127  addMouseListener(this);
128  mAllowLogic = false;
131  if (mInstances == 0)
132  {
133  if (theme != nullptr)
134  {
135  mSkin = theme->load("label.xml",
136  "",
137  true,
139  }
140  }
141  mInstances ++;
142 
143  if (mSkin != nullptr)
145  else
146  mPadding = 0;
147  setSelectable(false);
148 }
149 
150 void Label::draw(Graphics *const graphics)
151 {
152  BLOCK_START("Label::draw")
153  int textX;
154  const Rect &rect = mDimension;
155  const int textY = rect.height / 2 - getFont()->getHeight() / 2;
156  Font *const font = getFont();
157 
158  switch (mAlignment)
159  {
160  case Graphics::LEFT:
161  default:
162  textX = mPadding;
163  break;
164  case Graphics::CENTER:
165  textX = (rect.width - font->getWidth(mCaption)) / 2;
166  break;
167  case Graphics::RIGHT:
168  if (rect.width > mPadding)
169  textX = rect.width - mPadding - font->getWidth(mCaption);
170  else
171  textX = 0;
172  break;
173  }
174 
175  if (mTextChanged)
176  {
182  font->generate(mTextChunk);
183  mTextChanged = false;
184  }
185 
186  const Image *const image = mTextChunk.img;
187  if (image != nullptr)
188  graphics->drawImage(image, textX, textY);
189  BLOCK_END("Label::draw")
190 }
191 
192 void Label::safeDraw(Graphics *const graphics)
193 {
194  Label::draw(graphics);
195 }
196 
198 {
199  const Font *const font = getFont();
200  const int pad2 = 2 * mPadding;
201  setWidth(font->getWidth(mCaption) + pad2);
202  setHeight(font->getHeight() + pad2);
203 }
204 
206 {
207  if (mForegroundColor != color || mForegroundColor2 != color)
208  mTextChanged = true;
209 // logger->log("Label::setForegroundColor: " + mCaption);
210  mForegroundColor = color;
211  mForegroundColor2 = color;
212 }
213 
215  const Color &color2)
216 {
217  if (mForegroundColor != color1 || mForegroundColor2 != color2)
218  mTextChanged = true;
219 // logger->log("Label::setForegroundColorAll: " + mCaption);
220  mForegroundColor = color1;
221  mForegroundColor2 = color2;
222 }
223 
224 void Label::resizeTo(const int maxSize, const int minSize)
225 {
226  const Font *const font = getFont();
227  const int pad2 = 2 * mPadding;
228  setHeight(font->getHeight() + pad2);
229 
230  if (font->getWidth(mCaption) + pad2 > maxSize)
231  {
232  const int dots = font->getWidth("...");
233  if (dots > maxSize)
234  {
235  setWidth(maxSize);
236  return;
237  }
238  const size_t szChars = mCaption.size();
239  for (size_t f = 1; f < szChars - 1; f ++)
240  {
241  const std::string text = mCaption.substr(0, szChars - f);
242  const int width = font->getWidth(text) + dots + pad2;
243  if (width <= maxSize)
244  {
245  setCaption(text + "...");
246  setWidth(width);
247  return;
248  }
249  }
250  setWidth(maxSize);
251  }
252  else
253  {
254  int sz = font->getWidth(mCaption) + pad2;
255  if (sz < minSize)
256  sz = minSize;
257  setWidth(sz);
258  }
259 }
260 
261 void Label::setCaption(const std::string& caption)
262 {
263  if (caption != mCaption)
264  mTextChanged = true;
265  mCaption = caption;
266 }
267 
268 void Label::setParent(Widget *const widget)
269 {
270  if (mWindow != nullptr)
271  mWindow->addWidgetListener(this);
272  Widget::setParent(widget);
273 }
274 
275 void Label::setWindow(Widget *const widget)
276 {
277  if ((widget == nullptr) && (mWindow != nullptr))
278  {
280  mWindow = nullptr;
281  }
282  else
283  {
284  Widget2::setWindow(widget);
285  }
286 }
287 
289 {
290  mTextChanged = true;
292 }
293 
295 {
296  mSkin = nullptr;
297 }
Font * getFont() const
Definition: widget.cpp:330
int width
Definition: rect.h:218
std::string text
Definition: textchunk.h:64
Definition: skin.h:35
void setWidth(const int width)
Definition: widget.cpp:132
void unload(Skin *const skin)
Definition: theme.cpp:249
Gui * gui
Definition: gui.cpp:110
Definition: font.h:88
static int mInstances
Definition: label.h:173
TextChunk mTextChunk
Definition: label.h:183
Definition: rect.h:72
#define BLOCK_START(name)
Definition: perfomance.h:78
static std::string getThemePath()
Definition: theme.h:66
Skin * load(const std::string &filename, const std::string &filename2, const bool full, const std::string &defaultPath)
Definition: theme.cpp:178
#define BLOCK_END(name)
Definition: perfomance.h:79
static void finalCleanup()
Definition: label.cpp:294
Color mForegroundColor
Definition: widget.h:1085
std::string mCaption
Definition: label.h:181
Font * textFont
Definition: textchunk.h:63
void init()
Definition: label.cpp:125
bool mTextChanged
Definition: label.h:192
void setSelectable(const bool selectable)
Definition: widget.h:947
~Label()
Definition: label.cpp:107
int getPadding() const
Definition: skin.h:99
void removeMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:296
virtual void setWindow(Widget *const window)
Definition: widget2.h:96
void setCaption(const std::string &caption)
Definition: label.cpp:261
void widgetHidden(const Event &event)
Definition: label.cpp:288
Widget * mWindow
Definition: widget2.h:111
int mPadding
Definition: label.h:190
bool mAllowLogic
Definition: widget.h:1159
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:291
int height
Definition: rect.h:223
void draw(Graphics *const graphics)
Definition: label.cpp:150
virtual void setParent(Widget *parent)
Definition: widget.h:625
void setWindow(Widget *const widget)
Definition: label.cpp:275
void setHeight(const int height)
Definition: widget.cpp:139
void addWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:301
Theme * theme
Definition: theme.cpp:61
#define A_UNUSED
Definition: localconsts.h:151
Graphics::Alignment mAlignment
Definition: label.h:188
Color mForegroundColor2
Definition: widget2.h:112
Image * img
Definition: textchunk.h:62
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
void removeDragged(const Widget *const widget)
Definition: gui.cpp:1160
Definition: widget.h:97
void removeWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:306
int getWidth(const std::string &text) const
Definition: font.cpp:333
Definition: event.h:77
Definition: image.h:61
Color color
Definition: textchunk.h:65
Definition: color.h:74
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:44
void setForegroundColorAll(const Color &color1, const Color &color2)
Definition: label.cpp:214
void setForegroundColor(const Color &color)
Definition: label.cpp:205
Label(const Widget2 *const widget)
Definition: label.cpp:77
int getHeight() const
Definition: font.cpp:360
void resizeTo(const int maxSize, const int minSize)
Definition: label.cpp:224
void deleteImage()
Definition: textchunk.cpp:192
Color color2
Definition: textchunk.h:66
Rect mDimension
Definition: widget.h:1100
void safeDraw(Graphics *const graphics)
Definition: label.cpp:192
void adjustSize()
Definition: label.cpp:197
void setParent(Widget *const widget)
Definition: label.cpp:268
static Skin * mSkin
Definition: label.h:171
void generate(TextChunk &chunk)
Definition: font.cpp:428