X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2FTizen.NUI.Components%2FControls%2FButton.Internal.cs;h=ea06e8f05bcce5587855cc0bf1f6d5ff92430683;hb=6abbb85ad2ceac1606192524b1bf8a2823829f73;hp=d57c4f0fd5ac81113edaa7ea0ab0efb333129eef;hpb=3aef9c55da730ee0b73edbfa5f6f521a2870c0ba;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git diff --git a/src/Tizen.NUI.Components/Controls/Button.Internal.cs b/src/Tizen.NUI.Components/Controls/Button.Internal.cs old mode 100755 new mode 100644 index d57c4f0..ea06e8f --- a/src/Tizen.NUI.Components/Controls/Button.Internal.cs +++ b/src/Tizen.NUI.Components/Controls/Button.Internal.cs @@ -1,7 +1,26 @@ -using System; +/* + * Copyright(c) 2022 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 System.Diagnostics; using Tizen.NUI.BaseComponents; using Tizen.NUI.Components.Extension; +using Tizen.NUI.Accessibility; // To use AccessibilityManager namespace Tizen.NUI.Components { @@ -10,19 +29,21 @@ namespace Tizen.NUI.Components private ImageView overlayImage; private TextLabel buttonText; private ImageView buttonIcon; + private Vector2 size; - private EventHandler stateChangeHander; + private EventHandler stateChangeHandler; - private bool isSelected = false; - private bool isEnabled = true; private bool isPressed = false; + internal int styleApplying = 0; - private StringSelector textSelector = new StringSelector(); - private StringSelector translatableTextSelector = new StringSelector(); - private ColorSelector textColorSelector = new ColorSelector(); - private FloatSelector pointSizeSelector = new FloatSelector(); - - private StringSelector iconURLSelector = new StringSelector(); + /// + /// Gets accessibility name. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override string AccessibilityGetName() + { + return Text; + } /// /// The ButtonExtension instance that is injected by ButtonStyle. @@ -37,7 +58,12 @@ namespace Tizen.NUI.Components [EditorBrowsable(EditorBrowsableState.Never)] protected virtual TextLabel CreateText() { - return new TextLabel(); + return new TextLabel(new TextLabelStyle()) + { + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + AccessibilityHidden = true, + }; } /// @@ -47,7 +73,10 @@ namespace Tizen.NUI.Components [EditorBrowsable(EditorBrowsableState.Never)] protected virtual ImageView CreateIcon() { - return new ImageView(); + return new ImageView() + { + AccessibilityHidden = true, + }; } /// @@ -57,7 +86,15 @@ namespace Tizen.NUI.Components [EditorBrowsable(EditorBrowsableState.Never)] protected virtual ImageView CreateOverlayImage() { - return new ImageView(); + return new ImageView + { + PositionUsesPivotPoint = true, + ParentOrigin = NUI.ParentOrigin.Center, + PivotPoint = NUI.PivotPoint.Center, + WidthResizePolicy = ResizePolicyType.FillToParent, + HeightResizePolicy = ResizePolicyType.FillToParent, + AccessibilityHidden = true, + }; } /// @@ -65,7 +102,7 @@ namespace Tizen.NUI.Components /// /// The click information. [EditorBrowsable(EditorBrowsableState.Never)] - protected virtual void OnClick(ClickEventArgs eventArgs) + protected virtual void OnClicked(ClickedEventArgs eventArgs) { } @@ -84,20 +121,80 @@ namespace Tizen.NUI.Components protected override void OnUpdate() { base.OnUpdate(); - UpdateUIContent(); - Extension?.OnRelayout(this); } + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override bool HandleControlStateOnTouch(Touch touch) + { + if (!IsEnabled || 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: + { + if (!isPressed) + { + return false; + } + + isPressed = false; + + if (IsSelectable) + { + Extension?.SetTouchInfo(touch); + IsSelected = !IsSelected; + } + else + { + Extension?.SetTouchInfo(touch); + UpdateState(); + } + + ClickedEventArgs eventArgs = new ClickedEventArgs(); + OnClickedInternal(eventArgs, touch); + + return true; + } + default: + break; + } + return base.HandleControlStateOnTouch(touch); + } + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void OnEnabled(bool enabled) + { + base.OnEnabled(enabled); + UpdateState(); + } + /// /// 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 (styleApplying > 0) return; + ControlState sourceState = ControlState; ControlState targetState; @@ -123,270 +220,265 @@ namespace Tizen.NUI.Components PreviousState = ControlStatesExtension.FromControlStateClass(sourceState), CurrentState = ControlStatesExtension.FromControlStateClass(targetState) }; - stateChangeHander?.Invoke(this, e); + stateChangeHandler?.Invoke(this, e); Extension?.OnControlStateChanged(this, new ControlStateChangedEventArgs(sourceState, targetState)); } } /// - /// Measure text, it can be override. + /// Dispose Button and all children on it. /// + /// Dispose type. /// 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() + protected override void Dispose(DisposeTypes type) { - if (Style.IconRelativeOrientation == null || Icon == null || TextLabel == null) + if (disposed) { return; } - TextLabel.WidthResizePolicy = ResizePolicyType.Fixed; - TextLabel.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) - { - TextLabel.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd; - TextLabel.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - Icon.SizeHeight; - } - else + + if (type == DisposeTypes.Explicit) { - TextLabel.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd - iconPaddingStart - iconPaddingEnd - Icon.SizeWidth; - TextLabel.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom; + Extension?.OnDispose(this); + + if (buttonIcon != null) + { + Utility.Dispose(buttonIcon); + } + if (buttonText != null) + { + Utility.Dispose(buttonText); + } + if (overlayImage != null) + { + Utility.Dispose(overlayImage); + } } + + base.Dispose(type); } /// - /// Layout child, it can be override. + /// Initializes AT-SPI object. /// - /// 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() + public override void OnInitialize() + { + base.OnInitialize(); + + AccessibilityRole = Role.PushButton; + AccessibilityHighlightable = true; + EnableControlStatePropagation = true; + + AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "Button"); + + buttonText = CreateText(); + buttonIcon = CreateIcon(); + LayoutItems(); + + Feedback = true; + } + + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void OnRelayout(Vector2 size, RelayoutContainer container) { - if (Style.IconRelativeOrientation == null || Icon == null || TextLabel == null) + if (size == null) return; + + if (size.Equals(this.size)) { return; } - var buttonIcon = Icon; - var buttonText = TextLabel; + this.size = new Vector2(size); - int textPaddingStart = Style.TextPadding.Start; - int textPaddingEnd = Style.TextPadding.End; - int textPaddingTop = Style.TextPadding.Top; - int textPaddingBottom = Style.TextPadding.Bottom; + UpdateSizeAndSpacing(); + } - int iconPaddingStart = Style.IconPadding.Start; - int iconPaddingEnd = Style.IconPadding.End; - int iconPaddingTop = Style.IconPadding.Top; - int iconPaddingBottom = Style.IconPadding.Bottom; + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo) + { + base.OnControlStateChanged(controlStateChangedInfo); - 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); - } + var stateEnabled = !controlStateChangedInfo.CurrentState.Contains(ControlState.Disabled); - 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 (IsEnabled != stateEnabled) + { + IsEnabled = stateEnabled; } - if (string.IsNullOrEmpty(buttonText.Text)) + + var statePressed = controlStateChangedInfo.CurrentState.Contains(ControlState.Pressed); + + if (isPressed != statePressed) { - buttonIcon.ParentOrigin = NUI.ParentOrigin.Center; - buttonIcon.PivotPoint = NUI.PivotPoint.Center; + isPressed = statePressed; } - } - /// - /// 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) + if (IsSelectable) { - Style.CopyFrom(buttonStyle); - UpdateUIContent(); + var stateSelected = controlStateChangedInfo.CurrentState.Contains(ControlState.Selected); + + if (IsSelected != stateSelected) + { + IsSelected = stateSelected; + } } } /// - /// Dispose Button and all children on it. + /// Put sub items (e.g. buttonText, buttonIcon) to the right place. /// - /// Dispose type. - /// 6 - protected override void Dispose(DisposeTypes type) + [EditorBrowsable(EditorBrowsableState.Never)] + protected virtual void LayoutItems() { - if (disposed) + if (buttonIcon == null || buttonText == null) { return; } - if (type == DisposeTypes.Explicit) + buttonIcon.Unparent(); + buttonText.Unparent(); + overlayImage?.Unparent(); + +#pragma warning disable CA2000 + Size2D cellPadding = String.IsNullOrEmpty(buttonText.Text) ? new Size2D(0, 0) : itemSpacing; +#pragma warning restore CA2000 + + if (IconRelativeOrientation == IconOrientation.Left) { - Extension?.OnDispose(this); + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + HorizontalAlignment = itemHorizontalAlignment, + VerticalAlignment = itemVerticalAlignment, + CellPadding = cellPadding + }; - if (Icon != null) + Add(buttonIcon); + Add(buttonText); + } + else if (IconRelativeOrientation == IconOrientation.Right) + { + Layout = new LinearLayout() { - Utility.Dispose(Icon); - } - if (TextLabel != null) + LinearOrientation = LinearLayout.Orientation.Horizontal, + HorizontalAlignment = itemHorizontalAlignment, + VerticalAlignment = itemVerticalAlignment, + CellPadding = cellPadding + }; + + Add(buttonText); + Add(buttonIcon); + } + else if (IconRelativeOrientation == IconOrientation.Top) + { + Layout = new LinearLayout() { - Utility.Dispose(TextLabel); - } - if (OverlayImage != null) + LinearOrientation = LinearLayout.Orientation.Vertical, + HorizontalAlignment = itemHorizontalAlignment, + VerticalAlignment = itemVerticalAlignment, + CellPadding = cellPadding + }; + + Add(buttonIcon); + Add(buttonText); + } + else if (IconRelativeOrientation == IconOrientation.Bottom) + { + Layout = new LinearLayout() { - Utility.Dispose(OverlayImage); - } + LinearOrientation = LinearLayout.Orientation.Vertical, + HorizontalAlignment = itemHorizontalAlignment, + VerticalAlignment = itemVerticalAlignment, + CellPadding = cellPadding + }; + + Add(buttonText); + Add(buttonIcon); } - base.Dispose(type); + if (overlayImage != null) + { + overlayImage.ExcludeLayouting = true; + Add(overlayImage); + } } - /// - [EditorBrowsable(EditorBrowsableState.Never)] - protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo) + private void UpdateSizeAndSpacing() { - base.OnControlStateChanged(controlStateChangedInfo); + if (size == null || buttonIcon == null || buttonText == null) + { + return; + } - var stateEnabled = !controlStateChangedInfo.CurrentState.Contains(ControlState.Disabled); + LinearLayout layout = Layout as LinearLayout; - if (isEnabled != stateEnabled) + if (layout == null) { - isEnabled = stateEnabled; + return; } - var statePressed = controlStateChangedInfo.CurrentState.Contains(ControlState.Pressed); + float lengthWithoutText = 0; + Size2D cellPadding = null; + Extents iconMargin = buttonIcon.Margin ?? new Extents(0); + Extents textMargin = buttonText.Margin ?? new Extents(0); - if (isPressed != statePressed) + if (buttonIcon.Size.Width != 0 && buttonIcon.Size.Height != 0) { - isPressed = statePressed; - } - } + lengthWithoutText = buttonIcon.Size.Width; - /// - /// 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; - } + if (!String.IsNullOrEmpty(buttonText.Text)) + { + cellPadding = itemSpacing; - private void UpdateUIContent() - { - MeasureText(); - LayoutChild(); + if (iconRelativeOrientation == IconOrientation.Left || iconRelativeOrientation == IconOrientation.Right) + { + lengthWithoutText += (itemSpacing?.Width ?? 0) + iconMargin.Start + iconMargin.End + textMargin.Start + textMargin.End + Padding.Start + Padding.End; + } + else + { + lengthWithoutText += (itemSpacing?.Height ?? 0) + iconMargin.Top + iconMargin.Bottom + textMargin.Top + textMargin.Bottom + Padding.Top + Padding.Bottom; + } + } + } - Sensitive = isEnabled; + layout.CellPadding = cellPadding ?? new Size2D(0, 0); + + // If the button has fixed width and the text is not empty, the text should not exceed button boundary. + if (WidthSpecification != LayoutParamPolicies.WrapContent && !String.IsNullOrEmpty(buttonText.Text)) + { + buttonText.MaximumSize = new Size2D((int)Math.Max(size.Width - lengthWithoutText, Math.Max(buttonText.MinimumSize.Width, 1)), (int)size.Height); + } } - private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e) + private void OnClickedInternal(ClickedEventArgs eventArgs, Touch touch) { - MeasureText(); - LayoutChild(); + // If GrabTouchAfterLeave is true, Up will result in Finished rather than Interrupted even if it is out of the button area. + // So, it is necessary to check whether it is Up in the button area. + if (GrabTouchAfterLeave == true) + { + Vector2 localPosition = touch.GetLocalPosition(0); + if ((localPosition != null && Size != null && + 0 <= localPosition.X && localPosition.X <= Size.Width && + 0 <= localPosition.Y && localPosition.Y <= Size.Height) == false) + { + return; + } + } + OnClickedInternal(eventArgs); } - private void OnClickInternal(ClickEventArgs eventArgs) + private void OnClickedInternal(ClickedEventArgs eventArgs) { Command?.Execute(CommandParameter); - OnClick(eventArgs); - Extension?.OnClick(this, eventArgs); - ClickEvent?.Invoke(this, eventArgs); - } + OnClicked(eventArgs); + Extension?.OnClicked(this, eventArgs); - private void OnIconRelayout(object sender, EventArgs e) - { - MeasureText(); - LayoutChild(); + ClickEventArgs nestedEventArgs = new ClickEventArgs(); + ClickEvent?.Invoke(this, nestedEventArgs); + Clicked?.Invoke(this, eventArgs); } - } }