From b12d92783917a005688e8f1bf04d3149de479a3f Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Fri, 5 Nov 2021 05:47:14 -0600 Subject: [PATCH 1/3] A few compiler fixes --- .../Extensions/IObservableExtensions.cs | 20 +++++++++++++++++++ .../Screens/CompilerConfigurationView.axaml | 2 +- .../CompilerConfigurationView.axaml.cs | 16 +++++++-------- .../Screens/CompilerConfigurationViewModel.cs | 3 +++ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Wabbajack.App/Extensions/IObservableExtensions.cs b/Wabbajack.App/Extensions/IObservableExtensions.cs index c28f9bf6..67fb134e 100644 --- a/Wabbajack.App/Extensions/IObservableExtensions.cs +++ b/Wabbajack.App/Extensions/IObservableExtensions.cs @@ -6,6 +6,8 @@ using System.Reactive.Subjects; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Syntax; using ReactiveUI; +using Wabbajack.App.Controls; +using Wabbajack.Paths; namespace Wabbajack.App.Extensions; @@ -40,4 +42,22 @@ public static class IObservableExtensions return Disposable.Create(() => d.Dispose()); } + + public static IDisposable BindFileSelectionBox(this FileSelectionBox box, TViewModel viewModel, + Expression> vmProperty) + where TViewModel: class? + { + var disposables = new CompositeDisposable(); + + box.WhenAnyValue(view => view.SelectedPath) + .BindTo(viewModel, vmProperty) + .DisposeWith(disposables); + + viewModel.WhenAnyValue(vmProperty) + .Where(p => p != default) + .Subscribe(box.Load) + .DisposeWith(disposables); + + return disposables; + } } \ No newline at end of file diff --git a/Wabbajack.App/Screens/CompilerConfigurationView.axaml b/Wabbajack.App/Screens/CompilerConfigurationView.axaml index 4ababa55..470eb86a 100644 --- a/Wabbajack.App/Screens/CompilerConfigurationView.axaml +++ b/Wabbajack.App/Screens/CompilerConfigurationView.axaml @@ -6,7 +6,7 @@ xmlns:i="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:controls="clr-namespace:Wabbajack.App.Controls" x:Class="Wabbajack.App.Screens.CompilerConfigurationView"> - + Compiler Configuration diff --git a/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs b/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs index ecb150f8..191ee1a5 100644 --- a/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs +++ b/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs @@ -7,6 +7,7 @@ using Avalonia.Interactivity; using Avalonia.Threading; using ReactiveUI; using Wabbajack.App.Controls; +using Wabbajack.App.Extensions; using Wabbajack.App.Views; using Wabbajack.Common; using Wabbajack.Paths; @@ -22,22 +23,19 @@ public partial class CompilerConfigurationView : ScreenBase { - this.Bind(ViewModel, vm => vm.SettingsFile, view => view.SettingsFile.SelectedPath) - .DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.Title, view => view.Title.Text) .DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.SettingsFile, view => view.SettingsFile.SelectedPath) + SettingsFile.BindFileSelectionBox(ViewModel, vm => vm.SettingsFile) .DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.Source, view => view.Source.SelectedPath) + Source.BindFileSelectionBox(ViewModel, vm => vm.Source) + .DisposeWith(disposables); + + DownloadsFolder.BindFileSelectionBox(ViewModel, vm => vm.Downloads) .DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.Downloads, view => view.DownloadsFolder.SelectedPath) - .DisposeWith(disposables); - - this.Bind(ViewModel, vm => vm.OutputFolder, view => view.OutputFolder.SelectedPath) + OutputFolder.BindFileSelectionBox(ViewModel, vm => vm.OutputFolder) .DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.AllGames, view => view.BaseGame.Items) diff --git a/Wabbajack.App/Screens/CompilerConfigurationViewModel.cs b/Wabbajack.App/Screens/CompilerConfigurationViewModel.cs index e560c472..b60850f6 100644 --- a/Wabbajack.App/Screens/CompilerConfigurationViewModel.cs +++ b/Wabbajack.App/Screens/CompilerConfigurationViewModel.cs @@ -102,6 +102,7 @@ public class CompilerConfigurationViewModel : ViewModelBase { return new MO2CompilerSettings { + ModListName = Title, Downloads = Downloads, Source = Source, Game = BaseGame.Game, @@ -157,6 +158,7 @@ public class CompilerConfigurationViewModel : ViewModelBase var data = iniFile.LoadIniFile(); var generalModData = data["General"]; + AlwaysEnabled = Array.Empty(); if ((generalModData["notes"]?.Contains("WABBAJACK_ALWAYS_ENABLE") ?? false) || (generalModData["comments"]?.Contains("WABBAJACK_ALWAYS_ENABLE") ?? false)) AlwaysEnabled = AlwaysEnabled.Append(modFolder.RelativeTo(mo2Folder)).ToArray(); @@ -195,6 +197,7 @@ public class CompilerConfigurationViewModel : ViewModelBase throw new NotImplementedException(); } + Title = s.ModListName; Source = s.Source; Downloads = s.Downloads; OutputFolder = s.OutputFile.Depth > 1 ? s.OutputFile.Parent : s.OutputFile; From cec652864ee528f33ecf5114d419101c3311549f Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Fri, 5 Nov 2021 16:58:08 -0600 Subject: [PATCH 2/3] Add other profiles --- .../Screens/CompilerConfigurationView.axaml | 27 ++++++++++++++-- .../CompilerConfigurationView.axaml.cs | 20 ++++++++++++ .../Screens/CompilerConfigurationViewModel.cs | 31 +++++++++++++++++-- Wabbajack.Compiler/MO2CompilerSettings.cs | 1 + 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/Wabbajack.App/Screens/CompilerConfigurationView.axaml b/Wabbajack.App/Screens/CompilerConfigurationView.axaml index 470eb86a..8c6de53c 100644 --- a/Wabbajack.App/Screens/CompilerConfigurationView.axaml +++ b/Wabbajack.App/Screens/CompilerConfigurationView.axaml @@ -8,7 +8,7 @@ x:Class="Wabbajack.App.Screens.CompilerConfigurationView"> Compiler Configuration - @@ -29,9 +29,28 @@ - - + + + + + + + + + + + + + + + + + + + @@ -48,6 +67,8 @@ + + diff --git a/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs b/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs index 191ee1a5..64cc85dd 100644 --- a/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs +++ b/Wabbajack.App/Screens/CompilerConfigurationView.axaml.cs @@ -20,6 +20,7 @@ public partial class CompilerConfigurationView : ScreenBase AddAlwaysEnabled_Command().FireAndForget()); + AddOtherProfile.Command = ReactiveCommand.Create(() => AddOtherProfile_Command().FireAndForget()); this.WhenActivated(disposables => { @@ -54,8 +55,27 @@ public partial class CompilerConfigurationView : ScreenBase { ViewModel?.RemoveAlwaysExcluded(itm); }) })) .DisposeWith(disposables); + + this.OneWayBind(ViewModel, vm => vm.OtherProfiles, view => view.OtherProfilesList.Items, + d => d!.Select(itm => new RemovableItemViewModel + { + Text = itm.ToString(), + DeleteCommand = ReactiveCommand.Create(() => { ViewModel?.RemoveOtherProfile(itm); }) + })) + .DisposeWith(disposables); }); } + + private async Task AddOtherProfile_Command() + { + var dialog = new OpenFolderDialog + { + Title = "Select a profile folder" + }; + var result = await dialog.ShowAsync(App.MainWindow); + if (!string.IsNullOrWhiteSpace(result)) + ViewModel!.AddOtherProfile(result.ToAbsolutePath()); + } private async Task AddAlwaysEnabled_Command() { diff --git a/Wabbajack.App/Screens/CompilerConfigurationViewModel.cs b/Wabbajack.App/Screens/CompilerConfigurationViewModel.cs index b60850f6..e4ffb383 100644 --- a/Wabbajack.App/Screens/CompilerConfigurationViewModel.cs +++ b/Wabbajack.App/Screens/CompilerConfigurationViewModel.cs @@ -71,6 +71,9 @@ public class CompilerConfigurationViewModel : ViewModelBase [Reactive] public IEnumerable AlwaysEnabled { get; set; } = Array.Empty(); + [Reactive] + public string[] OtherProfiles { get; set; } = Array.Empty(); + public AbsolutePath SettingsOutputLocation => Source.Combine(Title) .WithExtension(IsMO2Compilation ? Ext.MO2CompilerSettings : Ext.CompilerSettings); @@ -109,10 +112,24 @@ public class CompilerConfigurationViewModel : ViewModelBase Profile = SelectedProfile, UseGamePaths = true, OutputFile = OutputFolder.Combine(SelectedProfile).WithExtension(Ext.Wabbajack), - AlwaysEnabled = AlwaysEnabled.ToArray() + AlwaysEnabled = AlwaysEnabled.ToArray(), + OtherProfiles = OtherProfiles.ToArray() }; } + public bool AddOtherProfile(AbsolutePath path) + { + if (!path.InFolder(Source.Combine(Consts.MO2Profiles))) return false; + var relative = path.RelativeTo(Source.Combine(Consts.MO2Profiles)).ToString(); + OtherProfiles = OtherProfiles.Append(relative).Distinct().ToArray(); + return true; + } + + public void RemoveOtherProfile(string profile) + { + OtherProfiles = OtherProfiles.Where(p => p != profile).ToArray(); + } + public bool AddAlwaysExcluded(AbsolutePath path) { if (!path.InFolder(Source)) return false; @@ -150,6 +167,8 @@ public class CompilerConfigurationViewModel : ViewModelBase IsMO2Compilation = true; + + AlwaysEnabled = Array.Empty(); // Find Always Enabled mods foreach (var modFolder in mo2Folder.Combine("mods").EnumerateDirectories()) { @@ -158,12 +177,17 @@ public class CompilerConfigurationViewModel : ViewModelBase var data = iniFile.LoadIniFile(); var generalModData = data["General"]; - AlwaysEnabled = Array.Empty(); if ((generalModData["notes"]?.Contains("WABBAJACK_ALWAYS_ENABLE") ?? false) || (generalModData["comments"]?.Contains("WABBAJACK_ALWAYS_ENABLE") ?? false)) AlwaysEnabled = AlwaysEnabled.Append(modFolder.RelativeTo(mo2Folder)).ToArray(); } + var otherProfilesFile = settingsFile.Parent.Combine("otherprofiles.txt"); + if (otherProfilesFile.FileExists()) + { + OtherProfiles = await otherProfilesFile.ReadAllLinesAsync().ToArray(); + } + if (mo2Folder.Depth > 1) OutputFolder = mo2Folder.Parent; @@ -173,6 +197,8 @@ public class CompilerConfigurationViewModel : ViewModelBase } } + + private async Task SaveSettingsFile() { await using var st = SettingsOutputLocation.Open(FileMode.Create, FileAccess.Write, FileShare.None); @@ -189,6 +215,7 @@ public class CompilerConfigurationViewModel : ViewModelBase { var mo2 = await LoadSettingsFile(path); AlwaysEnabled = mo2.AlwaysEnabled; + OtherProfiles = mo2.OtherProfiles; SelectedProfile = mo2.Profile; s = mo2; } diff --git a/Wabbajack.Compiler/MO2CompilerSettings.cs b/Wabbajack.Compiler/MO2CompilerSettings.cs index 2a3bed7c..ce3ac65d 100644 --- a/Wabbajack.Compiler/MO2CompilerSettings.cs +++ b/Wabbajack.Compiler/MO2CompilerSettings.cs @@ -7,4 +7,5 @@ public class MO2CompilerSettings : CompilerSettings { public string Profile { get; set; } = ""; public RelativePath[] AlwaysEnabled { get; set; } = Array.Empty(); + public string[] OtherProfiles { get; set; } } \ No newline at end of file From c9fe3ac62759caa31083ee134a07b1359cd5e050 Mon Sep 17 00:00:00 2001 From: Timothy Baldridge Date: Mon, 8 Nov 2021 06:32:51 -0700 Subject: [PATCH 3/3] Style the play buttons --- Wabbajack.App/Assets/Wabbajack.axaml | 16 ++++++++++++ .../Controls/InstalledListView.axaml | 18 ++++++++----- .../Controls/InstalledListView.axaml.cs | 13 ++++++++-- .../Controls/InstalledListViewModel.cs | 26 ++++++++++++++++++- Wabbajack.App/Controls/LogView.axaml | 25 +++++++----------- Wabbajack.App/Controls/LogView.axaml.cs | 9 +++---- Wabbajack.App/Models/ImageCache.cs | 20 +++++++++++++- Wabbajack.App/Screens/CompilationViewModel.cs | 2 +- Wabbajack.App/Screens/PlaySelectView.axaml | 16 +++++------- Wabbajack.App/Screens/PlaySelectViewModel.cs | 6 +++-- .../SavedSettings/InstallationSettings.cs | 1 + 11 files changed, 108 insertions(+), 44 deletions(-) diff --git a/Wabbajack.App/Assets/Wabbajack.axaml b/Wabbajack.App/Assets/Wabbajack.axaml index 46111d3e..5a080b4c 100644 --- a/Wabbajack.App/Assets/Wabbajack.axaml +++ b/Wabbajack.App/Assets/Wabbajack.axaml @@ -62,6 +62,22 @@ + + + + + + \ No newline at end of file diff --git a/Wabbajack.App/Controls/InstalledListView.axaml b/Wabbajack.App/Controls/InstalledListView.axaml index fd19d10f..fd481324 100644 --- a/Wabbajack.App/Controls/InstalledListView.axaml +++ b/Wabbajack.App/Controls/InstalledListView.axaml @@ -5,11 +5,15 @@ xmlns:i="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Wabbajack.App.Controls.InstalledListView"> - - - - - + \ No newline at end of file diff --git a/Wabbajack.App/Controls/InstalledListView.axaml.cs b/Wabbajack.App/Controls/InstalledListView.axaml.cs index 25e86a64..83ec403a 100644 --- a/Wabbajack.App/Controls/InstalledListView.axaml.cs +++ b/Wabbajack.App/Controls/InstalledListView.axaml.cs @@ -12,14 +12,23 @@ public partial class InstalledListView : ReactiveUserControl { + this.OneWayBind(ViewModel, vm => vm.Image, view => view.ListImage.Source) + .DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.Name, view => view.Title.Text) .DisposeWith(disposables); - this.OneWayBind(ViewModel, vm => vm.InstallPath, view => view.Title.Text, + this.OneWayBind(ViewModel, vm => vm.Author, view => view.Author.Text) + .DisposeWith(disposables); + + this.OneWayBind(ViewModel, vm => vm.Version, view => view.Version.Text) + .DisposeWith(disposables); + + this.OneWayBind(ViewModel, vm => vm.InstallPath, view => view.InstallationPath.Text, p => p.ToString()) .DisposeWith(disposables); - this.BindCommand(ViewModel, vm => vm.Play, view => view.PlayButton) + this.BindCommand(ViewModel, vm => vm.Play, view => view.ListButton) .DisposeWith(disposables); }); } diff --git a/Wabbajack.App/Controls/InstalledListViewModel.cs b/Wabbajack.App/Controls/InstalledListViewModel.cs index 720b7790..0032af1b 100644 --- a/Wabbajack.App/Controls/InstalledListViewModel.cs +++ b/Wabbajack.App/Controls/InstalledListViewModel.cs @@ -1,8 +1,14 @@ using System.Reactive; +using System.Threading.Tasks; +using Avalonia.Media.Imaging; +using Avalonia.Threading; using ReactiveUI; +using ReactiveUI.Fody.Helpers; using Wabbajack.App.Messages; +using Wabbajack.App.Models; using Wabbajack.App.Screens; using Wabbajack.App.ViewModels; +using Wabbajack.Common; using Wabbajack.DTOs.SavedSettings; using Wabbajack.Paths; @@ -12,7 +18,7 @@ public class InstalledListViewModel : ViewModelBase { private readonly InstallationConfigurationSetting _setting; - public InstalledListViewModel(InstallationConfigurationSetting setting) + public InstalledListViewModel(InstallationConfigurationSetting setting, ImageCache imageCache) { Activator = new ViewModelActivator(); _setting = setting; @@ -22,10 +28,28 @@ public class InstalledListViewModel : ViewModelBase MessageBus.Current.SendMessage(new ConfigureLauncher(InstallPath)); MessageBus.Current.SendMessage(new NavigateTo(typeof(LauncherViewModel))); }); + + LoadImage(imageCache).FireAndForget(); + } + + public async Task LoadImage(ImageCache cache) + { + var img = await cache.From(_setting.Install.Combine("modlist-image.png"), 270, 150); + Dispatcher.UIThread.Post(() => + { + Image = img; + }); } public AbsolutePath InstallPath => _setting.Install; public string Name => _setting.Metadata?.Title ?? ""; + + public string Version => _setting.Metadata?.Version?.ToString() ?? ""; + + public string Author => _setting.Metadata?.Author ?? ""; public ReactiveCommand Play { get; } + + [Reactive] + public IBitmap Image { get; set; } } \ No newline at end of file diff --git a/Wabbajack.App/Controls/LogView.axaml b/Wabbajack.App/Controls/LogView.axaml index a59ad25a..602bc76a 100644 --- a/Wabbajack.App/Controls/LogView.axaml +++ b/Wabbajack.App/Controls/LogView.axaml @@ -9,21 +9,16 @@ Current Log Contents - - - - - - - - - - - - - - + + + + + + + + + +