[NUI] Fix license year information for TabView classes
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / TabBar.cs
1 /*
2  * Copyright(c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 using System;
18 using System.Collections.Generic;
19 using System.ComponentModel;
20 using Tizen.NUI.BaseComponents;
21
22 namespace Tizen.NUI.Components
23 {
24     /// <summary>
25     /// TabButtonSelectedEventArgs is a class to record tab button selected event
26     /// arguments which will be sent to a user.
27     /// </summary>
28     [EditorBrowsable(EditorBrowsableState.Never)]
29     public class TabButtonSelectedEventArgs : EventArgs
30     {
31         /// <summary>
32         /// Creates a new instance of TabButtonSelectedEventArgs.
33         /// </summary>
34         /// <param name="index">The selected index.</param>
35         [EditorBrowsable(EditorBrowsableState.Never)]
36         public TabButtonSelectedEventArgs(int index)
37         {
38             Index = index;
39         }
40
41         /// <summary>
42         /// The index of the selected tab button.
43         /// </summary>
44         [EditorBrowsable(EditorBrowsableState.Never)]
45         public int Index { get; }
46     }
47
48     /// <summary>
49     /// TabBar is a class which contains a set of TabButtons and has one of them selected.
50     /// </summary>
51     [EditorBrowsable(EditorBrowsableState.Never)]
52     public class TabBar : Control
53     {
54         private IList<TabButton> tabButtons;
55
56         private TabButtonGroup tabButtonGroup;
57
58         /// <summary>
59         /// Creates a new instance of TabBar.
60         /// </summary>
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         public TabBar()
63         {
64             Layout = new LinearLayout() { LinearOrientation = LinearLayout.Orientation.Horizontal };
65
66             WidthSpecification = LayoutParamPolicies.MatchParent;
67
68             tabButtons = new List<TabButton>();
69             tabButtonGroup = new TabButtonGroup();
70             SelectedIndex = -1;
71         }
72
73         /// <summary>
74         /// An event for the tab button selected signal which can be used to
75         /// subscribe or unsubscribe the event handler provided by a user.
76         /// </summary>
77         [EditorBrowsable(EditorBrowsableState.Never)]
78         public event EventHandler<TabButtonSelectedEventArgs> TabButtonSelected;
79
80         /// <summary>
81         /// The index of the selected tab button.
82         /// </summary>
83         [EditorBrowsable(EditorBrowsableState.Never)]
84         protected int SelectedIndex { get; set; }
85
86         /// <summary>
87         /// Gets the count of tab buttons.
88         /// </summary>
89         [EditorBrowsable(EditorBrowsableState.Never)]
90         public int TabButtonCount => tabButtons.Count;
91
92         /// <summary>
93         /// Adds a tab button to TabBar.
94         /// </summary>
95         /// <param name="tabButton">A tab button to be added to TabBar.</param>
96         /// <exception cref="ArgumentNullException">Thrown when the argument tabButton is null.</exception>
97         [EditorBrowsable(EditorBrowsableState.Never)]
98         protected internal void AddTabButton(TabButton tabButton)
99         {
100             if (tabButton == null)
101             {
102                 throw new ArgumentNullException(nameof(tabButton), "tabButton should not be null.");
103             }
104
105             tabButtons.Add(tabButton);
106             Add(tabButton);
107             tabButtonGroup.Add(tabButton);
108
109             tabButton.Clicked += (object sender, ClickedEventArgs e) =>
110             {
111                 int index = tabButtons.IndexOf(tabButton);
112
113                 if (SelectedIndex == index)
114                 {
115                     return;
116                 }
117
118                 SelectedIndex = index;
119
120                 if (TabButtonSelected != null)
121                 {
122                     TabButtonSelectedEventArgs args = new TabButtonSelectedEventArgs(SelectedIndex);
123                     TabButtonSelected(this, args);
124                 }
125             };
126
127             if (SelectedIndex == -1)
128             {
129                 tabButton.IsSelected = true;
130                 SelectedIndex = 0;
131
132                 if (TabButtonSelected != null)
133                 {
134                     TabButtonSelectedEventArgs args = new TabButtonSelectedEventArgs(SelectedIndex);
135                     TabButtonSelected(this, args);
136                 }
137             }
138
139             //TODO: To support non-unified tab button size.
140             CalculateUnifiedTabButtonSize();
141         }
142
143         /// <summary>
144         /// Removes a tab button from TabBar.
145         /// </summary>
146         /// <param name="tabButton">A tab button to be removed from TabBar.</param>
147         /// <exception cref="ArgumentNullException">Thrown when the argument tabButton is null.</exception>
148         /// <exception cref="ArgumentException">Thrown when the argument tabButton does not exist in TabBar.</exception>
149         [EditorBrowsable(EditorBrowsableState.Never)]
150         protected internal void RemoveTabButton(TabButton tabButton)
151         {
152             if (tabButton == null)
153             {
154                 throw new ArgumentNullException(nameof(tabButton), "tabButton should not be null.");
155             }
156
157             if (tabButtons.Contains(tabButton) == false)
158             {
159                 throw new ArgumentException("tabButton does not exist in TabBar.", nameof(tabButton));
160             }
161
162             int index = tabButtons.IndexOf(tabButton);
163             TabButton selectedTabButton = tabButtons[SelectedIndex];
164
165             tabButtons.Remove(tabButton);
166             Remove(tabButton);
167             tabButtonGroup.Remove(tabButton);
168
169             if ((index < SelectedIndex) || (tabButtons.Count == SelectedIndex))
170             {
171                 SelectedIndex -= 1;
172
173                 if (TabButtonSelected != null)
174                 {
175                     TabButtonSelectedEventArgs args = new TabButtonSelectedEventArgs(SelectedIndex);
176                     TabButtonSelected(this, args);
177                 }
178             }
179
180             if ((SelectedIndex != -1) && (selectedTabButton != tabButtons[SelectedIndex]))
181             {
182                 tabButtons[SelectedIndex].IsSelected = true;
183             }
184
185             //TODO: To support non-unified tab button size.
186             CalculateUnifiedTabButtonSize();
187         }
188
189         /// <inheritdoc/>
190         public override void OnRelayout(Vector2 size, RelayoutContainer container)
191         {
192             base.OnRelayout(size, container);
193
194             //TODO: To support non-unified tab button size.
195             CalculateUnifiedTabButtonSize();
196         }
197
198         private void CalculateUnifiedTabButtonSize()
199         {
200             if (tabButtons.Count <= 0)
201             {
202                 return;
203             }
204
205             var tabButtonWidth = Size.Width / tabButtons.Count;
206
207             foreach (TabButton tabButton in tabButtons)
208             {
209                 if (tabButton.Size.Width != tabButtonWidth)
210                 {
211                     tabButton.Size = new Size(tabButtonWidth, tabButton.Size.Height);
212                 }
213             }
214         }
215
216         /// <summary>
217         /// Gets the tab button at the specified index of TabBar.
218         /// </summary>
219         /// <param name="index">The index of TabBar where the specified tab button exists.</param>
220         /// <exception cref="ArgumentOutOfRangeException">Thrown when the index is less than 0, or greater than or equal to the number of tab buttons.</exception>
221         [EditorBrowsable(EditorBrowsableState.Never)]
222         public TabButton GetTabButton(int index)
223         {
224             if ((index < 0) || (index >= tabButtons.Count))
225             {
226                 throw new ArgumentOutOfRangeException(nameof(index), "index should not be greater than or equal to 0, and less than the number of tab buttons.");
227             }
228
229             return tabButtons[index];
230         }
231
232         /// <summary>
233         /// Dispose TabBar and all children on it.
234         /// </summary>
235         /// <param name="type">Dispose type.</param>
236         [EditorBrowsable(EditorBrowsableState.Never)]
237         protected override void Dispose(DisposeTypes type)
238         {
239             if (disposed)
240             {
241                 return;
242             }
243
244             if (type == DisposeTypes.Explicit)
245             {
246                 if (tabButtons != null)
247                 {
248                     foreach (TabButton tabButton in tabButtons)
249                     {
250                         Utility.Dispose(tabButton);
251                     }
252
253                     tabButtons = null;
254                 }
255
256                 tabButtonGroup = null;
257             }
258
259             base.Dispose(type);
260         }
261     }
262 }