private EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> preFocusChangeEventHandler;
private PreFocusChangeEventCallback preFocusChangeCallback;
+ private EventHandler<FocusChangingEventArgs> focusChangingEventHandler;
+ private PreFocusChangeEventCallback focusChangingCallback;
+
private EventHandler<FocusChangedEventArgs> focusChangedEventHandler;
private FocusChangedEventCallback focusChangedEventCallback;
/// It won't be emitted for focus movement by calling the SetCurrentFocusView directly.<br />
/// </summary>
/// <since_tizen> 3 </since_tizen>
+ [Obsolete("Please do not use! This will be deprecated in API10. Please use KeyFocusChanging instead!")]
+ // this will be deprecated, so suppress warning would be OK.
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1710:Identifiers should have correct suffix", Justification = "<Pending>")]
public event EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> PreFocusChange
{
add
if (preFocusChangeEventHandler == null)
{
preFocusChangeCallback = OnPreFocusChange;
- PreFocusChangeSignal().Connect(preFocusChangeCallback);
+ using PreFocusChangeSignal signal = PreFocusChangeSignal();
+ signal?.Connect(preFocusChangeCallback);
}
preFocusChangeEventHandler += value;
}
remove
{
preFocusChangeEventHandler -= value;
- if (preFocusChangeEventHandler == null && PreFocusChangeSignal().Empty() == false)
+ using PreFocusChangeSignal signal = PreFocusChangeSignal();
+ if (preFocusChangeEventHandler == null && signal?.Empty() == false)
{
- PreFocusChangeSignal().Disconnect(preFocusChangeCallback);
+ signal?.Disconnect(preFocusChangeCallback);
}
}
}
/// <summary>
- /// The FocusGroupChanged will be triggered after the current focused view has been changed.
+ /// FocusChanging will be triggered before the focus is going to be changed.<br />
+ /// The FocusManager makes the best guess for which view to focus towards the given direction, but applications might want to change that.<br />
+ /// By connecting with this event, they can check the proposed view to focus and assign a different view if they wish.<br />
+ /// This event is only triggered when the navigation key is pressed and FocusManager tries to move the focus automatically.<br />
+ /// It won't be emitted for focus movement by calling the SetCurrentFocusView directly.<br />
+ /// </summary>
+ /// <remarks>
+ /// by setting FocusChangingEventArgs.Proposed with the view to be focused, the focus will be moved to the assigned view.
+ /// </remarks>
+ /// <since_tizen> 10 </since_tizen>
+ public event EventHandler<FocusChangingEventArgs> FocusChanging
+ {
+ add
+ {
+ if (focusChangingEventHandler == null)
+ {
+ focusChangingCallback = OnFocusChanging;
+ //this is same as old PreFocusChangeSignal, so the body will be same. (only name is changed, behavior is same)
+ using PreFocusChangeSignal signal = PreFocusChangeSignal();
+ signal?.Connect(focusChangingCallback);
+ }
+ focusChangingEventHandler += value;
+ }
+ remove
+ {
+ focusChangingEventHandler -= value;
+ //this is same as old PreFocusChangeSignal, so the body will be same. (only name is changed, behavior is same)
+ using PreFocusChangeSignal signal = PreFocusChangeSignal();
+ if (focusChangingEventHandler == null && signal?.Empty() == false)
+ {
+ signal?.Disconnect(focusChangingCallback);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The FocusChanged will be triggered after the current focused view has been changed.
/// </summary>
/// <since_tizen> 3 </since_tizen>
public event EventHandler<FocusChangedEventArgs> FocusChanged
if (focusChangedEventCallback == null)
{
focusChangedEventCallback = OnFocusChanged;
- FocusChangedSignal().Connect(focusChangedEventCallback);
+ using FocusChangedSignal signal = FocusChangedSignal();
+ signal?.Connect(focusChangedEventCallback);
}
focusChangedEventHandler += value;
}
{
focusChangedEventHandler -= value;
- if (focusChangedEventCallback == null && FocusChangedSignal().Empty() == false)
+ using FocusChangedSignal signal = FocusChangedSignal();
+ if (focusChangedEventCallback == null && signal?.Empty() == false)
{
- FocusChangedSignal().Disconnect(focusChangedEventCallback);
+ signal?.Disconnect(focusChangedEventCallback);
}
}
}
if (focusGroupChangedEventCallback == null)
{
focusGroupChangedEventCallback = OnFocusGroupChanged;
- FocusGroupChangedSignal().Connect(focusGroupChangedEventCallback);
+ using FocusGroupChangedSignal signal = FocusGroupChangedSignal();
+ signal?.Connect(focusGroupChangedEventCallback);
}
focusGroupChangedEventHandler += value;
}
{
focusGroupChangedEventHandler -= value;
- if (focusGroupChangedEventCallback == null && FocusGroupChangedSignal().Empty() == false)
+ using FocusGroupChangedSignal signal = FocusGroupChangedSignal();
+ if (focusGroupChangedEventCallback == null && signal?.Empty() == false)
{
- FocusGroupChangedSignal().Disconnect(focusGroupChangedEventCallback);
+ signal?.Disconnect(focusGroupChangedEventCallback);
}
}
}
if (focusedViewEnterKeyEventCallback == null)
{
focusedViewEnterKeyEventCallback = OnFocusedViewEnterKey;
- FocusedViewEnterKeySignal().Connect(focusedViewEnterKeyEventCallback);
+ using ViewSignal signal = FocusedViewEnterKeySignal();
+ signal?.Connect(focusedViewEnterKeyEventCallback);
}
focusedViewEnterKeyEventHandler += value;
}
{
focusedViewEnterKeyEventHandler -= value;
- if (focusedViewEnterKeyEventCallback != null && FocusedViewEnterKeySignal().Empty() == false)
+ using ViewSignal signal = FocusedViewEnterKeySignal();
+ if (focusedViewEnterKeyEventCallback != null && signal?.Empty() == false)
{
- FocusedViewEnterKeySignal().Disconnect(focusedViewEnterKeyEventCallback);
+ signal?.Disconnect(focusedViewEnterKeyEventCallback);
}
}
}
if (focusedViewEnterKeyEventCallback2 == null)
{
focusedViewEnterKeyEventCallback2 = OnFocusedViewEnterKey2;
- FocusedViewEnterKeySignal().Connect(focusedViewEnterKeyEventCallback2);
+ using ViewSignal signal = FocusedViewEnterKeySignal();
+ signal?.Connect(focusedViewEnterKeyEventCallback2);
}
focusedViewEnterKeyEventHandler2 += value;
}
{
focusedViewEnterKeyEventHandler2 -= value;
- if (focusedViewEnterKeyEventCallback2 != null && FocusedViewEnterKeySignal().Empty() == false)
+ using ViewSignal signal = FocusedViewEnterKeySignal();
+ if (focusedViewEnterKeyEventCallback2 != null && signal?.Empty() == false)
{
- FocusedViewEnterKeySignal().Disconnect(focusedViewEnterKeyEventCallback2);
+ signal?.Disconnect(focusedViewEnterKeyEventCallback2);
}
}
}
}
}
+ private IntPtr OnFocusChanging(IntPtr current, IntPtr proposed, View.FocusDirection direction)
+ {
+ View originallyProposed = null;
+ FocusChangingEventArgs e = new FocusChangingEventArgs();
+
+ if (current != global::System.IntPtr.Zero)
+ {
+ e.Current = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
+ }
+ if (proposed != global::System.IntPtr.Zero)
+ {
+ originallyProposed = e.Proposed = Registry.GetManagedBaseHandleFromNativePtr(proposed) as View;
+ }
+ e.Direction = direction;
+
+ focusChangingEventHandler?.Invoke(this, e);
+
+ if (originallyProposed != e.Proposed)
+ {
+ //when user has changed Proposed
+ return e.Proposed.GetPtrfromView();
+ }
+ else
+ {
+ if (originallyProposed != null)
+ {
+ return proposed;
+ }
+ else
+ {
+ return current;
+ }
+ }
+ }
+
private void OnFocusChanged(IntPtr current, IntPtr next)
{
if (focusChangedEventHandler != null)
{
FocusChangedEventArgs e = new FocusChangedEventArgs();
- e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
- e.NextView = Registry.GetManagedBaseHandleFromNativePtr(next) as View;
+ e.Previous = e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
+ e.Current = e.NextView = Registry.GetManagedBaseHandleFromNativePtr(next) as View;
focusChangedEventHandler(this, e);
}
}
/// Event arguments that passed via the PreFocusChange signal.
/// </summary>
/// <since_tizen> 3 </since_tizen>
+ [Obsolete("Please do not use! This will be deprecated in API10. Please use FocusChangingEventArgs instead!")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1034:Nested types should not be visible", Justification = "<Pending>")]
+ // this will be deprecated, so suppress warning would be OK.
public class PreFocusChangeEventArgs : EventArgs
{
private View current;
/// <since_tizen> 3 </since_tizen>
public class FocusChangedEventArgs : EventArgs
{
+ private View currentView;
+ private View nextView;
+ private View previous;
private View current;
- private View next;
/// <summary>
/// The current focus view.
/// </summary>
/// <since_tizen> 3 </since_tizen>
+ [Obsolete("Please do not use! This will be deprecated! Please use Previous instead!")]
public View CurrentView
{
get
{
- return current;
+ return currentView;
}
set
{
- current = value;
+ currentView = value;
}
}
/// <summary>
/// The next focus view.
/// </summary>
/// <since_tizen> 3 </since_tizen>
+ [Obsolete("Please do not use! This will be deprecated! Please use Current instead!")]
public View NextView
{
get
{
- return next;
+ return nextView;
}
set
{
- next = value;
+ nextView = value;
+ }
+ }
+ /// <summary>
+ /// The previously focused view.
+ /// </summary>
+ /// <since_tizen> 10 </since_tizen>
+ public View Previous
+ {
+ get
+ {
+ return previous;
+ }
+ set
+ {
+ previous = value;
+ }
+ }
+ /// <summary>
+ /// The current focused view after focus changed.
+ /// </summary>
+ /// <since_tizen> 10 </since_tizen>
+ public View Current
+ {
+ get
+ {
+ return current;
+ }
+ set
+ {
+ current = value;
}
}
}
--- /dev/null
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using Tizen.NUI.Events;
+using System.Collections.Generic;
+
+namespace Tizen.NUI.Samples
+{
+ public class FocusManagerEventTest : IExample
+ {
+ private const int TestWidth = 100, TestHeight = 100;
+ private Window window;
+ private View rootView, left, center, right;
+ private View childUpper, childLower;
+ private Animation focusOut, focusIn;
+
+ public void Activate()
+ {
+ window = NUIApplication.GetDefaultWindow();
+
+ rootView = new View()
+ {
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = LayoutParamPolicies.MatchParent,
+
+ Layout = new LinearLayout()
+ {
+ LinearOrientation = LinearLayout.Orientation.Horizontal,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center,
+ CellPadding = new Size2D(20, 20),
+ },
+ Name = "rootView",
+ BackgroundColor = Color.Gray,
+ Focusable = true,
+ };
+ window.Add(rootView);
+
+ left = new View()
+ {
+ Name = "left",
+ WidthSpecification = TestWidth,
+ HeightSpecification = TestHeight,
+ BackgroundColor = Color.Red,
+ Focusable = true,
+ };
+ rootView.Add(left);
+
+ center = new View()
+ {
+ Name = "center",
+ WidthSpecification = TestWidth,
+ HeightSpecification = TestHeight,
+ BackgroundColor = Color.Blue,
+ Focusable = true,
+ };
+ rootView.Add(center);
+
+ right = new View()
+ {
+ Name = "right",
+ WidthSpecification = TestWidth * 2,
+ HeightSpecification = TestHeight * 3,
+ BackgroundColor = Color.Green,
+ Focusable = true,
+ Layout = new LinearLayout()
+ {
+ LinearOrientation = LinearLayout.Orientation.Vertical,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center,
+ CellPadding = new Size2D(10, 10),
+ },
+ };
+ rootView.Add(right);
+
+ childUpper = new View()
+ {
+ Name = "childUpper",
+ WidthSpecification = TestWidth,
+ HeightSpecification = TestHeight,
+ BackgroundColor = Color.Yellow,
+ Focusable = true,
+ };
+ right.Add(childUpper);
+
+ childLower = new View()
+ {
+ Name = "childLower",
+ WidthSpecification = TestWidth,
+ HeightSpecification = TestHeight,
+ BackgroundColor = Color.Pink,
+ Focusable = true,
+ };
+ right.Add(childLower);
+
+ FocusManager.Instance.FocusChanging += onFocusChanging;
+ FocusManager.Instance.FocusChanged += onFocusChanged;
+ FocusManager.Instance.SetCurrentFocusView(center);
+ }
+
+ public void Deactivate()
+ {
+ rootView.Unparent();
+ left.Unparent();
+ center.Unparent();
+ right.Unparent();
+ childUpper.Unparent();
+ childLower.Unparent();
+ rootView.Dispose();
+ left.Dispose();
+ center.Dispose();
+ right.Dispose();
+ childUpper.Dispose();
+ childLower.Dispose();
+ }
+
+ private void onFocusChanging(object sender, FocusChangingEventArgs e)
+ {
+ if (e.Current)
+ {
+ Tizen.Log.Debug("NUITEST", $"e.Current.Name={e.Current.Name}");
+ }
+
+ if (e.Proposed)
+ {
+ Tizen.Log.Debug("NUITEST", $"e.Proposed.Name={e.Proposed.Name}");
+ }
+
+ Tizen.Log.Debug("NUITEST", $"e.Direction.Name={e.Direction}");
+
+ if (e.Current == left)
+ {
+ if (e.Direction == View.FocusDirection.Right)
+ {
+ e.Proposed = center;
+ }
+ else
+ {
+ e.Proposed = rootView;
+ }
+ }
+ else if (e.Current == center)
+ {
+ if (e.Direction == View.FocusDirection.Right)
+ {
+ e.Proposed = right;
+ }
+ else if (e.Direction == View.FocusDirection.Left)
+ {
+ e.Proposed = left;
+ }
+ else
+ {
+ e.Proposed = rootView;
+ }
+ }
+ else if (e.Current == right)
+ {
+ if (e.Direction == View.FocusDirection.Left)
+ {
+ e.Proposed = center;
+ }
+ else if (e.Direction == View.FocusDirection.Forward || e.Direction == View.FocusDirection.Backward)
+ {
+ //for FocusGroup
+ e.Proposed = rootView;
+ }
+ else if (e.Direction == View.FocusDirection.Down)
+ {
+ e.Proposed = childUpper;
+ }
+ }
+ else if (e.Current == rootView)
+ {
+ if (e.Direction == View.FocusDirection.Down || e.Direction == View.FocusDirection.Right)
+ {
+ e.Proposed = left;
+ }
+ else if (e.Direction == View.FocusDirection.Forward || e.Direction == View.FocusDirection.Backward)
+ {
+ //for FocusGroup
+ e.Proposed = right;
+ }
+ }
+ else if (e.Current == childUpper)
+ {
+ if (e.Direction == View.FocusDirection.Down)
+ {
+ e.Proposed = childLower;
+ }
+ else if (e.Direction == View.FocusDirection.Up)
+ {
+ e.Proposed = right;
+ }
+ }
+ else if (e.Current == childLower)
+ {
+ if (e.Direction == View.FocusDirection.Down)
+ {
+ e.Proposed = right;
+ }
+ else if (e.Direction == View.FocusDirection.Up)
+ {
+ e.Proposed = childUpper;
+ }
+ }
+ else if (e.Current == null)
+ {
+ e.Proposed = center;
+ }
+ }
+
+ private void onFocusChanged(object sender, NUI.FocusManager.FocusChangedEventArgs e)
+ {
+ if (e.Previous)
+ {
+ Tizen.Log.Debug("NUITEST", $"e.Previous.Name={e.Previous.Name}");
+ if (e.Previous != rootView && e.Previous != right)
+ {
+ focusOut = new Animation(500);
+ focusOut.AnimateTo(e.Previous, "size", new Size(TestWidth * 0.7f, TestWidth * 0.7f, 0));
+ focusOut.Play();
+ }
+ }
+
+ if (e.Current)
+ {
+ Tizen.Log.Debug("NUITEST", $"e.Current.Name={e.Current.Name}");
+ if (e.Current != rootView && e.Current != right)
+ {
+ focusIn = new Animation(500);
+ focusIn.AnimateTo(e.Current, "size", new Size(TestWidth, TestWidth, 0));
+ focusIn.Play();
+ }
+ }
+ }
+
+ }
+}