diff --git a/Aaru.Tui/Aaru.Tui.csproj b/Aaru.Tui/Aaru.Tui.csproj index f0b98a888..4db8eebc7 100644 --- a/Aaru.Tui/Aaru.Tui.csproj +++ b/Aaru.Tui/Aaru.Tui.csproj @@ -13,6 +13,8 @@ + + diff --git a/Aaru.Tui/App.axaml b/Aaru.Tui/App.axaml index 5e0c9a5d5..ae591df8d 100644 --- a/Aaru.Tui/App.axaml +++ b/Aaru.Tui/App.axaml @@ -2,8 +2,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:console="https://github.com/jinek/consolonia" x:Class="Aaru.Tui.App" - RequestedThemeVariant="Dark"> + RequestedThemeVariant="Light"> - + \ No newline at end of file diff --git a/Aaru.Tui/App.axaml.cs b/Aaru.Tui/App.axaml.cs index 766e539b7..ade758311 100644 --- a/Aaru.Tui/App.axaml.cs +++ b/Aaru.Tui/App.axaml.cs @@ -28,12 +28,50 @@ using Aaru.Tui.ViewModels.Windows; using Aaru.Tui.Views.Windows; using Avalonia; -using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; +using Prism.DryIoc; namespace Aaru.Tui; -public class App : Application +public class App : PrismApplication +{ + /// + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + + base.Initialize(); + } + + /// + protected override void RegisterTypes(IContainerRegistry containerRegistry) + { + // Register your Services, Views, Dialogs, etc. here + + // Views - Region Navigation + containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterForNavigation(); + } + + /// + protected override AvaloniaObject CreateShell() => Container.Resolve(); + + + /// Called after Initialize. + protected override void OnInitialized() + { + // Register Views to the Region it will appear in. Don't register them in the ViewModel. + IRegionManager regionManager = Container.Resolve(); + + // WARNING: Prism v11.0.0 + // - DataTemplates MUST define a DataType or else an XAML error will be thrown + // - Error: DataTemplate inside of DataTemplates must have a DataType set + regionManager.RegisterViewWithRegion("ContentRegion", typeof(FileView)); + } +} + +/*public class App : Application { public override void Initialize() { @@ -52,4 +90,4 @@ public class App : Application base.OnFrameworkInitializationCompleted(); } -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/Aaru.Tui/ViewModels/ViewModelBase.cs b/Aaru.Tui/ViewModels/ViewModelBase.cs index 51804c672..72bdbe706 100644 --- a/Aaru.Tui/ViewModels/ViewModelBase.cs +++ b/Aaru.Tui/ViewModels/ViewModelBase.cs @@ -29,4 +29,30 @@ using CommunityToolkit.Mvvm.ComponentModel; namespace Aaru.Tui.ViewModels; -public class ViewModelBase : ObservableObject; \ No newline at end of file +public class ViewModelBase : ObservableObject, IRegionAware +{ + /// + /// Called to determine if this instance can handle the navigation request. + /// Don't call this directly, use . + /// + /// The navigation context. + /// if this instance accepts the navigation request; otherwise, . + public virtual bool IsNavigationTarget(NavigationContext navigationContext) => + + // Auto-allow navigation + OnNavigatingTo(navigationContext); + + /// Called when the implementer is being navigated away from. + /// The navigation context. + public virtual void OnNavigatedFrom(NavigationContext navigationContext) {} + + /// Called when the implementer has been navigated to. + /// The navigation context. + public virtual void OnNavigatedTo(NavigationContext navigationContext) {} + + /// Navigation validation checker. + /// Override for Prism 7.2's IsNavigationTarget. + /// The navigation context. + /// if this instance accepts the navigation request; otherwise, . + public virtual bool OnNavigatingTo(NavigationContext navigationContext) => true; +} \ No newline at end of file diff --git a/Aaru.Tui/ViewModels/Windows/FileViewViewModel.cs b/Aaru.Tui/ViewModels/Windows/FileViewViewModel.cs new file mode 100644 index 000000000..ee0055155 --- /dev/null +++ b/Aaru.Tui/ViewModels/Windows/FileViewViewModel.cs @@ -0,0 +1,479 @@ +using System.Collections.ObjectModel; +using System.Reflection; +using System.Text; +using System.Windows.Input; +using Aaru.CommonTypes; +using Aaru.CommonTypes.Enums; +using Aaru.CommonTypes.Interfaces; +using Aaru.Core; +using Aaru.Helpers; +using Aaru.Tui.Models; +using Aaru.Tui.Views.Windows; +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Humanizer; +using Humanizer.Bytes; +using Spectre.Console; +using Color = Avalonia.Media.Color; + +namespace Aaru.Tui.ViewModels.Windows; + +public sealed partial class FileViewViewModel : ViewModelBase +{ + readonly IRegionManager _regionManager; + [ObservableProperty] + string _copyright; + [ObservableProperty] + string _currentPath; + [ObservableProperty] + ObservableCollection _files = []; + [ObservableProperty] + string _informationalVersion; + [ObservableProperty] + bool _isStatusVisible; + FileModel? _selectedFile; + [ObservableProperty] + string _status; + + public FileViewViewModel(IRegionManager regionManager) + { + ExitCommand = new RelayCommand(Exit); + SectorViewCommand = new RelayCommand(SectorView); + GoToPathCommand = new AsyncRelayCommand(GoToPathAsync); + HelpCommand = new AsyncRelayCommand(HelpAsync); + OpenSelectedFileCommand = new RelayCommand(OpenSelectedFile, CanOpenSelectedFile); + _regionManager = regionManager; + + InformationalVersion = + Assembly.GetExecutingAssembly() + .GetCustomAttribute() + ?.InformationalVersion ?? + "?.?.?"; + + Copyright = Assembly.GetExecutingAssembly().GetCustomAttribute()?.Copyright ?? ""; + Status = Localization.Resources.Loading; + } + + public FileModel? SelectedFile + { + get => _selectedFile; + set + { + SetProperty(ref _selectedFile, value); + OnPropertyChanged(nameof(IsFileInfoAvailable)); + OnPropertyChanged(nameof(SelectedFileIsNotDirectory)); + OnPropertyChanged(nameof(SelectedFileLength)); + OnPropertyChanged(nameof(SelectedFileCreationTime)); + OnPropertyChanged(nameof(SelectedFileLastWriteTime)); + OnPropertyChanged(nameof(SelectedFileAttributes)); + OnPropertyChanged(nameof(SelectedFileUnixMode)); + OnPropertyChanged(nameof(SelectedFileHasInformation)); + OnPropertyChanged(nameof(SelectedFileInformation)); + } + } + + public ICommand OpenSelectedFileCommand { get; } + public ICommand ExitCommand { get; } + public ICommand SectorViewCommand { get; } + public ICommand GoToPathCommand { get; } + public ICommand HelpCommand { get; } + public bool IsFileInfoAvailable => SelectedFile?.FileInfo != null; + public bool SelectedFileIsNotDirectory => SelectedFile?.IsDirectory == false; + public long? SelectedFileLength => SelectedFile?.IsDirectory == false ? SelectedFile?.FileInfo?.Length : 0; + public DateTime? SelectedFileCreationTime => SelectedFile?.FileInfo?.CreationTime; + public DateTime? SelectedFileLastWriteTime => SelectedFile?.FileInfo?.LastWriteTime; + public string? SelectedFileAttributes => SelectedFile?.FileInfo?.Attributes.ToString(); + public string? SelectedFileUnixMode => SelectedFile?.FileInfo?.UnixFileMode.ToString(); + public bool SelectedFileHasInformation => SelectedFile?.Information != null; + + public string? SelectedFileInformation => SelectedFile?.Information; + + Task HelpAsync() => + /* var dialog = new MainHelpDialog + { + DataContext = new MainHelpDialogViewModel(null!) + }; + + // Set the dialog reference after creation + ((MainHelpDialogViewModel)dialog.DataContext!)._dialog = dialog; + + return dialog.ShowDialog(_view);*/ + Task.CompletedTask; + + Task GoToPathAsync() => + /* var dialog = new GoToPathDialog + { + DataContext = new GoToPathDialogViewModel(null!) + }; + + // Set the dialog reference after creation + ((GoToPathDialogViewModel)dialog.DataContext!)._dialog = dialog; + + bool? result = await dialog.ShowDialog(_view); + + if(result == true) + { + var viewModel = (GoToPathDialogViewModel)dialog.DataContext; + + if(viewModel.Path is not null && Directory.Exists(viewModel.Path)) + { + Environment.CurrentDirectory = viewModel.Path; + LoadFiles(); + } + }*/ + Task.CompletedTask; + + void SectorView() + { + if(SelectedFile?.ImageFormat is null) return; + + var parameters = new NavigationParameters + { + { + "imageFormat", SelectedFile.ImageFormat + }, + { + "filePath", SelectedFile.Path + } + }; + + _regionManager.RequestNavigate("ContentRegion", nameof(HexViewWindow), parameters); + } + + void Exit() + { + var lifetime = Application.Current!.ApplicationLifetime as IControlledApplicationLifetime; + lifetime!.Shutdown(); + } + + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + LoadFiles(); + } + + public void LoadComplete() + { + LoadFiles(); + } + + public void LoadFiles() + { + IsStatusVisible = true; + Status = Localization.Resources.Loading; + CurrentPath = Directory.GetCurrentDirectory(); + Files.Clear(); + + var parentDirectory = new FileModel + { + Filename = "..", + Path = Path.GetRelativePath(CurrentPath, ".."), + ForegroundBrush = + new SolidColorBrush(Color.Parse(DirColorsParser.Instance.DirectoryColor ?? + DirColorsParser.Instance.NormalColor)), + IsDirectory = true + }; + + Files.Add(parentDirectory); + + foreach(FileModel model in Directory.GetDirectories(CurrentPath, "*", SearchOption.TopDirectoryOnly) + .Select(directory => new FileModel + { + Path = directory, + Filename = Path.GetFileName(directory), + ForegroundBrush = + new SolidColorBrush(Color.Parse(DirColorsParser.Instance + .DirectoryColor ?? + DirColorsParser.Instance.NormalColor)), + IsDirectory = true + })) + Files.Add(model); + + foreach(string file in Directory.GetFiles(CurrentPath, "*", SearchOption.TopDirectoryOnly)) + { + var model = new FileModel + { + Path = file, + Filename = Path.GetFileName(file) + }; + + string extension = Path.GetExtension(file); + + model.ForegroundBrush = + new SolidColorBrush(Color.Parse(DirColorsParser.Instance.ExtensionColors.TryGetValue(extension, + out string? hex) + ? hex + : DirColorsParser.Instance.NormalColor)); + + Files.Add(model); + } + + _ = Task.Run(Worker); + } + + void Worker() + { + IsStatusVisible = true; + Status = Localization.Resources.Loading_file_information; + + foreach(FileModel file in Files) + { + try + { + file.FileInfo = new FileInfo(file.Path); + + IFilter inputFilter = PluginRegister.Singleton.GetFilter(file.Path); + + if(inputFilter is null) continue; + + IBaseImage imageFormat = ImageFormat.Detect(inputFilter); + + if(imageFormat is null) continue; + + ErrorNumber opened = imageFormat.Open(inputFilter); + + if(opened != ErrorNumber.NoError) continue; + + StringBuilder sb = new(); + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.Version)) + { + sb.AppendFormat(Aaru.Localization.Core.Format_0_version_1_WithMarkup, + Markup.Escape(imageFormat.Format), + Markup.Escape(imageFormat.Info.Version)) + .AppendLine(); + } + else + { + sb.AppendFormat(Aaru.Localization.Core.Format_0_WithMarkup, Markup.Escape(imageFormat.Format)) + .AppendLine(); + } + + switch(string.IsNullOrWhiteSpace(imageFormat.Info.Application)) + { + case false when !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion): + sb.AppendFormat(Aaru.Localization.Core.Was_created_with_0_version_1_WithMarkup, + Markup.Escape(imageFormat.Info.Application), + Markup.Escape(imageFormat.Info.ApplicationVersion)) + .AppendLine(); + + break; + case false: + sb.AppendFormat(Aaru.Localization.Core.Was_created_with_0_WithMarkup, + Markup.Escape(imageFormat.Info.Application)) + .AppendLine(); + + break; + } + + sb.AppendFormat(Aaru.Localization.Core.Image_without_headers_is_0_bytes_long, + imageFormat.Info.ImageSize) + .AppendLine(); + + sb.AppendFormat(Aaru.Localization.Core.Contains_a_media_of_0_sectors, imageFormat.Info.Sectors) + .AppendLine(); + + sb.AppendFormat(Aaru.Localization.Core.Maximum_sector_size_of_0_bytes, imageFormat.Info.SectorSize) + .AppendLine(); + + sb.AppendFormat(Aaru.Localization.Core.Would_be_0_humanized, + ByteSize.FromBytes(imageFormat.Info.Sectors * imageFormat.Info.SectorSize).Humanize()) + .AppendLine(); + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.Creator)) + { + sb.AppendFormat(Aaru.Localization.Core.Created_by_0_WithMarkup, + Markup.Escape(imageFormat.Info.Creator)) + .AppendLine(); + } + + if(imageFormat.Info.CreationTime != DateTime.MinValue) + sb.AppendFormat(Aaru.Localization.Core.Created_on_0, imageFormat.Info.CreationTime).AppendLine(); + + if(imageFormat.Info.LastModificationTime != DateTime.MinValue) + { + sb.AppendFormat(Aaru.Localization.Core.Last_modified_on_0, imageFormat.Info.LastModificationTime) + .AppendLine(); + } + + sb.AppendFormat(Aaru.Localization.Core.Contains_a_media_of_type_0, + imageFormat.Info.MediaType.Humanize()) + .AppendLine(); + + sb.AppendFormat(Aaru.Localization.Core.XML_type_0, imageFormat.Info.MetadataMediaType).AppendLine(); + + sb.AppendLine(imageFormat.Info.HasPartitions + ? Aaru.Localization.Core.Has_partitions + : Aaru.Localization.Core.Doesnt_have_partitions); + + sb.AppendLine(imageFormat.Info.HasSessions + ? Aaru.Localization.Core.Has_sessions + : Aaru.Localization.Core.Doesnt_have_sessions); + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.Comments)) + { + sb.AppendFormat(Aaru.Localization.Core.Comments_0_WithMarkup, + Markup.Escape(imageFormat.Info.Comments)) + .AppendLine(); + } + + if(imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0) + { + sb.AppendFormat(Aaru.Localization.Core.Media_is_number_0_on_a_set_of_1_medias, + imageFormat.Info.MediaSequence, + imageFormat.Info.LastMediaSequence) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle)) + { + sb.AppendFormat(Aaru.Localization.Core.Media_title_0_WithMarkup, + Markup.Escape(imageFormat.Info.MediaTitle)) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer)) + { + sb.AppendFormat(Aaru.Localization.Core.Media_manufacturer_0_WithMarkup, + Markup.Escape(imageFormat.Info.MediaManufacturer)) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel)) + { + sb.AppendFormat(Aaru.Localization.Core.Media_model_0_WithMarkup, + Markup.Escape(imageFormat.Info.MediaModel)) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber)) + { + sb.AppendFormat(Aaru.Localization.Core.Media_serial_number_0_WithMarkup, + Markup.Escape(imageFormat.Info.MediaSerialNumber)) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode)) + { + sb.AppendFormat(Aaru.Localization.Core.Media_barcode_0_WithMarkup, + Markup.Escape(imageFormat.Info.MediaBarcode)) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber)) + { + sb.AppendFormat(Aaru.Localization.Core.Media_part_number_0_WithMarkup, + Markup.Escape(imageFormat.Info.MediaPartNumber)) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer)) + { + sb.AppendFormat(Aaru.Localization.Core.Drive_manufacturer_0_WithMarkup, + Markup.Escape(imageFormat.Info.DriveManufacturer)) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel)) + { + sb.AppendFormat(Aaru.Localization.Core.Drive_model_0_WithMarkup, + Markup.Escape(imageFormat.Info.DriveModel)) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber)) + { + sb.AppendFormat(Aaru.Localization.Core.Drive_serial_number_0_WithMarkup, + Markup.Escape(imageFormat.Info.DriveSerialNumber)) + .AppendLine(); + } + + if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision)) + { + sb.AppendFormat(Aaru.Localization.Core.Drive_firmware_info_0_WithMarkup, + Markup.Escape(imageFormat.Info.DriveFirmwareRevision)) + .AppendLine(); + } + + if(imageFormat.Info.Cylinders > 0 && + imageFormat.Info is { Heads: > 0, SectorsPerTrack: > 0 } && + imageFormat.Info.MetadataMediaType != MetadataMediaType.OpticalDisc && + imageFormat is not ITapeImage { IsTape: true }) + { + sb.AppendFormat(Aaru.Localization.Core + .Media_geometry_0_cylinders_1_heads_2_sectors_per_track_WithMarkup, + imageFormat.Info.Cylinders, + imageFormat.Info.Heads, + imageFormat.Info.SectorsPerTrack) + .AppendLine(); + } + + if(imageFormat.Info.ReadableMediaTags is { Count: > 0 }) + { + sb.AppendFormat(Aaru.Localization.Core.Contains_0_readable_media_tags_WithMarkup, + imageFormat.Info.ReadableMediaTags.Count) + .AppendLine(); + + foreach(MediaTagType tag in imageFormat.Info.ReadableMediaTags.Order()) + sb.Append($"[italic][rosybrown]{Markup.Escape(tag.ToString())}[/][/] "); + + sb.AppendLine(); + } + + if(imageFormat.Info.ReadableSectorTags is { Count: > 0 }) + { + sb.AppendFormat(Aaru.Localization.Core.Contains_0_readable_sector_tags_WithMarkup, + imageFormat.Info.ReadableSectorTags.Count) + .AppendLine(); + + foreach(SectorTagType tag in imageFormat.Info.ReadableSectorTags.Order()) + sb.Append($"[italic][rosybrown]{Markup.Escape(tag.ToString())}[/][/] "); + + sb.AppendLine(); + } + + file.Information = sb.ToString(); + + file.ImageFormat = imageFormat as IMediaImage; + } + catch(Exception ex) + { + SentrySdk.CaptureException(ex); + } + } + + Status = Localization.Resources.Done; + IsStatusVisible = false; + } + + void OpenSelectedFile() + { + if(SelectedFile.IsDirectory) + { + CurrentPath = SelectedFile.Path; + Environment.CurrentDirectory = CurrentPath; + LoadFiles(); + + return; + } + + if(SelectedFile.ImageFormat is null) return; + + var parameters = new NavigationParameters + { + { + "imageFormat", SelectedFile.ImageFormat + }, + { + "filePath", SelectedFile.Path + } + }; + + _regionManager.RequestNavigate("ContentRegion", nameof(ImageWindow), parameters); + } + + bool CanOpenSelectedFile() => SelectedFile != null; +} \ No newline at end of file diff --git a/Aaru.Tui/ViewModels/Windows/HexViewWindowViewModel.cs b/Aaru.Tui/ViewModels/Windows/HexViewWindowViewModel.cs index 8c979b613..c7be06cab 100644 --- a/Aaru.Tui/ViewModels/Windows/HexViewWindowViewModel.cs +++ b/Aaru.Tui/ViewModels/Windows/HexViewWindowViewModel.cs @@ -31,6 +31,7 @@ using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.Tui.ViewModels.Dialogs; using Aaru.Tui.Views.Dialogs; +using Aaru.Tui.Views.Windows; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using CommunityToolkit.Mvvm.ComponentModel; @@ -42,22 +43,23 @@ namespace Aaru.Tui.ViewModels.Windows; public sealed partial class HexViewWindowViewModel : ViewModelBase { - private const int BYTES_PER_LINE = 16; - readonly IMediaImage _imageFormat; - readonly ManagedWindow _view; + private const int BYTES_PER_LINE = 16; + readonly IRegionManager _regionManager; + readonly ManagedWindow _view; [ObservableProperty] ulong _currentSector; [ObservableProperty] string _filePath; [ObservableProperty] long _fileSize; + IMediaImage _imageFormat; [ObservableProperty] ObservableCollection _lines = []; bool _longMode; - internal HexViewWindowViewModel(ManagedWindow view, IMediaImage imageFormat, string filePath, - ulong currentSector = 0) + internal HexViewWindowViewModel(IRegionManager regionManager) { + _regionManager = regionManager; ExitCommand = new RelayCommand(Exit); BackCommand = new RelayCommand(Back); NextSectorCommand = new RelayCommand(NextSector); @@ -65,12 +67,6 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase GoToCommand = new AsyncRelayCommand(GoToAsync); HelpCommand = new AsyncRelayCommand(HelpAsync); ToggleLongCommand = new RelayCommand(ToggleLong); - - _view = view; - _imageFormat = imageFormat; - _currentSector = currentSector; - FilePath = filePath; - LoadSector(); } public ICommand BackCommand { get; } @@ -81,6 +77,17 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase public ICommand HelpCommand { get; } public ICommand ToggleLongCommand { get; } + /// + public override void OnNavigatedTo(NavigationContext navigationContext) + { + base.OnNavigatedTo(navigationContext); + + _imageFormat = navigationContext.Parameters.GetValue("imageFormat"); + FilePath = navigationContext.Parameters.GetValue("filePath"); + + LoadSector(); + } + void ToggleLong() { _longMode = !_longMode; @@ -150,7 +157,16 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase void Back() { - _view.Close(); + IRegion? region = _regionManager.Regions["ContentRegion"]; + IRegionNavigationService? navigationService = region.NavigationService; + + if(navigationService?.Journal.CanGoBack == true) + navigationService.Journal.GoBack(); + else + { + // No history - navigate directly to FileView + _regionManager.RequestNavigate("ContentRegion", nameof(FileView)); + } } void Exit() @@ -202,8 +218,6 @@ public sealed partial class HexViewWindowViewModel : ViewModelBase offset += bytesRead; } } - - public void LoadComplete() {} } public sealed class HexViewLine diff --git a/Aaru.Tui/ViewModels/Windows/ImageWindowViewModel.cs b/Aaru.Tui/ViewModels/Windows/ImageWindowViewModel.cs index 7531f799c..be055069a 100644 --- a/Aaru.Tui/ViewModels/Windows/ImageWindowViewModel.cs +++ b/Aaru.Tui/ViewModels/Windows/ImageWindowViewModel.cs @@ -31,8 +31,7 @@ using System.Windows.Input; using Aaru.CommonTypes; using Aaru.CommonTypes.Interfaces; using Aaru.Tui.Models; -using Aaru.Tui.ViewModels.Dialogs; -using Aaru.Tui.Views.Dialogs; +using Aaru.Tui.Views.Windows; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using CommunityToolkit.Mvvm.ComponentModel; @@ -46,12 +45,13 @@ namespace Aaru.Tui.ViewModels.Windows; public sealed partial class ImageWindowViewModel : ViewModelBase { - readonly IMediaImage _imageFormat; - readonly ManagedWindow _view; + readonly IRegionManager _regionManager; + readonly ManagedWindow _view; [ObservableProperty] public string _filePath; [ObservableProperty] string _filesystemInformation; + IMediaImage _imageFormat; [ObservableProperty] bool _isFilesystemInformationVisible; [ObservableProperty] @@ -82,15 +82,12 @@ public sealed partial class ImageWindowViewModel : ViewModelBase [ObservableProperty] string? _status; - public ImageWindowViewModel(ManagedWindow view, IMediaImage imageFormat, string filePath) + public ImageWindowViewModel(IRegionManager regionManager) { - _imageFormat = imageFormat; - FilePath = filePath; - _view = view; - - ExitCommand = new RelayCommand(Exit); - BackCommand = new RelayCommand(Back); - HelpCommand = new AsyncRelayCommand(HelpAsync); + _regionManager = regionManager; + ExitCommand = new RelayCommand(Exit); + BackCommand = new RelayCommand(Back); + HelpCommand = new AsyncRelayCommand(HelpAsync); } public FileSystemModelNode? SelectedNode @@ -153,7 +150,16 @@ public sealed partial class ImageWindowViewModel : ViewModelBase void Back() { - _view.Close(); + IRegion? region = _regionManager.Regions["ContentRegion"]; + IRegionNavigationService? navigationService = region.NavigationService; + + if(navigationService?.Journal.CanGoBack == true) + navigationService.Journal.GoBack(); + else + { + // No history - navigate directly to FileView + _regionManager.RequestNavigate("ContentRegion", nameof(FileView)); + } } void Exit() @@ -162,13 +168,17 @@ public sealed partial class ImageWindowViewModel : ViewModelBase lifetime!.Shutdown(); } - public void LoadComplete() + /// + public override void OnNavigatedTo(NavigationContext navigationContext) { + _imageFormat = navigationContext.Parameters.GetValue("imageFormat"); + FilePath = navigationContext.Parameters.GetValue("filePath"); + _ = Task.Run(Worker); } - Task HelpAsync() - { + Task HelpAsync() => + /* var dialog = new ImageHelpDialog { DataContext = new ImageHelpDialogViewModel(null!) @@ -177,8 +187,8 @@ public sealed partial class ImageWindowViewModel : ViewModelBase // Set the dialog reference after creation ((ImageHelpDialogViewModel)dialog.DataContext!)._dialog = dialog; - return dialog.ShowDialog(_view); - } + return dialog.ShowDialog(_view);*/ + Task.CompletedTask; void Worker() { diff --git a/Aaru.Tui/ViewModels/Windows/MainWindowViewModel.cs b/Aaru.Tui/ViewModels/Windows/MainWindowViewModel.cs index 1015a85bf..068288ba3 100644 --- a/Aaru.Tui/ViewModels/Windows/MainWindowViewModel.cs +++ b/Aaru.Tui/ViewModels/Windows/MainWindowViewModel.cs @@ -25,462 +25,6 @@ // Copyright © 2011-2025 Natalia Portillo // ****************************************************************************/ -using System.Collections.ObjectModel; -using System.Reflection; -using System.Text; -using System.Windows.Input; -using Aaru.CommonTypes; -using Aaru.CommonTypes.Enums; -using Aaru.CommonTypes.Interfaces; -using Aaru.Core; -using Aaru.Helpers; -using Aaru.Tui.Models; -using Aaru.Tui.ViewModels.Dialogs; -using Aaru.Tui.Views.Dialogs; -using Aaru.Tui.Views.Windows; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Media; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; -using Humanizer; -using Humanizer.Bytes; -using Spectre.Console; -using Color = Avalonia.Media.Color; - namespace Aaru.Tui.ViewModels.Windows; -public sealed partial class MainWindowViewModel : ViewModelBase -{ - readonly Window _view; - [ObservableProperty] - string _copyright; - [ObservableProperty] - string _currentPath; - [ObservableProperty] - ObservableCollection _files = []; - [ObservableProperty] - string _informationalVersion; - [ObservableProperty] - bool _isStatusVisible; - FileModel? _selectedFile; - [ObservableProperty] - string _status; - - public MainWindowViewModel(Window view) - { - _view = view; - ExitCommand = new RelayCommand(Exit); - SectorViewCommand = new RelayCommand(SectorView); - GoToPathCommand = new AsyncRelayCommand(GoToPathAsync); - HelpCommand = new AsyncRelayCommand(HelpAsync); - OpenSelectedFileCommand = new RelayCommand(OpenSelectedFile, CanOpenSelectedFile); - - InformationalVersion = - Assembly.GetExecutingAssembly() - .GetCustomAttribute() - ?.InformationalVersion ?? - "?.?.?"; - - Copyright = Assembly.GetExecutingAssembly().GetCustomAttribute()?.Copyright ?? ""; - Status = Localization.Resources.Loading; - } - - public FileModel? SelectedFile - { - get => _selectedFile; - set - { - SetProperty(ref _selectedFile, value); - OnPropertyChanged(nameof(IsFileInfoAvailable)); - OnPropertyChanged(nameof(SelectedFileIsNotDirectory)); - OnPropertyChanged(nameof(SelectedFileLength)); - OnPropertyChanged(nameof(SelectedFileCreationTime)); - OnPropertyChanged(nameof(SelectedFileLastWriteTime)); - OnPropertyChanged(nameof(SelectedFileAttributes)); - OnPropertyChanged(nameof(SelectedFileUnixMode)); - OnPropertyChanged(nameof(SelectedFileHasInformation)); - OnPropertyChanged(nameof(SelectedFileInformation)); - } - } - - public ICommand OpenSelectedFileCommand { get; } - public ICommand ExitCommand { get; } - public ICommand SectorViewCommand { get; } - public ICommand GoToPathCommand { get; } - public ICommand HelpCommand { get; } - public bool IsFileInfoAvailable => SelectedFile?.FileInfo != null; - public bool SelectedFileIsNotDirectory => SelectedFile?.IsDirectory == false; - public long? SelectedFileLength => SelectedFile?.IsDirectory == false ? SelectedFile?.FileInfo?.Length : 0; - public DateTime? SelectedFileCreationTime => SelectedFile?.FileInfo?.CreationTime; - public DateTime? SelectedFileLastWriteTime => SelectedFile?.FileInfo?.LastWriteTime; - public string? SelectedFileAttributes => SelectedFile?.FileInfo?.Attributes.ToString(); - public string? SelectedFileUnixMode => SelectedFile?.FileInfo?.UnixFileMode.ToString(); - public bool SelectedFileHasInformation => SelectedFile?.Information != null; - - public string? SelectedFileInformation => SelectedFile?.Information; - - Task HelpAsync() - { - var dialog = new MainHelpDialog - { - DataContext = new MainHelpDialogViewModel(null!) - }; - - // Set the dialog reference after creation - ((MainHelpDialogViewModel)dialog.DataContext!)._dialog = dialog; - - return dialog.ShowDialog(_view); - } - - async Task GoToPathAsync() - { - var dialog = new GoToPathDialog - { - DataContext = new GoToPathDialogViewModel(null!) - }; - - // Set the dialog reference after creation - ((GoToPathDialogViewModel)dialog.DataContext!)._dialog = dialog; - - bool? result = await dialog.ShowDialog(_view); - - if(result == true) - { - var viewModel = (GoToPathDialogViewModel)dialog.DataContext; - - if(viewModel.Path is not null && Directory.Exists(viewModel.Path)) - { - Environment.CurrentDirectory = viewModel.Path; - LoadFiles(); - } - } - } - - void SectorView() - { - if(SelectedFile?.ImageFormat is null) return; - - var view = new HexViewWindow(); - - var vm = new HexViewWindowViewModel(view, SelectedFile.ImageFormat, SelectedFile.Path); - view.DataContext = vm; - view.Show(); - } - - void Exit() - { - var lifetime = Application.Current!.ApplicationLifetime as IControlledApplicationLifetime; - lifetime!.Shutdown(); - } - - public void LoadComplete() - { - LoadFiles(); - } - - public void LoadFiles() - { - IsStatusVisible = true; - Status = Localization.Resources.Loading; - CurrentPath = Directory.GetCurrentDirectory(); - Files.Clear(); - - var parentDirectory = new FileModel - { - Filename = "..", - Path = Path.GetRelativePath(CurrentPath, ".."), - ForegroundBrush = - new SolidColorBrush(Color.Parse(DirColorsParser.Instance.DirectoryColor ?? - DirColorsParser.Instance.NormalColor)), - IsDirectory = true - }; - - Files.Add(parentDirectory); - - foreach(FileModel model in Directory.GetDirectories(CurrentPath, "*", SearchOption.TopDirectoryOnly) - .Select(directory => new FileModel - { - Path = directory, - Filename = Path.GetFileName(directory), - ForegroundBrush = - new SolidColorBrush(Color.Parse(DirColorsParser.Instance - .DirectoryColor ?? - DirColorsParser.Instance.NormalColor)), - IsDirectory = true - })) - Files.Add(model); - - foreach(string file in Directory.GetFiles(CurrentPath, "*", SearchOption.TopDirectoryOnly)) - { - var model = new FileModel - { - Path = file, - Filename = Path.GetFileName(file) - }; - - string extension = Path.GetExtension(file); - - model.ForegroundBrush = - new SolidColorBrush(Color.Parse(DirColorsParser.Instance.ExtensionColors.TryGetValue(extension, - out string? hex) - ? hex - : DirColorsParser.Instance.NormalColor)); - - Files.Add(model); - } - - _ = Task.Run(Worker); - } - - void Worker() - { - IsStatusVisible = true; - Status = Localization.Resources.Loading_file_information; - - foreach(FileModel file in Files) - { - try - { - file.FileInfo = new FileInfo(file.Path); - - IFilter inputFilter = PluginRegister.Singleton.GetFilter(file.Path); - - if(inputFilter is null) continue; - - IBaseImage imageFormat = ImageFormat.Detect(inputFilter); - - if(imageFormat is null) continue; - - ErrorNumber opened = imageFormat.Open(inputFilter); - - if(opened != ErrorNumber.NoError) continue; - - StringBuilder sb = new(); - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.Version)) - { - sb.AppendFormat(Aaru.Localization.Core.Format_0_version_1_WithMarkup, - Markup.Escape(imageFormat.Format), - Markup.Escape(imageFormat.Info.Version)) - .AppendLine(); - } - else - sb.AppendFormat(Aaru.Localization.Core.Format_0_WithMarkup, Markup.Escape(imageFormat.Format)) - .AppendLine(); - - switch(string.IsNullOrWhiteSpace(imageFormat.Info.Application)) - { - case false when !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion): - sb.AppendFormat(Aaru.Localization.Core.Was_created_with_0_version_1_WithMarkup, - Markup.Escape(imageFormat.Info.Application), - Markup.Escape(imageFormat.Info.ApplicationVersion)) - .AppendLine(); - - break; - case false: - sb.AppendFormat(Aaru.Localization.Core.Was_created_with_0_WithMarkup, - Markup.Escape(imageFormat.Info.Application)) - .AppendLine(); - - break; - } - - sb.AppendFormat(Aaru.Localization.Core.Image_without_headers_is_0_bytes_long, - imageFormat.Info.ImageSize) - .AppendLine(); - - sb.AppendFormat(Aaru.Localization.Core.Contains_a_media_of_0_sectors, imageFormat.Info.Sectors) - .AppendLine(); - - sb.AppendFormat(Aaru.Localization.Core.Maximum_sector_size_of_0_bytes, imageFormat.Info.SectorSize) - .AppendLine(); - - sb.AppendFormat(Aaru.Localization.Core.Would_be_0_humanized, - ByteSize.FromBytes(imageFormat.Info.Sectors * imageFormat.Info.SectorSize).Humanize()) - .AppendLine(); - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.Creator)) - sb.AppendFormat(Aaru.Localization.Core.Created_by_0_WithMarkup, - Markup.Escape(imageFormat.Info.Creator)) - .AppendLine(); - - if(imageFormat.Info.CreationTime != DateTime.MinValue) - sb.AppendFormat(Aaru.Localization.Core.Created_on_0, imageFormat.Info.CreationTime).AppendLine(); - - if(imageFormat.Info.LastModificationTime != DateTime.MinValue) - sb.AppendFormat(Aaru.Localization.Core.Last_modified_on_0, imageFormat.Info.LastModificationTime) - .AppendLine(); - - sb.AppendFormat(Aaru.Localization.Core.Contains_a_media_of_type_0, - imageFormat.Info.MediaType.Humanize()) - .AppendLine(); - - sb.AppendFormat(Aaru.Localization.Core.XML_type_0, imageFormat.Info.MetadataMediaType).AppendLine(); - - sb.AppendLine(imageFormat.Info.HasPartitions - ? Aaru.Localization.Core.Has_partitions - : Aaru.Localization.Core.Doesnt_have_partitions); - - sb.AppendLine(imageFormat.Info.HasSessions - ? Aaru.Localization.Core.Has_sessions - : Aaru.Localization.Core.Doesnt_have_sessions); - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.Comments)) - sb.AppendFormat(Aaru.Localization.Core.Comments_0_WithMarkup, - Markup.Escape(imageFormat.Info.Comments)) - .AppendLine(); - - if(imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0) - { - sb.AppendFormat(Aaru.Localization.Core.Media_is_number_0_on_a_set_of_1_medias, - imageFormat.Info.MediaSequence, - imageFormat.Info.LastMediaSequence) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle)) - { - sb.AppendFormat(Aaru.Localization.Core.Media_title_0_WithMarkup, - Markup.Escape(imageFormat.Info.MediaTitle)) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer)) - { - sb.AppendFormat(Aaru.Localization.Core.Media_manufacturer_0_WithMarkup, - Markup.Escape(imageFormat.Info.MediaManufacturer)) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel)) - { - sb.AppendFormat(Aaru.Localization.Core.Media_model_0_WithMarkup, - Markup.Escape(imageFormat.Info.MediaModel)) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber)) - { - sb.AppendFormat(Aaru.Localization.Core.Media_serial_number_0_WithMarkup, - Markup.Escape(imageFormat.Info.MediaSerialNumber)) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode)) - { - sb.AppendFormat(Aaru.Localization.Core.Media_barcode_0_WithMarkup, - Markup.Escape(imageFormat.Info.MediaBarcode)) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber)) - { - sb.AppendFormat(Aaru.Localization.Core.Media_part_number_0_WithMarkup, - Markup.Escape(imageFormat.Info.MediaPartNumber)) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer)) - { - sb.AppendFormat(Aaru.Localization.Core.Drive_manufacturer_0_WithMarkup, - Markup.Escape(imageFormat.Info.DriveManufacturer)) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel)) - { - sb.AppendFormat(Aaru.Localization.Core.Drive_model_0_WithMarkup, - Markup.Escape(imageFormat.Info.DriveModel)) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber)) - { - sb.AppendFormat(Aaru.Localization.Core.Drive_serial_number_0_WithMarkup, - Markup.Escape(imageFormat.Info.DriveSerialNumber)) - .AppendLine(); - } - - if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision)) - { - sb.AppendFormat(Aaru.Localization.Core.Drive_firmware_info_0_WithMarkup, - Markup.Escape(imageFormat.Info.DriveFirmwareRevision)) - .AppendLine(); - } - - if(imageFormat.Info.Cylinders > 0 && - imageFormat.Info is { Heads: > 0, SectorsPerTrack: > 0 } && - imageFormat.Info.MetadataMediaType != MetadataMediaType.OpticalDisc && - imageFormat is not ITapeImage { IsTape: true }) - { - sb.AppendFormat(Aaru.Localization.Core - .Media_geometry_0_cylinders_1_heads_2_sectors_per_track_WithMarkup, - imageFormat.Info.Cylinders, - imageFormat.Info.Heads, - imageFormat.Info.SectorsPerTrack) - .AppendLine(); - } - - if(imageFormat.Info.ReadableMediaTags is { Count: > 0 }) - { - sb.AppendFormat(Aaru.Localization.Core.Contains_0_readable_media_tags_WithMarkup, - imageFormat.Info.ReadableMediaTags.Count) - .AppendLine(); - - foreach(MediaTagType tag in imageFormat.Info.ReadableMediaTags.Order()) - sb.Append($"[italic][rosybrown]{Markup.Escape(tag.ToString())}[/][/] "); - - sb.AppendLine(); - } - - if(imageFormat.Info.ReadableSectorTags is { Count: > 0 }) - { - sb.AppendFormat(Aaru.Localization.Core.Contains_0_readable_sector_tags_WithMarkup, - imageFormat.Info.ReadableSectorTags.Count) - .AppendLine(); - - foreach(SectorTagType tag in imageFormat.Info.ReadableSectorTags.Order()) - sb.Append($"[italic][rosybrown]{Markup.Escape(tag.ToString())}[/][/] "); - - sb.AppendLine(); - } - - file.Information = sb.ToString(); - - file.ImageFormat = imageFormat as IMediaImage; - } - catch(Exception ex) - { - SentrySdk.CaptureException(ex); - } - } - - Status = Localization.Resources.Done; - IsStatusVisible = false; - } - - void OpenSelectedFile() - { - if(SelectedFile.IsDirectory) - { - CurrentPath = SelectedFile.Path; - Environment.CurrentDirectory = CurrentPath; - LoadFiles(); - - return; - } - - if(SelectedFile.ImageFormat is null) return; - - var imageWindow = new ImageWindow(); - - var imageViewModel = new ImageWindowViewModel(imageWindow, SelectedFile.ImageFormat, SelectedFile.Path); - - imageWindow.DataContext = imageViewModel; - imageWindow.Show(); - } - - bool CanOpenSelectedFile() => SelectedFile != null; -} \ No newline at end of file +public sealed class MainWindowViewModel {} \ No newline at end of file diff --git a/Aaru.Tui/Views/Windows/FileView.axaml b/Aaru.Tui/Views/Windows/FileView.axaml new file mode 100644 index 000000000..ad8b42ff8 --- /dev/null +++ b/Aaru.Tui/Views/Windows/FileView.axaml @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Aaru.Tui/Views/Windows/FileView.axaml.cs b/Aaru.Tui/Views/Windows/FileView.axaml.cs new file mode 100644 index 000000000..b0ea35f2e --- /dev/null +++ b/Aaru.Tui/Views/Windows/FileView.axaml.cs @@ -0,0 +1,60 @@ +// /*************************************************************************** +// Aaru Data Preservation Suite +// ---------------------------------------------------------------------------- +// +// Author(s) : Natalia Portillo +// +// Component : Text User Interface. +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2025 Natalia Portillo +// ****************************************************************************/ + +using Aaru.Tui.ViewModels.Windows; +using Avalonia.Controls; +using Avalonia.Input; + +namespace Aaru.Tui.Views.Windows; + +public partial class FileView : UserControl +{ + public FileView() + { + InitializeComponent(); + } + + private void ListBox_OnKeyDown(object sender, KeyEventArgs e) + { + if(e.Key == Key.Enter) + { + if(DataContext is FileViewViewModel vm && vm.OpenSelectedFileCommand.CanExecute(null)) + { + vm.OpenSelectedFileCommand.Execute(null); + e.Handled = true; + } + } + } + + /// + protected override void OnDataContextChanged(EventArgs e) + { + base.OnDataContextChanged(e); + + (DataContext as FileViewViewModel)?.LoadComplete(); + } +} \ No newline at end of file diff --git a/Aaru.Tui/Views/Windows/HexViewWindow.axaml b/Aaru.Tui/Views/Windows/HexViewWindow.axaml index b0a595ecc..c93d3493e 100644 --- a/Aaru.Tui/Views/Windows/HexViewWindow.axaml +++ b/Aaru.Tui/Views/Windows/HexViewWindow.axaml @@ -1,12 +1,12 @@ - + @@ -101,4 +101,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/Aaru.Tui/Views/Windows/HexViewWindow.axaml.cs b/Aaru.Tui/Views/Windows/HexViewWindow.axaml.cs index 68b9b66d7..766223741 100644 --- a/Aaru.Tui/Views/Windows/HexViewWindow.axaml.cs +++ b/Aaru.Tui/Views/Windows/HexViewWindow.axaml.cs @@ -25,25 +25,14 @@ // Copyright © 2011-2025 Natalia Portillo // ****************************************************************************/ -using Aaru.Tui.ViewModels.Windows; -using Avalonia.Interactivity; -using Iciclecreek.Avalonia.WindowManager; +using Avalonia.Controls; namespace Aaru.Tui.Views.Windows; -public partial class HexViewWindow : ManagedWindow +public partial class HexViewWindow : UserControl { public HexViewWindow() { InitializeComponent(); } - - - /// - protected override void OnLoaded(RoutedEventArgs e) - { - base.OnLoaded(e); - - (DataContext as HexViewWindowViewModel)?.LoadComplete(); - } } \ No newline at end of file diff --git a/Aaru.Tui/Views/Windows/ImageWindow.axaml b/Aaru.Tui/Views/Windows/ImageWindow.axaml index e1a9019b5..e6886cefa 100644 --- a/Aaru.Tui/Views/Windows/ImageWindow.axaml +++ b/Aaru.Tui/Views/Windows/ImageWindow.axaml @@ -1,17 +1,17 @@ - + @@ -174,4 +174,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/Aaru.Tui/Views/Windows/ImageWindow.axaml.cs b/Aaru.Tui/Views/Windows/ImageWindow.axaml.cs index 173a06bfa..74420cefc 100644 --- a/Aaru.Tui/Views/Windows/ImageWindow.axaml.cs +++ b/Aaru.Tui/Views/Windows/ImageWindow.axaml.cs @@ -25,24 +25,14 @@ // Copyright © 2011-2025 Natalia Portillo // ****************************************************************************/ -using Aaru.Tui.ViewModels.Windows; -using Avalonia.Interactivity; -using Iciclecreek.Avalonia.WindowManager; +using Avalonia.Controls; namespace Aaru.Tui.Views.Windows; -public partial class ImageWindow : ManagedWindow +public partial class ImageWindow : UserControl { public ImageWindow() { InitializeComponent(); } - - /// - protected override void OnLoaded(RoutedEventArgs e) - { - base.OnLoaded(e); - - (DataContext as ImageWindowViewModel)?.LoadComplete(); - } } \ No newline at end of file diff --git a/Aaru.Tui/Views/Windows/MainWindow.axaml b/Aaru.Tui/Views/Windows/MainWindow.axaml index 596619b92..fc705ae36 100644 --- a/Aaru.Tui/Views/Windows/MainWindow.axaml +++ b/Aaru.Tui/Views/Windows/MainWindow.axaml @@ -1,195 +1,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/Aaru.Tui/Views/Windows/MainWindow.axaml.cs b/Aaru.Tui/Views/Windows/MainWindow.axaml.cs index 5f48c01e9..66b99987d 100644 --- a/Aaru.Tui/Views/Windows/MainWindow.axaml.cs +++ b/Aaru.Tui/Views/Windows/MainWindow.axaml.cs @@ -25,39 +25,15 @@ // Copyright © 2011-2025 Natalia Portillo // ****************************************************************************/ -using Aaru.Tui.ViewModels.Windows; using Avalonia.Controls; -using Avalonia.Input; -using Avalonia.Interactivity; namespace Aaru.Tui.Views.Windows; +/// Main window view. public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } - - public MainWindow(object? dataContext) : this() => DataContext = dataContext; - - private void ListBox_OnKeyDown(object sender, KeyEventArgs e) - { - if(e.Key == Key.Enter) - { - if(DataContext is MainWindowViewModel vm && vm.OpenSelectedFileCommand.CanExecute(null)) - { - vm.OpenSelectedFileCommand.Execute(null); - e.Handled = true; - } - } - } - - /// - protected override void OnLoaded(RoutedEventArgs e) - { - base.OnLoaded(e); - - (DataContext as MainWindowViewModel)?.LoadComplete(); - } } \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index 65c79e360..7d0f0462b 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -39,6 +39,8 @@ + +