/* * Copyright(c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using System.Collections.Generic; using System.ComponentModel; using Tizen.NUI.BaseComponents; namespace Tizen.NUI.Components { /// /// TabButtonSelectedEventArgs is a class to record tab button selected event /// arguments which will be sent to a user. /// [EditorBrowsable(EditorBrowsableState.Never)] public class TabButtonSelectedEventArgs : EventArgs { /// /// Creates a new instance of TabButtonSelectedEventArgs. /// The indices of tab buttons in TabBar are basically the order of adding to TabBar by . /// So a tab button's index in TabBar can be changed whenever or is called. /// /// The index of the selected tab button in TabBar. [EditorBrowsable(EditorBrowsableState.Never)] public TabButtonSelectedEventArgs(int index) { Index = index; } /// /// The index of the selected tab button. /// [EditorBrowsable(EditorBrowsableState.Never)] public int Index { get; } } /// /// TabBar is a class which contains a set of TabButtons and has one of them selected. /// /// 9 public class TabBar : Control { private IList tabButtons; private TabButtonGroup tabButtonGroup; /// /// Creates a new instance of TabBar. /// /// 9 public TabBar() { Layout = new LinearLayout() { LinearOrientation = LinearLayout.Orientation.Horizontal }; WidthSpecification = LayoutParamPolicies.MatchParent; tabButtons = new List(); tabButtonGroup = new TabButtonGroup(); SelectedIndex = -1; } /// /// An event for the tab button selected signal which can be used to /// subscribe or unsubscribe the event handler provided by a user. /// [EditorBrowsable(EditorBrowsableState.Never)] public event EventHandler TabButtonSelected; /// /// The index of the selected tab button. /// The indices of tab buttons in TabBar are basically the order of adding to TabBar by . /// So a tab button's index in TabBar can be changed whenever or is called. /// [EditorBrowsable(EditorBrowsableState.Never)] protected int SelectedIndex { get; set; } /// /// Gets the count of tab buttons. /// /// 9 public int TabButtonCount => tabButtons.Count; /// [EditorBrowsable(EditorBrowsableState.Never)] public override void OnInitialize() { base.OnInitialize(); SetAccessibilityConstructor(Role.PageTabList); } /// /// Adds a tab button to TabBar. /// /// A tab button to be added to TabBar. /// Thrown when the argument tabButton is null. [EditorBrowsable(EditorBrowsableState.Never)] protected internal void AddTabButton(TabButton tabButton) { if (tabButton == null) { throw new ArgumentNullException(nameof(tabButton), "tabButton should not be null."); } tabButtons.Add(tabButton); Add(tabButton); tabButtonGroup.Add(tabButton); tabButton.Clicked += (object sender, ClickedEventArgs e) => { int index = tabButtons.IndexOf(tabButton); if (SelectedIndex == index) { return; } SelectedIndex = index; if (TabButtonSelected != null) { TabButtonSelectedEventArgs args = new TabButtonSelectedEventArgs(SelectedIndex); TabButtonSelected(this, args); } }; if (SelectedIndex == -1) { tabButton.IsSelected = true; SelectedIndex = 0; if (TabButtonSelected != null) { TabButtonSelectedEventArgs args = new TabButtonSelectedEventArgs(SelectedIndex); TabButtonSelected(this, args); } } //TODO: To support non-unified tab button size. CalculateUnifiedTabButtonSize(); } /// /// Removes a tab button from TabBar. /// /// A tab button to be removed from TabBar. /// Thrown when the argument tabButton is null. /// Thrown when the argument tabButton does not exist in TabBar. [EditorBrowsable(EditorBrowsableState.Never)] protected internal void RemoveTabButton(TabButton tabButton) { if (tabButton == null) { throw new ArgumentNullException(nameof(tabButton), "tabButton should not be null."); } if (tabButtons.Contains(tabButton) == false) { throw new ArgumentException("tabButton does not exist in TabBar.", nameof(tabButton)); } int index = tabButtons.IndexOf(tabButton); TabButton selectedTabButton = tabButtons[SelectedIndex]; tabButtons.Remove(tabButton); Remove(tabButton); tabButtonGroup.Remove(tabButton); if ((index < SelectedIndex) || (tabButtons.Count == SelectedIndex)) { SelectedIndex -= 1; if (TabButtonSelected != null) { TabButtonSelectedEventArgs args = new TabButtonSelectedEventArgs(SelectedIndex); TabButtonSelected(this, args); } } if ((SelectedIndex != -1) && (selectedTabButton != tabButtons[SelectedIndex])) { tabButtons[SelectedIndex].IsSelected = true; } //TODO: To support non-unified tab button size. CalculateUnifiedTabButtonSize(); } /// [EditorBrowsable(EditorBrowsableState.Never)] public override void OnRelayout(Vector2 size, RelayoutContainer container) { base.OnRelayout(size, container); //TODO: To support non-unified tab button size. CalculateUnifiedTabButtonSize(); } private void CalculateUnifiedTabButtonSize() { if (tabButtons.Count <= 0) { return; } var tabButtonWidth = Size.Width / tabButtons.Count; foreach (TabButton tabButton in tabButtons) { if (tabButton.Size.Width != tabButtonWidth) { tabButton.Size = new Size(tabButtonWidth, tabButton.Size.Height); } } } /// /// Gets the tab button at the specified index of TabBar. /// The indices of tab buttons in TabBar are basically the order of adding to TabBar by . /// So a tab button's index in TabBar can be changed whenever or is called. /// /// The index of tab button in TabBar where the specified tab button exists. /// Thrown when the index is less than 0, or greater than or equal to the number of tab buttons. /// 9 public TabButton GetTabButton(int index) { if ((index < 0) || (index >= tabButtons.Count)) { throw new ArgumentOutOfRangeException(nameof(index), "index should not be greater than or equal to 0, and less than the number of tab buttons."); } return tabButtons[index]; } /// [EditorBrowsable(EditorBrowsableState.Never)] protected override void Dispose(DisposeTypes type) { if (disposed) { return; } if (type == DisposeTypes.Explicit) { if (tabButtons != null) { foreach (TabButton tabButton in tabButtons) { Utility.Dispose(tabButton); } tabButtons = null; } tabButtonGroup = null; } base.Dispose(type); } } }