Files
minecraft-modpack-updater/ModpackUpdater.Apps.Manager/Ui/MainWindow.axaml.cs
2025-11-16 22:34:14 +01:00

207 lines
7.8 KiB
C#

using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Media;
using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.Settings;
using ModpackUpdater.Apps.Manager.Ui.Models;
using Pilz.Features;
using Pilz.UI.AvaloniaUI.Features;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class MainWindow : Window, IMainApi
{
public static IImage? ButtonImageAddAction => AppGlobals.Symbols.GetImageSource(AppSymbols.add);
public static IImage? ButtonImageRemoveAction => AppGlobals.Symbols.GetImageSource(AppSymbols.remove);
public MainWindowViewModel Model { get; } = new();
Window IMainApi.MainWindow => this;
public IMainApi MainApi => this;
public MainWindow()
{
DataContext = Model;
InitializeComponent();
ButtonWorkspace.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.workspace);
MenuItemWorkspacePreferences.Icon = AppGlobals.Symbols.GetImage(AppSymbols.settings, SymbolSize.Small);
MenuItemSaveWorkspace.Icon = AppGlobals.Symbols.GetImage(AppSymbols.save, SymbolSize.Small);
MenuItemNewWorkspace.Icon = AppGlobals.Symbols.GetImage(AppSymbols.new_window, SymbolSize.Small);
MenuItemRecentWorkspaces.Icon = AppGlobals.Symbols.GetImage(AppSymbols.time_machine, SymbolSize.Small);
ButtonUpdate.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done);
ButtonTools.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.tools);
MenuItemCreateUpdate.Icon = AppGlobals.Symbols.GetImage(AppSymbols.add, SymbolSize.Small);
MenuItemRemoveUpdate.Icon = AppGlobals.Symbols.GetImage(AppSymbols.remove, SymbolSize.Small);
ImageUpdate.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done);
ImageMetadata.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.show_property);
ImageGeneral.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.normal_screen);
ImageSource.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.input);
ImageDestination.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.output);
PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).InsertItemsTo(MenuItemNewWorkspace.Items,
customClickHandler: MenuItemNewWorkspaceItem_Click,
insertPrioSplitters: true);
var menuFlyoutTools = new MenuFlyout();
ButtonTools.Flyout = menuFlyoutTools;
PluginFeatureController.Instance.Functions.Get(FeatureTypes.Tools).InsertItemsTo(menuFlyoutTools.Items,
customClickHandler: MenuItemToolsItem_Click,
insertPrioSplitters: true);
}
private async Task LoadNewWorkspace(IWorkspace? workspace)
{
if (workspace is null)
return;
if (!await workspace.Load())
{
// Error
return;
}
if (workspace != Model.CurrentWorkspace)
Model.CurrentWorkspace = workspace;
AddToRecentFiles(workspace);
LoadRecentWorkspaces();
}
private void LoadRecentWorkspaces()
{
var settings = Program.Settings.Get<WorkspaceSettings>();
MenuItemRecentWorkspaces.Items.Clear();
settings.Workspaces.ForEach(config =>
{
if (PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).OfType<WorkspaceFeature>().FirstOrDefault(n => n.Identifier == config.ProviderId) is not WorkspaceFeature feature)
return;
var item = new MenuItem
{
Header = config.DisplayText,
Icon = feature.Icon,
DataContext = new MainWindowRecentFilesItem(config, feature),
};
item.Click += MenuItemRecentWorkspaceItem_Click;
MenuItemRecentWorkspaces.Items.Add(item);
});
}
private static void AddToRecentFiles(IWorkspace workspace)
{
var settings = Program.Settings.Get<WorkspaceSettings>();
settings.Workspaces.Remove(workspace.Config);
settings.Workspaces.Insert(0, workspace.Config);
while (settings.Workspaces.Count > 20)
settings.Workspaces.RemoveAt(20);
}
private void Window_OnLoaded(object? sender, RoutedEventArgs e)
{
LoadRecentWorkspaces();
}
private async void MenuItemNewWorkspaceItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is not MenuItem item || item.Tag is not WorkspaceFeature feature)
return;
var context = new WorkspaceContext(MainApi, null);
await feature.Configure(context);
if (context.Workspace != null)
await LoadNewWorkspace(context.Workspace);
}
private async void MenuItemRecentWorkspaceItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is MenuItem item && item.DataContext is MainWindowRecentFilesItem tag && tag.Feature.CreateFromConfig(tag.Config) is IWorkspace workspace)
await LoadNewWorkspace(workspace);
}
private void MenuItemToolsItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is MenuItem item && item.Tag is PluginFunction func)
func.Execute(new MainApiParameters(this));
}
private void MenuItemCreateUpdate_OnClick(object? sender, RoutedEventArgs e)
{
if (Model.CurrentWorkspace?.UpdateInfos is null
|| Model.CurrentTreeNodes?.ElementAtOrDefault(1) is not { } nodeUpdates)
return;
var update = new UpdateInfo
{
Version = new(),
};
Model.CurrentWorkspace.UpdateInfos.Updates.Insert(0, update);
nodeUpdates.Nodes.Insert(0, new ActionSetTreeNode(update));
}
private void MenuItemRemoveUpdate_OnClick(object? sender, RoutedEventArgs e)
{
if (Model.CurrentWorkspace?.UpdateInfos is null
|| Model.CurrentTreeNodes?.ElementAtOrDefault(1) is not { } nodeUpdates
|| Model.SelectedTreeNode is not ActionSetTreeNode nodeUpdate
|| nodeUpdate.Infos is not UpdateInfo update)
return;
nodeUpdates.Nodes.Remove(nodeUpdate);
Model.CurrentWorkspace.UpdateInfos.Updates.Remove(update);
}
private void ButtonAddAction_OnClick(object? sender, RoutedEventArgs e)
{
if (Model.CurrentWorkspace?.InstallInfos is not { } rootInfos
|| Model.SelectedTreeNode is not ActionSetTreeNode nodeUpdate
|| Model.CurrentGridRows is not { } rows)
return;
InstallAction action;
switch (nodeUpdate.Infos)
{
case UpdateInfo updateInfos:
updateInfos.Actions.Add((UpdateAction)(action = new UpdateAction()));
break;
case InstallInfos installInfos:
installInfos.Actions.Add(action = new InstallAction());
break;
default:
return;
}
rows.Add(new MainWindowGridRow(action, rootInfos));
}
private void ButtonRemoveAction_OnClick(object? sender, RoutedEventArgs e)
{
if (Model.SelectedGridRow is not { } row
|| Model.SelectedTreeNode is not ActionSetTreeNode nodeUpdate
|| Model.CurrentGridRows is not { } rows)
return;
switch (nodeUpdate.Infos)
{
case UpdateInfo updateInfos:
if (row.Action is UpdateAction action)
updateInfos.Actions.Remove(action);
break;
case InstallInfos installInfos:
installInfos.Actions.Remove(row.Action);
break;
default:
return;
}
rows.Remove(row);
}
}