From ca3b6f0f0954199156b20d88856f3c9459875a10 Mon Sep 17 00:00:00 2001 From: Kangho Hur Date: Thu, 13 Apr 2017 15:51:26 +0900 Subject: [PATCH] Add Focus related properties for VE TASK=TCAPI-2264 - Make sure that all these API should be invoked after all renderers are created. (e.g. use it inside Page.OnAppearing()) Change-Id: Ie441a067d5a7b94af120985b0a691fad6ce8250f --- .../TizenSpecific/FocusDirection.cs | 16 ++ .../TizenSpecific/VisualElement.cs | 234 ++++++++++++++++++++- Xamarin.Forms.Core/Xamarin.Forms.Core.csproj | 1 + .../Extensions/FocusDirectionExtensions.cs | 29 +++ .../Renderers/VisualElementRenderer.cs | 135 +++++++++++- packaging/xamarin-forms-tizen.spec | 2 +- 6 files changed, 412 insertions(+), 5 deletions(-) create mode 100644 Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/FocusDirection.cs create mode 100644 Xamarin.Forms.Platform.Tizen/Extensions/FocusDirectionExtensions.cs diff --git a/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/FocusDirection.cs b/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/FocusDirection.cs new file mode 100644 index 0000000..b4f15e1 --- /dev/null +++ b/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/FocusDirection.cs @@ -0,0 +1,16 @@ +using System.ComponentModel; + +namespace Xamarin.Forms.PlatformConfiguration.TizenSpecific +{ + [EditorBrowsable(EditorBrowsableState.Never)] + public enum FocusDirection + { + None, + Back, + Forward, + Up, + Down, + Right, + Left + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/VisualElement.cs b/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/VisualElement.cs index 7eb4c71..40c7d75 100644 --- a/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/VisualElement.cs +++ b/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/VisualElement.cs @@ -1,3 +1,5 @@ +using System.ComponentModel; + namespace Xamarin.Forms.PlatformConfiguration.TizenSpecific { using FormsElement = Forms.VisualElement; @@ -5,6 +7,23 @@ namespace Xamarin.Forms.PlatformConfiguration.TizenSpecific { public static readonly BindableProperty StyleProperty = BindableProperty.Create("ThemeStyle", typeof(string), typeof(VisualElement), default(string)); + public static readonly BindableProperty IsFocusAllowedProperty = BindableProperty.Create("IsFocusAllowed", typeof(bool), typeof(VisualElement), true); + + [EditorBrowsable(EditorBrowsableState.Never)] + public static readonly BindableProperty NextFocusDirectionProperty = BindableProperty.Create("NextFocusDirection", typeof(FocusDirection), typeof(VisualElement), FocusDirection.None, propertyChanged: OnNextFocusDirectionPropertyChanged); + + public static readonly BindableProperty NextFocusUpViewProperty = BindableProperty.Create("NextFocusUpView", typeof(View), typeof(VisualElement), default(View)); + + public static readonly BindableProperty NextFocusDownViewProperty = BindableProperty.Create("NextFocusDownView", typeof(View), typeof(VisualElement), default(View)); + + public static readonly BindableProperty NextFocusLeftViewProperty = BindableProperty.Create("NextFocusLeftView", typeof(View), typeof(VisualElement), default(View)); + + public static readonly BindableProperty NextFocusRightViewProperty = BindableProperty.Create("NextFocusRightView", typeof(View), typeof(VisualElement), default(View)); + + public static readonly BindableProperty NextFocusBackViewProperty = BindableProperty.Create("NextFocusBackView", typeof(View), typeof(VisualElement), default(View)); + + public static readonly BindableProperty NextFocusForwardViewProperty = BindableProperty.Create("NextFocusForwardView", typeof(View), typeof(VisualElement), default(View)); + public static string GetStyle(BindableObject element) { return (string)element.GetValue(StyleProperty); @@ -25,5 +44,218 @@ namespace Xamarin.Forms.PlatformConfiguration.TizenSpecific SetStyle(config.Element, value); return config; } + + public static bool IsFocusAllowed(BindableObject element) + { + return (bool)element.GetValue(IsFocusAllowedProperty); + } + + public static void SetFocusAllowed(BindableObject element, bool value) + { + element.SetValue(IsFocusAllowedProperty, value); + } + + public static bool IsFocusAllowed(this IPlatformElementConfiguration config) + { + return IsFocusAllowed(config.Element); + } + + public static IPlatformElementConfiguration SetFocusAllowed(this IPlatformElementConfiguration config, bool value) + { + SetFocusAllowed(config.Element, value); + return config; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static FocusDirection GetNextFocusDirection(BindableObject element) + { + return (FocusDirection)element.GetValue(NextFocusDirectionProperty); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static void SetNextFocusDirection(BindableObject element, FocusDirection value) + { + element.SetValue(NextFocusDirectionProperty, value); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static FocusDirection GetNextFocusDirection(this IPlatformElementConfiguration config) + { + return GetNextFocusDirection(config.Element); + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public static IPlatformElementConfiguration SetNextFocusDirection(this IPlatformElementConfiguration config, FocusDirection value) + { + SetNextFocusDirection(config.Element, value); + return config; + } + + public static IPlatformElementConfiguration MoveFocusUp(this IPlatformElementConfiguration config) + { + SetNextFocusDirection(config.Element, FocusDirection.Up); + return config; + } + + public static IPlatformElementConfiguration MoveFocusDown(this IPlatformElementConfiguration config) + { + SetNextFocusDirection(config.Element, FocusDirection.Down); + return config; + } + + public static IPlatformElementConfiguration MoveFocusLeft(this IPlatformElementConfiguration config) + { + SetNextFocusDirection(config.Element, FocusDirection.Left); + return config; + } + + public static IPlatformElementConfiguration MoveFocusRight(this IPlatformElementConfiguration config) + { + SetNextFocusDirection(config.Element, FocusDirection.Right); + return config; + } + + public static IPlatformElementConfiguration MoveFocusBack(this IPlatformElementConfiguration config) + { + SetNextFocusDirection(config.Element, FocusDirection.Back); + return config; + } + + public static IPlatformElementConfiguration MoveFocusForward(this IPlatformElementConfiguration config) + { + SetNextFocusDirection(config.Element, FocusDirection.Forward); + return config; + } + + public static View GetNextFocusUpView(BindableObject element) + { + return (View)element.GetValue(NextFocusUpViewProperty); + } + + public static void SetNextFocusUpView(BindableObject element, View value) + { + element.SetValue(NextFocusUpViewProperty, value); + } + + public static View GetNextFocusUpView(this IPlatformElementConfiguration config) + { + return GetNextFocusUpView(config.Element); + } + + public static IPlatformElementConfiguration SetNextFocusUpView(this IPlatformElementConfiguration config, View value) + { + SetNextFocusUpView(config.Element, value); + return config; + } + + public static View GetNextFocusDownView(BindableObject element) + { + return (View)element.GetValue(NextFocusDownViewProperty); + } + + public static void SetNextFocusDownView(BindableObject element, View value) + { + element.SetValue(NextFocusDownViewProperty, value); + } + + public static View GetNextFocusDownView(this IPlatformElementConfiguration config) + { + return GetNextFocusDownView(config.Element); + } + + public static IPlatformElementConfiguration SetNextFocusDownView(this IPlatformElementConfiguration config, View value) + { + SetNextFocusDownView(config.Element, value); + return config; + } + + public static View GetNextFocusLeftView(BindableObject element) + { + return (View)element.GetValue(NextFocusLeftViewProperty); + } + + public static void SetNextFocusLeftView(BindableObject element, View value) + { + element.SetValue(NextFocusLeftViewProperty, value); + } + + public static View GetNextFocusLeftView(this IPlatformElementConfiguration config) + { + return GetNextFocusLeftView(config.Element); + } + + public static IPlatformElementConfiguration SetNextFocusLeftView(this IPlatformElementConfiguration config, View value) + { + SetNextFocusLeftView(config.Element, value); + return config; + } + + public static View GetNextFocusRightView(BindableObject element) + { + return (View)element.GetValue(NextFocusRightViewProperty); + } + + public static void SetNextFocusRightView(BindableObject element, View value) + { + element.SetValue(NextFocusRightViewProperty, value); + } + + public static View GetNextFocusRightView(this IPlatformElementConfiguration config) + { + return GetNextFocusRightView(config.Element); + } + + public static IPlatformElementConfiguration SetNextFocusRightView(this IPlatformElementConfiguration config, View value) + { + SetNextFocusRightView(config.Element, value); + return config; + } + + public static View GetNextFocusBackView(BindableObject element) + { + return (View)element.GetValue(NextFocusBackViewProperty); + } + + public static void SetNextFocusBackView(BindableObject element, View value) + { + element.SetValue(NextFocusBackViewProperty, value); + } + + public static View GetNextFocusBackView(this IPlatformElementConfiguration config) + { + return GetNextFocusBackView(config.Element); + } + + public static IPlatformElementConfiguration SetNextFocusBackView(this IPlatformElementConfiguration config, View value) + { + SetNextFocusBackView(config.Element, value); + return config; + } + + public static View GetNextFocusForwardView(BindableObject element) + { + return (View)element.GetValue(NextFocusForwardViewProperty); + } + + public static void SetNextFocusForwardView(BindableObject element, View value) + { + element.SetValue(NextFocusForwardViewProperty, value); + } + + public static View GetNextFocusForwardView(this IPlatformElementConfiguration config) + { + return GetNextFocusForwardView(config.Element); + } + + public static IPlatformElementConfiguration SetNextFocusForwardView(this IPlatformElementConfiguration config, View value) + { + SetNextFocusForwardView(config.Element, value); + return config; + } + + static void OnNextFocusDirectionPropertyChanged(BindableObject bindable, object oldvalue, object newvalue) + { + bindable.SetValue(NextFocusDirectionProperty, FocusDirection.None); + } } -} +} \ No newline at end of file diff --git a/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj b/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj index 65e6871..fe60e77 100644 --- a/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj +++ b/Xamarin.Forms.Core/Xamarin.Forms.Core.csproj @@ -110,6 +110,7 @@ + diff --git a/Xamarin.Forms.Platform.Tizen/Extensions/FocusDirectionExtensions.cs b/Xamarin.Forms.Platform.Tizen/Extensions/FocusDirectionExtensions.cs new file mode 100644 index 0000000..fe7d090 --- /dev/null +++ b/Xamarin.Forms.Platform.Tizen/Extensions/FocusDirectionExtensions.cs @@ -0,0 +1,29 @@ +using Xamarin.Forms.PlatformConfiguration.TizenSpecific; +using EFocusDirection = ElmSharp.FocusDirection; + +namespace Xamarin.Forms.Platform.Tizen +{ + public static class FocusDirectionExtensions + { + public static EFocusDirection ToNative(this FocusDirection direction) + { + switch (direction) + { + case FocusDirection.Back: + return EFocusDirection.Previous; + case FocusDirection.Forward: + return EFocusDirection.Next; + case FocusDirection.Up: + return EFocusDirection.Up; + case FocusDirection.Down: + return EFocusDirection.Down; + case FocusDirection.Right: + return EFocusDirection.Right; + case FocusDirection.Left: + return EFocusDirection.Left; + default: + return EFocusDirection.Next; + } + } + } +} diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/VisualElementRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/VisualElementRenderer.cs index 6baff19..51170bd 100644 --- a/Xamarin.Forms.Platform.Tizen/Renderers/VisualElementRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/VisualElementRenderer.cs @@ -3,11 +3,10 @@ using System.Collections.Generic; using System.Diagnostics; using System.ComponentModel; using ElmSharp; -using EColor = ElmSharp.Color; using ESize = ElmSharp.Size; using ERect = ElmSharp.Rect; -using ERectangle = ElmSharp.Rectangle; using Specific = Xamarin.Forms.PlatformConfiguration.TizenSpecific.VisualElement; +using XFocusDirection = Xamarin.Forms.PlatformConfiguration.TizenSpecific.FocusDirection; namespace Xamarin.Forms.Platform.Tizen { @@ -55,6 +54,14 @@ namespace Xamarin.Forms.Platform.Tizen RegisterPropertyHandler(VisualElement.InputTransparentProperty, UpdateInputTransparent); RegisterPropertyHandler(VisualElement.BackgroundColorProperty, UpdateBackgroundColor); RegisterPropertyHandler(Specific.StyleProperty, UpdateThemeStyle); + RegisterPropertyHandler(Specific.IsFocusAllowedProperty, UpdateFocusAllowed); + RegisterPropertyHandler(Specific.NextFocusDirectionProperty, UpdateFocusDirection); + RegisterPropertyHandler(Specific.NextFocusUpViewProperty, UpdateFocusUpView); + RegisterPropertyHandler(Specific.NextFocusDownViewProperty, UpdateFocusDownView); + RegisterPropertyHandler(Specific.NextFocusLeftViewProperty, UpdateFocusLeftView); + RegisterPropertyHandler(Specific.NextFocusRightViewProperty, UpdateFocusRightView); + RegisterPropertyHandler(Specific.NextFocusBackViewProperty, UpdateFocusBackView); + RegisterPropertyHandler(Specific.NextFocusForwardViewProperty, UpdateFocusForwardView); RegisterPropertyHandler(VisualElement.AnchorXProperty, ApplyTransformation); RegisterPropertyHandler(VisualElement.AnchorYProperty, ApplyTransformation); @@ -778,6 +785,128 @@ namespace Xamarin.Forms.Platform.Tizen { } + void UpdateFocusAllowed(bool initialize) + { + if (!initialize) + { + var widget = NativeView as Widget; + if (widget != null) + { + widget.AllowFocus(Specific.IsFocusAllowed(Element)); + } + else + { + Log.Warn("{0} uses {1} which does not support Focus management", this, NativeView); + } + } + } + + void UpdateFocusDirection(bool initialize) + { + var direction = Specific.GetNextFocusDirection(Element); + if (!initialize && direction != XFocusDirection.None) + { + var widget = NativeView as Widget; + if (widget != null) + { + widget.FocusNext(direction.ToNative()); + } + else + { + Log.Warn("{0} uses {1} which does not support Focus management", this, NativeView); + } + } + } + + void SetNextFocusViewInternal(XFocusDirection direction) + { + var widget = NativeView as Widget; + if (widget != null) + { + EvasObject nativeControl; + switch (direction) + { + case XFocusDirection.Back: + nativeControl = Platform.GetRenderer(Specific.GetNextFocusBackView(Element))?.NativeView; + break; + case XFocusDirection.Forward: + nativeControl = Platform.GetRenderer(Specific.GetNextFocusForwardView(Element))?.NativeView; + break; + case XFocusDirection.Up: + nativeControl = Platform.GetRenderer(Specific.GetNextFocusUpView(Element))?.NativeView; + break; + case XFocusDirection.Down: + nativeControl = Platform.GetRenderer(Specific.GetNextFocusDownView(Element))?.NativeView; + break; + case XFocusDirection.Right: + nativeControl = Platform.GetRenderer(Specific.GetNextFocusRightView(Element))?.NativeView; + break; + case XFocusDirection.Left: + nativeControl = Platform.GetRenderer(Specific.GetNextFocusLeftView(Element))?.NativeView; + break; + default: + nativeControl = null; + break; + } + if (nativeControl != null) + { + widget.SetNextFocusObject(nativeControl, direction.ToNative()); + } + } + else + { + Log.Warn("{0} uses {1} which does not support Focus management", this, NativeView); + } + } + + void UpdateFocusUpView(bool initialize) + { + if (!initialize && Specific.GetNextFocusUpView(Element) != null) + { + SetNextFocusViewInternal(XFocusDirection.Up); + } + } + + void UpdateFocusDownView(bool initialize) + { + if (!initialize && Specific.GetNextFocusDownView(Element) != null) + { + SetNextFocusViewInternal(XFocusDirection.Down); + } + } + + void UpdateFocusLeftView(bool initialize) + { + if (!initialize && Specific.GetNextFocusLeftView(Element) != null) + { + SetNextFocusViewInternal(XFocusDirection.Left); + } + } + + void UpdateFocusRightView(bool initialize) + { + if (!initialize && Specific.GetNextFocusRightView(Element) != null) + { + SetNextFocusViewInternal(XFocusDirection.Right); + } + } + + void UpdateFocusBackView(bool initialize) + { + if (!initialize && Specific.GetNextFocusBackView(Element) != null) + { + SetNextFocusViewInternal(XFocusDirection.Back); + } + } + + void UpdateFocusForwardView(bool initialize) + { + if (!initialize && Specific.GetNextFocusForwardView(Element) != null) + { + SetNextFocusViewInternal(XFocusDirection.Forward); + } + } + void ApplyRotation(EvasMap map, ERect geometry, ref bool changed) { var rotationX = Element.RotationX; @@ -890,4 +1019,4 @@ namespace Xamarin.Forms.Platform.Tizen --s_ignoreCount; } } -} \ No newline at end of file +} diff --git a/packaging/xamarin-forms-tizen.spec b/packaging/xamarin-forms-tizen.spec index 0a280c1..f230c3d 100644 --- a/packaging/xamarin-forms-tizen.spec +++ b/packaging/xamarin-forms-tizen.spec @@ -2,7 +2,7 @@ %define XF_RELEASE 214 # Increase this XF_DEV_VERSION when any public APIs of Xamarin.Forms.Platform.Tizen are changed. -%define XF_DEV_VERSION 003 +%define XF_DEV_VERSION 004 Name: xamarin-forms-tizen Summary: Xamarin.Forms for Tizen platform -- 2.7.4