2 * Copyright(c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 using System.ComponentModel;
18 using System.Diagnostics.CodeAnalysis;
19 using Tizen.NUI.BaseComponents;
21 namespace Tizen.NUI.Components
24 /// TabButton is a class which is used for selecting one content in a TabView.
26 [EditorBrowsable(EditorBrowsableState.Never)]
27 public class TabButton : SelectButton
29 private bool selectedAgain = false;
31 private TabButtonStyle tabButtonStyle = null;
33 private bool styleApplied = false;
35 private View topLine = null;
36 private View bottomLine = null; // Visible only if TabButton is selected or pressed.
39 /// Creates a new instance of TabButton.
41 [EditorBrowsable(EditorBrowsableState.Never)]
48 /// Creates a new instance of TabButton.
50 /// <param name="style">Creates TabButton by special style defined in UX.</param>
51 [EditorBrowsable(EditorBrowsableState.Never)]
52 public TabButton(string style) : base(style)
58 /// Creates a new instance of TabButton.
60 /// <param name="tabButtonStyle">Creates TabButton by style customized by user.</param>
61 [EditorBrowsable(EditorBrowsableState.Never)]
62 public TabButton(TabButtonStyle tabButtonStyle) : base(tabButtonStyle)
68 /// Applies style to TabButton.
70 /// <param name="viewStyle">The style to apply.</param>
71 [EditorBrowsable(EditorBrowsableState.Never)]
72 public override void ApplyStyle(ViewStyle viewStyle)
76 base.ApplyStyle(viewStyle);
78 tabButtonStyle = viewStyle as TabButtonStyle;
80 //Apply TopLine style.
81 if (tabButtonStyle?.TopLine != null)
83 topLine?.ApplyStyle(tabButtonStyle.TopLine);
86 //Apply BottomLine style.
87 if (tabButtonStyle?.BottomLine != null)
89 bottomLine?.ApplyStyle(tabButtonStyle.BottomLine);
94 //Calculate children's sizes and positions based on padding sizes.
99 [EditorBrowsable(EditorBrowsableState.Never)]
100 public override bool OnKey(Key key)
102 if ((IsEnabled == false) || (key == null))
107 if (key.State == Key.StateType.Up)
109 if (key.KeyPressedName == "Return")
111 if (IsSelected == true)
113 selectedAgain = true;
118 bool ret = base.OnKey(key);
120 if (selectedAgain == true)
123 selectedAgain = false;
130 /// Dispose TabButton and all children on it.
132 /// <param name="type">Dispose type.</param>
133 [EditorBrowsable(EditorBrowsableState.Never)]
134 protected override void Dispose(DisposeTypes type)
141 if (type == DisposeTypes.Explicit)
145 Utility.Dispose(topLine);
148 if (bottomLine != null)
150 Utility.Dispose(bottomLine);
158 /// Gets TabButton style.
160 /// <returns>The default TabButton style.</returns>
161 [EditorBrowsable(EditorBrowsableState.Never)]
162 protected override ViewStyle CreateViewStyle()
164 return new TabButtonStyle();
168 [EditorBrowsable(EditorBrowsableState.Never)]
169 protected override bool HandleControlStateOnTouch(Touch touch)
171 if ((IsEnabled == false) || (touch == null))
176 PointStateType state = touch.GetState(0);
179 case PointStateType.Up:
180 if (IsSelected == true)
182 selectedAgain = true;
189 bool ret = base.HandleControlStateOnTouch(touch);
191 if (selectedAgain == true)
194 selectedAgain = false;
201 [SuppressMessage("Microsoft.Design",
202 "CA1062: Validate arguments of public methods",
203 MessageId = "controlStateChangedInfo",
204 Justification = "OnControlStateChanged is called when controlState is changed so controlStateChangedInfo cannot be null.")]
205 [EditorBrowsable(EditorBrowsableState.Never)]
206 protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
208 if (controlStateChangedInfo.PreviousState.Contains(ControlState.Selected) != controlStateChangedInfo.CurrentState.Contains(ControlState.Selected))
210 // TabButton does not invoke SelectedChanged if button or key is
211 // unpressed while its state is selected.
212 if (selectedAgain == true)
217 base.OnControlStateChanged(controlStateChangedInfo);
222 [EditorBrowsable(EditorBrowsableState.Never)]
223 protected override void OnUpdate()
230 [EditorBrowsable(EditorBrowsableState.Never)]
231 protected override void LayoutItems()
233 if (styleApplied == false)
238 if ((Icon == null) && (TextLabel == null))
243 // Icon is added in Button.LayoutItems().
244 if ((Icon != null) && (Children.Contains(Icon) == false))
249 // TextLabel is added in Button.LayoutItems().
250 if ((TextLabel != null) && (Children.Contains(TextLabel) == false))
255 // FIXME: set Selector<Extents> to padding
256 var padding = new Extents(40, 40, 24, 24);
257 var iconPadding = IconPadding;
258 var textPadding = TextPadding;
260 // Calculate size of TextLabel.
261 if (TextLabel != null)
263 // TODO: Other orientation cases are not implemented yet.
264 if ((IconRelativeOrientation == IconOrientation.Left) || (IconRelativeOrientation == IconOrientation.Right))
266 var naturalWidthSum = (ushort)padding?.Start + (ushort)padding?.End + iconPadding.Start + iconPadding.End + (float)Icon?.SizeWidth + TextLabel.GetNaturalSize().Width;
267 var naturalWidthDiff = SizeWidth - naturalWidthSum;
269 if (naturalWidthDiff > 0)
271 TextLabel.SizeWidth = TextLabel.GetNaturalSize().Width;
275 TextLabel.SizeWidth = SizeWidth - (ushort)padding?.Start - (ushort)padding?.End - iconPadding.Start - iconPadding.End - textPadding.Start - textPadding.End - (float)Icon?.SizeWidth;
280 // Calculate positions of Icon and TextLabel.
281 switch (IconRelativeOrientation)
283 // TODO: Other orientation cases are not implemented yet.
284 case IconOrientation.Left:
285 if (LayoutDirection == ViewLayoutDirectionType.LTR)
290 float iconY = (ushort)padding?.Top + iconPadding.Top;
292 if (string.IsNullOrEmpty(TextLabel?.Text))
294 iconX = (SizeWidth - Icon.SizeWidth) / 2;
298 var widthSum = (ushort)padding?.Start + (ushort)padding?.End + iconPadding.Start + iconPadding.End + textPadding.Start + textPadding.End + Icon.SizeWidth + (float)TextLabel?.SizeWidth;
299 var widthDiff = SizeWidth - widthSum;
303 iconX = (ushort)padding?.Start + iconPadding.Start + (widthDiff / 2);
307 iconX = (ushort)padding?.Start + iconPadding.Start;
311 Icon.Position = new Position(iconX, iconY);
314 if (TextLabel != null)
316 TextLabel.HorizontalAlignment = HorizontalAlignment.Begin;
321 if (string.IsNullOrEmpty(Icon?.ResourceUrl))
323 textX = (SizeWidth - TextLabel.SizeWidth) / 2;
324 textY = (ushort)padding?.Top + textPadding.Top;
328 textX = (float)Icon?.PositionX + (float)Icon?.SizeWidth;
329 textY = (ushort)padding?.Top + textPadding.Top + (((float)Icon?.SizeHeight - TextLabel.SizeHeight) / 2);
332 TextLabel.Position = new Position(textX, textY);
343 private void Initialize()
345 Layout = new AbsoluteLayout();
347 topLine = new View(tabButtonStyle?.TopLine);
350 bottomLine = new View(tabButtonStyle?.BottomLine);