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