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.
19 using System.ComponentModel;
20 using Tizen.NUI.BaseComponents;
21 using Tizen.NUI.Components.Extension;
22 using Tizen.NUI.Accessibility; // To use AccessibilityManager
24 namespace Tizen.NUI.Components
26 public partial class Button
28 private ImageView overlayImage;
29 private TextLabel buttonText;
30 private ImageView buttonIcon;
32 private EventHandler<StateChangedEventArgs> stateChangeHandler;
34 private bool isPressed = false;
35 private bool styleApplied = false;
38 /// Get accessibility name.
40 [EditorBrowsable(EditorBrowsableState.Never)]
41 protected override string AccessibilityGetName()
47 /// Prevents from showing child widgets in AT-SPI tree.
49 [EditorBrowsable(EditorBrowsableState.Never)]
50 protected override bool AccessibilityShouldReportZeroChildren()
56 /// The ButtonExtension instance that is injected by ButtonStyle.
58 [EditorBrowsable(EditorBrowsableState.Never)]
59 protected ButtonExtension Extension { get; set; }
62 /// Creates Button's text part.
64 /// <return>The created Button's text part.</return>
65 [EditorBrowsable(EditorBrowsableState.Never)]
66 protected virtual TextLabel CreateText()
70 HorizontalAlignment = HorizontalAlignment.Center,
71 VerticalAlignment = VerticalAlignment.Center,
72 AccessibilityHighlightable = false
77 /// Creates Button's icon part.
79 /// <return>The created Button's icon part.</return>
80 [EditorBrowsable(EditorBrowsableState.Never)]
81 protected virtual ImageView CreateIcon()
85 AccessibilityHighlightable = false
90 /// Creates Button's overlay image part.
92 /// <return>The created Button's overlay image part.</return>
93 [EditorBrowsable(EditorBrowsableState.Never)]
94 protected virtual ImageView CreateOverlayImage()
98 PositionUsesPivotPoint = true,
99 ParentOrigin = NUI.ParentOrigin.Center,
100 PivotPoint = NUI.PivotPoint.Center,
101 WidthResizePolicy = ResizePolicyType.FillToParent,
102 HeightResizePolicy = ResizePolicyType.FillToParent,
103 AccessibilityHighlightable = false
108 /// Called when the Button is Clicked by a user
110 /// <param name="eventArgs">The click information.</param>
111 [EditorBrowsable(EditorBrowsableState.Never)]
112 protected virtual void OnClicked(ClickedEventArgs eventArgs)
117 /// Get Button style.
119 /// <returns>The default button style.</returns>
120 /// <since_tizen> 8 </since_tizen>
121 protected override ViewStyle CreateViewStyle()
123 return new ButtonStyle();
126 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
127 [EditorBrowsable(EditorBrowsableState.Never)]
128 protected override void OnUpdate()
131 Extension?.OnRelayout(this);
135 [EditorBrowsable(EditorBrowsableState.Never)]
136 protected override bool HandleControlStateOnTouch(Touch touch)
138 if (!IsEnabled || null == touch)
143 PointStateType state = touch.GetState(0);
147 case PointStateType.Down:
149 Extension?.SetTouchInfo(touch);
152 case PointStateType.Interrupted:
156 case PointStateType.Up:
158 bool clicked = isPressed && IsEnabled;
164 Extension?.SetTouchInfo(touch);
165 IsSelected = !IsSelected;
169 Extension?.SetTouchInfo(touch);
175 ClickedEventArgs eventArgs = new ClickedEventArgs();
176 OnClickedInternal(eventArgs);
184 return base.HandleControlStateOnTouch(touch);
188 /// Update Button State.
190 /// <since_tizen> 6 </since_tizen>
191 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
192 [EditorBrowsable(EditorBrowsableState.Never)]
193 protected void UpdateState()
195 if (!styleApplied) return;
197 ControlState sourceState = ControlState;
198 ControlState targetState;
201 targetState = IsEnabled ? ControlState.Normal : ControlState.Disabled;
203 // Selected, DisabledSelected
204 if (IsSelected) targetState += ControlState.Selected;
206 // Pressed, PressedSelected
207 if (isPressed) targetState += ControlState.Pressed;
209 // Focused, FocusedPressed, FocusedPressedSelected, DisabledFocused, DisabledSelectedFocused
210 if (IsFocused) targetState += ControlState.Focused;
212 if (sourceState != targetState)
214 ControlState = targetState;
217 StateChangedEventArgs e = new StateChangedEventArgs
219 PreviousState = ControlStatesExtension.FromControlStateClass(sourceState),
220 CurrentState = ControlStatesExtension.FromControlStateClass(targetState)
222 stateChangeHandler?.Invoke(this, e);
224 Extension?.OnControlStateChanged(this, new ControlStateChangedEventArgs(sourceState, targetState));
229 /// Dispose Button and all children on it.
231 /// <param name="type">Dispose type.</param>
232 /// <since_tizen> 6 </since_tizen>
233 protected override void Dispose(DisposeTypes type)
240 if (type == DisposeTypes.Explicit)
242 Extension?.OnDispose(this);
244 if (buttonIcon != null)
246 Utility.Dispose(buttonIcon);
248 if (buttonText != null)
250 Utility.Dispose(buttonText);
252 if (overlayImage != null)
254 Utility.Dispose(overlayImage);
262 /// Initializes AT-SPI object.
264 [EditorBrowsable(EditorBrowsableState.Never)]
265 public override void OnInitialize()
268 SetAccessibilityConstructor(Role.PushButton);
270 AccessibilityHighlightable = true;
271 EnableControlStatePropagation = true;
273 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "Button");
275 buttonText = CreateText();
276 buttonIcon = CreateIcon();
285 [EditorBrowsable(EditorBrowsableState.Never)]
286 protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
288 base.OnControlStateChanged(controlStateChangedInfo);
290 var stateEnabled = !controlStateChangedInfo.CurrentState.Contains(ControlState.Disabled);
292 if (IsEnabled != stateEnabled)
294 IsEnabled = stateEnabled;
297 var statePressed = controlStateChangedInfo.CurrentState.Contains(ControlState.Pressed);
299 if (isPressed != statePressed)
301 isPressed = statePressed;
306 /// Put sub items (e.g. buttonText, buttonIcon) to the right place.
308 [EditorBrowsable(EditorBrowsableState.Never)]
309 protected virtual void LayoutItems()
311 if (buttonIcon == null || buttonText == null)
316 buttonIcon.Unparent();
317 buttonText.Unparent();
318 overlayImage?.Unparent();
320 if (IconRelativeOrientation == IconOrientation.Left)
322 Layout = new LinearLayout()
324 LinearOrientation = LinearLayout.Orientation.Horizontal,
325 LinearAlignment = LinearLayout.Alignment.Center,
331 else if (IconRelativeOrientation == IconOrientation.Right)
333 Layout = new LinearLayout()
335 LinearOrientation = LinearLayout.Orientation.Horizontal,
336 LinearAlignment = LinearLayout.Alignment.Center,
342 else if (IconRelativeOrientation == IconOrientation.Top)
344 Layout = new LinearLayout()
346 LinearOrientation = LinearLayout.Orientation.Vertical,
347 LinearAlignment = LinearLayout.Alignment.Center,
353 else if (IconRelativeOrientation == IconOrientation.Bottom)
355 Layout = new LinearLayout()
357 LinearOrientation = LinearLayout.Orientation.Vertical,
358 LinearAlignment = LinearLayout.Alignment.Center,
365 if (overlayImage != null)
367 overlayImage.ExcludeLayouting = true;
372 private void OnClickedInternal(ClickedEventArgs eventArgs)
374 Command?.Execute(CommandParameter);
375 OnClicked(eventArgs);
376 Extension?.OnClicked(this, eventArgs);
378 ClickEventArgs nestedEventArgs = new ClickEventArgs();
379 ClickEvent?.Invoke(this, nestedEventArgs);
380 Clicked?.Invoke(this, eventArgs);
383 internal override bool OnAccessibilityActivated()
385 using (var key = new Key())
387 key.State = Key.StateType.Down;
388 key.KeyPressedName = "Return";
394 key.State = Key.StateType.Up;