ManaPlus
tab.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2008-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/tabs/tab.h"
68 
69 #include "settings.h"
70 
71 #include "gui/gui.h"
72 #include "gui/skin.h"
73 
74 #include "gui/widgets/label.h"
75 #include "gui/widgets/tabbedarea.h"
76 
78 
79 #include "resources/imagerect.h"
80 
81 #include "resources/image/image.h"
82 
83 #include "utils/delete2.h"
84 
85 #include "debug.h"
86 
87 int Tab::mInstances = 0;
88 float Tab::mAlpha = 1.0;
89 
90 namespace
91 {
92  std::string const data[Tab::TAB_COUNT] =
93  {
94  "tab.xml",
95  "tab_highlighted.xml",
96  "tab_selected.xml",
97  "tab_unused.xml"
98  };
99 } // namespace
100 
102 
103 Tab::Tab(const Widget2 *const widget) :
104  BasicContainer(widget),
105  MouseListener(),
106  WidgetListener(),
107  mLabel(new Label(this)),
108  mTabbedArea(nullptr),
109  mTabColor(&getThemeColor(ThemeColorId::TAB, 255U)),
110  mTabOutlineColor(&getThemeColor(ThemeColorId::TAB_OUTLINE, 255U)),
111  mTabHighlightedColor(&getThemeColor(ThemeColorId::TAB_HIGHLIGHTED, 255U)),
112  mTabHighlightedOutlineColor(&getThemeColor(
113  ThemeColorId::TAB_HIGHLIGHTED_OUTLINE, 255U)),
114  mTabSelectedColor(&getThemeColor(ThemeColorId::TAB_SELECTED, 255U)),
115  mTabSelectedOutlineColor(&getThemeColor(
116  ThemeColorId::TAB_SELECTED_OUTLINE, 255U)),
117  mFlashColor(&getThemeColor(ThemeColorId::TAB_FLASH, 255U)),
118  mFlashOutlineColor(&getThemeColor(ThemeColorId::TAB_FLASH_OUTLINE, 255U)),
119  mPlayerFlashColor(&getThemeColor(ThemeColorId::TAB_PLAYER_FLASH, 255U)),
120  mPlayerFlashOutlineColor(&getThemeColor(
121  ThemeColorId::TAB_PLAYER_FLASH_OUTLINE, 255U)),
122  mFlash(0),
123  mVertexes(new ImageCollection),
124  mImage(nullptr),
125  mMode(0),
126  mLabelMode(-1),
127  mHasMouse(false)
128 {
129  init();
130 }
131 
133 {
134  if (gui != nullptr)
135  gui->removeDragged(this);
136 
137  mInstances--;
138  if (mInstances == 0 && (theme != nullptr))
139  {
140  for (int mode = 0; mode < TAB_COUNT; mode ++)
141  theme->unload(tabImg[mode]);
142  }
143 
144  delete2(mLabel)
145 
146  if (mImage != nullptr)
147  {
148  mImage->decRef();
149  mImage = nullptr;
150  }
152 }
153 
154 void Tab::init()
155 {
156  addMouseListener(this);
157  setFocusable(false);
158  setFrameSize(0);
159  mFlash = 0;
160 
161  addWidgetListener(this);
162 
163  if (mInstances == 0)
164  {
165  // Load the skin
166  if (theme != nullptr)
167  {
168  for (int mode = 0; mode < TAB_COUNT; mode ++)
169  {
170  tabImg[mode] = theme->load(data[mode],
171  "tab.xml",
172  true,
174  }
175  }
176  updateAlpha();
177  }
178  mInstances++;
179 
180  add(mLabel);
181 
182  const Skin *const skin = tabImg[TAB_STANDARD];
183  if (skin == nullptr)
184  return;
185  const int padding = skin->getPadding();
186 
187  mLabel->setPosition(padding, padding);
188 }
189 
191 {
192  const float alpha = std::max(settings.guiAlpha,
194 
195  if (alpha != mAlpha)
196  {
197  mAlpha = alpha;
198  for (int a = 0; a < 9; a++)
199  {
200  for (int t = 0; t < TAB_COUNT; t++)
201  {
202  Skin *const skin = tabImg[t];
203  if (skin != nullptr)
204  {
205  const ImageRect &rect = skin->getBorder();
206  Image *const image = rect.grid[a];
207  if (image != nullptr)
208  image->setAlpha(mAlpha);
209  }
210  }
211  }
212  }
213 }
214 
215 void Tab::draw(Graphics *const graphics)
216 {
217  BLOCK_START("Tab::draw")
218  int mode = TAB_STANDARD;
219 
220  // check which type of tab to draw
221  if (mTabbedArea != nullptr)
222  {
223  int labelMode = mFlash;
224 
225  if (mTabbedArea->isTabSelected(this))
226  {
227  labelMode = 3;
228  mode = TAB_SELECTED;
229  // if tab is selected, it doesnt need to highlight activity
230  mFlash = 0;
231  }
232  else if (labelMode == 0)
233  {
234  if (mHasMouse)
235  {
236  labelMode = 4;
237  mode = TAB_HIGHLIGHTED;
238  }
239  }
240  else if (mHasMouse)
241  {
242  mode = TAB_HIGHLIGHTED;
243  }
244 
245  // mRedraw need here because no other way to say label to change color
246  // +++ text from label must be moved to tab itself
247  if (labelMode != mLabelMode || mRedraw)
248  {
249  mLabelMode = labelMode;
250  switch (labelMode)
251  {
252  case 0: // default state
253  default:
256  break;
257  case 1: // mFlash == 1
260  break;
261  case 2: // mFlash == 2
264  break;
265  case 3: // mTabbedArea->isTabSelected(this)
268  break;
269  case 4: // mHasMouse
272  break;
273  }
274  }
275  }
276 
277  const Skin *const skin = tabImg[mode];
278  if (skin == nullptr)
279  {
280  BLOCK_END("Tab::draw")
281  return;
282  }
283 
284  updateAlpha();
285 
286  const ImageRect &rect = skin->getBorder();
287  if (mRedraw || mode != mMode || graphics->getRedraw())
288  {
289  mMode = mode;
290  mRedraw = false;
291  mVertexes->clear();
292  graphics->calcWindow(mVertexes,
293  0, 0,
295  rect);
296 
297  if (mImage != nullptr)
298  {
299  const Skin *const skin1 = tabImg[TAB_STANDARD];
300  if (skin1 != nullptr)
301  {
302  const int padding = skin1->getPadding();
303  graphics->calcTileCollection(mVertexes,
304  mImage,
305  padding,
306  padding);
307  }
308  }
309  graphics->finalize(mVertexes);
310  }
311 
312  graphics->drawTileCollection(mVertexes);
313 
314  drawChildren(graphics);
315  BLOCK_END("Tab::draw")
316 }
317 
318 void Tab::safeDraw(Graphics *const graphics)
319 {
320  BLOCK_START("Tab::draw")
321  int mode = TAB_STANDARD;
322 
323  // check which type of tab to draw
324  if (mTabbedArea != nullptr)
325  {
326  int labelMode = mFlash;
327 
328  if (mTabbedArea->isTabSelected(this))
329  {
330  labelMode = 3;
331  mode = TAB_SELECTED;
332  // if tab is selected, it doesnt need to highlight activity
333  mFlash = 0;
334  }
335  else if (labelMode == 0)
336  {
337  if (mHasMouse)
338  {
339  labelMode = 4;
340  mode = TAB_HIGHLIGHTED;
341  }
342  }
343  else if (mHasMouse)
344  {
345  mode = TAB_HIGHLIGHTED;
346  }
347 
348  if (labelMode != mLabelMode)
349  {
350  mLabelMode = labelMode;
351  switch (labelMode)
352  {
353  case 0: // default state
354  default:
357  break;
358  case 1: // mFlash == 1
361  break;
362  case 2: // mFlash == 2
365  break;
366  case 3: // mTabbedArea->isTabSelected(this)
369  break;
370  case 4: // mHasMouse
373  break;
374  }
375  }
376  }
377 
378  const Skin *const skin = tabImg[mode];
379  if (skin == nullptr)
380  {
381  BLOCK_END("Tab::draw")
382  return;
383  }
384 
385  updateAlpha();
386 
387  graphics->drawImageRect(0, 0,
389  skin->getBorder());
390  if (mImage != nullptr)
391  {
392  const Skin *const skin1 = tabImg[TAB_STANDARD];
393  if (skin1 != nullptr)
394  {
395  const int padding = skin1->getPadding();
396  graphics->drawImage(mImage, padding, padding);
397  }
398  }
399 
400  safeDrawChildren(graphics);
401  BLOCK_END("Tab::draw")
402 }
403 
405 {
406  mRedraw = true;
407 }
408 
409 void Tab::widgetMoved(const Event &event A_UNUSED)
410 {
411  mRedraw = true;
412 }
413 
414 void Tab::setLabelFont(Font *const font)
415 {
416  if (mLabel == nullptr)
417  return;
418 
419  mLabel->setFont(font);
420  mLabel->adjustSize();
421  adjustSize();
422  mRedraw = true;
423 }
424 
425 
427 {
428  const Skin *const skin = tabImg[TAB_STANDARD];
429  if (skin == nullptr)
430  return;
431  const int pad2 = skin->getPadding() * 2;
432 
433  if (mImage != nullptr)
434  {
435  const SDL_Rect &rect = mImage->mBounds;
436  setSize(rect.w + pad2, rect.h + pad2);
437  }
438  else
439  {
440  setSize(mLabel->getWidth() + pad2,
441  mLabel->getHeight() + pad2);
442  }
443 
444  if (mTabbedArea != nullptr)
446 }
447 
449 {
450  mTabbedArea = tabbedArea;
451 }
452 
454 {
455  return mTabbedArea;
456 }
457 
458 void Tab::setCaption(const std::string &caption)
459 {
460  mLabel->setCaption(caption);
461  mLabel->adjustSize();
462  adjustSize();
463 }
464 
465 void Tab::setImage(Image *const image)
466 {
467  if (mImage != nullptr)
468  mImage->decRef();
469  mImage = image;
470  adjustSize();
471 }
472 
473 const std::string &Tab::getCaption() const
474 {
475  return mLabel->getCaption();
476 }
477 
479 {
480  mHasMouse = true;
481 }
482 
484 {
485  mHasMouse = false;
486 }
487 
489 {
490  for (int f = 0; f < TAB_COUNT; f ++)
491  {
492  tabImg[f] = nullptr;
493  }
494 }
virtual void safeDrawChildren(Graphics *const graphics)
void add(Widget *const widget)
virtual void drawChildren(Graphics *const graphics)
Definition: event.h:79
Definition: font.h:90
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
virtual void calcWindow(ImageCollection *const vertCol, const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
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
Definition: label.h:91
void adjustSize()
Definition: label.cpp:200
void setForegroundColorAll(const Color &color1, const Color &color2)
Definition: label.cpp:217
const std::string & getCaption() const
Definition: label.h:133
void setCaption(const std::string &caption)
Definition: label.cpp:264
int width
Definition: rect.h:219
int height
Definition: rect.h:224
float guiAlpha
Definition: settings.h:131
Definition: skin.h:37
const ImageRect & getBorder() const
Definition: skin.h:68
int getPadding() const
Definition: skin.h:100
int mMode
Definition: tab.h:239
const Color * mFlashColor
Definition: tab.h:232
const Color * mTabSelectedColor
Definition: tab.h:230
const Color * mTabColor
Definition: tab.h:226
void mouseEntered(MouseEvent &event)
Definition: tab.cpp:478
Tab(const Widget2 *const widget)
Definition: tab.cpp:103
const Color * mTabSelectedOutlineColor
Definition: tab.h:231
int mFlash
Definition: tab.h:236
void init()
Definition: tab.cpp:154
void adjustSize()
Definition: tab.cpp:426
const Color * mTabHighlightedColor
Definition: tab.h:228
void updateAlpha()
Definition: tab.cpp:190
const Color * mTabOutlineColor
Definition: tab.h:227
void widgetMoved(const Event &event)
Definition: tab.cpp:409
void setTabbedArea(TabbedArea *tabbedArea)
Definition: tab.cpp:448
const std::string & getCaption() const
Definition: tab.cpp:473
static int mInstances
Definition: tab.h:223
void safeDraw(Graphics *const graphics)
Definition: tab.cpp:318
const Color * mPlayerFlashColor
Definition: tab.h:234
bool mHasMouse
Definition: tab.h:243
@ TAB_COUNT
Definition: tab.h:102
@ TAB_HIGHLIGHTED
Definition: tab.h:99
@ TAB_SELECTED
Definition: tab.h:100
@ TAB_STANDARD
Definition: tab.h:98
TabbedArea * mTabbedArea
Definition: tab.h:216
const Color * mTabHighlightedOutlineColor
Definition: tab.h:229
static Skin * tabImg[TAB_COUNT]
Definition: tab.h:222
void mouseExited(MouseEvent &event)
Definition: tab.cpp:483
void setCaption(const std::string &caption)
Definition: tab.cpp:458
~Tab()
Definition: tab.cpp:132
void setLabelFont(Font *const font)
Definition: tab.cpp:414
Image * mImage
Definition: tab.h:238
void setImage(Image *const image)
Definition: tab.cpp:465
void draw(Graphics *const graphics)
Definition: tab.cpp:215
Label * mLabel
Definition: tab.h:214
static void finalCleanup()
Definition: tab.cpp:488
const Color * mFlashOutlineColor
Definition: tab.h:233
static float mAlpha
Definition: tab.h:224
TabbedArea * getTabbedArea() const
Definition: tab.cpp:453
int mLabelMode
Definition: tab.h:240
ImageCollection * mVertexes
Definition: tab.h:237
const Color * mPlayerFlashOutlineColor
Definition: tab.h:235
void widgetResized(const Event &event)
Definition: tab.cpp:404
bool isTabSelected(const size_t index) const
Definition: tabbedarea.cpp:292
void adjustTabPositions()
Definition: tabbedarea.cpp:606
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
float getMinimumOpacity() const
Definition: theme.h:124
void setFrameSize(const unsigned int frameSize)
Definition: widget.h:168
void setFocusable(const bool focusable)
Definition: widget.cpp:192
void setSize(const int width, const int height)
Definition: widget.cpp:367
Rect mDimension
Definition: widget.h:1101
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:292
void setFont(Font *const font)
Definition: widget.cpp:349
void addWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:302
bool mRedraw
Definition: widget.h:1164
void setPosition(const int x, const int y)
Definition: widget.cpp:161
int getHeight() const
Definition: widget.h:240
int getWidth() const
Definition: widget.h:221
#define new
Definition: debug_new.h:147
#define delete2(var)
Definition: delete2.h:25
Gui * gui
Definition: gui.cpp:111
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
uint32_t data
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79
Settings settings
Definition: settings.cpp:32
Theme * theme
Definition: theme.cpp:62