Skip to content

Commit

Permalink
feat(focus): Add support for FindFirstFocusableElement
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed May 2, 2020
1 parent 8891ee4 commit 66c514b
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public static bool TryMoveFocus( global::Windows.UI.Xaml.Input.FocusNavigationDi
throw new global::System.NotImplementedException("The member DependencyObject FocusManager.FindNextElement(FocusNavigationDirection focusNavigationDirection) is not implemented in Uno.");
}
#endif
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __MACOS__
#if false || false || false || false || false
[global::Uno.NotImplemented]
public static global::Windows.UI.Xaml.DependencyObject FindFirstFocusableElement( global::Windows.UI.Xaml.DependencyObject searchScope)
{
Expand Down
20 changes: 20 additions & 0 deletions src/Uno.UI/UI/Xaml/Input/FocusManager.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,26 @@ public static View InnerFindNextFocusableElement(FocusNavigationDirection focusN
}
}

public static DependencyObject InnerFindFirstFocusableElement(DependencyObject searchScope)
{
if (searchScope == null)
{
searchScope = Window.Current.Content;
}

if (IsFocusableView(searchScope as View))
{
return searchScope;
}

if (!(searchScope is ViewGroup searchViewGroup))
{
return null;
}

return searchViewGroup.EnumerateAllChildren(IsFocusableView, maxDepth: 300).FirstOrDefault() as DependencyObject;
}

private static void FocusNative(Control control)
{
control.RequestFocus();
Expand Down
10 changes: 10 additions & 0 deletions src/Uno.UI/UI/Xaml/Input/FocusManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ public static UIElement FindNextFocusableElement(FocusNavigationDirection focusN
return InnerFindNextFocusableElement(focusNavigationDirection) as UIElement;
}

/// <summary>
/// Retrieves the first element that can receive focus based on the specified scope.
/// </summary>
/// <param name="searchScope">The root object from which to search. If null, the search scope is the current window.</param>
/// <returns>The first focusable object.</returns>
public static DependencyObject FindFirstFocusableElement(DependencyObject searchScope)
{
return InnerFindFirstFocusableElement(searchScope);
}

internal static bool SetFocusedElement(DependencyObject newFocus, FocusNavigationDirection focusNavigationDirection, FocusState focusState)
{
var control = newFocus as Control; // For now only called for Control
Expand Down
22 changes: 21 additions & 1 deletion src/Uno.UI/UI/Xaml/Input/FocusManager.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static UIView InnerFindNextFocusableElement(FocusNavigationDirection focu
{
var focusedView = GetFocusedElement() as UIView;
var absoluteFocusedFrame = focusedView.ConvertRectToView(focusedView.Bounds, UIApplication.SharedApplication.KeyWindow);

var focusableViews = SearchOtherFocusableViews(focusedView);

switch (focusNavigationDirection)
Expand Down Expand Up @@ -208,6 +208,26 @@ public static UIView InnerFindNextFocusableElement(FocusNavigationDirection focu
}
}

public static DependencyObject InnerFindFirstFocusableElement(DependencyObject searchScope)
{
if (searchScope == null)
{
searchScope = Window.Current.Content;
}

if (!(searchScope is UIView searchView))
{
return null;
}

if (IsFocusableView(searchView))
{
return searchScope;
}

return searchView.FindSubviews(selector: IsFocusableView, maxDepth: 100).FirstOrDefault() as DependencyObject;
}

private static void FocusNative(Control control) => control.BecomeFirstResponder();

//We need to validate this difference because focused elements don't have the same absolute position once focused
Expand Down
20 changes: 20 additions & 0 deletions src/Uno.UI/UI/Xaml/Input/FocusManager.macOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,26 @@ public static NSView InnerFindNextFocusableElement(FocusNavigationDirection focu
}
}

public static DependencyObject InnerFindFirstFocusableElement(DependencyObject searchScope)
{
if (searchScope == null)
{
searchScope = Window.Current.Content;
}

if (!(searchScope is NSView searchView))
{
return null;
}

if (IsFocusableView(searchView))
{
return searchScope;
}

return searchView.FindSubviews(selector: IsFocusableView, maxDepth: 100).FirstOrDefault() as DependencyObject;
}

private static void FocusNative(Control control) => control.BecomeFirstResponder();

//We need to validate this difference because focused elements don't have the same absolute position once focused
Expand Down
5 changes: 5 additions & 0 deletions src/Uno.UI/UI/Xaml/Input/FocusManager.net.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public static View InnerFindNextFocusableElement(FocusNavigationDirection focusN
throw new NotImplementedException();
}

public static DependencyObject InnerFindFirstFocusableElement(DependencyObject searchScope)
{
throw new NotImplementedException();
}

public static void OnFocusChanged(View control, FocusState state)
{
throw new NotImplementedException();
Expand Down
5 changes: 5 additions & 0 deletions src/Uno.UI/UI/Xaml/Input/FocusManager.wasm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,10 @@ private static UIElement InnerFindNextFocusableElement(FocusNavigationDirection
{
return null;
}

public static DependencyObject InnerFindFirstFocusableElement(DependencyObject searchScope)
{
return null;
}
}
}

0 comments on commit 66c514b

Please sign in to comment.