/* * Copyright(c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using System.ComponentModel; using Tizen.NUI.BaseComponents; using Tizen.NUI.Binding; using Tizen.NUI.Components.Extension; namespace Tizen.NUI.Components { /// /// Button is one kind of common component, a button clearly describes what action will occur when the user selects it. /// Button may contain text or an icon. /// /// 6 public class Button : Control { /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IconRelativeOrientationProperty = BindableProperty.Create(nameof(IconRelativeOrientation), typeof(IconOrientation?), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (newValue != null) { instance.privateIconRelativeOrientation = (IconOrientation?)newValue; } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.privateIconRelativeOrientation; }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (newValue != null) { instance.privateIsEnabled = (bool)newValue; } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.privateIsEnabled; }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (newValue != null) { instance.privateIsSelected = (bool)newValue; } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.privateIsSelected; }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (newValue != null) { instance.privateIsSelectable = (bool)newValue; } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.privateIsSelectable; }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (null != newValue && null != instance.Style?.IconPadding) { instance.Style.IconPadding.CopyFrom((Extents)newValue); instance.UpdateUIContent(); } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.Style?.IconPadding; }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (null != newValue && null != instance.Style?.TextPadding) { instance.Style.TextPadding.CopyFrom((Extents)newValue); instance.UpdateUIContent(); } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.Style?.TextPadding; }); private ImageView overlayImage; private TextLabel buttonText; private ImageView buttonIcon; private EventHandler stateChangeHander; private bool isSelected = false; private bool isEnabled = true; private bool isPressed = false; /// /// The last touch information triggering selected state change. /// [EditorBrowsable(EditorBrowsableState.Never)] protected Touch SelectionChangedByTouch { get; set; } /// /// 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 OnClick(ClickEventArgs eventArgs) { } static Button() { } /// /// Creates a new instance of a Button. /// /// 6 public Button() : base() { Initialize(); } /// /// Creates a new instance of a Button with style. /// /// Create Button by special style defined in UX. /// 8 public Button(string style) : base(style) { Initialize(); } /// /// Creates a new instance of a Button with style. /// /// Create Button by style customized by user. /// 8 public Button(ButtonStyle buttonStyle) : base(buttonStyle) { Initialize(); } /// /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
///
/// 6 public event EventHandler ClickEvent; /// /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.
///
/// 6 public event EventHandler StateChangedEvent { add { stateChangeHander += value; } remove { stateChangeHander -= value; } } /// /// Icon orientation. /// /// 6 public enum IconOrientation { /// /// Top. /// /// 6 Top, /// /// Bottom. /// /// 6 Bottom, /// /// Left. /// /// 6 Left, /// /// Right. /// /// 6 Right, } /// /// Button's icon part. /// [EditorBrowsable(EditorBrowsableState.Never)] public ImageView ButtonIcon { get { if (null == buttonIcon) { buttonIcon = CreateIcon(); if (null != Extension) { buttonIcon = Extension.OnCreateIcon(this, buttonIcon); } Add(buttonIcon); buttonIcon.Relayout += OnIconRelayout; } return buttonIcon; } internal set { buttonIcon = value; } } /// /// Button's overlay image part. /// [EditorBrowsable(EditorBrowsableState.Never)] public ImageView ButtonOverlay { get { if (null == overlayImage) { overlayImage = CreateOverlayImage(); if (null != Extension) { overlayImage = Extension.OnCreateOverlayImage(this, overlayImage); } overlayImage.WidthResizePolicy = ResizePolicyType.FillToParent; overlayImage.HeightResizePolicy = ResizePolicyType.FillToParent; Add(overlayImage); } return overlayImage; } internal set { overlayImage = value; } } /// /// Button's text part. /// [EditorBrowsable(EditorBrowsableState.Never)] public TextLabel ButtonText { get { if (null == buttonText) { buttonText = CreateText(); if (null != Extension) { buttonText = Extension.OnCreateText(this, buttonText); } buttonText.HorizontalAlignment = HorizontalAlignment.Center; buttonText.VerticalAlignment = VerticalAlignment.Center; Add(buttonText); } return buttonText; } internal set { buttonText = value; } } /// /// Return a copied Style instance of Button /// /// /// It returns copied Style instance and changing it does not effect to the Button. /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle) /// /// 8 public new ButtonStyle Style => ViewStyle as ButtonStyle; /// /// The text of Button. /// /// 6 public string Text { get { return Style?.Text?.Text?.GetValue(ControlState); } set { if (null != Style?.Text) { Style.Text.Text = value; } } } /// /// Flag to decide Button can be selected or not. /// /// 6 public bool IsSelectable { get { return (bool)GetValue(IsSelectableProperty); } set { SetValue(IsSelectableProperty, value); } } private bool privateIsSelectable { get { return Style?.IsSelectable ?? false; } set { Style.IsSelectable = value; } } /// /// Translate text string in Button. /// /// 6 public string TranslatableText { get { return Style?.Text?.TranslatableText?.All; } set { if (null != Style?.Text) { Style.Text.TranslatableText = value; } } } /// /// Text point size in Button. /// /// 6 public float PointSize { get { return Style?.Text?.PointSize?.All ?? 0; } set { if (null != Style?.Text) { Style.Text.PointSize = value; } } } /// /// Text font family in Button. /// /// 6 public string FontFamily { get { return Style?.Text?.FontFamily.All; } set { if (null != Style?.Text) { Style.Text.FontFamily = value; } } } /// /// Text color in Button. /// /// 6 public Color TextColor { get { return Style?.Text?.TextColor?.All; } set { if (null != Style?.Text) { Style.Text.TextColor = value; } } } /// /// Text horizontal alignment in Button. /// /// 6 public HorizontalAlignment TextAlignment { get { return Style?.Text?.HorizontalAlignment ?? HorizontalAlignment.Center; } set { if (null != Style?.Text) { Style.Text.HorizontalAlignment = value; } } } /// /// Icon image's resource url in Button. /// /// 6 public string IconURL { get { return Style?.Icon?.ResourceUrl?.All; } set { if (null != Style?.Icon) { Style.Icon.ResourceUrl = value; } } } private StringSelector textSelector = new StringSelector(); /// /// Text string selector in Button. /// /// 6 public StringSelector TextSelector { get { return textSelector; } set { if (value == null || textSelector == null) { Tizen.Log.Fatal("NUI", "[Exception] Button.TextSelector is null"); throw new NullReferenceException("Button.TextSelector is null"); } else { textSelector.Clone(value); } } } private StringSelector translatableTextSelector = new StringSelector(); /// /// Translateable text string selector in Button. /// /// 6 public StringSelector TranslatableTextSelector { get { return translatableTextSelector; } set { if (value == null || translatableTextSelector == null) { Tizen.Log.Fatal("NUI", "[Exception] Button.TranslatableTextSelector is null"); throw new NullReferenceException("Button.TranslatableTextSelector is null"); } else { translatableTextSelector.Clone(value); } } } private ColorSelector textColorSelector = new ColorSelector(); /// /// Text color selector in Button. /// /// 6 public ColorSelector TextColorSelector { get { return textColorSelector; } set { if (value == null || textColorSelector == null) { Tizen.Log.Fatal("NUI", "[Exception] Button.textColorSelector is null"); throw new NullReferenceException("Button.textColorSelector is null"); } else { textColorSelector.Clone(value); } } } private FloatSelector pointSizeSelector = new FloatSelector(); /// /// Text font size selector in Button. /// /// 6 public FloatSelector PointSizeSelector { get { return pointSizeSelector; } set { if (value == null || pointSizeSelector == null) { Tizen.Log.Fatal("NUI", "[Exception] Button.pointSizeSelector is null"); throw new NullReferenceException("Button.pointSizeSelector is null"); } else { pointSizeSelector.Clone(value); } } } private StringSelector iconURLSelector = new StringSelector(); /// /// Icon image's resource url selector in Button. /// /// 6 public StringSelector IconURLSelector { get { return iconURLSelector; } set { if (value == null || iconURLSelector == null) { Tizen.Log.Fatal("NUI", "[Exception] Button.iconURLSelector is null"); throw new NullReferenceException("Button.iconURLSelector is null"); } else { iconURLSelector.Clone(value); } } } /// /// Flag to decide selected state in Button. /// /// 6 public bool IsSelected { get { return (bool)GetValue(IsSelectedProperty); } set { SetValue(IsSelectedProperty, value); } } private bool privateIsSelected { get { return isSelected; } set { isSelected = value; UpdateState(); } } /// /// Flag to decide enable or disable in Button. /// /// 6 public bool IsEnabled { get { return (bool)GetValue(IsEnabledProperty); } set { SetValue(IsEnabledProperty, value); } } private bool privateIsEnabled { get { return isEnabled; } set { isEnabled = value; UpdateState(); } } /// /// Icon relative orientation in Button, work only when show icon and text. /// /// 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)] public IconOrientation? IconRelativeOrientation { get { return (IconOrientation?)GetValue(IconRelativeOrientationProperty); } set { SetValue(IconRelativeOrientationProperty, value); } } private IconOrientation? privateIconRelativeOrientation { get { return Style?.IconRelativeOrientation; } set { if (Style != null && Style.IconRelativeOrientation != value) { Style.IconRelativeOrientation = value; UpdateUIContent(); } } } /// /// Icon padding in Button, work only when show icon and text. /// /// 6 public Extents IconPadding { get => (Extents)GetValue(IconPaddingProperty); set => SetValue(IconPaddingProperty, value); } /// /// Text padding in Button, work only when show icon and text. /// /// 6 public Extents TextPadding { get => (Extents)GetValue(TextPaddingProperty); set => SetValue(TextPaddingProperty, value); } /// /// 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 (ButtonIcon != null) { Utility.Dispose(ButtonIcon); } if (ButtonText != null) { Utility.Dispose(ButtonText); } if (ButtonOverlay != null) { Utility.Dispose(ButtonOverlay); } } base.Dispose(type); } /// /// Called after a key event is received by the view that has had its focus set. /// /// The key event. /// True if the key event should be consumed. /// 6 public override bool OnKey(Key key) { if (null == key) return false; if (key.State == Key.StateType.Down) { if (key.KeyPressedName == "Return") { isPressed = true; UpdateState(); } } else if (key.State == Key.StateType.Up) { if (key.KeyPressedName == "Return") { bool clicked = isPressed && isEnabled; isPressed = false; if (Style.IsSelectable != null && Style.IsSelectable == true) { IsSelected = !IsSelected; } else { UpdateState(); } if (clicked) { ClickEventArgs eventArgs = new ClickEventArgs(); OnClickInternal(eventArgs); } } } return base.OnKey(key); } /// /// Called when the control gain key input focus. Should be overridden by derived classes if they need to customize what happens when the focus is gained. /// /// 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)] public override void OnFocusGained() { base.OnFocusGained(); UpdateState(); } /// /// Called when the control loses key input focus. Should be overridden by derived classes if they need to customize what happens when the focus is lost. /// /// 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)] public override void OnFocusLost() { base.OnFocusLost(); UpdateState(); } /// /// Called after a touch event is received by the owning view.
/// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).
///
/// The touch event. /// True if the event should be consumed. /// 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)] public override bool OnTouch(Touch touch) { if (null == touch) return false; PointStateType state = touch.GetState(0); switch (state) { case PointStateType.Down: isPressed = true; Extension?.SetTouchInfo(touch); UpdateState(); return true; case PointStateType.Interrupted: isPressed = false; UpdateState(); return true; case PointStateType.Up: { bool clicked = isPressed && isEnabled; isPressed = false; if (Style.IsSelectable != null && Style.IsSelectable == true) { Extension?.SetTouchInfo(touch); IsSelected = !IsSelected; } else { Extension?.SetTouchInfo(touch); UpdateState(); } if (clicked) { ClickEventArgs eventArgs = new ClickEventArgs(); OnClickInternal(eventArgs); } return true; } default: break; } return base.OnTouch(touch); } /// /// Apply style to button. /// /// The style to apply. /// 8 public override void ApplyStyle(ViewStyle viewStyle) { base.ApplyStyle(viewStyle); ButtonStyle buttonStyle = viewStyle as ButtonStyle; if (null != buttonStyle) { Extension = buttonStyle.CreateExtension(); if (buttonStyle.Overlay != null) { ButtonOverlay?.ApplyStyle(buttonStyle.Overlay); } if (buttonStyle.Text != null) { ButtonText?.ApplyStyle(buttonStyle.Text); } if (buttonStyle.Icon != null) { ButtonIcon?.ApplyStyle(buttonStyle.Icon); } } } /// /// 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() { ControlStates sourceState = ControlState; ControlStates targetState; if (isEnabled) { if (isPressed) { // Pressed targetState = ControlStates.Pressed; } else { // Normal targetState = ControlStates.Normal; // Selected targetState |= (IsSelected ? ControlStates.Selected : 0); // Focused, SelectedFocused targetState |= (IsFocused ? ControlStates.Focused : 0); } } else { // Disabled targetState = ControlStates.Disabled; // DisabledSelected, DisabledFocused targetState |= (IsSelected ? ControlStates.Selected : (IsFocused ? ControlStates.Focused : 0)); } if (sourceState != targetState) { ControlState = targetState; OnUpdate(); StateChangedEventArgs e = new StateChangedEventArgs { PreviousState = sourceState, CurrentState = targetState }; stateChangeHander?.Invoke(this, e); Extension?.OnControlStateChanged(this, new ControlStateChangedEventArgs(sourceState, targetState)); } } /// /// It is hijack by using protected, style copy problem when class inherited from Button. /// /// 6 private void Initialize() { var style = (ButtonStyle)Style; EnableControlStatePropagation = true; UpdateState(); LayoutDirectionChanged += OnLayoutDirectionChanged; } /// /// 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 (Style.IconRelativeOrientation == null || ButtonIcon == null || ButtonText == null) { return; } ButtonText.WidthResizePolicy = ResizePolicyType.Fixed; ButtonText.HeightResizePolicy = ResizePolicyType.Fixed; int textPaddingStart = Style.TextPadding.Start; int textPaddingEnd = Style.TextPadding.End; int textPaddingTop = Style.TextPadding.Top; int textPaddingBottom = Style.TextPadding.Bottom; int iconPaddingStart = Style.IconPadding.Start; int iconPaddingEnd = Style.IconPadding.End; int iconPaddingTop = Style.IconPadding.Top; int iconPaddingBottom = Style.IconPadding.Bottom; if (IconRelativeOrientation == IconOrientation.Top || IconRelativeOrientation == IconOrientation.Bottom) { ButtonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd; ButtonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - ButtonIcon.SizeHeight; } else { ButtonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd - iconPaddingStart - iconPaddingEnd - ButtonIcon.SizeWidth; ButtonText.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 (Style.IconRelativeOrientation == null || ButtonIcon == null || ButtonText == null) { return; } var buttonIcon = ButtonIcon; var buttonText = ButtonText; int textPaddingStart = Style.TextPadding.Start; int textPaddingEnd = Style.TextPadding.End; int textPaddingTop = Style.TextPadding.Top; int textPaddingBottom = Style.TextPadding.Bottom; int iconPaddingStart = Style.IconPadding.Start; int iconPaddingEnd = Style.IconPadding.End; int iconPaddingTop = Style.IconPadding.Top; int iconPaddingBottom = Style.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 /// 8 protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e) { ButtonStyle buttonStyle = StyleManager.Instance.GetViewStyle(style) as ButtonStyle; if (buttonStyle != null) { Style.CopyFrom(buttonStyle); UpdateUIContent(); } } private void UpdateUIContent() { MeasureText(); LayoutChild(); Sensitive = isEnabled; } private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e) { MeasureText(); LayoutChild(); } private void OnClickInternal(ClickEventArgs eventArgs) { Command?.Execute(CommandParameter); OnClick(eventArgs); Extension?.OnClick(this, eventArgs); ClickEvent?.Invoke(this, eventArgs); } private void OnIconRelayout(object sender, EventArgs e) { MeasureText(); LayoutChild(); } /// /// ClickEventArgs is a class to record button click event arguments which will sent to user. /// /// 6 public class ClickEventArgs : EventArgs { } /// /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user. /// /// 6 public class StateChangedEventArgs : EventArgs { /// previous state of Button /// 6 public ControlStates PreviousState; /// current state of Button /// 6 public ControlStates CurrentState; } /// /// Get current text part to the attached ButtonExtension. /// /// /// It returns null if the passed extension is invaild. /// /// The extension instance that is currently attached to this Button. /// The button's text part. [EditorBrowsable(EditorBrowsableState.Never)] public TextLabel GetCurrentText(ButtonExtension extension) { return (extension == Extension) ? ButtonText : null; } /// /// Get current icon part to the attached ButtonExtension. /// /// /// It returns null if the passed extension is invaild. /// /// The extension instance that is currently attached to this Button. /// The button's icon part. [EditorBrowsable(EditorBrowsableState.Never)] public ImageView GetCurrentIcon(ButtonExtension extension) { return (extension == Extension) ? ButtonIcon : null; } /// /// Get current overlay image part to the attached ButtonExtension. /// /// /// It returns null if the passed extension is invaild. /// /// The extension instance that is currently attached to this Button. /// The button's overlay image part. [EditorBrowsable(EditorBrowsableState.Never)] public ImageView GetCurrentOverlayImage(ButtonExtension extension) { return (extension == Extension) ? ButtonOverlay : null; } } }