Merge pull request #162 from Noggog/CompilerView-revamp

Compiler view revamp
This commit is contained in:
Timothy Baldridge 2019-11-09 20:56:41 -07:00 committed by GitHub
commit 69dd759dd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1340 additions and 917 deletions

View File

@ -77,6 +77,12 @@ namespace Wabbajack
return new ErrorResponse(successful, reason);
}
#endregion
public static ErrorResponse Convert(IErrorResponse err, bool nullIsSuccess = true)
{
if (err == null) return ErrorResponse.Create(nullIsSuccess);
return new ErrorResponse(err.Succeeded, err.Reason, err.Exception);
}
}
public interface IErrorResponse

View File

@ -168,5 +168,10 @@ namespace Wabbajack
.Select(x => x as R)
.NotNull();
}
public static IObservable<bool> Invert(this IObservable<bool> source)
{
return source.Select(x => !x);
}
}
}

View File

@ -0,0 +1,19 @@
<UserControl
x:Class="Wabbajack.BorderFadeDownView"
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"
d:DesignHeight="450"
d:DesignWidth="5"
mc:Ignorable="d">
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#191919" />
<GradientStop Offset="0.4" Color="#00191919" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</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 BorderFadeDownView.xaml
/// </summary>
public partial class BorderFadeDownView : UserControl
{
public BorderFadeDownView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,36 @@
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.Data;
namespace Wabbajack
{
[ValueConversion(typeof(Visibility), typeof(bool))]
public class BoolToVisibilityHiddenConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(Visibility))
throw new InvalidOperationException($"The target must be of type {nameof(Visibility)}");
bool compareTo = true;
if (parameter is bool p)
{
compareTo = p;
}
else if (parameter is string str && str.ToUpper().Equals("FALSE"))
{
compareTo = false;
}
return ((bool)value) == compareTo ? Visibility.Visible : Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,29 @@
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.Data;
namespace Wabbajack
{
[ValueConversion(typeof(bool), typeof(bool))]
public class InverseBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(bool))
throw new InvalidOperationException($"The target must be of type bool");
return !((bool)value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(bool))
throw new InvalidOperationException($"The target must be of type bool");
return !((bool)value);
}
}
}

View File

@ -64,7 +64,6 @@ namespace Wabbajack
public string Website { get; set; }
public string Readme { get; set; }
public string SplashScreen { get; set; }
public string Location { get; set; }
public string DownloadLocation { get; set; }
}
}

View File

@ -9,6 +9,8 @@
<!--Converters-->
<local:BoolToVisibilityConverter x:Key="bool2VisibilityConverter" />
<local:BoolToVisibilityHiddenConverter x:Key="bool2VisibilityHiddenConverter" />
<local:InverseBooleanConverter x:Key="InverseBooleanConverter" />
<local:IsNotNullVisibilityConverter x:Key="IsNotNullVisibilityConverter"/>
<!--Colors-->

View File

@ -17,25 +17,25 @@ namespace Wabbajack
{
public MainWindowVM MWVM { get; }
[Reactive]
public string Mo2Folder { get; set; }
private readonly ObservableAsPropertyHelper<string> _Mo2Folder;
public string Mo2Folder => _Mo2Folder.Value;
[Reactive]
public string MOProfile { get; set; }
private readonly ObservableAsPropertyHelper<string> _MOProfile;
public string MOProfile => _MOProfile.Value;
[Reactive]
public string ModListName { get; set; }
public FilePickerVM Location { get; }
public FilePickerVM ModlistLocation { get; }
[Reactive]
public bool UIReady { get; set; } = true;
public bool Compiling { get; set; }
[Reactive]
public string AuthorName { get; set; }
public string AuthorText { get; set; }
[Reactive]
public string Summary { get; set; } = "Description (700 characters max)";
public string Description { get; set; }
public FilePickerVM ImagePath { get; }
@ -57,16 +57,18 @@ namespace Wabbajack
public CompilerVM(MainWindowVM mainWindowVM, string source)
{
this.MWVM = mainWindowVM;
this.Location = new FilePickerVM()
this.ModlistLocation = new FilePickerVM()
{
TargetPath = source,
DoExistsCheck = false,
DoExistsCheck = true,
PathType = FilePickerVM.PathTypeOptions.File,
PromptTitle = "Select Modlist"
};
this.DownloadLocation = new FilePickerVM()
{
DoExistsCheck = false,
DoExistsCheck = true,
PathType = FilePickerVM.PathTypeOptions.Folder,
PromptTitle = "Select Download Location",
};
this.ImagePath = new FilePickerVM()
{
@ -85,7 +87,11 @@ namespace Wabbajack
this.BeginCommand = ReactiveCommand.CreateFromTask(
execute: this.ExecuteBegin,
canExecute: this.WhenAny(x => x.UIReady)
canExecute: Observable.CombineLatest(
this.WhenAny(x => x.Compiling),
this.WhenAny(x => x.ModlistLocation.InError),
this.WhenAny(x => x.DownloadLocation.InError),
resultSelector: (c, ml, down) => !c && !ml && !down)
.ObserveOnGuiThread());
this._Image = this.WhenAny(x => x.ImagePath.TargetPath)
@ -100,13 +106,73 @@ namespace Wabbajack
})
.ToProperty(this, nameof(this.Image));
ConfigureForBuild(source);
this._Mo2Folder = this.WhenAny(x => x.ModlistLocation.TargetPath)
.Select(loc =>
{
try
{
var profile_folder = Path.GetDirectoryName(loc);
return Path.GetDirectoryName(Path.GetDirectoryName(profile_folder));
}
catch (Exception)
{
return null;
}
})
.ToProperty(this, nameof(this.Mo2Folder));
this._MOProfile = this.WhenAny(x => x.ModlistLocation.TargetPath)
.Select(loc =>
{
try
{
var profile_folder = Path.GetDirectoryName(loc);
return Path.GetFileName(profile_folder);
}
catch (Exception)
{
return null;
}
})
.ToProperty(this, nameof(this.MOProfile));
// If Mo2 folder changes and download location is empty, set it for convenience
this.WhenAny(x => x.Mo2Folder)
.Where(x => Directory.Exists(x))
.Subscribe(x =>
{
try
{
var tmp_compiler = new Compiler(this.Mo2Folder);
this.DownloadLocation.TargetPath = tmp_compiler.MO2DownloadsFolder;
}
catch (Exception ex)
{
Utils.Log($"Error setting default download location {ex}");
}
})
.DisposeWith(this.CompositeDisposable);
// Wire missing Mo2Folder to signal error state for Modlist Location
this.ModlistLocation.AdditionalError = this.WhenAny(x => x.Mo2Folder)
.Select<string, IErrorResponse>(moFolder =>
{
if (Directory.Exists(moFolder)) return ErrorResponse.Success;
return ErrorResponse.Fail($"MO2 Folder could not be located from the given modlist location.{Environment.NewLine}Make sure your modlist is inside a valid MO2 distribution.");
});
// Load settings
CompilationSettings settings = this.MWVM.Settings.CompilationSettings.TryCreate(source);
this.AuthorName = settings.Author;
this.ModListName = settings.ModListName;
this.Summary = settings.Description;
this.AuthorText = settings.Author;
if (string.IsNullOrWhiteSpace(settings.ModListName))
{
// Set ModlistName initially off just the MO2Profile
this.ModListName = this.MOProfile;
}
else
{
this.ModListName = settings.ModListName;
}
this.Description = settings.Description;
this.ReadMeText.TargetPath = settings.Readme;
this.ImagePath.TargetPath = settings.SplashScreen;
this.Website = settings.Website;
@ -114,82 +180,63 @@ namespace Wabbajack
{
this.DownloadLocation.TargetPath = settings.DownloadLocation;
}
if (!string.IsNullOrWhiteSpace(settings.Location))
{
this.Location.TargetPath = settings.Location;
}
this.MWVM.Settings.SaveSignal
.Subscribe(_ =>
{
settings.Author = this.AuthorName;
settings.Author = this.AuthorText;
settings.ModListName = this.ModListName;
settings.Description = this.Summary;
settings.Description = this.Description;
settings.Readme = this.ReadMeText.TargetPath;
settings.SplashScreen = this.ImagePath.TargetPath;
settings.Website = this.Website;
settings.Location = this.Location.TargetPath;
settings.DownloadLocation = this.DownloadLocation.TargetPath;
})
.DisposeWith(this.CompositeDisposable);
}
private void ConfigureForBuild(string location)
{
var profile_folder = Path.GetDirectoryName(location);
this.Mo2Folder = Path.GetDirectoryName(Path.GetDirectoryName(profile_folder));
if (!File.Exists(Path.Combine(this.Mo2Folder, "ModOrganizer.exe")))
{
Utils.Log($"Error! No ModOrganizer2.exe found in {this.Mo2Folder}");
}
this.MOProfile = Path.GetFileName(profile_folder);
this.ModListName = this.MOProfile;
var tmp_compiler = new Compiler(this.Mo2Folder);
this.DownloadLocation.TargetPath = tmp_compiler.MO2DownloadsFolder;
}
private async Task ExecuteBegin()
{
if (this.Mo2Folder != null)
Compiler compiler;
try
{
var compiler = new Compiler(this.Mo2Folder)
compiler = new Compiler(this.Mo2Folder)
{
MO2Profile = this.MOProfile,
ModListName = this.ModListName,
ModListAuthor = this.AuthorName,
ModListDescription = this.Summary,
ModListAuthor = this.AuthorText,
ModListDescription = this.Description,
ModListImage = this.ImagePath.TargetPath,
ModListWebsite = this.Website,
ModListReadme = this.ReadMeText.TargetPath,
};
await Task.Run(() =>
{
UIReady = false;
try
{
compiler.Compile();
if (compiler.ModList?.ReportHTML != null)
{
this.HTMLReport = compiler.ModList.ReportHTML;
}
}
catch (Exception ex)
{
while (ex.InnerException != null) ex = ex.InnerException;
Utils.Log($"Can't continue: {ex.ExceptionToString()}");
}
finally
{
UIReady = true;
}
});
}
else
catch (Exception ex)
{
Utils.Log("Cannot compile modlist: no valid Mod Organizer profile directory selected.");
UIReady = true;
while (ex.InnerException != null) ex = ex.InnerException;
Utils.Log($"Compiler error: {ex.ExceptionToString()}");
return;
}
await Task.Run(() =>
{
Compiling = true;
try
{
compiler.Compile();
if (compiler.ModList?.ReportHTML != null)
{
this.HTMLReport = compiler.ModList.ReportHTML;
}
}
catch (Exception ex)
{
while (ex.InnerException != null) ex = ex.InnerException;
Utils.Log($"Compiler error: {ex.ExceptionToString()}");
}
finally
{
Compiling = false;
}
});
}
}
}

View File

@ -46,6 +46,9 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<bool> _Exists;
public bool Exists => _Exists.Value;
private readonly ObservableAsPropertyHelper<ErrorResponse> _ErrorState;
public ErrorResponse ErrorState => _ErrorState.Value;
private readonly ObservableAsPropertyHelper<bool> _InError;
public bool InError => _InError.Value;
@ -96,15 +99,25 @@ namespace Wabbajack
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, nameof(this.Exists));
this._InError = Observable.CombineLatest(
this.WhenAny(x => x.Exists),
this._ErrorState = Observable.CombineLatest(
this.WhenAny(x => x.Exists)
.Select(exists => ErrorResponse.Create(successful: exists, exists ? default(string) : "Path does not exist")),
this.WhenAny(x => x.AdditionalError)
.Select(x => x ?? Observable.Return<IErrorResponse>(ErrorResponse.Success))
.Switch()
.Select(err => !err?.Succeeded ?? false),
resultSelector: (exist, err) => !exist || err)
.Switch(),
resultSelector: (exist, err) =>
{
if (exist.Failed) return exist;
return ErrorResponse.Convert(err);
})
.ToProperty(this, nameof(this.ErrorState));
this._InError = this.WhenAny(x => x.ErrorState)
.Select(x => !x.Succeeded)
.ToProperty(this, nameof(this.InError));
// Doesn't derive from ErrorState, as we want to bubble non-empty tooltips,
// which is slightly different logic
this._ErrorTooltip = Observable.CombineLatest(
this.WhenAny(x => x.Exists)
.Select(exists => exists ? default(string) : "Path does not exist"),
@ -113,12 +126,8 @@ namespace Wabbajack
.Switch(),
resultSelector: (exists, err) =>
{
if ((!err?.Succeeded ?? false)
&& !string.IsNullOrWhiteSpace(err.Reason))
{
return err.Reason;
}
return exists;
if (!string.IsNullOrWhiteSpace(exists)) return exists;
return err?.Reason;
})
.ToProperty(this, nameof(this.ErrorTooltip));
}

View File

@ -14,6 +14,7 @@ using System.Windows.Media.Imaging;
using Wabbajack.Common;
using Wabbajack.Lib;
using ReactiveUI.Fody.Helpers;
using System.Windows.Media;
namespace Wabbajack
{
@ -56,8 +57,8 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<float> _ProgressPercent;
public float ProgressPercent => _ProgressPercent.Value;
private readonly ObservableAsPropertyHelper<BitmapImage> _Image;
public BitmapImage Image => _Image.Value;
private readonly ObservableAsPropertyHelper<ImageSource> _Image;
public ImageSource Image => _Image.Value;
private readonly ObservableAsPropertyHelper<string> _TitleText;
public string TitleText => _TitleText.Value;
@ -68,6 +69,12 @@ namespace Wabbajack
private readonly ObservableAsPropertyHelper<string> _Description;
public string Description => _Description.Value;
private readonly ObservableAsPropertyHelper<string> _ProgressTitle;
public string ProgressTitle => _ProgressTitle.Value;
private readonly ObservableAsPropertyHelper<string> _ModListName;
public string ModListName => _ModListName.Value;
// Command properties
public IReactiveCommand BeginCommand { get; }
public IReactiveCommand ShowReportCommand { get; }
@ -172,6 +179,7 @@ namespace Wabbajack
.StartWith(default(BitmapImage)),
this.WhenAny(x => x.Installing),
resultSelector: (modList, slideshow, installing) => installing ? slideshow : modList)
.Select<BitmapImage, ImageSource>(x => x)
.ToProperty(this, nameof(this.Image));
this._TitleText = Observable.CombineLatest(
this.WhenAny(x => x.ModList.Name),
@ -194,6 +202,9 @@ namespace Wabbajack
this.WhenAny(x => x.Installing),
resultSelector: (modList, mod, installing) => installing ? mod : modList)
.ToProperty(this, nameof(this.Description));
this._ModListName = this.WhenAny(x => x.ModList)
.Select(x => x?.Name)
.ToProperty(this, nameof(this.ModListName));
// Define commands
this.ShowReportCommand = ReactiveCommand.Create(ShowReport);
@ -231,6 +242,16 @@ namespace Wabbajack
}
})
.DisposeWith(this.CompositeDisposable);
this._ProgressTitle = Observable.CombineLatest(
this.WhenAny(x => x.Installing),
this.WhenAny(x => x.InstallingMode),
resultSelector: (installing, mode) =>
{
if (!installing) return "Configuring";
return mode ? "Installing" : "Installed";
})
.ToProperty(this, nameof(this.ProgressTitle));
}
private void ShowReport()

View File

@ -0,0 +1,87 @@
<UserControl
x:Class="Wabbajack.BeginButton"
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:icon="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:local="clr-namespace:Wabbajack"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Border
x:Name="BeginButtonPurpleGlow"
Width="76"
Height="76"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{StaticResource PrimaryVariantBrush}"
CornerRadius="43"
Visibility="{Binding IsEnabled, ElementName=button, Converter={StaticResource bool2VisibilityHiddenConverter}}">
<Border.Effect>
<BlurEffect Radius="10" />
</Border.Effect>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Opacity" Value="0.5" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=BeginButton}" Value="True">
<Setter Property="Opacity" Value="0.8" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Button
x:Name="button"
Width="54"
Height="54"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Command="{Binding Command, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
<icon:PackIconMaterial
Width="25"
Height="25"
Margin="5,0,0,0"
Kind="Play">
<icon:PackIconMaterial.Style>
<Style TargetType="icon:PackIconMaterial">
<Setter Property="Foreground" Value="#666666" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="True">
<Setter Property="Foreground" Value="{StaticResource SecondaryBrush}" />
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="True" />
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Foreground" Value="#00ffe7" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</icon:PackIconMaterial.Style>
</icon:PackIconMaterial>
<Button.Style>
<Style BasedOn="{StaticResource CircleButtonStyle}" TargetType="Button">
<Setter Property="Background" Value="#333333" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource SecondaryBrush}" />
<Setter Property="Background" Value="#222222" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect
BlurRadius="15"
ShadowDepth="0"
Color="{StaticResource Secondary}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</UserControl>

View File

@ -0,0 +1,36 @@
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 BeginButton.xaml
/// </summary>
public partial class BeginButton : UserControl
{
public ICommand Command
{
get => (ICommand)GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(BeginButton),
new FrameworkPropertyMetadata(default(ICommand)));
public BeginButton()
{
InitializeComponent();
}
}
}

View File

@ -6,251 +6,203 @@
xmlns:local="clr-namespace:Wabbajack"
xmlns:mahapps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignInstance local:CompilerVM}"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<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>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="45" />
<RowDefinition Height="4*" />
<RowDefinition Height="*" MinHeight="150" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="5" />
</Grid.ColumnDefinitions>
<local:BorderFadeDownView
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="0" />
<local:BorderFadeDownView
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="4" />
<local:DetailImageView
Title="{Binding ModListName}"
Grid.Row="1"
Grid.Column="3"
Author="{Binding AuthorText}"
BorderThickness="0"
Description="{Binding Description}"
Image="{Binding Image}" />
<Rectangle
x:Name="ControlVerticalThinSeparator"
Grid.Row="1"
Grid.Column="2"
Width="1"
HorizontalAlignment="Center"
Fill="{StaticResource DarkBackgroundBrush}"
SnapsToDevicePixels="True" />
<!-- Comes after image area so shadow can overlay -->
<local:TopProgressView
Title="{Binding ModListName, Mode=OneWay}"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="5"
OverhangShadow="True"
ProgressPercent="{Binding ProgressPercent}"
StatePrefixTitle="Compiling" />
<ScrollViewer
Grid.Row="1"
Grid.Column="1"
Margin="5,0,5,5"
Background="Transparent"
HorizontalScrollBarVisibility="Disabled"
IsEnabled="{Binding Compiling, Converter={StaticResource InverseBooleanConverter}}"
VerticalScrollBarVisibility="Auto">
<StackPanel
Grid.Row="0"
Margin="0,8,0,8"
Orientation="Horizontal">
<TextBlock
FontSize="16"
FontWeight="Bold"
Text="Compiling" />
<TextBlock FontSize="16" Text=" : " />
<TextBlock FontSize="16" Text="{Binding MOProfile}" />
</StackPanel>
<Grid
Grid.Row="1"
Grid.Column="0"
Margin="0,8,0,8"
IsEnabled="{Binding UIReady}">
<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="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Splash Screen Path:" />
<local:FilePicker
Grid.Column="1"
Width="534"
HorizontalAlignment="Left"
DataContext="{Binding ImagePath}"
IsEnabled="{Binding UIReady}" />
</Grid>
</Grid>
<ScrollViewer
Grid.Row="1"
Grid.Column="2"
Margin="0,5,0,0"
Background="Transparent"
HorizontalScrollBarVisibility="Disabled"
IsEnabled="{Binding UIReady}"
VerticalScrollBarVisibility="Auto">
<StackPanel Background="Transparent" Orientation="Vertical">
<StackPanel.Resources>
<Thickness
x:Key="TitleMargin"
Bottom="1"
Left="5" />
<Style
x:Key="ValueStyle"
BasedOn="{StaticResource MainTextBoxStyle}"
TargetType="TextBox">
<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 Margin="{StaticResource TitleMargin}" Text="ModList Name" />
<TextBox Style="{StaticResource ValueStyle}" Text="{Binding ModListName}" />
<TextBlock Margin="{StaticResource TitleMargin}" Text="Author" />
<TextBox Style="{StaticResource ValueStyle}" Text="{Binding AuthorName}" />
<TextBlock Margin="{StaticResource TitleMargin}" Text="Description" />
<TextBox
Height="150"
mahapps:TextBoxHelper.Watermark="(700 characters max)"
AcceptsReturn="True"
AcceptsTab="False"
MaxLength="700"
Style="{StaticResource ValueStyle}"
Text="{Binding Summary}"
TextWrapping="Wrap" />
<TextBlock Margin="{StaticResource TitleMargin}" Text="Website" />
<TextBox Style="{StaticResource ValueStyle}" Text="{Binding Website}" />
<TextBlock
Margin="{StaticResource TitleMargin}"
Text="Readme Path"
ToolTip="Path to a readme file." />
<local:FilePicker
DataContext="{Binding ReadMeText}"
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, Mode=OneWay}" />
<!-- 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 -->
Orientation="Vertical">
<StackPanel.Resources>
<Thickness
x:Key="TitleMargin"
Bottom="1"
Left="5" />
<Style
x:Key="ValueStyle"
BasedOn="{StaticResource MainTextBoxStyle}"
TargetType="TextBox">
<Setter Property="MaxLength" Value="50" />
<Setter Property="AcceptsTab" Value="False" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Margin" Value="0,0,0,6" />
</Style>
<Style x:Key="PickerStyle" TargetType="local:FilePicker">
<Setter Property="Margin" Value="0,0,0,6" />
</Style>
</StackPanel.Resources>
<TextBlock Margin="{StaticResource TitleMargin}" Text="ModList Name" />
<TextBox Style="{StaticResource ValueStyle}" Text="{Binding ModListName, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Margin="{StaticResource TitleMargin}" Text="Author" />
<TextBox Style="{StaticResource ValueStyle}" Text="{Binding AuthorText, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Margin="{StaticResource TitleMargin}" Text="Description" />
<TextBox
Height="150"
mahapps:TextBoxHelper.Watermark="(700 characters max)"
AcceptsReturn="True"
AcceptsTab="False"
MaxLength="700"
Style="{StaticResource ValueStyle}"
Text="{Binding Description, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" />
<TextBlock Margin="{StaticResource TitleMargin}" Text="Image" />
<local:FilePicker
DataContext="{Binding ImagePath}"
Style="{StaticResource PickerStyle}"
ToolTip="Path to an image to display for the modlist." />
<TextBlock Margin="{StaticResource TitleMargin}" Text="Website" />
<TextBox Style="{StaticResource ValueStyle}" Text="{Binding Website}" />
<TextBlock
Margin="{StaticResource TitleMargin}"
Text="Readme Path"
ToolTip="Path to a readme file." />
<local:FilePicker
DataContext="{Binding ReadMeText}"
Style="{StaticResource PickerStyle}"
ToolTip="Path to a readme file." />
</StackPanel>
</ScrollViewer>
<Rectangle
x:Name="ControlTopThinSeparator"
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="5"
Height="1"
Margin="25,0"
VerticalAlignment="Top"
Fill="{StaticResource DarkBackgroundBrush}"
SnapsToDevicePixels="True" />
<Grid
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="5"
MaxWidth="1000">
<Border
x:Name="ConfigurationBackgroundHaze"
Height="120"
Background="{StaticResource PrimaryVariantBrush}"
CornerRadius="50"
Opacity="0.10">
<Border.Effect>
<BlurEffect Radius="45" />
</Border.Effect>
</Border>
<Grid
Grid.Row="5"
Grid.RowSpan="2"
Grid.Column="0"
Margin="-4,10,0,10"
HorizontalAlignment="Stretch">
Margin="35,0,35,0"
VerticalAlignment="Center"
ClipToBounds="False"
Visibility="{Binding Compiling, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition MinHeight="10" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
<TextBlock
Grid.Row="0"
Grid.Column="0"
Content="Installation Location:" />
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontSize="14"
Text="Modlist Location"
TextAlignment="Center" />
<local:FilePicker
Grid.Row="0"
Grid.Column="1"
IsEnabled="{Binding UIReady}"
DataContext="{Binding Location}" />
<Label
Grid.Row="2"
Grid.Column="0"
Content="Download Location:" />
<local:FilePicker
Grid.Row="2"
Grid.Column="1"
IsEnabled="{Binding UIReady}"
DataContext="{Binding DownloadLocation}" />
</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.Column="2"
Height="30"
VerticalAlignment="Center"
DataContext="{Binding ModlistLocation}"
FontSize="14" />
<TextBlock
Grid.Row="1"
Margin="0,4,0,0"
Command="{Binding BeginCommand}">
<TextBlock FontSize="13" FontWeight="Bold">Begin</TextBlock>
</Button>
Grid.Column="0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
FontSize="14"
Text="Download Location"
TextAlignment="Center" />
<local:FilePicker
Grid.Row="1"
Grid.Column="2"
Height="30"
VerticalAlignment="Center"
DataContext="{Binding DownloadLocation}"
FontSize="14" />
<local:BeginButton
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="4"
Command="{Binding BeginCommand}" />
</Grid>
</Grid>
</Viewbox>
<Grid
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="5"
Margin="5"
Visibility="{Binding Compiling, Converter={StaticResource bool2VisibilityConverter}, FallbackValue=Hidden}">
<local:LogCpuView DataContext="{Binding MWVM}" />
</Grid>
</Grid>
</UserControl>

View File

@ -0,0 +1,195 @@
<UserControl
x:Class="Wabbajack.DetailImageView"
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:icon="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:local="clr-namespace:Wabbajack"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
ClipToBounds="True"
mc:Ignorable="d">
<UserControl.Resources>
<Color x:Key="TextBackgroundFill">#92000000</Color>
<SolidColorBrush x:Key="TextBackgroundFillBrush" Color="{StaticResource TextBackgroundFill}" />
<Color x:Key="TextBackgroundHoverFill">#DF000000</Color>
<Style x:Key="BackgroundBlurStyle" TargetType="TextBlock">
<Setter Property="Background" Value="{StaticResource TextBackgroundFillBrush}" />
<Setter Property="Foreground" Value="Transparent" />
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=TextHoverTrigger}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"
To="{StaticResource TextBackgroundHoverFill}"
Duration="0:0:0.06" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"
To="{StaticResource TextBackgroundFill}"
Duration="0:0:0.06" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger Binding="{Binding Image}" Value="{x:Null}">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle
Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="2"
Fill="{StaticResource WindowBackgroundBrush}" />
<Viewbox
Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="UniformToFill">
<Image Source="{Binding Image, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</Viewbox>
<Image
Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="2"
Width="60"
Height="60"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Source="{Binding Badge, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<TextBlock
x:Name="TitleTextShadow"
Grid.Row="2"
Grid.Column="0"
Margin="-20,15,40,-10"
Padding="40,10"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontSize="65"
FontWeight="Bold"
Style="{StaticResource BackgroundBlurStyle}"
Text="{Binding Title, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
TextWrapping="WrapWithOverflow">
<TextBlock.Effect>
<BlurEffect Radius="85" />
</TextBlock.Effect>
</TextBlock>
<TextBlock
x:Name="ArtistTextShadow"
Grid.Row="3"
Grid.Column="0"
Margin="35,-10,-10,10"
Padding="30,10"
HorizontalAlignment="Left"
FontFamily="Lucida Sans"
FontSize="30"
FontWeight="Bold"
Style="{StaticResource BackgroundBlurStyle}"
TextWrapping="WrapWithOverflow">
<TextBlock.Effect>
<BlurEffect Radius="55" />
</TextBlock.Effect>
<Run FontSize="15" Text="by" />
<Run Text="{Binding Author, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</TextBlock>
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="20,25,20,0"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontSize="65"
FontWeight="Bold"
Text="{Binding Title, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
TextWrapping="WrapWithOverflow">
<TextBlock.Effect>
<DropShadowEffect />
</TextBlock.Effect>
</TextBlock>
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="55,0,20,20"
FontFamily="Lucida Sans"
FontSize="30"
FontWeight="Bold"
TextWrapping="Wrap">
<TextBlock.Effect>
<DropShadowEffect />
</TextBlock.Effect>
<Run FontSize="15" Text="by" />
<Run Text="{Binding Author, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</TextBlock>
<TextBlock
x:Name="DescriptionTextShadow"
Grid.Row="2"
Grid.RowSpan="2"
Grid.Column="1"
Margin="-10,15,-5,15"
Padding="30,10"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontSize="16"
Style="{StaticResource BackgroundBlurStyle}"
Text="{Binding Description, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
TextAlignment="Right"
TextWrapping="Wrap">
<TextBlock.Effect>
<BlurEffect Radius="55" />
</TextBlock.Effect>
</TextBlock>
<TextBlock
Grid.Row="2"
Grid.RowSpan="2"
Grid.Column="1"
Margin="20,25,25,25"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontSize="16"
Text="{Binding Description, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
TextAlignment="Right"
TextWrapping="Wrap">
<TextBlock.Effect>
<DropShadowEffect />
</TextBlock.Effect>
</TextBlock>
<Rectangle
x:Name="TextHoverTrigger"
Grid.Row="2"
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Fill="Transparent" />
</Grid>
</UserControl>

View File

@ -0,0 +1,68 @@
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 DetailImageView.xaml
/// </summary>
public partial class DetailImageView : UserControl
{
public ImageSource Image
{
get => (ImageSource)GetValue(ImageProperty);
set => SetValue(ImageProperty, value);
}
public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(nameof(Image), typeof(ImageSource), typeof(DetailImageView),
new FrameworkPropertyMetadata(default(ImageSource)));
public ImageSource Badge
{
get => (ImageSource)GetValue(BadgeProperty);
set => SetValue(BadgeProperty, value);
}
public static readonly DependencyProperty BadgeProperty = DependencyProperty.Register(nameof(Badge), typeof(ImageSource), typeof(DetailImageView),
new FrameworkPropertyMetadata(default(ImageSource)));
public string Title
{
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(DetailImageView),
new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string Author
{
get => (string)GetValue(AuthorProperty);
set => SetValue(AuthorProperty, value);
}
public static readonly DependencyProperty AuthorProperty = DependencyProperty.Register(nameof(Author), typeof(string), typeof(DetailImageView),
new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string Description
{
get => (string)GetValue(DescriptionProperty);
set => SetValue(DescriptionProperty, value);
}
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(nameof(Description), typeof(string), typeof(DetailImageView),
new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public DetailImageView()
{
InitializeComponent();
}
}
}

View File

@ -7,45 +7,11 @@
xmlns:local="clr-namespace:Wabbajack"
xmlns:mahapps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignInstance local:InstallerVM}"
d:DesignHeight="500"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Resources>
<Color x:Key="TextBackgroundFill">#92000000</Color>
<SolidColorBrush x:Key="TextBackgroundFillBrush" Color="{StaticResource TextBackgroundFill}" />
<Color x:Key="TextBackgroundHoverFill">#DF000000</Color>
<Style x:Key="BackgroundBlurStyle" TargetType="TextBlock">
<Setter Property="Background" Value="{StaticResource TextBackgroundFillBrush}" />
<Setter Property="Foreground" Value="Transparent" />
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=TextHoverTrigger}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"
To="{StaticResource TextBackgroundHoverFill}"
Duration="0:0:0.06" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(TextBlock.Background).(SolidColorBrush.Color)"
To="{StaticResource TextBackgroundFill}"
Duration="0:0:0.06" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger Binding="{Binding Image}" Value="{x:Null}">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style
x:Key="SlideshowButton"
BasedOn="{StaticResource CircleButtonStyle}"
@ -57,433 +23,172 @@
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="5" />
<RowDefinition Height="45" />
<RowDefinition Height="4*" />
<RowDefinition Height="*" MinHeight="150" />
</Grid.RowDefinitions>
<Rectangle
<local:BorderFadeDownView
x:Name="BorderEdgeFadeDown"
Grid.Row="1"
Grid.RowSpan="3">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#191919" />
<GradientStop Offset="0.4" Color="#00191919" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<!-- Slideshow -->
<Border
Grid.RowSpan="2" />
<Grid
x:Name="Slideshow"
Grid.Row="2"
Margin="5,0,5,5"
BorderBrush="#171717"
BorderThickness="1,0,1,1"
UseLayoutRounding="True">
<Grid ClipToBounds="True">
Grid.Row="1"
Margin="5,0,5,5">
<Border BorderBrush="#171717" BorderThickness="1,0,1,1">
<local:DetailImageView
Title="{Binding TitleText, Mode=OneWay}"
Author="{Binding AuthorText, Mode=OneWay}"
Description="{Binding Description, Mode=OneWay}"
Image="{Binding Image, Mode=OneWay}" />
</Border>
<Grid
Margin="0,20,25,0"
HorizontalAlignment="Right"
VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle
Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="2"
Fill="{StaticResource WindowBackgroundBrush}" />
<Viewbox
Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="UniformToFill">
<Image Source="{Binding Image}" />
</Viewbox>
<Image
Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="2"
Width="60"
Height="60"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Source="{Binding ModlistImage}" />
<TextBlock
x:Name="TitleTextShadow"
Grid.Row="2"
Grid.Column="0"
Margin="-20,15,40,-10"
Padding="40,10"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontSize="65"
FontWeight="Bold"
Style="{StaticResource BackgroundBlurStyle}"
Text="{Binding TitleText}"
TextWrapping="WrapWithOverflow">
<TextBlock.Effect>
<BlurEffect Radius="85" />
</TextBlock.Effect>
</TextBlock>
<TextBlock
x:Name="ArtistTextShadow"
Grid.Row="3"
Grid.Column="0"
Margin="35,-10,-10,10"
Padding="30,10"
HorizontalAlignment="Left"
FontFamily="Lucida Sans"
FontSize="30"
FontWeight="Bold"
Style="{StaticResource BackgroundBlurStyle}"
TextWrapping="WrapWithOverflow">
<TextBlock.Effect>
<BlurEffect Radius="55" />
</TextBlock.Effect>
<Run FontSize="15" Text="by" />
<Run Text="{Binding AuthorText, Mode=OneWay}" />
</TextBlock>
<TextBlock
Grid.Row="2"
Grid.Column="0"
Margin="20,25,20,0"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontSize="65"
FontWeight="Bold"
Text="{Binding TitleText}"
TextWrapping="WrapWithOverflow">
<TextBlock.Effect>
<DropShadowEffect />
</TextBlock.Effect>
</TextBlock>
<TextBlock
Grid.Row="3"
Grid.Column="0"
Margin="55,0,20,20"
FontFamily="Lucida Sans"
FontSize="30"
FontWeight="Bold"
TextWrapping="Wrap">
<TextBlock.Effect>
<DropShadowEffect />
</TextBlock.Effect>
<Run FontSize="15" Text="by" />
<Run Text="{Binding AuthorText, Mode=OneWay}" />
</TextBlock>
<Grid
Grid.Row="0"
Grid.Column="1"
Margin="0,20,25,0"
HorizontalAlignment="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.Effect>
<DropShadowEffect
BlurRadius="25"
Opacity="1"
Color="Black" />
</Grid.Effect>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Opacity" Value="0" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, ElementName=Slideshow}" Value="True" />
<Condition Binding="{Binding Installing}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.12" />
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
<LinearDoubleKeyFrame KeyTime="0:0:0.3" Value="1" />
<LinearDoubleKeyFrame KeyTime="0:0:0.42" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Button
Grid.Column="3"
Width="60"
Height="60"
Margin="6"
Background="{StaticResource BackgroundBrush}"
Command="{Binding Slideshow.SlideShowNextItemCommand}"
Style="{StaticResource CircleButtonStyle}"
ToolTip="Skip to the next mod">
<icon:PackIconFontAwesome
Width="28"
Height="28"
Kind="ChevronRightSolid" />
</Button>
<ToggleButton
x:Name="PlayPauseButton"
Grid.Column="2"
Margin="6"
Background="{StaticResource BackgroundBrush}"
IsChecked="{Binding Slideshow.Enable}">
<ToggleButton.Style>
<Style BasedOn="{StaticResource SlideshowButton}" TargetType="ToggleButton">
<Setter Property="ToolTip" Value="Play slideshow" />
<Style.Triggers>
<DataTrigger Binding="{Binding Slideshow.Enable}" Value="True">
<Setter Property="ToolTip" Value="Pause slideshow" />
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
<icon:PackIconMaterial>
<icon:PackIconMaterial.Style>
<Style TargetType="icon:PackIconMaterial">
<Setter Property="Kind" Value="Pause" />
<Style.Triggers>
<DataTrigger Binding="{Binding Slideshow.Enable}" Value="True">
<Setter Property="Kind" Value="Play" />
</DataTrigger>
</Style.Triggers>
</Style>
</icon:PackIconMaterial.Style>
</icon:PackIconMaterial>
</ToggleButton>
<Button
Grid.Column="1"
Margin="6"
Background="{StaticResource BackgroundBrush}"
Command="{Binding Slideshow.VisitNexusSiteCommand}"
Style="{StaticResource SlideshowButton}"
ToolTip="Open Nexus Website">
<icon:PackIconMaterial
Width="28"
Height="28"
Kind="Web" />
</Button>
<ToggleButton
Grid.Column="0"
Background="{StaticResource BackgroundBrush}"
IsChecked="{Binding Slideshow.ShowNSFW}"
ToolTip="Show NSFW mods">
<ToggleButton.Style>
<Style BasedOn="{StaticResource SlideshowButton}" TargetType="ToggleButton">
<Setter Property="ToolTip" Value="Show NSFW mods" />
<Style.Triggers>
<DataTrigger Binding="{Binding Slideshow.ShowNSFW}" Value="True">
<Setter Property="ToolTip" Value="Hide NSFW mods" />
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
<Grid>
<TextBlock
Margin="4"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="Lucida Sans"
FontSize="9"
FontWeight="Bold"
Text="NSFW" />
<icon:PackIconOcticons
Width="40"
Height="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#88FFFFFF"
Kind="CircleSlash"
Visibility="{Binding Slideshow.ShowNSFW, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}" />
</Grid>
</ToggleButton>
</Grid>
<TextBlock
x:Name="DescriptionTextShadow"
Grid.Row="2"
Grid.RowSpan="2"
Grid.Column="1"
Margin="-10,15,-5,15"
Padding="30,10"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontSize="16"
Style="{StaticResource BackgroundBlurStyle}"
Text="{Binding Description}"
TextAlignment="Right"
TextWrapping="Wrap">
<TextBlock.Effect>
<BlurEffect Radius="55" />
</TextBlock.Effect>
</TextBlock>
<TextBlock
Grid.Row="2"
Grid.RowSpan="2"
Grid.Column="1"
Margin="20,25,25,25"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontSize="16"
Text="{Binding Description}"
TextAlignment="Right"
TextWrapping="Wrap">
<TextBlock.Effect>
<DropShadowEffect />
</TextBlock.Effect>
</TextBlock>
<Rectangle
x:Name="TextHoverTrigger"
Grid.Row="2"
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Fill="Transparent" />
</Grid>
</Border>
<!-- Top progress bar -->
<!-- Comes after slideshow control, so that any effects/overlap goes on top -->
<Rectangle
Grid.Row="2"
Height="25"
Margin="6,0"
VerticalAlignment="Top"
IsHitTestVisible="False">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#AA000000" />
<GradientStop Offset="1" Color="#00000000" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="1" Fill="{StaticResource BackgroundBrush}" />
<mahapps:MetroProgressBar
x:Name="BottomProgressBarDarkGlow"
Grid.Row="1"
Grid.RowSpan="2"
Height="16"
Margin="-4"
VerticalAlignment="Top"
Background="Transparent"
BorderBrush="Transparent"
Foreground="{StaticResource PrimaryVariantBrush}"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay}">
<mahapps:MetroProgressBar.Effect>
<BlurEffect Radius="25" />
</mahapps:MetroProgressBar.Effect>
</mahapps:MetroProgressBar>
<mahapps:MetroProgressBar
x:Name="BottomProgressBarBrightGlow"
Grid.Row="1"
Grid.RowSpan="2"
Height="6"
Margin="-4"
VerticalAlignment="Top"
Background="Transparent"
BorderBrush="Transparent"
Foreground="{StaticResource PrimaryBrush}"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay}">
<mahapps:MetroProgressBar.Effect>
<BlurEffect Radius="20" />
</mahapps:MetroProgressBar.Effect>
</mahapps:MetroProgressBar>
<Grid x:Name="TopBarGrid" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<mahapps:MetroProgressBar
Grid.Column="0"
Grid.ColumnSpan="4"
Background="{StaticResource WindowBackgroundBrush}"
BorderThickness="0"
Foreground="Transparent"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay}" />
<mahapps:MetroProgressBar
Grid.Column="0"
Grid.ColumnSpan="4"
Background="Transparent"
BorderThickness="0"
Foreground="{StaticResource PrimaryVariantBrush}"
Maximum="1"
Opacity="{Binding ProgressPercent, Mode=OneWay}"
Value="{Binding ProgressPercent, Mode=OneWay}" />
<TextBlock
Grid.Column="0"
Width="90"
Margin="10,0,0,8"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontWeight="Black"
TextAlignment="Right">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="Configuring" />
<Setter Property="FontSize" Value="15" />
<Grid.Effect>
<DropShadowEffect
BlurRadius="25"
Opacity="1"
Color="Black" />
</Grid.Effect>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Opacity" Value="0" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding InstallingMode}" Value="True" />
<Condition Binding="{Binding IsMouseOver, ElementName=Slideshow}" Value="True" />
<Condition Binding="{Binding Installing}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Text" Value="Installing" />
<Setter Property="FontSize" Value="14" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding InstallingMode}" Value="True" />
<Condition Binding="{Binding Installing}" Value="False" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Text" Value="Installed" />
<Setter Property="FontSize" Value="14" />
</MultiDataTrigger.Setters>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.12" />
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
<LinearDoubleKeyFrame KeyTime="0:0:0.3" Value="1" />
<LinearDoubleKeyFrame KeyTime="0:0:0.42" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock
Grid.Column="1"
Margin="15,0,0,0"
VerticalAlignment="Center"
FontFamily="Lucida Sans"
FontSize="25"
FontWeight="Black"
Text="{Binding ModListName}" />
</Grid.Style>
<Button
Grid.Column="3"
Width="60"
Height="60"
Margin="6"
Background="{StaticResource BackgroundBrush}"
Command="{Binding Slideshow.SlideShowNextItemCommand}"
Style="{StaticResource CircleButtonStyle}"
ToolTip="Skip to the next mod">
<icon:PackIconFontAwesome
Width="28"
Height="28"
Kind="ChevronRightSolid" />
</Button>
<ToggleButton
x:Name="PlayPauseButton"
Grid.Column="2"
Margin="6"
Background="{StaticResource BackgroundBrush}"
IsChecked="{Binding Slideshow.Enable}">
<ToggleButton.Style>
<Style BasedOn="{StaticResource SlideshowButton}" TargetType="ToggleButton">
<Setter Property="ToolTip" Value="Play slideshow" />
<Style.Triggers>
<DataTrigger Binding="{Binding Slideshow.Enable}" Value="True">
<Setter Property="ToolTip" Value="Pause slideshow" />
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
<icon:PackIconMaterial>
<icon:PackIconMaterial.Style>
<Style TargetType="icon:PackIconMaterial">
<Setter Property="Kind" Value="Play" />
<Style.Triggers>
<DataTrigger Binding="{Binding Slideshow.Enable}" Value="True">
<Setter Property="Kind" Value="Pause" />
</DataTrigger>
</Style.Triggers>
</Style>
</icon:PackIconMaterial.Style>
</icon:PackIconMaterial>
</ToggleButton>
<Button
Grid.Column="1"
Margin="6"
Background="{StaticResource BackgroundBrush}"
Command="{Binding Slideshow.VisitNexusSiteCommand}"
Style="{StaticResource SlideshowButton}"
ToolTip="Open Nexus Website">
<icon:PackIconMaterial
Width="28"
Height="28"
Kind="Web" />
</Button>
<ToggleButton
Grid.Column="0"
Background="{StaticResource BackgroundBrush}"
IsChecked="{Binding Slideshow.ShowNSFW}"
ToolTip="Show NSFW mods">
<ToggleButton.Style>
<Style BasedOn="{StaticResource SlideshowButton}" TargetType="ToggleButton">
<Setter Property="ToolTip" Value="Show NSFW mods" />
<Style.Triggers>
<DataTrigger Binding="{Binding Slideshow.ShowNSFW}" Value="True">
<Setter Property="ToolTip" Value="Hide NSFW mods" />
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
<Grid>
<TextBlock
Margin="4"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="Lucida Sans"
FontSize="9"
FontWeight="Bold"
Text="NSFW" />
<icon:PackIconOcticons
Width="40"
Height="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="#88FFFFFF"
Kind="CircleSlash"
Visibility="{Binding Slideshow.ShowNSFW, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}" />
</Grid>
</ToggleButton>
</Grid>
</Grid>
<!-- Comes after slideshow control, so that any effects/overlap goes on top -->
<local:TopProgressView
Title="{Binding ModListName}"
Grid.Row="0"
Grid.RowSpan="2"
ProgressPercent="{Binding ProgressPercent}"
StatePrefixTitle="{Binding ProgressTitle}">
<!-- Readd when Pause/Stop implementations added -->
<!--<Button Grid.Column="2"
ToolTip="Pause Installation"
@ -503,40 +208,10 @@
Height="25"
Kind="TimesCircleSolid" />
</Button>-->
</Grid>
<mahapps:MetroProgressBar
x:Name="BottomProgressBar"
Grid.Row="1"
Grid.RowSpan="2"
Height="5"
VerticalAlignment="Top"
Background="Transparent"
BorderBrush="Transparent"
Foreground="{StaticResource PrimaryBrush}"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay}" />
<mahapps:MetroProgressBar
x:Name="BottomProgressBarHighlight"
Grid.Row="1"
Grid.RowSpan="2"
Height="5"
VerticalAlignment="Top"
Background="Transparent"
BorderBrush="Transparent"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay}">
<mahapps:MetroProgressBar.Foreground>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#CCFFFFFF" />
<GradientStop Offset="0.3" Color="#00FFFFFF" />
<GradientStop Offset="0.7" Color="#00FFFFFF" />
<GradientStop Offset="1" Color="#CCFFFFFF" />
</LinearGradientBrush>
</mahapps:MetroProgressBar.Foreground>
</mahapps:MetroProgressBar>
</local:TopProgressView>
<!-- Bottom Area -->
<Grid
Grid.Row="3"
Grid.Row="2"
Margin="5,0,5,5"
ClipToBounds="True"
Visibility="{Binding InstallingMode, Converter={StaticResource bool2VisibilityConverter}, ConverterParameter=False}">
@ -606,33 +281,6 @@
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border
x:Name="BeginButtonPurpleGlow"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="5"
Width="76"
Height="76"
Margin="0,0,14,0"
HorizontalAlignment="Right"
Background="{StaticResource PrimaryVariantBrush}"
CornerRadius="43"
Visibility="{Binding IsEnabled, ElementName=BeginButton, Converter={StaticResource bool2VisibilityConverter}}">
<Border.Effect>
<BlurEffect Radius="10" />
</Border.Effect>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Opacity" Value="0.5" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=BeginButton}" Value="True">
<Setter Property="Opacity" Value="0.8" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<TextBlock
Grid.Row="1"
Grid.Column="0"
@ -663,124 +311,31 @@
VerticalAlignment="Center"
DataContext="{Binding DownloadLocation}"
FontSize="14" />
<Button
x:Name="BeginButton"
<local:BeginButton
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="4"
Width="55"
Height="55"
Margin="0,0,25,0"
HorizontalAlignment="Right"
Command="{Binding BeginCommand}">
<icon:PackIconMaterial
Width="25"
Height="25"
Margin="5,0,0,0"
Kind="Play">
<icon:PackIconMaterial.Style>
<Style TargetType="icon:PackIconMaterial">
<Setter Property="Foreground" Value="#666666" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled, ElementName=BeginButton}" Value="True">
<Setter Property="Foreground" Value="{StaticResource SecondaryBrush}" />
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, ElementName=BeginButton}" Value="True" />
<Condition Binding="{Binding IsEnabled, ElementName=BeginButton}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Foreground" Value="#00ffe7" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</icon:PackIconMaterial.Style>
</icon:PackIconMaterial>
<Button.Style>
<Style BasedOn="{StaticResource CircleButtonStyle}" TargetType="Button">
<Setter Property="Background" Value="#333333" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled, ElementName=BeginButton}" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource SecondaryBrush}" />
<Setter Property="Background" Value="#222222" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect
BlurRadius="15"
ShadowDepth="0"
Color="{StaticResource Secondary}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Command="{Binding BeginCommand, Mode=OneWay}" />
</Grid>
</ScrollViewer>
</Grid>
<Rectangle
x:Name="ControlTopThinSeparator"
Grid.Column="0"
Grid.ColumnSpan="3"
Height="1"
Margin="25,0"
VerticalAlignment="Top"
Fill="{StaticResource DarkBackgroundBrush}" />
Fill="{StaticResource DarkBackgroundBrush}"
SnapsToDevicePixels="True" />
</Grid>
<Grid
Grid.Row="3"
Grid.Row="2"
Margin="5,0,5,5"
Visibility="{Binding InstallingMode, Converter={StaticResource bool2VisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="4" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox
Grid.Column="0"
local:AutoScrollBehavior.ScrollOnNewItem="True"
ItemsSource="{Binding MWVM.Log}" />
<ListBox
x:Name="CpuListBox"
Grid.Column="2"
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, Mode=OneTime}" 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, Mode=OneTime}" />
<TextBlock Grid.Column="3" Text=" - " />
<TextBlock Grid.Column="4" Text="{Binding Msg, Mode=OneTime}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Visibility="{Binding InstallingMode, Converter={StaticResource bool2VisibilityConverter}, FallbackValue=Hidden}">
<local:LogCpuView DataContext="{Binding MWVM}" />
</Grid>
</Grid>
</UserControl>

View File

@ -0,0 +1,62 @@
<UserControl
x:Class="Wabbajack.LogCpuView"
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"
d:DesignHeight="250"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="4" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox
Grid.Column="0"
Margin="0,0,2,0"
local:AutoScrollBehavior.ScrollOnNewItem="True"
ItemsSource="{Binding Log}" />
<ListBox
Grid.Column="2"
HorizontalAlignment="Stretch"
ItemsSource="{Binding 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>
</Grid>
</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 LogCpuView.xaml
/// </summary>
public partial class LogCpuView : UserControl
{
public LogCpuView()
{
InitializeComponent();
}
}
}

View File

@ -12,8 +12,10 @@
MinHeight="650"
Closing="Window_Closing"
Icon="../Resources/Icons/wabbajack.ico"
RenderOptions.BitmapScalingMode="HighQuality"
ResizeMode="CanResize"
Style="{StaticResource {x:Type Window}}"
UseLayoutRounding="True"
WindowStyle="ToolWindow"
mc:Ignorable="d">
<ContentPresenter Content="{Binding ActivePane}">

View File

@ -10,8 +10,10 @@
Height="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">
<Grid Margin="20">

View File

@ -0,0 +1,138 @@
<UserControl
x:Class="Wabbajack.TopProgressView"
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:mahapps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="5" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<Rectangle
Grid.Row="2"
Height="25"
Margin="6,0"
VerticalAlignment="Top"
IsHitTestVisible="False"
Visibility="{Binding OverhangShadow, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource bool2VisibilityConverter}}">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#AA000000" />
<GradientStop Offset="1" Color="#00000000" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="1" Fill="{StaticResource BackgroundBrush}" />
<mahapps:MetroProgressBar
x:Name="BottomProgressBarDarkGlow"
Grid.Row="1"
Grid.RowSpan="2"
Height="16"
Margin="-4"
VerticalAlignment="Top"
Background="Transparent"
BorderBrush="Transparent"
Foreground="{StaticResource PrimaryVariantBrush}"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
<mahapps:MetroProgressBar.Effect>
<BlurEffect Radius="25" />
</mahapps:MetroProgressBar.Effect>
</mahapps:MetroProgressBar>
<mahapps:MetroProgressBar
x:Name="BottomProgressBarBrightGlow"
Grid.Row="1"
Grid.RowSpan="2"
Height="6"
Margin="-4"
VerticalAlignment="Top"
Background="Transparent"
BorderBrush="Transparent"
Foreground="{StaticResource PrimaryBrush}"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
<mahapps:MetroProgressBar.Effect>
<BlurEffect Radius="20" />
</mahapps:MetroProgressBar.Effect>
</mahapps:MetroProgressBar>
<Grid x:Name="TopBarGrid" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<mahapps:MetroProgressBar
Grid.Column="0"
Grid.ColumnSpan="4"
Background="{StaticResource WindowBackgroundBrush}"
BorderThickness="0"
Foreground="Transparent"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<mahapps:MetroProgressBar
Grid.Column="0"
Grid.ColumnSpan="4"
Background="Transparent"
BorderThickness="0"
Foreground="{StaticResource PrimaryVariantBrush}"
Maximum="1"
Opacity="{Binding ProgressPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
Value="{Binding ProgressPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<TextBlock
Grid.Column="0"
Width="90"
Margin="10,0,0,8"
VerticalAlignment="Bottom"
FontFamily="Lucida Sans"
FontWeight="Black"
Text="{Binding StatePrefixTitle, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
TextAlignment="Right" />
<TextBlock
Grid.Column="1"
Margin="15,0,0,0"
VerticalAlignment="Center"
FontFamily="Lucida Sans"
FontSize="25"
FontWeight="Black"
Text="{Binding Title, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<ContentControl Grid.Column="2" />
</Grid>
<mahapps:MetroProgressBar
x:Name="BottomProgressBar"
Grid.Row="1"
Grid.RowSpan="2"
Height="5"
VerticalAlignment="Top"
Background="Transparent"
BorderBrush="Transparent"
Foreground="{StaticResource PrimaryBrush}"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<mahapps:MetroProgressBar
x:Name="BottomProgressBarHighlight"
Grid.Row="1"
Grid.RowSpan="2"
Height="5"
VerticalAlignment="Top"
Background="Transparent"
BorderBrush="Transparent"
Maximum="1"
Value="{Binding ProgressPercent, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
<mahapps:MetroProgressBar.Foreground>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#CCFFFFFF" />
<GradientStop Offset="0.3" Color="#00FFFFFF" />
<GradientStop Offset="0.7" Color="#00FFFFFF" />
<GradientStop Offset="1" Color="#CCFFFFFF" />
</LinearGradientBrush>
</mahapps:MetroProgressBar.Foreground>
</mahapps:MetroProgressBar>
</Grid>
</UserControl>

View File

@ -0,0 +1,60 @@
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 TopProgressView.xaml
/// </summary>
public partial class TopProgressView : UserControl
{
public double ProgressPercent
{
get => (double)GetValue(ProgressPercentProperty);
set => SetValue(ProgressPercentProperty, value);
}
public static readonly DependencyProperty ProgressPercentProperty = DependencyProperty.Register(nameof(ProgressPercent), typeof(double), typeof(TopProgressView),
new FrameworkPropertyMetadata(default(double)));
public string Title
{
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(TopProgressView),
new FrameworkPropertyMetadata(default(string)));
public string StatePrefixTitle
{
get => (string)GetValue(StatePrefixTitleProperty);
set => SetValue(StatePrefixTitleProperty, value);
}
public static readonly DependencyProperty StatePrefixTitleProperty = DependencyProperty.Register(nameof(StatePrefixTitle), typeof(string), typeof(TopProgressView),
new FrameworkPropertyMetadata(default(string)));
public bool OverhangShadow
{
get => (bool)GetValue(OverhangShadowProperty);
set => SetValue(OverhangShadowProperty, value);
}
public static readonly DependencyProperty OverhangShadowProperty = DependencyProperty.Register(nameof(OverhangShadow), typeof(bool), typeof(TopProgressView),
new FrameworkPropertyMetadata(true));
public TopProgressView()
{
InitializeComponent();
}
}
}

View File

@ -161,8 +161,22 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="BorderFadeDownView.xaml.cs">
<DependentUpon>BorderFadeDownView.xaml</DependentUpon>
</Compile>
<Compile Include="Converters\InverseBooleanConverter.cs" />
<Compile Include="Converters\BoolToVisibilityHiddenConverter.cs" />
<Compile Include="Views\BeginButton.xaml.cs">
<DependentUpon>BeginButton.xaml</DependentUpon>
</Compile>
<Compile Include="Converters\BoolToVisibilityConverter.cs" />
<Compile Include="Views\DetailImageView.xaml.cs">
<DependentUpon>DetailImageView.xaml</DependentUpon>
</Compile>
<Compile Include="Extensions\EnumerableExt.cs" />
<Compile Include="Views\TopProgressView.xaml.cs">
<DependentUpon>TopProgressView.xaml</DependentUpon>
</Compile>
<Compile Include="Settings.cs" />
<Compile Include="View Models\FilePickerVM.cs" />
<Compile Include="View Models\ModListVM.cs" />
@ -186,6 +200,9 @@
</Compile>
<Compile Include="View Models\CompilerVM.cs" />
<Compile Include="View Models\MainWindowVM.cs" />
<Compile Include="Views\LogCpuView.xaml.cs">
<DependentUpon>LogCpuView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ModeSelectionWindow.xaml.cs">
<DependentUpon>ModeSelectionWindow.xaml</DependentUpon>
</Compile>
@ -199,10 +216,26 @@
<DependentUpon>TextViewer.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UserControlRx.cs" />
<Page Include="BorderFadeDownView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\BeginButton.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\DetailImageView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\CompilerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\TopProgressView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\DownloadWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -215,6 +248,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LogCpuView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>