Skip to content

Commit b97f909

Browse files
Avid29Arlodotexe
authored andcommitted
Improved keydown handling for Segmented control including RTL and vertical support
1 parent f9d2b77 commit b97f909

File tree

1 file changed

+31
-39
lines changed

1 file changed

+31
-39
lines changed

components/Segmented/src/Segmented/Segmented.cs

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -61,60 +61,52 @@ protected override void PrepareContainerForItemOverride(DependencyObject element
6161

6262
private void Segmented_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
6363
{
64-
switch (e.Key)
64+
var dir = e.Key switch
6565
{
66-
case VirtualKey.Left: e.Handled = MoveFocus(MoveDirection.Previous); break;
67-
case VirtualKey.Right: e.Handled = MoveFocus(MoveDirection.Next); break;
68-
}
69-
}
66+
#if !HAS_UNO
67+
// Invert left/right when the flow direction is right to left
68+
VirtualKey.Left when FlowDirection is FlowDirection.RightToLeft => 1,
69+
VirtualKey.Right when FlowDirection is FlowDirection.RightToLeft => -1,
70+
#endif
7071

71-
private enum MoveDirection
72-
{
73-
Next,
74-
Previous
72+
// Decrement if left/up or increment if right/up
73+
VirtualKey.Left or VirtualKey.Up => -1,
74+
VirtualKey.Right or VirtualKey.Down => 1,
75+
76+
// Otherwise don't adjust
77+
_ => 0,
78+
};
79+
80+
if (dir is not 0)
81+
{
82+
e.Handled = MoveFocus(dir);
83+
}
7584
}
7685

7786
/// <summary>
7887
/// Adjust the selected item and range based on keyboard input.
7988
/// This is used to override the ListView behaviors for up/down arrow manipulation vs left/right for a horizontal control
8089
/// </summary>
81-
/// <param name="direction">direction to move the selection</param>
90+
/// <param name="adjustment">The signed number of indicies to shift the focus.</param>
8291
/// <returns>True if the focus was moved, false otherwise</returns>
83-
private bool MoveFocus(MoveDirection direction)
92+
private bool MoveFocus(int adjustment)
8493
{
85-
bool retVal = false;
8694
var currentContainerItem = GetCurrentContainerItem();
95+
if (currentContainerItem is null)
96+
return false;
8797

88-
if (currentContainerItem != null)
89-
{
90-
var currentItem = ItemFromContainer(currentContainerItem);
91-
var previousIndex = Items.IndexOf(currentItem);
92-
var index = previousIndex;
98+
var currentItem = ItemFromContainer(currentContainerItem);
99+
var previousIndex = Items.IndexOf(currentItem);
93100

94-
if (direction == MoveDirection.Previous)
95-
{
96-
if (previousIndex > 0)
97-
{
98-
index -= 1;
99-
}
100-
}
101-
else if (direction == MoveDirection.Next)
102-
{
103-
if (previousIndex < Items.Count - 1)
104-
{
105-
index += 1;
106-
}
107-
}
101+
// Apply the adjustment, with a clamp
102+
var index = Math.Clamp(previousIndex + adjustment, 0, Items.Count);
108103

109-
// Only do stuff if the index is actually changing
110-
if (index != previousIndex && ContainerFromIndex(index) is SegmentedItem newItem)
111-
{
112-
newItem.Focus(FocusState.Keyboard);
113-
retVal = true;
114-
}
115-
}
104+
// Only do stuff if the index is actually changing
105+
if (index == previousIndex || ContainerFromIndex(index) is not SegmentedItem newItem)
106+
return false;
116107

117-
return retVal;
108+
newItem.Focus(FocusState.Keyboard);
109+
return true;
118110
}
119111

120112
private SegmentedItem? GetCurrentContainerItem()

0 commit comments

Comments
 (0)