Add Focus related properties for VE
authorKangho Hur <kangho.hur@samsung.com>
Thu, 13 Apr 2017 06:51:26 +0000 (15:51 +0900)
committerKangho Hur <kangho.hur@samsung.com>
Mon, 24 Apr 2017 04:39:49 +0000 (13:39 +0900)
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

Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/FocusDirection.cs [new file with mode: 0644]
Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/VisualElement.cs
Xamarin.Forms.Core/Xamarin.Forms.Core.csproj
Xamarin.Forms.Platform.Tizen/Extensions/FocusDirectionExtensions.cs [new file with mode: 0644]
Xamarin.Forms.Platform.Tizen/Renderers/VisualElementRenderer.cs
packaging/xamarin-forms-tizen.spec

diff --git a/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/FocusDirection.cs b/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/FocusDirection.cs
new file mode 100644 (file)
index 0000000..b4f15e1
--- /dev/null
@@ -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
index 7eb4c71..40c7d75 100644 (file)
@@ -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<Tizen, FormsElement> config)
+               {
+                       return IsFocusAllowed(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetFocusAllowed(this IPlatformElementConfiguration<Tizen, FormsElement> 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<Tizen, FormsElement> config)
+               {
+                       return GetNextFocusDirection(config.Element);
+               }
+
+               [EditorBrowsable(EditorBrowsableState.Never)]
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetNextFocusDirection(this IPlatformElementConfiguration<Tizen, FormsElement> config, FocusDirection value)
+               {
+                       SetNextFocusDirection(config.Element, value);
+                       return config;
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> MoveFocusUp(this IPlatformElementConfiguration<Tizen, FormsElement> config)
+               {
+                       SetNextFocusDirection(config.Element, FocusDirection.Up);
+                       return config;
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> MoveFocusDown(this IPlatformElementConfiguration<Tizen, FormsElement> config)
+               {
+                       SetNextFocusDirection(config.Element, FocusDirection.Down);
+                       return config;
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> MoveFocusLeft(this IPlatformElementConfiguration<Tizen, FormsElement> config)
+               {
+                       SetNextFocusDirection(config.Element, FocusDirection.Left);
+                       return config;
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> MoveFocusRight(this IPlatformElementConfiguration<Tizen, FormsElement> config)
+               {
+                       SetNextFocusDirection(config.Element, FocusDirection.Right);
+                       return config;
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> MoveFocusBack(this IPlatformElementConfiguration<Tizen, FormsElement> config)
+               {
+                       SetNextFocusDirection(config.Element, FocusDirection.Back);
+                       return config;
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> MoveFocusForward(this IPlatformElementConfiguration<Tizen, FormsElement> 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<Tizen, FormsElement> config)
+               {
+                       return GetNextFocusUpView(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetNextFocusUpView(this IPlatformElementConfiguration<Tizen, FormsElement> 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<Tizen, FormsElement> config)
+               {
+                       return GetNextFocusDownView(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetNextFocusDownView(this IPlatformElementConfiguration<Tizen, FormsElement> 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<Tizen, FormsElement> config)
+               {
+                       return GetNextFocusLeftView(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetNextFocusLeftView(this IPlatformElementConfiguration<Tizen, FormsElement> 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<Tizen, FormsElement> config)
+               {
+                       return GetNextFocusRightView(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetNextFocusRightView(this IPlatformElementConfiguration<Tizen, FormsElement> 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<Tizen, FormsElement> config)
+               {
+                       return GetNextFocusBackView(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetNextFocusBackView(this IPlatformElementConfiguration<Tizen, FormsElement> 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<Tizen, FormsElement> config)
+               {
+                       return GetNextFocusForwardView(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetNextFocusForwardView(this IPlatformElementConfiguration<Tizen, FormsElement> 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
index 5cb829e..5cdf7d1 100644 (file)
     <Compile Include="PlatformConfiguration\iOSSpecific\UIStatusBarAnimation.cs" />
     <Compile Include="PlatformConfiguration\iOSSpecific\UpdateMode.cs" />
     <Compile Include="PlatformConfiguration\iOSSpecific\VisualElement.cs" />
+    <Compile Include="PlatformConfiguration\TizenSpecific\FocusDirection.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\StyleValues.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\VisualElement.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\Page.cs" />
diff --git a/Xamarin.Forms.Platform.Tizen/Extensions/FocusDirectionExtensions.cs b/Xamarin.Forms.Platform.Tizen/Extensions/FocusDirectionExtensions.cs
new file mode 100644 (file)
index 0000000..fe7d090
--- /dev/null
@@ -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;
+                       }
+               }
+       }
+}
index 6baff19..51170bd 100644 (file)
@@ -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
+}
index 0a280c1..f230c3d 100644 (file)
@@ -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