3969a907d5c4d54d12aab7f68d0d691a81f54c7b
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / TabView.cs
1 /*
2  * Copyright(c) 2023 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.ComponentModel;
19 using System.Diagnostics.CodeAnalysis;
20 using Tizen.NUI.BaseComponents;
21
22 namespace Tizen.NUI.Components
23 {
24     /// <summary>
25     /// TabView is a class which contains a TabBar and TabContent.
26     /// TabView adds TabButtons and Views to TabBar and TabContent in TabView by <see cref="TabView.AddTab"/>.
27     /// TabView removes TabButtons and Views from TabBar and TabContent in TabView by <see cref="TabView.RemoveTab"/>.
28     /// TabView selects a view from the TabContent according to the selected TabButton in the TabBar.
29     ///
30     /// <example>
31     /// <code>
32     /// var tabView = new TabView()
33     /// {
34     ///     WidthSpecification = LayoutParamPolicies.MatchParent,
35     ///     HeightSpecification = LayoutParamPolicies.MatchParent,
36     /// };
37     ///
38     /// var tabButton = new TabButton()
39     /// {
40     ///     Text = "Tab#1"
41     /// };
42     ///
43     /// var content = new View()
44     /// {
45     ///     BackgroundColor = Color.Red,
46     ///     WidthSpecification = LayoutParamPolicies.MatchParent,
47     ///     HeightSpecification = LayoutParamPolicies.MatchParent,
48     /// };
49     ///
50     /// tabView.AddTab(tabButton, content);
51     ///
52     /// var tabButton2 = new TabButton()
53     /// {
54     ///     Text = "Tab#2"
55     /// };
56     ///
57     /// var content2 = new View()
58     /// {
59     ///     BackgroundColor = Color.Green,
60     ///     WidthSpecification = LayoutParamPolicies.MatchParent,
61     ///     HeightSpecification = LayoutParamPolicies.MatchParent,
62     /// };
63     ///
64     /// tabView.AddTab(tabButton2, content2);
65     ///
66     /// var tabButton3 = new TabButton()
67     /// {
68     ///     Text = "Tab#3"
69     /// };
70     ///
71     /// var content3 = new View()
72     /// {
73     ///     BackgroundColor = Color.Blue,
74     ///     WidthSpecification = LayoutParamPolicies.MatchParent,
75     ///     HeightSpecification = LayoutParamPolicies.MatchParent,
76     /// };
77     ///
78     /// tabView.AddTab(tabButton3, content3);
79     /// </code>
80     /// </example>
81     /// </summary>
82     /// <since_tizen> 9 </since_tizen>
83     public class TabView : Control
84     {
85         private TabBar tabBar = null;
86
87         private TabContent content = null;
88
89         private void Initialize()
90         {
91             Layout = new LinearLayout() { LinearOrientation = LinearLayout.Orientation.Vertical };
92             WidthSpecification = LayoutParamPolicies.MatchParent;
93             HeightSpecification = LayoutParamPolicies.MatchParent;
94
95             InitTabBar();
96             InitContent();
97
98             // To show TabBar's shadow TabBar is raised above Content.
99             TabBar.RaiseAbove(Content);
100         }
101
102         /// <summary>
103         /// Creates a new instance of TabView.
104         /// </summary>
105         /// <since_tizen> 9 </since_tizen>
106         public TabView()
107         {
108             Initialize();
109         }
110
111         /// <summary>
112         /// Creates a new instance of a TabView with style.
113         /// </summary>
114         /// <param name="style">A style applied to the newly created TabView.</param>
115         [EditorBrowsable(EditorBrowsableState.Never)]
116         public TabView(ControlStyle style) : base(style)
117         {
118             Initialize();
119         }
120
121         /// <inheritdoc/>
122         [EditorBrowsable(EditorBrowsableState.Never)]
123         public override void OnInitialize()
124         {
125             base.OnInitialize();
126
127             AccessibilityRole = Role.PageTabList;
128         }
129
130         private void InitTabBar()
131         {
132             if (tabBar != null)
133             {
134                 return;
135             }
136
137             tabBar = new TabBar();
138             tabBar.TabButtonSelected += tabButtonSelectedHandler;
139
140             Add(tabBar);
141         }
142
143         private void InitContent()
144         {
145             if (content != null)
146             {
147                 return;
148             }
149
150             content = new TabContent();
151             content.WidthSpecification = LayoutParamPolicies.MatchParent;
152             content.HeightSpecification = LayoutParamPolicies.MatchParent;
153
154             Add(content);
155         }
156
157         private void tabButtonSelectedHandler(object sender, TabButtonSelectedEventArgs args)
158         {
159             if ((content != null) && (content.ViewCount > args.Index))
160             {
161                 content.SelectContentView(args.Index);
162             }
163         }
164
165         /// <summary>
166         /// Gets TabBar of TabView.
167         /// </summary>
168         /// <since_tizen> 9 </since_tizen>
169         public TabBar TabBar
170         {
171             get
172             {
173                 return tabBar;
174             }
175
176             [EditorBrowsable(EditorBrowsableState.Never)]
177             protected set
178             {
179                 if (tabBar != null)
180                 {
181                     tabBar.TabButtonSelected -= tabButtonSelectedHandler;
182                     Utility.Dispose(tabBar);
183                 }
184
185                 tabBar = value;
186                 Add(tabBar);
187             }
188         }
189
190         /// <summary>
191         /// Gets TabContent of TabView.
192         /// </summary>
193         /// <since_tizen> 9 </since_tizen>
194         public TabContent Content
195         {
196             get
197             {
198                 return content;
199             }
200
201             [EditorBrowsable(EditorBrowsableState.Never)]
202             protected set
203             {
204                 if (content != null)
205                 {
206                     Utility.Dispose(content);
207                 }
208
209                 content = value;
210                 Add(content);
211             }
212         }
213
214         /// <summary>
215         /// Adds a tab with tab button and content view.
216         /// </summary>
217         /// <param name="tabButton">A tab button to be added.</param>
218         /// <param name="view">A content view to be added.</param>
219         /// <since_tizen> 9 </since_tizen>
220         public void AddTab(TabButton tabButton, View view)
221         {
222             if (TabBar != null)
223             {
224                 TabBar.AddTabButton(tabButton);
225             }
226
227             if (Content != null)
228             {
229                 Content.AddContentView(view);
230             }
231         }
232
233         /// <summary>
234         /// Removes a tab at the specified index of TabView.
235         /// The indices of tabs(tab buttons and views) in TabView are basically the order of adding to TabView by <see cref="TabView.AddTab"/>.
236         /// So the index of a tab(tab button and view) in TabView can be changed whenever <see cref="TabView.AddTab"/> or <see cref="TabView.RemoveTab"/> is called.
237         /// </summary>
238         /// <param name="index">The index of a tab(tab button and view) in TabView where the tab will be removed.</param>
239         /// <exception cref="ArgumentOutOfRangeException">Thrown when the index is less than 0, or greater than or equal to the number of tabs.</exception>
240         /// <since_tizen> 9 </since_tizen>
241         public void RemoveTab(int index)
242         {
243             var tabButton = TabBar.GetTabButton(index);
244             if (tabButton != null)
245             {
246                 TabBar.RemoveTabButton(tabButton);
247             }
248
249             var view = Content.GetView(index);
250             if (view != null)
251             {
252                 Content.RemoveContentView(view);
253             }
254         }
255
256         /// <summary>
257         /// Adds a tab from the given TabItem.
258         /// TabItem contains Title and IconURL of a new TabButton in TabBar and Content of a new View in TabContent.
259         /// <param name="tabItem">The tab item which contains Title and IconURL of a new TabButton in TabBar and Content of a new View in TabContent.</param>
260         /// </summary>
261         [EditorBrowsable(EditorBrowsableState.Never)]
262         [SuppressMessage("Microsoft.Reliability",
263                          "CA2000:DisposeObjectsBeforeLosingScope",
264                          Justification = "The tabButton is added to TabBar and disposed when TabBar is disposed.")]
265         public virtual void Add(TabItem tabItem)
266         {
267             if (tabItem == null) return;
268
269             var hasTitle = (String.IsNullOrEmpty(tabItem.Title) == false);
270             var hasIconUrl = (String.IsNullOrEmpty(tabItem.IconUrl) == false);
271
272             // Adds a new TabButton and Content View only if TabItem has TabButton properties and Content View.
273             if ((hasTitle || hasIconUrl) && (tabItem.Content != null))
274             {
275                 var tabButton = new TabButton(tabItem.TabButtonStyle);
276
277                 if (hasTitle)
278                 {
279                     tabButton.Text = tabItem.Title;
280                 }
281
282                 if (hasIconUrl)
283                 {
284                     tabButton.IconURL = tabItem.IconUrl;
285                 }
286
287                 TabBar.AddTabButton(tabButton);
288
289                 Content.AddContentView(tabItem.Content);
290             }
291         }
292
293         /// <inheritdoc/>
294         [EditorBrowsable(EditorBrowsableState.Never)]
295         protected override void Dispose(DisposeTypes type)
296         {
297             if (disposed)
298             {
299                 return;
300             }
301
302             if (type == DisposeTypes.Explicit)
303             {
304                 if (tabBar != null)
305                 {
306                     tabBar.TabButtonSelected -= tabButtonSelectedHandler;
307                     Utility.Dispose(tabBar);
308                 }
309
310                 if (content != null)
311                 {
312                     Utility.Dispose(content);
313                 }
314             }
315
316             base.Dispose(type);
317         }
318     }
319 }