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 #ifndef GUI_WIDGETS_TABBEDAREA_H 68 #define GUI_WIDGETS_TABBEDAREA_H 69 70 #include "listeners/keylistener.h" 71 #include "listeners/mouselistener.h" 72 #include "listeners/widgetlistener.h" 73 74 #include "gui/widgets/basiccontainer2.h" 75 76 #include "listeners/actionlistener.h" 77 78 class Button; 79 class Image; 80 class Tab; 81 82 /** 83 * A tabbed area, the same as the guichan tabbed area in 0.8, but extended 84 */ 85 class TabbedArea final : public ActionListener, 86 public BasicContainer, 87 public KeyListener, 88 public MouseListener, 89 public WidgetListener 90 { 91 public: 92 /** 93 * Constructor. 94 */ 95 explicit TabbedArea(const Widget2 *const widget); 96 97 A_DELETE_COPY(TabbedArea) 98 99 ~TabbedArea() override final; 100 101 void postInit() override final; 102 103 /** 104 * Draw the tabbed area. 105 */ 106 void draw(Graphics *const graphics) override final A_NONNULL(2); 107 108 void safeDraw(Graphics *const graphics) override final A_NONNULL(2); 109 110 /** 111 * Return how many tabs have been created. 112 */ 113 int getNumberOfTabs() const A_WARN_UNUSED; 114 115 /** 116 * Return tab with specified name as caption. 117 */ 118 Tab *getTab(const std::string &name) const A_WARN_UNUSED; 119 120 Tab *getTabByIndex(const int index) const A_WARN_UNUSED; 121 122 Widget *getWidgetByIndex(const int index) const A_WARN_UNUSED; 123 124 /** 125 * Returns the widget with the tab that has specified caption 126 */ 127 Widget *getWidget(const std::string &name) const A_WARN_UNUSED; 128 129 /** 130 * Returns the widget for the current tab 131 */ 132 Widget *getCurrentWidget() const A_WARN_UNUSED; 133 134 /** 135 * Add a tab. Overridden since it needs to size the widget. 136 * 137 * @param tab The tab widget for the tab. 138 * @param widget The widget to view when the tab is selected. 139 */ 140 void addTab(Tab *const tab, Widget *const widget); 141 142 void addTab(const std::string &caption, Widget *const widget); 143 144 void addTab(Image *const image, Widget *const widget); 145 146 bool isTabSelected(const size_t index) const A_WARN_UNUSED; 147 148 bool isTabSelected(const Tab *const tab) const A_WARN_UNUSED; 149 150 bool isTabPresent(const Tab *const tab) const A_WARN_UNUSED; 151 152 /** 153 * Overload the remove tab function as it's broken in guichan 0.8. 154 */ 155 void removeTab(Tab *const tab); 156 157 void removeAll(const bool del); 158 159 /** 160 * Overload the logic function since it's broken in guichan 0.8. 161 */ 162 void logic() override final; 163 getContainerHeight()164 int getContainerHeight() const noexcept2 A_WARN_UNUSED 165 { return mWidgetContainer->getHeight(); } 166 167 void setSelectedTab(Tab *const tab); 168 169 void setSelectedTabDefault(); 170 171 void setSelectedTabByIndex(const size_t index); 172 173 int getSelectedTabIndex() const A_WARN_UNUSED; 174 getSelectedTab()175 Tab* getSelectedTab() const noexcept2 A_WARN_UNUSED 176 { return mSelectedTab; } 177 setOpaque(const Opaque opaque)178 void setOpaque(const Opaque opaque) 179 { mOpaque = opaque; } 180 isOpaque()181 bool isOpaque() const noexcept2 A_WARN_UNUSED 182 { return mOpaque == Opaque_true; } 183 184 void adjustSize(); 185 186 void setSelectedTabByName(const std::string &name); 187 188 void widgetResized(const Event &event) override final; 189 190 /* 191 void moveLeft(Tab *tab); 192 193 void moveRight(Tab *tab); 194 */ 195 void adjustTabPositions(); 196 197 void action(const ActionEvent& actionEvent) override final; 198 199 // Inherited from MouseListener 200 201 void mousePressed(MouseEvent &event) override final; 202 203 void enableScrollButtons(const bool enable); 204 setRightMargin(const int n)205 void setRightMargin(const int n) noexcept2 206 { mRightMargin = n; } 207 getRightMargin()208 int getRightMargin() const noexcept2 A_WARN_UNUSED 209 { return mRightMargin; } 210 setFollowDownScroll(const bool n)211 void setFollowDownScroll(const bool n) noexcept2 212 { mFollowDownScroll = n; } 213 getFollowDownScroll()214 bool getFollowDownScroll() const noexcept2 A_WARN_UNUSED 215 { return mFollowDownScroll; } 216 217 void keyPressed(KeyEvent& event) override final; 218 setBlockSwitching(const bool b)219 void setBlockSwitching(const bool b) noexcept2 220 { mBlockSwitching = b; } 221 222 void setWidth(int width); 223 224 void setHeight(int height); 225 226 void setSize(int width, int height); 227 228 void setDimension(const Rect &dimension); 229 230 void death(const Event &event) override final; 231 setResizeHeight(bool b)232 void setResizeHeight(bool b) noexcept2 233 { mResizeHeight = b; } 234 235 void adjustWidget(Widget *const widget) const; 236 237 void selectNextTab(); 238 239 void selectPrevTab(); 240 getTabContainer()241 Widget *getTabContainer() const noexcept2 A_WARN_UNUSED 242 { return mTabContainer; } 243 getWidgetContainer()244 Widget *getWidgetContainer() const noexcept2 A_WARN_UNUSED 245 { return mWidgetContainer; } 246 247 private: 248 typedef STD_VECTOR <std::pair<Tab*, Widget*> > TabContainer; 249 250 /** The tab arrows */ 251 Button *mArrowButton[2] A_NONNULLPOINTER; 252 253 /** Check whether the arrow should be clickable */ 254 void updateArrowEnableState(); 255 256 /** 257 * Update the overall width of all tab. Used to know whether the arrows 258 * have to be drawn or not. 259 */ 260 void updateTabsWidth(); 261 262 Tab* mSelectedTab; 263 BasicContainer2* mTabContainer A_NONNULLPOINTER; 264 BasicContainer2* mWidgetContainer A_NONNULLPOINTER; 265 STD_VECTOR<Tab*> mTabsToDelete; 266 TabContainer mTabs; 267 268 /** 269 * The overall width of all tab. 270 */ 271 int mTabsWidth; 272 273 /** 274 * Update the overall width of visible tab. Used to know whether 275 * the arrows have to be enable or not. 276 */ 277 void updateVisibleTabsWidth(); 278 279 /** 280 * The overall width of visible tab. 281 */ 282 int mVisibleTabsWidth; 283 284 /** 285 * The tab scroll index. When scrolling with the arrows, the tabs 286 * must be displayed according to the current index. 287 * So the first tab displayed may not be the first in the list. 288 * @note the index must start at 0. 289 */ 290 unsigned int mTabScrollIndex; 291 int mRightMargin; 292 293 Opaque mOpaque; 294 bool mEnableScrollButtons; 295 bool mFollowDownScroll; 296 bool mBlockSwitching; 297 bool mResizeHeight; 298 }; 299 300 #endif // GUI_WIDGETS_TABBEDAREA_H 301