mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Refactor FileTreeViewItem to actually be reactive
This commit is contained in:
parent
741276acf3
commit
2556c54e99
@ -2188,12 +2188,12 @@
|
|||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
<Style TargetType="{x:Type TreeViewItem}">
|
<Style TargetType="{x:Type TreeViewItem}" x:Key="TreeViewItem">
|
||||||
<Setter Property="Background" Value="Transparent" />
|
<Setter Property="Background" Value="Transparent" />
|
||||||
<Setter Property="MinHeight" Value="21" />
|
<Setter Property="MinHeight" Value="21" />
|
||||||
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
|
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
|
||||||
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
|
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
|
||||||
<Setter Property="Padding" Value="2,4,2,3" />
|
<Setter Property="Padding" Value="4,6,4,6" />
|
||||||
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
|
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
|
||||||
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}" />
|
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}" />
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
@ -2275,14 +2275,7 @@
|
|||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
<Style TargetType="{x:Type wj:FileTreeViewItemVM}">
|
<Style TargetType="{x:Type wj:FileTreeViewItem}" BasedOn="{StaticResource TreeViewItem}">
|
||||||
<Setter Property="Background" Value="Transparent" />
|
|
||||||
<Setter Property="MinHeight" Value="21" />
|
|
||||||
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
|
|
||||||
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
|
|
||||||
<Setter Property="Padding" Value="4,6,4,6" />
|
|
||||||
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
|
|
||||||
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}" />
|
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="{x:Type TreeViewItem}">
|
<ControlTemplate TargetType="{x:Type TreeViewItem}">
|
||||||
@ -2312,7 +2305,7 @@
|
|||||||
<ColumnDefinition Width="5*" />
|
<ColumnDefinition Width="5*" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<ic:SymbolIcon IsFilled="True" Symbol="{Binding Path=Symbol, RelativeSource={RelativeSource TemplatedParent}}" Margin="0, 0, 4, 0" Foreground="{StaticResource PrimaryBrush}"/>
|
<ic:SymbolIcon IsFilled="True" Symbol="{Binding Path=Header.Symbol, RelativeSource={RelativeSource TemplatedParent}}" Margin="0, 0, 4, 0" Foreground="{StaticResource PrimaryBrush}"/>
|
||||||
<StackPanel Orientation="Horizontal" Grid.Column="1">
|
<StackPanel Orientation="Horizontal" Grid.Column="1">
|
||||||
<ContentPresenter
|
<ContentPresenter
|
||||||
x:Name="PART_Header"
|
x:Name="PART_Header"
|
||||||
@ -2320,11 +2313,11 @@
|
|||||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
ContentSource="Header"/>
|
ContentSource="Header"/>
|
||||||
</StackPanel>
|
</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"/>
|
<ComboBox Name="CompilerFileStateListbox" ItemsSource="{wj:EnumToItemsSource {x:Type wj:CompilerFileState}}" DisplayMemberPath="DisplayName" SelectedValue="{Binding Path=Header.CompilerFileState, RelativeSource={RelativeSource TemplatedParent}}" SelectedValuePath="Value" Grid.Column="2"/>
|
||||||
<Grid.Style>
|
<Grid.Style>
|
||||||
<Style TargetType="Grid">
|
<Style TargetType="Grid">
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<DataTrigger Binding="{Binding Path=SpecialFileState, RelativeSource={RelativeSource TemplatedParent}}" Value="True">
|
<DataTrigger Binding="{Binding Path=Header.SpecialFileState, RelativeSource={RelativeSource TemplatedParent}}" Value="True">
|
||||||
<Setter Property="Background" Value="{StaticResource PrimaryVariantBrush}" />
|
<Setter Property="Background" Value="{StaticResource PrimaryVariantBrush}" />
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
|
@ -48,36 +48,41 @@ namespace Wabbajack
|
|||||||
Ignore,
|
Ignore,
|
||||||
[Description("Always Enabled")]
|
[Description("Always Enabled")]
|
||||||
AlwaysEnabled
|
AlwaysEnabled
|
||||||
}
|
}
|
||||||
public class FileTreeViewItemVM : TreeViewItem
|
public class FileTreeViewItem : TreeViewItem
|
||||||
{
|
{
|
||||||
private CompilerFileState _compilerFileState = CompilerFileState.AutoMatch;
|
public FileTreeViewItem(DirectoryInfo dir)
|
||||||
|
{
|
||||||
|
Header = new FileTreeItemVM(dir);
|
||||||
|
}
|
||||||
|
public FileTreeViewItem(FileInfo file)
|
||||||
|
{
|
||||||
|
Header = new FileTreeItemVM(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class FileTreeItemVM : ReactiveObject, IDisposable
|
||||||
|
{
|
||||||
|
private readonly CompositeDisposable _disposable = new();
|
||||||
public FileSystemInfo Info { get; set; }
|
public FileSystemInfo Info { get; set; }
|
||||||
public bool IsDirectory { get; set; }
|
public bool IsDirectory { get; set; }
|
||||||
public Symbol Symbol { get; set; }
|
public Symbol Symbol { get; set; }
|
||||||
public CompilerFileState CompilerFileState
|
[Reactive] public CompilerFileState CompilerFileState { get; set; }
|
||||||
{
|
|
||||||
get => _compilerFileState;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_compilerFileState = value;
|
|
||||||
SpecialFileState = _compilerFileState != CompilerFileState.AutoMatch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public RelativePath PathRelativeToRoot { get; set; }
|
public RelativePath PathRelativeToRoot { get; set; }
|
||||||
[Reactive] public bool SpecialFileState { get; set; }
|
[Reactive] public bool SpecialFileState { get; set; }
|
||||||
public FileTreeViewItemVM(DirectoryInfo info)
|
public FileTreeItemVM(DirectoryInfo info)
|
||||||
{
|
{
|
||||||
Info = info;
|
Info = info;
|
||||||
IsDirectory = true;
|
IsDirectory = true;
|
||||||
Header = info.Name;
|
|
||||||
Symbol = Symbol.Folder;
|
Symbol = Symbol.Folder;
|
||||||
|
|
||||||
|
this.WhenAnyValue(ftvivm => ftvivm.CompilerFileState)
|
||||||
|
.Subscribe(cfs => SpecialFileState = cfs != CompilerFileState.AutoMatch)
|
||||||
|
.DisposeWith(_disposable);
|
||||||
}
|
}
|
||||||
public FileTreeViewItemVM(FileInfo info)
|
public FileTreeItemVM(FileInfo info)
|
||||||
{
|
{
|
||||||
Info = info;
|
Info = info;
|
||||||
Header = info.Name;
|
|
||||||
Symbol = info.Extension.ToLower() switch {
|
Symbol = info.Extension.ToLower() switch {
|
||||||
".7z" or ".zip" or ".rar" or ".bsa" or ".ba2" or ".wabbajack" or ".tar" or ".tar.gz" => Symbol.Archive,
|
".7z" or ".zip" or ".rar" or ".bsa" or ".ba2" or ".wabbajack" or ".tar" or ".tar.gz" => Symbol.Archive,
|
||||||
".toml" or ".ini" or ".cfg" or ".json" or ".yaml" or ".xml" or ".yml" or ".meta" => Symbol.DocumentSettings,
|
".toml" or ".ini" or ".cfg" or ".json" or ".yaml" or ".xml" or ".yml" or ".meta" => Symbol.DocumentSettings,
|
||||||
@ -95,8 +100,17 @@ namespace Wabbajack
|
|||||||
_ => Symbol.Document
|
_ => Symbol.Document
|
||||||
};
|
};
|
||||||
SpecialFileState = CompilerFileState != CompilerFileState.AutoMatch;
|
SpecialFileState = CompilerFileState != CompilerFileState.AutoMatch;
|
||||||
|
|
||||||
|
this.WhenAnyValue(ftvivm => ftvivm.CompilerFileState)
|
||||||
|
.Subscribe(cfs => SpecialFileState = cfs != CompilerFileState.AutoMatch)
|
||||||
|
.DisposeWith(_disposable);
|
||||||
|
}
|
||||||
|
public override string ToString() => Info.Name;
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
_disposable.Dispose();
|
||||||
}
|
}
|
||||||
public override string ToString() => Info.FullName;
|
|
||||||
}
|
}
|
||||||
public class CompilerFileManagerVM : BackNavigatingVM
|
public class CompilerFileManagerVM : BackNavigatingVM
|
||||||
{
|
{
|
||||||
@ -149,7 +163,7 @@ namespace Wabbajack
|
|||||||
|
|
||||||
private IEnumerable<TreeViewItem> LoadFiles(DirectoryInfo parent)
|
private IEnumerable<TreeViewItem> LoadFiles(DirectoryInfo parent)
|
||||||
{
|
{
|
||||||
var parentTreeItem = new FileTreeViewItemVM(parent)
|
var parentTreeItem = new FileTreeViewItem(parent)
|
||||||
{
|
{
|
||||||
IsExpanded = true,
|
IsExpanded = true,
|
||||||
ItemsSource = LoadDirectoryContents(parent),
|
ItemsSource = LoadDirectoryContents(parent),
|
||||||
@ -162,36 +176,38 @@ namespace Wabbajack
|
|||||||
{
|
{
|
||||||
return parent.EnumerateDirectories()
|
return parent.EnumerateDirectories()
|
||||||
.OrderBy(dir => dir.Name)
|
.OrderBy(dir => dir.Name)
|
||||||
.Select(dir => new FileTreeViewItemVM(dir) { ItemsSource = (dir.EnumerateDirectories().Any() || dir.EnumerateFiles().Any()) ? new ObservableCollection<TreeViewItem>([new TreeViewItem() { Header = "Loading..." }]) : null}).Select(item => {
|
.Select(dir => new FileTreeViewItem(dir) { ItemsSource = (dir.EnumerateDirectories().Any() || dir.EnumerateFiles().Any()) ? new ObservableCollection<TreeViewItem>([new TreeViewItem() { Header = "Loading..." }]) : null}).Select(item => {
|
||||||
item.Expanded += LoadingItem_Expanded;
|
item.Expanded += LoadingItem_Expanded;
|
||||||
item.PathRelativeToRoot = ((AbsolutePath)item.Info.FullName).RelativeTo(Settings.Source);
|
var header = (FileTreeItemVM)item.Header;
|
||||||
if (Settings.NoMatchInclude.Contains(item.PathRelativeToRoot)) { item.CompilerFileState = CompilerFileState.NoMatchInclude; }
|
header.PathRelativeToRoot = ((AbsolutePath)header.Info.FullName).RelativeTo(Settings.Source);
|
||||||
else if(Settings.Include.Contains(item.PathRelativeToRoot)) { item.CompilerFileState = CompilerFileState.Include; }
|
if (Settings.NoMatchInclude.Contains(header.PathRelativeToRoot)) { header.CompilerFileState = CompilerFileState.NoMatchInclude; }
|
||||||
else if(Settings.Ignore.Contains(item.PathRelativeToRoot)) { item.CompilerFileState = CompilerFileState.Ignore; }
|
else if(Settings.Include.Contains(header.PathRelativeToRoot)) { header.CompilerFileState = CompilerFileState.Include; }
|
||||||
else if(Settings.AlwaysEnabled.Contains(item.PathRelativeToRoot)) { item.CompilerFileState = CompilerFileState.AlwaysEnabled; }
|
else if(Settings.Ignore.Contains(header.PathRelativeToRoot)) { header.CompilerFileState = CompilerFileState.Ignore; }
|
||||||
item.SpecialFileState = item.CompilerFileState != CompilerFileState.AutoMatch;
|
else if(Settings.AlwaysEnabled.Contains(header.PathRelativeToRoot)) { header.CompilerFileState = CompilerFileState.AlwaysEnabled; }
|
||||||
while(!item.SpecialFileState)
|
header.SpecialFileState = header.CompilerFileState != CompilerFileState.AutoMatch;
|
||||||
|
while(!header.SpecialFileState)
|
||||||
{
|
{
|
||||||
item.SpecialFileState = Settings.NoMatchInclude.Any(p => item.PathRelativeToRoot.InFolder(p));
|
header.SpecialFileState = Settings.NoMatchInclude.Any(p => header.PathRelativeToRoot.InFolder(p));
|
||||||
item.SpecialFileState = Settings.Include.Any(p => item.PathRelativeToRoot.InFolder(p));
|
header.SpecialFileState = Settings.Include.Any(p => header.PathRelativeToRoot.InFolder(p));
|
||||||
item.SpecialFileState = Settings.Ignore.Any(p => item.PathRelativeToRoot.InFolder(p));
|
header.SpecialFileState = Settings.Ignore.Any(p => header.PathRelativeToRoot.InFolder(p));
|
||||||
item.SpecialFileState = Settings.AlwaysEnabled.Any(p => item.PathRelativeToRoot.InFolder(p));
|
header.SpecialFileState = Settings.AlwaysEnabled.Any(p => header.PathRelativeToRoot.InFolder(p));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
item.Header = header;
|
||||||
return item;
|
return item;
|
||||||
})
|
})
|
||||||
.Concat(parent.EnumerateFiles()
|
.Concat(parent.EnumerateFiles()
|
||||||
.OrderBy(file => file.Name)
|
.OrderBy(file => file.Name)
|
||||||
.Select(file => new FileTreeViewItemVM(file)));
|
.Select(file => new FileTreeViewItem(file)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadingItem_Expanded(object sender, System.Windows.RoutedEventArgs e)
|
private void LoadingItem_Expanded(object sender, System.Windows.RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var parent = (FileTreeViewItemVM)e.OriginalSource;
|
var parent = (FileTreeViewItem)e.OriginalSource;
|
||||||
var children = parent.ItemsSource.OfType<TreeViewItem>();
|
var children = parent.ItemsSource.OfType<TreeViewItem>();
|
||||||
var firstChild = children.Any() ? children.First().Header : null;
|
var firstChild = children.Any() ? children.First().Header : null;
|
||||||
if (firstChild != null && firstChild is string firstString && firstString == "Loading...")
|
if (firstChild != null && firstChild is string firstString && firstString == "Loading...")
|
||||||
parent.ItemsSource = LoadDirectoryContents((DirectoryInfo)parent.Info);
|
parent.ItemsSource = LoadDirectoryContents((DirectoryInfo)((FileTreeItemVM)parent.Header).Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<FileSystemInfo> GetDirectoryContents(DirectoryInfo dir)
|
private IEnumerable<FileSystemInfo> GetDirectoryContents(DirectoryInfo dir)
|
||||||
|
Loading…
Reference in New Issue
Block a user