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-2017 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 /* _______ __ __ __ ______ __ __ _______ __ __
24  * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
25  * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
26  * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
27  * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
28  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
29  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
30  *
31  * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
32  *
33  *
34  * Per Larsson a.k.a finalman
35  * Olof Naessén a.k.a jansem/yakslem
36  *
37  * Visit: http://guichan.sourceforge.net
38  *
39  * License: (BSD)
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  * notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  * notice, this list of conditions and the following disclaimer in
47  * the documentation and/or other materials provided with the
48  * distribution.
49  * 3. Neither the name of Guichan nor the names of its contributors may
50  * be used to endorse or promote products derived from this software
51  * without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
54  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
55  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
56  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
57  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
59  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
60  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
61  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */
65 
66 #include "gui/widgets/tabs/tab.h"
67 
68 #include "settings.h"
69 
70 #include "gui/gui.h"
71 #include "gui/skin.h"
72 
73 #include "gui/widgets/label.h"
74 #include "gui/widgets/tabbedarea.h"
75 
77 
78 #include "resources/imagerect.h"
79 
80 #include "resources/image/image.h"
81 
82 #include "utils/delete2.h"
83 
84 #include "debug.h"
85 
86 int Tab::mInstances = 0;
87 float Tab::mAlpha = 1.0;
88 
89 namespace
90 {
91  std::string const data[Tab::TAB_COUNT] =
92  {
93  "tab.xml",
94  "tab_highlighted.xml",
95  "tab_selected.xml",
96  "tab_unused.xml"
97  };
98 } // namespace
99 
101 
102 Tab::Tab(const Widget2 *const widget) :
103  BasicContainer(widget),
104  MouseListener(),
105  WidgetListener(),
106  mLabel(new Label(this)),
107  mTabbedArea(nullptr),
108  mTabColor(&getThemeColor(ThemeColorId::TAB)),
109  mTabOutlineColor(&getThemeColor(ThemeColorId::TAB_OUTLINE)),
110  mTabHighlightedColor(&getThemeColor(ThemeColorId::TAB_HIGHLIGHTED)),
111  mTabHighlightedOutlineColor(&getThemeColor(
113  mTabSelectedColor(&getThemeColor(ThemeColorId::TAB_SELECTED)),
114  mTabSelectedOutlineColor(&getThemeColor(
116  mFlashColor(&getThemeColor(ThemeColorId::TAB_FLASH)),
117  mFlashOutlineColor(&getThemeColor(ThemeColorId::TAB_FLASH_OUTLINE)),
118  mPlayerFlashColor(&getThemeColor(ThemeColorId::TAB_PLAYER_FLASH)),
119  mPlayerFlashOutlineColor(&getThemeColor(
121  mFlash(0),
123  mImage(nullptr),
124  mMode(0),
125  mLabelMode(-1),
126  mHasMouse(false)
127 {
128  init();
129 }
130 
132 {
133  if (gui != nullptr)
134  gui->removeDragged(this);
135 
136  mInstances--;
137  if (mInstances == 0 && (theme != nullptr))
138  {
139  for (int mode = 0; mode < TAB_COUNT; mode ++)
140  theme->unload(tabImg[mode]);
141  }
142 
143  delete2(mLabel);
144 
145  if (mImage != nullptr)
146  {
147  mImage->decRef();
148  mImage = nullptr;
149  }
151 }
152 
153 void Tab::init()
154 {
155  addMouseListener(this);
156  setFocusable(false);
157  setFrameSize(0);
158  mFlash = 0;
159 
160  addWidgetListener(this);
161 
162  if (mInstances == 0)
163  {
164  // Load the skin
165  if (theme != nullptr)
166  {
167  for (int mode = 0; mode < TAB_COUNT; mode ++)
168  tabImg[mode] = theme->load(data[mode], "tab.xml");
169  }
170  updateAlpha();
171  }
172  mInstances++;
173 
174  add(mLabel);
175 
176  const Skin *const skin = tabImg[TAB_STANDARD];
177  if (skin == nullptr)
178  return;
179  const int padding = skin->getPadding();
180 
181  mLabel->setPosition(padding, padding);
182 }
183 
185 {
186  const float alpha = std::max(settings.guiAlpha,
188 
189  if (alpha != mAlpha)
190  {
191  mAlpha = alpha;
192  for (int a = 0; a < 9; a++)
193  {
194  for (int t = 0; t < TAB_COUNT; t++)
195  {
196  Skin *const skin = tabImg[t];
197  if (skin != nullptr)
198  {
199  const ImageRect &rect = skin->getBorder();
200  Image *const image = rect.grid[a];
201  if (image != nullptr)
202  image->setAlpha(mAlpha);
203  }
204  }
205  }
206  }
207 }
208 
209 void Tab::draw(Graphics *const graphics)
210 {
211  BLOCK_START("Tab::draw")
212  int mode = TAB_STANDARD;
213 
214  // check which type of tab to draw
215  if (mTabbedArea != nullptr)
216  {
217  int labelMode = mFlash;
218 
219  if (mTabbedArea->isTabSelected(this))
220  {
221  labelMode = 3;
222  mode = TAB_SELECTED;
223  // if tab is selected, it doesnt need to highlight activity
224  mFlash = 0;
225  }
226  else if (labelMode == 0)
227  {
228  if (mHasMouse)
229  {
230  labelMode = 4;
231  mode = TAB_HIGHLIGHTED;
232  }
233  }
234  else if (mHasMouse)
235  {
236  mode = TAB_HIGHLIGHTED;
237  }
238 
239  // mRedraw need here because no other way to say label to change color
240  // +++ text from label must be moved to tab itself
241  if (labelMode != mLabelMode || mRedraw)
242  {
243  mLabelMode = labelMode;
244  switch (labelMode)
245  {
246  case 0: // default state
247  default:
250  break;
251  case 1: // mFlash == 1
254  break;
255  case 2: // mFlash == 2
258  break;
259  case 3: // mTabbedArea->isTabSelected(this)
262  break;
263  case 4: // mHasMouse
266  break;
267  }
268  }
269  }
270 
271  const Skin *const skin = tabImg[mode];
272  if (skin == nullptr)
273  {
274  BLOCK_END("Tab::draw")
275  return;
276  }
277 
278  updateAlpha();
279 
280  const ImageRect &rect = skin->getBorder();
281  if (mRedraw || mode != mMode || graphics->getRedraw())
282  {
283  mMode = mode;
284  mRedraw = false;
285  mVertexes->clear();
286  graphics->calcWindow(mVertexes,
287  0, 0,
289  rect);
290 
291  if (mImage != nullptr)
292  {
293  const Skin *const skin1 = tabImg[TAB_STANDARD];
294  if (skin1 != nullptr)
295  {
296  const int padding = skin1->getPadding();
297  graphics->calcTileCollection(mVertexes,
298  mImage,
299  padding,
300  padding);
301  }
302  }
303  graphics->finalize(mVertexes);
304  }
305 
306  graphics->drawTileCollection(mVertexes);
307 
308  drawChildren(graphics);
309  BLOCK_END("Tab::draw")
310 }
311 
312 void Tab::safeDraw(Graphics *const graphics)
313 {
314  BLOCK_START("Tab::draw")
315  int mode = TAB_STANDARD;
316 
317  // check which type of tab to draw
318  if (mTabbedArea != nullptr)
319  {
320  int labelMode = mFlash;
321 
322  if (mTabbedArea->isTabSelected(this))
323  {
324  labelMode = 3;
325  mode = TAB_SELECTED;
326  // if tab is selected, it doesnt need to highlight activity
327  mFlash = 0;
328  }
329  else if (labelMode == 0)
330  {
331  if (mHasMouse)
332  {
333  labelMode = 4;
334  mode = TAB_HIGHLIGHTED;
335  }
336  }
337  else if (mHasMouse)
338  {
339  mode = TAB_HIGHLIGHTED;
340  }
341 
342  if (labelMode != mLabelMode)
343  {
344  mLabelMode = labelMode;
345  switch (labelMode)
346  {
347  case 0: // default state
348  default:
351  break;
352  case 1: // mFlash == 1
355  break;
356  case 2: // mFlash == 2
359  break;
360  case 3: // mTabbedArea->isTabSelected(this)
363  break;
364  case 4: // mHasMouse
367  break;
368  }
369  }
370  }
371 
372  const Skin *const skin = tabImg[mode];
373  if (skin == nullptr)
374  {
375  BLOCK_END("Tab::draw")
376  return;
377  }
378 
379  updateAlpha();
380 
381  graphics->drawImageRect(0, 0,
383  skin->getBorder());
384  if (mImage != nullptr)
385  {
386  const Skin *const skin1 = tabImg[TAB_STANDARD];
387  if (skin1 != nullptr)
388  {
389  const int padding = skin1->getPadding();
390  graphics->drawImage(mImage, padding, padding);
391  }
392  }
393 
394  safeDrawChildren(graphics);
395  BLOCK_END("Tab::draw")
396 }
397 
399 {
400  mRedraw = true;
401 }
402 
403 void Tab::widgetMoved(const Event &event A_UNUSED)
404 {
405  mRedraw = true;
406 }
407 
409 {
410  if (mLabel == nullptr)
411  return;
412 
413  mLabel->setFont(font);
414  mLabel->adjustSize();
415  adjustSize();
416  mRedraw = true;
417 }
418 
419 
421 {
422  const Skin *const skin = tabImg[TAB_STANDARD];
423  if (skin == nullptr)
424  return;
425  const int pad2 = skin->getPadding() * 2;
426 
427  if (mImage != nullptr)
428  {
429  const SDL_Rect &rect = mImage->mBounds;
430  setSize(rect.w + pad2, rect.h + pad2);
431  }
432  else
433  {
434  setSize(mLabel->getWidth() + pad2,
435  mLabel->getHeight() + pad2);
436  }
437 
438  if (mTabbedArea != nullptr)
440 }
441 
443 {
444  mTabbedArea = tabbedArea;
445 }
446 
448 {
449  return mTabbedArea;
450 }
451 
452 void Tab::setCaption(const std::string &caption)
453 {
454  mLabel->setCaption(caption);
455  mLabel->adjustSize();
456  adjustSize();
457 }
458 
459 void Tab::setImage(Image *const image)
460 {
461  if (mImage != nullptr)
462  mImage->decRef();
463  mImage = image;
464  adjustSize();
465 }
466 
467 const std::string &Tab::getCaption() const
468 {
469  return mLabel->getCaption();
470 }
471 
473 {
474  mHasMouse = true;
475 }
476 
478 {
479  mHasMouse = false;
480 }
481 
483 {
484  for (int f = 0; f < TAB_COUNT; f ++)
485  {
486  tabImg[f] = nullptr;
487  }
488 }
void setSize(const int width, const int height)
Definition: widget.cpp:366
void adjustTabPositions()
Definition: tabbedarea.cpp:596
const Color * mTabHighlightedColor
Definition: tab.h:227
int width
Definition: rect.h:218
int getWidth() const
Definition: widget.h:220
Tab(const Widget2 *const widget)
Definition: tab.cpp:102
Definition: skin.h:35
virtual void drawTileCollection(const ImageCollection *const vertCol)=0
void unload(Skin *const skin)
Definition: theme.cpp:249
int mMode
Definition: tab.h:238
Gui * gui
Definition: gui.cpp:110
void setCaption(const std::string &caption)
Definition: tab.cpp:452
Definition: font.h:88
void updateAlpha()
Definition: tab.cpp:184
void mouseExited(MouseEvent &event)
Definition: tab.cpp:477
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha=255U) const A_INLINE
Definition: widget2.h:44
virtual void drawImageRect(const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
TabbedArea * mTabbedArea
Definition: tab.h:215
static float mAlpha
Definition: tab.h:223
float getMinimumOpacity() const
Definition: theme.h:124
void draw(Graphics *const graphics)
Definition: tab.cpp:209
TabbedArea * getTabbedArea() const
Definition: tab.cpp:447
#define BLOCK_START(name)
Definition: perfomance.h:78
Label * mLabel
Definition: tab.h:213
ImageCollection * mVertexes
Definition: window.h:702
#define BLOCK_END(name)
Definition: perfomance.h:79
#define delete2(var)
Definition: delete2.h:24
ImageCollection * mVertexes
Definition: tab.h:236
const Color * mTabHighlightedOutlineColor
Definition: tab.h:228
const Color * mTabSelectedOutlineColor
Definition: tab.h:230
const Color * mFlashColor
Definition: tab.h:231
void mouseEntered(MouseEvent &event)
Definition: tab.cpp:472
virtual void finalize(ImageCollection *const col)
Definition: graphics.h:464
#define new
Definition: debug_new.h:147
int mLabelMode
Definition: tab.h:239
Settings settings
Definition: settings.cpp:31
virtual void setAlpha(const float alpha)
Definition: image.cpp:285
int getPadding() const
Definition: skin.h:99
int mFlash
Definition: tab.h:235
const Color * mTabColor
Definition: tab.h:225
const ImageRect & getBorder() const
Definition: skin.h:67
void setCaption(const std::string &caption)
Definition: label.cpp:256
Image * grid[9]
Definition: imagerect.h:41
Definition: label.h:87
uint32_t data
Image * mImage
Definition: tab.h:237
void setFrameSize(const unsigned int frameSize)
Definition: widget.h:167
void add(Widget *const widget)
#define nullptr
Definition: localconsts.h:44
static int mInstances
Definition: tab.h:222
const Color * mFlashOutlineColor
Definition: tab.h:232
void addMouseListener(MouseListener *const mouseListener)
Definition: widget.cpp:291
void setPosition(const int x, const int y)
Definition: widget.cpp:160
int height
Definition: rect.h:223
bool mHasMouse
Definition: tab.h:242
static void finalCleanup()
Definition: tab.cpp:482
bool getRedraw() const
Definition: graphics.h:286
virtual ~Tab()
Definition: tab.cpp:131
void addWidgetListener(WidgetListener *const widgetListener)
Definition: widget.cpp:301
const Color * mTabSelectedColor
Definition: tab.h:229
Skin * load(const std::string &filename, const std::string &filename2, const bool full=true, const std::string &defaultPath=getThemePath())
Definition: theme.cpp:178
void setLabelFont(Font *const font)
Definition: tab.cpp:408
Theme * theme
Definition: theme.cpp:61
#define A_UNUSED
Definition: localconsts.h:171
void setFocusable(const bool focusable)
Definition: widget.cpp:191
const Color * mPlayerFlashColor
Definition: tab.h:233
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
void removeDragged(const Widget *const widget)
Definition: gui.cpp:1144
void setFont(Font *const font)
Definition: widget.cpp:348
void setImage(Image *const image)
Definition: tab.cpp:459
bool isTabSelected(const size_t index) const
Definition: tabbedarea.cpp:283
virtual void drawChildren(Graphics *const graphics)
Definition: event.h:77
bool mRedraw
Definition: widget.h:1163
const std::string & getCaption() const
Definition: tab.cpp:467
Definition: image.h:61
void setTabbedArea(TabbedArea *tabbedArea)
Definition: tab.cpp:442
virtual void calcTileCollection(ImageCollection *const vertCol, const Image *const image, int x, int y)=0
int getHeight() const
Definition: widget.h:239
void init()
Definition: tab.cpp:153
SDL_Rect mBounds
Definition: image.h:210
void setForegroundColorAll(const Color &color1, const Color &color2)
Definition: label.cpp:209
static Skin * tabImg[TAB_COUNT]
Definition: tab.h:221
const Color * mTabOutlineColor
Definition: tab.h:226
float guiAlpha
Definition: settings.h:129
Rect mDimension
Definition: widget.h:1100
void safeDraw(Graphics *const graphics)
Definition: tab.cpp:312
void adjustSize()
Definition: label.cpp:192
virtual void safeDrawChildren(Graphics *const graphics)
void decRef()
Definition: image.cpp:521
const Color * mPlayerFlashOutlineColor
Definition: tab.h:234
virtual void calcWindow(ImageCollection *const vertCol, const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
const std::string & getCaption() const
Definition: label.h:132
void widgetResized(const Event &event)
Definition: tab.cpp:398
void widgetMoved(const Event &event)
Definition: tab.cpp:403
void adjustSize()
Definition: tab.cpp:420