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 /// The ButtonExtension instance that is injected by ButtonStyle.
23 [EditorBrowsable(EditorBrowsableState.Never)]
24 protected ButtonExtension Extension { get; set; }
27 /// Creates Button's text part.
29 /// <return>The created Button's text part.</return>
30 [EditorBrowsable(EditorBrowsableState.Never)]
31 protected virtual TextLabel CreateText()
33 return new TextLabel();
37 /// Creates Button's icon part.
39 /// <return>The created Button's icon part.</return>
40 [EditorBrowsable(EditorBrowsableState.Never)]
41 protected virtual ImageView CreateIcon()
43 return new ImageView();
47 /// Creates Button's overlay image part.
49 /// <return>The created Button's overlay image part.</return>
50 [EditorBrowsable(EditorBrowsableState.Never)]
51 protected virtual ImageView CreateOverlayImage()
53 return new ImageView();
57 /// Called when the Button is Clicked by a user
59 /// <param name="eventArgs">The click information.</param>
60 [EditorBrowsable(EditorBrowsableState.Never)]
61 protected virtual void OnClicked(ClickedEventArgs eventArgs)
68 /// <returns>The default button style.</returns>
69 /// <since_tizen> 8 </since_tizen>
70 protected override ViewStyle CreateViewStyle()
72 return new ButtonStyle();
75 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
76 [EditorBrowsable(EditorBrowsableState.Never)]
77 protected override void OnUpdate()
82 Extension?.OnRelayout(this);
86 [EditorBrowsable(EditorBrowsableState.Never)]
87 protected override bool HandleControlStateOnTouch(Touch touch)
89 if (!IsEnabled || null == touch)
94 PointStateType state = touch.GetState(0);
98 case PointStateType.Down:
100 Extension?.SetTouchInfo(touch);
103 case PointStateType.Interrupted:
107 case PointStateType.Up:
109 bool clicked = isPressed && IsEnabled;
115 Extension?.SetTouchInfo(touch);
116 IsSelected = !IsSelected;
120 Extension?.SetTouchInfo(touch);
126 ClickedEventArgs eventArgs = new ClickedEventArgs();
127 OnClickedInternal(eventArgs);
135 return base.HandleControlStateOnTouch(touch);
139 /// Update Button State.
141 /// <param name="touchInfo">The touch information in case the state has changed by touching.</param>
142 /// <since_tizen> 6 </since_tizen>
143 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
144 [EditorBrowsable(EditorBrowsableState.Never)]
145 protected void UpdateState()
147 if (!styleApplied) return;
149 ControlState sourceState = ControlState;
150 ControlState targetState;
153 targetState = IsEnabled ? ControlState.Normal : ControlState.Disabled;
155 // Selected, DisabledSelected
156 if (IsSelected) targetState += ControlState.Selected;
158 // Pressed, PressedSelected
159 if (isPressed) targetState += ControlState.Pressed;
161 // Focused, FocusedPressed, FocusedPressedSelected, DisabledFocused, DisabledSelectedFocused
162 if (IsFocused) targetState += ControlState.Focused;
164 if (sourceState != targetState)
166 ControlState = targetState;
169 StateChangedEventArgs e = new StateChangedEventArgs
171 PreviousState = ControlStatesExtension.FromControlStateClass(sourceState),
172 CurrentState = ControlStatesExtension.FromControlStateClass(targetState)
174 stateChangeHandler?.Invoke(this, e);
176 Extension?.OnControlStateChanged(this, new ControlStateChangedEventArgs(sourceState, targetState));
181 /// Measure text, it can be override.
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 virtual void MeasureText()
188 if (Icon == null || TextLabel == null)
192 TextLabel.WidthResizePolicy = ResizePolicyType.Fixed;
193 TextLabel.HeightResizePolicy = ResizePolicyType.Fixed;
194 int textPaddingStart = buttonStyle.TextPadding.Start;
195 int textPaddingEnd = buttonStyle.TextPadding.End;
196 int textPaddingTop = buttonStyle.TextPadding.Top;
197 int textPaddingBottom = buttonStyle.TextPadding.Bottom;
199 int iconPaddingStart = buttonStyle.IconPadding.Start;
200 int iconPaddingEnd = buttonStyle.IconPadding.End;
201 int iconPaddingTop = buttonStyle.IconPadding.Top;
202 int iconPaddingBottom = buttonStyle.IconPadding.Bottom;
204 if (IconRelativeOrientation == IconOrientation.Top || IconRelativeOrientation == IconOrientation.Bottom)
206 TextLabel.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd;
207 TextLabel.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - Icon.SizeHeight;
211 TextLabel.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd - iconPaddingStart - iconPaddingEnd - Icon.SizeWidth;
212 TextLabel.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom;
217 /// Layout child, it can be override.
219 /// <since_tizen> 6 </since_tizen>
220 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
221 [EditorBrowsable(EditorBrowsableState.Never)]
222 protected virtual void LayoutChild()
224 if (Icon == null || TextLabel == null)
229 var buttonIcon = Icon;
230 var buttonText = TextLabel;
232 int textPaddingStart = buttonStyle.TextPadding.Start;
233 int textPaddingEnd = buttonStyle.TextPadding.End;
234 int textPaddingTop = buttonStyle.TextPadding.Top;
235 int textPaddingBottom = buttonStyle.TextPadding.Bottom;
237 int iconPaddingStart = buttonStyle.IconPadding.Start;
238 int iconPaddingEnd = buttonStyle.IconPadding.End;
239 int iconPaddingTop = buttonStyle.IconPadding.Top;
240 int iconPaddingBottom = buttonStyle.IconPadding.Bottom;
242 switch (IconRelativeOrientation)
244 case IconOrientation.Top:
245 buttonIcon.PositionUsesPivotPoint = true;
246 buttonIcon.ParentOrigin = NUI.ParentOrigin.TopCenter;
247 buttonIcon.PivotPoint = NUI.PivotPoint.TopCenter;
248 buttonIcon.Position2D = new Position2D(0, iconPaddingTop);
250 buttonText.PositionUsesPivotPoint = true;
251 buttonText.ParentOrigin = NUI.ParentOrigin.BottomCenter;
252 buttonText.PivotPoint = NUI.PivotPoint.BottomCenter;
253 buttonText.Position2D = new Position2D(0, -textPaddingBottom);
255 case IconOrientation.Bottom:
256 buttonIcon.PositionUsesPivotPoint = true;
257 buttonIcon.ParentOrigin = NUI.ParentOrigin.BottomCenter;
258 buttonIcon.PivotPoint = NUI.PivotPoint.BottomCenter;
259 buttonIcon.Position2D = new Position2D(0, -iconPaddingBottom);
261 buttonText.PositionUsesPivotPoint = true;
262 buttonText.ParentOrigin = NUI.ParentOrigin.TopCenter;
263 buttonText.PivotPoint = NUI.PivotPoint.TopCenter;
264 buttonText.Position2D = new Position2D(0, textPaddingTop);
266 case IconOrientation.Left:
267 if (LayoutDirection == ViewLayoutDirectionType.LTR)
269 buttonIcon.PositionUsesPivotPoint = true;
270 buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft;
271 buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft;
272 buttonIcon.Position2D = new Position2D(iconPaddingStart, 0);
274 buttonText.PositionUsesPivotPoint = true;
275 buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
276 buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
277 buttonText.Position2D = new Position2D(-textPaddingEnd, 0);
281 buttonIcon.PositionUsesPivotPoint = true;
282 buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
283 buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
284 buttonIcon.Position2D = new Position2D(-iconPaddingStart, 0);
286 buttonText.PositionUsesPivotPoint = true;
287 buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
288 buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
289 buttonText.Position2D = new Position2D(textPaddingEnd, 0);
293 case IconOrientation.Right:
294 if (LayoutDirection == ViewLayoutDirectionType.RTL)
296 buttonIcon.PositionUsesPivotPoint = true;
297 buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft;
298 buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft;
299 buttonIcon.Position2D = new Position2D(iconPaddingEnd, 0);
301 buttonText.PositionUsesPivotPoint = true;
302 buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
303 buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
304 buttonText.Position2D = new Position2D(-textPaddingStart, 0);
308 buttonIcon.PositionUsesPivotPoint = true;
309 buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
310 buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
311 buttonIcon.Position2D = new Position2D(-iconPaddingEnd, 0);
313 buttonText.PositionUsesPivotPoint = true;
314 buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
315 buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
316 buttonText.Position2D = new Position2D(textPaddingStart, 0);
322 if (string.IsNullOrEmpty(buttonText.Text))
324 buttonIcon.ParentOrigin = NUI.ParentOrigin.Center;
325 buttonIcon.PivotPoint = NUI.PivotPoint.Center;
330 /// Theme change callback when theme is changed, this callback will be trigger.
332 /// <param name="sender">The sender</param>
333 /// <param name="e">The event data</param>
334 [EditorBrowsable(EditorBrowsableState.Never)]
335 protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
337 ButtonStyle buttonStyle = StyleManager.Instance.GetViewStyle(StyleName) as ButtonStyle;
338 if (buttonStyle != null)
340 ApplyStyle(buttonStyle);
346 /// Dispose Button and all children on it.
348 /// <param name="type">Dispose type.</param>
349 /// <since_tizen> 6 </since_tizen>
350 protected override void Dispose(DisposeTypes type)
357 if (type == DisposeTypes.Explicit)
359 Extension?.OnDispose(this);
363 Utility.Dispose(Icon);
365 if (TextLabel != null)
367 Utility.Dispose(TextLabel);
369 if (OverlayImage != null)
371 Utility.Dispose(OverlayImage);
379 [EditorBrowsable(EditorBrowsableState.Never)]
380 protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
382 base.OnControlStateChanged(controlStateChangedInfo);
384 var stateEnabled = !controlStateChangedInfo.CurrentState.Contains(ControlState.Disabled);
386 if (IsEnabled != stateEnabled)
388 IsEnabled = stateEnabled;
391 var statePressed = controlStateChangedInfo.CurrentState.Contains(ControlState.Pressed);
393 if (isPressed != statePressed)
395 isPressed = statePressed;
400 /// It is hijack by using protected, style copy problem when class inherited from Button.
402 /// <since_tizen> 6 </since_tizen>
403 private void Initialize()
405 EnableControlStatePropagation = true;
407 LayoutDirectionChanged += OnLayoutDirectionChanged;
409 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "Button");
412 private void UpdateUIContent()
417 Sensitive = IsEnabled;
420 private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
426 private void OnClickedInternal(ClickedEventArgs eventArgs)
428 Command?.Execute(CommandParameter);
429 OnClicked(eventArgs);
430 Extension?.OnClicked(this, eventArgs);
432 ClickEventArgs nestedEventArgs = new ClickEventArgs();
433 ClickEvent?.Invoke(this, nestedEventArgs);
434 Clicked?.Invoke(this, eventArgs);
437 private void OnIconRelayout(object sender, EventArgs e)
443 internal override bool OnAccessibilityActivated()
455 bool clicked = isPressed && IsEnabled;
460 IsSelected = !IsSelected;
469 ClickedEventArgs eventArgs = new ClickedEventArgs();
470 OnClickedInternal(eventArgs);