ManaPlus
staticbrowserbox.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2019 The ManaPlus Developers
6  * Copyright (C) 2019-2021 Andrei Karas
7  * Copyright (C) 2009 Aethyra Development Team
8  *
9  * This file is part of The ManaPlus Client.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24 
26 
28 
29 #include "gui/gui.h"
30 #include "gui/mouseoverlink.h"
31 #include "gui/skin.h"
32 
33 #include "gui/fonts/font.h"
34 
35 #include "gui/widgets/browserbox.inc"
37 
38 #include "render/graphics.h"
39 
40 #include "resources/imageset.h"
41 
42 #include "resources/image/image.h"
43 
46 
47 #include "utils/browserboxtools.h"
48 #include "utils/checkutils.h"
49 #include "utils/foreach.h"
50 #include "utils/stdmove.h"
51 #include "utils/stringutils.h"
53 
54 #include <algorithm>
55 
56 #include "debug.h"
57 
60 
62  const Opaque opaque,
63  const std::string &skin) :
64  Widget(widget),
65  MouseListener(),
66  mTextRows(),
67  mTextRowLinksCount(),
68  mLineParts(),
69  mLinks(),
70  mLinkHandler(nullptr),
71  mSkin(nullptr),
72  mHighlightMode(0),
73  mSelectedLink(-1),
74  mHeight(0),
75  mWidth(0),
76  mYStart(0),
77  mPadding(0),
78  mNewLinePadding(15U),
79  mItemPadding(0),
80  mHighlightColor(getThemeColor(ThemeColorId::HIGHLIGHT, 255U)),
81  mHyperLinkColor(getThemeColor(ThemeColorId::HYPERLINK, 255U)),
82  mOpaque(opaque),
83  mUseLinksAndUserColors(true),
84  mUseEmotes(true),
85  mProcessVars(false),
86  mEnableImages(false),
87  mEnableKeys(false),
88  mEnableTabs(false),
89  mSeparator(false)
90 {
91  mAllowLogic = false;
92 
93  setFocusable(true);
94  addMouseListener(this);
95 
97 
98  if (theme != nullptr)
99  {
100  mSkin = theme->load(skin,
101  "browserbox.xml",
102  true,
104  }
105  if (mInstances == 0)
106  {
108  "graphics/sprites/chatemotes.png", 17, 18);
109  }
110  mInstances ++;
111 
112  if (mSkin != nullptr)
113  {
116  mSkin->getOption("newLinePadding", 15));
117  mItemPadding = mSkin->getOption("itemPadding");
118  if (mSkin->getOption("highlightBackground") != 0)
120  if (mSkin->getOption("highlightUnderline") != 0)
122  }
123 
124  readColor(BLACK);
125  readColor(RED);
126  readColor(GREEN);
127  readColor(BLUE);
128  readColor(ORANGE);
129  readColor(YELLOW);
130  readColor(PINK);
131  readColor(PURPLE);
132  readColor(GRAY);
133  readColor(BROWN);
134 
135  mForegroundColor = getThemeColor(ThemeColorId::BROWSERBOX, 255U);
136  mForegroundColor2 = getThemeColor(ThemeColorId::BROWSERBOX_OUTLINE, 255U);
137 }
138 
140 {
141  if (gui != nullptr)
142  gui->removeDragged(this);
143 
144  if (theme != nullptr)
145  {
146  theme->unload(mSkin);
147  mSkin = nullptr;
148  }
149 
150  mInstances --;
151  if (mInstances == 0)
152  {
153  if (mEmotes != nullptr)
154  {
155  mEmotes->decRef();
156  mEmotes = nullptr;
157  }
158  }
159 }
160 
162 {
163  mLinkHandler = linkHandler;
164 }
165 
166 void StaticBrowserBox::addSeparator(const std::string &row)
167 {
168  if (mSeparator)
169  return;
170  addRow(row, false);
171  mSeparator = true;
172 }
173 
174 void StaticBrowserBox::addRow(const std::string &row,
175  const bool atTop)
176 {
177  std::string tmp = row;
178  std::string newRow;
179  size_t idx1;
180  const Font *const font = getFont();
181  int linksCount = 0;
182 
183  if (getWidth() < 0)
184  return;
185 
186  mSeparator = false;
187 
188  if (mProcessVars)
189  {
191  }
192 
193  // Use links and user defined colors
195  {
196  BrowserLink bLink;
197 
198  // Check for links in format "@@link|Caption@@"
199  const uint32_t sz = CAST_U32(mTextRows.size());
200 
201  if (mEnableKeys)
202  {
204  }
205 
206  idx1 = tmp.find("@@");
207  while (idx1 != std::string::npos)
208  {
209  const size_t idx2 = tmp.find('|', idx1);
210  const size_t idx3 = tmp.find("@@", idx2);
211 
212  if (idx2 == std::string::npos || idx3 == std::string::npos)
213  break;
214  bLink.link = tmp.substr(idx1 + 2, idx2 - (idx1 + 2));
215  bLink.caption = tmp.substr(idx2 + 1, idx3 - (idx2 + 1));
216  bLink.y1 = CAST_S32(sz) * font->getHeight();
217  bLink.y2 = bLink.y1 + font->getHeight();
218  if (bLink.caption.empty())
219  {
221  bLink.link);
222  if (translator != nullptr)
223  bLink.caption = translator->getStr(bLink.caption);
224  }
225 
226  newRow.append(tmp.substr(0, idx1));
227 
228  std::string tmp2 = newRow;
229  idx1 = tmp2.find("##");
230  while (idx1 != std::string::npos)
231  {
232  tmp2.erase(idx1, 3);
233  idx1 = tmp2.find("##");
234  }
235  bLink.x1 = font->getWidth(tmp2) - 1;
236  bLink.x2 = bLink.x1 + font->getWidth(bLink.caption) + 1;
237 
238  if (atTop)
239  mLinks.insert(mLinks.begin(), bLink);
240  else
241  mLinks.push_back(bLink);
242  linksCount ++;
243 
244  newRow.append("##<").append(bLink.caption);
245 
246  tmp.erase(0, idx3 + 2);
247  if (!tmp.empty())
248  newRow.append("##>");
249 
250  idx1 = tmp.find("@@");
251  }
252 
253  newRow.append(tmp);
254  }
255  // Don't use links and user defined colors
256  else
257  {
258  newRow = row;
259  }
260 
261  if (mEnableTabs)
262  {
264  }
265 
266  if (atTop)
267  {
268  mTextRows.push_front(newRow);
269  mTextRowLinksCount.push_front(linksCount);
270  }
271  else
272  {
273  mTextRows.push_back(newRow);
274  mTextRowLinksCount.push_back(linksCount);
275  }
276 
277  std::string plain = STD_MOVE(newRow);
278  // workaround if used only one string started from bold
279  // width for this string can be calculated wrong
280  // this workaround fix width if string start from bold sign
281  const bool startBold = (plain.find("##B") == 0);
282  for (idx1 = plain.find("##");
283  idx1 != std::string::npos;
284  idx1 = plain.find("##"))
285  {
286  plain.erase(idx1, 3);
287  }
288 
289  // Adjust the StaticBrowserBox size. This need only for implementing "---"
290  const int w = startBold ?
291  boldFont->getWidth(plain) : font->getWidth(plain) + 2 * mPadding;
292  if (w > getWidth())
293  setWidth(w);
294 }
295 
296 void StaticBrowserBox::addRow(const std::string &cmd,
297  const char *const text)
298 {
299  addRow(strprintf("@@%s|%s@@", encodeLinkText(cmd).c_str(),
300  encodeLinkText(text).c_str()),
301  false);
302 }
303 
304 void StaticBrowserBox::addImage(const std::string &path)
305 {
306  if (!mEnableImages)
307  return;
308 
309  mTextRows.push_back("~~~" + path);
310  mTextRowLinksCount.push_back(0);
311 }
312 
314 {
315  mTextRows.clear();
316  mTextRowLinksCount.clear();
317  mLinks.clear();
318  setWidth(0);
319  setHeight(0);
320  mSelectedLink = -1;
321 }
322 
324 {
325  if (mLinkHandler == nullptr)
326  return;
327 
328  const LinkIterator i = std::find_if(mLinks.begin(), mLinks.end(),
329  MouseOverLink(event.getX(), event.getY()));
330 
331  if (i != mLinks.end())
332  {
333  mLinkHandler->handleLink(i->link, &event);
334  event.consume();
335  }
336 }
337 
339 {
340  const LinkIterator i = std::find_if(mLinks.begin(), mLinks.end(),
341  MouseOverLink(event.getX(), event.getY()));
342 
343  mSelectedLink = (i != mLinks.end())
344  ? CAST_S32(i - mLinks.begin()) : -1;
345 }
346 
348 {
349  mSelectedLink = -1;
350 }
351 
352 void StaticBrowserBox::draw(Graphics *const graphics)
353 {
354  BLOCK_START("StaticBrowserBox::draw")
355  const ClipRect &cr = graphics->getTopClip();
356  mYStart = cr.y - cr.yOffset;
357  const int yEnd = mYStart + cr.height;
358  if (mYStart < 0)
359  mYStart = 0;
360 
361  if (mDimension.width != mWidth)
362  {
363  updateHeight();
364  reportAlways("browserbox resize in draw: %d, %d",
366  mWidth)
367  }
368 
369  if (mOpaque == Opaque_true)
370  {
371  graphics->setColor(mBackgroundColor);
372  graphics->fillRectangle(Rect(0, 0,
374  }
375 
376  if (mSelectedLink >= 0 &&
377  mSelectedLink < CAST_S32(mLinks.size()))
378  {
380  {
382  graphics->setColor(mHighlightColor);
383  graphics->fillRectangle(Rect(
384  link.x1,
385  link.y1,
386  link.x2 - link.x1,
387  link.y2 - link.y1));
388  }
389 
391  {
393  graphics->setColor(mHyperLinkColor);
394  graphics->drawLine(
395  link.x1,
396  link.y2,
397  link.x2,
398  link.y2);
399  }
400  }
401 
402  Font *const font = getFont();
403 
405  {
406  const LinePart &part = *i;
407  if (part.mY + 50 < mYStart)
408  continue;
409  if (part.mY > yEnd)
410  break;
411  if (part.mType == 0U)
412  {
413  if (part.mBold)
414  {
415  boldFont->drawString(graphics,
416  part.mColor,
417  part.mColor2,
418  part.mText,
419  part.mX, part.mY);
420  }
421  else
422  {
423  font->drawString(graphics,
424  part.mColor,
425  part.mColor2,
426  part.mText,
427  part.mX, part.mY);
428  }
429  }
430  else if (part.mImage != nullptr)
431  {
432  graphics->drawImage(part.mImage, part.mX, part.mY);
433  }
434  }
435 
436  BLOCK_END("StaticBrowserBox::draw")
437 }
438 
440 {
441  StaticBrowserBox::draw(graphics);
442 }
443 
445 {
446  unsigned int y = CAST_U32(mPadding);
447  int moreHeight = 0;
448  int link = 0;
449  bool bold = false;
450  const unsigned int wWidth = CAST_U32(mDimension.width - mPadding);
451  const Font *const font = getFont();
452  const int fontHeight = font->getHeight() + 2 * mItemPadding;
453  const int fontWidthMinus = font->getWidth("-");
454 
455  Color selColor[2] = {mForegroundColor, mForegroundColor2};
456  const Color textColor[2] = {mForegroundColor, mForegroundColor2};
457  mLineParts.clear();
458  uint32_t dataWidth = 0;
459 
460  if (mSeparator)
461  {
462  mSeparator = false;
463  mTextRows.pop_back();
464  }
465 
467  {
468  unsigned int x = CAST_U32(mPadding);
469  const std::string row = *(i);
470  int objects = 0;
471 
472  // Check for separator lines
473  if (row.find("---", 0) == 0)
474  {
475  const int dashWidth = fontWidthMinus;
476  for (x = CAST_U32(mPadding); x < wWidth; x ++)
477  {
478  mLineParts.push_back(LinePart(CAST_S32(x),
480  selColor[0], selColor[1], "-", false));
481  x += CAST_U32(CAST_S32(
482  dashWidth) - 2);
483  }
484 
485  y += CAST_U32(fontHeight);
486  continue;
487  }
488  else if (mEnableImages && row.find("~~~", 0) == 0)
489  {
490  std::string str = row.substr(3);
491  const size_t sz = str.size();
492  if (sz > 2 && str.substr(sz - 1) == "~")
493  str = str.substr(0, sz - 1);
494  Image *const img = Loader::getImage(str);
495  if (img != nullptr)
496  {
497  img->incRef();
498  mLineParts.push_back(LinePart(CAST_S32(x),
500  selColor[0], selColor[1], img));
501  y += CAST_U32(img->getHeight() + 2);
502  moreHeight += img->getHeight();
503  if (img->getWidth() + mPadding + 2 > CAST_S32(dataWidth))
504  dataWidth = img->getWidth() + 2 + mPadding;
505  }
506  continue;
507  }
508 
509  Color prevColor[2];
510  prevColor[0] = selColor[0];
511  prevColor[1] = selColor[1];
512  bold = false;
513 
514  for (size_t start = 0, end = std::string::npos;
515  start != std::string::npos;
516  start = end, end = std::string::npos)
517  {
518  size_t idx1 = end;
519  size_t idx2 = end;
520 
521  // "Tokenize" the string at control sequences
523  idx1 = row.find("##", start + 1);
524  if (start == 0 || mUseLinksAndUserColors)
525  {
526  // Check for color change in format "##x", x = [L,P,0..9]
527  if (row.find("##", start) == start && row.size() > start + 2)
528  {
529  const signed char c = row.at(start + 2);
530 
531  bool valid(false);
532  const Color col[2] =
533  {
536  c | 0x80), valid)
537  };
538 
539  if (c == '>')
540  {
541  selColor[0] = prevColor[0];
542  selColor[1] = prevColor[1];
543  }
544  else if (c == '<')
545  {
546  prevColor[0] = selColor[0];
547  prevColor[1] = selColor[1];
548  selColor[0] = col[0];
549  selColor[1] = col[1];
550  }
551  else if (c == 'B')
552  {
553  bold = true;
554  }
555  else if (c == 'b')
556  {
557  bold = false;
558  }
559  else if (valid)
560  {
561  selColor[0] = col[0];
562  selColor[1] = col[1];
563  }
564  else
565  {
566  switch (c)
567  {
568  case '0':
569  selColor[0] = mColors[0][ColorName::BLACK];
570  selColor[1] = mColors[1][ColorName::BLACK];
571  break;
572  case '1':
573  selColor[0] = mColors[0][ColorName::RED];
574  selColor[1] = mColors[1][ColorName::RED];
575  break;
576  case '2':
577  selColor[0] = mColors[0][ColorName::GREEN];
578  selColor[1] = mColors[1][ColorName::GREEN];
579  break;
580  case '3':
581  selColor[0] = mColors[0][ColorName::BLUE];
582  selColor[1] = mColors[1][ColorName::BLUE];
583  break;
584  case '4':
585  selColor[0] = mColors[0][ColorName::ORANGE];
586  selColor[1] = mColors[1][ColorName::ORANGE];
587  break;
588  case '5':
589  selColor[0] = mColors[0][ColorName::YELLOW];
590  selColor[1] = mColors[1][ColorName::YELLOW];
591  break;
592  case '6':
593  selColor[0] = mColors[0][ColorName::PINK];
594  selColor[1] = mColors[1][ColorName::PINK];
595  break;
596  case '7':
597  selColor[0] = mColors[0][ColorName::PURPLE];
598  selColor[1] = mColors[1][ColorName::PURPLE];
599  break;
600  case '8':
601  selColor[0] = mColors[0][ColorName::GRAY];
602  selColor[1] = mColors[1][ColorName::GRAY];
603  break;
604  case '9':
605  selColor[0] = mColors[0][ColorName::BROWN];
606  selColor[1] = mColors[1][ColorName::BROWN];
607  break;
608  default:
609  selColor[0] = textColor[0];
610  selColor[1] = textColor[1];
611  break;
612  }
613  }
614 
615  if (c == '<' && link < CAST_S32(mLinks.size()))
616  {
617  int size;
618  if (bold)
619  {
621  mLinks[CAST_SIZE(link)].caption) + 1;
622  }
623  else
624  {
625  size = font->getWidth(
626  mLinks[CAST_SIZE(link)].caption) + 1;
627  }
628 
629  BrowserLink &linkRef = mLinks[CAST_SIZE(
630  link)];
631  linkRef.x1 = CAST_S32(x);
632  linkRef.y1 = CAST_S32(y);
633  linkRef.x2 = linkRef.x1 + size;
634  linkRef.y2 = CAST_S32(y) + fontHeight - 1;
635  link++;
636  }
637 
638  start += 3;
639  if (start == row.size())
640  break;
641  }
642  }
643  if (mUseEmotes)
644  idx2 = row.find("%%", start + 1);
645  if (idx1 < idx2)
646  end = idx1;
647  else
648  end = idx2;
649  if (mUseEmotes)
650  {
651  // check for emote icons
652  if (row.size() > start + 2 && row.substr(start, 2) == "%%")
653  {
654  if (objects < 5)
655  {
656  const int cid = row.at(start + 2) - '0';
657  if (cid >= 0)
658  {
659  if (mEmotes != nullptr)
660  {
661  const size_t sz = mEmotes->size();
662  if (CAST_SIZE(cid) < sz)
663  {
664  Image *const img = mEmotes->get(
665  CAST_SIZE(cid));
666  if (img != nullptr)
667  {
668  mLineParts.push_back(LinePart(
669  CAST_S32(x),
671  selColor[0], selColor[1], img));
672  x += 18;
673  }
674  }
675  }
676  }
677  objects ++;
678  }
679 
680  start += 3;
681  if (start == row.size())
682  {
683  if (x > dataWidth)
684  dataWidth = x;
685  break;
686  }
687  }
688  }
689  const size_t len = (end == std::string::npos) ? end : end - start;
690 
691  if (start >= row.length())
692  break;
693 
694  std::string part = row.substr(start, len);
695 
696  mLineParts.push_back(LinePart(CAST_S32(x),
698  selColor[0], selColor[1], part.c_str(), bold));
699 
700  int width = 0;
701  if (bold)
702  width = boldFont->getWidth(part);
703  else
704  width = font->getWidth(part);
705 
706  x += CAST_U32(width);
707  if (x > dataWidth)
708  dataWidth = x;
709  }
710  y += CAST_U32(fontHeight);
711  }
712  mWidth = dataWidth + mPadding;
713  mHeight = CAST_S32(mTextRows.size())
714  * fontHeight + moreHeight + 2 * mPadding;
715  setSize(mWidth,
716  mHeight);
717 }
718 
719 std::string StaticBrowserBox::getTextAtPos(const int x,
720  const int y) const
721 {
722  int textX = 0;
723  int textY = 0;
724 
725  getAbsolutePosition(textX, textY);
726  if (x < textX || y < textY)
727  return std::string();
728 
729  textY = y - textY;
730  std::string str;
731  int lastY = 0;
732 
734  {
735  const LinePart &part = *i;
736  if (part.mY + 50 < mYStart)
737  continue;
738  if (part.mY > textY)
739  break;
740 
741  if (part.mY > lastY)
742  {
743  str = part.mText;
744  lastY = part.mY;
745  }
746  else
747  {
748  str.append(part.mText);
749  }
750  }
751 
752  return str;
753 }
754 
756  const Color &color2)
757 {
758  mForegroundColor = color1;
759  mForegroundColor2 = color2;
760 }
761 
763 {
764  if (mSelectedLink <= 0)
765  mSelectedLink = CAST_S32(mLinks.size()) - 1;
766  else
767  mSelectedLink --;
768 }
769 
771 {
772  mSelectedLink ++;
773  if (mSelectedLink >= static_cast<signed int>(mLinks.size()))
774  mSelectedLink = 0;
775 }
776 
778 {
779  if ((mLinkHandler == nullptr) ||
780  mSelectedLink < 0 ||
781  mSelectedLink >= static_cast<signed int>(mLinks.size()))
782  {
783  return;
784  }
785 
787  nullptr);
788 }
#define CAST_S8
Definition: cast.h:26
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
#define CAST_SIZE
Definition: cast.h:34
#define reportAlways(...)
Definition: checkutils.h:253
int yOffset
Definition: cliprect.h:127
Definition: color.h:76
Definition: font.h:90
int getHeight() const
Definition: font.cpp:362
int getWidth(const std::string &text) const
Definition: font.cpp:334
void drawString(Graphics *const graphics, Color col, const Color &col2, const std::string &text, const int x, const int y)
Definition: font.cpp:254
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
virtual void fillRectangle(const Rect &rectangle)=0
virtual void setColor(const Color &color)
Definition: graphics.h:320
virtual void drawLine(int x1, int y1, int x2, int y2)=0
ClipRect & getTopClip() const
Definition: graphics.h:281
void removeDragged(const Widget *const widget)
Definition: gui.cpp:1162
Image * get(const size_type i) const
Definition: imageset.cpp:67
size_type size() const
Definition: imageset.h:73
int mX
Definition: linepart.h:93
unsigned char mType
Definition: linepart.h:98
int mY
Definition: linepart.h:94
bool mBold
Definition: linepart.h:100
Color mColor
Definition: linepart.h:95
Image * mImage
Definition: linepart.h:99
Color mColor2
Definition: linepart.h:96
std::string mText
Definition: linepart.h:97
virtual void handleLink(const std::string &link, MouseEvent *event)=0
int getX() const
Definition: mouseevent.h:127
int getY() const
Definition: mouseevent.h:138
const std::string getStr(const std::string &str)
Definition: podict.cpp:45
Definition: rect.h:74
int y
Definition: rect.h:214
int width
Definition: rect.h:219
int height
Definition: rect.h:224
virtual void decRef()
Definition: resource.cpp:50
int getOption(const std::string &name) const
Definition: skin.h:106
int getPadding() const
Definition: skin.h:100
void addRow(const std::string &row, const bool atTop)
Links::iterator LinkIterator
void setForegroundColorAll(const Color &color1, const Color &color2)
std::list< int > mTextRowLinksCount
void mouseExited(MouseEvent &event)
void mouseMoved(MouseEvent &event)
unsigned int mNewLinePadding
static ImageSet * mEmotes
Color mColors[2][ColorName::COLORS_MAX]
StaticBrowserBox(const Widget2 *const widget, const Opaque opaque, const std::string &skin)
unsigned int mHighlightMode
LinkHandler * mLinkHandler
LinePartList::const_iterator LinePartCIter
void draw(Graphics *const graphics)
void mousePressed(MouseEvent &event)
LinePartList mLineParts
std::string getTextAtPos(const int x, const int y) const
void addImage(const std::string &path)
TextRows::const_iterator TextRowCIter
void addSeparator(const std::string &row)
void safeDraw(Graphics *const graphics)
void setLinkHandler(LinkHandler *linkHandler)
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
const Color & getThemeCharColor(const signed char c, bool &valid) const A_INLINE
Definition: widget2.h:52
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 setFocusable(const bool focusable)
Definition: widget.cpp:192
void setWidth(const int width)
Definition: widget.cpp:133
void setSize(const int width, const int height)
Definition: widget.cpp:367
virtual void getAbsolutePosition(int &x, int &y) const
Definition: widget.cpp:312
Rect mDimension
Definition: widget.h:1101
Color mBackgroundColor
Definition: widget.h:1091
bool mAllowLogic
Definition: widget.h:1160
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:292
void setHeight(const int height)
Definition: widget.cpp:140
Font * getFont() const
Definition: widget.cpp:331
int getWidth() const
Definition: widget.h:221
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
Gui * gui
Definition: gui.cpp:111
Font * boldFont
Definition: gui.cpp:112
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
void replaceKeys(std::string &data)
void replaceVars(std::string &data)
std::string replaceLinkCommands(const std::string &link)
void replaceTabs(std::string &data)
int size()
Definition: emotedb.cpp:306
Image * getImage(const std::string &idPath)
Definition: imageloader.cpp:86
ImageSet * getImageSet(const std::string &imagePath, const int w, const int h)
const bool Opaque_true
Definition: opaque.h:30
bool Opaque
Definition: opaque.h:30
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
PoDict * translator
Definition: podict.cpp:28
#define STD_MOVE(var)
Definition: stdmove.h:28
std::string strprintf(const char *const format,...)
std::string encodeLinkText(std::string data)
Theme * theme
Definition: theme.cpp:62
static Color readColor(const std::string &description)
Definition: theme.cpp:697