2 using System.ComponentModel;
3 using Tizen.NUI.BaseComponents;
4 using Tizen.NUI.Components.Extension;
5 using Tizen.NUI.Accessibility; // To use AccessibilityManager
7 namespace Tizen.NUI.Components
9 public partial class Button
11 private ImageView overlayImage;
12 private TextLabel buttonText;
13 private ImageView buttonIcon;
15 private EventHandler<StateChangedEventArgs> stateChangeHandler;
17 private bool isPressed = false;
18 private bool styleApplied = false;
21 /// Get accessibility name.
23 [EditorBrowsable(EditorBrowsableState.Never)]
24 protected override string AccessibilityGetName()
30 /// Prevents from showing child widgets in AT-SPI tree.
32 [EditorBrowsable(EditorBrowsableState.Never)]
33 protected override bool AccessibilityShouldReportZeroChildren()
39 /// The ButtonExtension instance that is injected by ButtonStyle.
41 [EditorBrowsable(EditorBrowsableState.Never)]
42 protected ButtonExtension Extension { get; set; }
45 /// Creates Button's text part.
47 /// <return>The created Button's text part.</return>
48 [EditorBrowsable(EditorBrowsableState.Never)]
49 protected virtual TextLabel CreateText()
53 PositionUsesPivotPoint = true,
54 ParentOrigin = NUI.ParentOrigin.Center,
55 PivotPoint = NUI.PivotPoint.Center,
56 WidthResizePolicy = ResizePolicyType.FillToParent,
57 HeightResizePolicy = ResizePolicyType.FillToParent,
58 HorizontalAlignment = HorizontalAlignment.Center,
59 VerticalAlignment = VerticalAlignment.Center,
60 AccessibilityHighlightable = false
65 /// Creates Button's icon part.
67 /// <return>The created Button's icon part.</return>
68 [EditorBrowsable(EditorBrowsableState.Never)]
69 protected virtual ImageView CreateIcon()
73 PositionUsesPivotPoint = true,
74 ParentOrigin = NUI.ParentOrigin.Center,
75 PivotPoint = NUI.PivotPoint.Center,
76 AccessibilityHighlightable = false
81 /// Creates Button's overlay image part.
83 /// <return>The created Button's overlay image part.</return>
84 [EditorBrowsable(EditorBrowsableState.Never)]
85 protected virtual ImageView CreateOverlayImage()
89 PositionUsesPivotPoint = true,
90 ParentOrigin = NUI.ParentOrigin.Center,
91 PivotPoint = NUI.PivotPoint.Center,
92 WidthResizePolicy = ResizePolicyType.FillToParent,
93 HeightResizePolicy = ResizePolicyType.FillToParent,
94 AccessibilityHighlightable = false
99 /// Called when the Button is Clicked by a user
101 /// <param name="eventArgs">The click information.</param>
102 [EditorBrowsable(EditorBrowsableState.Never)]
103 protected virtual void OnClicked(ClickedEventArgs eventArgs)
108 /// Get Button style.
110 /// <returns>The default button style.</returns>
111 /// <since_tizen> 8 </since_tizen>
112 protected override ViewStyle CreateViewStyle()
114 return new ButtonStyle();
117 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
118 [EditorBrowsable(EditorBrowsableState.Never)]
119 protected override void OnUpdate()
124 Extension?.OnRelayout(this);
128 [EditorBrowsable(EditorBrowsableState.Never)]
129 protected override bool HandleControlStateOnTouch(Touch touch)
131 if (!IsEnabled || null == touch)
136 PointStateType state = touch.GetState(0);
140 case PointStateType.Down:
142 Extension?.SetTouchInfo(touch);
145 case PointStateType.Interrupted:
149 case PointStateType.Up:
151 bool clicked = isPressed && IsEnabled;
157 Extension?.SetTouchInfo(touch);
158 IsSelected = !IsSelected;
162 Extension?.SetTouchInfo(touch);
168 ClickedEventArgs eventArgs = new ClickedEventArgs();
169 OnClickedInternal(eventArgs);
177 return base.HandleControlStateOnTouch(touch);
181 /// Update Button State.
183 /// <since_tizen> 6 </since_tizen>
184 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
185 [EditorBrowsable(EditorBrowsableState.Never)]
186 protected void UpdateState()
188 if (!styleApplied) return;
190 ControlState sourceState = ControlState;
191 ControlState targetState;
194 targetState = IsEnabled ? ControlState.Normal : ControlState.Disabled;
196 // Selected, DisabledSelected
197 if (IsSelected) targetState += ControlState.Selected;
199 // Pressed, PressedSelected
200 if (isPressed) targetState += ControlState.Pressed;
202 // Focused, FocusedPressed, FocusedPressedSelected, DisabledFocused, DisabledSelectedFocused
203 if (IsFocused) targetState += ControlState.Focused;
205 if (sourceState != targetState)
207 ControlState = targetState;
210 StateChangedEventArgs e = new StateChangedEventArgs
212 PreviousState = ControlStatesExtension.FromControlStateClass(sourceState),
213 CurrentState = ControlStatesExtension.FromControlStateClass(targetState)
215 stateChangeHandler?.Invoke(this, e);
217 Extension?.OnControlStateChanged(this, new ControlStateChangedEventArgs(sourceState, targetState));
222 /// Measure text, it can be override.
224 /// <since_tizen> 6 </since_tizen>
225 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
226 [EditorBrowsable(EditorBrowsableState.Never)]
227 protected virtual void MeasureText()
229 if (buttonIcon == null || buttonText == null)
233 buttonText.WidthResizePolicy = ResizePolicyType.Fixed;
234 buttonText.HeightResizePolicy = ResizePolicyType.Fixed;
236 var textPadding = TextPadding;
237 int textPaddingStart = textPadding.Start;
238 int textPaddingEnd = textPadding.End;
239 int textPaddingTop = textPadding.Top;
240 int textPaddingBottom = textPadding.Bottom;
242 var iconPadding = IconPadding;
243 int iconPaddingStart = iconPadding.Start;
244 int iconPaddingEnd = iconPadding.End;
245 int iconPaddingTop = iconPadding.Top;
246 int iconPaddingBottom = iconPadding.Bottom;
248 if (IconRelativeOrientation == IconOrientation.Top || IconRelativeOrientation == IconOrientation.Bottom)
250 buttonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd;
251 buttonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - buttonIcon.SizeHeight;
255 buttonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd - iconPaddingStart - iconPaddingEnd - buttonIcon.SizeWidth;
256 buttonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom;
261 /// Layout child, it can be override.
263 /// <since_tizen> 6 </since_tizen>
264 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
265 [EditorBrowsable(EditorBrowsableState.Never)]
266 protected virtual void LayoutChild()
268 if (buttonIcon == null || buttonText == null)
273 var textPadding = TextPadding;
274 int textPaddingStart = textPadding.Start;
275 int textPaddingEnd = textPadding.End;
276 int textPaddingTop = textPadding.Top;
277 int textPaddingBottom = textPadding.Bottom;
279 var iconPadding = IconPadding;
280 int iconPaddingStart = iconPadding.Start;
281 int iconPaddingEnd = iconPadding.End;
282 int iconPaddingTop = iconPadding.Top;
283 int iconPaddingBottom = iconPadding.Bottom;
285 switch (IconRelativeOrientation)
287 case IconOrientation.Top:
288 buttonIcon.PositionUsesPivotPoint = true;
289 buttonIcon.ParentOrigin = NUI.ParentOrigin.TopCenter;
290 buttonIcon.PivotPoint = NUI.PivotPoint.TopCenter;
291 buttonIcon.Position2D = new Position2D(0, iconPaddingTop);
293 buttonText.PositionUsesPivotPoint = true;
294 buttonText.ParentOrigin = NUI.ParentOrigin.BottomCenter;
295 buttonText.PivotPoint = NUI.PivotPoint.BottomCenter;
296 buttonText.Position2D = new Position2D(0, -textPaddingBottom);
298 case IconOrientation.Bottom:
299 buttonIcon.PositionUsesPivotPoint = true;
300 buttonIcon.ParentOrigin = NUI.ParentOrigin.BottomCenter;
301 buttonIcon.PivotPoint = NUI.PivotPoint.BottomCenter;
302 buttonIcon.Position2D = new Position2D(0, -iconPaddingBottom);
304 buttonText.PositionUsesPivotPoint = true;
305 buttonText.ParentOrigin = NUI.ParentOrigin.TopCenter;
306 buttonText.PivotPoint = NUI.PivotPoint.TopCenter;
307 buttonText.Position2D = new Position2D(0, textPaddingTop);
309 case IconOrientation.Left:
310 if (LayoutDirection == ViewLayoutDirectionType.LTR)
312 buttonIcon.PositionUsesPivotPoint = true;
313 buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft;
314 buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft;
315 buttonIcon.Position2D = new Position2D(iconPaddingStart, 0);
317 buttonText.PositionUsesPivotPoint = true;
318 buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
319 buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
320 buttonText.Position2D = new Position2D(-textPaddingEnd, 0);
324 buttonIcon.PositionUsesPivotPoint = true;
325 buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
326 buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
327 buttonIcon.Position2D = new Position2D(-iconPaddingStart, 0);
329 buttonText.PositionUsesPivotPoint = true;
330 buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
331 buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
332 buttonText.Position2D = new Position2D(textPaddingEnd, 0);
336 case IconOrientation.Right:
337 if (LayoutDirection == ViewLayoutDirectionType.RTL)
339 buttonIcon.PositionUsesPivotPoint = true;
340 buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft;
341 buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft;
342 buttonIcon.Position2D = new Position2D(iconPaddingEnd, 0);
344 buttonText.PositionUsesPivotPoint = true;
345 buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
346 buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
347 buttonText.Position2D = new Position2D(-textPaddingStart, 0);
351 buttonIcon.PositionUsesPivotPoint = true;
352 buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
353 buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
354 buttonIcon.Position2D = new Position2D(-iconPaddingEnd, 0);
356 buttonText.PositionUsesPivotPoint = true;
357 buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
358 buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
359 buttonText.Position2D = new Position2D(textPaddingStart, 0);
365 if (string.IsNullOrEmpty(buttonText.Text))
367 buttonIcon.ParentOrigin = NUI.ParentOrigin.Center;
368 buttonIcon.PivotPoint = NUI.PivotPoint.Center;
373 /// Dispose Button and all children on it.
375 /// <param name="type">Dispose type.</param>
376 /// <since_tizen> 6 </since_tizen>
377 protected override void Dispose(DisposeTypes type)
384 if (type == DisposeTypes.Explicit)
386 Extension?.OnDispose(this);
388 if (buttonIcon != null)
390 Utility.Dispose(buttonIcon);
392 if (buttonText != null)
394 Utility.Dispose(buttonText);
396 if (overlayImage != null)
398 Utility.Dispose(overlayImage);
406 /// Initializes AT-SPI object.
408 [EditorBrowsable(EditorBrowsableState.Never)]
409 public override void OnInitialize()
412 SetAccessibilityConstructor(Role.PushButton);
414 AccessibilityHighlightable = true;
415 EnableControlStatePropagation = true;
416 LayoutDirectionChanged += OnLayoutDirectionChanged;
418 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "Button");
426 [EditorBrowsable(EditorBrowsableState.Never)]
427 protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
429 base.OnControlStateChanged(controlStateChangedInfo);
431 var stateEnabled = !controlStateChangedInfo.CurrentState.Contains(ControlState.Disabled);
433 if (IsEnabled != stateEnabled)
435 IsEnabled = stateEnabled;
438 var statePressed = controlStateChangedInfo.CurrentState.Contains(ControlState.Pressed);
440 if (isPressed != statePressed)
442 isPressed = statePressed;
446 private void UpdateUIContent()
451 Sensitive = IsEnabled;
454 private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
460 private void OnClickedInternal(ClickedEventArgs eventArgs)
462 Command?.Execute(CommandParameter);
463 OnClicked(eventArgs);
464 Extension?.OnClicked(this, eventArgs);
466 ClickEventArgs nestedEventArgs = new ClickEventArgs();
467 ClickEvent?.Invoke(this, nestedEventArgs);
468 Clicked?.Invoke(this, eventArgs);
471 private void OnIconRelayout(object sender, EventArgs e)
477 internal override bool OnAccessibilityActivated()
479 using (var key = new Key())
481 key.State = Key.StateType.Down;
482 key.KeyPressedName = "Return";
488 key.State = Key.StateType.Up;