added keyboard navigation for selected images -> TOOD: allow visual keyboardnavigation when photo is not maximized

This commit is contained in:
Ano-sys
2026-04-03 01:26:51 +02:00
parent 70f22af18c
commit 162df64596
3 changed files with 90 additions and 7 deletions
+12 -6
View File
@@ -20,7 +20,9 @@
ExtendClientAreaChromeHints="NoChrome"
TransparencyLevelHint="AcrylicBlur"
Background="Transparent"
ExtendClientAreaToDecorationsHint="True">
ExtendClientAreaToDecorationsHint="True"
Focusable="True"
KeyDown="OnKeyDownHandler">
<Design.DataContext>
<vm:MainWindowViewModel/>
@@ -115,7 +117,8 @@
<ItemsRepeater ItemsSource="{Binding Photos}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ClipToBounds="False">
ClipToBounds="False"
IsTabStop="True">
<ItemsRepeater.Layout>
<UniformGridLayout MinItemWidth="220"
MinItemHeight="290"
@@ -150,7 +153,9 @@
ClipToBounds="True"
Background="#14000000">
<Image Source="{Binding PreviewImage}"
Stretch="UniformToFill"/>
Stretch="UniformToFill"
PointerEntered="PointerEnteredPhotoHandler"
/>
</Border>
<TextBlock Text="{Binding DisplayName}"
@@ -184,14 +189,15 @@
<TransitioningContentControl Grid.Row="0"
Grid.RowSpan="2"
Content="{Binding SelectedPhoto}"
ZIndex="50">
ZIndex="50"
>
<TransitioningContentControl.PageTransition>
<CrossFade Duration="0:0:0.18"/>
</TransitioningContentControl.PageTransition>
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="PointerReleased">
<ic:InvokeCommandAction Command="{Binding Path=DataContext.SelectedPhotoClicked, ElementName=Root}"/>
<ic:InvokeCommandAction Command="{Binding Path=DataContext.ResetSelectedPhoto, ElementName=Root}"/>
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
@@ -211,7 +217,7 @@
Stretch="Uniform">
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="PointerReleased">
<ic:InvokeCommandAction Command="{Binding Path=DataContext.SelectedPhotoClicked, ElementName=Root}"/>
<ic:InvokeCommandAction Command="{Binding Path=DataContext.ResetSelectedPhoto, ElementName=Root}"/>
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
</Image>
+58
View File
@@ -1,3 +1,4 @@
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Xaml.Interactions.DragAndDrop;
@@ -9,6 +10,7 @@ namespace Photos.Views;
public partial class MainWindow : Window
{
private IFolderPickerService _folderPickerService;
private int _currentImageIndex = 0;
public MainWindow()
{
@@ -21,4 +23,60 @@ public partial class MainWindow : Window
{
(DataContext as MainWindowViewModel)?.WindowDropHandler(e);
}
private void OnKeyDownHandler(object sender, KeyEventArgs e)
{
if (DataContext is not MainWindowViewModel vm) return;
async Task HandleEnter()
{
if (vm.IsPhotoFocused()) vm.UnfocusPhoto();
else await vm.TryFocusImage(_currentImageIndex);
}
void HandleEscape()
{
vm.UnfocusPhoto();
}
async Task HandleArrowKey()
{
if(vm.IsPhotoFocused()) await vm.TryFocusImage(_currentImageIndex);
// TODO: move basic selection
}
switch (e.Key)
{
case Key.Enter:
HandleEnter().GetAwaiter();
break;
case Key.Escape:
HandleEscape();
break;
case Key.Down:
break;
case Key.Left:
if (_currentImageIndex > 0)
{
_currentImageIndex--;
HandleArrowKey().GetAwaiter();
}
break;
case Key.Right:
if (_currentImageIndex < vm.Photos.Count - 1)
{
_currentImageIndex++;
HandleArrowKey().GetAwaiter();
}
break;
}
}
private void PointerEnteredPhotoHandler(object sender, PointerEventArgs e)
{
if (sender is not Image i || DataContext is not MainWindowViewModel vm) return;
var idx = vm.GetImageIndex(i);
if (idx == -1) return;
_currentImageIndex = idx;
}
}