- Switched image loading/saving from Magick.NET to native stb_image (Ghost.StbI), removing Magick.NET dependency. - Added Ghost.StbI project with native DLL, P/Invoke bindings, and wrapper. - Refactored TextureAssetHandler and TextureProcessor for stb_image, memory-mapped IO, and HDR/16-bit support. - Split IAssetHandler into IImportableAssetHandler and IPackableAssetHandler; updated interfaces to use FileStream. - Added shader and mesh asset handlers (GraphicsShaderAssetHandler, ComputeShaderAssetHandler, FBXAssetHandler). - Improved asset registry/catalog path handling and naming consistency. - Updated asset import pipeline to use new interfaces and trigger engine reimport. - Enhanced UI toolbar button styles and EditPage layout. - Added StbIBindingTest, DisableRuntimeMarshalling, and native wrapper attributes. - Updated wrapper generator for regex derivesFrom; added stbi.json config. - Removed Magick.NET reference; added Ghost.StbI and Ghost.Ufbx references. - Miscellaneous bugfixes and code cleanup.
147 lines
4.6 KiB
C#
147 lines
4.6 KiB
C#
using CommunityToolkit.WinUI;
|
|
using Ghost.Editor.Core.Contracts;
|
|
using Ghost.Editor.Models;
|
|
using Ghost.Editor.ViewModels.Controls;
|
|
using Microsoft.UI.Xaml;
|
|
using Microsoft.UI.Xaml.Controls;
|
|
using Microsoft.UI.Xaml.Input;
|
|
|
|
namespace Ghost.Editor.Views.Controls;
|
|
|
|
internal sealed partial class ContentBrowser : UserControl
|
|
{
|
|
public static ContentBrowser? LastFocused
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
private readonly IInspectorService _inspectorService;
|
|
private bool _isUpdatingSelection = false;
|
|
|
|
public ContentBrowserViewModel ViewModel
|
|
{
|
|
get;
|
|
}
|
|
|
|
public ContentBrowser()
|
|
{
|
|
_inspectorService = App.GetService<IInspectorService>();
|
|
ViewModel = App.GetService<ContentBrowserViewModel>();
|
|
|
|
InitializeComponent();
|
|
|
|
Loaded += ProjectBrowser_Loaded;
|
|
Unloaded += ProjectBrowser_Unloaded;
|
|
}
|
|
|
|
private void ProjectBrowser_GettingFocus(UIElement sender, GettingFocusEventArgs args)
|
|
{
|
|
if (_isUpdatingSelection)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LastFocused = this;
|
|
}
|
|
|
|
private void ProjectBrowser_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
_inspectorService.OnSelectionChanged += _inspectorService_OnSelectionChanged;
|
|
GettingFocus += ProjectBrowser_GettingFocus;
|
|
}
|
|
|
|
private void ProjectBrowser_Unloaded(object sender, RoutedEventArgs e)
|
|
{
|
|
_inspectorService.OnSelectionChanged -= _inspectorService_OnSelectionChanged;
|
|
GettingFocus -= ProjectBrowser_GettingFocus;
|
|
|
|
if (LastFocused == this)
|
|
{
|
|
LastFocused = null;
|
|
}
|
|
}
|
|
|
|
private void _inspectorService_OnSelectionChanged(object? sender, InspectorSelectionChangedEventArgs e)
|
|
{
|
|
if (e.Source is not ContentBrowserViewModel)
|
|
{
|
|
PART_FilesView.DeselectAll();
|
|
PART_DirectoriesView.SelectedNodes.Clear();
|
|
}
|
|
}
|
|
|
|
private void PART_DirectoriesView_SelectionChanged(TreeView sender, TreeViewSelectionChangedEventArgs args)
|
|
{
|
|
if (_isUpdatingSelection)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_isUpdatingSelection = true;
|
|
|
|
PART_FilesView.DeselectAll();
|
|
if (args.AddedItems.Count > 0 && args.AddedItems[0] is ExplorerItem selectedItem)
|
|
{
|
|
ViewModel.SelectedItem = selectedItem;
|
|
ViewModel.NavigateToDirectory(selectedItem.Path);
|
|
}
|
|
|
|
_isUpdatingSelection = false;
|
|
}
|
|
|
|
private void PART_FilesView_SelectionChanged(object sender, SelectionChangedEventArgs args)
|
|
{
|
|
if (_isUpdatingSelection)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_isUpdatingSelection = true;
|
|
|
|
PART_DirectoriesView.SelectedNodes.Clear();
|
|
if (PART_FilesView.SelectedItem is ExplorerItem selectedItem)
|
|
{
|
|
ViewModel.SelectedItem = selectedItem;
|
|
}
|
|
|
|
_isUpdatingSelection = false;
|
|
}
|
|
|
|
private async void PART_FilesView_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
|
|
{
|
|
if (PART_FilesView.SelectedItem is ExplorerItem selectedItem)
|
|
{
|
|
_isUpdatingSelection = true;
|
|
|
|
PART_FilesView.DeselectAll();
|
|
PART_DirectoriesView.SelectedNodes.Clear();
|
|
|
|
// NOTE: There is bug that the hover state of the item may remain when navigating to another folder.
|
|
// Which causes incorrect selection (double click a folder -> directories view select target folder -> files view select the item that has the same index as the double clicked one and the hover visual stay remain from last level)
|
|
// Not sure if this is a WinUI bug or something else. This may because of the virtualization of the ItemsView.
|
|
// The core issue is not sure why PART_FilesView_SelectionChanged been triggered after NavigateToDirectory is already finished. And this only happens after the first double click navigation (first time is always fine).
|
|
|
|
// HACK: Wait a moment to let the ui clear it's state, otherwise the bug above will happen because of the virtualization.
|
|
await Task.Delay(100);
|
|
|
|
ViewModel.SelectedItem = selectedItem;
|
|
|
|
var navigatedItem = ViewModel.OpenSelected();
|
|
if (navigatedItem.Item1 != null)
|
|
{
|
|
if (navigatedItem.Item2 == 0)
|
|
{
|
|
PART_DirectoriesView.SelectedItem = navigatedItem.Item1;
|
|
}
|
|
else if (navigatedItem.Item2 == 1)
|
|
{
|
|
var index = ViewModel.Files.IndexOf(navigatedItem.Item1);
|
|
PART_FilesView.SelectedIndex = index;
|
|
}
|
|
}
|
|
|
|
_isUpdatingSelection = false;
|
|
}
|
|
}
|
|
} |