ManaPlus
button.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  *
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 
24 /* _______ __ __ __ ______ __ __ _______ __ __
25  * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
26  * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
27  * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
28  * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
29  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
30  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
31  *
32  * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
33  *
34  *
35  * Per Larsson a.k.a finalman
36  * Olof Naessén a.k.a jansem/yakslem
37  *
38  * Visit: http://guichan.sourceforge.net
39  *
40  * License: (BSD)
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  * notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  * notice, this list of conditions and the following disclaimer in
48  * the documentation and/or other materials provided with the
49  * distribution.
50  * 3. Neither the name of Guichan nor the names of its contributors may
51  * be used to endorse or promote products derived from this software
52  * without specific prior written permission.
53  *
54  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
55  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
56  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
57  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
58  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
59  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
60  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
61  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
62  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
63  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65  */
66 
67 #include "gui/widgets/button.h"
68 
69 #include "settings.h"
70 
71 #include "resources/imageset.h"
72 #include "resources/imagerect.h"
73 
74 #include "resources/image/image.h"
75 
76 #include "gui/gui.h"
77 #include "gui/skin.h"
78 
79 #include "gui/fonts/font.h"
80 
81 #include "render/renderers.h"
82 
84 
85 #include "utils/delete2.h"
86 
87 #include "debug.h"
88 
89 float Button::mAlpha = 1.0;
90 
91 static std::string const data[Button::BUTTON_COUNT] =
92 {
93  ".xml",
94  "_highlighted.xml",
95  "_pressed.xml",
96  "_disabled.xml"
97 };
98 
99 Button::Button(const Widget2 *const widget,
100  const std::string &restrict skinName) :
101  Widget(widget),
102  MouseListener(),
103  KeyListener(),
104  FocusListener(),
105  WidgetListener(),
106  mSkin(),
107  mCaption(),
108  mDescription(),
109  mSkinName(skinName),
110  mTextChunk(),
111  mVertexes2(new ImageCollection),
112  mEnabledColor(getThemeColor(ThemeColorId::BUTTON, 255U)),
113  mEnabledColor2(getThemeColor(ThemeColorId::BUTTON_OUTLINE, 255U)),
114  mDisabledColor(getThemeColor(ThemeColorId::BUTTON_DISABLED, 255U)),
115  mDisabledColor2(getThemeColor(ThemeColorId::BUTTON_DISABLED_OUTLINE,
116  255U)),
117  mHighlightedColor(getThemeColor(ThemeColorId::BUTTON_HIGHLIGHTED, 255U)),
118  mHighlightedColor2(getThemeColor(
119  ThemeColorId::BUTTON_HIGHLIGHTED_OUTLINE, 255U)),
120  mPressedColor(getThemeColor(ThemeColorId::BUTTON_PRESSED, 255U)),
121  mPressedColor2(getThemeColor(ThemeColorId::BUTTON_PRESSED_OUTLINE, 255U)),
122  mImages(nullptr),
123  mImageSet(nullptr),
124  mAlignment(Graphics::CENTER),
125  mClickCount(0),
126  mSpacing(),
127  mTag(0),
128  mMode(0),
129  mXOffset(0),
130  mYOffset(0),
131  mImageWidth(0),
132  mImageHeight(0),
133  mHasMouse(false),
134  mKeyPressed(false),
135  mMousePressed(false),
136  mStick(false),
137  mPressed(false),
138  mTextChanged(true)
139 {
140  init();
141  adjustSize();
142 }
143 
144 Button::Button(const Widget2 *const widget,
145  const std::string &restrict caption,
146  const std::string &restrict actionEventId,
147  const std::string &restrict skinName,
148  ActionListener *const listener) :
149  Widget(widget),
150  MouseListener(),
151  KeyListener(),
152  FocusListener(),
153  WidgetListener(),
154  mSkin(),
155  mCaption(caption),
156  mDescription(),
157  mSkinName(skinName),
158  mTextChunk(),
159  mVertexes2(new ImageCollection),
160  mEnabledColor(getThemeColor(ThemeColorId::BUTTON, 255U)),
161  mEnabledColor2(getThemeColor(ThemeColorId::BUTTON_OUTLINE, 255U)),
162  mDisabledColor(getThemeColor(ThemeColorId::BUTTON_DISABLED, 255U)),
163  mDisabledColor2(getThemeColor(ThemeColorId::BUTTON_DISABLED_OUTLINE,
164  255U)),
165  mHighlightedColor(getThemeColor(ThemeColorId::BUTTON_HIGHLIGHTED, 255U)),
166  mHighlightedColor2(getThemeColor(
167  ThemeColorId::BUTTON_HIGHLIGHTED_OUTLINE, 255U)),
168  mPressedColor(getThemeColor(ThemeColorId::BUTTON_PRESSED, 255U)),
169  mPressedColor2(getThemeColor(ThemeColorId::BUTTON_PRESSED_OUTLINE, 255U)),
170  mImages(nullptr),
171  mImageSet(nullptr),
172  mAlignment(Graphics::CENTER),
173  mClickCount(0),
174  mSpacing(),
175  mTag(0),
176  mMode(0),
177  mXOffset(0),
178  mYOffset(0),
179  mImageWidth(0),
180  mImageHeight(0),
181  mHasMouse(false),
182  mKeyPressed(false),
183  mMousePressed(false),
184  mStick(false),
185  mPressed(false),
186  mTextChanged(true)
187 {
188  init();
189  adjustSize();
190  setActionEventId(actionEventId);
191 
192  if (listener != nullptr)
194 }
195 
196 Button::Button(const Widget2 *const widget,
197  const std::string &restrict caption,
198  const std::string &restrict imageName,
199  const int imageWidth,
200  const int imageHeight,
201  const std::string &restrict actionEventId,
202  const std::string &restrict skinName,
203  ActionListener *const listener) :
204  Widget(widget),
205  MouseListener(),
206  KeyListener(),
207  FocusListener(),
208  WidgetListener(),
209  mSkin(),
210  mCaption(caption),
211  mDescription(),
212  mSkinName(skinName),
213  mTextChunk(),
214  mVertexes2(new ImageCollection),
215  mEnabledColor(getThemeColor(ThemeColorId::BUTTON, 255U)),
216  mEnabledColor2(getThemeColor(ThemeColorId::BUTTON_OUTLINE, 255U)),
217  mDisabledColor(getThemeColor(ThemeColorId::BUTTON_DISABLED, 255U)),
218  mDisabledColor2(getThemeColor(ThemeColorId::BUTTON_DISABLED_OUTLINE,
219  255U)),
220  mHighlightedColor(getThemeColor(ThemeColorId::BUTTON_HIGHLIGHTED, 255U)),
221  mHighlightedColor2(getThemeColor(
222  ThemeColorId::BUTTON_HIGHLIGHTED_OUTLINE, 255U)),
223  mPressedColor(getThemeColor(ThemeColorId::BUTTON_PRESSED, 255U)),
224  mPressedColor2(getThemeColor(ThemeColorId::BUTTON_PRESSED_OUTLINE, 255U)),
225  mImages(nullptr),
226  mImageSet(nullptr),
227  mAlignment(Graphics::CENTER),
228  mClickCount(0),
229  mSpacing(),
230  mTag(0),
231  mMode(0),
232  mXOffset(0),
233  mYOffset(0),
234  mImageWidth(imageWidth),
235  mImageHeight(imageHeight),
236  mHasMouse(false),
237  mKeyPressed(false),
238  mMousePressed(false),
239  mStick(false),
240  mPressed(false),
241  mTextChanged(true)
242 {
243  init();
244  loadImageSet(imageName);
245  adjustSize();
246  setActionEventId(actionEventId);
247 
248  if (listener != nullptr)
250 }
251 
252 Button::Button(const Widget2 *const widget,
253  const std::string &restrict imageName,
254  const int imageWidth,
255  const int imageHeight,
256  const std::string &restrict actionEventId,
257  const std::string &restrict skinName,
258  ActionListener *const listener) :
259  Widget(widget),
260  MouseListener(),
261  KeyListener(),
262  FocusListener(),
263  WidgetListener(),
264  mSkin(),
265  mCaption(),
266  mDescription(),
267  mSkinName(skinName),
268  mTextChunk(),
269  mVertexes2(new ImageCollection),
270  mEnabledColor(getThemeColor(ThemeColorId::BUTTON, 255U)),
271  mEnabledColor2(getThemeColor(ThemeColorId::BUTTON_OUTLINE, 255U)),
272  mDisabledColor(getThemeColor(ThemeColorId::BUTTON_DISABLED, 255U)),
273  mDisabledColor2(getThemeColor(ThemeColorId::BUTTON_DISABLED_OUTLINE,
274  255U)),
275  mHighlightedColor(getThemeColor(ThemeColorId::BUTTON_HIGHLIGHTED, 255U)),
276  mHighlightedColor2(getThemeColor(
277  ThemeColorId::BUTTON_HIGHLIGHTED_OUTLINE, 255U)),
278  mPressedColor(getThemeColor(ThemeColorId::BUTTON_PRESSED, 255U)),
279  mPressedColor2(getThemeColor(ThemeColorId::BUTTON_PRESSED_OUTLINE, 255U)),
280  mImages(nullptr),
281  mImageSet(nullptr),
282  mAlignment(Graphics::CENTER),
283  mClickCount(0),
284  mSpacing(),
285  mTag(0),
286  mMode(0),
287  mXOffset(0),
288  mYOffset(0),
289  mImageWidth(imageWidth),
290  mImageHeight(imageHeight),
291  mHasMouse(false),
292  mKeyPressed(false),
293  mMousePressed(false),
294  mStick(false),
295  mPressed(false),
296  mTextChanged(true)
297 {
298  init();
299  loadImageSet(imageName);
300  adjustSize();
301  setActionEventId(actionEventId);
302 
303  if (listener != nullptr)
305 }
306 
308 {
309  mAllowLogic = false;
310  addMouseListener(this);
311  addKeyListener(this);
312  addFocusListener(this);
313  addWidgetListener(this);
314 
315  setFocusable(true);
316  setFrameSize(0);
317 
318  if (theme != nullptr)
319  {
320  for (int mode = 0; mode < BUTTON_COUNT; mode ++)
321  {
322  Skin *const skin = theme->load(mSkinName + data[mode],
323  "button.xml",
324  true,
326  if (skin != nullptr)
327  {
328  mSkin[mode] = skin;
329  mSpacing[mode] = skin->getOption("spacing");
330  }
331  }
332  }
333 
334  updateAlpha();
335 }
336 
338 {
339  if (mWindow != nullptr)
341 
342  if (gui != nullptr)
343  gui->removeDragged(this);
344 
345  if (theme != nullptr)
346  {
347  for (int mode = 0; mode < BUTTON_COUNT; mode ++)
348  theme->unload(mSkin[mode]);
349  }
351  if (mImageSet != nullptr)
352  {
353  mImageSet->decRef();
354  mImageSet = nullptr;
355  }
356  if (mImages != nullptr)
357  {
358  for (int f = 0; f < BUTTON_COUNT; f ++)
359  mImages[f] = nullptr;
360  delete [] mImages;
361  mImages = nullptr;
362  }
364 }
365 
366 void Button::loadImage(const std::string &imageName)
367 {
368  if (mImageSet != nullptr)
369  {
370  mImageSet->decRef();
371  mImageSet = nullptr;
372  }
373  Image *const image = Theme::getImageFromThemeXml(imageName, "");
374  mImages = new Image*[BUTTON_COUNT];
375  for (int f = 0; f < BUTTON_COUNT; f ++)
376  mImages[f] = image;
377 }
378 
379 void Button::setImage(Image *const image)
380 {
381  if (image == nullptr)
382  return;
383  if (mImageSet != nullptr)
384  {
385  mImageSet->decRef();
386  mImageSet = nullptr;
387  }
388  mImageWidth = image->getWidth();
389  mImageHeight = image->getHeight();
390  mImages = new Image*[BUTTON_COUNT];
391  for (int f = 0; f < BUTTON_COUNT; f ++)
392  mImages[f] = image;
393 }
394 
395 void Button::loadImageSet(const std::string &imageName)
396 {
397  if (mImageSet != nullptr)
398  {
399  mImageSet->decRef();
400  mImageSet = nullptr;
401  }
404  if (mImageSet == nullptr)
405  return;
406  mImages = new Image*[BUTTON_COUNT];
407  mImages[0] = nullptr;
408  for (size_t f = 0; f < BUTTON_COUNT; f ++)
409  {
410  Image *const img = mImageSet->get(f);
411  if (img != nullptr)
412  mImages[f] = img;
413  else
414  mImages[f] = mImages[0];
415  }
416 }
417 
419 {
420  const float alpha = std::max(settings.guiAlpha,
422 
423  if (mAlpha != alpha)
424  {
425  mAlpha = alpha;
426  for (int mode = 0; mode < BUTTON_COUNT; mode ++)
427  {
428  for (int a = 0; a < 9; a ++)
429  {
430  Skin *const skin = mSkin[mode];
431  if (skin != nullptr)
432  {
433  const ImageRect &rect = skin->getBorder();
434  Image *const image = rect.grid[a];
435  if (image != nullptr)
436  image->setAlpha(mAlpha);
437  }
438  }
439  }
440  }
441 }
442 
443 void Button::draw(Graphics *const graphics)
444 {
445  BLOCK_START("Button::draw")
446  int mode;
447 
448  if (!isEnabled())
449  mode = BUTTON_DISABLED;
450  else if (isPressed2())
451  mode = BUTTON_PRESSED;
452  else if (mHasMouse)
453  mode = BUTTON_HIGHLIGHTED;
454  else
455  mode = BUTTON_STANDARD;
456 
457  const Skin *const skin = mSkin[mode];
458  if (skin == nullptr)
459  {
460  BLOCK_END("Button::draw")
461  return;
462  }
463 
464  updateAlpha();
465 
466  bool recalc = false;
467  if (mRedraw)
468  {
469  recalc = true;
470  }
471  else
472  {
473  // because we don't know where parent windows was moved,
474  // need recalc vertexes
475  ClipRect &rect = graphics->getTopClip();
476  if (rect.xOffset != mXOffset || rect.yOffset != mYOffset)
477  {
478  recalc = true;
479  mXOffset = rect.xOffset;
480  mYOffset = rect.yOffset;
481  }
482  else if (mMode != mode)
483  {
484  recalc = true;
485  mMode = mode;
486  }
487  else if (graphics->getRedraw())
488  {
489  recalc = true;
490  }
491  }
492 
493  const int padding = skin->getPadding();
494  const int spacing = mSpacing[mode];
495 
496  if (recalc)
497  mTextChanged = true;
498 
499  int imageX = 0;
500  int imageY = 0;
501  int textX = 0;
502  const Rect &rect = mDimension;
503  const int width = rect.width;
504  const int height = rect.height;
505  Font *const font = getFont();
506  int textY = height / 2 - font->getHeight() / 2;
507  if (mImages != nullptr)
508  imageY = height / 2 - mImageHeight / 2;
509 
510 // need move calculation from draw!!!
511 
512  switch (mAlignment)
513  {
514  default:
515  case Graphics::LEFT:
516  {
517  if (mImages != nullptr)
518  {
519  imageX = padding;
520  textX = padding + mImageWidth + spacing;
521  }
522  else
523  {
524  textX = padding;
525  }
526  break;
527  }
528  case Graphics::CENTER:
529  {
530  const int width1 = font->getWidth(mCaption);
531  if (mImages != nullptr)
532  {
533  const int w = width1 + mImageWidth + spacing;
534  imageX = (width - w) / 2;
535  textX = imageX + mImageWidth + spacing - width1 / 2;
536  }
537  else
538  {
539  textX = (width - width1) / 2;
540  }
541  break;
542  }
543  case Graphics::RIGHT:
544  {
545  const int width1 = font->getWidth(mCaption);
546  textX = width - width1 - padding;
547  imageX = textX - width1 - spacing;
548  break;
549  }
550  }
551 
552  if (recalc)
553  {
554  mRedraw = false;
555  mMode = mode;
556  mVertexes2->clear();
557  graphics->calcWindow(mVertexes2,
558  0, 0,
559  width, height,
560  skin->getBorder());
561 
562  if (mImages != nullptr)
563  {
564  if (isPressed())
565  {
566  graphics->calcTileCollection(mVertexes2,
567  mImages[mode],
568  imageX + 1, imageY + 1);
569  }
570  else
571  {
572  graphics->calcTileCollection(mVertexes2,
573  mImages[mode],
574  imageX, imageY);
575  }
576  }
577  graphics->finalize(mVertexes2);
578  }
579  graphics->drawTileCollection(mVertexes2);
580 
581  if (isPressed())
582  {
583  textX ++;
584  textY ++;
585  }
586 
587  if (mTextChanged)
588  {
589  mTextChunk.textFont = font;
592  switch (mode)
593  {
594  case BUTTON_DISABLED:
597  break;
598  case BUTTON_PRESSED:
601  break;
602  case BUTTON_HIGHLIGHTED:
605  break;
606  default:
609  break;
610  }
611  font->generate(mTextChunk);
612  mTextChanged = false;
613  }
614 
615  const Image *const image = mTextChunk.img;
616  if (image != nullptr)
617  graphics->drawImage(image, textX, textY);
618 
619  BLOCK_END("Button::draw")
620 }
621 
622 void Button::safeDraw(Graphics *const graphics)
623 {
624  BLOCK_START("Button::safeDraw")
625  int mode;
626 
627  if (!isEnabled())
628  mode = BUTTON_DISABLED;
629  else if (isPressed2())
630  mode = BUTTON_PRESSED;
631  else if (mHasMouse || isFocused())
632  mode = BUTTON_HIGHLIGHTED;
633  else
634  mode = BUTTON_STANDARD;
635 
636  const Skin *const skin = mSkin[mode];
637  if (skin == nullptr)
638  {
639  BLOCK_END("Button::safeDraw")
640  return;
641  }
642 
643  updateAlpha();
644 
645  if (mMode != mode)
646  {
647  mTextChanged = true;
648  mMode = mode;
649  }
650 
651  const int padding = skin->getPadding();
652  const int spacing = mSpacing[mode];
653 
654  int imageX = 0;
655  int imageY = 0;
656  int textX = 0;
657  const Rect &rect = mDimension;
658  const int width = rect.width;
659  const int height = rect.height;
660  Font *const font = getFont();
661  int textY = height / 2 - font->getHeight() / 2;
662  if (mImages != nullptr)
663  imageY = height / 2 - mImageHeight / 2;
664 
665 // need move calculation from draw!!!
666 
667  switch (mAlignment)
668  {
669  default:
670  case Graphics::LEFT:
671  {
672  if (mImages != nullptr)
673  {
674  imageX = padding;
675  textX = padding + mImageWidth + spacing;
676  }
677  else
678  {
679  textX = padding;
680  }
681  break;
682  }
683  case Graphics::CENTER:
684  {
685  const int width1 = font->getWidth(mCaption);
686  if (mImages != nullptr)
687  {
688  const int w = width1 + mImageWidth + spacing;
689  imageX = (width - w) / 2;
690  textX = imageX + mImageWidth + spacing - width1 / 2;
691  }
692  else
693  {
694  textX = (width - width1) / 2;
695  }
696  break;
697  }
698  case Graphics::RIGHT:
699  {
700  const int width1 = font->getWidth(mCaption);
701  textX = width - width1 - padding;
702  imageX = textX - width1 - spacing;
703  break;
704  }
705  }
706 
707  graphics->drawImageRect(0, 0, width, height, skin->getBorder());
708 
709  if (mImages != nullptr)
710  {
711  if (isPressed())
712  graphics->drawImage(mImages[mode], imageX + 1, imageY + 1);
713  else
714  graphics->drawImage(mImages[mode], imageX, imageY);
715  }
716 
717  if (isPressed())
718  {
719  textX ++;
720  textY ++;
721  }
722 
723  if (mTextChanged)
724  {
725  mTextChunk.textFont = font;
728  switch (mode)
729  {
730  case BUTTON_DISABLED:
733  break;
734  case BUTTON_PRESSED:
737  break;
738  case BUTTON_HIGHLIGHTED:
741  break;
742  default:
745  break;
746  }
747  font->generate(mTextChunk);
748  mTextChanged = false;
749  }
750 
751  const Image *const image = mTextChunk.img;
752  if (image != nullptr)
753  graphics->drawImage(image, textX, textY);
754 
755  BLOCK_END("Button::safeDraw")
756 }
757 
759 {
760  if (event.getButton() == MouseButton::LEFT)
761  {
762  if (mStick)
763  mPressed = !mPressed;
764 
765  if (mMousePressed && mHasMouse)
766  {
767  mMousePressed = false;
768  mClickCount = event.getClickCount();
770  }
771  else
772  {
773  mMousePressed = false;
774  mClickCount = 0;
775  }
776  event.consume();
777  }
778 }
779 
781 {
782  mRedraw = true;
783 }
784 
786 {
787  mRedraw = true;
788 }
789 
791 {
793  mVertexes2->clear();
795  mRedraw = true;
796  mTextChanged = true;
797 }
798 
800 {
801  const Font *const font = getFont();
802  const Skin *const skin = mSkin[BUTTON_STANDARD];
803  if (skin == nullptr)
804  return;
805  const int padding = skin->getPadding();
806 
807  if (mImages != nullptr)
808  {
809  const int width = font->getWidth(mCaption);
810  if (width != 0)
811  {
812  const int spacing = mSpacing[BUTTON_STANDARD];
813  setWidth(width + mImageWidth + spacing + 2 * padding);
814  }
815  else
816  {
817  setWidth(mImageWidth + 2 * padding);
818  }
819  int height = font->getHeight();
820  if (height < mImageHeight)
821  height = mImageHeight;
822  setHeight(height + 2 * padding);
823  }
824  else
825  {
826  setWidth(font->getWidth(mCaption) + 2 * padding);
827  setHeight(font->getHeight() + 2 * padding);
828  }
829 }
830 
832 {
833  const InputActionT action = event.getActionId();
834 
835  if (action == InputAction::GUI_SELECT)
836  {
837  mKeyPressed = true;
838  event.consume();
839  }
840 }
841 
843 {
844  const InputActionT action = event.getActionId();
845 
846  if (action == InputAction::GUI_SELECT && mKeyPressed)
847  {
848  mKeyPressed = false;
849  if (mStick)
850  mPressed = !mPressed;
852  event.consume();
853  }
854 }
855 
856 bool Button::isPressed2() const
857 {
858  return mPressed || isPressed();
859 }
860 
861 bool Button::isPressed() const
862 {
863  if (mMousePressed)
864  return mHasMouse;
865  return mKeyPressed;
866 }
867 
868 void Button::focusLost(const Event& event A_UNUSED)
869 {
870  mMousePressed = false;
871  mKeyPressed = false;
872 }
873 
875 {
876  if (event.getButton() == MouseButton::LEFT)
877  {
878  mMousePressed = true;
879  event.consume();
880  }
881 }
882 
884 {
885  mHasMouse = true;
886 }
887 
889 {
890  mHasMouse = false;
891 }
892 
894 {
895  event.consume();
896 }
897 
899 {
900  if (mWindow != nullptr)
901  mWindow->addWidgetListener(this);
902  Widget::setParent(widget);
903 }
904 
905 void Button::setWindow(Widget *const widget)
906 {
907  if ((widget == nullptr) && (mWindow != nullptr))
908  {
910  mWindow = nullptr;
911  }
912  else
913  {
914  Widget2::setWindow(widget);
915  }
916 }
static std::string const data[Button::BUTTON_COUNT]
Definition: button.cpp:91
void setImage(Image *const image)
Definition: button.cpp:379
int mSpacing[BUTTON_COUNT]
Definition: button.h:320
bool mStick
Definition: button.h:343
bool mHasMouse
Definition: button.h:331
int mImageHeight
Definition: button.h:327
void focusLost(const Event &event)
Definition: button.cpp:868
~Button()
Definition: button.cpp:337
Color mEnabledColor
Definition: button.h:299
void updateAlpha()
Definition: button.cpp:418
bool mTextChanged
Definition: button.h:345
void keyPressed(KeyEvent &event)
Definition: button.cpp:831
void init()
Definition: button.cpp:307
static float mAlpha
Definition: button.h:284
Button(const Widget2 *const widget, const std::string &skinName)
Definition: button.cpp:99
void setParent(Widget *widget)
Definition: button.cpp:898
ImageCollection * mVertexes2
Definition: button.h:298
void mousePressed(MouseEvent &event)
Definition: button.cpp:874
std::string mCaption
Definition: button.h:290
void mouseReleased(MouseEvent &event)
Definition: button.cpp:758
int mMode
Definition: button.h:323
Color mPressedColor
Definition: button.h:305
bool isPressed() const
Definition: button.cpp:861
void adjustSize()
Definition: button.cpp:799
ImageSet * mImageSet
Definition: button.h:308
@ BUTTON_DISABLED
Definition: button.h:269
@ BUTTON_COUNT
Definition: button.h:270
@ BUTTON_HIGHLIGHTED
Definition: button.h:267
@ BUTTON_STANDARD
Definition: button.h:266
@ BUTTON_PRESSED
Definition: button.h:268
bool isPressed2() const
Definition: button.cpp:856
void mouseDragged(MouseEvent &event)
Definition: button.cpp:893
void setWindow(Widget *const widget)
Definition: button.cpp:905
Color mHighlightedColor2
Definition: button.h:304
TextChunk mTextChunk
Definition: button.h:296
int mImageWidth
Definition: button.h:326
void mouseExited(MouseEvent &event)
Definition: button.cpp:888
Skin * mSkin[BUTTON_COUNT]
Definition: button.h:286
Color mDisabledColor2
Definition: button.h:302
std::string mSkinName
Definition: button.h:294
void widgetHidden(const Event &event)
Definition: button.cpp:790
Color mPressedColor2
Definition: button.h:306
void draw(Graphics *const graphics)
Definition: button.cpp:443
Color mHighlightedColor
Definition: button.h:303
void safeDraw(Graphics *const graphics)
Definition: button.cpp:622
void loadImage(const std::string &imageName)
Definition: button.cpp:366
Color mDisabledColor
Definition: button.h:301
bool mKeyPressed
Definition: button.h:336
Color mEnabledColor2
Definition: button.h:300
int mClickCount
Definition: button.h:315
Graphics::Alignment mAlignment
Definition: button.h:313
int mYOffset
Definition: button.h:325
void mouseEntered(MouseEvent &event)
Definition: button.cpp:883
void loadImageSet(const std::string &imageName)
Definition: button.cpp:395
Image ** mImages
Definition: button.h:307
int mXOffset
Definition: button.h:324
void widgetResized(const Event &event)
Definition: button.cpp:780
void keyReleased(KeyEvent &event)
Definition: button.cpp:842
bool mPressed
Definition: button.h:344
void widgetMoved(const Event &event)
Definition: button.cpp:785
bool mMousePressed
Definition: button.h:341
int yOffset
Definition: cliprect.h:127
int xOffset
Definition: cliprect.h:122
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
virtual void drawTileCollection(const ImageCollection *const vertCol)=0
bool getRedraw() const
Definition: graphics.h:287
virtual void calcTileCollection(ImageCollection *const vertCol, const Image *const image, int x, int y)=0
virtual void finalize(ImageCollection *const col)
Definition: graphics.h:465
@ CENTER
Definition: graphics.h:132
virtual void calcWindow(ImageCollection *const vertCol, const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
ClipRect & getTopClip() const
Definition: graphics.h:281
virtual void drawImageRect(const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
void removeDragged(const Widget *const widget)
Definition: gui.cpp:1162
Image * grid[9]
Definition: imagerect.h:42
Image * get(const size_type i) const
Definition: imageset.cpp:67
MouseButtonT getButton() const
Definition: mouseevent.h:116
Definition: rect.h:74
int width
Definition: rect.h:219
int height
Definition: rect.h:224
virtual void decRef()
Definition: resource.cpp:50
float guiAlpha
Definition: settings.h:131
Definition: skin.h:37
int getOption(const std::string &name) const
Definition: skin.h:106
const ImageRect & getBorder() const
Definition: skin.h:68
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
static Image * getImageFromThemeXml(const std::string &name, const std::string &name2)
Definition: theme.cpp:926
Skin * load(const std::string &filename, const std::string &filename2, const bool full, const std::string &defaultPath)
Definition: theme.cpp:179
float getMinimumOpacity() const
Definition: theme.h:124
static ImageSet * getImageSetFromTheme(const std::string &path, const int w, const int h)
Definition: theme.cpp:660
virtual void setWindow(Widget *const window)
Definition: widget2.h:97
Widget * mWindow
Definition: widget2.h:112
Definition: widget.h:99
void setFrameSize(const unsigned int frameSize)
Definition: widget.h:168
void setFocusable(const bool focusable)
Definition: widget.cpp:192
void setWidth(const int width)
Definition: widget.cpp:133
void distributeActionEvent()
Definition: widget.cpp:493
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
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:596
void addKeyListener(KeyListener *const keyListener)
Definition: widget.cpp:272
bool mRedraw
Definition: widget.h:1164
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
bool isEnabled() const
Definition: widget.cpp:375
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:252
void addFocusListener(FocusListener *const focusListener)
Definition: widget.cpp:282
virtual bool isFocused() const
Definition: widget.cpp:184
#define new
Definition: debug_new.h:147
#define delete2(var)
Definition: delete2.h:25
RenderType openGLMode
Gui * gui
Definition: gui.cpp:111
InputAction ::T InputActionT
Definition: inputaction.h:717
#define restrict
Definition: localconsts.h:165
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
#define isBatchDrawRenders(val)
Definition: renderers.h:31
Settings settings
Definition: settings.cpp:32
Theme * theme
Definition: theme.cpp:62