Refactor folder structure

This commit is contained in:
2026-02-18 00:50:46 +09:00
parent 426786397c
commit db8ca971a8
413 changed files with 2885 additions and 3634 deletions

View File

@@ -0,0 +1,39 @@
using Microsoft.UI.Xaml.Data;
namespace Ghost.Editor.Utilities.Converters;
public partial class AssetPathToGlyphConverter : IValueConverter
{
public object? Convert(object value, Type targetType, object parameter, string language)
{
if (value is not string path)
{
return null;
}
if (Directory.Exists(path))
{
return "\uE8B7";
}
var extension = Path.GetExtension(path).ToLowerInvariant();
// TODO: Use resource dictionary for icons.
return extension switch
{
".ghostscene" => "\uF159",
".fbx" or ".obj" => "\uF158",
".png" or ".jpg" or ".jpeg" or ".gif" or ".bmp" => "\uE91B",
".mp3" or ".wav" or ".ogg" => "\uE767",
".mp4" or ".avi" or ".mkv" => "\uE714",
".txt" or ".md" => "\uF000",
".cs" or ".hlsl" => "\uE943",
_ => "\uE8A5",
};
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,26 @@
using Ghost.Editor.Core.Contracts;
using Ghost.Editor.Models;
using Microsoft.UI.Xaml.Data;
namespace Ghost.Editor.Utilities.Converters;
public partial class ExplorerItemToIconUriConverter : IValueConverter
{
private readonly IPreviewService _previewService = App.GetService<IPreviewService>();
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is ExplorerItem item)
{
var path = _previewService.GetIconPath(item.FullName, item.IsDirectory, IconSize.Small);
return new Uri(path);
}
throw new NotSupportedException();
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,16 @@
using Microsoft.UI.Xaml.Data;
namespace Ghost.Editor.Utilities.Converters;
public partial class GetDirectoryNameConverter : IValueConverter
{
public object? Convert(object value, Type targetType, object parameter, string language)
{
return value is string path ? System.IO.Path.GetDirectoryName(path) : null;
}
public object? ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,29 @@
using Ghost.Engine.Utilities;
using Microsoft.UI.Xaml.Data;
using Misaki.HighPerformance.Mathematics;
using System.Numerics;
namespace Ghost.Editor.Utilities.Converters;
public partial class Vector3ToQuaternionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is float3 vector)
{
return quaternion.EulerXYZ(vector);
}
throw new ArgumentException($"Value must be of type {typeof(float3)}.", nameof(value));
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
if (value is quaternion qua)
{
return math.EulerXYZ(qua);
}
throw new ArgumentException($"Value must be of type {typeof(quaternion)}.", nameof(value));
}
}

View File

@@ -0,0 +1,46 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Reflection;
namespace Ghost.Editor.Utilities;
public class ReflectionBinding
{
private void RefreshField(FieldInfo field, FrameworkElement control, object source)
{
var value = field.GetValue(source);
switch (control)
{
case TextBox tb:
tb.Text = value?.ToString();
break;
case NumberBox nb when value is double d:
nb.Value = d;
break;
// Add more controls...
}
}
public void StartPollingField(FieldInfo field, FrameworkElement control, object component)
{
var lastValue = field.GetValue(component);
DispatcherTimer timer = new()
{
Interval = TimeSpan.FromMilliseconds(200)
};
timer.Tick += (_, _) =>
{
var currentValue = field.GetValue(component);
if (!Equals(currentValue, lastValue))
{
RefreshField(field, control, component);
lastValue = currentValue;
}
};
timer.Start();
}
}

View File

@@ -0,0 +1,39 @@
using Windows.Storage;
using Windows.Storage.Pickers;
using WinRT.Interop;
namespace Ghost.Editor.Utilities;
public static class SystemUtilities
{
public static async Task<StorageFolder?> OpenFolderPickerAsync(PickerLocationId startLocation = PickerLocationId.DocumentsLibrary, string settingsIdentifier = "")
{
var openPicker = new FolderPicker();
var hWnd = WindowNative.GetWindowHandle(App.Window);
InitializeWithWindow.Initialize(openPicker, hWnd);
openPicker.SuggestedStartLocation = startLocation;
openPicker.FileTypeFilter.Add("*");
openPicker.SettingsIdentifier = settingsIdentifier;
var folder = await openPicker.PickSingleFolderAsync();
return folder;
}
public static async Task<StorageFile?> OpenFilePickerAsync(PickerLocationId startLocation = PickerLocationId.DocumentsLibrary, string settingsIdentifier = "", params IEnumerable<string> filter)
{
var openPicker = new FileOpenPicker();
var hWnd = WindowNative.GetWindowHandle(App.Window);
InitializeWithWindow.Initialize(openPicker, hWnd);
openPicker.SuggestedStartLocation = startLocation;
openPicker.SettingsIdentifier = settingsIdentifier;
foreach (var fileType in filter)
{
openPicker.FileTypeFilter.Add(fileType);
}
var file = await openPicker.PickSingleFileAsync();
return file;
}
}