mirror of
https://github.com/4sval/FModel.git
synced 2026-09-26 11:07:39 -05:00
This commit is contained in:
Submodule CUE4Parse updated: cfff57a048...cb72c6e181
@@ -4,6 +4,7 @@
|
||||
xmlns:local="clr-namespace:FModel"
|
||||
xmlns:viewModels="clr-namespace:FModel.ViewModels"
|
||||
xmlns:controls="clr-namespace:FModel.Views.Resources.Controls"
|
||||
xmlns:explorer="clr-namespace:FModel.Views.Resources.Controls.Explorer"
|
||||
xmlns:inputs="clr-namespace:FModel.Views.Resources.Controls.Inputs"
|
||||
xmlns:converters="clr-namespace:FModel.Views.Resources.Converters"
|
||||
xmlns:settings="clr-namespace:FModel.Settings"
|
||||
@@ -558,7 +559,7 @@
|
||||
DataContext="{Binding CUE4Parse.AssetsFolder.SelectedFolder.PathAtThisPoint}" />
|
||||
|
||||
<Grid Grid.Row="2">
|
||||
<ListBox x:Name="AssetsExplorer"
|
||||
<explorer:AssetExplorerListBox x:Name="AssetsExplorer"
|
||||
ItemsSource="{Binding CUE4Parse.AssetsFolder.SelectedFolder.CombinedEntries}"
|
||||
Background="{DynamicResource {x:Static adonisUi:Brushes.Layer3BackgroundBrush}}"
|
||||
PreviewKeyDown="OnPreviewKeyDown">
|
||||
@@ -574,9 +575,9 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ListBox.Style>
|
||||
</ListBox>
|
||||
</explorer:AssetExplorerListBox>
|
||||
<!-- once we need sorting, convert this to a listview (see search window) and add the header back (customize the template to re-add GridViewHeaderRowPresenter) -->
|
||||
<ListBox x:Name="AssetsListExplorer"
|
||||
<explorer:AssetExplorerListBox x:Name="AssetsListExplorer"
|
||||
ItemsSource="{Binding CUE4Parse.AssetsFolder.SelectedFolder.CombinedEntries}"
|
||||
Background="{DynamicResource {x:Static adonisUi:Brushes.Layer3BackgroundBrush}}"
|
||||
PreviewKeyDown="OnPreviewKeyDown">
|
||||
@@ -594,7 +595,7 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ListBox.Style>
|
||||
</ListBox>
|
||||
</explorer:AssetExplorerListBox>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -271,21 +271,17 @@ public partial class MainWindow
|
||||
if (sender is not ItemContainerGenerator { Status: GeneratorStatus.ContainersGenerated } generator)
|
||||
return;
|
||||
|
||||
var foundVisibleItem = false;
|
||||
var itemCount = generator.Items.Count;
|
||||
var list = ReferenceEquals(generator, AssetsExplorer.ItemContainerGenerator) ? AssetsExplorer
|
||||
: ReferenceEquals(generator, AssetsListExplorer.ItemContainerGenerator) ? AssetsListExplorer
|
||||
: AssetsListName;
|
||||
|
||||
for (var i = 0; i < itemCount; i++)
|
||||
if (!list.IsVisible || list.FindVisualChild<VirtualizingPanel>() is not { } panel)
|
||||
return;
|
||||
|
||||
foreach (var container in panel.Children.OfType<ListBoxItem>())
|
||||
{
|
||||
var container = generator.ContainerFromIndex(i);
|
||||
if (container == null)
|
||||
if (container is FrameworkElement { IsVisible: true, DataContext: GameFileViewModel file })
|
||||
{
|
||||
if (foundVisibleItem) break; // we're past the visible range already
|
||||
continue; // keep scrolling to find visible items
|
||||
}
|
||||
|
||||
if (container is FrameworkElement { IsVisible: true } && generator.Items[i] is GameFileViewModel file)
|
||||
{
|
||||
foundVisibleItem = true;
|
||||
file.OnIsVisible();
|
||||
}
|
||||
}
|
||||
@@ -303,7 +299,6 @@ public partial class MainWindow
|
||||
public void SelectFolder(TreeItem folder)
|
||||
{
|
||||
_applicationView.SelectedLeftTabIndex = 1;
|
||||
UpdateLayout();
|
||||
AssetsFolderName.SelectFolder(folder);
|
||||
AssetsFolderName.FocusSelection();
|
||||
}
|
||||
|
||||
@@ -101,9 +101,9 @@ public class TreeItem : ViewModel
|
||||
{
|
||||
get
|
||||
{
|
||||
// BulkPopulate sorts Folders before this view is created
|
||||
_filteredFoldersView ??= new ListCollectionView(Folders)
|
||||
{
|
||||
SortDescriptions = { new SortDescription(nameof(Header), ListSortDirection.Ascending) },
|
||||
Filter = e => ItemFilter(e, SearchText.Trim().Split(' ', StringSplitOptions.RemoveEmptyEntries))
|
||||
};
|
||||
return _filteredFoldersView;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Collections;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using FModel.Extensions;
|
||||
|
||||
namespace FModel.Views.Resources.Controls.Explorer;
|
||||
|
||||
public class AssetExplorerListBox : ListBox
|
||||
{
|
||||
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
|
||||
{
|
||||
base.OnItemsSourceChanged(oldValue, newValue);
|
||||
|
||||
// Always start at the top, otherwise inherited offset can cause items not to be visible when we change folder
|
||||
if (this.FindVisualChild<VirtualizingPanel>() is IScrollInfo scroll)
|
||||
{
|
||||
scroll.SetVerticalOffset(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,16 @@
|
||||
xmlns:adonisExtensions="clr-namespace:AdonisUI.Extensions;assembly=AdonisUI"
|
||||
xmlns:adonisConverters="clr-namespace:AdonisUI.Converters;assembly=AdonisUI"
|
||||
x:Class="FModel.Views.Resources.Controls.TiledExplorer.ResourcesDictionary">
|
||||
<LinearGradientBrush x:Key="TiledFolderTabBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#FFE8C480" Offset="0" />
|
||||
<GradientStop Color="#FFD9AA63" Offset="1" />
|
||||
</LinearGradientBrush>
|
||||
<LinearGradientBrush x:Key="TiledFolderBodyBrush" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#FFF3D9A4" Offset="0" />
|
||||
<GradientStop Color="#FFE5BD77" Offset="1" />
|
||||
</LinearGradientBrush>
|
||||
<SolidColorBrush x:Key="TiledFolderOutlineBrush" Color="#D8A360" />
|
||||
|
||||
<controls:TypeDataTemplateSelector x:Key="TiledExplorerTemplateSelector"
|
||||
FolderTemplateKey="TiledFolderDataTemplate"
|
||||
FileTemplateKey="TiledFileDataTemplate" />
|
||||
@@ -69,14 +79,7 @@
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
<Setter Property="ItemTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<ContentControl Content="{Binding}"
|
||||
ContentTemplateSelector="{StaticResource TiledExplorerTemplateSelector}" />
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="ItemTemplateSelector" Value="{StaticResource TiledExplorerTemplateSelector}" />
|
||||
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
@@ -201,7 +204,7 @@
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="TiledFolderDataTemplate" DataType="{x:Type vm:TreeItem}">
|
||||
<tiledExplorer:FolderButton ContextMenu="{StaticResource FolderContextMenu}" />
|
||||
<tiledExplorer:FolderButton />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ListFileDataTemplate"
|
||||
@@ -211,7 +214,7 @@
|
||||
|
||||
<DataTemplate x:Key="ListFolderDataTemplate"
|
||||
DataType="{x:Type vm:TreeItem}">
|
||||
<listExplorer:FolderRow ContextMenu="{StaticResource FolderContextMenu}" />
|
||||
<listExplorer:FolderRow />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="TextureNumTemplate">
|
||||
|
||||
@@ -44,7 +44,7 @@ public partial class ResourcesDictionary
|
||||
{
|
||||
if (sender is not ListBoxItem item)
|
||||
return;
|
||||
if (item.DataContext is not GameFileViewModel)
|
||||
if (item.DataContext is not (GameFileViewModel or TreeItem))
|
||||
return;
|
||||
var listBox = ItemsControl.ItemsControlFromItemContainer(item) as ListBox;
|
||||
if (listBox == null)
|
||||
@@ -57,9 +57,20 @@ public partial class ResourcesDictionary
|
||||
}
|
||||
item.Focus();
|
||||
|
||||
var contextMenu = listBox.FindResource("FileContextMenu") as ContextMenu;
|
||||
var isFolder = item.DataContext is TreeItem;
|
||||
var contextMenu = listBox.FindResource(isFolder ? "FolderContextMenu" : "FileContextMenu") as ContextMenu;
|
||||
if (contextMenu is not null)
|
||||
{
|
||||
if (isFolder)
|
||||
{
|
||||
// Create FolderContextMenu only on right-click
|
||||
listBox.ContextMenu = null;
|
||||
contextMenu.PlacementTarget = item;
|
||||
contextMenu.IsOpen = true;
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
listBox.ContextMenu = null;
|
||||
item.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
|
||||
@@ -20,36 +20,13 @@
|
||||
|
||||
<Viewbox Grid.Row="0" Height="96" VerticalAlignment="Center">
|
||||
<Canvas Width="128" Height="128">
|
||||
<Canvas.Resources>
|
||||
<LinearGradientBrush x:Key="FolderTabGradient"
|
||||
StartPoint="0,0"
|
||||
EndPoint="0,1">
|
||||
<GradientStop Color="#FFE8C480"
|
||||
Offset="0" />
|
||||
<GradientStop Color="#FFD9AA63"
|
||||
Offset="1" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<LinearGradientBrush x:Key="FolderBodyGradient"
|
||||
StartPoint="0,0"
|
||||
EndPoint="0,1">
|
||||
<GradientStop Color="#FFF3D9A4"
|
||||
Offset="0" />
|
||||
<GradientStop Color="#FFE5BD77"
|
||||
Offset="1" />
|
||||
</LinearGradientBrush>
|
||||
|
||||
<SolidColorBrush x:Key="FolderOutlineBrush"
|
||||
Color="#D8A360" />
|
||||
</Canvas.Resources>
|
||||
|
||||
<Path Fill="{StaticResource FolderTabGradient}"
|
||||
Stroke="{StaticResource FolderOutlineBrush}"
|
||||
<Path Fill="{StaticResource TiledFolderTabBrush}"
|
||||
Stroke="{StaticResource TiledFolderOutlineBrush}"
|
||||
StrokeThickness="2"
|
||||
Data="M20 34 H54 L62 46 H108 C112 46 115 49 115 53 V60 H13 V45 C13 39 16 34 20 34 Z" />
|
||||
|
||||
<Path Fill="{StaticResource FolderBodyGradient}"
|
||||
Stroke="{StaticResource FolderOutlineBrush}"
|
||||
<Path Fill="{StaticResource TiledFolderBodyBrush}"
|
||||
Stroke="{StaticResource TiledFolderOutlineBrush}"
|
||||
StrokeThickness="2"
|
||||
Data="M13 60 H115 V104 C115 110 110 115 104 115 H24 C18 115 13 110 13 104 Z" />
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ public sealed class FolderTree : ListBox
|
||||
{
|
||||
public static readonly DependencyProperty FoldersProperty = DependencyProperty.Register(nameof(Folders), typeof(AssetsFolderViewModel), typeof(FolderTree));
|
||||
|
||||
public static readonly RoutedEvent ExpandArrowEvent = EventManager.RegisterRoutedEvent("ExpandArrow", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(FolderTree));
|
||||
public static readonly RoutedEvent CollapseArrowEvent = EventManager.RegisterRoutedEvent("CollapseArrow", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(FolderTree));
|
||||
|
||||
public AssetsFolderViewModel Folders
|
||||
{
|
||||
get => (AssetsFolderViewModel) GetValue(FoldersProperty);
|
||||
@@ -58,12 +61,28 @@ public sealed class FolderTree : ListBox
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleFolder(TreeItem folder)
|
||||
{
|
||||
if (Folders == null)
|
||||
return;
|
||||
|
||||
var wasExpanded = folder.IsExpanded;
|
||||
Folders.Toggle(folder);
|
||||
if (folder.IsExpanded == wasExpanded)
|
||||
return;
|
||||
|
||||
if (ItemContainerGenerator.ContainerFromItem(folder) is ListBoxItem row)
|
||||
{
|
||||
row.FindVisualChild<ToggleButton>()?.RaiseEvent(new RoutedEventArgs(folder.IsExpanded ? ExpandArrowEvent : CollapseArrowEvent));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.OriginalSource is DependencyObject source && source.FindAncestor<ToggleButton>() is { DataContext: TreeItem folder } && ContainerFromElement(this, source) is ListBoxItem)
|
||||
{
|
||||
e.Handled = true;
|
||||
Folders?.Toggle(folder);
|
||||
ToggleFolder(folder);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -77,7 +96,7 @@ public sealed class FolderTree : ListBox
|
||||
e.Handled = true;
|
||||
if (folder.Folders.Count > 0)
|
||||
{
|
||||
Folders?.Toggle(folder);
|
||||
ToggleFolder(folder);
|
||||
}
|
||||
else if (folder.AssetsList.Assets.Count > 0)
|
||||
{
|
||||
@@ -113,7 +132,7 @@ public sealed class FolderTree : ListBox
|
||||
case Key.Left:
|
||||
if (folder.IsExpanded)
|
||||
{
|
||||
Folders?.Toggle(folder);
|
||||
ToggleFolder(folder);
|
||||
}
|
||||
else if (folder.Parent != null)
|
||||
{
|
||||
@@ -123,7 +142,7 @@ public sealed class FolderTree : ListBox
|
||||
case Key.Right:
|
||||
if (!folder.IsExpanded)
|
||||
{
|
||||
Folders?.Toggle(folder);
|
||||
ToggleFolder(folder);
|
||||
}
|
||||
else if (folder.Folders.Count > 0)
|
||||
{
|
||||
@@ -144,7 +163,7 @@ public sealed class FolderTree : ListBox
|
||||
SelectFolder(folder);
|
||||
if (!folder.IsExpanded)
|
||||
{
|
||||
Folders?.Toggle(folder);
|
||||
ToggleFolder(folder);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -311,33 +311,30 @@
|
||||
<Setter TargetName="Arrow"
|
||||
Property="Tag"
|
||||
Value="-45" />
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard x:Name="ExpandArrow">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="ArrowRotation"
|
||||
Storyboard.TargetProperty="Angle"
|
||||
From="-90"
|
||||
To="-45"
|
||||
Duration="0:0:0.2" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard x:Name="CollapseArrow">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="ArrowRotation"
|
||||
Storyboard.TargetProperty="Angle"
|
||||
From="-45"
|
||||
To="-90"
|
||||
Duration="0:0:0.2" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
<!-- Don't replay animation whe not needed -->
|
||||
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
|
||||
<RemoveStoryboard BeginStoryboardName="ExpandArrow" />
|
||||
<RemoveStoryboard BeginStoryboardName="CollapseArrow" />
|
||||
<EventTrigger RoutedEvent="controls:FolderTree.ExpandArrow">
|
||||
<BeginStoryboard x:Name="ExpandArrow">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="ArrowRotation"
|
||||
Storyboard.TargetProperty="Angle"
|
||||
From="-90"
|
||||
To="-45"
|
||||
FillBehavior="Stop"
|
||||
Duration="0:0:0.2" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
<EventTrigger RoutedEvent="controls:FolderTree.CollapseArrow">
|
||||
<BeginStoryboard x:Name="CollapseArrow">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="ArrowRotation"
|
||||
Storyboard.TargetProperty="Angle"
|
||||
From="-45"
|
||||
To="-90"
|
||||
FillBehavior="Stop"
|
||||
Duration="0:0:0.2" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
<EventTrigger RoutedEvent="FrameworkElement.Unloaded">
|
||||
<RemoveStoryboard BeginStoryboardName="ExpandArrow" />
|
||||
|
||||
@@ -56,7 +56,7 @@ public class StaticModel : UModel<MeshVertex>
|
||||
Box = staticMesh.Bounds * 1.5f * Constants.SCALE_DOWN_RATIO;
|
||||
}
|
||||
|
||||
public StaticModel(UPaperSprite paperSprite, UTexture2D texture) : base(paperSprite)
|
||||
public StaticModel(UPaperSprite paperSprite) : base(paperSprite)
|
||||
{
|
||||
Indices = new uint[paperSprite.BakedRenderData.Length];
|
||||
for (int i = 0; i < Indices.Length; i++)
|
||||
@@ -97,7 +97,7 @@ public class StaticModel : UModel<MeshVertex>
|
||||
{
|
||||
Materials[0] = new Material();
|
||||
}
|
||||
Materials[0].Parameters.Textures[CMaterialParams2.FallbackDiffuse] = texture;
|
||||
Materials[0].Parameters.Textures[CMaterialParams2.FallbackDiffuse] = paperSprite.BakedSourceTexture;
|
||||
Materials[0].IsUsed = true;
|
||||
|
||||
Sections = new Section[1];
|
||||
|
||||
@@ -460,7 +460,7 @@ public class Renderer : IDisposable
|
||||
return;
|
||||
}
|
||||
|
||||
Options.Models[guid] = new StaticModel(original, texture);
|
||||
Options.Models[guid] = new StaticModel(original);
|
||||
Options.SelectModel(guid);
|
||||
}
|
||||
|
||||
@@ -804,8 +804,8 @@ public class Renderer : IDisposable
|
||||
|
||||
private void WorldTextureData(Material material, UObject textureData, string name, string key)
|
||||
{
|
||||
if (textureData.TryGetValue(out FPackageIndex package, name) && package.Load() is UTexture2D texture)
|
||||
material.Parameters.Textures[key] = texture;
|
||||
if (textureData.TryGetValue(out FPackageIndex package, name))
|
||||
material.Parameters.Textures[key] = package;
|
||||
}
|
||||
|
||||
private void AdditionalWorlds(UObject actor, Matrix4x4 relation, CancellationToken cancellationToken)
|
||||
|
||||
Reference in New Issue
Block a user