internal static object?FindNextFocusWithSearchRootIgnoreEngagementWithHintRectImpl( FocusNavigationDirection focusNavigationDirection, object pSearchRoot, Rect focusHintRectangle, Rect focusExclusionRectangle) { object? spScope = pSearchRoot; DependencyObject?spScopeDO = spScope as DependencyObject; object?candidate = null; Rect hintRect = focusHintRectangle; Rect exRect = focusExclusionRectangle; var cDOSearchRoot = spScopeDO; if (cDOSearchRoot == null && InIslandsMode()) { // Return error if cDOSearchRoot is not valid in islands/ desktop mode throw new InvalidOperationException("Search root is invalid."); } XYFocusOptions xyFocusOptions = new XYFocusOptions(); xyFocusOptions.SearchRoot = cDOSearchRoot; xyFocusOptions.ConsiderEngagement = false; xyFocusOptions.FocusHintRectangle = hintRect; xyFocusOptions.ExclusionRect = exRect; candidate = FindNextFocus(focusNavigationDirection, xyFocusOptions); return(candidate); }
internal static object?FindNextFocusWithSearchRootIgnoreEngagementWithClipImpl( FocusNavigationDirection focusNavigationDirection, object pSearchRoot, bool ignoreClipping, bool ignoreCone) { object? spScope = pSearchRoot; DependencyObject?spScopeDO = spScope as DependencyObject; object?candidate = null; var cDOSearchRoot = spScopeDO as DependencyObject; if (cDOSearchRoot == null && InIslandsMode()) { // Return error if cDOSearchRoot is not valid in islands/ desktop mode throw new InvalidOperationException("Invalid search root"); } XYFocusOptions xyFocusOptions = new XYFocusOptions(); xyFocusOptions.SearchRoot = cDOSearchRoot; xyFocusOptions.ConsiderEngagement = false; xyFocusOptions.IgnoreClipping = ignoreClipping == true; xyFocusOptions.IgnoreCone = ignoreCone == true; candidate = FindNextFocus(focusNavigationDirection, xyFocusOptions); return(candidate); }
private static object?FindNextFocus( FocusNavigationDirection focusNavigationDirection, XYFocusOptions xyFocusOptions) { if (focusNavigationDirection == FocusNavigationDirection.None) { throw new ArgumentOutOfRangeException(nameof(focusNavigationDirection)); } var core = DXamlCore.Current; if (core == null) { throw new InvalidOperationException("XamlCore is not set."); } FocusManager?focusManager = null; if (xyFocusOptions.SearchRoot is DependencyObject searchRoot) { focusManager = VisualTree.GetFocusManagerForElement(searchRoot); } else if (core.GetHandle().InitializationType == InitializationType.IslandsOnly) { // Return error if searchRoot is not valid in islands/ desktop mode throw new ArgumentException("The search root must not be null."); } else { // For compat reasons, these FocusManager static APIs need to always use the CoreWindow as the // ContentRoot, so explicitly return the CoreWindow content root. var contentRootCoordinator = core.GetHandle().ContentRootCoordinator; var contentRoot = contentRootCoordinator?.CoreWindowContentRoot; if (contentRoot == null) { return(null); } focusManager = contentRoot.FocusManager; } if (focusManager == null) { return(null); } var root = focusManager.ContentRoot; var scale = RootScale.GetRasterizationScaleForContentRoot(root); ConvertOptionsRectsToPhysical(scale, xyFocusOptions); var candidate = focusManager.FindNextFocus( new FindFocusOptions(focusNavigationDirection), xyFocusOptions); return(candidate); }
private static UIElement?FindNextFocusableElementImpl(FocusNavigationDirection focusNavigationDirection) { if (InIslandsMode()) { // This api is not supported in islands/ desktop mode. throw new NotSupportedException("This API is not supported in desktop mode."); } XYFocusOptions xyFocusOptions = new XYFocusOptions(); xyFocusOptions.UpdateManifold = false; var candidate = FindNextFocus(focusNavigationDirection, xyFocusOptions); return(candidate as UIElement); }
private static void ConvertOptionsRectsToPhysical(float scale, XYFocusOptions xyFocusOptions) { if (xyFocusOptions.ExclusionRect != null) { Rect exclusionRect = xyFocusOptions.ExclusionRect.Value; exclusionRect = DXamlCore.Current.DipsToPhysicalPixels(scale, exclusionRect); xyFocusOptions.ExclusionRect = exclusionRect; } if (xyFocusOptions.FocusHintRectangle != null) { Rect hintRect = xyFocusOptions.FocusHintRectangle.Value; hintRect = DXamlCore.Current.DipsToPhysicalPixels(scale, hintRect); xyFocusOptions.FocusHintRectangle = hintRect; } }
private static DependencyObject?FindNextElementImpl(FocusNavigationDirection focusNavigationDirection) { if (InIslandsMode()) { // Return error if FindNextElement is called without focus navigation option in islands/desktop if (typeof(FocusManager).Log().IsEnabled(LogLevel.Error)) { typeof(FocusManager).Log().LogError("FindNextElement override with FindNextElementOptions must be used in WinUI Desktop apps."); } return(null); } var xyFocusOptions = new XYFocusOptions { UpdateManifold = false }; var candidate = FindNextFocus(focusNavigationDirection, xyFocusOptions); return(candidate as DependencyObject); }
private object?FindNextFocusWithSearchRootIgnoreEngagementImpl(FocusNavigationDirection focusNavigationDirection, object?pSearchRoot) { object? spScope = pSearchRoot; DependencyObject?spScopeDO = spScope as DependencyObject; object?candidate; var cDOSearchRoot = spScopeDO; if (cDOSearchRoot == null && InIslandsMode()) { // Return error if cDOSearchRoot is not valid in islands/ desktop mode throw new ArgumentException("Search root must not be null.", nameof(pSearchRoot)); } var xyFocusOptions = new XYFocusOptions(); xyFocusOptions.SearchRoot = cDOSearchRoot; xyFocusOptions.ConsiderEngagement = false; candidate = FindNextFocus(focusNavigationDirection, xyFocusOptions); return(candidate); }
public DependencyObject?FindNextFocus(FindFocusOptions findFocusOptions, XYFocusOptions xyFocusOptions, DependencyObject?component = null, bool updateManifolds = true) => FindNextFocusResult;
private static DependencyObject?FindNextElementWithOptionsImpl( FocusNavigationDirection focusNavigationDirection, FindNextElementOptions pFocusNavigationOverride) { var options = pFocusNavigationOverride; var xyFocusOptions = new XYFocusOptions { UpdateManifold = false }; var searchRoot = options.SearchRoot; var exclusionRect = options.ExclusionRect; var hintRect = options.HintRect; var navigationStrategyOverride = options.XYFocusNavigationStrategyOverride; var ignoreOcclusivity = options.IgnoreOcclusivity; ContentRoot?contentRoot = null; if (searchRoot != null) { contentRoot = VisualTree.GetContentRootForElement(searchRoot); } else if (InIslandsMode()) { // Return error if searchRootAsDO is not valid in islands/desktop mode throw new InvalidOperationException("Search root is not a dependency object."); } else { contentRoot = DXamlCore.Current.GetHandle().ContentRootCoordinator.CoreWindowContentRoot; } // If we are being passed in the public root visual of the XamlRoot as the SearchRoot, then override the SearchRoot to be the RootVisual. // This will enable searching through both the public root visual and the popup root. We will also allow Next/Prev. var shouldOverrideSearchRoot = contentRoot != null && GetAppVisibleXamlRootContent(contentRoot) == searchRoot; if (shouldOverrideSearchRoot) { searchRoot = contentRoot !.VisualTree.RootElement; } else { if (focusNavigationDirection != FocusNavigationDirection.Up && focusNavigationDirection != FocusNavigationDirection.Down && focusNavigationDirection != FocusNavigationDirection.Left && focusNavigationDirection != FocusNavigationDirection.Right) { throw new ArgumentOutOfRangeException( "Focus navigation directions Next, Previous, and None " + "are not supported when using FindNextElementOptions"); } } if (searchRoot != null) { xyFocusOptions.SearchRoot = searchRoot; } if (!exclusionRect.IsUniform) { xyFocusOptions.ExclusionRect = exclusionRect; } if (!hintRect.IsUniform) { xyFocusOptions.FocusHintRectangle = hintRect; } xyFocusOptions.NavigationStrategyOverride = navigationStrategyOverride; xyFocusOptions.IgnoreOcclusivity = ignoreOcclusivity; var candidate = FindNextFocus(focusNavigationDirection, xyFocusOptions); return(candidate as DependencyObject); }
private static bool TryMoveFocusStatic( FocusNavigationDirection focusNavigationDirection, FindNextElementOptions?pFocusNavigationOverride, ref IAsyncOperation <FocusMovementResult>?asyncOperation, bool useAsync) { DependencyObject?searchRootAsDO = null; Rect hintRect; Rect exclusionRect; XYFocusNavigationStrategyOverride navigationStrategyOverride; XYFocusOptions xyFocusOptions = new XYFocusOptions(); var pIsFocusMoved = false; FindNextElementOptions?options = pFocusNavigationOverride; bool ignoreOcclusivity; FocusAsyncOperation?spFocusAsyncOperation = null; DXamlCore pCore = DXamlCore.Current; if (pCore == null) { throw new InvalidOperationException("XamlCore is not set."); } FocusManager?focusManager = null; ContentRoot? contentRoot = null; var contentRootCoordinator = pCore.GetHandle().ContentRootCoordinator; if (options != null) { var searchRoot = options.SearchRoot; exclusionRect = options.ExclusionRect; hintRect = options.HintRect; navigationStrategyOverride = options.XYFocusNavigationStrategyOverride; ignoreOcclusivity = options.IgnoreOcclusivity; searchRootAsDO = searchRoot as DependencyObject; if (searchRootAsDO != null) { contentRoot = VisualTree.GetContentRootForElement(searchRootAsDO); focusManager = contentRoot?.FocusManager; if (focusManager == null) { throw new InvalidOperationException("Search root is not part of the visual tree."); } } else if (pCore.GetHandle().InitializationType == InitializationType.IslandsOnly) { // SearchRoot must exist for islands/ desktop throw new ArgumentException("The search root must not be null."); } else { contentRoot = contentRootCoordinator?.CoreWindowContentRoot; } // If we are being passed in the public root visual of a XamlRoot as the SearchRoot, then override the SearchRoot to be the RootVisual. // This will enable searching through both the public root visual and the popup root. We will also allow Next/Prev. bool shouldOverrideSearchRoot = contentRoot != null && GetAppVisibleXamlRootContent(contentRoot) == searchRootAsDO; if (shouldOverrideSearchRoot) { searchRootAsDO = contentRoot !.VisualTree.RootElement; } else { if (focusNavigationDirection != FocusNavigationDirection.Up && focusNavigationDirection != FocusNavigationDirection.Down && focusNavigationDirection != FocusNavigationDirection.Left && focusNavigationDirection != FocusNavigationDirection.Right) { throw new ArgumentOutOfRangeException( "Focus navigation directions Next, Previous, and None " + "are not supported when using FindNextElementOptions"); } } xyFocusOptions.NavigationStrategyOverride = navigationStrategyOverride; xyFocusOptions.IgnoreOcclusivity = ignoreOcclusivity; Rect exclusionRectNative = exclusionRect; Rect hintRectNative = hintRect; if (searchRootAsDO != null) { xyFocusOptions.SearchRoot = searchRootAsDO; } if (!exclusionRectNative.IsUniform) { xyFocusOptions.ExclusionRect = exclusionRectNative; } if (!hintRectNative.IsUniform) { xyFocusOptions.FocusHintRectangle = hintRectNative; } if (contentRoot != null) { var scale = RootScale.GetRasterizationScaleForContentRoot(contentRoot); ConvertOptionsRectsToPhysical(scale, xyFocusOptions); } } if (focusManager == null) { // Return error if call is without focus navigation option in islands/ desktop if (pCore.GetHandle().InitializationType == InitializationType.IslandsOnly) { throw new InvalidOperationException("Focus navigation options must be set for desktop apps."); } // For compat reasons, these FocusManager static APIs need to always use the CoreWindow as the // ContentRoot, so explicitly return the CoreWindow content root. if (contentRoot == null) { contentRoot = contentRootCoordinator?.CoreWindowContentRoot; } if (contentRoot == null) { return(pIsFocusMoved); } focusManager = contentRoot.FocusManager; } FocusMovement movement = new FocusMovement(xyFocusOptions, focusNavigationDirection, null); if (useAsync) { spFocusAsyncOperation = new FocusAsyncOperation(movement.CorrelationId); asyncOperation = spFocusAsyncOperation.CreateAsyncOperation(); // Async operation is not guaranteed to be released synchronously. // Therefore, we let UpdateFocus to handle the responsibility of releasing it. // TODO Uno specific: Do not use async operations, only simulated // movement.ShouldCompleteAsyncOperation = focusManager.TrySetAsyncOperation(spFocusAsyncOperation); if (movement.ShouldCompleteAsyncOperation) { //spFocusAsyncOperation.StartOperation(); } } FocusMovementResult result = focusManager.FindAndSetNextFocus(movement); // TODO Uno specific: Simulate async completion. spFocusAsyncOperation?.CoreSetResults(result); spFocusAsyncOperation?.CoreFireCompletion(); // We ignore result.GetHResult() here because this is a "Try" function pIsFocusMoved = result.WasMoved; // Async operation is not guaranteed to be released synchronously. // Therefore, we let UpdateFocus to handle the responsibility of releasing it. //spFocusAsyncOperation.Detach(); return(pIsFocusMoved); }