diff --git a/Photos/ViewModels/MainWindowViewModel.cs b/Photos/ViewModels/MainWindowViewModel.cs index f3f20ca..13c7d53 100644 --- a/Photos/ViewModels/MainWindowViewModel.cs +++ b/Photos/ViewModels/MainWindowViewModel.cs @@ -91,10 +91,29 @@ public partial class MainWindowViewModel : ViewModelBase await SelectedPhoto.LoadFullImage(); } - public void SelectedPhotoClicked() + public void ResetSelectedPhoto() { if (SelectedPhoto is null) return; SelectedPhoto.FullImage = null; SelectedPhoto = null; } + + public async Task TryFocusImage(int index) + { + if (index < 0 || index >= Photos.Count ) return; + // if(SelectedPhoto != null) ResetSelectedPhoto(); + SelectedPhoto = Photos[index]; + await SelectedPhoto.LoadFullImage(); + } + + public void UnfocusPhoto() => ResetSelectedPhoto(); + + public bool IsPhotoFocused() => SelectedPhoto != null; + + public int GetImageIndex(Image i) + { + var p = Photos.FirstOrDefault(x => x.PreviewImage == i.Source); + if (p is null) return -1; + return Photos.IndexOf(p); + } } \ No newline at end of file diff --git a/Photos/Views/MainWindow.axaml b/Photos/Views/MainWindow.axaml index 5a68770..d58a077 100644 --- a/Photos/Views/MainWindow.axaml +++ b/Photos/Views/MainWindow.axaml @@ -20,7 +20,9 @@ ExtendClientAreaChromeHints="NoChrome" TransparencyLevelHint="AcrylicBlur" Background="Transparent" - ExtendClientAreaToDecorationsHint="True"> + ExtendClientAreaToDecorationsHint="True" + Focusable="True" + KeyDown="OnKeyDownHandler"> @@ -115,7 +117,8 @@ + ClipToBounds="False" + IsTabStop="True"> + Stretch="UniformToFill" + PointerEntered="PointerEnteredPhotoHandler" + /> + ZIndex="50" + > - + @@ -211,7 +217,7 @@ Stretch="Uniform"> - + diff --git a/Photos/Views/MainWindow.axaml.cs b/Photos/Views/MainWindow.axaml.cs index c2e68ff..e76f1a5 100644 --- a/Photos/Views/MainWindow.axaml.cs +++ b/Photos/Views/MainWindow.axaml.cs @@ -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; + } } \ No newline at end of file