From 5eb30c79aab9d8238407b7e2544868a06a20b957 Mon Sep 17 00:00:00 2001 From: "dongsug.song" Date: Mon, 14 Mar 2022 22:13:37 +0900 Subject: [PATCH] [NUI][TEST] key foucs default algorithm test --- .../Controls/Navigation/ContentPage.cs | 26 ++++++ .../Controls/Navigation/Navigator.cs | 75 +-------------- .../Controls/Navigation/Page.cs | 66 +++++++++++++- src/Tizen.NUI.Components/Controls/TimePicker.cs | 92 +++++++++++++++---- .../Tizen.NUI.StyleGuide/Examples/PickerExample.cs | 101 +++++++++++++++++++++ 5 files changed, 272 insertions(+), 88 deletions(-) create mode 100644 test/Tizen.NUI.StyleGuide/Examples/PickerExample.cs diff --git a/src/Tizen.NUI.Components/Controls/Navigation/ContentPage.cs b/src/Tizen.NUI.Components/Controls/Navigation/ContentPage.cs index 5b09e0e..51d3d4c 100755 --- a/src/Tizen.NUI.Components/Controls/Navigation/ContentPage.cs +++ b/src/Tizen.NUI.Components/Controls/Navigation/ContentPage.cs @@ -144,6 +144,32 @@ namespace Tizen.NUI.Components NotifyPropertyChanged(); } } + + /// + /// for the case of ContentPage, it sets key focus on AppBar's NavigationContent + /// + protected internal override void RestoreKeyFocus() + { + if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) + { + if (base.LastFocusedView) + { + FocusManager.Instance.SetCurrentFocusView(this.LastFocusedView); + } + else + { + if (AppBar != null && AppBar.NavigationContent != null && AppBar.NavigationContent.Focusable) + { + FocusManager.Instance.SetCurrentFocusView(AppBar.NavigationContent); + } + else + { + FocusManager.Instance.ClearFocus(); + } + } + } + } + private View InternalContent { get diff --git a/src/Tizen.NUI.Components/Controls/Navigation/Navigator.cs b/src/Tizen.NUI.Components/Controls/Navigation/Navigator.cs index 6b6b12b..7e8dbf2 100755 --- a/src/Tizen.NUI.Components/Controls/Navigation/Navigator.cs +++ b/src/Tizen.NUI.Components/Controls/Navigation/Navigator.cs @@ -338,19 +338,7 @@ namespace Tizen.NUI.Components page.InvokeAppearing(); curTop.InvokeDisappearing(); - //test. - // if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) - // { - // curTop.LastFocusedView = FocusManager.Instance.GetCurrentFocusView(); - // if(page.LastFocusedView) - // { - // FocusManager.Instance.SetCurrentFocusView(page.LastFocusedView); - // } - // else - // { - // FocusManager.Instance.ClearFocus(); - // } - // } + curTop.SaveKeyFocus(); //TODO: The following transition codes will be replaced with view transition. InitializeAnimation(); @@ -383,29 +371,15 @@ namespace Tizen.NUI.Components page.InvokeAppeared(); NotifyAccessibilityStatesChangeOfPages(curTop, page); - //test. - // if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) - // { - // FocusManager.Instance.ClearFocus(); - // FocusManager.Instance.MoveFocus(View.FocusDirection.Down); - // //FocusManager.Instance.MoveFocus(View.FocusDirection.Down); - // } - + page.RestoreKeyFocus(); }; newAnimation.Play(); } else { ShowContentOfPage(page); + page.RestoreKeyFocus(); } - - //test. - // if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) - // { - // FocusManager.Instance.ClearFocus(); - // FocusManager.Instance.MoveFocus(View.FocusDirection.Down); - // FocusManager.Instance.MoveFocus(View.FocusDirection.Down); - // } } /// @@ -444,20 +418,7 @@ namespace Tizen.NUI.Components //Invoke Page events newTop.InvokeAppearing(); curTop.InvokeDisappearing(); - - //test. - // if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) - // { - // curTop.LastFocusedView = FocusManager.Instance.GetCurrentFocusView(); - // if(newTop.LastFocusedView) - // { - // FocusManager.Instance.SetCurrentFocusView(newTop.LastFocusedView); - // } - // else - // { - // FocusManager.Instance.ClearFocus(); - // } - // } + curTop.SaveKeyFocus(); //TODO: The following transition codes will be replaced with view transition. InitializeAnimation(); @@ -494,16 +455,7 @@ namespace Tizen.NUI.Components //Invoke Page events newTop.InvokeAppeared(); - - //test. - // if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) - // { - // FocusManager.Instance.ClearFocus(); - // FocusManager.Instance.MoveFocus(View.FocusDirection.Down); - // //FocusManager.Instance.MoveFocus(View.FocusDirection.Down); - // } - - + newTop.RestoreKeyFocus(); }; newAnimation.Play(); } @@ -512,23 +464,6 @@ namespace Tizen.NUI.Components Remove(curTop); } - //test. - // if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) - // { - // if(newTop.LastFocusedView) - // { - // FocusManager.Instance.SetCurrentFocusView(newTop.LastFocusedView); - // } - // } - - // //test. - // if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) - // { - // FocusManager.Instance.ClearFocus(); - // FocusManager.Instance.MoveFocus(View.FocusDirection.Down); - // FocusManager.Instance.MoveFocus(View.FocusDirection.Down); - // } - return curTop; } diff --git a/src/Tizen.NUI.Components/Controls/Navigation/Page.cs b/src/Tizen.NUI.Components/Controls/Navigation/Page.cs index e2d7197..983d923 100755 --- a/src/Tizen.NUI.Components/Controls/Navigation/Page.cs +++ b/src/Tizen.NUI.Components/Controls/Navigation/Page.cs @@ -94,7 +94,7 @@ namespace Tizen.NUI.Components return instance.InternalDisappearingTransition; }); - internal BaseComponents.View LastFocusedView = null; + protected internal BaseComponents.View LastFocusedView = null; private Navigator navigator = null; @@ -232,5 +232,69 @@ namespace Tizen.NUI.Components { Disappeared?.Invoke(this, new PageDisappearedEventArgs()); } + + /// + /// works only when DefaultAlgorithm is enabled. + /// to save the currentl focused View when disappeared. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected internal virtual void SaveKeyFocus() + { + if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) + { + var currentFocusedView = FocusManager.Instance.GetCurrentFocusView(); + if (currentFocusedView) + { + var findChild = this.FindDescendantByID(currentFocusedView.ID); + if (findChild) + { + this.LastFocusedView = findChild; + return; + } + } + this.LastFocusedView = null; + } + } + + /// + /// works only when DefaultAlgorithm is enabled. + /// to set key focused View when showing. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected internal virtual void RestoreKeyFocus() + { + if (FocusManager.Instance.IsDefaultAlgorithmEnabled()) + { + if (this.LastFocusedView) + { + FocusManager.Instance.SetCurrentFocusView(this.LastFocusedView); + } + else + { + var temp = new Tizen.NUI.BaseComponents.View() + { + Size = new Size(0.1f, 0.1f, 0.0f), + Position = new Position(0, 0, 0), + Focusable = true, + }; + this.Add(temp); + temp.LowerToBottom(); + FocusManager.Instance.SetCurrentFocusView(temp); + var focused = FocusManager.Instance.GetNearestFocusableActor(this, temp, Tizen.NUI.BaseComponents.View.FocusDirection.Down); + if (focused) + { + FocusManager.Instance.SetCurrentFocusView(focused); + } + else + { + FocusManager.Instance.ClearFocus(); + } + temp.Unparent(); + temp.Dispose(); + } + } + + } + } } diff --git a/src/Tizen.NUI.Components/Controls/TimePicker.cs b/src/Tizen.NUI.Components/Controls/TimePicker.cs index 101961f..d75e2bd 100755 --- a/src/Tizen.NUI.Components/Controls/TimePicker.cs +++ b/src/Tizen.NUI.Components/Controls/TimePicker.cs @@ -34,7 +34,7 @@ namespace Tizen.NUI.Components /// TimeChangedEventArgs default constructor. /// time value of TimePicker. /// - [EditorBrowsable(EditorBrowsableState.Never)] + [EditorBrowsable(EditorBrowsableState.Never)] public TimeChangedEventArgs(DateTime time) { Time = time; @@ -106,6 +106,7 @@ namespace Tizen.NUI.Components /// 9 public TimePicker() { + SetKeyboardNavigationSupport(true); } /// @@ -115,6 +116,7 @@ namespace Tizen.NUI.Components /// 9 public TimePicker(string style) : base(style) { + SetKeyboardNavigationSupport(true); } /// @@ -124,6 +126,7 @@ namespace Tizen.NUI.Components /// 9 public TimePicker(TimePickerStyle timePickerStyle) : base(timePickerStyle) { + SetKeyboardNavigationSupport(true); } /// @@ -194,7 +197,7 @@ namespace Tizen.NUI.Components else hourPicker.CurrentValue = currentTime.Hour - 12; ampmPicker.CurrentValue = 2; } - else + else { isAm = true; if (currentTime.Hour == 0) hourPicker.CurrentValue = 12; @@ -243,7 +246,7 @@ namespace Tizen.NUI.Components hourPicker.MaxValue = 23; hourPicker.CurrentValue = currentTime.Hour; } - else + else { hourPicker.MinValue = 1; hourPicker.MaxValue = 12; @@ -271,6 +274,7 @@ namespace Tizen.NUI.Components { MinValue = 1, MaxValue = 12, + Focusable = true, }; hourPicker.ValueChanged += OnHourValueChanged; @@ -278,6 +282,7 @@ namespace Tizen.NUI.Components { MinValue = 0, MaxValue = 59, + Focusable = true, }; minutePicker.ValueChanged += OnMinuteValueChanged; @@ -285,6 +290,7 @@ namespace Tizen.NUI.Components { MinValue = 1, MaxValue = 2, + Focusable = true, }; ampmPicker.ValueChanged += OnAmpmValueChanged; @@ -321,7 +327,7 @@ namespace Tizen.NUI.Components //Apply CellPadding. if (timePickerStyle?.CellPadding != null && Layout != null) ((LinearLayout)Layout).CellPadding = new Size2D(timePickerStyle.CellPadding.Width, timePickerStyle.CellPadding.Height); - + //Apply Internal Pickers style. if (timePickerStyle?.Pickers != null && hourPicker != null && minutePicker != null && ampmPicker != null) { @@ -330,7 +336,57 @@ namespace Tizen.NUI.Components ampmPicker.ApplyStyle(timePickerStyle.Pickers); } } - + + /// + /// ToDo : only key navigation is enabled, but value editing is not yet added. for example, after enter key and up/down key the value need be changed. + /// + /// + /// + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override View GetNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled) + { + if (currentFocusedView == hourPicker) + { + if (direction == View.FocusDirection.Right) + { + return minutePicker; + } + else if (direction == View.FocusDirection.Left) + { + return null; + } + } + else if (currentFocusedView == minutePicker) + { + if (direction == View.FocusDirection.Right) + { + return ampmPicker; + } + else if (direction == View.FocusDirection.Left) + { + return hourPicker; + } + } + else if (currentFocusedView == ampmPicker) + { + if (direction == View.FocusDirection.Right) + { + return null; + } + else if (direction == View.FocusDirection.Left) + { + return minutePicker; + } + } + + Tizen.Log.Fatal("NUITEST", $"type={currentFocusedView.GetType()}, direction={direction}"); + + return null; + } + + [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "The CellPadding will be dispose when the time picker disposed")] @@ -338,7 +394,8 @@ namespace Tizen.NUI.Components { HeightSpecification = LayoutParamPolicies.MatchParent; - Layout = new LinearLayout() { + Layout = new LinearLayout() + { LinearOrientation = LinearLayout.Orientation.Horizontal, }; Console.WriteLine("initialize"); @@ -363,12 +420,12 @@ namespace Tizen.NUI.Components if (!is24HourView) { - if (isAm) + if (isAm) { if (e.Value == 12) ChangeTime(0, 0, true); else ChangeTime(e.Value, 0, true); } - else + else { if (e.Value == 12) ChangeTime(12, 0, true); else ChangeTime(e.Value + 12, 0, true); @@ -376,12 +433,12 @@ namespace Tizen.NUI.Components } else ChangeTime(e.Value, 0, true); - + OnTimeChanged(); } private void OnMinuteValueChanged(object sender, ValueChangedEventArgs e) - { + { if (currentTime.Minute == e.Value) return; ChangeTime(0, e.Value, false); @@ -390,7 +447,7 @@ namespace Tizen.NUI.Components } private void OnAmpmValueChanged(object sender, ValueChangedEventArgs e) - { + { if ((isAm && e.Value == 1) || (!isAm && e.Value == 2)) return; if (e.Value == 1) @@ -400,7 +457,7 @@ namespace Tizen.NUI.Components isAm = true; } - else + else { //PM if (currentTime.Hour == 0) ChangeTime(12, 0, true); else ChangeTime(currentTime.Hour + 12, 0, true); @@ -412,7 +469,7 @@ namespace Tizen.NUI.Components } private void OnTimeChanged() - { + { TimeChangedEventArgs eventArgs = new TimeChangedEventArgs(currentTime); TimeChanged?.Invoke(this, eventArgs); } @@ -429,10 +486,11 @@ namespace Tizen.NUI.Components String timePattern = timeFormatInfo.ShortTimePattern; String[] timePatternArray = timePattern.Split(' ', ':'); - foreach (String format in timePatternArray) { - if (format.IndexOf("H") != -1|| format.IndexOf("h") != -1) Add(hourPicker); + foreach (String format in timePatternArray) + { + if (format.IndexOf("H") != -1 || format.IndexOf("h") != -1) Add(hourPicker); else if (format.IndexOf("M") != -1 || format.IndexOf("m") != -1) Add(minutePicker); - else if (format.IndexOf("t") != -1) + else if (format.IndexOf("t") != -1) { is24HourView = false; ampmForceSet = false; @@ -448,7 +506,7 @@ namespace Tizen.NUI.Components //FIXME: There is no localeChanged Event for Component now // AMPM text has to update when system locale changed. CultureInfo info = CultureInfo.CurrentCulture; - ampmText = new string[] {info.DateTimeFormat.AMDesignator, info.DateTimeFormat.PMDesignator}; + ampmText = new string[] { info.DateTimeFormat.AMDesignator, info.DateTimeFormat.PMDesignator }; ampmPicker.DisplayedValues = new ReadOnlyCollection(ampmText); } } diff --git a/test/Tizen.NUI.StyleGuide/Examples/PickerExample.cs b/test/Tizen.NUI.StyleGuide/Examples/PickerExample.cs new file mode 100644 index 0000000..61b9e1f --- /dev/null +++ b/test/Tizen.NUI.StyleGuide/Examples/PickerExample.cs @@ -0,0 +1,101 @@ +/* + * 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 Tizen.NUI; +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Components; + +namespace Tizen.NUI.StyleGuide +{ + // IExample inehrited class will be automatically added in the main examples list. + internal class PickerExample : ContentPage, IExample + { + private Window window; + private View rootContent; + private TimePicker timePicker; + private TextLabel label; + private Button button; + + public void Activate() + { + } + public void Deactivate() + { + window = null; + } + + /// Modify this method for adding other examples. + public PickerExample() : base() + { + WidthSpecification = LayoutParamPolicies.MatchParent; + HeightSpecification = LayoutParamPolicies.MatchParent; + + // Navigator bar title is added here. + AppBar = new AppBar() + { + Title = "Picker Default Style", + }; + + // Example root content view. + // you can decorate, add children on this view. + rootContent = new View() + { + WidthSpecification = LayoutParamPolicies.MatchParent, + HeightSpecification = LayoutParamPolicies.MatchParent, + + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Vertical, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + CellPadding = new Size2D(10, 20), + }, + }; + + // Picker style examples. + timePicker = new TimePicker() + { + WidthSpecification = LayoutParamPolicies.MatchParent, + Time = DateTime.Now + }; + rootContent.Add(timePicker); + + + label = new TextLabel + { + WidthSpecification = LayoutParamPolicies.MatchParent, + Text = $"Time: {timePicker.Time.ToString()}" + }; + rootContent.Add(label); + + button = new Tizen.NUI.Components.Button + { + WidthSpecification = LayoutParamPolicies.MatchParent, + Text = "set time" + }; + rootContent.Add(button); + + button.Clicked += (s, e) => + { + label.Text = $"Time: {timePicker.Time.ToString()}"; + }; + + Content = rootContent; + } + } +} -- 2.7.4