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-2019 The ManaPlus Developers
5  * Copyright (C) 2019-2021 Andrei Karas
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * 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
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 /* _______ __ __ __ ______ __ __ _______ __ __
24  * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
25  * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
26  * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
27  * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
28  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
29  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
30  *
31  * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
32  *
33  *
34  * Per Larsson a.k.a finalman
35  * Olof Naessén a.k.a jansem/yakslem
36  *
37  * Visit: http://guichan.sourceforge.net
38  *
39  * License: (BSD)
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  * notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  * notice, this list of conditions and the following disclaimer in
47  * the documentation and/or other materials provided with the
48  * distribution.
49  * 3. Neither the name of Guichan nor the names of its contributors may
50  * be used to endorse or promote products derived from this software
51  * without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
54  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
56  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
57  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
59  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
60  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
61  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */
65 
66 #include "gui/widgets/label.h"
67 
68 #include "gui/gui.h"
69 #include "gui/skin.h"
70 
71 #include "gui/fonts/font.h"
72 
73 #include "debug.h"
74 
75 Skin *Label::mSkin = nullptr;
76 int Label::mInstances = 0;
77 
78 Label::Label(const Widget2 *const widget) :
79  Widget(widget),
82  mCaption(),
83  mTextChunk(),
84  mAlignment(Graphics::LEFT),
85  mPadding(0),
86  mTextChanged(true)
87 {
88  init();
89 }
90 
91 Label::Label(const Widget2 *const widget,
92  const std::string &caption) :
93  Widget(widget),
96  mCaption(caption),
97  mTextChunk(),
98  mAlignment(Graphics::LEFT),
99  mPadding(0),
100  mTextChanged(true)
101 {
102  const Font *const font = getFont();
103  setWidth(font->getWidth(caption));
104  setHeight(font->getHeight());
105  init();
106 }
107 
109 {
110  if (mWindow != nullptr)
112 
113  if (gui != nullptr)
114  gui->removeDragged(this);
115 
116  mInstances --;
117  if (mInstances == 0)
118  {
119  if (theme != nullptr)
120  theme->unload(mSkin);
121  }
122  removeMouseListener(this);
124 }
125 
127 {
128  addMouseListener(this);
129  mAllowLogic = false;
131  mForegroundColor2 = getThemeColor(ThemeColorId::LABEL_OUTLINE, 255U);
132  if (mInstances == 0)
133  {
134  if (theme != nullptr)
135  {
136  mSkin = theme->load("label.xml",
137  "",
138  true,
140  }
141  }
142  mInstances ++;
143 
144  if (mSkin != nullptr)
146  else
147  mPadding = 0;
148  setSelectable(false);
149 }
150 
151 void Label::draw(Graphics *const graphics)
152 {
153  BLOCK_START("Label::draw")
154  int textX;
155  const Rect &rect = mDimension;
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  {
177  mTextChunk.textFont = font;
182  font->generate(mTextChunk);
183  mTextChanged = false;
184  }
185 
186  const Image *const image = mTextChunk.img;
187  if (image != nullptr)
188  {
189  const int textY = rect.height / 2 - font->getHeight() / 2;
190  graphics->drawImage(image, textX, textY);
191  }
192  BLOCK_END("Label::draw")
193 }
194 
195 void Label::safeDraw(Graphics *const graphics)
196 {
197  Label::draw(graphics);
198 }
199 
201 {
202  const Font *const font = getFont();
203  const int pad2 = 2 * mPadding;
204  setWidth(font->getWidth(mCaption) + pad2);
205  setHeight(font->getHeight() + pad2);
206 }
207 
209 {
210  if (mForegroundColor != color || mForegroundColor2 != color)
211  mTextChanged = true;
212 // logger->log("Label::setForegroundColor: " + mCaption);
213  mForegroundColor = color;
214  mForegroundColor2 = color;
215 }
216 
218  const Color &color2)
219 {
220  if (mForegroundColor != color1 || mForegroundColor2 != color2)
221  mTextChanged = true;
222 // logger->log("Label::setForegroundColorAll: " + mCaption);
223  mForegroundColor = color1;
224  mForegroundColor2 = color2;
225 }
226 
227 void Label::resizeTo(const int maxSize, const int minSize)
228 {
229  const Font *const font = getFont();
230  const int pad2 = 2 * mPadding;
231  setHeight(font->getHeight() + pad2);
232 
233  if (font->getWidth(mCaption) + pad2 > maxSize)
234  {
235  const int dots = font->getWidth("...");
236  if (dots > maxSize)
237  {
238  setWidth(maxSize);
239  return;
240  }
241  const size_t szChars = mCaption.size();
242  for (size_t f = 1; f < szChars - 1; f ++)
243  {
244  const std::string text = mCaption.substr(0, szChars - f);
245  const int width = font->getWidth(text) + dots + pad2;
246  if (width <= maxSize)
247  {
248  setCaption(text + "...");
249  setWidth(width);
250  return;
251  }
252  }
253  setWidth(maxSize);
254  }
255  else
256  {
257  int sz = font->getWidth(mCaption) + pad2;
258  if (sz < minSize)
259  sz = minSize;
260  setWidth(sz);
261  }
262 }
263 
264 void Label::setCaption(const std::string& caption)
265 {
266  if (caption != mCaption)
267  mTextChanged = true;
268  mCaption = caption;
269 }
270 
271 void Label::setParent(Widget *const widget)
272 {
273  if (mWindow != nullptr)
274  mWindow->addWidgetListener(this);
275  Widget::setParent(widget);
276 }
277 
278 void Label::setWindow(Widget *const widget)
279 {
280  if ((widget == nullptr) && (mWindow != nullptr))
281  {
283  mWindow = nullptr;
284  }
285  else
286  {
287  Widget2::setWindow(widget);
288  }
289 }
290 
292 {
293  mTextChanged = true;
295 }
296 
298 {
299  mSkin = nullptr;
300 }
Definition: color.h:76
Definition: event.h:79
Definition: font.h:90
int getHeight() const
Definition: font.cpp:362
void generate(TextChunk &chunk)
Definition: font.cpp:430
int getWidth(const std::string &text) const
Definition: font.cpp:334
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
@ CENTER
Definition: graphics.h:132
void removeDragged(const Widget *const widget)
Definition: gui.cpp:1162
void setForegroundColor(const Color &color)
Definition: label.cpp:208
void resizeTo(const int maxSize, const int minSize)
Definition: label.cpp:227
bool mTextChanged
Definition: label.h:193
void init()
Definition: label.cpp:126
static void finalCleanup()
Definition: label.cpp:297
~Label()
Definition: label.cpp:108
void adjustSize()
Definition: label.cpp:200
void setForegroundColorAll(const Color &color1, const Color &color2)
Definition: label.cpp:217
static Skin * mSkin
Definition: label.h:172
static int mInstances
Definition: label.h:174
int mPadding
Definition: label.h:191
void setParent(Widget *const widget)
Definition: label.cpp:271
void widgetHidden(const Event &event)
Definition: label.cpp:291
void safeDraw(Graphics *const graphics)
Definition: label.cpp:195
void draw(Graphics *const graphics)
Definition: label.cpp:151
Graphics::Alignment mAlignment
Definition: label.h:189
TextChunk mTextChunk
Definition: label.h:184
void setCaption(const std::string &caption)
Definition: label.cpp:264
std::string mCaption
Definition: label.h:182
Label(const Widget2 *const widget)
Definition: label.cpp:78
void setWindow(Widget *const widget)
Definition: label.cpp:278
Definition: rect.h:74
int width
Definition: rect.h:219
int height
Definition: rect.h:224
Definition: skin.h:37
int getPadding() const
Definition: skin.h:100
void deleteImage()
Definition: textchunk.cpp:193
Font * textFont
Definition: textchunk.h:64
Image * img
Definition: textchunk.h:63
Color color
Definition: textchunk.h:66
Color color2
Definition: textchunk.h:67
std::string text
Definition: textchunk.h:65
void unload(Skin *const skin)
Definition: theme.cpp:250
static std::string getThemePath()
Definition: theme.h:67
Skin * load(const std::string &filename, const std::string &filename2, const bool full, const std::string &defaultPath)
Definition: theme.cpp:179
virtual void setWindow(Widget *const window)
Definition: widget2.h:97
Widget * mWindow
Definition: widget2.h:112
Color mForegroundColor2
Definition: widget2.h:113
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:45
Definition: widget.h:99
Color mForegroundColor
Definition: widget.h:1086
void setWidth(const int width)
Definition: widget.cpp:133
void removeMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:297
Rect mDimension
Definition: widget.h:1101
bool mAllowLogic
Definition: widget.h:1160
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:292
void addWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:302
void setHeight(const int height)
Definition: widget.cpp:140
Font * getFont() const
Definition: widget.cpp:331
virtual void setParent(Widget *parent)
Definition: widget.h:626
void removeWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:307
void setSelectable(const bool selectable)
Definition: widget.h:948
Gui * gui
Definition: gui.cpp:111
#define A_UNUSED
Definition: localconsts.h:160
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
Theme * theme
Definition: theme.cpp:62