[TUI] Add GoTo Sector dialog for improved sector navigation

This commit is contained in:
2025-10-16 16:36:53 +01:00
parent db0de68cb3
commit 6cf92f6ef2
5 changed files with 142 additions and 0 deletions

View File

@@ -19,6 +19,9 @@
<Compile Update="Views\Windows\HexViewWindow.axaml.cs"> <Compile Update="Views\Windows\HexViewWindow.axaml.cs">
<DependentUpon>HexViewWindow.axaml</DependentUpon> <DependentUpon>HexViewWindow.axaml</DependentUpon>
</Compile> </Compile>
<Compile Update="Views\Dialogs\GoToSectorDialog.axaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -0,0 +1,62 @@
using System.Windows.Input;
using Avalonia.Controls;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace Aaru.Tui.ViewModels.Dialogs;
public sealed partial class GoToSectorDialogViewModel : ViewModelBase
{
readonly ulong _maxSector;
internal Window _dialog = null!;
[ObservableProperty]
string _errorMessage = string.Empty;
[ObservableProperty]
bool _hasError;
[ObservableProperty]
string _sectorNumber = string.Empty;
public GoToSectorDialogViewModel(Window dialog, ulong maxSector)
{
_dialog = dialog;
_maxSector = maxSector;
OkCommand = new RelayCommand(Ok);
CancelCommand = new RelayCommand(Cancel);
}
public ulong? Result { get; private set; }
public ICommand OkCommand { get; }
public ICommand CancelCommand { get; }
void Ok()
{
if(!ulong.TryParse((string?)SectorNumber, out ulong sector))
{
ErrorMessage = "Please enter a valid number.";
HasError = true;
return;
}
if(sector > _maxSector)
{
ErrorMessage = $"Sector number must be less than or equal to {_maxSector}.";
HasError = true;
return;
}
Result = sector;
_dialog.Close(true);
}
void Cancel()
{
Result = null;
_dialog.Close(false);
}
}

View File

@@ -1,11 +1,13 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Windows.Input; using System.Windows.Input;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.Tui.ViewModels.Dialogs;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using GoToSectorDialog = Aaru.Tui.Views.Dialogs.GoToSectorDialog;
namespace Aaru.Tui.ViewModels.Windows; namespace Aaru.Tui.ViewModels.Windows;
@@ -31,6 +33,7 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase
BackCommand = new RelayCommand(Back); BackCommand = new RelayCommand(Back);
NextSectorCommand = new RelayCommand(NextSector); NextSectorCommand = new RelayCommand(NextSector);
PreviousSectorCommand = new RelayCommand(PreviousSector); PreviousSectorCommand = new RelayCommand(PreviousSector);
GoToCommand = new AsyncRelayCommand(GoToAsync);
_parent = parent; _parent = parent;
_view = view; _view = view;
@@ -44,6 +47,31 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase
public ICommand ExitCommand { get; } public ICommand ExitCommand { get; }
public ICommand NextSectorCommand { get; } public ICommand NextSectorCommand { get; }
public ICommand PreviousSectorCommand { get; } public ICommand PreviousSectorCommand { get; }
public ICommand GoToCommand { get; }
async Task GoToAsync()
{
var dialog = new GoToSectorDialog
{
DataContext = new GoToSectorDialogViewModel(null!, _imageFormat.Info.Sectors - 1)
};
// Set the dialog reference after creation
((GoToSectorDialogViewModel)dialog.DataContext!)._dialog = dialog;
bool? result = await dialog.ShowDialog<bool?>(_view);
if(result == true)
{
var viewModel = (GoToSectorDialogViewModel)dialog.DataContext;
if(viewModel.Result.HasValue)
{
CurrentSector = viewModel.Result.Value;
LoadSector();
}
}
}
void PreviousSector() void PreviousSector()
{ {

View File

@@ -0,0 +1,38 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Aaru.Tui.ViewModels.Dialogs"
xmlns:brushes="https://github.com/jinek/consolonia"
Width="40"
Height="8"
x:Class="Aaru.Tui.Views.Dialogs.GoToSectorDialog"
x:DataType="vm:GoToSectorDialogViewModel"
Title="Go to Sector"
WindowStartupLocation="CenterScreen"
RequestedThemeVariant="Dark"
CanResize="False">
<Design.DataContext>
<vm:GoToSectorDialogViewModel />
</Design.DataContext>
<Border BorderThickness="1">
<Border.BorderBrush>
<brushes:LineBrush LineStyle="DoubleLine"
Brush="Blue" />
</Border.BorderBrush>
<StackPanel>
<TextBlock Text="Enter sector number:" />
<TextBox Text="{Binding SectorNumber, Mode=OneWay}"
Watermark="Sector number" />
<TextBlock Text="{Binding ErrorMessage, Mode=OneWay}"
Foreground="Red"
IsVisible="{Binding HasError, Mode=OneWay}" />
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Spacing="1">
<Button Content="OK"
Command="{Binding OkCommand, Mode=OneWay}" />
<Button Content="Cancel"
Command="{Binding CancelCommand, Mode=OneWay}" />
</StackPanel>
</StackPanel>
</Border>
</Window>

View File

@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace Aaru.Tui.Views.Dialogs;
public partial class GoToSectorDialog : Window
{
public GoToSectorDialog()
{
InitializeComponent();
}
}