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-2017 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)),
80  mHyperLinkColor(getThemeColor(ThemeColorId::HYPERLINK)),
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  mSkin = theme->load(skin, "browserbox.xml");
99  if (mInstances == 0)
100  {
102  "graphics/sprites/chatemotes.png", 17, 18);
103  }
104  mInstances ++;
105 
106  if (mSkin != nullptr)
107  {
110  mSkin->getOption("newLinePadding", 15));
111  mItemPadding = mSkin->getOption("itemPadding");
112  if (mSkin->getOption("highlightBackground") != 0)
114  if (mSkin->getOption("highlightUnderline") != 0)
116  }
117 
118  readColor(BLACK);
119  readColor(RED);
120  readColor(GREEN);
121  readColor(BLUE);
122  readColor(ORANGE);
123  readColor(YELLOW);
124  readColor(PINK);
125  readColor(PURPLE);
126  readColor(GRAY);
127  readColor(BROWN);
128 
131 }
132 
134 {
135  if (gui != nullptr)
136  gui->removeDragged(this);
137 
138  if (theme != nullptr)
139  {
140  theme->unload(mSkin);
141  mSkin = nullptr;
142  }
143 
144  mInstances --;
145  if (mInstances == 0)
146  {
147  if (mEmotes != nullptr)
148  {
149  mEmotes->decRef();
150  mEmotes = nullptr;
151  }
152  }
153 }
154 
156 {
157  mLinkHandler = linkHandler;
158 }
159 
160 void StaticBrowserBox::addSeparator(const std::string &row)
161 {
162  if (mSeparator)
163  return;
164  addRow(row, false);
165  mSeparator = true;
166 }
167 
168 void StaticBrowserBox::addRow(const std::string &row,
169  const bool atTop)
170 {
171  std::string tmp = row;
172  std::string newRow;
173  size_t idx1;
174  const Font *const font = getFont();
175  int linksCount = 0;
176 
177  if (getWidth() < 0)
178  return;
179 
180  mSeparator = false;
181 
182  if (mProcessVars)
183  {
185  }
186 
187  // Use links and user defined colors
189  {
190  BrowserLink bLink;
191 
192  // Check for links in format "@@link|[email protected]@"
193  const uint32_t sz = CAST_U32(mTextRows.size());
194 
195  if (mEnableKeys)
196  {
198  }
199 
200  idx1 = tmp.find("@@");
201  while (idx1 != std::string::npos)
202  {
203  const size_t idx2 = tmp.find('|', idx1);
204  const size_t idx3 = tmp.find("@@", idx2);
205 
206  if (idx2 == std::string::npos || idx3 == std::string::npos)
207  break;
208  bLink.link = tmp.substr(idx1 + 2, idx2 - (idx1 + 2));
209  bLink.caption = tmp.substr(idx2 + 1, idx3 - (idx2 + 1));
210  bLink.y1 = CAST_S32(sz) * font->getHeight();
211  bLink.y2 = bLink.y1 + font->getHeight();
212  if (bLink.caption.empty())
213  {
215  bLink.link);
216  if (translator != nullptr)
217  bLink.caption = translator->getStr(bLink.caption);
218  }
219 
220  newRow.append(tmp.substr(0, idx1));
221 
222  std::string tmp2 = newRow;
223  idx1 = tmp2.find("##");
224  while (idx1 != std::string::npos)
225  {
226  tmp2.erase(idx1, 3);
227  idx1 = tmp2.find("##");
228  }
229  bLink.x1 = font->getWidth(tmp2) - 1;
230  bLink.x2 = bLink.x1 + font->getWidth(bLink.caption) + 1;
231 
232  if (atTop)
233  mLinks.insert(mLinks.begin(), bLink);
234  else
235  mLinks.push_back(bLink);
236  linksCount ++;
237 
238  newRow.append("##<").append(bLink.caption);
239 
240  tmp.erase(0, idx3 + 2);
241  if (!tmp.empty())
242  newRow.append("##>");
243 
244  idx1 = tmp.find("@@");
245  }
246 
247  newRow.append(tmp);
248  }
249  // Don't use links and user defined colors
250  else
251  {
252  newRow = row;
253  }
254 
255  if (mEnableTabs)
256  {
258  }
259 
260  if (atTop)
261  {
262  mTextRows.push_front(newRow);
263  mTextRowLinksCount.push_front(linksCount);
264  }
265  else
266  {
267  mTextRows.push_back(newRow);
268  mTextRowLinksCount.push_back(linksCount);
269  }
270 
271  std::string plain = STD_MOVE(newRow);
272  // workaround if used only one string started from bold
273  // width for this string can be calculated wrong
274  // this workaround fix width if string start from bold sign
275  const bool startBold = (plain.find("##B") == 0);
276  for (idx1 = plain.find("##");
277  idx1 != std::string::npos;
278  idx1 = plain.find("##"))
279  {
280  plain.erase(idx1, 3);
281  }
282 
283  // Adjust the StaticBrowserBox size. This need only for implementing "---"
284  const int w = startBold ?
285  boldFont->getWidth(plain) : font->getWidth(plain) + 2 * mPadding;
286  if (w > getWidth())
287  setWidth(w);
288 }
289 
290 void StaticBrowserBox::addRow(const std::string &cmd,
291  const char *const text)
292 {
293  addRow(strprintf("@@%s|%[email protected]@", encodeLinkText(cmd).c_str(),
294  encodeLinkText(text).c_str()));
295 }
296 
297 void StaticBrowserBox::addImage(const std::string &path)
298 {
299  if (!mEnableImages)
300  return;
301 
302  mTextRows.push_back("~~~" + path);
303  mTextRowLinksCount.push_back(0);
304 }
305 
307 {
308  mTextRows.clear();
309  mTextRowLinksCount.clear();
310  mLinks.clear();
311  setWidth(0);
312  setHeight(0);
313  mSelectedLink = -1;
314 }
315 
317 {
318  if (mLinkHandler == nullptr)
319  return;
320 
321  const LinkIterator i = std::find_if(mLinks.begin(), mLinks.end(),
322  MouseOverLink(event.getX(), event.getY()));
323 
324  if (i != mLinks.end())
325  {
326  mLinkHandler->handleLink(i->link, &event);
327  event.consume();
328  }
329 }
330 
332 {
333  const LinkIterator i = std::find_if(mLinks.begin(), mLinks.end(),
334  MouseOverLink(event.getX(), event.getY()));
335 
336  mSelectedLink = (i != mLinks.end())
337  ? CAST_S32(i - mLinks.begin()) : -1;
338 }
339 
341 {
342  mSelectedLink = -1;
343 }
344 
345 void StaticBrowserBox::draw(Graphics *const graphics)
346 {
347  BLOCK_START("StaticBrowserBox::draw")
348  const ClipRect &cr = graphics->getTopClip();
349  mYStart = cr.y - cr.yOffset;
350  const int yEnd = mYStart + cr.height;
351  if (mYStart < 0)
352  mYStart = 0;
353 
354  if (mDimension.width != mWidth)
355  {
356  updateHeight();
357  reportAlways("browserbox resize in draw: %d, %d",
359  mWidth);
360  }
361 
362  if (mOpaque == Opaque_true)
363  {
364  graphics->setColor(mBackgroundColor);
365  graphics->fillRectangle(Rect(0, 0,
367  }
368 
369  if (mSelectedLink >= 0 &&
370  mSelectedLink < CAST_S32(mLinks.size()))
371  {
373  {
375  graphics->setColor(mHighlightColor);
376  graphics->fillRectangle(Rect(
377  link.x1,
378  link.y1,
379  link.x2 - link.x1,
380  link.y2 - link.y1));
381  }
382 
384  {
386  graphics->setColor(mHyperLinkColor);
387  graphics->drawLine(
388  link.x1,
389  link.y2,
390  link.x2,
391  link.y2);
392  }
393  }
394 
395  Font *const font = getFont();
396 
398  {
399  const LinePart &part = *i;
400  if (part.mY + 50 < mYStart)
401  continue;
402  if (part.mY > yEnd)
403  break;
404  if (part.mType == 0u)
405  {
406  if (part.mBold)
407  {
408  boldFont->drawString(graphics,
409  part.mColor,
410  part.mColor2,
411  part.mText,
412  part.mX, part.mY);
413  }
414  else
415  {
416  font->drawString(graphics,
417  part.mColor,
418  part.mColor2,
419  part.mText,
420  part.mX, part.mY);
421  }
422  }
423  else if (part.mImage != nullptr)
424  {
425  graphics->drawImage(part.mImage, part.mX, part.mY);
426  }
427  }
428 
429  BLOCK_END("StaticBrowserBox::draw")
430 }
431 
433 {
434  StaticBrowserBox::draw(graphics);
435 }
436 
438 {
439  unsigned int y = CAST_U32(mPadding);
440  int moreHeight = 0;
441  int link = 0;
442  bool bold = false;
443  const unsigned int wWidth = CAST_U32(mDimension.width - mPadding);
444  const Font *const font = getFont();
445  const int fontHeight = font->getHeight() + 2 * mItemPadding;
446  const int fontWidthMinus = font->getWidth("-");
447 
448  Color selColor[2] = {mForegroundColor, mForegroundColor2};
449  const Color textColor[2] = {mForegroundColor, mForegroundColor2};
450  mLineParts.clear();
451  uint32_t dataWidth = 0;
452 
453  if (mSeparator)
454  {
455  mSeparator = false;
456  mTextRows.pop_back();
457  }
458 
460  {
461  unsigned int x = CAST_U32(mPadding);
462  const std::string row = *(i);
463  int objects = 0;
464 
465  // Check for separator lines
466  if (row.find("---", 0) == 0)
467  {
468  const int dashWidth = fontWidthMinus;
469  for (x = CAST_U32(mPadding); x < wWidth; x ++)
470  {
471  mLineParts.push_back(LinePart(CAST_S32(x),
472  CAST_S32(y) + mItemPadding,
473  selColor[0], selColor[1], "-", false));
474  x += CAST_U32(CAST_S32(
475  dashWidth) - 2);
476  }
477 
478  y += CAST_U32(fontHeight);
479  continue;
480  }
481  else if (mEnableImages && row.find("~~~", 0) == 0)
482  {
483  std::string str = row.substr(3);
484  const size_t sz = str.size();
485  if (sz > 2 && str.substr(sz - 1) == "~")
486  str = str.substr(0, sz - 1);
487  Image *const img = Loader::getImage(str);
488  if (img != nullptr)
489  {
490  img->incRef();
491  mLineParts.push_back(LinePart(CAST_S32(x),
492  CAST_S32(y) + mItemPadding,
493  selColor[0], selColor[1], img));
494  y += CAST_U32(img->getHeight() + 2);
495  moreHeight += img->getHeight();
496  if (img->getWidth() + mPadding + 2 > CAST_S32(dataWidth))
497  dataWidth = img->getWidth() + 2 + mPadding;
498  }
499  continue;
500  }
501 
502  Color prevColor[2];
503  prevColor[0] = selColor[0];
504  prevColor[1] = selColor[1];
505  bold = false;
506 
507  for (size_t start = 0, end = std::string::npos;
508  start != std::string::npos;
509  start = end, end = std::string::npos)
510  {
511  size_t idx1 = end;
512  size_t idx2 = end;
513 
514  // "Tokenize" the string at control sequences
516  idx1 = row.find("##", start + 1);
517  if (start == 0 || mUseLinksAndUserColors)
518  {
519  // Check for color change in format "##x", x = [L,P,0..9]
520  if (row.find("##", start) == start && row.size() > start + 2)
521  {
522  const signed char c = row.at(start + 2);
523 
524  bool valid(false);
525  const Color col[2] =
526  {
527  getThemeCharColor(c, valid),
529  c | 0x80), valid)
530  };
531 
532  if (c == '>')
533  {
534  selColor[0] = prevColor[0];
535  selColor[1] = prevColor[1];
536  }
537  else if (c == '<')
538  {
539  prevColor[0] = selColor[0];
540  prevColor[1] = selColor[1];
541  selColor[0] = col[0];
542  selColor[1] = col[1];
543  }
544  else if (c == 'B')
545  {
546  bold = true;
547  }
548  else if (c == 'b')
549  {
550  bold = false;
551  }
552  else if (valid)
553  {
554  selColor[0] = col[0];
555  selColor[1] = col[1];
556  }
557  else
558  {
559  switch (c)
560  {
561  case '0':
562  selColor[0] = mColors[0][ColorName::BLACK];
563  selColor[1] = mColors[1][ColorName::BLACK];
564  break;
565  case '1':
566  selColor[0] = mColors[0][ColorName::RED];
567  selColor[1] = mColors[1][ColorName::RED];
568  break;
569  case '2':
570  selColor[0] = mColors[0][ColorName::GREEN];
571  selColor[1] = mColors[1][ColorName::GREEN];
572  break;
573  case '3':
574  selColor[0] = mColors[0][ColorName::BLUE];
575  selColor[1] = mColors[1][ColorName::BLUE];
576  break;
577  case '4':
578  selColor[0] = mColors[0][ColorName::ORANGE];
579  selColor[1] = mColors[1][ColorName::ORANGE];
580  break;
581  case '5':
582  selColor[0] = mColors[0][ColorName::YELLOW];
583  selColor[1] = mColors[1][ColorName::YELLOW];
584  break;
585  case '6':
586  selColor[0] = mColors[0][ColorName::PINK];
587  selColor[1] = mColors[1][ColorName::PINK];
588  break;
589  case '7':
590  selColor[0] = mColors[0][ColorName::PURPLE];
591  selColor[1] = mColors[1][ColorName::PURPLE];
592  break;
593  case '8':
594  selColor[0] = mColors[0][ColorName::GRAY];
595  selColor[1] = mColors[1][ColorName::GRAY];
596  break;
597  case '9':
598  selColor[0] = mColors[0][ColorName::BROWN];
599  selColor[1] = mColors[1][ColorName::BROWN];
600  break;
601  default:
602  selColor[0] = textColor[0];
603  selColor[1] = textColor[1];
604  break;
605  }
606  }
607 
608  if (c == '<' && link < CAST_S32(mLinks.size()))
609  {
610  int size;
611  if (bold)
612  {
613  size = boldFont->getWidth(
614  mLinks[CAST_SIZE(link)].caption) + 1;
615  }
616  else
617  {
618  size = font->getWidth(
619  mLinks[CAST_SIZE(link)].caption) + 1;
620  }
621 
622  BrowserLink &linkRef = mLinks[CAST_SIZE(
623  link)];
624  linkRef.x1 = CAST_S32(x);
625  linkRef.y1 = CAST_S32(y);
626  linkRef.x2 = linkRef.x1 + size;
627  linkRef.y2 = CAST_S32(y) + fontHeight - 1;
628  link++;
629  }
630 
631  start += 3;
632  if (start == row.size())
633  break;
634  }
635  }
636  if (mUseEmotes)
637  idx2 = row.find("%%", start + 1);
638  if (idx1 < idx2)
639  end = idx1;
640  else
641  end = idx2;
642  if (mUseEmotes)
643  {
644  // check for emote icons
645  if (row.size() > start + 2 && row.substr(start, 2) == "%%")
646  {
647  if (objects < 5)
648  {
649  const int cid = row.at(start + 2) - '0';
650  if (cid >= 0)
651  {
652  if (mEmotes != nullptr)
653  {
654  const size_t sz = mEmotes->size();
655  if (CAST_SIZE(cid) < sz)
656  {
657  Image *const img = mEmotes->get(
658  CAST_SIZE(cid));
659  if (img != nullptr)
660  {
661  mLineParts.push_back(LinePart(
662  CAST_S32(x),
663  CAST_S32(y) + mItemPadding,
664  selColor[0], selColor[1], img));
665  x += 18;
666  }
667  }
668  }
669  }
670  objects ++;
671  }
672 
673  start += 3;
674  if (start == row.size())
675  {
676  if (x > dataWidth)
677  dataWidth = x;
678  break;
679  }
680  }
681  }
682  const size_t len = (end == std::string::npos) ? end : end - start;
683 
684  if (start >= row.length())
685  break;
686 
687  std::string part = row.substr(start, len);
688 
689  mLineParts.push_back(LinePart(CAST_S32(x),
690  CAST_S32(y) + mItemPadding,
691  selColor[0], selColor[1], part.c_str(), bold));
692 
693  int width = 0;
694  if (bold)
695  width = boldFont->getWidth(part);
696  else
697  width = font->getWidth(part);
698 
699  x += CAST_U32(width);
700  if (x > dataWidth)
701  dataWidth = x;
702  }
703  y += CAST_U32(fontHeight);
704  }
705  mWidth = dataWidth + mPadding;
706  mHeight = CAST_S32(mTextRows.size())
707  * fontHeight + moreHeight + 2 * mPadding;
708  setSize(mWidth,
709  mHeight);
710 }
711 
712 std::string StaticBrowserBox::getTextAtPos(const int x,
713  const int y) const
714 {
715  int textX = 0;
716  int textY = 0;
717 
718  getAbsolutePosition(textX, textY);
719  if (x < textX || y < textY)
720  return std::string();
721 
722  textY = y - textY;
723  std::string str;
724  int lastY = 0;
725 
727  {
728  const LinePart &part = *i;
729  if (part.mY + 50 < mYStart)
730  continue;
731  if (part.mY > textY)
732  break;
733 
734  if (part.mY > lastY)
735  {
736  str = part.mText;
737  lastY = part.mY;
738  }
739  else
740  {
741  str.append(part.mText);
742  }
743  }
744 
745  return str;
746 }
747 
749  const Color &color2)
750 {
751  mForegroundColor = color1;
752  mForegroundColor2 = color2;
753 }
754 
756 {
757  if (mSelectedLink <= 0)
758  mSelectedLink = CAST_S32(mLinks.size()) - 1;
759  else
760  mSelectedLink --;
761 }
762 
764 {
765  mSelectedLink ++;
766  if (mSelectedLink >= static_cast<signed int>(mLinks.size()))
767  mSelectedLink = 0;
768 }
769 
771 {
772  if ((mLinkHandler == nullptr) ||
773  mSelectedLink < 0 ||
774  mSelectedLink >= static_cast<signed int>(mLinks.size()))
775  {
776  return;
777  }
778 
780  nullptr);
781 }
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
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha=255U) const A_INLINE
Definition: widget2.h:44
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)
LinePartList mLineParts
#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:69
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:906
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
Skin * load(const std::string &filename, const std::string &filename2, const bool full=true, const std::string &defaultPath=getThemePath())
Definition: theme.cpp:178
virtual void fillRectangle(const Rect &rectangle)=0
Theme * theme
Definition: theme.cpp:61
#define A_UNUSED
Definition: localconsts.h:171
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:1144
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
int getX() const
Definition: mouseevent.h:124
void replaceTabs(std::string &data)
void draw(Graphics *const graphics)
int getHeight() const
Definition: font.cpp:360
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
int getHeight() const A_INLINE
Definition: image.h:122
Color mColors[2][ColorName::COLORS_MAX]
void addRow(const std::string &row, const bool atTop=false)