Tons of GUI work

This commit is contained in:
Timothy Baldridge 2019-07-30 21:59:19 -06:00
parent 13e839156d
commit 12a6b12a65
14 changed files with 3460 additions and 24 deletions

View File

@ -87,9 +87,19 @@ namespace Wabbajack.Common
File.WriteAllText(filename, JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings() {TypeNameHandling = TypeNameHandling.Auto}));
}
public static string ToJSON<T>(this T obj)
{
return JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto });
}
public static T FromJSON<T>(this string filename)
{
return JsonConvert.DeserializeObject<T>(File.ReadAllText(filename));
return JsonConvert.DeserializeObject<T>(File.ReadAllText(filename), new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto });
}
public static T FromJSONString<T>(this string data)
{
return JsonConvert.DeserializeObject<T>(data, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto });
}
public static T FromJSON<T>(this Stream data)
{

View File

@ -21,26 +21,37 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug (no commandargs)|Any CPU = Debug (no commandargs)|Any CPU
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}.Debug (no commandargs)|Any CPU.ActiveCfg = Debug|Any CPU
{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}.Debug (no commandargs)|Any CPU.Build.0 = Debug|Any CPU
{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3F3FB6E-B9EB-4F49-9875-D78578BC7AE5}.Release|Any CPU.Build.0 = Release|Any CPU
{8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug (no commandargs)|Any CPU.ActiveCfg = Debug|Any CPU
{8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug (no commandargs)|Any CPU.Build.0 = Debug|Any CPU
{8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8AA97F58-5044-4BBA-B8D9-A74B6947A660}.Release|Any CPU.Build.0 = Release|Any CPU
{33602679-8484-40C7-A10C-774DFF5D8314}.Debug (no commandargs)|Any CPU.ActiveCfg = Debug (no commandargs)|Any CPU
{33602679-8484-40C7-A10C-774DFF5D8314}.Debug (no commandargs)|Any CPU.Build.0 = Debug (no commandargs)|Any CPU
{33602679-8484-40C7-A10C-774DFF5D8314}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33602679-8484-40C7-A10C-774DFF5D8314}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33602679-8484-40C7-A10C-774DFF5D8314}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33602679-8484-40C7-A10C-774DFF5D8314}.Release|Any CPU.Build.0 = Release|Any CPU
{FF5D892F-8FF4-44FC-8F7F-CD58F307AD1B}.Debug (no commandargs)|Any CPU.ActiveCfg = Debug|Any CPU
{FF5D892F-8FF4-44FC-8F7F-CD58F307AD1B}.Debug (no commandargs)|Any CPU.Build.0 = Debug|Any CPU
{FF5D892F-8FF4-44FC-8F7F-CD58F307AD1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF5D892F-8FF4-44FC-8F7F-CD58F307AD1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF5D892F-8FF4-44FC-8F7F-CD58F307AD1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF5D892F-8FF4-44FC-8F7F-CD58F307AD1B}.Release|Any CPU.Build.0 = Release|Any CPU
{BA2CFEA1-072B-42D6-822A-8C6D0E3AE5D9}.Debug (no commandargs)|Any CPU.ActiveCfg = Debug|Any CPU
{BA2CFEA1-072B-42D6-822A-8C6D0E3AE5D9}.Debug (no commandargs)|Any CPU.Build.0 = Debug|Any CPU
{BA2CFEA1-072B-42D6-822A-8C6D0E3AE5D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA2CFEA1-072B-42D6-822A-8C6D0E3AE5D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA2CFEA1-072B-42D6-822A-8C6D0E3AE5D9}.Release|Any CPU.ActiveCfg = Release|Any CPU

View File

@ -5,6 +5,8 @@ using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using Wabbajack.Common;
@ -48,8 +50,11 @@ namespace Wabbajack
}
}
private string _mo2Folder;
private string _modListName;
private ModList _modList;
private string _location;
public string ModListName
{
get
@ -63,6 +68,19 @@ namespace Wabbajack
}
}
public string Location
{
get
{
return _location;
}
set
{
_location = value;
OnPropertyChanged("Location");
}
}
private List<CPUStatus> InternalStatus { get; }
public string LogFile { get; private set; }
@ -113,6 +131,16 @@ namespace Wabbajack
}
}
internal void ConfigureForInstall(string modlist)
{
MessageBox.Show("Hello, world!");
_modList = modlist.FromJSONString<ModList>();
Mode = "Installing";
ModListName = _modList.Name;
Location = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
public void LogMsg(string msg)
{
dispatcher.Invoke(() => Log.Add(msg));
@ -134,5 +162,103 @@ namespace Wabbajack
InternalStatus[id] = new CPUStatus() { ID = id, Msg = msg, Progress = progress };
}
}
private ICommand _changePath;
public ICommand ChangePath
{
get
{
if (_changePath == null)
{
_changePath = new LambdaCommand(() => true, () => this.ExecuteChangePath());
}
return _changePath;
}
}
private void ExecuteChangePath()
{
if (Mode == "Installing")
{
var ofd = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
ofd.Description = "Select Installation Directory";
ofd.UseDescriptionForTitle = true;
if (ofd.ShowDialog() == true)
{
Location = ofd.SelectedPath;
}
}
else
{
var fsd = new Ookii.Dialogs.Wpf.VistaOpenFileDialog();
fsd.Title = "Select a ModOrganizer modlist.txt file";
fsd.Filter = "modlist.txt|modlist.txt";
if (fsd.ShowDialog() == true)
{
Location = fsd.FileName;
ConfigureForBuild();
}
}
}
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")))
LogMsg($"Error! No ModOrganizer2.exe found in {mo2folder}");
var profile_name = Path.GetFileName(profile_folder);
ModListName = profile_name;
Mode = "Building";
_mo2Folder = mo2folder;
}
private ICommand _begin;
public ICommand Begin
{
get
{
if (_begin == null)
{
_begin = new LambdaCommand(() => true, () => this.ExecuteBegin());
}
return _begin;
}
}
private void ExecuteBegin()
{
if (Mode == "Installing")
{
var installer = new Installer(_modList, Location, msg => this.LogMsg(msg));
var th = new Thread(() =>
{
try
{
installer.Install();
}
catch (Exception ex)
{
LogMsg(ex.ToString());
LogMsg(ex.StackTrace);
}
});
th.Priority = ThreadPriority.BelowNormal;
th.Start();
}
else
{
var compiler = new Compiler(_mo2Folder, msg => LogMsg(msg));
compiler.MO2Profile = ModListName;
var th = new Thread(() =>
{
compiler.LoadArchives();
compiler.Compile();
});
th.Priority = ThreadPriority.BelowNormal;
th.Start();
}
}
}
}

View File

@ -732,7 +732,8 @@ namespace Wabbajack
internal void PatchExecutable()
{
var data = JsonConvert.SerializeObject(ModList).BZip2String();
var settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto };
var data = JsonConvert.SerializeObject(ModList, settings).BZip2String();
var executable = Assembly.GetExecutingAssembly().Location;
var out_path = Path.Combine(Path.GetDirectoryName(executable), MO2Profile + ".exe");
Info("Patching Executable {0}", Path.GetFileName(out_path));

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@ -347,5 +348,32 @@ namespace Wabbajack
}
public static string CheckForModPack()
{
using (var s = File.OpenRead(Assembly.GetExecutingAssembly().Location))
{
var magic_bytes = Encoding.ASCII.GetBytes(Consts.ModPackMagic);
s.Position = s.Length - magic_bytes.Length;
using (var br = new BinaryReader(s))
{
var bytes = br.ReadBytes(magic_bytes.Length);
var magic = Encoding.ASCII.GetString(bytes);
if (magic != Consts.ModPackMagic)
{
return null;
}
s.Position = s.Length - magic_bytes.Length - 8;
var start_pos = br.ReadInt64();
s.Position = start_pos;
long length = br.ReadInt64();
return br.ReadBytes((int)length).BZip2String();
}
}
}
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Windows.Input;
namespace Wabbajack
{
internal class LambdaCommand : ICommand
{
private Action _execute;
private Func<bool> _canExecute;
public event EventHandler CanExecuteChanged;
public LambdaCommand(Func<bool> canExecute, Action execute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
}
}

View File

@ -5,21 +5,33 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Wabbajack"
mc:Ignorable="d"
Title="Wabbajack" Height="600" Width="800"
Title="Wabbajack" Height="700" Width="800"
Style="{StaticResource {x:Type Window}}" Icon="square_transparent_icon.ico" WindowStyle="ToolWindow">
<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0, 16, 0, 16">
<TextBlock Text="{Binding Mode}" FontSize="16" FontWeight="Bold"></TextBlock>
<TextBlock Text=" : " FontSize="16"></TextBlock>
<TextBlock Text="{Binding ModListName}" FontSize="16"></TextBlock>
</StackPanel>
<ListBox Grid.Row ="1" ItemsSource="{Binding Status}" Width="Auto" HorizontalAlignment="Stretch">
<Grid HorizontalAlignment="Stretch" Grid.Row="1" Margin="0, 10, 0, 10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="Location:" Grid.Column="0"></Label>
<TextBox Grid.Column="1" Text="{Binding Location}"></TextBox>
<Button Content="Select" MinWidth="80" Grid.Column="2" Command="{Binding ChangePath}"></Button>
</Grid>
<ListBox Grid.Row ="2" ItemsSource="{Binding Status}" Width="Auto" HorizontalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
@ -50,8 +62,9 @@
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Text="Log:" Grid.Row="2" FontSize="14" Margin="0, 16, 0, 8"></TextBlock>
<ListBox local:AutoScrollBehavior.ScrollOnNewItem="True" Grid.Row ="3" ItemsSource="{Binding Log}">
<TextBlock Text="Log:" Grid.Row="3" FontSize="14" Margin="0, 16, 0, 8"></TextBlock>
<ListBox local:AutoScrollBehavior.ScrollOnNewItem="True" Grid.Row ="4" ItemsSource="{Binding Log}">
</ListBox>
<Button Content="Begin" Grid.Row="5" Height="30" Command="{Binding Begin}"></Button>
</Grid>
</Window>

View File

@ -25,38 +25,62 @@ namespace Wabbajack
{
public MainWindow()
{
var args = Environment.GetCommandLineArgs();
bool DebugMode = false;
string MO2Folder = null, InstallFolder = null, MO2Profile = null;
if (args.Length > 1)
{
DebugMode = true;
MO2Folder = args[1];
MO2Profile = args[2];
InstallFolder = args[3];
}
InitializeComponent();
var context = new AppState(Dispatcher, "Building");
this.DataContext = context;
WorkQueue.Init((id, msg, progress) => context.SetProgress(id, msg, progress));
var compiler = new Compiler("c:\\Mod Organizer 2", msg => context.LogMsg(msg));
compiler.MO2Profile = "DEV"; //"Basic Graphics and Fixes";
context.ModListName = compiler.MO2Profile;
context.Mode = "Building";
new Thread(() =>
if (DebugMode)
{
compiler.LoadArchives();
compiler.Compile();
new Thread(() =>
{
var compiler = new Compiler(MO2Folder, msg => context.LogMsg(msg));
compiler.MO2Profile = MO2Profile;
context.ModListName = compiler.MO2Profile;
context.Mode = "Building";
compiler.LoadArchives();
compiler.Compile();
compiler.ModList.ToJSON("C:\\tmp\\modpack.json");
var modlist = compiler.ModList;
var create = modlist.Directives.OfType<CreateBSA>().ToList();
compiler = null;
var installer = new Installer(modlist, "c:\\tmp\\install\\", msg => context.LogMsg(msg));
installer.Install();
var modlist = compiler.ModList.ToJSON();
compiler = null;
}).Start();
context.ConfigureForInstall(modlist);
}).Start();
}
else
{
new Thread(() =>
{
var modlist = Installer.CheckForModPack();
context.LogMsg($"Modlist returned {modlist != null}");
if (modlist == null)
{
}
else
{
context.ConfigureForInstall(modlist);
}
}).Start();
}
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace DarkBlendTheme
{
public class LeftMarginMultiplierConverter : IValueConverter
{
public double Length { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var item = value as TreeViewItem;
if (item == null)
return new Thickness(0);
return new Thickness(Length * item.GetDepth(), 0, 0, 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
}

3096
Wabbajack/Themes/Styles.xaml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
namespace DarkBlendTheme
{
public static class TreeViewItemExtensions
{
public static int GetDepth(this TreeViewItem item)
{
TreeViewItem parent;
while ((parent = GetParent(item)) != null)
{
return GetDepth(parent) + 1;
}
return 0;
}
private static TreeViewItem GetParent(TreeViewItem item)
{
var parent = VisualTreeHelper.GetParent(item);
while (!(parent is TreeViewItem || parent is TreeView))
{
if (parent == null) return null;
parent = VisualTreeHelper.GetParent(parent);
}
return parent as TreeViewItem;
}
}
}

View File

@ -40,6 +40,16 @@
<PropertyGroup>
<ApplicationIcon>square_transparent_icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug %28no commandargs%29|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug %28no commandargs%29\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Costura, Version=4.0.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
<HintPath>..\packages\Costura.Fody.4.0.0\lib\net40\Costura.dll</HintPath>
@ -47,12 +57,19 @@
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Ookii.Dialogs.Wpf, Version=1.0.0.0, Culture=neutral, PublicKeyToken=66aa232afad40158, processorArchitecture=MSIL">
<HintPath>..\packages\Ookii.Dialogs.Wpf.1.1.0\lib\net45\Ookii.Dialogs.Wpf.dll</HintPath>
</Reference>
<Reference Include="SharpCompress, Version=0.23.0.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>..\packages\SharpCompress.0.23.0\lib\net45\SharpCompress.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Security" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
@ -74,6 +91,7 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="LambdaCommand.cs" />
<Compile Include="Themes\LeftMarginMultiplierConverter.cs" />
<Compile Include="Themes\TreeViewItemExtensions.cs" />
<Page Include="MainWindow.xaml">

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<StartArguments>"c:\Mod Organizer 2" "Nexus SSO Test" "c:\tmp\validate"</StartArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug %28no commandargs%29|AnyCPU'">
<StartArguments>
</StartArguments>
</PropertyGroup>
</Project>

View File

@ -3,6 +3,7 @@
<package id="Costura.Fody" version="4.0.0" targetFramework="net472" />
<package id="Fody" version="5.1.1" targetFramework="net472" developmentDependency="true" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" />
<package id="Ookii.Dialogs.Wpf" version="1.1.0" targetFramework="net472" />
<package id="SharpCompress" version="0.23.0" targetFramework="net472" />
<package id="WebSocketSharpFork" version="1.0.4.0" targetFramework="net472" />
<package id="WPFThemes.DarkBlend" version="1.0.8" targetFramework="net472" />