This commit is contained in:
WeeXnes 2025-04-21 03:49:47 +02:00
parent 426a90bfcc
commit aabe596064
12 changed files with 345 additions and 39 deletions

View file

@ -8,6 +8,7 @@
CanResize="False"
x:Class="PS2_Manager.AddGameWindow"
Title="Install Game"
WindowStartupLocation="CenterScreen"
Loaded="Control_OnLoaded"
SizeChanged="Control_OnSizeChanged"
Background="#201c29"

View file

@ -1,4 +1,6 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using PS2_Manager.Core;
@ -17,7 +19,28 @@ public partial class App : Application
Globals.LoadSettings();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
if (String.IsNullOrEmpty(settings.library_path.GetValue<string>()))
{
var setupWindow = new Setup();
setupWindow.Closed += (_, _) =>
{
// Replace MainWindow after setup finishes
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
var mainWindow = new MainWindow();
desktop.MainWindow = mainWindow;
mainWindow.Show();
}
};
desktop.MainWindow = setupWindow;
}
else
{
desktop.MainWindow = new MainWindow();
}
}
base.OnFrameworkInitializationCompleted();

View file

@ -19,11 +19,26 @@ public class Game
public EventHandler? InstallationFinished { get; set; }
public UpdateVar<double> InstallProgress { get; private set; }
public Game(string isoPath)
public Game(string isoPath, bool installed = false)
{
this.GamePath = isoPath;
this.GameID = ISO.GetSerial(isoPath);
this.Cover = this.GetCover();
if (!installed)
{
this.Cover = this.GetCover();
}
else
{
this.Name = ParseFormattedFilename(Path.GetFileName(isoPath));
this.Cover = new Bitmap(Path.Combine(Path.Combine(settings.library_path.GetValue<string>(), "ART"), this.GameID + "_COV.png"));
}
}
private string ParseFormattedFilename(string filename)
{
string[] parts = filename.Split('.');
return parts[^2];
}
public async void Install()
@ -86,6 +101,7 @@ public class Game
this.InstallCover();
this.InstallationFinished?.Invoke(this, EventArgs.Empty);
MainWindow.RefreshGamesListTrigger?.Invoke(this, EventArgs.Empty);
Console.WriteLine($"Copied ISO to: {destPath}");
}

View file

@ -24,4 +24,19 @@ public static class Util
var result = dialog.ShowAsync(parent).GetAwaiter().GetResult();
return result?.FirstOrDefault();
}
public static string FormatFileSize(long bytes)
{
string[] sizes = { "B", "KB", "MB", "GB", "TB" };
double len = bytes;
int order = 0;
while (len >= 1024 && order < sizes.Length - 1)
{
order++;
len /= 1024;
}
// Format to 1 decimal place
return string.Format("{0:0.0} {1}", len, sizes[order]);
}
}

View file

@ -0,0 +1,12 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="PS2_Manager.EditGame">
<StackPanel Orientation="Vertical" Margin="10">
<TextBlock Text="Display Name:" HorizontalAlignment="Center" Padding="0,10"/>
<TextBox Name="DisplayNameBox" TextChanged="DisplayNameBox_OnTextChanged"/>
</StackPanel>
</UserControl>

View file

@ -0,0 +1,23 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using PS2_Manager.Core;
namespace PS2_Manager;
public partial class EditGame : UserControl
{
public Game game { get; set; }
public EditGame(Game _game)
{
this.game = _game;
InitializeComponent();
}
private void DisplayNameBox_OnTextChanged(object? sender, TextChangedEventArgs e)
{
this.game.Name = DisplayNameBox.Text;
MainWindow.RefreshGamesListTrigger.Invoke(null, EventArgs.Empty);
}
}

View file

@ -0,0 +1,20 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="PS2_Manager.GameInfo">
<Grid RowDefinitions="350, *, *, *, *">
<Border Grid.Row="0" Width="205" Height="292" Background="Black" CornerRadius="5" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Name="CoverImage" Source="Images/missing.png" Stretch="UniformToFill"/>
</Border>
<TextBlock Grid.Row="1" Text="" HorizontalAlignment="Center"
Name="GameNameTextBlock"/>
<TextBlock Grid.Row="2" Text="" HorizontalAlignment="Center"
Name="GameIdTextBlock"/>
<TextBlock Grid.Row="3" Text="" HorizontalAlignment="Center"
Name="IsoSizeTextBlock"/>
<TextBlock Grid.Row="4" Text="" HorizontalAlignment="Center"
Name="GameDateTextBlock"/>
</Grid>
</UserControl>

View file

@ -0,0 +1,27 @@
using System;
using System.IO;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using PS2_Manager.Core;
namespace PS2_Manager;
public partial class GameInfo : UserControl
{
public Game game { get; set; }
public GameInfo(Game _game)
{
InitializeComponent();
this.game = _game;
CoverImage.Source = game.Cover;
GameNameTextBlock.Text = game.Name;
GameIdTextBlock.Text = game.GameID;
FileInfo fileInfo = new FileInfo(game.GamePath);
IsoSizeTextBlock.Text = Util.FormatFileSize(fileInfo.Length);
DateTime lastModified = fileInfo.LastWriteTime;
string formattedDate = lastModified.ToString("dd.MM.yyyy HH:mm");
GameDateTextBlock.Text = formattedDate;
}
}

View file

@ -2,38 +2,84 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PS2_Manager.Core"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="PS2_Manager.MainWindow"
Title="PS2_Manager"
Background="#201c29"
Background="Transparent"
SystemDecorations="None"
Width="880"
Width="990"
Height="520"
WindowStartupLocation="CenterScreen"
Loaded="Control_OnLoaded">
<Grid RowDefinitions="20, *">
<Grid Grid.Row="0">
<Border Background="#35313d"
PointerPressed="WindowDrag">
<Grid ColumnDefinitions="*, 20">
<TextBlock Name="WindowTitle" FontSize="12" Padding="8,0,0,0" VerticalAlignment="Center"/>
<Border Grid.Column="1" Background="#625f69" PointerPressed="WindowClose">
<TextBlock FontSize="12" Text="×" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
<Grid ColumnDefinitions="680, 10, 300" Background="Transparent">
<Grid Grid.Column="0" RowDefinitions="20, *">
<Grid Grid.Row="0">
<Border Background="#35313d"
PointerPressed="WindowDrag">
<Grid ColumnDefinitions="*, 20">
<TextBlock Name="WindowTitle" FontSize="12" Padding="8,0,0,0" VerticalAlignment="Center"/>
<Border Grid.Column="1" Background="#625f69" PointerPressed="WindowClose">
<TextBlock FontSize="12" Text="×" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
</Grid>
</Border>
</Grid>
<Grid Grid.Row="1">
<Border Background="Red" CornerRadius="0" Margin="8">
<Grid ColumnDefinitions="300, *">
<Border Background="Aqua">
<ListBox Name="GamesList"></ListBox>
</Border>
<Border Background="#201c29" CornerRadius="0,0,10,10">
<Grid ColumnDefinitions="300, 1, *">
<Border CornerRadius="10" Margin="5">
<ListBox Name="GamesList" Background="Transparent"
SelectionChanged="GamesList_OnSelectionChanged"
>
<ListBox.ItemTemplate>
<DataTemplate x:DataType="local:Game">
<Border Background="Transparent" Padding="10">
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="Remove Game"/>
<MenuItem Header="Show Details"/>
</ContextMenu>
</Border.ContextMenu>
<TextBlock Text="{Binding Name}"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu x:Name="EmptyAreaContextMenu">
<MenuItem Header="Add New Game" Click="OpenFileButton_Clicked"/>
<MenuItem Header="Refresh List" Click="Context_RefreshGames"/>
</ContextMenu>
</ListBox.ContextMenu>
<ListBox.Styles>
<Style Selector="ListBoxItem:selected /template/ ContentPresenter">
<Setter Property="Background" Value="#35313d"/>
</Style>
<Style Selector="ListBoxItem">
<Setter Property="Padding" Value="0"/>
<Setter Property="CornerRadius" Value="10"/>
</Style>
</ListBox.Styles>
</ListBox>
</Border>
<Border Grid.Column="1" Background="Aqua">
<Button Click="OpenFileButton_Clicked" Content="Install Game"></Button>
</Border>
</Grid>
</Border>
<Border Grid.Column="1">
<Border Width="1" Background="#35313d" Margin="2,10"/>
</Border>
<Border Grid.Column="2">
<Border Margin="2,0,0,0" Name="GameEdit">
</Border>
</Border>
</Grid>
</Border>
</Grid>
</Grid>
<Grid Grid.Column="2" RowDefinitions="20, *" IsVisible="False" Name="GameShowcaseGrid">
<Border Grid.Row="1" Background="#35313d" CornerRadius="10" Name="InfoWindow">
</Border>
</Grid>
</Grid>
</Window>

View file

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using Avalonia.Controls;
using Avalonia.Input;
@ -10,9 +11,20 @@ namespace PS2_Manager;
public partial class MainWindow : Window
{
public static EventHandler? RefreshGamesListTrigger { get; set; }
public MainWindow()
{
InitializeComponent();
RefreshGamesListTrigger += FetchGamesFromLibrary;
}
private void ShowcaseGame(Game game)
{
GameShowcaseGrid.IsVisible = true;
InfoWindow.Child = new GameInfo(game);
GameEdit.Child = new EditGame(game);
}
private void WindowDrag(object? sender, PointerPressedEventArgs e)
@ -34,7 +46,7 @@ public partial class MainWindow : Window
var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "Open Text File",
Title = "Select PS2 Iso file to install",
AllowMultiple = false,
FileTypeFilter = new []
{
@ -52,18 +64,35 @@ public partial class MainWindow : Window
private async void Control_OnLoaded(object? sender, RoutedEventArgs e)
{
WindowTitle.Text = "PS2 Games Manager";
if (String.IsNullOrEmpty(settings.library_path.GetValue<string>()))
{
var topLevel = TopLevel.GetTopLevel(this);
var path = await topLevel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = "Open Game Library",
AllowMultiple = false
});
Console.WriteLine(path[0].Path.LocalPath);
if(!String.IsNullOrEmpty(path[0].Path.LocalPath))
settings.library_path.SetValue(path[0].Path.LocalPath);
}
FetchGamesFromLibrary();
}
public void FetchGamesFromLibrary(object? sender = null, EventArgs? e = null)
{
List<Game> Games = new List<Game>();
Console.WriteLine("Loading library...");
string[] files = Directory.GetFiles(Path.Combine(settings.library_path.GetValue<string>(), "DVD"));
foreach (var file in files)
{
Console.WriteLine(file);
Game newGame =
new Game(file, true);
Games.Add(newGame);
}
GamesList.ItemsSource = Games;
}
private void GamesList_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
{
if (GamesList.SelectedItem is Game selectedGame)
{
Console.WriteLine($"Clicked on game: {selectedGame.Name}, ID: {selectedGame.GameID}");
this.ShowcaseGame(selectedGame);
}
}
private void Context_RefreshGames(object? sender, RoutedEventArgs e)
{
FetchGamesFromLibrary();
}
}

32
PS2_Manager/Setup.axaml Normal file
View file

@ -0,0 +1,32 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="PS2_Manager.Setup"
WindowStartupLocation="CenterScreen"
SystemDecorations="None"
Title="Setup"
Height="349"
Width="598"
Background="#201c29">
<Grid RowDefinitions="20, *">
<Grid Grid.Row="0">
<Border Background="#35313d"
PointerPressed="WindowDrag">
<Grid ColumnDefinitions="*, 20">
<TextBlock Name="WindowTitle" FontSize="12" Text="Setup PS2 Manager" Padding="8,0,0,0" VerticalAlignment="Center"/>
</Grid>
</Border>
</Grid>
<Grid Grid.Row="1" Margin="20">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Name="InfoText1" Text="Welcome to PS2 Manager" HorizontalAlignment="Center"/>
<Separator/>
<TextBlock Name="InfoText2" Text="First of all please select the path to your PS2 Game Library" HorizontalAlignment="Center"/>
<Button Name="OpenLibraryButton" Content="Select Folder" HorizontalAlignment="Center" Margin="0,10"
Click="OpenLibraryButton_OnClick"/>
</StackPanel>
</Grid>
</Grid>
</Window>

View file

@ -0,0 +1,62 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.Platform.Storage;
using PS2_Manager.Core;
namespace PS2_Manager;
public partial class Setup : Window
{
public Setup()
{
InitializeComponent();
}
private void WindowDrag(object? sender, PointerPressedEventArgs e)
{
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
{
BeginMoveDrag(e);
}
}
private void FinishSetup()
{
InfoText1.Text = "Setup Finished";
InfoText2.Text = "You can now exit to the Main Application";
OpenLibraryButton.Content = "Exit";
OpenLibraryButton.Click -= OpenLibraryButton_OnClick;
OpenLibraryButton.Click += (sender, args) =>
{
this.Close();
};
}
private async void OpenLibraryButton_OnClick(object? sender, RoutedEventArgs e)
{
settings.library_path.SetValue("");
while (String.IsNullOrEmpty(settings.library_path.GetValue<string>()))
{
var topLevel = TopLevel.GetTopLevel(this);
var path = await topLevel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = "Open Game Library",
AllowMultiple = false
});
try
{
if (!String.IsNullOrEmpty(path[0].Path.LocalPath))
settings.library_path.SetValue(path[0].Path.LocalPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
FinishSetup();
}
}