mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Add interactive CompilerFileState setting combo box to compiler file manager
This commit is contained in:
parent
2937dce6f1
commit
f5c9e075c7
49
Wabbajack.App.Wpf/MarkupExtensions/EnumMarkupConverter.cs
Normal file
49
Wabbajack.App.Wpf/MarkupExtensions/EnumMarkupConverter.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using SteamKit2.GC.Artifact.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
public class EnumToItemsSource : MarkupExtension
|
||||
{
|
||||
private readonly Type _type;
|
||||
|
||||
public EnumToItemsSource(Type type)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
public static string GetEnumDescription(Enum value)
|
||||
{
|
||||
FieldInfo fi = value.GetType().GetField(value.ToString());
|
||||
|
||||
DescriptionAttribute[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
|
||||
|
||||
if (attributes != null && attributes.Any())
|
||||
{
|
||||
return attributes.First().Description;
|
||||
}
|
||||
|
||||
return value.ToString();
|
||||
}
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
return Enum.GetValues(_type)
|
||||
.Cast<Enum>()
|
||||
.Select(e =>
|
||||
{
|
||||
return new
|
||||
{
|
||||
Value = e,
|
||||
DisplayName = GetEnumDescription((Enum)e)
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@
|
||||
<local:AbsolutePathToStringConverter x:Key="AbsolutePathToStringConverter" />
|
||||
<local:FileSizeConverter x:Key="FileSizeConverter"/>
|
||||
<local:WidthHeightRectConverter x:Key="WidthHeightRectConverter" />
|
||||
<math:MathConverter x:Key="MathConverter"/>
|
||||
<math:MathConverter x:Key="MathConverter" />
|
||||
|
||||
<!-- Colors -->
|
||||
<Color x:Key="WindowBackgroundColor">#222531</Color>
|
||||
@ -2303,16 +2303,25 @@
|
||||
x:Name="Expander"
|
||||
ClickMode="Press"
|
||||
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
|
||||
Style="{DynamicResource TreeViewToggleButtonStyle}" />
|
||||
Style="{DynamicResource TreeViewToggleButtonStyle}"
|
||||
Foreground="{StaticResource PrimaryBrush}"/>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Grid.Column="1">
|
||||
<Grid Grid.Column="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="5*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ic:SymbolIcon IsFilled="True" Symbol="{Binding Path=Symbol, RelativeSource={RelativeSource TemplatedParent}}" Margin="0, 0, 4, 0" Foreground="{StaticResource PrimaryBrush}"/>
|
||||
<ContentPresenter
|
||||
<StackPanel Orientation="Horizontal" Grid.Column="1">
|
||||
<ContentPresenter
|
||||
x:Name="PART_Header"
|
||||
Margin="4, 0, 0, 0"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
ContentSource="Header" />
|
||||
</StackPanel>
|
||||
ContentSource="Header"/>
|
||||
</StackPanel>
|
||||
<ComboBox Name="CompilerFileStateListbox" ItemsSource="{wj:EnumToItemsSource {x:Type wj:CompilerFileState}}" DisplayMemberPath="DisplayName" SelectedValue="{Binding Path=CompilerFileState, RelativeSource={RelativeSource TemplatedParent}}" SelectedValuePath="Value" Grid.Column="2"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ItemsPresenter x:Name="ItemsHost" />
|
||||
|
@ -122,7 +122,7 @@ namespace Wabbajack
|
||||
.Select(p => !string.IsNullOrWhiteSpace(p)))
|
||||
.Select(v => v.First && v.Second));
|
||||
*/
|
||||
NextCommand = ReactiveCommand.CreateFromTask(async () => await NextPage());
|
||||
NextCommand = ReactiveCommand.CreateFromTask(NextPage);
|
||||
|
||||
ModlistLocation = new FilePickerVM
|
||||
{
|
||||
@ -220,10 +220,10 @@ namespace Wabbajack
|
||||
Settings.OutputFile = newSettings.OutputFile.Combine(newSettings.ModListName).WithExtension(Ext.Wabbajack);
|
||||
|
||||
Settings.Game = newSettings.Game;
|
||||
Settings.Include = newSettings.Include;
|
||||
Settings.Ignore = newSettings.Ignore;
|
||||
Settings.AlwaysEnabled = newSettings.AlwaysEnabled;
|
||||
Settings.NoMatchInclude = newSettings.NoMatchInclude;
|
||||
Settings.Include = newSettings.Include.ToHashSet();
|
||||
Settings.Ignore = newSettings.Ignore.ToHashSet();
|
||||
Settings.AlwaysEnabled = newSettings.AlwaysEnabled.ToHashSet();
|
||||
Settings.NoMatchInclude = newSettings.NoMatchInclude.ToHashSet();
|
||||
Settings.AdditionalProfiles = newSettings.AdditionalProfiles;
|
||||
}
|
||||
|
||||
@ -264,6 +264,7 @@ namespace Wabbajack
|
||||
|
||||
private async Task NextPage()
|
||||
{
|
||||
await SaveSettingsFile();
|
||||
NavigateToGlobal.Send(ScreenType.CompilerFileManager);
|
||||
LoadCompilerSettings.Send(Settings.ToCompilerSettings());
|
||||
}
|
||||
@ -409,43 +410,43 @@ namespace Wabbajack
|
||||
|
||||
public void AddAlwaysEnabled(RelativePath path)
|
||||
{
|
||||
Settings.AlwaysEnabled = (Settings.AlwaysEnabled ?? Array.Empty<RelativePath>()).Append(path).Distinct().ToArray();
|
||||
Settings.AlwaysEnabled = (Settings.AlwaysEnabled ?? new()).Append(path).Distinct().ToHashSet();
|
||||
}
|
||||
|
||||
public void RemoveAlwaysEnabled(RelativePath path)
|
||||
{
|
||||
Settings.AlwaysEnabled = Settings.AlwaysEnabled.Where(p => p != path).ToArray();
|
||||
Settings.AlwaysEnabled = Settings.AlwaysEnabled.Where(p => p != path).ToHashSet();
|
||||
}
|
||||
|
||||
public void AddNoMatchInclude(RelativePath path)
|
||||
{
|
||||
Settings.NoMatchInclude = (Settings.NoMatchInclude ?? Array.Empty<RelativePath>()).Append(path).Distinct().ToArray();
|
||||
Settings.NoMatchInclude = (Settings.NoMatchInclude ?? new()).Append(path).Distinct().ToHashSet();
|
||||
}
|
||||
|
||||
public void RemoveNoMatchInclude(RelativePath path)
|
||||
{
|
||||
Settings.NoMatchInclude = Settings.NoMatchInclude.Where(p => p != path).ToArray();
|
||||
Settings.NoMatchInclude = Settings.NoMatchInclude.Where(p => p != path).ToHashSet();
|
||||
}
|
||||
|
||||
public void AddInclude(RelativePath path)
|
||||
{
|
||||
Settings.Include = (Settings.Include ?? Array.Empty<RelativePath>()).Append(path).Distinct().ToArray();
|
||||
Settings.Include = (Settings.Include ?? new()).Append(path).Distinct().ToHashSet();
|
||||
}
|
||||
|
||||
public void RemoveInclude(RelativePath path)
|
||||
{
|
||||
Settings.Include = Settings.Include.Where(p => p != path).ToArray();
|
||||
Settings.Include = Settings.Include.Where(p => p != path).ToHashSet();
|
||||
}
|
||||
|
||||
|
||||
public void AddIgnore(RelativePath path)
|
||||
{
|
||||
Settings.Ignore = (Settings.Ignore ?? Array.Empty<RelativePath>()).Append(path).Distinct().ToArray();
|
||||
Settings.Ignore = (Settings.Ignore ?? new()).Append(path).Distinct().ToHashSet();
|
||||
}
|
||||
|
||||
public void RemoveIgnore(RelativePath path)
|
||||
{
|
||||
Settings.Ignore = Settings.Ignore.Where(p => p != path).ToArray();
|
||||
Settings.Ignore = Settings.Ignore.Where(p => p != path).ToHashSet();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -31,15 +31,22 @@ using Wabbajack.Services.OSIntegrated;
|
||||
using NexusMods.Paths.FileTree;
|
||||
using System.Windows.Controls;
|
||||
using FluentIcons.Common;
|
||||
using System.Windows.Input;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
public enum State
|
||||
public enum CompilerFileState
|
||||
{
|
||||
[Description("Auto Match")]
|
||||
AutoMatch,
|
||||
[Description("No Match Include")]
|
||||
NoMatchInclude,
|
||||
[Description("Force Include")]
|
||||
Include,
|
||||
[Description("Force Ignore")]
|
||||
Ignore,
|
||||
[Description("Always Enabled")]
|
||||
AlwaysEnabled
|
||||
}
|
||||
public class FileTreeViewItemVM : TreeViewItem
|
||||
@ -48,7 +55,7 @@ namespace Wabbajack
|
||||
public FileSystemInfo Info { get; set; }
|
||||
public bool IsDirectory { get; set; }
|
||||
public Symbol Symbol { get; set; }
|
||||
public State CompilerState { get; set; }
|
||||
public CompilerFileState CompilerFileState { get; set; }
|
||||
public RelativePath PathRelativeToRoot { get; set; }
|
||||
public FileTreeViewItemVM(DirectoryInfo info)
|
||||
{
|
||||
@ -92,6 +99,7 @@ namespace Wabbajack
|
||||
|
||||
[Reactive] public CompilerSettingsVM Settings { get; set; } = new();
|
||||
public IEnumerable<TreeViewItem> Files { get; set; }
|
||||
public ICommand PrevCommand { get; set; }
|
||||
|
||||
|
||||
public CompilerFileManagerVM(ILogger<CompilerFileManagerVM> logger, DTOSerializer dtos, SettingsManager settingsManager,
|
||||
@ -113,6 +121,7 @@ namespace Wabbajack
|
||||
})
|
||||
.DisposeWith(CompositeDisposable);
|
||||
|
||||
PrevCommand = ReactiveCommand.Create(PrevPage);
|
||||
this.WhenActivated(disposables =>
|
||||
{
|
||||
var fileTree = GetDirectoryContents(new DirectoryInfo(Settings.Source.ToString()));
|
||||
@ -121,12 +130,18 @@ namespace Wabbajack
|
||||
});
|
||||
}
|
||||
|
||||
private void PrevPage()
|
||||
{
|
||||
NavigateToGlobal.Send(ScreenType.CompilerDetails);
|
||||
LoadCompilerSettings.Send(Settings.ToCompilerSettings());
|
||||
}
|
||||
|
||||
private IEnumerable<TreeViewItem> LoadFiles(DirectoryInfo parent)
|
||||
{
|
||||
var parentTreeItem = new FileTreeViewItemVM(parent)
|
||||
{
|
||||
IsExpanded = true,
|
||||
ItemsSource = LoadDirectoryContents(parent)
|
||||
ItemsSource = LoadDirectoryContents(parent),
|
||||
};
|
||||
return [parentTreeItem];
|
||||
|
||||
@ -139,10 +154,10 @@ namespace Wabbajack
|
||||
.Select(dir => new FileTreeViewItemVM(dir) { ItemsSource = (dir.EnumerateDirectories().Any() || dir.EnumerateFiles().Any()) ? new ObservableCollection<TreeViewItem>([new TreeViewItem() { Header = "Loading..." }]) : null}).Select(item => {
|
||||
item.Expanded += LoadingItem_Expanded;
|
||||
item.PathRelativeToRoot = ((AbsolutePath)item.Info.FullName).RelativeTo(Settings.Source);
|
||||
if (Settings.NoMatchInclude.Contains(item.PathRelativeToRoot)) { item.CompilerState = State.NoMatchInclude; }
|
||||
else if(Settings.Include.Contains(item.PathRelativeToRoot)) { item.CompilerState = State.Include; }
|
||||
else if(Settings.Ignore.Contains(item.PathRelativeToRoot)) { item.CompilerState = State.Ignore; }
|
||||
else if(Settings.AlwaysEnabled.Contains(item.PathRelativeToRoot)) { item.CompilerState = State.AlwaysEnabled; }
|
||||
if (Settings.NoMatchInclude.Contains(item.PathRelativeToRoot)) { item.CompilerFileState = CompilerFileState.NoMatchInclude; }
|
||||
else if(Settings.Include.Contains(item.PathRelativeToRoot)) { item.CompilerFileState = CompilerFileState.Include; }
|
||||
else if(Settings.Ignore.Contains(item.PathRelativeToRoot)) { item.CompilerFileState = CompilerFileState.Ignore; }
|
||||
else if(Settings.AlwaysEnabled.Contains(item.PathRelativeToRoot)) { item.CompilerFileState = CompilerFileState.AlwaysEnabled; }
|
||||
|
||||
return item;
|
||||
})
|
||||
|
@ -36,10 +36,10 @@ public class CompilerSettingsVM : ViewModel
|
||||
MachineUrl = cs.MachineUrl;
|
||||
Profile = cs.Profile;
|
||||
AdditionalProfiles = cs.AdditionalProfiles;
|
||||
NoMatchInclude = cs.NoMatchInclude;
|
||||
Include = cs.Include;
|
||||
Ignore = cs.Ignore;
|
||||
AlwaysEnabled = cs.AlwaysEnabled;
|
||||
NoMatchInclude = cs.NoMatchInclude.ToHashSet();
|
||||
Include = cs.Include.ToHashSet();
|
||||
Ignore = cs.Ignore.ToHashSet();
|
||||
AlwaysEnabled = cs.AlwaysEnabled.ToHashSet();
|
||||
Version = cs.Version?.ToString() ?? "";
|
||||
Description = cs.Description;
|
||||
}
|
||||
@ -90,19 +90,19 @@ public class CompilerSettingsVM : ViewModel
|
||||
/// This file, or files in these folders, are automatically included if they don't match
|
||||
/// any other step
|
||||
/// </summary>
|
||||
[Reactive] public RelativePath[] NoMatchInclude { get; set; } = Array.Empty<RelativePath>();
|
||||
[Reactive] public HashSet<RelativePath> NoMatchInclude { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// These files are inlined into the modlist
|
||||
/// </summary>
|
||||
[Reactive] public RelativePath[] Include { get; set; } = Array.Empty<RelativePath>();
|
||||
[Reactive] public HashSet<RelativePath> Include { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// These files are ignored when compiling the modlist
|
||||
/// </summary>
|
||||
[Reactive] public RelativePath[] Ignore { get; set; } = Array.Empty<RelativePath>();
|
||||
[Reactive] public HashSet<RelativePath> Ignore { get; set; } = new();
|
||||
|
||||
[Reactive] public RelativePath[] AlwaysEnabled { get; set; } = Array.Empty<RelativePath>();
|
||||
[Reactive] public HashSet<RelativePath> AlwaysEnabled { get; set; } = new();
|
||||
[Reactive] public string Version { get; set; }
|
||||
[Reactive] public string Description { get; set; }
|
||||
|
||||
@ -130,10 +130,10 @@ public class CompilerSettingsVM : ViewModel
|
||||
MachineUrl = MachineUrl,
|
||||
Profile = Profile,
|
||||
AdditionalProfiles = AdditionalProfiles,
|
||||
NoMatchInclude = NoMatchInclude,
|
||||
Include = Include,
|
||||
Ignore = Ignore,
|
||||
AlwaysEnabled = AlwaysEnabled,
|
||||
NoMatchInclude = NoMatchInclude.ToArray(),
|
||||
Include = Include.ToArray(),
|
||||
Ignore = Ignore.ToArray(),
|
||||
AlwaysEnabled = AlwaysEnabled.ToArray(),
|
||||
Version = System.Version.Parse(Version),
|
||||
Description = Description
|
||||
};
|
||||
|
@ -130,7 +130,7 @@ namespace Wabbajack
|
||||
|
||||
var searchTextPredicates = this.ObservableForProperty(vm => vm.Search)
|
||||
.Throttle(searchThrottle, RxApp.MainThreadScheduler)
|
||||
.Select(change => change.Value.Trim())
|
||||
.Select(change => change.Value?.Trim() ?? "")
|
||||
.StartWith(Search)
|
||||
.Select<string, Func<GalleryModListMetadataVM, bool>>(txt =>
|
||||
{
|
||||
@ -193,8 +193,8 @@ namespace Wabbajack
|
||||
var searchSorter = this.WhenValueChanged(vm => vm.Search)
|
||||
.Throttle(searchThrottle, RxApp.MainThreadScheduler)
|
||||
.Select(s => SortExpressionComparer<GalleryModListMetadataVM>
|
||||
.Descending(m => m.Metadata.Title.StartsWith(s, StringComparison.InvariantCultureIgnoreCase))
|
||||
.ThenByDescending(m => m.Metadata.Title.Contains(s, StringComparison.InvariantCultureIgnoreCase))
|
||||
.Descending(m => m.Metadata.Title.StartsWith(s ?? "", StringComparison.InvariantCultureIgnoreCase))
|
||||
.ThenByDescending(m => m.Metadata.Title.Contains(s ?? "", StringComparison.InvariantCultureIgnoreCase))
|
||||
.ThenByDescending(m => !m.IsBroken));
|
||||
_modLists.Connect()
|
||||
.ObserveOn(RxApp.MainThreadScheduler)
|
||||
|
@ -16,6 +16,24 @@
|
||||
d:DesignWidth="800"
|
||||
x:TypeArguments="local:CompilerFileManagerVM"
|
||||
mc:Ignorable="d">
|
||||
<TreeView x:Name="FileTreeView">
|
||||
</TreeView>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="7*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TreeView x:Name="FileTreeView"/>
|
||||
<Grid Grid.Row="1" Margin="0, 16, 0, 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button x:Name="PrevButton" Content="Back to Modlist Details" Margin="0, 0, 16, 0"/>
|
||||
<Button Grid.Column="1" x:Name="ReinferSettingsButton" Content="Re-infer Settings" Margin="0, 0, 16, 0"/>
|
||||
<Button Grid.Column="5" x:Name="ContinueButton" Content="Continue" Margin="16, 0, 0, 0"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</rxui:ReactiveUserControl>
|
||||
|
@ -35,6 +35,9 @@ namespace Wabbajack
|
||||
.BindToStrict(this, v => v.FileTreeView.ItemsSource)
|
||||
.DisposeWith(disposables);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.PrevCommand, v => v.PrevButton)
|
||||
.DisposeWith(disposables);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user