1 // SuperTuxKart - a fun racing game with go-kart 2 // Copyright (C) 2009-2015 Marianne Gagnon 3 // 4 // This program is free software; you can redistribute it and/or 5 // modify it under the terms of the GNU General Public License 6 // as published by the Free Software Foundation; either version 3 7 // of the License, or (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 19 20 #ifndef HEADER_RIBBON_HPP 21 #define HEADER_RIBBON_HPP 22 23 #include <irrString.h> 24 25 #include "guiengine/widget.hpp" 26 #include "guiengine/widgets/icon_button_widget.hpp" 27 #include "utils/cpp2011.hpp" 28 #include "utils/leak_check.hpp" 29 #include "utils/ptr_vector.hpp" 30 31 #include <IGUIStaticText.h> 32 33 namespace GUIEngine 34 { 35 /** Types of ribbons */ 36 enum RibbonType 37 { 38 RIBBON_COMBO, //!< select one item out of many, like in a combo box 39 RIBBON_TOOLBAR, //!< a row of individual buttons 40 RIBBON_TABS, //!< a tab bar 41 RIBBON_VERTICAL_TABS //!< a vertical tab bar 42 }; 43 44 /** Filp directions of ribbons */ 45 enum RibbonFlip 46 { 47 FLIP_NO, // For non-tab ribbons 48 FLIP_UP_LEFT, // For horizontal tabs it goes up vertical ones it goes left 49 FLIP_DOWN_RIGHT // For horizontal tabs it goes down vertical ones it goes right 50 }; 51 52 /** \brief A static text/icons/tabs bar widget. 53 * The contents of this ribbon are static. 54 * \ingroup widgetsgroup 55 * \note items you add to a list are kept after the the ribbon was in 56 * is removed (i.e. you don't need to add items everytime the 57 * screen is shown, only upon loading) 58 */ 59 class RibbonWidget : public Widget 60 { 61 public: 62 class IRibbonListener 63 { 64 public: ~IRibbonListener()65 virtual ~IRibbonListener(){} 66 virtual void onRibbonWidgetScroll(const int delta_x) = 0; 67 virtual void onRibbonWidgetFocus(RibbonWidget* emitter, 68 const int playerID) = 0; 69 virtual void onSelectionChange() = 0; 70 }; 71 72 private: 73 friend class DynamicRibbonWidget; 74 friend class EventHandler; 75 76 int m_selection[MAX_PLAYER_COUNT]; 77 78 /** The type of this ribbon (toolbar, combo, tabs, vertical tabs) */ 79 RibbonType m_ribbon_type; 80 81 /** The flip direction of this ribbon */ 82 RibbonFlip m_ribbon_flip; 83 84 /** Each item within the ribbon holds a flag saying whether it is 85 * selected or not. This method updates the flag in all of this 86 * ribbon's children. Called everytime selection changes.*/ 87 void updateSelection(); 88 89 /** Callbacks */ 90 virtual EventPropagation rightPressed(const int playerID=0) OVERRIDE; 91 virtual EventPropagation leftPressed (const int playerID=0) OVERRIDE; 92 virtual EventPropagation upPressed (const int playerID=0) OVERRIDE; 93 virtual EventPropagation downPressed (const int playerID=0) OVERRIDE; 94 EventPropagation moveToNextItem(const bool horizontally, const bool reverse, const int playerID); 95 EventPropagation propagationType(const bool horizontally); 96 void selectNextActiveWidget(const bool horizontally, const bool reverse, 97 const int playerID, const int old_selection); 98 virtual EventPropagation mouseHovered(Widget* child, 99 const int playerID) OVERRIDE; 100 virtual EventPropagation transmitEvent(Widget* w, 101 const std::string& originator, 102 const int playerID=0) OVERRIDE; 103 virtual EventPropagation focused(const int playerID) OVERRIDE; 104 virtual void unfocused(const int playerID, Widget* new_focus) OVERRIDE; 105 106 virtual EventPropagation onClick() OVERRIDE; 107 108 PtrVector<irr::gui::IGUIStaticText, REF> m_labels; 109 110 IRibbonListener* m_listener; 111 PtrVector<Widget> m_active_children; 112 113 public: 114 115 LEAK_CHECK() 116 117 /** Internal identifier of filler items that are added in a ribbon 118 * widget to filllines when the number of items cannot be divided 119 * by the number of rows in the grid (mostly used by dynamic ribbon 120 * widgets, but the base ribbon needs to know about filler items) 121 */ 122 static const char NO_ITEM_ID[]; 123 124 /** Contains which element within the ribbon is currently focused by 125 * player 0 (used by the skin to show mouse hovers over items that 126 * are not selected). Only used for COMBO and TAB ribbons. */ 127 Widget* m_mouse_focus; 128 129 RibbonWidget(const RibbonType type=RIBBON_COMBO); 130 virtual ~RibbonWidget(); 131 132 virtual void add() OVERRIDE; 133 134 /** Sets a listener that will be notified of changes on this ribbon. 135 * Does _not_ take ownership of the listener, i.e. will not delete it. 136 * You may call this with the listener parameter set to NULL to 137 * remove the listener. */ setListener(IRibbonListener * listener)138 void setListener(IRibbonListener* listener) { m_listener = listener; } 139 // -------------------------------------------------------------------- 140 /** Returns the type of this ribbon (see the GUI module overview page 141 * for detailed descriptions) */ getRibbonType() const142 RibbonType getRibbonType() const { return m_ribbon_type; } 143 // -------------------------------------------------------------------- 144 /** Returns the flip direction of thin ribbon */ getRibbonFlip() const145 RibbonFlip getRibbonFlip() const { return m_ribbon_flip; } 146 // -------------------------------------------------------------------- 147 /** Returns the number of active items within the ribbon */ getActiveChildrenNumber(const int playerID) const148 int getActiveChildrenNumber(const int playerID) const 149 { return m_active_children.size(); } 150 // -------------------------------------------------------------------- 151 /** Returns the numerical ID of the selected item within the ribbon */ getSelection(const int playerID) const152 int getSelection(const int playerID) const 153 { return m_selection[playerID]; } 154 // -------------------------------------------------------------------- 155 /** Returns the string ID (internal name) of the selection */ 156 const std::string& getSelectionIDString(const int playerID); 157 // -------------------------------------------------------------------- 158 /** Returns the user-visible text of the selection */ getSelectionText(const int playerID)159 irr::core::stringw getSelectionText(const int playerID) 160 { 161 const int selection = m_selection[playerID]; 162 if (selection < 0 || selection >= int(m_children.size())) return ""; 163 return m_children[selection].m_text; 164 } 165 // -------------------------------------------------------------------- 166 167 /** Sets the ID of the selected item within the ribbon */ setSelection(const int i,const int playerID)168 void setSelection(const int i, const int playerID) 169 { m_selection[playerID] = i; updateSelection(); } 170 171 /** Select an item in the ribbon by its internal name */ 172 void select(std::string item, const int playerID); 173 174 /** 175 * \brief This method can be used to rename an item. 176 * Has no effect for ribbons without individual labels. 177 * 178 * \pre Must be called after the ribbon was add()ed 179 * \param id The index of the item to rename, in range [0 .. item count - 1] 180 */ 181 void setLabel(const unsigned int id, irr::core::stringw new_name); 182 183 void setItemVisible(const unsigned int id, bool visible); 184 185 void setFlip(RibbonFlip direction); 186 187 /** Returns the ID of the item, or -1 if not found */ 188 int findItemNamed(const char* internalName); 189 190 /** Returns the the widget, or NULL if not found */ 191 GUIEngine::Widget * findWidgetNamed(const char* interalName); 192 193 /** \brief Dynamically (at runtime) add a text item to this ribbon 194 * \pre This must be called before RibbonWidget::add, while the 195 * widget is not yet displayed 196 * \pre only valid for ribbons that take text-only contents 197 * (e.g. tab bars) 198 */ 199 void addTextChild(const core::stringw& text, const std::string &id); 200 201 202 /** \brief Dynamically (at runtime) add an icon item to this ribbon. 203 * \pre this must be called before RibbonWidget::add, while the widget 204 * is not yet displayed 205 * \pre only valid for ribbons that take icon contents 206 */ 207 void addIconChild(const core::stringw& text, const std::string &id, 208 const int w, const int h, const std::string &icon, 209 const IconButtonWidget::IconPathType iconPathType= 210 IconButtonWidget::ICON_PATH_TYPE_RELATIVE); 211 212 /** 213 * \brief clear all children of this ribbon (likely because new ones will be added soon after) 214 * \pre this must be called before RibbonWidget::add, while the widget is not yet displayed 215 */ 216 void clearAllChildren(); 217 218 /** 219 * \brief clear one child from this ribbon 220 * \pre this must be called before RibbonWidget::add, while the widget is not yet displayed 221 */ 222 void removeChildNamed(const char* name); 223 getRibbonChildren()224 PtrVector<Widget>& getRibbonChildren() { return m_children; } 225 226 virtual EventPropagation onActivationInput(const int playerID) OVERRIDE; 227 }; 228 229 } 230 231 #endif 232