Initial Compiler/Installer split for VM and Views

This commit is contained in:
Justin Swanson 2019-10-24 23:26:29 -05:00
parent dcbf3b069f
commit e2ff7efe76
17 changed files with 900 additions and 517 deletions

View File

@ -62,15 +62,36 @@ namespace Wabbajack.Lib
return null;
}
public static BitmapImage BitmapImageFromResource(string name)
public static BitmapImage BitmapImageFromResource(string name) => BitmapImageFromStream(Utils.GetResourceStream(name));
public static BitmapImage BitmapImageFromStream(Stream stream)
{
var img = new BitmapImage();
img.BeginInit();
img.StreamSource = Utils.GetResourceStream(name);
img.StreamSource = stream;
img.EndInit();
return img;
}
public static bool TryGetBitmapImageFromFile(string path, out BitmapImage bitmapImage)
{
try
{
if (!File.Exists(path))
{
bitmapImage = default;
return false;
}
bitmapImage = new BitmapImage(new Uri(path, UriKind.RelativeOrAbsolute));
return true;
}
catch (Exception)
{
bitmapImage = default;
return false;
}
}
public static string OpenFileDialog(string filter)
{
OpenFileDialog ofd = new OpenFileDialog();

View File

@ -3,6 +3,7 @@ using System.Linq;
using System.Linq.Expressions;
using System.Reactive;
using System.Reactive.Linq;
using System.Threading.Tasks;
using DynamicData;
using DynamicData.Kernel;
using ReactiveUI;
@ -92,6 +93,57 @@ namespace Wabbajack
.Unit();
}
public static IObservable<Unit> SelectTask<T>(this IObservable<T> source, Func<T, Task> task)
{
return source
.SelectMany(async i =>
{
await task(i).ConfigureAwait(false);
return System.Reactive.Unit.Default;
});
}
public static IObservable<Unit> SelectTask<T>(this IObservable<T> source, Func<Task> task)
{
return source
.SelectMany(async _ =>
{
await task().ConfigureAwait(false);
return System.Reactive.Unit.Default;
});
}
public static IObservable<R> SelectTask<T, R>(this IObservable<T> source, Func<Task<R>> task)
{
return source
.SelectMany(_ => task());
}
public static IObservable<R> SelectTask<T, R>(this IObservable<T> source, Func<T, Task<R>> task)
{
return source
.SelectMany(x => task(x));
}
public static IObservable<T> DoTask<T>(this IObservable<T> source, Func<T, Task> task)
{
return source
.SelectMany(async (x) =>
{
await task(x).ConfigureAwait(false);
return x;
});
}
public static IObservable<R> WhereCastable<T, R>(this IObservable<T> source)
where R : class
where T : class
{
return source
.Select(x => x as R)
.NotNull();
}
/// These snippets were provided by RolandPheasant (author of DynamicData)
/// They'll be going into the official library at some point, but are here for now.
#region Dynamic Data EnsureUniqueChanges

View File

@ -807,7 +807,7 @@
</Style>
<!-- TextBox -->
<Style BasedOn="{StaticResource {x:Type Control}}" TargetType="{x:Type TextBox}">
<Style x:Key="MainTextBoxStyle" BasedOn="{StaticResource {x:Type Control}}" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="{StaticResource TextBoxBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
@ -852,6 +852,7 @@
</MultiTrigger>-->
</Style.Triggers>
</Style>
<Style BasedOn="{StaticResource MainTextBoxStyle}" TargetType="TextBox" />
<!-- ComboBox -->
<Style x:Key="ComboBoxFocusVisual">

View File

@ -0,0 +1,217 @@
using ReactiveUI;
using Splat;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using Wabbajack.Common;
using Wabbajack.Lib;
namespace Wabbajack
{
public class CompilerVM : ViewModel, IDataErrorInfo
{
public MainWindowVM MWVM { get; }
public RunMode Mode => RunMode.Compile;
private string _Mo2Folder;
public string Mo2Folder { get => _Mo2Folder; set => this.RaiseAndSetIfChanged(ref _Mo2Folder, value); }
private string _ModListName;
public string ModListName { get => _ModListName; set => this.RaiseAndSetIfChanged(ref _ModListName, value); }
private string _Location;
public string Location { get => _Location; set => this.RaiseAndSetIfChanged(ref _Location, value); }
private bool _UIReady = true;
public bool UIReady { get => _UIReady; set => this.RaiseAndSetIfChanged(ref _UIReady, value); }
private string _ModName;
public string ModName { get => _ModName; set => this.RaiseAndSetIfChanged(ref _ModName, value); }
private string _AuthorName;
public string AuthorName { get => _AuthorName; set => this.RaiseAndSetIfChanged(ref _AuthorName, value); }
private string _Summary;
public string Summary { get => _Summary; set => this.RaiseAndSetIfChanged(ref _Summary, value); }
private string _ImagePath;
public string ImagePath { get => _ImagePath; set => this.RaiseAndSetIfChanged(ref _ImagePath, value); }
private readonly ObservableAsPropertyHelper<BitmapImage> _Image;
public BitmapImage Image => _Image.Value;
private string _NexusSiteURL;
public string NexusSiteURL { get => _NexusSiteURL; set => this.RaiseAndSetIfChanged(ref _NexusSiteURL, value); }
private string _ReadMeText;
public string ReadMeText { get => _ReadMeText; set => this.RaiseAndSetIfChanged(ref _ReadMeText, value); }
private string _HTMLReport;
public string HTMLReport { get => _HTMLReport; set => this.RaiseAndSetIfChanged(ref _HTMLReport, value); }
private string _DownloadLocation;
public string DownloadLocation { get => _DownloadLocation; set => this.RaiseAndSetIfChanged(ref _DownloadLocation, value); }
public IReactiveCommand BeginCommand { get; }
public IReactiveCommand ChangePathCommand { get; }
public IReactiveCommand ChangeDownloadPathCommand { get; }
public IReactiveCommand ChangeSplashScreenCommand { get; }
public CompilerVM(MainWindowVM mainWindowVM, string source)
{
this.MWVM = mainWindowVM;
this.Location = Path.GetDirectoryName(source);
this.BeginCommand = ReactiveCommand.Create(
execute: this.ExecuteBegin,
canExecute: this.WhenAny(x => x.UIReady)
.ObserveOnGuiThread());
this.ChangePathCommand = ReactiveCommand.Create(
ExecuteChangePath,
canExecute: this.WhenAny(x => x.UIReady)
.ObserveOnGuiThread());
this.ChangeDownloadPathCommand = ReactiveCommand.Create(
ExecuteChangeDownloadPath,
canExecute: this.WhenAny(x => x.UIReady)
.ObserveOnGuiThread());
this.ChangeSplashScreenCommand = ReactiveCommand.Create(
canExecute: this.WhenAny(x => x.UIReady)
.ObserveOnGuiThread(),
execute: () =>
{
this.ImagePath = UIUtils.OpenFileDialog("Banner image|*.png");
});
this._Image = this.WhenAny(x => x.ImagePath)
.Select(path =>
{
if (string.IsNullOrWhiteSpace(path)) return UIUtils.BitmapImageFromResource("Wabbajack.Resources.Banner_Dark.png");
if (UIUtils.TryGetBitmapImageFromFile(path, out var image))
{
return image;
}
return UIUtils.BitmapImageFromResource("Wabbajack.Resources.none.png");
})
.ToProperty(this, nameof(this.Image));
}
private void ExecuteChangePath()
{
Location = UIUtils.ShowFolderSelectionDialog("Select Your MO2 profile directory");
}
private void ExecuteChangeDownloadPath()
{
var folder = UIUtils.ShowFolderSelectionDialog("Select a location for MO2 downloads");
if (folder != null)
{
DownloadLocation = folder;
}
}
private void ConfigureForBuild()
{
var profile_folder = Path.GetDirectoryName(Location);
this.Mo2Folder = Path.GetDirectoryName(Path.GetDirectoryName(profile_folder));
if (!File.Exists(Path.Combine(this.Mo2Folder, "ModOrganizer.exe")))
this.Log().Error($"Error! No ModOrganizer2.exe found in {this.Mo2Folder}");
var profile_name = Path.GetFileName(profile_folder);
this.ModListName = profile_name;
var tmp_compiler = new Compiler(this.Mo2Folder);
DownloadLocation = tmp_compiler.MO2DownloadsFolder;
}
private void ExecuteBegin()
{
if (this.Mo2Folder != null)
{
var compiler = new Compiler(this.Mo2Folder)
{
MO2Profile = this.ModListName,
ModListName = this.ModName,
ModListAuthor = this.AuthorName,
ModListDescription = this.Summary,
ModListImage = this.ImagePath,
ModListWebsite = this.NexusSiteURL,
ModListReadme = this.ReadMeText,
};
var th = new Thread(() =>
{
UIReady = false;
try
{
compiler.Compile();
if (compiler.ModList != null && compiler.ModList.ReportHTML != null)
{
this.HTMLReport = compiler.ModList.ReportHTML;
}
}
catch (Exception ex)
{
while (ex.InnerException != null) ex = ex.InnerException;
this.Log().Warn(ex, "Can't continue");
}
finally
{
UIReady = true;
}
})
{
Priority = ThreadPriority.BelowNormal
};
th.Start();
}
else
{
this.Log().Warn("Cannot compile modlist: no valid Mod Organizer profile directory selected.");
UIReady = true;
}
}
public string Error => "Error";
public string this[string columnName] => Validate(columnName);
private string Validate(string columnName)
{
string validationMessage = null;
switch (columnName)
{
case "Location":
if (Location == null)
{
validationMessage = null;
}
else switch (Mode)
{
case RunMode.Compile when Location != null && Directory.Exists(Location) && File.Exists(Path.Combine(Location, "modlist.txt")):
Location = Path.Combine(Location, "modlist.txt");
validationMessage = null;
ConfigureForBuild();
break;
case RunMode.Install when Location != null && Directory.Exists(Location) && !Directory.EnumerateFileSystemEntries(Location).Any():
validationMessage = null;
break;
case RunMode.Install when Location != null && Directory.Exists(Location) && Directory.EnumerateFileSystemEntries(Location).Any():
validationMessage = "You have selected a non-empty directory. Installing the modlist here might result in a broken install!";
break;
default:
validationMessage = "Invalid Mod Organizer profile directory";
break;
}
break;
}
return validationMessage;
}
}
}

View File

@ -29,23 +29,18 @@ using Wabbajack.Lib;
namespace Wabbajack
{
public class AppState : ViewModel, IDataErrorInfo
public class InstallerVM : ViewModel, IDataErrorInfo
{
public SlideShow Slideshow { get; }
public MainWindowVM MWVM { get; }
private string _mo2Folder;
public readonly BitmapImage _noneImage = UIUtils.BitmapImageFromResource("Wabbajack.Resources.none.jpg");
private ModList _ModList;
public ModList ModList { get => _ModList; private set => this.RaiseAndSetIfChanged(ref _ModList, value); }
private string _ModListPath;
public string ModListPath { get => _ModListPath; private set => this.RaiseAndSetIfChanged(ref _ModListPath, value); }
private RunMode _Mode;
public RunMode Mode { get => _Mode; private set => this.RaiseAndSetIfChanged(ref _Mode, value); }
public RunMode Mode => RunMode.Install;
private string _ModListName;
public string ModListName { get => _ModListName; set => this.RaiseAndSetIfChanged(ref _ModListName, value); }
@ -59,15 +54,20 @@ namespace Wabbajack
private bool _Installing;
public bool Installing { get => _Installing; set => this.RaiseAndSetIfChanged(ref _Installing, value); }
private string _Location;
public string Location { get => _Location; set => this.RaiseAndSetIfChanged(ref _Location, value); }
private string _DownloadLocation;
public string DownloadLocation { get => _DownloadLocation; set => this.RaiseAndSetIfChanged(ref _DownloadLocation, value); }
// Command properties
public IReactiveCommand ChangePathCommand { get; }
public IReactiveCommand ChangeDownloadPathCommand { get; }
public IReactiveCommand BeginCommand { get; }
public IReactiveCommand ShowReportCommand { get; }
public IReactiveCommand OpenReadmeCommand { get; }
public IReactiveCommand OpenModListPropertiesCommand { get; }
public AppState(MainWindowVM mainWindowVM, RunMode mode)
public InstallerVM(MainWindowVM mainWindowVM)
{
if (Path.GetDirectoryName(Assembly.GetEntryAssembly().Location.ToLower()) == KnownFolders.Downloads.Path.ToLower())
{
@ -81,16 +81,11 @@ namespace Wabbajack
}
this.MWVM = mainWindowVM;
Mode = mode;
// Define commands
this.ChangePathCommand = ReactiveCommand.Create(ExecuteChangePath);
this.ChangeDownloadPathCommand = ReactiveCommand.Create(ExecuteChangeDownloadPath);
this.ShowReportCommand = ReactiveCommand.Create(ShowReport);
this.OpenModListPropertiesCommand = ReactiveCommand.Create(
execute: OpenModListProperties,
canExecute: this.WhenAny(x => x.UIReady)
.ObserveOnGuiThread());
this.OpenReadmeCommand = ReactiveCommand.Create(
execute: this.OpenReadmeWindow,
canExecute: this.WhenAny(x => x.ModList)
@ -104,33 +99,14 @@ namespace Wabbajack
this.Slideshow = new SlideShow(this);
}
private string _Location;
public string Location { get => _Location; set => this.RaiseAndSetIfChanged(ref _Location, value); }
private string _LocationLabel;
public string LocationLabel { get => _LocationLabel; set => this.RaiseAndSetIfChanged(ref _LocationLabel, value); }
private string _DownloadLocation;
public string DownloadLocation { get => _DownloadLocation; set => this.RaiseAndSetIfChanged(ref _DownloadLocation, value); }
private void ExecuteChangePath()
{
switch (this.Mode)
var folder = UIUtils.ShowFolderSelectionDialog("Select Installation directory");
if (folder == null) return;
Location = folder;
if (DownloadLocation == null)
{
case RunMode.Compile:
Location = UIUtils.ShowFolderSelectionDialog("Select Your MO2 profile directory");
break;
case RunMode.Install:
var folder = UIUtils.ShowFolderSelectionDialog("Select Installation directory");
if (folder == null) return;
Location = folder;
if (DownloadLocation == null)
{
DownloadLocation = Path.Combine(Location, "downloads");
}
break;
default:
throw new NotImplementedException();
DownloadLocation = Path.Combine(Location, "downloads");
}
}
@ -147,31 +123,6 @@ namespace Wabbajack
Process.Start(file);
}
private ModlistPropertiesWindow modlistPropertiesWindow;
public string newImagePath;
public string readmePath;
public bool ChangedProperties;
private void OpenModListProperties()
{
if (UIReady)
{
if (modlistPropertiesWindow == null)
{
modlistPropertiesWindow = new ModlistPropertiesWindow(this);
newImagePath = null;
ChangedProperties = false;
}
if(!modlistPropertiesWindow.IsClosed)
modlistPropertiesWindow.Show();
else
{
modlistPropertiesWindow = null;
OpenModListProperties();
}
}
}
private void OpenReadmeWindow()
{
if (string.IsNullOrEmpty(this.ModList.Readme)) return;
@ -209,11 +160,6 @@ namespace Wabbajack
}
else switch (Mode)
{
case RunMode.Compile when Location != null && Directory.Exists(Location) && File.Exists(Path.Combine(Location, "modlist.txt")):
Location = Path.Combine(Location, "modlist.txt");
validationMessage = null;
ConfigureForBuild();
break;
case RunMode.Install when Location != null && Directory.Exists(Location) && !Directory.EnumerateFileSystemEntries(Location).Any():
validationMessage = null;
break;
@ -229,28 +175,10 @@ namespace Wabbajack
return validationMessage;
}
private void ConfigureForBuild()
{
var profile_folder = Path.GetDirectoryName(Location);
var mo2folder = Path.GetDirectoryName(Path.GetDirectoryName(profile_folder));
if (!File.Exists(Path.Combine(mo2folder, "ModOrganizer.exe")))
Utils.Log($"Error! No ModOrganizer2.exe found in {mo2folder}");
var profile_name = Path.GetFileName(profile_folder);
this.ModListName = profile_name;
this.Mode = RunMode.Compile;
var tmp_compiler = new Compiler(mo2folder);
DownloadLocation = tmp_compiler.MO2DownloadsFolder;
_mo2Folder = mo2folder;
}
internal void ConfigureForInstall(string source, ModList modlist)
{
this.ModList = modlist;
this.ModListPath = source;
this.Mode = RunMode.Install;
ModListName = this.ModList.Name;
HTMLReport = this.ModList.ReportHTML;
Location = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
@ -302,49 +230,31 @@ namespace Wabbajack
};
th.Start();
}
else if (_mo2Folder != null)
}
public void Init(string source)
{
var modlist = Installer.LoadFromFile(source);
if (modlist == null)
{
var compiler = new Compiler(_mo2Folder)
MessageBox.Show("Invalid Modlist, or file not found.", "Invalid Modlist", MessageBoxButton.OK,
MessageBoxImage.Error);
Application.Current.Dispatcher.Invoke(() =>
{
MO2Profile = ModListName,
ModListName = ChangedProperties ? this.Slideshow.ModName : null,
ModListAuthor = ChangedProperties ? this.Slideshow.AuthorName : null,
ModListDescription = ChangedProperties ? this.Slideshow.Summary : null,
ModListImage = ChangedProperties ? newImagePath : null,
ModListWebsite = ChangedProperties ? this.Slideshow.NexusSiteURL : null,
ModListReadme = ChangedProperties ? readmePath : null
};
var th = new Thread(() =>
{
UIReady = false;
try
this.MWVM.MainWindow.ExitWhenClosing = false;
var window = new ModeSelectionWindow
{
compiler.Compile();
if (compiler.ModList != null && compiler.ModList.ReportHTML != null)
HTMLReport = compiler.ModList.ReportHTML;
}
catch (Exception ex)
{
while (ex.InnerException != null) ex = ex.InnerException;
Utils.Log(ex.StackTrace);
Utils.Log(ex.ToString());
Utils.Log($"{ex.Message} - Can't continue");
}
finally
{
UIReady = true;
}
})
{
Priority = ThreadPriority.BelowNormal
};
th.Start();
ShowActivated = true
};
window.Show();
this.MWVM.MainWindow.Close();
});
}
else
{
Utils.Log("Cannot compile modlist: no valid Mod Organizer profile directory selected.");
UIReady = true;
this.ConfigureForInstall(source, modlist);
}
this.UIReady = true;
}
}
}

View File

@ -4,6 +4,7 @@ using ReactiveUI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
@ -22,10 +23,10 @@ namespace Wabbajack
/// </summary>
public class MainWindowVM : ViewModel
{
public AppState AppState { get; }
public MainWindow MainWindow { get; }
private ViewModel _ActivePane;
public ViewModel ActivePane { get => _ActivePane; set => this.RaiseAndSetIfChanged(ref _ActivePane, value); }
private readonly ObservableAsPropertyHelper<ViewModel> _ActivePane;
public ViewModel ActivePane => _ActivePane.Value;
private int _QueueProgress;
public int QueueProgress { get => _QueueProgress; set => this.RaiseAndSetIfChanged(ref _QueueProgress, value); }
@ -37,8 +38,14 @@ namespace Wabbajack
private Subject<string> _logSubj = new Subject<string>();
public ObservableCollectionExtended<string> Log { get; } = new ObservableCollectionExtended<string>();
public MainWindowVM(RunMode mode)
private RunMode _Mode;
public RunMode Mode { get => _Mode; set => this.RaiseAndSetIfChanged(ref _Mode, value); }
public MainWindowVM(RunMode mode, string source, MainWindow mainWindow)
{
this.Mode = mode;
this.MainWindow = mainWindow;
// Set up logging
_logSubj
.ToObservableChangeSet()
@ -53,8 +60,6 @@ namespace Wabbajack
Utils.SetLoggerFn(s => _logSubj.OnNext(s));
Utils.SetStatusFn((msg, progress) => WorkQueue.Report(msg, progress));
this.AppState = new AppState(this, mode);
// Initialize work queue
WorkQueue.Init(
report_function: (id, msg, progress) => this._statusSubject.OnNext(new CPUStatus() { ID = id, Msg = msg, Progress = progress }),
@ -71,6 +76,29 @@ namespace Wabbajack
.Bind(this.StatusList)
.Subscribe()
.DisposeWith(this.CompositeDisposable);
// Wire mode to drive the active pane
this._ActivePane = this.WhenAny(x => x.Mode)
.ObserveOn(RxApp.MainThreadScheduler)
.Select<RunMode, ViewModel>(m =>
{
switch (m)
{
case RunMode.Compile:
return new CompilerVM(this, source);
case RunMode.Install:
return new InstallerVM(this);
default:
return default;
}
})
.ToProperty(this, nameof(this.ActivePane));
this.WhenAny(x => x.ActivePane)
.ObserveOn(RxApp.TaskpoolScheduler)
.WhereCastable<ViewModel, InstallerVM>()
.Subscribe(vm => vm.Init(source))
.DisposeWith(this.CompositeDisposable);
}
private void SetQueueSize(int max, int current)

View File

@ -31,7 +31,7 @@ namespace Wabbajack
public Queue<Slide> SlidesQueue { get; }
public AppState AppState { get; }
public InstallerVM Installer { get; }
public BitmapImage NextIcon { get; } = UIUtils.BitmapImageFromResource("Wabbajack.Resources.Icons.next.png");
public BitmapImage WabbajackLogo { get; } = UIUtils.BitmapImageFromResource("Wabbajack.Resources.Banner_Dark.png");
@ -63,13 +63,13 @@ namespace Wabbajack
public IReactiveCommand SlideShowNextItemCommand { get; } = ReactiveCommand.Create(() => { });
public IReactiveCommand VisitNexusSiteCommand { get; }
public SlideShow(AppState appState)
public SlideShow(InstallerVM appState)
{
SlideShowElements = NexusApiClient.CachedSlideShow.ToList();
CachedSlides = new Dictionary<string, Slide>();
SlidesQueue = new Queue<Slide>();
_random = new Random();
AppState = appState;
Installer = appState;
this.VisitNexusSiteCommand = ReactiveCommand.Create(
execute: () => Process.Start(this.NexusSiteURL),
@ -78,7 +78,7 @@ namespace Wabbajack
.ObserveOnGuiThread());
// Apply modlist properties when it changes
this.WhenAny(x => x.AppState.ModList)
this.WhenAny(x => x.Installer.ModList)
.NotNull()
.Subscribe(modList =>
{
@ -91,8 +91,8 @@ namespace Wabbajack
// Update splashscreen when modlist changes
Observable.CombineLatest(
(this).WhenAny(x => x.AppState.ModList),
(this).WhenAny(x => x.AppState.ModListPath),
(this).WhenAny(x => x.Installer.ModList),
(this).WhenAny(x => x.Installer.ModListPath),
(this).WhenAny(x => x.Enable),
(modList, modListPath, enabled) => (modList, modListPath, enabled))
// Do any potential unzipping on a background thread
@ -150,7 +150,7 @@ namespace Wabbajack
.FilterSwitch(
Observable.CombineLatest(
this.WhenAny(x => x.Enable),
this.WhenAny(x => x.AppState.Installing),
this.WhenAny(x => x.Installer.Installing),
resultSelector: (enabled, installing) => enabled && installing))
// Don't ever update more than once every half second. ToDo: Update to debounce
.Throttle(TimeSpan.FromMilliseconds(500), RxApp.MainThreadScheduler)
@ -195,7 +195,7 @@ namespace Wabbajack
if (!slide.IsNSFW || (slide.IsNSFW && ShowNSFW))
{
this.Image = AppState._noneImage;
this.Image = UIUtils.BitmapImageFromResource("Wabbajack.Resources.none.jpg");
if (slide.ImageURL != null && slide.Image != null)
{
if (!CachedSlides.ContainsKey(slide.ModID)) return;

View File

@ -0,0 +1,247 @@
<UserControl x:Class="Wabbajack.CompilerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wabbajack"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox Stretch="Uniform">
<Grid Margin="4,0,4,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="435" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="320" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="638" />
<ColumnDefinition Width="4" />
<ColumnDefinition Width="638" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Row="0"
Margin="0,8,0,8"
Orientation="Horizontal">
<TextBlock
FontSize="16"
FontWeight="Bold"
Text="{Binding Mode}" />
<TextBlock FontSize="16" Text=" : " />
<TextBlock FontSize="16" Text="{Binding ModListName}" />
</StackPanel>
<Grid Grid.Row="1" Grid.Column="0"
IsEnabled="{Binding UIReady}"
Margin="0,8,0,8">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Row="0"
Source="{Binding Image}"
Stretch="Fill" />
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label
Grid.Column="0"
Content="Splash Screen Path:" />
<TextBox
Grid.Column="1"
IsEnabled="{Binding UIReady}"
Text="{Binding ImagePath}" />
<Button
Grid.Column="2"
MinWidth="80"
Command="{Binding ChangeSplashScreenCommand}"
Content="Select" />
</Grid>
</Grid>
<ScrollViewer Grid.Row="1" Grid.Column="2" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"
Background="Transparent">
<StackPanel Orientation="Vertical" Background="Transparent" >
<StackPanel.Resources>
<Thickness x:Key="TitleMargin" Left="5" Bottom="1" />
<Style TargetType="TextBox" x:Key="ValueStyle" BasedOn="{StaticResource MainTextBoxStyle}" >
<Setter Property="MaxLength" Value="50" />
<Setter Property="AcceptsTab" Value="False" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Margin" Value="0,0,0,6" />
</Style>
</StackPanel.Resources>
<TextBlock Text="ModList Name" Margin="{StaticResource TitleMargin}" />
<TextBox Text="{Binding ModName}" Style="{StaticResource ValueStyle}" />
<TextBlock Text="Author" Margin="{StaticResource TitleMargin}" />
<TextBox Text="{Binding AuthorName}" Style="{StaticResource ValueStyle}" />
<TextBlock Text="Description" Margin="{StaticResource TitleMargin}" />
<TextBox Text="{Binding Summary}" Style="{StaticResource ValueStyle}" Height="150" MaxLength="700" AcceptsReturn="True" TextWrapping="Wrap" AcceptsTab="False" />
<TextBlock Text="Website" Margin="{StaticResource TitleMargin}" />
<TextBox Text="{Binding NexusSiteURL}" Style="{StaticResource ValueStyle}" />
<TextBlock Text="Readme Path" Margin="{StaticResource TitleMargin}" ToolTip="Path to a readme file." />
<TextBox Text="{Binding NexusSiteURL}" Style="{StaticResource ValueStyle}" ToolTip="Path to a readme file." />
</StackPanel>
</ScrollViewer>
<ProgressBar
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="1,0,1,0"
Background="#444444"
Maximum="100"
Minimum="0"
Value="{Binding MWVM.QueueProgress}" />
<!-- Log -->
<TextBlock
Grid.Row="3"
Margin="0,16,0,8"
FontSize="14"
Text="Log:" />
<ListBox
Grid.Row="4"
Margin="0,0,2,0"
local:AutoScrollBehavior.ScrollOnNewItem="True"
ItemsSource="{Binding MWVM.Log}" />
<!-- End Log -->
<!-- Location -->
<Grid
Grid.Row="5"
Grid.RowSpan="2"
Grid.Column="0"
Margin="-4,10,0,10"
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition MinHeight="10" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
Content="Installation Location:" />
<TextBox
Grid.Row="0"
Grid.Column="1"
IsEnabled="{Binding UIReady}"
Text="{Binding Location, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />
<Button
Grid.Row="0"
Grid.Column="2"
MinWidth="80"
Command="{Binding ChangePathCommand}"
Content="Select"
IsEnabled="{Binding UIReady}" />
<Label
Grid.Row="2"
Grid.Column="0"
Content="Download Location:" />
<TextBox
Grid.Row="2"
Grid.Column="1"
IsEnabled="{Binding UIReady}"
Text="{Binding DownloadLocation}" />
<Button
Grid.Row="2"
Grid.Column="2"
MinWidth="80"
Command="{Binding ChangeDownloadPathCommand}"
Content="Select"
IsEnabled="{Binding UIReady}" />
</Grid>
<!-- End Location -->
<!-- Work Queue Start -->
<TextBlock
Grid.Row="3"
Grid.Column="2"
Margin="0,16,0,8"
FontSize="14"
Text="Work Queue:" />
<ListBox
Grid.Row="4"
Grid.Column="2"
Width="Auto"
HorizontalAlignment="Stretch"
ItemsSource="{Binding MWVM.StatusList}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ProgressBar
Grid.Column="0"
Width="100"
Maximum="100"
Minimum="0"
Value="{Binding Progress, Mode=OneTime}">
<ProgressBar.Style>
<Style TargetType="ProgressBar">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Progress}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</ProgressBar.Style>
</ProgressBar>
<TextBlock Grid.Column="1" Text=" CPU " />
<TextBlock Grid.Column="2" Text="{Binding ID}" />
<TextBlock Grid.Column="3" Text=" - " />
<TextBlock Grid.Column="4" Text="{Binding Msg}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- Work Queue End -->
<Grid
Grid.Row="5"
Grid.RowSpan="2"
Grid.Column="2"
Margin="0,10,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Button
Grid.Row="0"
Margin="0,0,0,4"
Command="{Binding ShowReportCommand}"
Visibility="{Binding HTMLReport, Converter={StaticResource IsNotNullVisibilityConverter}}">
<TextBlock FontSize="13" FontWeight="Bold">View ModList Contents</TextBlock>
</Button>
<Button
Grid.Row="1"
Margin="0,4,0,0"
Command="{Binding BeginCommand}">
<TextBlock FontSize="13" FontWeight="Bold">Begin</TextBlock>
</Button>
</Grid>
</Grid>
</Viewbox>
</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 CompilerView.xaml
/// </summary>
public partial class CompilerView : UserControl
{
public CompilerView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,199 @@
<UserControl x:Class="Wabbajack.InstallationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wabbajack"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Viewbox Stretch="Uniform">
<Grid Margin="4,0,4,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="435" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="320" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="640" />
<ColumnDefinition Width="640" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Row="0"
Margin="0,8,0,8"
Orientation="Horizontal">
<TextBlock
FontSize="16"
FontWeight="Bold"
Text="{Binding Mode}" />
<TextBlock FontSize="16" Text=" : " />
<TextBlock FontSize="16" Text="{Binding ModListName}" />
</StackPanel>
<local:SlideshowView
x:Name="Slideshow"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,0,0,4"
DataContext="{Binding Slideshow}" />
<ProgressBar
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="1,0,1,0"
Background="#444444"
Maximum="100"
Minimum="0"
Value="{Binding MWVM.QueueProgress}" />
<!-- Log -->
<TextBlock
Grid.Row="3"
Margin="0,16,0,8"
FontSize="14"
Text="Log:" />
<ListBox
Grid.Row="4"
Margin="0,0,2,0"
local:AutoScrollBehavior.ScrollOnNewItem="True"
ItemsSource="{Binding MWVM.Log}" />
<!-- End Log -->
<!-- Location -->
<Grid
Grid.Row="5"
Grid.RowSpan="2"
Grid.Column="0"
Margin="-4,10,2,10"
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition MinHeight="10" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
Content="Installation Location:" />
<TextBox
Grid.Row="0"
Grid.Column="1"
IsEnabled="{Binding UIReady}"
Text="{Binding Location, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />
<Button
Grid.Row="0"
Grid.Column="2"
MinWidth="80"
Command="{Binding ChangePathCommand}"
Content="Select"
IsEnabled="{Binding UIReady}" />
<Label
Grid.Row="2"
Grid.Column="0"
Content="Download Location:" />
<TextBox
Grid.Row="2"
Grid.Column="1"
IsEnabled="{Binding UIReady}"
Text="{Binding DownloadLocation}" />
<Button
Grid.Row="2"
Grid.Column="2"
MinWidth="80"
Command="{Binding ChangeDownloadPathCommand}"
Content="Select"
IsEnabled="{Binding UIReady}" />
</Grid>
<!-- End Location -->
<!-- Work Queue Start -->
<TextBlock
Grid.Row="3"
Grid.Column="1"
Margin="2,16,0,8"
FontSize="14"
Text="Work Queue:" />
<ListBox
Grid.Row="4"
Grid.Column="1"
Width="Auto"
Margin="2,0,0,0"
HorizontalAlignment="Stretch"
ItemsSource="{Binding MWVM.StatusList}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ProgressBar
Grid.Column="0"
Width="100"
Maximum="100"
Minimum="0"
Value="{Binding Progress, Mode=OneTime}">
<ProgressBar.Style>
<Style TargetType="ProgressBar">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Progress}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</ProgressBar.Style>
</ProgressBar>
<TextBlock Grid.Column="1" Text=" CPU " />
<TextBlock Grid.Column="2" Text="{Binding ID}" />
<TextBlock Grid.Column="3" Text=" - " />
<TextBlock Grid.Column="4" Text="{Binding Msg}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- Work Queue End -->
<Grid
Grid.Row="5"
Grid.RowSpan="2"
Grid.Column="1"
Margin="2,10,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Button
Grid.Row="0"
Margin="0,0,0,4"
Command="{Binding ShowReportCommand}"
Visibility="{Binding HTMLReport, Converter={StaticResource IsNotNullVisibilityConverter}}">
<TextBlock FontSize="13" FontWeight="Bold">View ModList Contents</TextBlock>
</Button>
<Button
Grid.Row="1"
Margin="0,4,0,0"
Command="{Binding BeginCommand}">
<TextBlock FontSize="13" FontWeight="Bold">Begin</TextBlock>
</Button>
</Grid>
</Grid>
</Viewbox>
</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 InstallationView.xaml
/// </summary>
public partial class InstallationView : UserControl
{
public InstallationView()
{
InitializeComponent();
}
}
}

View File

@ -16,194 +16,14 @@
Style="{StaticResource {x:Type Window}}"
WindowStyle="ToolWindow"
mc:Ignorable="d">
<Viewbox Stretch="Uniform" DataContext="{Binding AppState}">
<Grid Margin="4,0,4,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="435" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="320" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="640" />
<ColumnDefinition Width="640" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Row="0"
Margin="0,8,0,8"
Orientation="Horizontal">
<TextBlock
FontSize="16"
FontWeight="Bold"
Text="{Binding Mode}" />
<TextBlock FontSize="16" Text=" : " />
<TextBlock FontSize="16" Text="{Binding ModListName}" />
</StackPanel>
<local:SlideshowView
x:Name="Slideshow"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,0,0,4"
DataContext="{Binding Slideshow}" />
<ProgressBar
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="1,0,1,0"
Background="#444444"
Maximum="100"
Minimum="0"
Value="{Binding MWVM.QueueProgress}" />
<!-- Log -->
<TextBlock
Grid.Row="3"
Margin="0,16,0,8"
FontSize="14"
Text="Log:" />
<ListBox
Grid.Row="4"
Margin="0,0,2,0"
local:AutoScrollBehavior.ScrollOnNewItem="True"
ItemsSource="{Binding MWVM.Log}" />
<!-- End Log -->
<!-- Location -->
<Grid
Grid.Row="5"
Grid.RowSpan="2"
Grid.Column="0"
Margin="-4,10,2,10"
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition MinHeight="10" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
Content="{Binding LocationLabel}" />
<TextBox
Grid.Row="0"
Grid.Column="1"
IsEnabled="{Binding UIReady}"
Text="{Binding Location, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />
<Button
Grid.Row="0"
Grid.Column="2"
MinWidth="80"
Command="{Binding ChangePathCommand}"
Content="Select"
IsEnabled="{Binding UIReady}" />
<Label
Grid.Row="2"
Grid.Column="0"
Content="Download Location:" />
<TextBox
Grid.Row="2"
Grid.Column="1"
IsEnabled="{Binding UIReady}"
Text="{Binding DownloadLocation}" />
<Button
Grid.Row="2"
Grid.Column="2"
MinWidth="80"
Command="{Binding ChangeDownloadPathCommand}"
Content="Select"
IsEnabled="{Binding UIReady}" />
</Grid>
<!-- End Location -->
<!-- Work Queue Start -->
<TextBlock
Grid.Row="3"
Grid.Column="1"
Margin="2,16,0,8"
FontSize="14"
Text="Work Queue:" />
<ListBox
Grid.Row="4"
Grid.Column="1"
Width="Auto"
Margin="2,0,0,0"
HorizontalAlignment="Stretch"
ItemsSource="{Binding MWVM.StatusList}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ProgressBar
Grid.Column="0"
Width="100"
Maximum="100"
Minimum="0"
Value="{Binding Progress, Mode=OneTime}">
<ProgressBar.Style>
<Style TargetType="ProgressBar">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Progress}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</ProgressBar.Style>
</ProgressBar>
<TextBlock Grid.Column="1" Text=" CPU " />
<TextBlock Grid.Column="2" Text="{Binding ID}" />
<TextBlock Grid.Column="3" Text=" - " />
<TextBlock Grid.Column="4" Text="{Binding Msg}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- Work Queue End -->
<Grid
Grid.Row="5"
Grid.RowSpan="2"
Grid.Column="1"
Margin="2,10,0,10">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Button
Grid.Row="0"
Margin="0,0,0,4"
Command="{Binding ShowReportCommand}"
Visibility="{Binding HTMLReport, Converter={StaticResource IsNotNullVisibilityConverter}}">
<TextBlock FontSize="13" FontWeight="Bold">View ModList Contents</TextBlock>
</Button>
<Button
Grid.Row="1"
Margin="0,4,0,0"
Command="{Binding BeginCommand}">
<TextBlock FontSize="13" FontWeight="Bold">Begin</TextBlock>
</Button>
</Grid>
</Grid>
</Viewbox>
<ContentPresenter Content="{Binding ActivePane}" >
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type local:CompilerVM}" >
<local:CompilerView />
</DataTemplate>
<DataTemplate DataType="{x:Type local:InstallerVM}" >
<local:InstallationView />
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
</Window>

View File

@ -19,52 +19,11 @@ namespace Wabbajack
public MainWindow(RunMode mode, string source)
{
var args = Environment.GetCommandLineArgs();
InitializeComponent();
this._mwvm = new MainWindowVM(mode);
var context = _mwvm.AppState;
_mwvm = new MainWindowVM(mode, source, this);
Utils.Log($"Wabbajack Build - {ThisAssembly.Git.Sha}");
DataContext = _mwvm;
new Thread(() =>
{
if (mode == RunMode.Compile)
{
Utils.Log("Compiler ready to execute");
context.Location = Path.GetDirectoryName(source);
context.LocationLabel = "MO2 Profile:";
}
else if (mode == RunMode.Install)
{
context.UIReady = false;
context.LocationLabel = "Installation Location:";
var modlist = Installer.LoadFromFile(source);
if (modlist == null)
{
MessageBox.Show("Invalid Modlist, or file not found.", "Invalid Modlist", MessageBoxButton.OK,
MessageBoxImage.Error);
Dispatcher.Invoke(() =>
{
ExitWhenClosing = false;
var window = new ModeSelectionWindow
{
ShowActivated = true
};
window.Show();
Close();
});
}
else
{
context.ConfigureForInstall(source, modlist);
}
}
context.UIReady = true;
}).Start();
this.DataContext = _mwvm;
}
internal bool ExitWhenClosing = true;

View File

@ -1,60 +0,0 @@
<Window x:Class="Wabbajack.ModlistPropertiesWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Wabbajack"
mc:Ignorable="d"
Title="Wabbajack (Modlist Properties)" Height="600" Width="900"
Style="{StaticResource {x:Type Window}}" Icon="../Resources/Icons/wabbajack.ico" WindowStyle="ToolWindow"
ResizeMode="NoResize">
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="300"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Grid.Row="0" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Stretch="Fill" Name="SplashScreenProperty"/>
<Button Height="30" Grid.Row="1" Click="SetSplashScreen_Click" ToolTip="Use a 1400x900 png file for the best results">
<TextBlock Text="Change splash screen image" FontSize="15" FontWeight="Bold"/>
</Button>
</Grid>
<Grid Grid.Column="1" Grid.Row="0" Margin="0 5 0 5">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="ModList Name" Name="ModlistNameProperty" ToolTip="Change the name of your ModList" MaxLength="50" AcceptsTab="False" FontSize="15" FontWeight="Bold" Margin="0,0,0,5"/>
<TextBox Grid.Row="1" Text="Author" Name="ModlistAuthorProperty" ToolTip="Change the name of the Author" MaxLength="50" AcceptsTab="False" FontSize="15" Margin="0 0 0 5" />
<TextBox Grid.Row="2" Text="Description (700 characters max)" Name="ModlistDescriptionProperty" ToolTip="Change the description" MaxLength="700" AcceptsReturn="True" TextWrapping="Wrap" AcceptsTab="False" FontSize="15" Margin="0,0,0,0"/>
</Grid>
<TextBox Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Text="Website" Name="ModlistWebsiteProperty" ToolTip="Change the website" MaxLength="80" AcceptsReturn="False" AcceptsTab="False" FontSize="15"/>
<Grid Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Height="30" Margin="0,10,0,-10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Height="30" Grid.ColumnSpan="3" Text="Readme path" Name="ModlistReadmeProperty" AcceptsReturn="False" AcceptsTab="False" FontSize="15"/>
<Button Height="30" Grid.Column="2" Content="Choose" Click="ChooseReadme_Click"/>
</Grid>
<Button Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Click="SaveProperties_Click" Margin="0,160,0,-160" Height="30" VerticalAlignment="Bottom">
<TextBlock Text="Save" FontSize="15" FontWeight="Bold"/>
</Button>
</Grid>
</Window>

View File

@ -1,75 +0,0 @@
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Media.Imaging;
using Wabbajack.Lib;
namespace Wabbajack
{
/// <summary>
/// Interaction logic for ModlistPropertiesWindow.xaml
/// </summary>
public partial class ModlistPropertiesWindow : Window
{
internal string newBannerFile;
internal readonly AppState state;
internal ModlistPropertiesWindow(AppState _state)
{
InitializeComponent();
var bannerImage = UIUtils.BitmapImageFromResource("Wabbajack.Resources.Banner_Dark.png");
SplashScreenProperty.Source = bannerImage;
newBannerFile = null;
state = _state;
}
private void SetSplashScreen_Click(object sender, RoutedEventArgs e)
{
var file = UIUtils.OpenFileDialog("Banner image|*.png");
if (file != null)
{
newBannerFile = file;
SplashScreenProperty.Source = new BitmapImage(new Uri(file));
}
}
private void SaveProperties_Click(object sender, RoutedEventArgs e)
{
if (state.UIReady)
{
if (newBannerFile != null)
{
BitmapImage splashScreen = new BitmapImage(new Uri(newBannerFile));
state.newImagePath = newBannerFile;
state.Slideshow.Image = splashScreen;
}
state.Slideshow.ModName = ModlistNameProperty.Text;
state.Slideshow.Summary = ModlistDescriptionProperty.Text;
state.Slideshow.AuthorName = ModlistAuthorProperty.Text;
state.Slideshow.NexusSiteURL = ModlistWebsiteProperty.Text;
state.readmePath = ModlistReadmeProperty.Text;
state.ChangedProperties = true;
Hide();
}
}
public bool IsClosed { get; private set; }
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
IsClosed = true;
}
private void ChooseReadme_Click(object sender, RoutedEventArgs e)
{
var file = UIUtils.OpenFileDialog("Readme|*.txt");
if (file != null)
{
ModlistReadmeProperty.Text = file;
}
}
}
}

View File

@ -33,11 +33,11 @@
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource MainButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding AppState.Mode}" Value="{x:Static local:RunMode.Install}">
<DataTrigger Binding="{Binding Installer.Mode}" Value="{x:Static local:RunMode.Install}">
<Setter Property="Command" Value="{Binding AppState.OpenReadmeCommand}" />
<Setter Property="Content" Value="Open README" />
</DataTrigger>
<DataTrigger Binding="{Binding AppState.Mode}" Value="{x:Static local:RunMode.Compile}">
<DataTrigger Binding="{Binding Installer.Mode}" Value="{x:Static local:RunMode.Compile}">
<Setter Property="Command" Value="{Binding AppState.OpenModListPropertiesCommand}" />
<Setter Property="Content" Value="Modlist Properties" />
</DataTrigger>

View File

@ -224,17 +224,21 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Views\CompilerView.xaml.cs">
<DependentUpon>CompilerView.xaml</DependentUpon>
</Compile>
<Compile Include="Converters\IsNotNullVisibilityConverter.cs" />
<Compile Include="Enums\RunMode.cs" />
<Compile Include="Extensions\ReactiveUIExt.cs" />
<Compile Include="Views\InstallationView.xaml.cs">
<DependentUpon>InstallationView.xaml</DependentUpon>
</Compile>
<Compile Include="Util\CPUStatus.cs" />
<Compile Include="View Models\CompilerVM.cs" />
<Compile Include="View Models\MainWindowVM.cs" />
<Compile Include="Views\SlideshowView.xaml.cs">
<DependentUpon>SlideshowView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModlistPropertiesWindow.xaml.cs">
<DependentUpon>ModlistPropertiesWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModeSelectionWindow.xaml.cs">
<DependentUpon>ModeSelectionWindow.xaml</DependentUpon>
</Compile>
@ -244,6 +248,14 @@
<Compile Include="Views\TextViewer.xaml.cs">
<DependentUpon>TextViewer.xaml</DependentUpon>
</Compile>
<Page Include="Views\CompilerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\InstallationView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\SlideshowView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -256,7 +268,7 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="View Models\AppState.cs" />
<Compile Include="View Models\InstallerVM.cs" />
<Compile Include="Util\AutoScrollBehavior.cs" />
<Compile Include="Views\MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
@ -266,10 +278,6 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ModlistPropertiesWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\Styles.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>