Merge pull request #211 from Noggog/one-window

One Window.  Few other improvements
This commit is contained in:
Timothy Baldridge 2019-11-24 17:11:42 -07:00 committed by GitHub
commit d072f7edc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 390 additions and 335 deletions

View File

@ -1,8 +0,0 @@
namespace Wabbajack
{
public enum RunMode
{
Compile,
Install
}
}

View File

@ -93,7 +93,6 @@
<Compile Include="Error States\ErrorResponse.cs" /> <Compile Include="Error States\ErrorResponse.cs" />
<Compile Include="Error States\GetResponse.cs" /> <Compile Include="Error States\GetResponse.cs" />
<Compile Include="Enums\ModManager.cs" /> <Compile Include="Enums\ModManager.cs" />
<Compile Include="Enums\RunMode.cs" />
<Compile Include="ExtensionManager.cs" /> <Compile Include="ExtensionManager.cs" />
<Compile Include="Extensions\DictionaryExt.cs" /> <Compile Include="Extensions\DictionaryExt.cs" />
<Compile Include="Extensions\EnumExt.cs" /> <Compile Include="Extensions\EnumExt.cs" />

View File

@ -1,8 +1,10 @@
<Application x:Class="Wabbajack.App" <Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x:Class="Wabbajack.App"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:Wabbajack" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ShutdownMode="OnExplicitShutdown"> xmlns:local="clr-namespace:Wabbajack"
ShutdownMode="OnExplicitShutdown"
StartupUri="Views\MainWindow.xaml">
<Application.Resources> <Application.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>

View File

@ -25,13 +25,6 @@ namespace Wabbajack
{ {
ExtensionManager.Associate(appPath); ExtensionManager.Associate(appPath);
} }
string[] args = Environment.GetCommandLineArgs();
StartupUri = new Uri("Views/ModeSelectionWindow.xaml", UriKind.Relative);
if (args.Length != 3) return;
if (!args[1].Contains("-i")) return;
// modlists gets loaded using a shell command
StartupUri = new Uri("Views/MainWindow.xaml", UriKind.Relative);
} }
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -102,7 +102,7 @@
<SolidColorBrush x:Key="PressedButtonBackground" Color="{StaticResource PressedBackgroundColor}" /> <SolidColorBrush x:Key="PressedButtonBackground" Color="{StaticResource PressedBackgroundColor}" />
<SolidColorBrush x:Key="MouseOverButtonBackground" Color="{StaticResource LightBackgroundColor}" /> <SolidColorBrush x:Key="MouseOverButtonBackground" Color="{StaticResource LightBackgroundColor}" />
<SolidColorBrush x:Key="DisabledButtonBackground" Color="{StaticResource LightDisabledBackgroundColor}" /> <SolidColorBrush x:Key="DisabledButtonBackground" Color="{StaticResource LightDisabledBackgroundColor}" />
<SolidColorBrush x:Key="DisabledButtonForeground" Color="{StaticResource DisabledBackgroundColor}" /> <SolidColorBrush x:Key="DisabledButtonForeground" Color="#FF7E7E7E" />
<SolidColorBrush x:Key="Expander.Background" Color="{StaticResource LightBackgroundColor}" /> <SolidColorBrush x:Key="Expander.Background" Color="{StaticResource LightBackgroundColor}" />
<SolidColorBrush x:Key="Expander.MouseOver.Arrow.Stroke" Color="{StaticResource ForegroundColor}" /> <SolidColorBrush x:Key="Expander.MouseOver.Arrow.Stroke" Color="{StaticResource ForegroundColor}" />
@ -1462,6 +1462,11 @@
BasedOn="{StaticResource MahApps.Metro.Styles.MetroCircleButtonStyle}" BasedOn="{StaticResource MahApps.Metro.Styles.MetroCircleButtonStyle}"
TargetType="ButtonBase"> TargetType="ButtonBase">
<Setter Property="Focusable" Value="False" /> <Setter Property="Focusable" Value="False" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource DisabledButtonForeground}" />
</Trigger>
</Style.Triggers>
</Style> </Style>
<!-- ToggleButton --> <!-- ToggleButton -->

View File

@ -40,6 +40,8 @@ namespace Wabbajack
public ObservableCollectionExtended<CPUStatus> StatusList { get; } = new ObservableCollectionExtended<CPUStatus>(); public ObservableCollectionExtended<CPUStatus> StatusList { get; } = new ObservableCollectionExtended<CPUStatus>();
public ObservableCollectionExtended<string> Log => MWVM.Log; public ObservableCollectionExtended<string> Log => MWVM.Log;
public IReactiveCommand BackCommand { get; }
public CompilerVM(MainWindowVM mainWindowVM) public CompilerVM(MainWindowVM mainWindowVM)
{ {
MWVM = mainWindowVM; MWVM = mainWindowVM;
@ -107,6 +109,11 @@ namespace Wabbajack
.ObserveOnGuiThread() .ObserveOnGuiThread()
.ToProperty(this, nameof(Compiling)); .ToProperty(this, nameof(Compiling));
BackCommand = ReactiveCommand.Create(
execute: () => mainWindowVM.ActivePane = mainWindowVM.ModeSelectionVM,
canExecute: this.WhenAny(x => x.Compiling)
.Select(x => !x));
// Compile progress updates and populate ObservableCollection // Compile progress updates and populate ObservableCollection
this.WhenAny(x => x.Compiler.ActiveCompilation) this.WhenAny(x => x.Compiler.ActiveCompilation)
.SelectMany(c => c?.QueueStatus ?? Observable.Empty<CPUStatus>()) .SelectMany(c => c?.QueueStatus ?? Observable.Empty<CPUStatus>())

View File

@ -31,8 +31,7 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<ModListVM> _modList; private readonly ObservableAsPropertyHelper<ModListVM> _modList;
public ModListVM ModList => _modList.Value; public ModListVM ModList => _modList.Value;
[Reactive] public FilePickerVM ModListPath { get; }
public string ModListPath { get; set; }
[Reactive] [Reactive]
public bool UIReady { get; set; } public bool UIReady { get; set; }
@ -80,13 +79,17 @@ namespace Wabbajack
public ObservableCollectionExtended<CPUStatus> StatusList { get; } = new ObservableCollectionExtended<CPUStatus>(); public ObservableCollectionExtended<CPUStatus> StatusList { get; } = new ObservableCollectionExtended<CPUStatus>();
public ObservableCollectionExtended<string> Log => MWVM.Log; public ObservableCollectionExtended<string> Log => MWVM.Log;
private readonly ObservableAsPropertyHelper<ModlistInstallationSettings> _CurrentSettings;
public ModlistInstallationSettings CurrentSettings => _CurrentSettings.Value;
// Command properties // Command properties
public IReactiveCommand BeginCommand { get; } public IReactiveCommand BeginCommand { get; }
public IReactiveCommand ShowReportCommand { get; } public IReactiveCommand ShowReportCommand { get; }
public IReactiveCommand OpenReadmeCommand { get; } public IReactiveCommand OpenReadmeCommand { get; }
public IReactiveCommand VisitWebsiteCommand { get; } public IReactiveCommand VisitWebsiteCommand { get; }
public IReactiveCommand BackCommand { get; }
public InstallerVM(MainWindowVM mainWindowVM, string source) public InstallerVM(MainWindowVM mainWindowVM)
{ {
if (Path.GetDirectoryName(Assembly.GetEntryAssembly().Location.ToLower()) == KnownFolders.Downloads.Path.ToLower()) if (Path.GetDirectoryName(Assembly.GetEntryAssembly().Location.ToLower()) == KnownFolders.Downloads.Path.ToLower())
{ {
@ -100,7 +103,6 @@ namespace Wabbajack
} }
MWVM = mainWindowVM; MWVM = mainWindowVM;
ModListPath = source;
Location = new FilePickerVM() Location = new FilePickerVM()
{ {
@ -118,41 +120,39 @@ namespace Wabbajack
}; };
DownloadLocation.AdditionalError = this.WhenAny(x => x.DownloadLocation.TargetPath) DownloadLocation.AdditionalError = this.WhenAny(x => x.DownloadLocation.TargetPath)
.Select(x => Utils.IsDirectoryPathValid(x)); .Select(x => Utils.IsDirectoryPathValid(x));
ModListPath = new FilePickerVM()
{
ExistCheckOption = FilePickerVM.ExistCheckOptions.On,
PathType = FilePickerVM.PathTypeOptions.File,
PromptTitle = "Select a modlist to install"
};
// Load settings // Load settings
ModlistInstallationSettings settings = MWVM.Settings.Installer.ModlistSettings.TryCreate(source); _CurrentSettings = this.WhenAny(x => x.ModListPath.TargetPath)
Location.TargetPath = settings.InstallationLocation; .Select(path => path == null ? null : MWVM.Settings.Installer.ModlistSettings.TryCreate(path))
DownloadLocation.TargetPath = settings.DownloadLocation; .ToProperty(this, nameof(CurrentSettings));
MWVM.Settings.SaveSignal this.WhenAny(x => x.CurrentSettings)
.Subscribe(_ => .Pairwise()
.Subscribe(settingsPair =>
{ {
settings.InstallationLocation = Location.TargetPath; SaveSettings(settingsPair.Previous);
settings.DownloadLocation = DownloadLocation.TargetPath; if (settingsPair.Current == null) return;
Location.TargetPath = settingsPair.Current.InstallationLocation;
DownloadLocation.TargetPath = settingsPair.Current.DownloadLocation;
}) })
.DisposeWith(CompositeDisposable); .DisposeWith(CompositeDisposable);
MWVM.Settings.SaveSignal
.Subscribe(_ => SaveSettings(CurrentSettings))
.DisposeWith(CompositeDisposable);
_modList = this.WhenAny(x => x.ModListPath) _modList = this.WhenAny(x => x.ModListPath.TargetPath)
.ObserveOn(RxApp.TaskpoolScheduler) .ObserveOn(RxApp.TaskpoolScheduler)
.Select(modListPath => .Select(modListPath =>
{ {
if (modListPath == null) return default(ModListVM); if (modListPath == null) return default(ModListVM);
if (!File.Exists(modListPath)) return default(ModListVM);
var modList = AInstaller.LoadFromFile(modListPath); var modList = AInstaller.LoadFromFile(modListPath);
if (modList == null) if (modList == null) return default(ModListVM);
{
MessageBox.Show("Invalid Modlist, or file not found.", "Invalid Modlist", MessageBoxButton.OK,
MessageBoxImage.Error);
Application.Current.Dispatcher.Invoke(() =>
{
MWVM.MainWindow.ExitWhenClosing = false;
var window = new ModeSelectionWindow
{
ShowActivated = true
};
window.Show();
MWVM.MainWindow.Close();
});
return default(ModListVM);
}
return new ModListVM(modList, modListPath); return new ModListVM(modList, modListPath);
}) })
.ObserveOnGuiThread() .ObserveOnGuiThread()
@ -166,6 +166,11 @@ namespace Wabbajack
.ObserveOnGuiThread() .ObserveOnGuiThread()
.ToProperty(this, nameof(Installing)); .ToProperty(this, nameof(Installing));
BackCommand = ReactiveCommand.Create(
execute: () => mainWindowVM.ActivePane = mainWindowVM.ModeSelectionVM,
canExecute: this.WhenAny(x => x.Installing)
.Select(x => !x));
_percentCompleted = this.WhenAny(x => x.ActiveInstallation) _percentCompleted = this.WhenAny(x => x.ActiveInstallation)
.StartWith(default(AInstaller)) .StartWith(default(AInstaller))
.Pairwise() .Pairwise()
@ -292,7 +297,7 @@ namespace Wabbajack
private void OpenReadmeWindow() private void OpenReadmeWindow()
{ {
if (string.IsNullOrEmpty(ModList.Readme)) return; if (string.IsNullOrEmpty(ModList.Readme)) return;
using (var fs = new FileStream(ModListPath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var fs = new FileStream(ModListPath.TargetPath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var ar = new ZipArchive(fs, ZipArchiveMode.Read)) using (var ar = new ZipArchive(fs, ZipArchiveMode.Read))
using (var ms = new MemoryStream()) using (var ms = new MemoryStream())
{ {
@ -322,7 +327,7 @@ namespace Wabbajack
try try
{ {
installer = new MO2Installer(ModListPath, ModList.SourceModList, Location.TargetPath) installer = new MO2Installer(ModListPath.TargetPath, ModList.SourceModList, Location.TargetPath)
{ {
DownloadFolder = DownloadLocation.TargetPath DownloadFolder = DownloadLocation.TargetPath
}; };
@ -361,5 +366,13 @@ namespace Wabbajack
} }
}); });
} }
private void SaveSettings(ModlistInstallationSettings settings)
{
MWVM.Settings.Installer.LastInstalledListLocation = ModListPath.TargetPath;
if (settings == null) return;
settings.InstallationLocation = Location.TargetPath;
settings.DownloadLocation = DownloadLocation.TargetPath;
}
} }
} }

View File

@ -21,24 +21,22 @@ namespace Wabbajack
public MainSettings Settings { get; } public MainSettings Settings { get; }
private readonly ObservableAsPropertyHelper<ViewModel> _activePane; [Reactive]
public ViewModel ActivePane => _activePane.Value; public ViewModel ActivePane { get; set; }
public ObservableCollectionExtended<string> Log { get; } = new ObservableCollectionExtended<string>(); public ObservableCollectionExtended<string> Log { get; } = new ObservableCollectionExtended<string>();
[Reactive] public readonly Lazy<CompilerVM> Compiler;
public RunMode Mode { get; set; } public readonly Lazy<InstallerVM> Installer;
public readonly ModeSelectionVM ModeSelectionVM;
private readonly Lazy<CompilerVM> _compiler; public MainWindowVM(MainWindow mainWindow, MainSettings settings)
private readonly Lazy<InstallerVM> _installer;
public MainWindowVM(RunMode mode, string source, MainWindow mainWindow, MainSettings settings)
{ {
Mode = mode;
MainWindow = mainWindow; MainWindow = mainWindow;
Settings = settings; Settings = settings;
_installer = new Lazy<InstallerVM>(() => new InstallerVM(this, source)); Installer = new Lazy<InstallerVM>(() => new InstallerVM(this));
_compiler = new Lazy<CompilerVM>(() => new CompilerVM(this)); Compiler = new Lazy<CompilerVM>(() => new CompilerVM(this));
ModeSelectionVM = new ModeSelectionVM(this);
// Set up logging // Set up logging
Utils.LogMessages Utils.LogMessages
@ -53,23 +51,29 @@ namespace Wabbajack
.Subscribe() .Subscribe()
.DisposeWith(CompositeDisposable); .DisposeWith(CompositeDisposable);
// Wire mode to drive the active pane. if (IsStartingFromModlist(out var path))
// Note: This is currently made into a derivative property driven by mode, {
// but it can be easily changed into a normal property that can be set from anywhere if needed Installer.Value.ModListPath.TargetPath = path;
_activePane = this.WhenAny(x => x.Mode) ActivePane = Installer.Value;
.Select<RunMode, ViewModel>(m => }
{ else
switch (m) {
{ // Start on mode selection
case RunMode.Compile: ActivePane = ModeSelectionVM;
return _compiler.Value; }
case RunMode.Install: }
return _installer.Value;
default: private static bool IsStartingFromModlist(out string modlistPath)
return default; {
} string[] args = Environment.GetCommandLineArgs();
}) if (args.Length != 3 || !args[1].Contains("-i"))
.ToProperty(this, nameof(ActivePane)); {
modlistPath = default;
return false;
}
modlistPath = args[2];
return true;
} }
} }
} }

View File

@ -1,16 +0,0 @@
using Wabbajack.Lib;
using Wabbajack.Lib.ModListRegistry;
namespace Wabbajack.UI
{
public class ModListDefinition : ViewModel
{
private readonly ModlistMetadata _meta;
public ModListDefinition(ModlistMetadata meta)
{
_meta = meta;
}
}
}

View File

@ -0,0 +1,84 @@
using Alphaleonis.Win32.Filesystem;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Windows.Input;
using Wabbajack.Common;
using Wabbajack.Lib;
using Wabbajack.Lib.ModListRegistry;
namespace Wabbajack
{
public class ModeSelectionVM : ViewModel
{
public ObservableCollection<ModlistMetadata> ModLists { get; } = new ObservableCollection<ModlistMetadata>(ModlistMetadata.LoadFromGithub());
[Reactive]
public ModlistMetadata SelectedModList { get; set; }
private MainWindowVM _mainVM;
public ICommand DownloadAndInstallCommand { get; }
public ICommand InstallCommand { get; }
public ICommand CompileCommand { get; }
public ModeSelectionVM(MainWindowVM mainVM)
{
_mainVM = mainVM;
InstallCommand = ReactiveCommand.Create(
execute: () =>
{
var path = mainVM.Settings.Installer.LastInstalledListLocation;
if (string.IsNullOrWhiteSpace(path)
|| !File.Exists(path))
{
path = UIUtils.OpenFileDialog($"*{ExtensionManager.Extension}|*{ExtensionManager.Extension}");
}
OpenInstaller(path);
});
CompileCommand = ReactiveCommand.Create(
execute: () =>
{
mainVM.ActivePane = mainVM.Compiler.Value;
});
DownloadAndInstallCommand = ReactiveCommand.Create(
canExecute: this.WhenAny(x => x.SelectedModList)
.Select(x => x != null)
.ObserveOnGuiThread(),
execute: () =>
{
OpenInstaller(Download());
});
}
private void OpenInstaller(string path)
{
if (path == null) return;
var installer = _mainVM.Installer.Value;
_mainVM.Settings.Installer.LastInstalledListLocation = path;
_mainVM.ActivePane = installer;
installer.ModListPath.TargetPath = path;
}
private string Download()
{
if (!Directory.Exists(Consts.ModListDownloadFolder))
Directory.CreateDirectory(Consts.ModListDownloadFolder);
string dest = Path.Combine(Consts.ModListDownloadFolder, SelectedModList.Links.MachineURL + ExtensionManager.Extension);
var window = new DownloadWindow(SelectedModList.Links.Download,
SelectedModList.Title,
SelectedModList.Links.DownloadMetadata?.Size ?? 0,
dest);
window.ShowDialog();
if (window.Result == DownloadWindow.WindowResult.Completed)
return dest;
return null;
}
}
}

View File

@ -1,48 +0,0 @@
using Alphaleonis.Win32.Filesystem;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using Wabbajack.Common;
using Wabbajack.Lib;
using Wabbajack.Lib.ModListRegistry;
namespace Wabbajack.UI
{
public class ModeSelectionWindowVM : ViewModel
{
public ObservableCollection<ModlistMetadata> ModLists { get; } = new ObservableCollection<ModlistMetadata>(ModlistMetadata.LoadFromGithub());
[Reactive]
public ModlistMetadata SelectedModList { get; set; }
private readonly ObservableAsPropertyHelper<bool> _canInstall;
public bool CanInstall => _canInstall.Value;
public ModeSelectionWindowVM()
{
_canInstall = this.WhenAny(x => x.SelectedModList)
.Select(x => x != null)
.ToProperty(this, nameof(CanInstall));
}
internal string Download()
{
if (!Directory.Exists(Consts.ModListDownloadFolder))
Directory.CreateDirectory(Consts.ModListDownloadFolder);
string dest = Path.Combine(Consts.ModListDownloadFolder, SelectedModList.Links.MachineURL + ExtensionManager.Extension);
var window = new DownloadWindow(SelectedModList.Links.Download,
SelectedModList.Title,
SelectedModList.Links.DownloadMetadata?.Size ?? 0,
dest);
window.ShowDialog();
if (window.Result == DownloadWindow.WindowResult.Completed)
return dest;
return null;
}
}
}

View File

@ -87,9 +87,9 @@
Value="{Binding ProgressPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" /> Value="{Binding ProgressPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<TextBlock <TextBlock
Grid.Column="0" Grid.Column="0"
Width="90" Width="130"
Margin="10,0,0,8" Margin="0,0,0,0"
VerticalAlignment="Bottom" VerticalAlignment="Center"
FontFamily="Lucida Sans" FontFamily="Lucida Sans"
FontWeight="Black" FontWeight="Black"
Text="{Binding StatePrefixTitle, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" Text="{Binding StatePrefixTitle, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"

View File

@ -3,6 +3,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:icon="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:local="clr-namespace:Wabbajack" xmlns:local="clr-namespace:Wabbajack"
xmlns:mahapps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" xmlns:mahapps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@ -58,6 +59,22 @@
OverhangShadow="True" OverhangShadow="True"
ProgressPercent="{Binding PercentCompleted}" ProgressPercent="{Binding PercentCompleted}"
StatePrefixTitle="Compiling" /> StatePrefixTitle="Compiling" />
<Button
x:Name="BackButton"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="5"
Width="30"
Height="30"
Margin="12,5,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{StaticResource ButtonBackground}"
Command="{Binding BackCommand}"
Style="{StaticResource CircleButtonStyle}"
ToolTip="Back to main menu">
<icon:PackIconMaterial Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Kind="ArrowLeft" />
</Button>
<ScrollViewer <ScrollViewer
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"

View File

@ -1,9 +1,9 @@
<Window x:Class="Wabbajack.UI.DownloadWindow" <Window x:Class="Wabbajack.DownloadWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Wabbajack.UI" xmlns:local="clr-namespace:Wabbajack"
Style="{StaticResource {x:Type Window}}" Icon="../Resources/Icons/wabbajack.ico" WindowStyle="ToolWindow" Style="{StaticResource {x:Type Window}}" Icon="../Resources/Icons/wabbajack.ico" WindowStyle="ToolWindow"
mc:Ignorable="d" mc:Ignorable="d"
Title="Downloading Modlist" Height="200" Width="800"> Title="Downloading Modlist" Height="200" Width="800">

View File

@ -5,7 +5,7 @@ using Wabbajack.Common;
using Wabbajack.Lib; using Wabbajack.Lib;
using Wabbajack.Lib.Downloaders; using Wabbajack.Lib.Downloaders;
namespace Wabbajack.UI namespace Wabbajack
{ {
/// <summary> /// <summary>
/// Interaction logic for DownloadWindow.xaml /// Interaction logic for DownloadWindow.xaml

View File

@ -216,6 +216,21 @@
Kind="TimesCircleSolid" /> Kind="TimesCircleSolid" />
</Button>--> </Button>-->
</local:TopProgressView> </local:TopProgressView>
<Button
x:Name="BackButton"
Grid.Row="0"
Grid.RowSpan="2"
Width="30"
Height="30"
Margin="7,5,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{StaticResource ButtonBackground}"
Command="{Binding BackCommand}"
Style="{StaticResource CircleButtonStyle}"
ToolTip="Back to main menu">
<icon:PackIconMaterial Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Kind="ArrowLeft" />
</Button>
<!-- Bottom Area --> <!-- Bottom Area -->
<Grid <Grid
Grid.Row="2" Grid.Row="2"
@ -286,6 +301,7 @@
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="40" /> <RowDefinition Height="40" />
<RowDefinition Height="40" /> <RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock <TextBlock
@ -294,14 +310,14 @@
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalAlignment="Center" VerticalAlignment="Center"
FontSize="14" FontSize="14"
Text="Installation Location" Text="Target Modlist"
TextAlignment="Center" /> TextAlignment="Center" />
<local:FilePicker <local:FilePicker
Grid.Row="1" Grid.Row="1"
Grid.Column="2" Grid.Column="2"
Height="30" Height="30"
VerticalAlignment="Center" VerticalAlignment="Center"
DataContext="{Binding Location}" DataContext="{Binding ModListPath}"
FontSize="14" /> FontSize="14" />
<TextBlock <TextBlock
Grid.Row="2" Grid.Row="2"
@ -309,18 +325,33 @@
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalAlignment="Center" VerticalAlignment="Center"
FontSize="14" FontSize="14"
Text="Download Location" Text="Installation Location"
TextAlignment="Center" /> TextAlignment="Center" />
<local:FilePicker <local:FilePicker
Grid.Row="2" Grid.Row="2"
Grid.Column="2" Grid.Column="2"
Height="30" Height="30"
VerticalAlignment="Center" VerticalAlignment="Center"
DataContext="{Binding Location}"
FontSize="14" />
<TextBlock
Grid.Row="3"
Grid.Column="0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontSize="14"
Text="Download Location"
TextAlignment="Center" />
<local:FilePicker
Grid.Row="3"
Grid.Column="2"
Height="30"
VerticalAlignment="Center"
DataContext="{Binding DownloadLocation}" DataContext="{Binding DownloadLocation}"
FontSize="14" /> FontSize="14" />
<local:BeginButton <local:BeginButton
Grid.Row="1" Grid.Row="1"
Grid.RowSpan="2" Grid.RowSpan="3"
Grid.Column="4" Grid.Column="4"
Margin="0,0,25,0" Margin="0,0,25,0"
HorizontalAlignment="Right" HorizontalAlignment="Right"

View File

@ -0,0 +1,34 @@
<UserControl
x:Class="Wabbajack.LinksView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wabbajack"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="Image">
<Setter Property="Margin" Value="5" />
</Style>
</Grid.Resources>
<Image
Name="GitHub"
Grid.Column="0"
MouseLeftButtonDown="GitHub_MouseLeftButtonDown" Source="../Resources/Icons/github.png"/>
<Image
Name="Patreon"
Grid.Column="1"
MouseLeftButtonDown="Patreon_MouseLeftButtonDown" Source="../Resources/Icons/patreon.png"/>
<Image
Name="Discord"
Grid.Column="2"
MouseLeftButtonDown="Discord_MouseLeftButtonDown"
Source="../Resources/Icons/discord.png" />
</Grid>
</UserControl>

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Wabbajack
{
/// <summary>
/// Interaction logic for LinksView.xaml
/// </summary>
public partial class LinksView : UserControl
{
public LinksView()
{
InitializeComponent();
}
private void GitHub_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Process.Start("https://github.com/wabbajack-tools/wabbajack");
}
private void Patreon_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Process.Start("https://www.patreon.com/user?u=11907933");
}
private void Discord_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Process.Start("https://discord.gg/zgbrkmA");
}
}
}

View File

@ -26,6 +26,9 @@
<DataTemplate DataType="{x:Type local:InstallerVM}"> <DataTemplate DataType="{x:Type local:InstallerVM}">
<local:InstallationView /> <local:InstallationView />
</DataTemplate> </DataTemplate>
<DataTemplate DataType="{x:Type local:ModeSelectionVM}">
<local:ModeSelectionView />
</DataTemplate>
</ContentPresenter.Resources> </ContentPresenter.Resources>
</ContentPresenter> </ContentPresenter>
</Window> </Window>

View File

@ -16,26 +16,10 @@ namespace Wabbajack
public MainWindow() public MainWindow()
{ {
string[] args = Environment.GetCommandLineArgs();
if (args.Length != 3) return;
var modlistPath = args[2];
_settings = MainSettings.LoadSettings(); _settings = MainSettings.LoadSettings();
Initialize(RunMode.Install, modlistPath, _settings); _mwvm = new MainWindowVM(this, _settings);
}
public MainWindow(RunMode mode, string source, MainSettings settings)
{
Initialize(mode, source, settings);
}
private void Initialize(RunMode mode, string source, MainSettings settings)
{
InitializeComponent();
_settings = settings;
_mwvm = new MainWindowVM(mode, source, this, settings);
Utils.Log($"Wabbajack Build - {ThisAssembly.Git.Sha}");
DataContext = _mwvm; DataContext = _mwvm;
Utils.Log($"Wabbajack Build - {ThisAssembly.Git.Sha}");
} }
internal bool ExitWhenClosing = true; internal bool ExitWhenClosing = true;

View File

@ -1,62 +1,36 @@
<Window <UserControl
x:Class="Wabbajack.ModeSelectionWindow" x:Class="Wabbajack.ModeSelectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wabbajack" xmlns:local="clr-namespace:Wabbajack"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="Wabbajack" d:DataContext="{d:DesignInstance local:ModeSelectionVM}"
Width="1024" d:DesignHeight="450"
Height="800" d:DesignWidth="800"
Closing="Close_Window"
Icon="../Resources/Icons/wabbajack.ico"
RenderOptions.BitmapScalingMode="HighQuality"
ResizeMode="CanResize"
Style="{StaticResource {x:Type Window}}"
UseLayoutRounding="True"
WindowStyle="ToolWindow"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid Margin="20"> <Grid Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="150" /> <RowDefinition Height="150" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
<RowDefinition Height="70" /> <RowDefinition Height="70" />
<RowDefinition Height="70" /> <RowDefinition Height="70" />
<RowDefinition Height="70" /> <RowDefinition Height="70" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Image
Name="GitHub"
Grid.Row="0"
Grid.Column="0"
Margin="5,0,0,0"
HorizontalAlignment="Right"
MouseLeftButtonDown="GitHub_MouseLeftButtonDown" />
<Image
Name="Patreon"
Grid.Row="0"
Grid.Column="1"
Margin="5,0,0,0"
MouseLeftButtonDown="Patreon_MouseLeftButtonDown" />
<Image
Name="Discord"
Grid.Row="0"
Grid.Column="2"
Margin="5,0,0,0"
MouseLeftButtonDown="Discord_MouseLeftButtonDown" />
<Image <Image
Name="Banner" Name="Banner"
Grid.Row="1" Grid.Row="0"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
Margin="2,0,2,0" Margin="2,0,2,0"
Source="../Resources/banner_small_dark.png"
Stretch="Uniform" /> Stretch="Uniform" />
<local:LinksView
Grid.Row="0"
Height="40"
HorizontalAlignment="Right"
VerticalAlignment="Top" />
<ListBox <ListBox
Grid.Row="2" Grid.Row="1"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
ItemsSource="{Binding ModLists}" ItemsSource="{Binding ModLists}"
ScrollViewer.CanContentScroll="False" ScrollViewer.CanContentScroll="False"
@ -77,7 +51,6 @@
<RowDefinition Height="15" /> <RowDefinition Height="15" />
<RowDefinition Height="150" /> <RowDefinition Height="150" />
<RowDefinition Height="20" /> <RowDefinition Height="20" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Image <Image
Grid.Row="0" Grid.Row="0"
@ -114,28 +87,27 @@
</ListBox> </ListBox>
<Button <Button
Name="InstallModlist" Name="InstallModlist"
Grid.Row="3" Grid.Row="2"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
Margin="2" Margin="2"
Click="InstallModlist_Click" Command="{Binding DownloadAndInstallCommand}">
IsEnabled="{Binding CanInstall}">
<TextBlock FontSize="40">Download and Install</TextBlock> <TextBlock FontSize="40">Download and Install</TextBlock>
</Button> </Button>
<Button <Button
Name="InstallFromList" Name="InstallFromList"
Grid.Row="4" Grid.Row="3"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
Margin="2" Margin="2"
Click="InstallFromList_Click"> Command="{Binding InstallCommand}">
<TextBlock FontSize="40">Install from Disk</TextBlock> <TextBlock FontSize="40">Install from Disk</TextBlock>
</Button> </Button>
<Button <Button
Name="CreateModlist" Name="CreateModlist"
Grid.Row="5" Grid.Row="4"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
Margin="2" Margin="2"
Click="CreateModlist_Click"> Command="{Binding CompileCommand}">
<TextBlock FontSize="40">Create a ModList</TextBlock> <TextBlock FontSize="40">Create a ModList</TextBlock>
</Button> </Button>
</Grid> </Grid>
</Window> </UserControl>

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Wabbajack
{
/// <summary>
/// Interaction logic for ModeSelectionView.xaml
/// </summary>
public partial class ModeSelectionView : UserControl
{
public ModeSelectionView()
{
InitializeComponent();
}
}
}

View File

@ -1,97 +0,0 @@
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Input;
using Wabbajack.Common;
using Wabbajack.Lib;
using Wabbajack.UI;
namespace Wabbajack
{
/// <summary>
/// Interaction logic for ModeSelectionWindow.xaml
/// </summary>
public partial class ModeSelectionWindow : Window
{
MainSettings _settings;
public ModeSelectionWindow()
{
InitializeComponent();
var bannerImage = UIUtils.BitmapImageFromResource("Wabbajack.Resources.banner_small_dark.png");
Banner.Source = bannerImage;
var patreonIcon = UIUtils.BitmapImageFromResource("Wabbajack.Resources.Icons.patreon_light.png");
Patreon.Source = patreonIcon;
var githubIcon = UIUtils.BitmapImageFromResource("Wabbajack.Resources.Icons.github_light.png");
GitHub.Source = githubIcon;
var discordIcon = UIUtils.BitmapImageFromResource("Wabbajack.Resources.Icons.discord.png");
Discord.Source = discordIcon;
_settings = MainSettings.LoadSettings();
DataContext = new ModeSelectionWindowVM();
}
private void CreateModlist_Click(object sender, RoutedEventArgs e)
{
ShutdownOnClose = false;
var window = new MainWindow(RunMode.Compile, null, _settings);
window.Left = Left;
window.Top = Top;
window.Show();
Close();
}
private void InstallModlist_Click(object sender, RoutedEventArgs e)
{
var result = ((ModeSelectionWindowVM)DataContext).Download();
if (result != null)
{
OpenMainWindowInstall(result);
}
}
private void InstallFromList_Click(object sender, RoutedEventArgs e)
{
OpenMainWindowInstall(
UIUtils.OpenFileDialog(
$"*{ExtensionManager.Extension}|*{ExtensionManager.Extension}",
initialDirectory: _settings.Installer.LastInstalledListLocation));
}
private void OpenMainWindowInstall(string file)
{
if (file == null) return;
ShutdownOnClose = false;
_settings.Installer.LastInstalledListLocation = Path.GetDirectoryName(file);
var window = new MainWindow(RunMode.Install, file, _settings);
window.Left = Left;
window.Top = Top;
window.Show();
Close();
}
public void Close_Window(object sender, CancelEventArgs e)
{
if (ShutdownOnClose)
Application.Current.Shutdown();
}
public bool ShutdownOnClose { get; set; } = true;
private void GitHub_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Process.Start("https://github.com/wabbajack-tools/wabbajack");
}
private void Patreon_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Process.Start("https://www.patreon.com/user?u=11907933");
}
private void Discord_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Process.Start("https://discord.gg/zgbrkmA");
}
}
}

View File

@ -169,6 +169,12 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="Converters\EqualsToBoolConverter.cs" /> <Compile Include="Converters\EqualsToBoolConverter.cs" />
<Compile Include="Views\LinksView.xaml.cs">
<DependentUpon>LinksView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModeSelectionView.xaml.cs">
<DependentUpon>ModeSelectionView.xaml</DependentUpon>
</Compile>
<Compile Include="View Models\GameVM.cs" /> <Compile Include="View Models\GameVM.cs" />
<Compile Include="Views\Compilers\MO2CompilerConfigView.xaml.cs"> <Compile Include="Views\Compilers\MO2CompilerConfigView.xaml.cs">
<DependentUpon>MO2CompilerConfigView.xaml</DependentUpon> <DependentUpon>MO2CompilerConfigView.xaml</DependentUpon>
@ -208,8 +214,7 @@
<Compile Include="Views\DownloadWindow.xaml.cs"> <Compile Include="Views\DownloadWindow.xaml.cs">
<DependentUpon>DownloadWindow.xaml</DependentUpon> <DependentUpon>DownloadWindow.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="View Models\ModeSelectionWindowVM.cs" /> <Compile Include="View Models\ModeSelectionVM.cs" />
<Compile Include="View Models\ModListDefinition.cs" />
<Compile Include="Views\Common\FilePicker.xaml.cs"> <Compile Include="Views\Common\FilePicker.xaml.cs">
<DependentUpon>FilePicker.xaml</DependentUpon> <DependentUpon>FilePicker.xaml</DependentUpon>
</Compile> </Compile>
@ -221,9 +226,6 @@
<Compile Include="Views\Common\LogCpuView.xaml.cs"> <Compile Include="Views\Common\LogCpuView.xaml.cs">
<DependentUpon>LogCpuView.xaml</DependentUpon> <DependentUpon>LogCpuView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Views\ModeSelectionWindow.xaml.cs">
<DependentUpon>ModeSelectionWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Converters\LeftMarginMultiplierConverter.cs" /> <Compile Include="Converters\LeftMarginMultiplierConverter.cs" />
<Compile Include="Util\TreeViewItemExtensions.cs" /> <Compile Include="Util\TreeViewItemExtensions.cs" />
<Compile Include="View Models\SlideShow.cs" /> <Compile Include="View Models\SlideShow.cs" />
@ -237,6 +239,14 @@
<Compile Include="Views\Compilers\VortexCompilerConfigView.xaml.cs"> <Compile Include="Views\Compilers\VortexCompilerConfigView.xaml.cs">
<DependentUpon>VortexCompilerConfigView.xaml</DependentUpon> <DependentUpon>VortexCompilerConfigView.xaml</DependentUpon>
</Compile> </Compile>
<Page Include="Views\LinksView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ModeSelectionView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Compilers\MO2CompilerConfigView.xaml"> <Page Include="Views\Compilers\MO2CompilerConfigView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@ -295,10 +305,6 @@
<DependentUpon>MainWindow.xaml</DependentUpon> <DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Page Include="Views\ModeSelectionWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\Styles.xaml"> <Page Include="Themes\Styles.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
@ -378,22 +384,16 @@
<EmbeddedResource Include="Resources\banner_small.png" /> <EmbeddedResource Include="Resources\banner_small.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\Icons\discord.png" /> <Resource Include="Resources\Icons\discord.png" />
<EmbeddedResource Include="Resources\Icons\github.png" />
<EmbeddedResource Include="Resources\Icons\patreon.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\Icons\next.png" /> <EmbeddedResource Include="Resources\Icons\next.png" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Icons\github_light.png" />
<EmbeddedResource Include="Resources\Icons\patreon_light.png" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\Banner_Dark.png" /> <EmbeddedResource Include="Resources\Banner_Dark.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\banner_small_dark.png" /> <Resource Include="Resources\banner_small_dark.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AlphaFS"> <PackageReference Include="AlphaFS">
@ -484,5 +484,9 @@
<Resource Include="Resources\Icons\gog.png" /> <Resource Include="Resources\Icons\gog.png" />
<Resource Include="Resources\Icons\steam.png" /> <Resource Include="Resources\Icons\steam.png" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Resource Include="Resources\Icons\github.png" />
<Resource Include="Resources\Icons\patreon.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>