1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 By using JUCE, you agree to the terms of both the JUCE 6 End-User License 11 Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). 12 13 End User License Agreement: www.juce.com/juce-6-licence 14 Privacy Policy: www.juce.com/juce-privacy-policy 15 16 Or: You may also use this code under the terms of the GPL v3 (see 17 www.gnu.org/licenses). 18 19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 21 DISCLAIMED. 22 23 ============================================================================== 24 */ 25 26 namespace juce 27 { 28 29 //============================================================================== 30 /** 31 A component with a TabbedButtonBar along one of its sides. 32 33 This makes it easy to create a set of tabbed pages, just add a bunch of tabs 34 with addTab(), and this will take care of showing the pages for you when the 35 user clicks on a different tab. 36 37 @see TabbedButtonBar 38 39 @tags{GUI} 40 */ 41 class JUCE_API TabbedComponent : public Component 42 { 43 public: 44 //============================================================================== 45 /** Creates a TabbedComponent, specifying where the tabs should be placed. 46 Once created, add some tabs with the addTab() method. 47 */ 48 explicit TabbedComponent (TabbedButtonBar::Orientation orientation); 49 50 /** Destructor. */ 51 ~TabbedComponent() override; 52 53 //============================================================================== 54 /** Changes the placement of the tabs. 55 56 This will rearrange the layout to place the tabs along the appropriate 57 side of this component, and will shift the content component accordingly. 58 59 @see TabbedButtonBar::setOrientation 60 */ 61 void setOrientation (TabbedButtonBar::Orientation orientation); 62 63 /** Returns the current tab placement. 64 @see setOrientation, TabbedButtonBar::getOrientation 65 */ 66 TabbedButtonBar::Orientation getOrientation() const noexcept; 67 68 /** Specifies how many pixels wide or high the tab-bar should be. 69 70 If the tabs are placed along the top or bottom, this specified the height 71 of the bar; if they're along the left or right edges, it'll be the width 72 of the bar. 73 */ 74 void setTabBarDepth (int newDepth); 75 76 /** Returns the current thickness of the tab bar. 77 @see setTabBarDepth 78 */ getTabBarDepth()79 int getTabBarDepth() const noexcept { return tabDepth; } 80 81 /** Specifies the thickness of an outline that should be drawn around the content component. 82 83 If this thickness is > 0, a line will be drawn around the three sides of the content 84 component which don't touch the tab-bar, and the content component will be inset by this amount. 85 86 To set the colour of the line, use setColour (outlineColourId, ...). 87 */ 88 void setOutline (int newThickness); 89 90 /** Specifies a gap to leave around the edge of the content component. 91 Each edge of the content component will be indented by the given number of pixels. 92 */ 93 void setIndent (int indentThickness); 94 95 //============================================================================== 96 /** Removes all the tabs from the bar. 97 @see TabbedButtonBar::clearTabs 98 */ 99 void clearTabs(); 100 101 /** Adds a tab to the tab-bar. 102 103 The component passed in will be shown for the tab. If deleteComponentWhenNotNeeded 104 is true, then the TabbedComponent will take ownership of the component and will delete 105 it when the tab is removed or when this object is deleted. 106 107 @see TabbedButtonBar::addTab 108 */ 109 void addTab (const String& tabName, 110 Colour tabBackgroundColour, 111 Component* contentComponent, 112 bool deleteComponentWhenNotNeeded, 113 int insertIndex = -1); 114 115 /** Changes the name of one of the tabs. */ 116 void setTabName (int tabIndex, const String& newName); 117 118 /** Gets rid of one of the tabs. */ 119 void removeTab (int tabIndex); 120 121 /** Moves a tab to a new index in the list. 122 Pass -1 as the index to move it to the end of the list. 123 */ 124 void moveTab (int currentIndex, int newIndex, bool animate = false); 125 126 /** Returns the number of tabs in the bar. */ 127 int getNumTabs() const; 128 129 /** Returns a list of all the tab names in the bar. */ 130 StringArray getTabNames() const; 131 132 /** Returns the content component that was added for the given index. 133 Be careful not to reposition or delete the components that are returned, as 134 this will interfere with the TabbedComponent's behaviour. 135 */ 136 Component* getTabContentComponent (int tabIndex) const noexcept; 137 138 /** Returns the colour of one of the tabs. */ 139 Colour getTabBackgroundColour (int tabIndex) const noexcept; 140 141 /** Changes the background colour of one of the tabs. */ 142 void setTabBackgroundColour (int tabIndex, Colour newColour); 143 144 //============================================================================== 145 /** Changes the currently-selected tab. 146 To deselect all the tabs, pass -1 as the index. 147 @see TabbedButtonBar::setCurrentTabIndex 148 */ 149 void setCurrentTabIndex (int newTabIndex, bool sendChangeMessage = true); 150 151 /** Returns the index of the currently selected tab. 152 @see addTab, TabbedButtonBar::getCurrentTabIndex() 153 */ 154 int getCurrentTabIndex() const; 155 156 /** Returns the name of the currently selected tab. 157 @see addTab, TabbedButtonBar::getCurrentTabName() 158 */ 159 String getCurrentTabName() const; 160 161 /** Returns the current component that's filling the panel. 162 This will return nullptr if there isn't one. 163 */ getCurrentContentComponent()164 Component* getCurrentContentComponent() const noexcept { return panelComponent.get(); } 165 166 //============================================================================== 167 /** Callback method to indicate the selected tab has been changed. 168 @see setCurrentTabIndex 169 */ 170 virtual void currentTabChanged (int newCurrentTabIndex, const String& newCurrentTabName); 171 172 /** Callback method to indicate that the user has right-clicked on a tab. */ 173 virtual void popupMenuClickOnTab (int tabIndex, const String& tabName); 174 175 /** Returns the tab button bar component that is being used. */ getTabbedButtonBar()176 TabbedButtonBar& getTabbedButtonBar() const noexcept { return *tabs; } 177 178 //============================================================================== 179 /** A set of colour IDs to use to change the colour of various aspects of the component. 180 181 These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() 182 methods. 183 184 @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour 185 */ 186 enum ColourIds 187 { 188 backgroundColourId = 0x1005800, /**< The colour to fill the background behind the tabs. */ 189 outlineColourId = 0x1005801, /**< The colour to use to draw an outline around the content. 190 (See setOutline) */ 191 }; 192 193 //============================================================================== 194 /** @internal */ 195 void paint (Graphics&) override; 196 /** @internal */ 197 void resized() override; 198 /** @internal */ 199 void lookAndFeelChanged() override; 200 201 protected: 202 //============================================================================== 203 /** This creates one of the tab buttons. 204 205 If you need to use custom tab components, you can override this method and 206 return your own class instead of the default. 207 */ 208 virtual TabBarButton* createTabButton (const String& tabName, int tabIndex); 209 210 /** @internal */ 211 std::unique_ptr<TabbedButtonBar> tabs; 212 213 private: 214 //============================================================================== 215 Array<WeakReference<Component>> contentComponents; 216 WeakReference<Component> panelComponent; 217 int tabDepth = 30, outlineThickness = 1, edgeIndent = 0; 218 219 struct ButtonBar; 220 void changeCallback (int newCurrentTabIndex, const String& newTabName); 221 222 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TabbedComponent) 223 }; 224 225 } // namespace juce 226