Skip to content

Commit

Permalink
Merge branch 'fluentribbon:develop' into focusvisual
Browse files Browse the repository at this point in the history
  • Loading branch information
cbra-caa authored Mar 10, 2023
2 parents 0434351 + 9a66e30 commit 0173116
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 111 deletions.
46 changes: 5 additions & 41 deletions Fluent.Ribbon/Controls/ComboBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -770,60 +770,25 @@ protected override void OnKeyDown(KeyEventArgs e)
}
}

if (this.Menu is not null
if (this.IsDropDownOpen
&& this.scrollViewer is not null
&& this.Menu is not null
&& this.Menu.Items.IsEmpty == false)
{
if (e.Key == Key.Tab)
{
if (this.Menu.IsKeyboardFocusWithin)
{
Keyboard.Focus(this.ItemContainerGenerator.ContainerOrContainerContentFromIndex<IInputElement>(0));
this.scrollViewer.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
else
{
Keyboard.Focus(this.Menu.ItemContainerGenerator.ContainerOrContainerContentFromIndex<IInputElement>(0));
this.Menu.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}

e.Handled = true;
return;
}

if (this.Menu.Items.Contains(this.Menu.ItemContainerGenerator.ItemFromContainerOrContainerContent((DependencyObject)Keyboard.FocusedElement)))
{
if (e.Key == Key.Down)
{
var indexOfMenuSelectedItem = this.Menu.ItemContainerGenerator.IndexFromContainer((DependencyObject)Keyboard.FocusedElement);

if (indexOfMenuSelectedItem != this.Menu.Items.Count - 1)
{
Keyboard.Focus(this.Menu.ItemContainerGenerator.ContainerOrContainerContentFromIndex<IInputElement>(indexOfMenuSelectedItem + 1));
}
else
{
Keyboard.Focus(this.Menu.ItemContainerGenerator.ContainerOrContainerContentFromIndex<IInputElement>(0));
}

e.Handled = true;
return;
}

if (e.Key == Key.Up)
{
var indexOfMenuSelectedItem = this.Menu.ItemContainerGenerator.IndexFromContainer((DependencyObject)Keyboard.FocusedElement);

if (indexOfMenuSelectedItem != 0)
{
Keyboard.Focus(this.Menu.ItemContainerGenerator.ContainerOrContainerContentFromIndex<IInputElement>(indexOfMenuSelectedItem - 1));
}
else
{
Keyboard.Focus(this.Menu.ItemContainerGenerator.ContainerOrContainerContentFromIndex<IInputElement>(this.Menu.Items.Count - 1));
}

e.Handled = true;
return;
}
}
}

if (baseKeyDownCalled == false
Expand All @@ -840,7 +805,6 @@ protected override void OnKeyDown(KeyEventArgs e)
/// <inheritdoc />
public virtual KeyTipPressedResult OnKeyTipPressed()
{
// Edge case: Whole dropdown content is disabled
if (this.IsKeyboardFocusWithin == false)
{
Keyboard.Focus(this);
Expand Down
27 changes: 14 additions & 13 deletions Fluent.Ribbon/Controls/DropDownButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -679,21 +679,22 @@ private void OnIsDropDownOpenChanged(bool newValue)
{
Mouse.Capture(this, CaptureMode.SubTree);

Keyboard.Focus(this.DropDownPopup);

this.RunInDispatcherAsync(
() =>
{
var container = this.ItemContainerGenerator.ContainerFromIndex(0);
if (this.DropDownPopup is not null)
{
this.RunInDispatcherAsync(
() =>
{
var container = this.ItemContainerGenerator.ContainerFromIndex(0);

NavigateToContainer(container);
NavigateToContainer(container);

// Edge case: Whole dropdown content is disabled
if (this.IsKeyboardFocusWithin == false)
{
Keyboard.Focus(this.DropDownPopup);
}
});
// Edge case: Whole dropdown content is disabled
if (this.IsKeyboardFocusWithin == false)
{
Keyboard.Focus(this.DropDownPopup.Child);
}
});
}

this.OnDropDownOpened();
}
Expand Down
19 changes: 4 additions & 15 deletions Fluent.Ribbon/Controls/RibbonGroupBox.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ReSharper disable once CheckNamespace
// ReSharper disable once CheckNamespace
namespace Fluent;

using System;
Expand Down Expand Up @@ -1273,8 +1273,6 @@ private static void OnIsDropDownOpenChanged(DependencyObject d, DependencyProper
{
if (groupBox.DropDownPopup is not null)
{
Keyboard.Focus(groupBox.DropDownPopup);

groupBox.RunInDispatcherAsync(
() =>
{
Expand All @@ -1284,7 +1282,7 @@ private static void OnIsDropDownOpenChanged(DependencyObject d, DependencyProper
// Edge case: Whole dropdown content is disabled
if (groupBox.IsKeyboardFocusWithin == false)
{
Keyboard.Focus(groupBox.DropDownPopup);
Keyboard.Focus(groupBox.DropDownPopup.Child);
}
});
}
Expand Down Expand Up @@ -1434,20 +1432,11 @@ public bool CanAddToQuickAccessToolBar
/// <inheritdoc />
public KeyTipPressedResult OnKeyTipPressed()
{
if (this.State == RibbonGroupBoxState.Collapsed
|| this.State == RibbonGroupBoxState.QuickAccess)
if (this.State is RibbonGroupBoxState.Collapsed or RibbonGroupBoxState.QuickAccess)
{
this.IsDropDownOpen = true;

if (this.DropDownPopup?.Child is not null)
{
Keyboard.Focus(this.DropDownPopup.Child);
this.DropDownPopup.Child.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));

return new KeyTipPressedResult(true, true);
}

return new KeyTipPressedResult(false, true);
return new KeyTipPressedResult(true, true);
}

return KeyTipPressedResult.Empty;
Expand Down
50 changes: 23 additions & 27 deletions Fluent.Ribbon/Controls/RibbonTabControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Fluent;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Fluent.Automation.Peers;
using Fluent.Extensions;
using Fluent.Helpers;
Expand Down Expand Up @@ -546,48 +547,33 @@ protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
/// <inheritdoc />
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
var newSelectedItem = e.AddedItems.Count > 0
? (RibbonTabItem?)e.AddedItems[0]
: null;

if (this.SelectedTabItem is not null
&& ReferenceEquals(this.SelectedTabItem, newSelectedItem) == false)
{
this.SelectedTabItem.IsSelected = false;
}

this.UpdateSelectedContent();

if (this.IsKeyboardFocusWithin
&& this.IsMinimized == false)
{
// If keyboard focus is within the control, make sure it is going to the correct place
var item = this.GetSelectedTabItem();
item?.Focus();
newSelectedItem?.Focus();
}

if (e.AddedItems.Count > 0)
{
if (this.IsMinimized)
{
this.IsDropDownOpen = true;

var ribbonTabItem = (RibbonTabItem?)e.AddedItems[0];

if (ribbonTabItem is not null)
{
ribbonTabItem.IsHitTestVisible = false;
}
}
}
else
if (e.AddedItems.Count == 0)
{
if (this.IsDropDownOpen)
{
this.IsDropDownOpen = false;
}
}

if (e.RemovedItems.Count > 0)
{
var ribbonTabItem = (RibbonTabItem?)e.RemovedItems[0];

if (ribbonTabItem is not null)
{
ribbonTabItem.IsHitTestVisible = true;
}
}

base.OnSelectionChanged(e);
}

Expand Down Expand Up @@ -649,6 +635,11 @@ protected override void OnKeyDown(KeyEventArgs e)
if (this.IsDropDownOpen)
{
this.IsDropDownOpen = false;

if (this.IsKeyboardFocusWithin)
{
this.GetSelectedTabItem()?.Focus();
}
}

break;
Expand Down Expand Up @@ -927,6 +918,11 @@ private void OnRibbonTabPopupOpening()

Mouse.Capture(this, CaptureMode.SubTree);

if (this.DropDownPopup is not null)
{
this.RunInDispatcherAsync(() => this.DropDownPopup.Child.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)), DispatcherPriority.Background);
}

this.DropDownOpened?.Invoke(this, EventArgs.Empty);
}

Expand Down
54 changes: 46 additions & 8 deletions Fluent.Ribbon/Controls/RibbonTabItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@ protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
else
{
this.TabControlParent.SelectedItem = newItem;
this.TabControlParent.IsDropDownOpen = true;
}

this.TabControlParent.RaiseRequestBackstageClose();
Expand All @@ -656,6 +657,35 @@ protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
}
}

/// <inheritdoc />
protected override void OnKeyDown(KeyEventArgs e)
{
switch (e.Key)
{
case Key.Enter:
case Key.Space:
if (this.TabControlParent is not null
&& this.TabControlParent.IsMinimized)
{
this.TabControlParent.IsDropDownOpen = true;

e.Handled = true;
}

break;
}

base.OnKeyDown(e);
}

/// <inheritdoc />
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);

this.SetCurrentValue(IsSelectedProperty, BooleanBoxes.TrueBox);
}

/// <inheritdoc />
protected override AutomationPeer OnCreateAutomationPeer() => new Fluent.Automation.Peers.RibbonTabItemAutomationPeer(this);

Expand All @@ -671,17 +701,15 @@ private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyCh

if (newValue)
{
if (container.TabControlParent?.SelectedTabItem is not null
&& ReferenceEquals(container.TabControlParent.SelectedTabItem, container) == false)
{
container.TabControlParent.SelectedTabItem.IsSelected = false;
}

container.OnSelected(new RoutedEventArgs(Selector.SelectedEvent, container));

container.IsHitTestVisible = false;
}
else
{
container.OnUnselected(new RoutedEventArgs(Selector.UnselectedEvent, container));

container.IsHitTestVisible = true;
}

// Raise UI automation events on this RibbonTabItem
Expand Down Expand Up @@ -761,12 +789,22 @@ public KeyTipPressedResult OnKeyTipPressed()
currentSelectedItem.IsSelected = false;
}

this.IsSelected = true;
this.SetCurrentValue(IsSelectedProperty, BooleanBoxes.TrueBox);

var result = KeyTipPressedResult.Empty;

if (this.TabControlParent is not null
&& this.TabControlParent.IsMinimized)
{
this.TabControlParent.IsDropDownOpen = true;

result = new KeyTipPressedResult(true, true);
}

// This way keytips for delay loaded elements work correctly. Partially fixes #244.
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new Action(() => { }));

return KeyTipPressedResult.Empty;
return result;
}

/// <inheritdoc />
Expand Down
10 changes: 3 additions & 7 deletions Fluent.Ribbon/Services/KeyTipService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -490,15 +490,11 @@ private void Show()
this.backUpFocusedControl = FocusWrapper.GetWrapperForCurrentFocus();
}

if (keyTipsTarget is Ribbon
{
IsMinimized: false,
SelectedTabIndex: >= 0,
TabControl: { }
})
if (keyTipsTarget is Ribbon && this.ribbon.TabControl != null)
{
// Focus ribbon
(this.ribbon.TabControl?.ItemContainerGenerator.ContainerFromIndex(this.ribbon.TabControl.SelectedIndex) as UIElement)?.Focus();
int selectedIndex = Math.Max(this.ribbon.TabControl.SelectedIndex, 0);
(this.ribbon.TabControl.ItemContainerGenerator.ContainerFromIndex(selectedIndex) as UIElement)?.Focus();
}

this.ClearUserInput();
Expand Down

0 comments on commit 0173116

Please sign in to comment.