using System; using System.ComponentModel; using Tizen.NUI.BaseComponents; using Tizen.NUI.Components.Extension; namespace Tizen.NUI.Components { public partial class Button { private ImageView overlayImage; private TextLabel buttonText; private ImageView buttonIcon; private EventHandler stateChangeHandler; private bool isPressed = false; private bool styleApplied = false; /// /// The ButtonExtension instance that is injected by ButtonStyle. /// [EditorBrowsable(EditorBrowsableState.Never)] protected ButtonExtension Extension { get; set; } /// /// Creates Button's text part. /// /// The created Button's text part. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual TextLabel CreateText() { return new TextLabel(); } /// /// Creates Button's icon part. /// /// The created Button's icon part. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual ImageView CreateIcon() { return new ImageView(); } /// /// Creates Button's overlay image part. /// /// The created Button's overlay image part. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual ImageView CreateOverlayImage() { return new ImageView(); } /// /// Called when the Button is Clicked by a user /// /// The click information. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual void OnClicked(ClickedEventArgs eventArgs) { } /// /// Get Button style. /// /// The default button style. /// 8 protected override ViewStyle CreateViewStyle() { return new ButtonStyle(); } /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected override void OnUpdate() { base.OnUpdate(); UpdateUIContent(); Extension?.OnRelayout(this); } /// /// Update Button State. /// /// The touch information in case the state has changed by touching. /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected void UpdateState() { if (!styleApplied) return; ControlState sourceState = ControlState; ControlState targetState; // Normal, Disabled targetState = IsEnabled ? ControlState.Normal : ControlState.Disabled; // Selected, DisabledSelected if (IsSelected) targetState += ControlState.Selected; // Pressed, PressedSelected if (isPressed) targetState += ControlState.Pressed; // Focused, FocusedPressed, FocusedPressedSelected, DisabledFocused, DisabledSelectedFocused if (IsFocused) targetState += ControlState.Focused; if (sourceState != targetState) { ControlState = targetState; OnUpdate(); StateChangedEventArgs e = new StateChangedEventArgs { PreviousState = ControlStatesExtension.FromControlStateClass(sourceState), CurrentState = ControlStatesExtension.FromControlStateClass(targetState) }; stateChangeHandler?.Invoke(this, e); Extension?.OnControlStateChanged(this, new ControlStateChangedEventArgs(sourceState, targetState)); } } /// /// Measure text, it can be override. /// /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual void MeasureText() { if (Icon == null || TextLabel == null) { return; } TextLabel.WidthResizePolicy = ResizePolicyType.Fixed; TextLabel.HeightResizePolicy = ResizePolicyType.Fixed; int textPaddingStart = buttonStyle.TextPadding.Start; int textPaddingEnd = buttonStyle.TextPadding.End; int textPaddingTop = buttonStyle.TextPadding.Top; int textPaddingBottom = buttonStyle.TextPadding.Bottom; int iconPaddingStart = buttonStyle.IconPadding.Start; int iconPaddingEnd = buttonStyle.IconPadding.End; int iconPaddingTop = buttonStyle.IconPadding.Top; int iconPaddingBottom = buttonStyle.IconPadding.Bottom; if (IconRelativeOrientation == IconOrientation.Top || IconRelativeOrientation == IconOrientation.Bottom) { TextLabel.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd; TextLabel.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - Icon.SizeHeight; } else { TextLabel.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd - iconPaddingStart - iconPaddingEnd - Icon.SizeWidth; TextLabel.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom; } } /// /// Layout child, it can be override. /// /// 6 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] protected virtual void LayoutChild() { if (Icon == null || TextLabel == null) { return; } var buttonIcon = Icon; var buttonText = TextLabel; int textPaddingStart = buttonStyle.TextPadding.Start; int textPaddingEnd = buttonStyle.TextPadding.End; int textPaddingTop = buttonStyle.TextPadding.Top; int textPaddingBottom = buttonStyle.TextPadding.Bottom; int iconPaddingStart = buttonStyle.IconPadding.Start; int iconPaddingEnd = buttonStyle.IconPadding.End; int iconPaddingTop = buttonStyle.IconPadding.Top; int iconPaddingBottom = buttonStyle.IconPadding.Bottom; switch (IconRelativeOrientation) { case IconOrientation.Top: buttonIcon.PositionUsesPivotPoint = true; buttonIcon.ParentOrigin = NUI.ParentOrigin.TopCenter; buttonIcon.PivotPoint = NUI.PivotPoint.TopCenter; buttonIcon.Position2D = new Position2D(0, iconPaddingTop); buttonText.PositionUsesPivotPoint = true; buttonText.ParentOrigin = NUI.ParentOrigin.BottomCenter; buttonText.PivotPoint = NUI.PivotPoint.BottomCenter; buttonText.Position2D = new Position2D(0, -textPaddingBottom); break; case IconOrientation.Bottom: buttonIcon.PositionUsesPivotPoint = true; buttonIcon.ParentOrigin = NUI.ParentOrigin.BottomCenter; buttonIcon.PivotPoint = NUI.PivotPoint.BottomCenter; buttonIcon.Position2D = new Position2D(0, -iconPaddingBottom); buttonText.PositionUsesPivotPoint = true; buttonText.ParentOrigin = NUI.ParentOrigin.TopCenter; buttonText.PivotPoint = NUI.PivotPoint.TopCenter; buttonText.Position2D = new Position2D(0, textPaddingTop); break; case IconOrientation.Left: if (LayoutDirection == ViewLayoutDirectionType.LTR) { buttonIcon.PositionUsesPivotPoint = true; buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft; buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft; buttonIcon.Position2D = new Position2D(iconPaddingStart, 0); buttonText.PositionUsesPivotPoint = true; buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight; buttonText.PivotPoint = NUI.PivotPoint.CenterRight; buttonText.Position2D = new Position2D(-textPaddingEnd, 0); } else { buttonIcon.PositionUsesPivotPoint = true; buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight; buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight; buttonIcon.Position2D = new Position2D(-iconPaddingStart, 0); buttonText.PositionUsesPivotPoint = true; buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft; buttonText.PivotPoint = NUI.PivotPoint.CenterLeft; buttonText.Position2D = new Position2D(textPaddingEnd, 0); } break; case IconOrientation.Right: if (LayoutDirection == ViewLayoutDirectionType.RTL) { buttonIcon.PositionUsesPivotPoint = true; buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft; buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft; buttonIcon.Position2D = new Position2D(iconPaddingEnd, 0); buttonText.PositionUsesPivotPoint = true; buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight; buttonText.PivotPoint = NUI.PivotPoint.CenterRight; buttonText.Position2D = new Position2D(-textPaddingStart, 0); } else { buttonIcon.PositionUsesPivotPoint = true; buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight; buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight; buttonIcon.Position2D = new Position2D(-iconPaddingEnd, 0); buttonText.PositionUsesPivotPoint = true; buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft; buttonText.PivotPoint = NUI.PivotPoint.CenterLeft; buttonText.Position2D = new Position2D(textPaddingStart, 0); } break; default: break; } if (string.IsNullOrEmpty(buttonText.Text)) { buttonIcon.ParentOrigin = NUI.ParentOrigin.Center; buttonIcon.PivotPoint = NUI.PivotPoint.Center; } } /// /// Theme change callback when theme is changed, this callback will be trigger. /// /// The sender /// The event data [EditorBrowsable(EditorBrowsableState.Never)] protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e) { ButtonStyle buttonStyle = StyleManager.Instance.GetViewStyle(StyleName) as ButtonStyle; if (buttonStyle != null) { ApplyStyle(buttonStyle); UpdateUIContent(); } } /// /// Dispose Button and all children on it. /// /// Dispose type. /// 6 protected override void Dispose(DisposeTypes type) { if (disposed) { return; } if (type == DisposeTypes.Explicit) { Extension?.OnDispose(this); if (Icon != null) { Utility.Dispose(Icon); } if (TextLabel != null) { Utility.Dispose(TextLabel); } if (OverlayImage != null) { Utility.Dispose(OverlayImage); } } base.Dispose(type); } /// [EditorBrowsable(EditorBrowsableState.Never)] protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo) { base.OnControlStateChanged(controlStateChangedInfo); var stateEnabled = !controlStateChangedInfo.CurrentState.Contains(ControlState.Disabled); if (IsEnabled != stateEnabled) { IsEnabled = stateEnabled; } var statePressed = controlStateChangedInfo.CurrentState.Contains(ControlState.Pressed); if (isPressed != statePressed) { isPressed = statePressed; } } /// /// It is hijack by using protected, style copy problem when class inherited from Button. /// /// 6 private void Initialize() { EnableControlStatePropagation = true; UpdateState(); LayoutDirectionChanged += OnLayoutDirectionChanged; } private void UpdateUIContent() { MeasureText(); LayoutChild(); Sensitive = IsEnabled; } private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e) { MeasureText(); LayoutChild(); } private void OnClickedInternal(ClickedEventArgs eventArgs) { Command?.Execute(CommandParameter); OnClicked(eventArgs); Extension?.OnClicked(this, eventArgs); ClickEventArgs nestedEventArgs = new ClickEventArgs(); ClickEvent?.Invoke(this, nestedEventArgs); Clicked?.Invoke(this, eventArgs); } private void OnIconRelayout(object sender, EventArgs e) { MeasureText(); LayoutChild(); } } }