This commit is contained in:
2025-11-17 15:02:47 +01:00
parent d80f5c47b1
commit 7e2a103dbe
17 changed files with 182 additions and 78 deletions

View File

@@ -13,7 +13,8 @@
x:DataType="mainWindow:MainWindowViewModel"
Title="Minecraft Modpack Manager"
WindowState="Maximized"
Loaded="Window_OnLoaded">
Loaded="Window_OnLoaded"
Closed="Window_OnClosed">
<Grid
x:Name="GridMain"
@@ -100,52 +101,80 @@
</ScrollViewer>
<!-- Panel: List header -->
<ContentControl
<StackPanel
Grid.Column="1"
Grid.Row="0"
Content="{Binding SelectedTreeNode}">
Spacing="6"
Orientation="Horizontal"
VerticalAlignment="Center">
<ContentControl.DataTemplates>
<DataTemplate
DataType="mainWindow:ActionSetTreeNode">
<!-- Panel: Menu -->
<ContentControl
Content="{Binding SelectedTreeNode}">
<StackPanel
Orientation="Horizontal">
<ContentControl.DataTemplates>
<DataTemplate
DataType="mainWindow:ActionSetTreeNode">
<!-- Button: Add action -->
<pilz:ImageButton
x:Name="ButtonAddAction"
Text="{x:Static langRes:GeneralLangRes.Add}"
ImageSource="{x:Static local:MainWindow.ButtonImageAddAction}"
Background="Transparent"
Click="ButtonAddAction_OnClick"/>
<StackPanel
Orientation="Horizontal">
<!-- Button: Remove action -->
<pilz:ImageButton
x:Name="ButtonRemoveAction"
Text="{x:Static langRes:GeneralLangRes.Remove}"
ImageSource="{x:Static local:MainWindow.ButtonImageRemoveAction}"
Background="Transparent"
Click="ButtonRemoveAction_OnClick"/>
<!-- Button: Add action -->
<pilz:ImageButton
x:Name="ButtonAddAction"
Text="{x:Static langRes:GeneralLangRes.Add}"
ImageSource="{x:Static local:MainWindow.ButtonImageAddAction}"
Background="Transparent"
Click="ButtonAddAction_OnClick"/>
<!-- TextBox: Version -->
<TextBox
Margin="3, 0, 3, 0"
Width="100"
Text="{Binding Version}"/>
<!-- Button: Remove action -->
<pilz:ImageButton
x:Name="ButtonRemoveAction"
Text="{x:Static langRes:GeneralLangRes.Remove}"
ImageSource="{x:Static local:MainWindow.ButtonImageRemoveAction}"
Background="Transparent"
Click="ButtonRemoveAction_OnClick"/>
<!-- CheckBox: Is public -->
<CheckBox
Margin="3, 0, 3, 0"
Content="{x:Static langRes:GeneralLangRes.Public}"
IsChecked="{Binding IsPublic}"/>
</StackPanel>
</DataTemplate>
<!-- TextBox: Version -->
<TextBox
Margin="3, 0, 3, 0"
Width="100"
Text="{Binding Version}"/>
<DataTemplate
DataType="mainWindow:MainWindowTreeNode"/>
</ContentControl.DataTemplates>
</ContentControl>
<!-- CheckBox: Is public -->
<CheckBox
Margin="3, 0, 3, 0"
Content="{x:Static langRes:GeneralLangRes.Public}"
IsChecked="{Binding IsPublic}"/>
</StackPanel>
</DataTemplate>
<DataTemplate
DataType="mainWindow:MainWindowTreeNode"/>
</ContentControl.DataTemplates>
</ContentControl>
<!-- Progress -->
<Panel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsVisible="{Binding Progress.Visible}">
<!-- ProgressBar: Status -->
<ProgressBar
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Maximum="{Binding Progress.MaxValue}"
Value="{Binding Progress.Value}"/>
<!-- TextBox: Status -->
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextAlignment="Center"
Text="{Binding Progress.Text}"/>
</Panel>
</StackPanel>
<!-- DataGrid -->
<DataGrid
@@ -155,7 +184,7 @@
VerticalAlignment="Stretch"
ItemsSource="{Binding CurrentGridRows}"
SelectedItem="{Binding SelectedGridRow}">
<DataGrid.Columns>
<DataGridTextColumn
Header="{x:Static langRes:GeneralLangRes.Id}"
@@ -177,6 +206,18 @@
<DataGridTextColumn
Header="{x:Static langRes:GeneralLangRes.DestinationPath}"
Binding="{Binding InheritedDestPath}"/>
<DataGridTemplateColumn
Header="{x:Static langRes:GeneralLangRes.State}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image
Width="{x:Static symbols:SymbolGlobals.DefaultImageSmallSize}"
Source="{Binding StateImage}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

View File

@@ -1,4 +1,5 @@
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.Media;
using ModpackUpdater.Apps.Manager.Api;
@@ -22,6 +23,7 @@ public partial class MainWindow : Window, IMainApi
public MainWindowViewModel Model { get; } = new();
Window IMainApi.MainWindow => this;
public IMainApi MainApi => this;
public bool HasClosed { get; private set; }
public MainWindow()
{
@@ -110,6 +112,11 @@ public partial class MainWindow : Window, IMainApi
LoadRecentWorkspaces();
}
private void Window_OnClosed(object? sender, EventArgs e)
{
HasClosed = true;
}
private async void MenuItemNewWorkspaceItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is not MenuItem item || item.Tag is not WorkspaceFeature feature)

View File

@@ -1,4 +1,5 @@
using System.ComponentModel;
using Avalonia.Media;
using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Utils;
using PropertyChanged;
@@ -18,7 +19,7 @@ public class MainWindowGridRow(InstallAction action, IActionSet baseActions) : I
private InstallAction Inherited => Base ?? action;
public bool IsUpdate => action is UpdateAction;
public bool? IsValid { get; set; } = null;
public IImage? StateImage { get; set; }
[DependsOn(nameof(Id), nameof(InheritFrom))]
public string? InheritedId => action is UpdateAction ua && !string.IsNullOrWhiteSpace(ua.InheritFrom) ? ua.InheritFrom : action.Id;

View File

@@ -16,7 +16,7 @@ public class MainWindowViewModel : INotifyPropertyChanged
private IWorkspace? currentWorkspace;
public bool IsUpdate => selectedTreeNode is ActionSetTreeNode node && node.Infos is UpdateInfo;
public ProgressInfos Progress { get; } = new();
public MainWindowGridRow? SelectedGridRow { get; set; }
[AlsoNotifyFor(nameof(CurrentTreeNodes))]

View File

@@ -0,0 +1,15 @@
using System.ComponentModel;
using PropertyChanged;
namespace ModpackUpdater.Apps.Manager.Ui.Models;
public class ProgressInfos : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public bool Visible { get; set; }
public double MaxValue { get; set; }
public double Value { get; set; }
[DependsOn(nameof(Value), nameof(MaxValue))]
public string? Text => $"{Math.Round(Value / MaxValue * 100)}%";
}

View File

@@ -7,12 +7,8 @@ namespace ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
public class UpdatesCollectorViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public bool ProgressVisible { get; set; }
public double ProgressMaxValue { get; set; }
public double ProgressValue { get; set; }
[DependsOn(nameof(ProgressValue), nameof(ProgressMaxValue))]
public string? ProgressText => $"{Math.Round(ProgressValue / ProgressMaxValue * 100)}%";
public ProgressInfos Progress { get; } = new();
public string? SearchText { get; set; }
public ObservableCollection<ModUpdateInfo> Updates { get; } = [];
}

View File

@@ -85,20 +85,20 @@
<Panel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsVisible="{Binding ProgressVisible}">
IsVisible="{Binding Progress.Visible}">
<!-- ProgressBar: Status -->
<ProgressBar
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Maximum="{Binding ProgressMaxValue}"
Value="{Binding ProgressValue}"/>
Maximum="{Binding Progress.MaxValue}"
Value="{Binding Progress.Value}"/>
<!-- TextBox: Status -->
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding ProgressText}"/>
Text="{Binding Progress.Text}"/>
</Panel>
</dialogs:AvaloniaFlyoutBase.FooterContent>
</dialogs:AvaloniaFlyoutBase>

View File

@@ -25,14 +25,15 @@ public partial class UpdatesCollectorView : AvaloniaFlyoutBase
private async Task FindUpdates()
{
Model.ProgressVisible = true;
Model.ProgressMaxValue = actions.Length;
Model.Progress.Value = 0;
Model.Progress.MaxValue = actions.Length;
Model.Progress.Visible = true;
foreach (var action in actions)
{
var updates = await factory.FindUpdates(action, workspace.ModpackConfig?.MinecraftVersion, workspace.ModpackConfig?.ModLoader ?? ModLoader.Any);
Model.ProgressValue += 1;
Model.Progress.Value += 1;
if (updates == null || updates.Length == 0 || updates[0].Value == action.SourceTag)
continue;
@@ -43,7 +44,7 @@ public partial class UpdatesCollectorView : AvaloniaFlyoutBase
break;
}
Model.ProgressVisible = false;
Model.Progress.Visible = false;
}
protected override object GetResult()