Start to wire up the picker boxes

This commit is contained in:
Timothy Baldridge 2022-01-05 06:59:30 -07:00 committed by Unnoen
parent 55aa6233a3
commit f75f93086c
No known key found for this signature in database
GPG Key ID: 8F8E42252BA20553
8 changed files with 196 additions and 39 deletions

View File

@ -6,6 +6,7 @@ namespace Wabbajack;
public static class Consts
{
public static RelativePath MO2IniName = "ModOrganizer.ini".ToRelativePath();
public static string AppName = "Wabbajack";
public static Uri WabbajackBuildServerUri => new("https://build.wabbajack.org");
public static Version CurrentMinimumWabbajackVersion { get; set; } = Version.Parse("2.3.0.0");

View File

@ -87,14 +87,6 @@ namespace Wabbajack
public bool AutomaticallyOverrideExistingInstall { get; set; }
}
[JsonName("CompilerSettings")]
public class CompilerSettings
{
public ModManager LastCompiledModManager { get; set; }
public AbsolutePath OutputLocation { get; set; }
public MO2CompilationSettings MO2Compilation { get; } = new MO2CompilationSettings();
}
[JsonName("FiltersSettings")]
[JsonObject(MemberSerialization.OptOut)]
public class FiltersSettings : ViewModel

View File

@ -1,5 +1,7 @@
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reactive;
using System.Windows.Media.Imaging;
using Microsoft.Extensions.Logging;
@ -10,16 +12,167 @@ using Wabbajack.RateLimiter;
using ReactiveUI;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Media;
using DynamicData.Binding;
using ReactiveUI.Fody.Helpers;
using Wabbajack.Common;
using Wabbajack.Compiler;
using Wabbajack.DTOs;
using Wabbajack.DTOs.Interventions;
using Wabbajack.DTOs.JsonConverters;
using Wabbajack.Installer;
using Wabbajack.Paths;
using Wabbajack.Paths.IO;
namespace Wabbajack
{
public enum CompilerState
{
Configuration,
Compiling,
Completed,
Errored
}
public class CompilerVM : BackNavigatingVM
{
public CompilerVM(ILogger<CompilerVM> logger) : base(logger)
private readonly DTOSerializer _dtos;
[Reactive]
public CompilerState State { get; set; }
[Reactive]
public ISubCompilerVM SubCompilerVM { get; set; }
// Paths
public FilePickerVM ModlistLocation { get; } = new();
public FilePickerVM DownloadLocation { get; } = new();
public FilePickerVM OutputLocation { get; } = new();
// Modlist Settings
[Reactive] public string ModListName { get; set; }
[Reactive] public string Version { get; set; }
[Reactive] public string Author { get; set; }
[Reactive] public string Description { get; set; }
public FilePickerVM ModListImagePath { get; } = new();
[Reactive] public ImageSource ModListImage { get; set; }
[Reactive] public string Website { get; set; }
[Reactive] public string Readme { get; set; }
[Reactive] public bool IsNSFW { get; set; }
[Reactive] public bool PublishUpdate { get; set; }
[Reactive] public string MachineUrl { get; set; }
[Reactive] public Game BaseGame { get; set; }
[Reactive] public string SelectedProfile { get; set; }
[Reactive] public AbsolutePath GamePath { get; set; }
[Reactive] public bool IsMO2Compilation { get; set; }
[Reactive] public RelativePath[] AlwaysEnabled { get; set; }
[Reactive] public string[] OtherProfiles { get; set; }
[Reactive] public AbsolutePath Source { get; set; }
public AbsolutePath SettingsOutputLocation => ModlistLocation.TargetPath.Combine(ModListName)
.WithExtension(IsMO2Compilation ? Ext.MO2CompilerSettings : Ext.CompilerSettings);
public CompilerVM(ILogger<CompilerVM> logger, DTOSerializer dtos) : base(logger)
{
_dtos = dtos;
SubCompilerVM = new MO2CompilerVM(this);
this.WhenActivated(disposables =>
{
State = CompilerState.Configuration;
Disposable.Empty.DisposeWith(disposables);
ModlistLocation.WhenAnyValue(vm => vm.TargetPath)
.Subscribe(p => InferModListFromLocation(p).FireAndForget())
.DisposeWith(disposables);
});
}
private async Task InferModListFromLocation(AbsolutePath settingsFile)
{
using var ll = LoadingLock.WithLoading();
if (settingsFile.FileName == "modlist.txt".ToRelativePath() && settingsFile.Depth > 3)
{
var mo2Folder = settingsFile.Parent.Parent.Parent;
var mo2Ini = mo2Folder.Combine(Consts.MO2IniName);
if (mo2Ini.FileExists())
{
var iniData = mo2Ini.LoadIniFile();
var general = iniData["General"];
BaseGame = GameRegistry.GetByFuzzyName(general["gameName"].FromMO2Ini()).Game;
Source = mo2Folder;
SelectedProfile = general["selected_profile"].FromMO2Ini();
GamePath = general["gamePath"].FromMO2Ini().ToAbsolutePath();
ModListName = SelectedProfile;
var settings = iniData["Settings"];
DownloadLocation.TargetPath = settings["download_directory"].FromMO2Ini().ToAbsolutePath();
IsMO2Compilation = true;
AlwaysEnabled = Array.Empty<RelativePath>();
// Find Always Enabled mods
foreach (var modFolder in mo2Folder.Combine("mods").EnumerateDirectories())
{
var iniFile = modFolder.Combine("meta.ini");
if (!iniFile.FileExists()) continue;
var data = iniFile.LoadIniFile();
var generalModData = data["General"];
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)
OutputLocation.TargetPath = mo2Folder.Parent;
await SaveSettingsFile();
ModlistLocation.TargetPath = SettingsOutputLocation;
}
}
}
private async Task SaveSettingsFile()
{
await using var st = SettingsOutputLocation.Open(FileMode.Create, FileAccess.Write, FileShare.None);
if (IsMO2Compilation)
await JsonSerializer.SerializeAsync(st, (MO2CompilerSettings) GetSettings(), _dtos.Options);
else
await JsonSerializer.SerializeAsync(st, GetSettings(), _dtos.Options);
}
private CompilerSettings GetSettings()
{
return new CompilerSettings
{
ModListName = ModListName,
ModListAuthor = Author,
Downloads = DownloadLocation.TargetPath,
Source = ModlistLocation.TargetPath,
Game = BaseGame,
Profile = SelectedProfile,
UseGamePaths = true,
OutputFile = OutputLocation.TargetPath.Combine(SelectedProfile).WithExtension(Ext.Wabbajack),
AlwaysEnabled = AlwaysEnabled.ToArray(),
OtherProfiles = OtherProfiles.ToArray()
};
}
}
}

View File

@ -166,31 +166,7 @@
<ColumnDefinition Width="20" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.RowSpan="5" Grid.Column="0"
Margin="15"
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:ImageRadioButtonView Grid.Row="0"
x:Name="MO2CompilerButton"
Height="35"
Margin="4"
IsChecked="{Binding SelectedCompilerType, Converter={StaticResource EqualsToBoolConverter}, ConverterParameter={x:Static local:ModManager.Standard}}">
<local:ImageRadioButtonView.Image>
<BitmapImage UriSource="../../Resources/MO2Button.png" />
</local:ImageRadioButtonView.Image>
</local:ImageRadioButtonView>
</Grid>
<ContentPresenter Grid.Row="1" Grid.Column="1"
x:Name="CustomCompilerSettingsPresenter">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type local:MO2CompilerVM}">
<local:MO2CompilerConfigView />
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
<local:MO2CompilerConfigView x:Name="CompilerConfigView" Grid.Row="1" Grid.Column="1" />
<local:BeginButton Grid.Row="0" Grid.RowSpan="3" Grid.Column="5"
x:Name="BeginButton" />
</Grid>

View File

@ -18,6 +18,38 @@ namespace Wabbajack
{
InitializeComponent();
this.WhenActivated(disposables =>
{
ViewModel.WhenAnyValue(vm => vm.State)
.Select(v => v == CompilerState.Configuration ? Visibility.Visible : Visibility.Collapsed)
.BindToStrict(this, view => view.BottomCompilerSettingsGrid.Visibility)
.DisposeWith(disposables);
ViewModel.WhenAnyValue(vm => vm.State)
.Select(v => v != CompilerState.Configuration ? Visibility.Visible : Visibility.Collapsed)
.BindToStrict(this, view => view.LogView.Visibility)
.DisposeWith(disposables);
ViewModel.WhenAnyValue(vm => vm.State)
.Select(v => v == CompilerState.Compiling ? Visibility.Visible : Visibility.Collapsed)
.BindToStrict(this, view => view.CpuView.Visibility)
.DisposeWith(disposables);
ViewModel.WhenAnyValue(vm => vm.State)
.Select(v => v == CompilerState.Completed ? Visibility.Visible : Visibility.Collapsed)
.BindToStrict(this, view => view.CompilationComplete.Visibility)
.DisposeWith(disposables);
ViewModel.WhenAnyValue(vm => vm.ModlistLocation)
.BindToStrict(this, view => view.CompilerConfigView.ModListLocation.PickerVM)
.DisposeWith(disposables);
UserInterventionsControl.Visibility = Visibility.Collapsed;
});
}
}
}

View File

@ -27,11 +27,12 @@
Text="Modlist Location"
TextAlignment="Center"
ToolTip="The MO2 modlist.txt file you want to use as your source" />
<local:FilePicker Grid.Row="0" Grid.Column="2"
<local:FilePicker
x:Name="ModListLocation"
Grid.Row="0" Grid.Column="2"
Height="30"
VerticalAlignment="Center"
FontSize="14"
PickerVM="{Binding ModListLocation}"
ToolTip="The MO2 modlist.txt file you want to use as your source" />
<TextBlock Grid.Row="1" Grid.Column="0"
HorizontalAlignment="Right"

View File

@ -36,4 +36,8 @@ public class CompilerSettings
/// These files are inlined into the modlist
/// </summary>
public RelativePath[] Include { get; set; } = Array.Empty<RelativePath>();
public string Profile { get; set; } = "";
public RelativePath[] AlwaysEnabled { get; set; } = Array.Empty<RelativePath>();
public string[] OtherProfiles { get; set; }
}

View File

@ -5,7 +5,5 @@ namespace Wabbajack.Compiler;
public class MO2CompilerSettings : CompilerSettings
{
public string Profile { get; set; } = "";
public RelativePath[] AlwaysEnabled { get; set; } = Array.Empty<RelativePath>();
public string[] OtherProfiles { get; set; }
}