From c84ecb8f552b30284b7f5b793fed7f1b09a58477 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 22 Mar 2022 22:01:52 +0100 Subject: [PATCH 001/119] doc: Update changelog. --- .../Plugins/linux-x64/libminiz.so.2.2.0.meta | 37 ---------- .../Plugins/linux-x64/libvips.so.42.meta | 37 ---------- .../Plugins/osx/FluentAssertions.dll.meta | 67 ------------------- .../JeremyAnsel.Media.WavefrontObj.dll.meta | 67 ------------------- VisualPinball.Unity/Plugins/osx/NLog.dll.meta | 67 ------------------- .../Plugins/osx/NetMiniZ.dll.meta | 67 ------------------- .../Plugins/osx/NetVips.dll.meta | 67 ------------------- .../Plugins/osx/OpenMcdf.dll.meta | 67 ------------------- .../Plugins/osx/System.Buffers.dll.meta | 67 ------------------- .../osx/VisualPinball.Resources.dll.meta | 67 ------------------- .../Plugins/osx/arm64/libvips.42.dylib.meta | 61 ----------------- .../Plugins/osx/libminiz.2.2.0.dylib.meta | 61 ----------------- .../Plugins/osx/x64/libvips.42.dylib.meta | 61 ----------------- .../Plugins/win-x86/libglib-2.0-0.dll.meta | 37 ---------- .../Plugins/win-x86/libgobject-2.0-0.dll.meta | 37 ---------- .../Plugins/win-x86/libminiz-2.2.0.dll.meta | 37 ---------- .../Plugins/win-x86/libvips-42.dll.meta | 37 ---------- .../TypeRestrictionPropertyDrawer.cs.meta | 22 +++--- .../Common/UnitPropertyDrawer.cs.meta | 22 +++--- .../ProjectSettings/ProjectVersion.txt | 4 +- 20 files changed, 24 insertions(+), 965 deletions(-) delete mode 100644 VisualPinball.Unity/Plugins/linux-x64/libminiz.so.2.2.0.meta delete mode 100644 VisualPinball.Unity/Plugins/linux-x64/libvips.so.42.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/FluentAssertions.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/JeremyAnsel.Media.WavefrontObj.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/NLog.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/NetMiniZ.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/NetVips.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/OpenMcdf.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/System.Buffers.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/VisualPinball.Resources.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/arm64/libvips.42.dylib.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/libminiz.2.2.0.dylib.meta delete mode 100644 VisualPinball.Unity/Plugins/osx/x64/libvips.42.dylib.meta delete mode 100644 VisualPinball.Unity/Plugins/win-x86/libglib-2.0-0.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/win-x86/libgobject-2.0-0.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/win-x86/libminiz-2.2.0.dll.meta delete mode 100644 VisualPinball.Unity/Plugins/win-x86/libvips-42.dll.meta diff --git a/VisualPinball.Unity/Plugins/linux-x64/libminiz.so.2.2.0.meta b/VisualPinball.Unity/Plugins/linux-x64/libminiz.so.2.2.0.meta deleted file mode 100644 index d77ba3c64..000000000 --- a/VisualPinball.Unity/Plugins/linux-x64/libminiz.so.2.2.0.meta +++ /dev/null @@ -1,37 +0,0 @@ -fileFormatVersion: 2 -guid: e01b97b82baf34d3b978b38cd56b7909 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Android: 1 - Exclude Linux64: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86_64 - DefaultValueInitialized: true - OS: Linux - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/linux-x64/libvips.so.42.meta b/VisualPinball.Unity/Plugins/linux-x64/libvips.so.42.meta deleted file mode 100644 index 9c33a8189..000000000 --- a/VisualPinball.Unity/Plugins/linux-x64/libvips.so.42.meta +++ /dev/null @@ -1,37 +0,0 @@ -fileFormatVersion: 2 -guid: a8d7399998b424736b8b45c9a745afdd -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Android: 1 - Exclude Linux64: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86_64 - DefaultValueInitialized: true - OS: Linux - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/FluentAssertions.dll.meta b/VisualPinball.Unity/Plugins/osx/FluentAssertions.dll.meta deleted file mode 100644 index 0aae7e0f1..000000000 --- a/VisualPinball.Unity/Plugins/osx/FluentAssertions.dll.meta +++ /dev/null @@ -1,67 +0,0 @@ -fileFormatVersion: 2 -guid: 2ff3616451db402babb91241bb478534 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 0 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/JeremyAnsel.Media.WavefrontObj.dll.meta b/VisualPinball.Unity/Plugins/osx/JeremyAnsel.Media.WavefrontObj.dll.meta deleted file mode 100644 index 869095443..000000000 --- a/VisualPinball.Unity/Plugins/osx/JeremyAnsel.Media.WavefrontObj.dll.meta +++ /dev/null @@ -1,67 +0,0 @@ -fileFormatVersion: 2 -guid: c128e53352934b978b92086569057e2e -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 0 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/NLog.dll.meta b/VisualPinball.Unity/Plugins/osx/NLog.dll.meta deleted file mode 100644 index 748d39ae8..000000000 --- a/VisualPinball.Unity/Plugins/osx/NLog.dll.meta +++ /dev/null @@ -1,67 +0,0 @@ -fileFormatVersion: 2 -guid: b5836c2589934c088183e61d68d838bd -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 0 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/NetMiniZ.dll.meta b/VisualPinball.Unity/Plugins/osx/NetMiniZ.dll.meta deleted file mode 100644 index c8f40e1e9..000000000 --- a/VisualPinball.Unity/Plugins/osx/NetMiniZ.dll.meta +++ /dev/null @@ -1,67 +0,0 @@ -fileFormatVersion: 2 -guid: 1cd00b127a2fe46bda1f7157c2805643 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 0 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/NetVips.dll.meta b/VisualPinball.Unity/Plugins/osx/NetVips.dll.meta deleted file mode 100644 index 70118cc53..000000000 --- a/VisualPinball.Unity/Plugins/osx/NetVips.dll.meta +++ /dev/null @@ -1,67 +0,0 @@ -fileFormatVersion: 2 -guid: efd150e7670c947d1bc5b58f258c0411 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 0 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/OpenMcdf.dll.meta b/VisualPinball.Unity/Plugins/osx/OpenMcdf.dll.meta deleted file mode 100644 index a8a9437b2..000000000 --- a/VisualPinball.Unity/Plugins/osx/OpenMcdf.dll.meta +++ /dev/null @@ -1,67 +0,0 @@ -fileFormatVersion: 2 -guid: a71e29523fd5435ebab91b056bc4668a -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 0 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/System.Buffers.dll.meta b/VisualPinball.Unity/Plugins/osx/System.Buffers.dll.meta deleted file mode 100644 index 1f3401121..000000000 --- a/VisualPinball.Unity/Plugins/osx/System.Buffers.dll.meta +++ /dev/null @@ -1,67 +0,0 @@ -fileFormatVersion: 2 -guid: 790bd16b83804608b169d768f9eab5c6 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 0 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/VisualPinball.Resources.dll.meta b/VisualPinball.Unity/Plugins/osx/VisualPinball.Resources.dll.meta deleted file mode 100644 index 094a27ab2..000000000 --- a/VisualPinball.Unity/Plugins/osx/VisualPinball.Resources.dll.meta +++ /dev/null @@ -1,67 +0,0 @@ -fileFormatVersion: 2 -guid: 3697eb7b79fa4337af40d4945edcd0ee -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 0 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: OSXUniversal - second: - enabled: 1 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: x86 - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Windows Store Apps: WindowsStoreApps - second: - enabled: 0 - settings: - CPU: AnyCPU - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/arm64/libvips.42.dylib.meta b/VisualPinball.Unity/Plugins/osx/arm64/libvips.42.dylib.meta deleted file mode 100644 index 4195d7a43..000000000 --- a/VisualPinball.Unity/Plugins/osx/arm64/libvips.42.dylib.meta +++ /dev/null @@ -1,61 +0,0 @@ -fileFormatVersion: 2 -guid: 7405861bffc445149297b77d1ed7de80 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: ARM64 - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: OSXUniversal - second: - enabled: 0 - settings: - CPU: ARM64 - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: None - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/libminiz.2.2.0.dylib.meta b/VisualPinball.Unity/Plugins/osx/libminiz.2.2.0.dylib.meta deleted file mode 100644 index be7db5068..000000000 --- a/VisualPinball.Unity/Plugins/osx/libminiz.2.2.0.dylib.meta +++ /dev/null @@ -1,61 +0,0 @@ -fileFormatVersion: 2 -guid: 719460f33a250490abe7a9eb12eda7b5 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: AnyCPU - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: OSXUniversal - second: - enabled: 0 - settings: - CPU: AnyCPU - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: None - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/osx/x64/libvips.42.dylib.meta b/VisualPinball.Unity/Plugins/osx/x64/libvips.42.dylib.meta deleted file mode 100644 index 7121756a6..000000000 --- a/VisualPinball.Unity/Plugins/osx/x64/libvips.42.dylib.meta +++ /dev/null @@ -1,61 +0,0 @@ -fileFormatVersion: 2 -guid: 629ca47c52bd64d36ab6fd6a6480dbff -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Android: 1 - Exclude Editor: 0 - Exclude Linux64: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86_64 - DefaultValueInitialized: true - OS: OSX - - first: - Standalone: Linux64 - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: OSXUniversal - second: - enabled: 0 - settings: - CPU: x86_64 - - first: - Standalone: Win - second: - enabled: 0 - settings: - CPU: None - - first: - Standalone: Win64 - second: - enabled: 0 - settings: - CPU: None - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/win-x86/libglib-2.0-0.dll.meta b/VisualPinball.Unity/Plugins/win-x86/libglib-2.0-0.dll.meta deleted file mode 100644 index 0240057b7..000000000 --- a/VisualPinball.Unity/Plugins/win-x86/libglib-2.0-0.dll.meta +++ /dev/null @@ -1,37 +0,0 @@ -fileFormatVersion: 2 -guid: 9021f42e1d3e74360a2fd003e93dae40 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Android: 1 - Exclude Linux64: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86 - DefaultValueInitialized: true - OS: Windows - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/win-x86/libgobject-2.0-0.dll.meta b/VisualPinball.Unity/Plugins/win-x86/libgobject-2.0-0.dll.meta deleted file mode 100644 index b6d690a4b..000000000 --- a/VisualPinball.Unity/Plugins/win-x86/libgobject-2.0-0.dll.meta +++ /dev/null @@ -1,37 +0,0 @@ -fileFormatVersion: 2 -guid: 51d02f718d3d14889b7ce744cd578683 -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Android: 1 - Exclude Linux64: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86 - DefaultValueInitialized: true - OS: Windows - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/win-x86/libminiz-2.2.0.dll.meta b/VisualPinball.Unity/Plugins/win-x86/libminiz-2.2.0.dll.meta deleted file mode 100644 index edaa842ff..000000000 --- a/VisualPinball.Unity/Plugins/win-x86/libminiz-2.2.0.dll.meta +++ /dev/null @@ -1,37 +0,0 @@ -fileFormatVersion: 2 -guid: 027b225a47cab476680e0c436a19607c -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Android: 1 - Exclude Linux64: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86 - DefaultValueInitialized: true - OS: Windows - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/Plugins/win-x86/libvips-42.dll.meta b/VisualPinball.Unity/Plugins/win-x86/libvips-42.dll.meta deleted file mode 100644 index b3974fe4a..000000000 --- a/VisualPinball.Unity/Plugins/win-x86/libvips-42.dll.meta +++ /dev/null @@ -1,37 +0,0 @@ -fileFormatVersion: 2 -guid: ab0cca862802649db88535582f8a7abb -PluginImporter: - externalObjects: {} - serializedVersion: 2 - iconMap: {} - executionOrder: {} - defineConstraints: [] - isPreloaded: 0 - isOverridable: 1 - isExplicitlyReferenced: 0 - validateReferences: 1 - platformData: - - first: - : Any - second: - enabled: 0 - settings: - Exclude Editor: 0 - Exclude Android: 1 - Exclude Linux64: 1 - Exclude OSXUniversal: 1 - Exclude Win: 1 - Exclude Win64: 1 - Exclude iOS: 1 - Exclude tvOS: 1 - - first: - Editor: Editor - second: - enabled: 1 - settings: - CPU: x86 - DefaultValueInitialized: true - OS: Windows - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs.meta index 181ec9f1a..ce62d0fb6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: b3c72225c90b1b640bba2e9f2efc0fa3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: b3c72225c90b1b640bba2e9f2efc0fa3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/UnitPropertyDrawer.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/UnitPropertyDrawer.cs.meta index a922a58e7..58a1c404e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/UnitPropertyDrawer.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/UnitPropertyDrawer.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 1accad5d5db00244284c9de6406ebaff -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 1accad5d5db00244284c9de6406ebaff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/ProjectVersion.txt b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/ProjectVersion.txt index 3384268eb..6b2c79b80 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/ProjectVersion.txt +++ b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2021.3.0f1 -m_EditorVersionWithRevision: 2021.3.0f1 (6eacc8284459) +m_EditorVersion: 2021.3.0f1 +m_EditorVersionWithRevision: 2021.3.0f1 (6eacc8284459) From 5d5d27929a1a5c68f7cb09fc32241c3862c72cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Fri, 19 Nov 2021 18:50:55 +0100 Subject: [PATCH 002/119] prefabs-library : first version - PrefabLibrarySettingsAsset - PrefabLibraryEditor - First try with global PinballMetaData embedded into assets .meta userData field - new JsonSerializableList object to allow save/load of polymorphic lists into Json format - new ProjectFolderPropertyDrawer for setting folders into PrefabLibrarySettingsAsset --- .../Common/JsonSerializableList.cs | 67 +++++++ .../Common/JsonSerializableList.cs.meta | 11 ++ .../PinballMetadata.meta | 8 + .../PinballMetadata/PinballMetadata.cs | 91 +++++++++ .../PinballMetadata/PinballMetadata.cs.meta | 11 ++ .../PrefabLibrary.meta | 8 + .../PrefabLibrary/PrefabLibraryEditor.cs | 173 ++++++++++++++++++ .../PrefabLibrary/PrefabLibraryEditor.cs.meta | 11 ++ .../PrefabLibrary/PrefabLibraryEditor.uxml | 8 + .../PrefabLibraryEditor.uxml.meta | 10 + .../PrefabLibrarySettingsAsset.cs | 67 +++++++ .../PrefabLibrarySettingsAsset.cs.meta | 11 ++ .../Utils/PropertyDrawers.meta | 8 + .../ProjectFolderPropertyDrawer.cs | 91 +++++++++ .../ProjectFolderPropertyDrawer.cs.meta | 11 ++ .../TypeRestrictionPropertyDrawer.cs | 0 .../TypeRestrictionPropertyDrawer.cs.meta | 11 ++ .../PropertyDrawers}/UnitPropertyDrawer.cs | 0 .../VisualPinball.Unity.Editor.csproj | 3 + 19 files changed, 600 insertions(+) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Common/JsonSerializableList.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Common/JsonSerializableList.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/ProjectFolderPropertyDrawer.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/ProjectFolderPropertyDrawer.cs.meta rename VisualPinball.Unity/VisualPinball.Unity.Editor/{Common => Utils/PropertyDrawers}/TypeRestrictionPropertyDrawer.cs (100%) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/TypeRestrictionPropertyDrawer.cs.meta rename VisualPinball.Unity/VisualPinball.Unity.Editor/{Common => Utils/PropertyDrawers}/UnitPropertyDrawer.cs (100%) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/JsonSerializableList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/JsonSerializableList.cs new file mode 100644 index 000000000..82ecbf1a0 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/JsonSerializableList.cs @@ -0,0 +1,67 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + /// + /// This class manage the Json serialization of a polymorphic list. + /// It outputs each list element type alongside its Json export to ensure correct serialization. + /// + [Serializable] + public class JsonPolymorphicList : ISerializationCallbackReceiver + { + [NonSerialized] + public List Items = new List(); + + [Serializable] + class SerializedItem + { + public string Type; + public string Json; + } + + [SerializeField] + private List SerializedItems = new List(); + + public void OnBeforeSerialize() + { + SerializedItems.Clear(); + foreach(var item in Items) { + SerializedItems.Add(new SerializedItem() { + Type = item.GetType().ToString(), + Json = JsonUtility.ToJson(item) + }); + } + } + + public void OnAfterDeserialize() + { + foreach (var item in SerializedItems) { + Type type = Type.GetType(item.Type); + if (type.IsSubclassOf(typeof(BaseType))) { + Items.Add((BaseType)JsonUtility.FromJson(item.Json, type)); + } + } + SerializedItems.Clear(); + } + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/JsonSerializableList.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/JsonSerializableList.cs.meta new file mode 100644 index 000000000..e103777a7 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/JsonSerializableList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f021fd2a4a0dbc242a47bd143a95b4b6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata.meta new file mode 100644 index 000000000..d64b3f293 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 339883d21b375b64f8356d5d35bba986 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs new file mode 100644 index 000000000..961d11a69 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + [Serializable] + public class PinballMetadataExtension + { + public int Version = 1; + } + + [Serializable] + public class PinballTagsMetadata : PinballMetadataExtension + { + public PinballTagsMetadata() : base() + { + Version = 2; + } + + public List Tags = new List(); + } + + [Serializable] + public class PinballMetadata + { + [SerializeField] + private JsonPolymorphicList Extensions = new JsonPolymorphicList(); + + public void AddExtenstion(PinballMetadataExtension ext) + { + Remove(ext.GetType()); + Extensions.Items.Add(ext); + } + + public void Remove(Type extType) + { + Extensions.Items.RemoveAll(E => E.GetType() == extType); + } + public ExtType GetExtension() where ExtType : PinballMetadataExtension + { + return (ExtType)Extensions.Items.FirstOrDefault(E => E.GetType() == typeof(ExtType)); + } + } + + public class PinballMetadataCache : Dictionary + { + public static PinballMetadata GetMetadata(string guid) => PinballMetadataMainCache.FirstOrDefault(KV => KV.Key.Equals(guid, StringComparison.InvariantCultureIgnoreCase)).Value; + public static void AddMetadata(string guid, PinballMetadata data) { + if (PinballMetadataMainCache.ContainsKey(guid)) { + PinballMetadataMainCache[guid] = data; + } else { + PinballMetadataMainCache.Add(guid, data); + } + } + + public static void RemoveMetaData(string guid) + { + PinballMetadataMainCache.Remove(guid); + } + + public static void ClearCache() + { + PinballMetadataMainCache.Clear(); + } + + public static PinballMetadata LoadMetadata(string guid) + { + var path = AssetDatabase.GUIDToAssetPath(guid); + var metadata = GetMetadata(guid); + if (metadata == null) { + metadata = new PinballMetadata(); + AddMetadata(guid, metadata); + if (path != "") { + path = path.Replace("\\", "/"); + AssetImporter import = AssetImporter.GetAtPath(path); + if (import.userData != string.Empty) { + EditorJsonUtility.FromJsonOverwrite(import.userData, metadata); + } + } + } + return metadata; + } + + private static PinballMetadataCache PinballMetadataMainCache = new PinballMetadataCache(); + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs.meta new file mode 100644 index 000000000..a31a5acbc --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a67bcb20b905c4645b71c88319389365 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary.meta new file mode 100644 index 000000000..97d11afb0 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ab2cf1c3dc8d4dd4ebea8daa3b0ece40 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs new file mode 100644 index 000000000..13b37859f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine; +using UnityEditor; +using Logger = NLog.Logger; +using Object = UnityEngine.Object; +using System.Linq; +using System.IO; +using UnityEngine.UIElements; + +namespace VisualPinball.Unity.Editor +{ + + + internal class PrefabLibraryFolderContent + { + private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + + public class PrefabData + { + public GameObject Prefab; + public PinballTagsMetadata TagsMetadata; + } + + public PrefabLibrarySettingsAsset.FolderSettings FolderSetting; + public List Prefabs = new List(); + private FileSystemWatcher FolderWatcher = new FileSystemWatcher(); + private List TagsCategories = new List(); + + public List Categories => TagsCategories; + + public List Tags { + get { + var tags = new List(); + foreach (var prefab in Prefabs) { + if (prefab.TagsMetadata != null) { + tags = tags.Union(prefab.TagsMetadata.Tags).ToList(); + } + } + return tags; + } + } + + public Action Populate; + + public PrefabLibraryFolderContent(PrefabLibrarySettingsAsset.FolderSettings folderSetting) + { + FolderSetting = folderSetting; + var folderPath = AssetDatabase.GUIDToAssetPath(FolderSetting.FolderReference.Guid); + if (folderPath != string.Empty) { + FolderWatcher.Path = folderPath; + FolderWatcher.NotifyFilter = NotifyFilters.Attributes + | NotifyFilters.CreationTime + | NotifyFilters.DirectoryName + | NotifyFilters.FileName + | NotifyFilters.LastAccess + | NotifyFilters.LastWrite + | NotifyFilters.Security + | NotifyFilters.Size; + FolderWatcher.Created += OnChanged; + FolderWatcher.Deleted += OnChanged; + FolderWatcher.Renamed += OnRenamed; + FolderWatcher.Changed += OnChanged; + FolderWatcher.EnableRaisingEvents = true; + } + } + + private void OnChanged(object sender, FileSystemEventArgs e) + { + + } + + private void OnRenamed(object sender, RenamedEventArgs e) + { + + } + + public void PopulatePrefabs() + { + Prefabs.Clear(); + var folderpath = AssetDatabase.GUIDToAssetPath(FolderSetting.FolderReference.Guid); + EditorUtility.DisplayProgressBar("Parsing Prefabs", folderpath, 0.0f); + var guids = AssetDatabase.FindAssets("t: Prefab", new[] { folderpath }); + int count = 0; + + foreach (var guid in guids) { + var path = AssetDatabase.GUIDToAssetPath(guid); + if (!FolderSetting.Recursive && !Path.GetDirectoryName(path).Equals(folderpath, StringComparison.InvariantCultureIgnoreCase)) { + continue; + } + var asset = AssetDatabase.LoadMainAssetAtPath(path.Replace("\\", "/")) as GameObject; + if (asset != null) { + var cachedMetadata = PinballMetadataCache.LoadMetadata(guid); + var prefabData = new PrefabData() { Prefab = asset, TagsMetadata = cachedMetadata.GetExtension() }; + Prefabs.Add(prefabData); + } + EditorUtility.DisplayProgressBar($"Parsing Prefabs {count+1}/{guids.Length}", path, (float)count++/guids.Length); + } + + EditorUtility.ClearProgressBar(); + + //Extract Categories + TagsCategories.Clear(); + foreach (var prefab in Prefabs) { + if (prefab.TagsMetadata != null) { + foreach (var tag in prefab.TagsMetadata.Tags) { + var subtags = tag.Split('.'); + if (subtags.Length > 1 && !TagsCategories.Contains(subtags[0])) { + TagsCategories.Add(subtags[0]); + } + } + } + } + + Populate?.Invoke(this); + } + } + + public class PrefabLibraryEditor : BaseEditorWindow + { + private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + + private List FolderContents = new List(); + private List Tags = new List(); + private List Categories = new List(); + + [MenuItem("Visual Pinball/Prefab Library", false, 601)] + public static void ShowWindow() + { + GetWindow().titleContent = new GUIContent("Prefabs Library"); + } + + public override void OnEnable() + { + base.OnEnable(); + + VisualTreeAsset original = AssetDatabase.LoadAssetAtPath("Packages/org.visualpinball.engine.unity/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml"); + TemplateContainer treeAsset = original.CloneTree(); + rootVisualElement.Add(treeAsset); + } + + public void OnGUI() + { + CheckPrefabSettinbgsAssets(); + } + + private void CheckPrefabSettinbgsAssets() + { + PinballMetadataCache.ClearCache(); + var guids = AssetDatabase.FindAssets("t: PrefabLibrarySettingsAsset"); + foreach(var guid in guids) { + var asset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); + foreach (var folder in asset.Folders) { + if (!FolderContents.Any(FC=>FC.FolderSetting == folder)) { + var newFolder = new PrefabLibraryFolderContent(folder); + newFolder.Populate += OnFolderPopulate; + newFolder.PopulatePrefabs(); + FolderContents.Add(newFolder); + } + } + Categories = Categories.Union(asset.Categories).ToList(); + Tags = Tags.Union(asset.AvailableTags).ToList(); + } + } + + private void OnFolderPopulate(PrefabLibraryFolderContent folder) + { + Categories = Categories.Union(folder.Categories).ToList(); + Tags = Tags.Union(folder.Tags).ToList(); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs.meta new file mode 100644 index 000000000..61e5a99db --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 991f30e39fecd70489c60bcd3f45943a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml new file mode 100644 index 000000000..fd59ac09f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml.meta new file mode 100644 index 000000000..df0be682e --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7804dd53ff4b519498831fb1664556a8 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs new file mode 100644 index 000000000..d4d599101 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs @@ -0,0 +1,67 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + /// + /// An asset containing somme prefab library settings. + /// Prefabs are populated to the using these settings. + /// + /// + /// You can have several PrefabLibrarySettingsAssets, the editor will find all of them into the AssetDatabase. + /// + [CreateAssetMenu(fileName = "Prefab Library Settings", menuName = "Visual Pinball/Prefab Library Settings", order = 101)] + public class PrefabLibrarySettingsAsset : ScriptableObject + { + public string Name = "Prefab Library"; + + [Serializable] + public class FolderSettings + { + public ProjectFolderReference FolderReference = new ProjectFolderReference(); + [Tooltip("Prefabs will be searched recursively into this path.")] + public bool Recursive = true; + } + + public bool Locked = false; + + public List AvailableTags = new List(); + + public List Categories + { + get { + var categories = new List(); + foreach(var tag in AvailableTags) { + var subtags = tag.Split('.'); + if (subtags.Length > 1 && !categories.Contains(subtags[0])) { + categories.Add(subtags[0]); + } + } + return categories; + } + } + + public List Folders = new List(); + + private Dictionary> AssetTags = new Dictionary>(); + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs.meta new file mode 100644 index 000000000..c798f3b0a --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e7ef981808f75684c9e9496d55e0971e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers.meta new file mode 100644 index 000000000..fafc5068e --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e081370b4eca1ee4abaff6c90385934c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/ProjectFolderPropertyDrawer.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/ProjectFolderPropertyDrawer.cs new file mode 100644 index 000000000..1af309f2f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/ProjectFolderPropertyDrawer.cs @@ -0,0 +1,91 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using UnityEditor; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace VisualPinball.Unity.Editor +{ + [Serializable] + public class ProjectFolderReference + { + public string Guid = string.Empty; + } + + [CustomPropertyDrawer(typeof(ProjectFolderReference))] + public class ProjectFolderPropertyDrawer : PropertyDrawer + { + private SerializedProperty guid; + private Object obj; + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + guid = property.FindPropertyRelative("Guid"); + obj = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid.stringValue)); + + GUIContent guiContent = EditorGUIUtility.ObjectContent(obj, typeof(DefaultAsset)); + + Rect r = EditorGUI.PrefixLabel(position, label); + + Rect textFieldRect = r; + textFieldRect.width -= 19f; + + GUIStyle textFieldStyle = new GUIStyle("TextField") { + imagePosition = obj ? ImagePosition.ImageLeft : ImagePosition.TextOnly + }; + + if (GUI.Button(textFieldRect, guiContent, textFieldStyle) && obj) + EditorGUIUtility.PingObject(obj); + + if (textFieldRect.Contains(Event.current.mousePosition)) { + if (Event.current.type == EventType.DragUpdated) { + Object reference = DragAndDrop.objectReferences[0]; + string path = AssetDatabase.GetAssetPath(reference); + DragAndDrop.visualMode = Directory.Exists(path) ? DragAndDropVisualMode.Copy : DragAndDropVisualMode.Rejected; + Event.current.Use(); + } else if (Event.current.type == EventType.DragPerform) { + Object reference = DragAndDrop.objectReferences[0]; + string path = AssetDatabase.GetAssetPath(reference); + if (Directory.Exists(path)) { + obj = reference; + guid.stringValue = AssetDatabase.AssetPathToGUID(path); + } + Event.current.Use(); + } + } + + Rect objectFieldRect = r; + objectFieldRect.x = textFieldRect.xMax + 1f; + objectFieldRect.width = 19f; + + if (GUI.Button(objectFieldRect, "", GUI.skin.GetStyle("IN ObjectField"))) { + string path = EditorUtility.OpenFolderPanel("Select a folder", "", ""); + if (path != string.Empty) { + if (path.Contains(Application.dataPath)) { + path = "Assets" + path.Substring(Application.dataPath.Length); + obj = AssetDatabase.LoadAssetAtPath(path, typeof(DefaultAsset)); + guid.stringValue = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(obj)); + } else Debug.LogError("The path must be in the Assets folder"); + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/ProjectFolderPropertyDrawer.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/ProjectFolderPropertyDrawer.cs.meta new file mode 100644 index 000000000..88c9b1595 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/ProjectFolderPropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1315b5c661a6bb64097d3c0a5addae10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/TypeRestrictionPropertyDrawer.cs similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs rename to VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/TypeRestrictionPropertyDrawer.cs diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/TypeRestrictionPropertyDrawer.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/TypeRestrictionPropertyDrawer.cs.meta new file mode 100644 index 000000000..cdc32b3a8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/TypeRestrictionPropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a3946b3258239a54f81bacead2952377 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/UnitPropertyDrawer.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/UnitPropertyDrawer.cs similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/Common/UnitPropertyDrawer.cs rename to VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/UnitPropertyDrawer.cs diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.csproj b/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.csproj index 48633ec69..90323121c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.csproj +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.csproj @@ -52,5 +52,8 @@ ..\Plugins\.unity\Unity.Entities.Hybrid.dll + + ..\Plugins\.unity\UnityEngine.UIElementsModule.dll + From c07e42c97bb93bff98a73f85768f24683cbb671b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Tue, 23 Nov 2021 09:17:16 +0100 Subject: [PATCH 003/119] prefab library : moving meta alogside moved cs --- .../Common/TypeRestrictionPropertyDrawer.cs.meta | 11 ----------- .../PropertyDrawers}/UnitPropertyDrawer.cs.meta | 8 ++++---- 2 files changed, 4 insertions(+), 15 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs.meta rename VisualPinball.Unity/VisualPinball.Unity.Editor/{Common => Utils/PropertyDrawers}/UnitPropertyDrawer.cs.meta (58%) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs.meta deleted file mode 100644 index ce62d0fb6..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TypeRestrictionPropertyDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b3c72225c90b1b640bba2e9f2efc0fa3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/UnitPropertyDrawer.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/UnitPropertyDrawer.cs.meta similarity index 58% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/Common/UnitPropertyDrawer.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/UnitPropertyDrawer.cs.meta index 58a1c404e..211746b74 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/UnitPropertyDrawer.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/UnitPropertyDrawer.cs.meta @@ -1,11 +1,11 @@ fileFormatVersion: 2 -guid: 1accad5d5db00244284c9de6406ebaff +guid: eb481e9f7b301b4428449bf025936309 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: + userData: + assetBundleName: + assetBundleVariant: From 0846787b8d2355c587d067f1ab10a6185028d0bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Wed, 22 Dec 2021 17:56:06 +0100 Subject: [PATCH 004/119] prefablibrary : First working version of PrefabLibraryEditor - generic Thumbnailview & ThumbnailViewElement - generic Popuplist adapted from UnityReferenceSource - PrefabThumnailView & PrefabThumbnailViewElement - LabelsPopupList - Added CreatePixelTexture helper to TextureExtensions - Updated PrefabLibraryEditor - Thumbnail view integrated - Details view including prefab interactive preview --- .../VisualPinball.Unity.Editor/Labels.meta | 8 + .../Labels/LabelsHandler.cs | 42 ++ .../Labels/LabelsHandler.cs.meta | 11 + .../Labels/LabelsLibraryAsset.cs | 34 ++ .../Labels/LabelsLibraryAsset.cs.meta | 11 + .../Labels/PinballLabel.cs | 82 +++ .../Labels/PinballLabel.cs.meta | 11 + .../Labels/PinballLabelCategory.cs | 34 ++ .../Labels/PinballLabelCategory.cs.meta | 11 + .../Labels/PopupLabelsList.cs | 181 ++++++ .../Labels/PopupLabelsList.cs.meta | 11 + .../PinballLabels.meta | 8 + .../PinballMetadata/PinballMetadata.cs | 11 - .../PinballMetadata/PinballTag.cs | 75 +++ .../PinballMetadata/PinballTag.cs.meta | 11 + .../PinballMetadata/PinballTagsMetaData.cs | 14 + .../PinballTagsMetaData.cs.meta | 11 + .../PrefabLibrary/PrefabLibraryEditor.cs | 161 ++++-- .../PrefabLibrarySettingsAsset.cs | 16 - .../PrefabLibrary/PrefabThumbnailElement.cs | 64 +++ .../PrefabThumbnailElement.cs.meta | 11 + .../PrefabLibrary/PrefabThumbnailView.cs | 42 ++ .../PrefabLibrary/PrefabThumbnailView.cs.meta | 11 + .../PrefabLibrary/TagThumbnailElement.cs | 52 ++ .../PrefabLibrary/TagThumbnailElement.cs.meta | 11 + .../Utils/PopupList.meta | 8 + .../Utils/PopupList/PopupList.cs | 518 ++++++++++++++++++ .../Utils/PopupList/PopupList.cs.meta | 11 + .../PinballLabelPropertyDrawer.cs | 75 +++ .../PinballLabelPropertyDrawer.cs.meta | 11 + .../Utils/ThumbnailView.meta | 8 + .../Utils/ThumbnailView/ThumbnailElement.cs | 89 +++ .../ThumbnailView/ThumbnailElement.cs.meta | 11 + .../Utils/ThumbnailView/ThumbnailView.cs | 242 ++++++++ .../Utils/ThumbnailView/ThumbnailView.cs.meta | 11 + .../Extensions/TextureExtensions.cs | 7 + 36 files changed, 1849 insertions(+), 76 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballLabels.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels.meta new file mode 100644 index 000000000..8a4057845 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6822ae07e9e60c144a6fa46a61ce3e93 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs new file mode 100644 index 000000000..fc242c6be --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs @@ -0,0 +1,42 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; + +namespace VisualPinball.Unity.Editor +{ + public class LabelsHandler + { + private List _pinballLabels = new List(); + + public string[] Categories => _pinballLabels.Select(L => L.Category).Distinct().ToArray(); + + public LabelsHandler() { } + + public void AddLabels(IEnumerable labels) + { + _pinballLabels.Union(labels.Select(L => new PinballLabel(L))); + } + + public string[] GetLabels(string category) => _pinballLabels.Where(L => string.IsNullOrEmpty(category) || L.Category.Equals(category, StringComparison.InvariantCultureIgnoreCase)) + .Select(L => L.Label).ToArray(); + + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs.meta new file mode 100644 index 000000000..3f6ae88c7 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1e09930d8dc03e84db0e60532c6e72ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs new file mode 100644 index 000000000..d507b0e70 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs @@ -0,0 +1,34 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + [CreateAssetMenu(fileName = "Labels Library", menuName = "Visual Pinball/Label Library", order = 101)] + public class LabelsLibraryAsset : ScriptableObject + { + public string Name = "Labels Library"; + + public List Categories = new List(); + + public List Labels = new List(); + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs.meta new file mode 100644 index 000000000..4e886fa51 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7edc6d1268bbb1438428d421b1f185a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs new file mode 100644 index 000000000..adbd02bb1 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs @@ -0,0 +1,82 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + [Serializable] + public class PinballLabel : ISerializationCallbackReceiver + { + [SerializeField] + private string _fullLabel = string.Empty; + public string FullLabel + { + get { return _fullLabel; } + set { _fullLabel = value; Build(); } + } + + [field: NonSerialized] + public bool Editable = true; + + [field:NonSerialized] + public string Label { get; private set; } = string.Empty; + [field:NonSerialized] + public string Category { get; private set; } = string.Empty; + + public PinballLabel(string label) + { + _fullLabel = label; + Build(); + } + + private void Build() + { + if (string.IsNullOrEmpty(_fullLabel)) { + Label = string.Empty; + Category = string.Empty; + return; + } + var tuple = Split(_fullLabel); + Category = tuple.Item1; + Label = tuple.Item2; + } + + internal static Tuple Split(string fullLabel) + { + var split = fullLabel.Split('.'); + string category = string.Empty, label = string.Empty; + + if (split.Length > 1) { + if (split.Length > 2) { + category = string.Join('_', split, 0, split.Length - 1); + } else { + category = split[0]; + } + label = split[split.Length - 1]; + } else { + label = fullLabel; + } + + return new Tuple(category, label); + } + + public void OnBeforeSerialize() {} + + public void OnAfterDeserialize() { Build(); } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs.meta new file mode 100644 index 000000000..2f46b0b99 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b42136ad39cf2904198d1142768b5ada +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs new file mode 100644 index 000000000..e845988ff --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs @@ -0,0 +1,34 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + [Serializable] + public class PinballLabelCategory + { + [SerializeField] + public string Name = string.Empty; + + [SerializeField] + public bool MultipleSelection = true; + + [SerializeField] + public Color Color = Color.blue; + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs.meta new file mode 100644 index 000000000..29f5876b1 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05f57b1f2cbcd0547b52ce8229a60f79 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs new file mode 100644 index 000000000..e418f75cf --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs @@ -0,0 +1,181 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEditor; +using UnityEngine; +using Logger = NLog.Logger; + +namespace VisualPinball.Unity.Editor +{ + public class PopupLabelList : PopupList + { + private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + + private PopupListElement _selectedElement = null; + private string _selectedCategory = string.Empty; + private Dictionary> _categoryDictionary = new Dictionary>(); + private GUIStyle _categoryStyle; + + private void CreateStyles() + { + _categoryStyle = new GUIStyle("MenuItem"); + } + + public PopupLabelList(InputData inputData) : base(inputData) + { + CreateStyles(); + BuildCategoryDictionary(""); + } + + public PopupLabelList(InputData inputData, string initialSelectionLabel) : base(inputData, initialSelectionLabel) + { + CreateStyles(); + BuildCategoryDictionary(""); + } + + public override float GetWindowHeight() + { + int count = _categoryDictionary.Keys.Count(K => !string.IsNullOrEmpty(K)); + count += _categoryDictionary.Values.Sum(L=>L.Count); + return count * k_LineHeight + 2 * k_Margin + (m_Data.m_AllowCustom ? k_TextFieldHeight : 0); + } + + private void BuildCategoryDictionary(string filterText) + { + _categoryDictionary.Clear(); + foreach (var element in m_Data.GetFilteredList(filterText)) { + var tuple = PinballLabel.Split(element.text); + if (!_categoryDictionary.Keys.Contains(tuple.Item1)) { + _categoryDictionary.Add(tuple.Item1, new List()); + } + _categoryDictionary[tuple.Item1].Add(element); + } + Logger.Debug($"Category Dictionary Rebuilt :\nKeys [{string.Join(",", _categoryDictionary.Keys.ToArray())}]"); + } + + protected override void OnFilterTextChange(string oldText, string newText) + { + BuildCategoryDictionary(newText); + } + + protected override void DrawList(EditorWindow editorWindow, Rect windowRect) + { + Event evt = Event.current; + + var categoryDictionary = new Dictionary>(); + foreach (var element in m_Data.GetFilteredList(m_EnteredText)) { + var tuple = PinballLabel.Split(element.text); + if (!categoryDictionary.Keys.Contains(tuple.Item1)) { + categoryDictionary.Add(tuple.Item1, new List()); + } + categoryDictionary[tuple.Item1].Add(element); + } + + int i = -1; + Rect rect = new Rect(); + + foreach (var category in categoryDictionary.Keys) { + if (!string.IsNullOrEmpty(category)) { + i++; + rect.Set(windowRect.x, windowRect.y + k_Margin + i * k_LineHeight + (m_Gravity == Gravity.Top && m_Data.m_AllowCustom ? k_TextFieldHeight : 0), windowRect.width, k_LineHeight); + HandleCategory(evt, category, rect); + } + + foreach (var element in categoryDictionary[category]) { + i++; + rect.Set(windowRect.x, windowRect.y + k_Margin + i * k_LineHeight + (m_Gravity == Gravity.Top && m_Data.m_AllowCustom ? k_TextFieldHeight : 0), windowRect.width, k_LineHeight); + HandleLabel(evt, category, element, rect); + } + } + } + + private void HandleLabel(Event evt, string category, PopupListElement element, Rect rect) + { + switch (evt.type) { + case EventType.Repaint: { + GUIStyle style = element.style; + bool selected = element.selected || element.partiallySelected; + bool isHover = element == _selectedElement; + bool isActive = selected; + + using (new EditorGUI.DisabledScope(!element.enabled)) { + GUIContent content = new GUIContent($"{(string.IsNullOrEmpty(category) ? string.Empty : " ")}{PinballLabel.Split(element.text).Item2}"); + style.Draw(rect, content, isHover, isActive, selected, false); + } + } + break; + case EventType.MouseDown: { + if (Event.current.button == 0 && rect.Contains(Event.current.mousePosition) && element.enabled) { + // Toggle state + if (m_Data.m_OnSelectCallback != null) + m_Data.m_OnSelectCallback(element); + + evt.Use(); + + // Auto close + if (m_Data.m_CloseOnSelection) + editorWindow.Close(); + } + } + break; + case EventType.MouseMove: { + if (rect.Contains(Event.current.mousePosition)) { + _selectedElement = element; + _selectedCategory = string.Empty; + //SelectCompletionWithIndex(i); + evt.Use(); + } + } + break; + } + } + + private void HandleCategory(Event evt, string category, Rect rect) + { + switch (evt.type) { + case EventType.Repaint: { + bool isHover = category == _selectedCategory; + + using (new EditorGUI.DisabledScope()) { + GUIContent content = new GUIContent(category); + _categoryStyle.Draw(rect, content, isHover, true, false, false); + } + } + break; + case EventType.MouseDown: { + if (Event.current.button == 0 && rect.Contains(Event.current.mousePosition)) { + //TODO Set the filterText to categoryname + '.' + evt.Use(); + } + } + break; + case EventType.MouseMove: { + if (rect.Contains(Event.current.mousePosition)) { + _selectedCategory = category; + _selectedElement = null; + //SelectCompletionWithIndex(i); + evt.Use(); + } + } + break; + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs.meta new file mode 100644 index 000000000..485be6447 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ebb45e6c4e090c6438ad6c83e7eac5c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballLabels.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballLabels.meta new file mode 100644 index 000000000..66cbd037f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballLabels.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e8168ee5cc0cdb442ab46c677d2c4f81 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs index 961d11a69..b68e837ec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs @@ -13,17 +13,6 @@ public class PinballMetadataExtension public int Version = 1; } - [Serializable] - public class PinballTagsMetadata : PinballMetadataExtension - { - public PinballTagsMetadata() : base() - { - Version = 2; - } - - public List Tags = new List(); - } - [Serializable] public class PinballMetadata { diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs new file mode 100644 index 000000000..34f538496 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs @@ -0,0 +1,75 @@ + +using System; +using System.ComponentModel; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + +namespace VisualPinball.Unity.Editor +{ + [Serializable] + public class PinballTag : ISerializationCallbackReceiver + { + [SerializeField] + private string _fullTag = string.Empty; + public string FullTag { + get { return _fullTag; } + set { _fullTag = value; Build(); } + } + [field: NonSerialized] + public string Tag { get; private set; } = string.Empty; + [field: NonSerialized] + public string Category { get; private set; } = string.Empty; + + public PinballTag(string fullTag) + { + _fullTag = fullTag; + Build(); + } + + public void OnBeforeSerialize() {} + + public void OnAfterDeserialize() { Build(); } + + private void Build() + { + if (string.IsNullOrEmpty(_fullTag)) { + Tag = string.Empty; + Category = string.Empty; + return; + } + var split = _fullTag.Split('.'); + if (split.Length > 1) { + if (split.Length > 2) { + Category = string.Join('_', split, 0, split.Length - 1); + } else { + Category = split[0]; + } + Tag = split[split.Length - 1]; + } + } + } + + //[CustomPropertyDrawer(typeof(PinballTag))] + //public class PinballTagPropertyDrawer : PropertyDrawer + //{ + // private string _tag = string.Empty; + // public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + // { + // var prop = property.FindPropertyRelative("FullTag"); + // _tag = prop.stringValue; + + // Rect r = EditorGUI.PrefixLabel(position, label); + + // Rect textFieldRect = r; + // textFieldRect.width -= 19f; + + // GUIStyle textFieldStyle = new GUIStyle("TextField") { + // imagePosition = ImagePosition.TextOnly + // }; + + // _tag = GUI.TextField(textFieldRect, _tag); + // } + //} +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs.meta new file mode 100644 index 000000000..8cf64f605 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5a3eac806e853124e842ba4ad79abcc7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs new file mode 100644 index 000000000..768df1e27 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace VisualPinball.Unity.Editor +{ + [Serializable] + public class PinballTagsMetadata : PinballMetadataExtension + { + public PinballTagsMetadata() : base() {} + public List Tags = new List(); + } + +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs.meta new file mode 100644 index 000000000..705dfc188 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c577752523210634d9370ab0b1e4ac44 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs index 13b37859f..0090cbfe7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs @@ -1,18 +1,29 @@ -using System; +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; using System.Collections.Generic; -using System.Text; using UnityEngine; using UnityEditor; using Logger = NLog.Logger; -using Object = UnityEngine.Object; using System.Linq; using System.IO; -using UnityEngine.UIElements; namespace VisualPinball.Unity.Editor { - - internal class PrefabLibraryFolderContent { private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); @@ -20,27 +31,12 @@ internal class PrefabLibraryFolderContent public class PrefabData { public GameObject Prefab; - public PinballTagsMetadata TagsMetadata; + public string[] Labels; } public PrefabLibrarySettingsAsset.FolderSettings FolderSetting; public List Prefabs = new List(); private FileSystemWatcher FolderWatcher = new FileSystemWatcher(); - private List TagsCategories = new List(); - - public List Categories => TagsCategories; - - public List Tags { - get { - var tags = new List(); - foreach (var prefab in Prefabs) { - if (prefab.TagsMetadata != null) { - tags = tags.Union(prefab.TagsMetadata.Tags).ToList(); - } - } - return tags; - } - } public Action Populate; @@ -92,7 +88,7 @@ public void PopulatePrefabs() var asset = AssetDatabase.LoadMainAssetAtPath(path.Replace("\\", "/")) as GameObject; if (asset != null) { var cachedMetadata = PinballMetadataCache.LoadMetadata(guid); - var prefabData = new PrefabData() { Prefab = asset, TagsMetadata = cachedMetadata.GetExtension() }; + var prefabData = new PrefabData() { Prefab = asset, Labels = AssetDatabase.GetLabels(new GUID(guid)) }; Prefabs.Add(prefabData); } EditorUtility.DisplayProgressBar($"Parsing Prefabs {count+1}/{guids.Length}", path, (float)count++/guids.Length); @@ -100,19 +96,6 @@ public void PopulatePrefabs() EditorUtility.ClearProgressBar(); - //Extract Categories - TagsCategories.Clear(); - foreach (var prefab in Prefabs) { - if (prefab.TagsMetadata != null) { - foreach (var tag in prefab.TagsMetadata.Tags) { - var subtags = tag.Split('.'); - if (subtags.Length > 1 && !TagsCategories.Contains(subtags[0])) { - TagsCategories.Add(subtags[0]); - } - } - } - } - Populate?.Invoke(this); } } @@ -121,9 +104,14 @@ public class PrefabLibraryEditor : BaseEditorWindow { private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); - private List FolderContents = new List(); - private List Tags = new List(); - private List Categories = new List(); + private List _folderContents = new List(); + + private LabelsHandler _labelsHandler = new LabelsHandler(); + + private List _thumbs = new List(); + private PrefabThumbnailView _thumbView = new PrefabThumbnailView(null) { MultiSelection = false }; + + private UnityEditor.Editor _previewEditor = null; [MenuItem("Visual Pinball/Prefab Library", false, 601)] public static void ShowWindow() @@ -135,39 +123,114 @@ public override void OnEnable() { base.OnEnable(); - VisualTreeAsset original = AssetDatabase.LoadAssetAtPath("Packages/org.visualpinball.engine.unity/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml"); - TemplateContainer treeAsset = original.CloneTree(); - rootVisualElement.Add(treeAsset); + CheckPrefabSettinbgsAssets(); + } + + private const float DetailsWindowWidth = 400.0f; + + private bool _showDetails = true; + private bool _showLabels = true; + + private void DetailsGUI() + { + + if (_thumbView.SelectedPrefab == null) { + DestroyImmediate(_previewEditor); + _previewEditor = null; + } else if (_previewEditor == null || _thumbView.SelectedPrefab != _previewEditor.target) { + if (_previewEditor != null) { + DestroyImmediate(_previewEditor); + } + _previewEditor = UnityEditor.Editor.CreateEditor(_thumbView.SelectedPrefab); + } + + if (_previewEditor) { + var previewSize = DetailsWindowWidth - GUI.skin.box.lineHeight - GUI.skin.label.padding.horizontal; + var rect = EditorGUILayout.GetControlRect(false, previewSize, GUILayout.Width(previewSize)); + EditorGUI.PrefixLabel(rect, new GUIContent("Preview")); + rect.yMin += GUI.skin.label.lineHeight + GUI.skin.label.padding.vertical; + _previewEditor.OnInteractivePreviewGUI(rect, GUI.skin.box); + + if (_showDetails = EditorGUILayout.BeginFoldoutHeaderGroup(_showDetails, new GUIContent("Details"))) { + EditorGUI.indentLevel++; + var style = EditorStyles.label; + style.wordWrap = true; + EditorGUILayout.LabelField($"Name : {_thumbView.SelectedPrefab.name}", style); + EditorGUILayout.LabelField($"Path : {AssetDatabase.GetAssetPath(_thumbView.SelectedPrefab)}", style); + EditorGUILayout.Separator(); + var meshRenderer = _thumbView.SelectedPrefab.GetComponentInChildren(); + var meshFilter = _thumbView.SelectedPrefab.GetComponentInChildren(); + if (meshRenderer && meshFilter){ + EditorGUILayout.LabelField($"Mesh : {meshRenderer.name}", style); + EditorGUI.indentLevel++; + if (meshFilter.sharedMesh != null) { + EditorGUILayout.LabelField($"{meshFilter.sharedMesh.subMeshCount} submesh{(meshFilter.sharedMesh.subMeshCount>1?"es":"")}", style); + EditorGUILayout.LabelField($"{meshFilter.sharedMesh.vertices.Length} vertices", style); + EditorGUILayout.LabelField($"{meshFilter.sharedMesh.triangles.Length} triangles", style); + } + if (meshRenderer.sharedMaterials != null) { + EditorGUILayout.LabelField($"{meshRenderer.sharedMaterials.Length} material{(meshRenderer.sharedMaterials.Length>1?"s":"")} : {(meshRenderer.sharedMaterials.Length > 0 ? string.Join(',', meshRenderer.sharedMaterials.Select(M => M ? M.name : "null")) : "")}", style); + } + EditorGUI.indentLevel--; + } + EditorGUI.indentLevel--; + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + if (_showLabels = EditorGUILayout.BeginFoldoutHeaderGroup(_showLabels, new GUIContent("Labels"))) { + EditorGUI.indentLevel++; + EditorGUILayout.LabelField(new GUIContent("Labels")); + EditorGUI.indentLevel--; + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + } else { + EditorGUILayout.LabelField(new GUIContent("Select a prefab")); + } } public void OnGUI() { - CheckPrefabSettinbgsAssets(); + EditorGUILayout.BeginHorizontal(); + + var thumbRect = new Rect(position); + thumbRect.width -= DetailsWindowWidth; + _thumbView.OnGUI(thumbRect); + + EditorGUILayout.BeginVertical(); + DetailsGUI(); + EditorGUILayout.EndVertical(); + + EditorGUILayout.EndHorizontal(); } private void CheckPrefabSettinbgsAssets() { PinballMetadataCache.ClearCache(); + var guids = AssetDatabase.FindAssets("t: PrefabLibrarySettingsAsset"); foreach(var guid in guids) { var asset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); foreach (var folder in asset.Folders) { - if (!FolderContents.Any(FC=>FC.FolderSetting == folder)) { + if (!_folderContents.Any(FC=>FC.FolderSetting == folder)) { var newFolder = new PrefabLibraryFolderContent(folder); newFolder.Populate += OnFolderPopulate; newFolder.PopulatePrefabs(); - FolderContents.Add(newFolder); + _folderContents.Add(newFolder); } } - Categories = Categories.Union(asset.Categories).ToList(); - Tags = Tags.Union(asset.AvailableTags).ToList(); + //LabelHandler add tags from settings assets } + + _thumbView.SetData(_thumbs); + AssetPreview.SetPreviewTextureCacheSize(_thumbs.Count + 10); } private void OnFolderPopulate(PrefabLibraryFolderContent folder) { - Categories = Categories.Union(folder.Categories).ToList(); - Tags = Tags.Union(folder.Tags).ToList(); + foreach (var prefab in folder.Prefabs) { + _thumbs.Add(new PrefabThumbnailElement(prefab.Prefab)); + } } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs index d4d599101..e0b74db1e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs @@ -44,22 +44,6 @@ public class FolderSettings public bool Locked = false; - public List AvailableTags = new List(); - - public List Categories - { - get { - var categories = new List(); - foreach(var tag in AvailableTags) { - var subtags = tag.Split('.'); - if (subtags.Length > 1 && !categories.Contains(subtags[0])) { - categories.Add(subtags[0]); - } - } - return categories; - } - } - public List Folders = new List(); private Dictionary> AssetTags = new Dictionary>(); diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs new file mode 100644 index 000000000..dd99c1de9 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs @@ -0,0 +1,64 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + public class PrefabThumbnailElement : ThumbnailElement + { + private GameObject _prefab = null; + public GameObject Prefab => _prefab; + + private static Dictionary _commonSizes = new Dictionary() { + { EThumbnailSize.Small, new Rect(3, 3, 64, 64) }, + { EThumbnailSize.Normal, new Rect(3, 3, 128, 128) }, + { EThumbnailSize.Large, new Rect(3, 3, 256, 256) } + }; + public override Dictionary CommonSizes => _commonSizes; + + public PrefabThumbnailElement(GameObject prefab) : base() + { + _prefab = prefab; + } + + public override string Name => _prefab?.name; + + public override void OnGUI(Rect rect, GUIStyle style) + { + var boxRect = new Rect(rect.x, rect.y, rect.width, rect.height); + var assetPreview = AssetPreview.GetAssetPreview(_prefab); + GUI.Box(boxRect, new GUIContent(), style); + boxRect.x += style.border.left; + boxRect.y += style.border.top; + boxRect.width -= style.border.horizontal; + boxRect.height -= style.border.vertical; + GUI.DrawTexture(boxRect, assetPreview, ScaleMode.StretchToFill); + } + + public override void DrawHoverContainer(Rect rect) + { + } + + public override Vector2 GetHoverContainerSize() + { + return new Vector2(100, 100); + } + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs.meta new file mode 100644 index 000000000..a87c2b5b7 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 51f12c64012021045a8d04de0d025c61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs new file mode 100644 index 000000000..9ef41a4b8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + public class PrefabThumbnailView : ThumbnailView + { + public GameObject SelectedPrefab => SelectedItem?.Prefab; + + public PrefabThumbnailView(IEnumerable data) : base(data) { } + + protected override void InitCommonStyles() + { + if (!_commonStyles.Inited) { + _commonStyles.DefaultStyle = new GUIStyle("button"); + _commonStyles.SelectedStyle = new GUIStyle(_commonStyles.DefaultStyle); + _commonStyles.SelectedStyle.active.background = TextureExtensions.CreatePixelTexture(new Color(0.5f, .5f, .8f)); + _commonStyles.SelectedStyle.normal = _commonStyles.SelectedStyle.active; + _commonStyles.SelectedStyle.hover = _commonStyles.SelectedStyle.active; + _commonStyles.SelectedStyle.focused = _commonStyles.SelectedStyle.active; + _commonStyles.NameStyle = new GUIStyle("label"); + _commonStyles.HoverStyle = new GUIStyle(); + _commonStyles.HoverStyle.normal.background = TextureExtensions.CreatePixelTexture(new Color(.25f, .25f, .25f)); + } + } + + protected override void OnGUIToolbar() + { + } + + protected override bool MatchLabelFilter(PrefabThumbnailElement item, string labelFilter) + { + var labels = AssetDatabase.GetLabels(item.Prefab); + return labels.Any(L => L.Contains(labelFilter, StringComparison.InvariantCultureIgnoreCase)); + } + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs.meta new file mode 100644 index 000000000..0a330acaf --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01f965648d0ef164d981e944d1603dc8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs new file mode 100644 index 000000000..8a88f422e --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs @@ -0,0 +1,52 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + public class TagThumbnailElement : ThumbnailElement + { + private string _tag = string.Empty; + private string _category = string.Empty; + + public TagThumbnailElement(string tag) : base() + { + _tag = tag; + } + + public override string Name => throw new System.NotImplementedException(); + + public override Dictionary CommonSizes => throw new System.NotImplementedException(); + + public override void DrawHoverContainer(Rect rect) + { + throw new System.NotImplementedException(); + } + + public override Vector2 GetHoverContainerSize() + { + throw new System.NotImplementedException(); + } + + public override void OnGUI(Rect rect, GUIStyle style) + { + throw new System.NotImplementedException(); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs.meta new file mode 100644 index 000000000..7ceb0da18 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d96844e6f902b7e4e8b618ddda7638bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList.meta new file mode 100644 index 000000000..fa1ed118c --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f2a2f44a80a3713438ef565e9424c4e9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs new file mode 100644 index 000000000..b8f095382 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs @@ -0,0 +1,518 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + public class PopupListElement + { + public GUIContent m_Content; + private float m_FilterScore = -1; + private bool m_Selected = false; + private bool m_WasSelected = false; + private bool m_PartiallySelected = false; + private bool m_Enabled = true; + + public PopupListElement() + { + } + + public PopupListElement(string text, bool selected, float score) + : base() + { + m_Content = new GUIContent(text); + if (!string.IsNullOrEmpty(m_Content.text)) { + char[] a = m_Content.text.ToCharArray(); + a[0] = char.ToUpper(a[0]); + m_Content.text = new string(a); + } + m_Selected = selected; + filterScore = score; + m_PartiallySelected = false; + m_Enabled = true; + } + + public PopupListElement(string text, bool selected) + { + m_Content = new GUIContent(text); + m_Selected = selected; + filterScore = 0; + m_PartiallySelected = false; + m_Enabled = true; + } + + public PopupListElement(string text) : this(text, false) + { + } + + public float filterScore + { + get { + return m_WasSelected ? float.MaxValue : m_FilterScore; + } + set { + m_FilterScore = value; + ResetScore(); + } + } + + public bool selectable => true; + + public bool selected + { + get { + return selectable && m_Selected; + } + set { + m_Selected = value; + if (m_Selected) + m_WasSelected = true; + } + } + + public bool enabled + { + get { + return m_Enabled; + } + set { + m_Enabled = value; + } + } + + public bool partiallySelected + { + get { + return selectable && m_PartiallySelected; + } + set { + m_PartiallySelected = value; + if (m_PartiallySelected) + m_WasSelected = true; + } + } + + public string text + { + get { + return m_Content.text; + } + set { + m_Content.text = value; + } + } + + public GUIStyle style + { + get { + return partiallySelected ? "MenuItemMixed" : "MenuItem"; + } + } + + public float width + { + get { + float min, max; + style.CalcMinMaxWidth(m_Content, out min, out max); + return max; + } + } + public void ResetScore() + { + m_WasSelected = m_Selected || m_PartiallySelected; + } + } + + public class PopupList : PopupWindowContent where T : PopupListElement, new() + { + public delegate void OnSelectCallback(T element); + string TextFieldText = string.Empty; + public enum Gravity + { + Top, + Bottom + } + + public class InputData + { + public List m_ListElements; + public bool m_CloseOnSelection; + public bool m_AllowCustom; + public bool m_EnableAutoCompletion = true; + public bool m_SortAlphabetically; + public OnSelectCallback m_OnSelectCallback; + public int m_MaxCount; + + public InputData() + { + m_ListElements = new List(); + } + + public void DeselectAll() + { + foreach (T element in m_ListElements) { + element.selected = false; + element.partiallySelected = false; + } + } + + public void ResetScores() + { + foreach (var element in m_ListElements) + element.ResetScore(); + } + + public virtual IEnumerable BuildQuery(string prefix) + { + if (prefix == "") + return m_ListElements; + else + return m_ListElements.Where( + element => element.m_Content.text.StartsWith(prefix, System.StringComparison.OrdinalIgnoreCase) + ); + } + + public IEnumerable GetFilteredList(string prefix) + { + IEnumerable res = BuildQuery(prefix); + if (m_MaxCount > 0) + res = res.OrderByDescending(element => element.filterScore).Take(m_MaxCount); + if (m_SortAlphabetically) + return res.OrderBy(element => element.text.ToLower()); + else + return res; + } + + public int GetFilteredCount(string prefix) + { + IEnumerable res = BuildQuery(prefix); + if (m_MaxCount > 0) + res = res.Take(m_MaxCount); + return res.Count(); + } + + public T NewOrMatchingElement(string label) + { + foreach (var element in m_ListElements) { + if (element.text.Equals(label, StringComparison.OrdinalIgnoreCase)) + return element; + } + + var res = new T() { text = label, selected = false }; + m_ListElements.Add(res); + return res; + } + } + + protected class Styles + { + public GUIStyle background = "grey_border"; + public GUIStyle customTextField; + public GUIStyle customTextFieldCancelButton; + public GUIStyle customTextFieldCancelButtonEmpty; + public Styles() + { + customTextField = new GUIStyle(EditorStyles.toolbarSearchField); + customTextFieldCancelButton = new GUIStyle("ToolbarSeachCancelButton"); + customTextFieldCancelButtonEmpty = new GUIStyle("ToolbarSeachCancelButtonEmpty"); + } + } + + // Static + protected static Styles s_Styles; + + // State + protected InputData m_Data; + + // Layout + protected const float k_LineHeight = 16; + protected const float k_TextFieldHeight = 16; + protected const float k_Margin = 10; + protected Gravity m_Gravity; + + protected string m_EnteredTextCompletion = ""; + protected string m_EnteredText = ""; + protected int m_SelectedCompletionIndex = 0; + + public PopupList(InputData inputData) : this(inputData, null) { } + + public PopupList(InputData inputData, string initialSelectionLabel) + { + m_Data = inputData; + m_Data.ResetScores(); + SelectNoCompletion(); + m_Gravity = Gravity.Top; + if (initialSelectionLabel != null) { + m_EnteredTextCompletion = initialSelectionLabel; + UpdateCompletion(); + } + } + + public override void OnClose() + { + if (m_Data != null) + m_Data.ResetScores(); + } + + public virtual float GetWindowHeight() + { + int count = (m_Data.m_MaxCount == 0) ? m_Data.GetFilteredCount(m_EnteredText) : m_Data.m_MaxCount; + return count * k_LineHeight + 2 * k_Margin + (m_Data.m_AllowCustom ? k_TextFieldHeight : 0); + } + + public virtual float GetWindowWidth() + { + return m_Data.GetFilteredList("").Max(E=>E.width); + } + + public override Vector2 GetWindowSize() + { + return new Vector2(GetWindowWidth(), GetWindowHeight()); + } + + public override void OnGUI(Rect windowRect) + { + Event evt = Event.current; + // We do not use the layout event + if (evt.type == EventType.Layout) + return; + + if (s_Styles == null) + s_Styles = new Styles(); + + if (evt.type == EventType.KeyDown && evt.keyCode == KeyCode.Escape) { + editorWindow.Close(); + GUIUtility.ExitGUI(); + } + + if (m_Gravity == Gravity.Bottom) { + DrawList(editorWindow, windowRect); + DrawCustomTextField(editorWindow, windowRect); + } else { + DrawCustomTextField(editorWindow, windowRect); + DrawList(editorWindow, windowRect); + } + + // Background with 1 pixel border (rendered above content) + if (evt.type == EventType.Repaint) + s_Styles.background.Draw(new Rect(windowRect.x, windowRect.y, windowRect.width, windowRect.height), false, false, false, false); + } + + protected virtual void DrawCustomTextField(EditorWindow editorWindow, Rect windowRect) + { + if (!m_Data.m_AllowCustom) + return; + + Event evt = Event.current; + bool enableAutoCompletion = m_Data.m_EnableAutoCompletion; + bool closeWindow = false; + bool clearText = false; + + string textBeforeEdit = CurrentDisplayedText(); + + // Handle "special" keyboard input + if (evt.type == EventType.KeyDown) { + switch (evt.keyCode) { + case KeyCode.Comma: + case KeyCode.Space: + case KeyCode.Tab: + case KeyCode.Return: + if (textBeforeEdit != "") { + // Toggle state + if (m_Data.m_OnSelectCallback != null) + m_Data.m_OnSelectCallback(m_Data.NewOrMatchingElement(textBeforeEdit)); + + if (evt.keyCode == KeyCode.Tab || evt.keyCode == KeyCode.Comma) + clearText = true; // to ease multiple entries (it is unlikely that the same filter is used more than once) + + // Auto close + if (m_Data.m_CloseOnSelection || evt.keyCode == KeyCode.Return) + closeWindow = true; + } + evt.Use(); + break; + case KeyCode.Delete: + case KeyCode.Backspace: + enableAutoCompletion = false; + // Don't use the event yet, so the textfield below can get it and delete the selection + break; + + case KeyCode.DownArrow: + ChangeSelectedCompletion(1); + evt.Use(); + break; + + case KeyCode.UpArrow: + ChangeSelectedCompletion(-1); + evt.Use(); + break; + case KeyCode.None: + if (evt.character == ' ' || evt.character == ',') { + evt.Use(); + } + break; + } + } + + // Draw textfield + { + Rect pos = new Rect(windowRect.x + k_Margin / 2, windowRect.y + (m_Gravity == Gravity.Top ? (k_Margin / 2) : (windowRect.height - k_TextFieldHeight - k_Margin / 2)), windowRect.width - k_Margin - 14, k_TextFieldHeight); + + TextFieldText = EditorGUI.TextField(pos, textBeforeEdit, s_Styles.customTextField); + + Rect buttonRect = pos; + buttonRect.x += pos.width; + buttonRect.width = 14; + // Draw "clear textfield" button (X) + if ((GUI.Button(buttonRect, GUIContent.none, TextFieldText != "" ? s_Styles.customTextFieldCancelButton : s_Styles.customTextFieldCancelButtonEmpty) && TextFieldText != "") + || clearText) { + TextFieldText = string.Empty; + GUIUtility.keyboardControl = 0; + enableAutoCompletion = false; + } + } + + // Handle autocompletion + if (textBeforeEdit != TextFieldText) { + OnFilterTextChange(m_EnteredText, TextFieldText); + m_EnteredText = TextFieldText; + + if (enableAutoCompletion) + UpdateCompletion(); + else + SelectNoCompletion(); + } + + if (closeWindow) + editorWindow.Close(); + } + + protected virtual void OnFilterTextChange(string oldText, string newText) {} + + protected string CurrentDisplayedText() + { + return m_EnteredTextCompletion != "" ? m_EnteredTextCompletion : m_EnteredText; + } + + protected void UpdateCompletion() + { + if (!m_Data.m_EnableAutoCompletion) + return; + IEnumerable query = m_Data.GetFilteredList(m_EnteredText).Select(element => element.text); + + if (m_EnteredTextCompletion != "" && m_EnteredTextCompletion.StartsWith(m_EnteredText, System.StringComparison.OrdinalIgnoreCase)) { + m_SelectedCompletionIndex = query.TakeWhile(element => element != m_EnteredTextCompletion).Count(); + // m_EnteredTextCompletion is already correct + } else { + // Clamp m_SelectedCompletionIndex to 0..query.Count () - 1 + if (m_SelectedCompletionIndex < 0) + m_SelectedCompletionIndex = 0; + else if (m_SelectedCompletionIndex >= query.Count()) + m_SelectedCompletionIndex = query.Count() - 1; + + m_EnteredTextCompletion = query.Skip(m_SelectedCompletionIndex).DefaultIfEmpty("").FirstOrDefault(); + } + AdjustRecycledEditorSelectionToCompletion(); + } + + protected void ChangeSelectedCompletion(int change) + { + int count = m_Data.GetFilteredCount(m_EnteredText); + if (m_SelectedCompletionIndex == -1 && change < 0) // specal case for initial selection + m_SelectedCompletionIndex = count; + + int index = count > 0 ? (m_SelectedCompletionIndex + change + count) % count : 0; + SelectCompletionWithIndex(index); + } + + protected void SelectCompletionWithIndex(int index) + { + m_SelectedCompletionIndex = index; + m_EnteredTextCompletion = ""; + UpdateCompletion(); + } + + protected void SelectNoCompletion() + { + m_SelectedCompletionIndex = -1; + m_EnteredTextCompletion = ""; + AdjustRecycledEditorSelectionToCompletion(); + } + + protected void AdjustRecycledEditorSelectionToCompletion() + { + if (m_EnteredTextCompletion != "") { + //PopupTextEditor.text = m_EnteredTextCompletion; + //PopupTextEditor.cursorIndex = m_EnteredText.Length; + //PopupTextEditor.selectIndex = m_EnteredTextCompletion.Length; //the selection goes from s_RecycledEditor.cursorIndex (already set by DoTextField) to s_RecycledEditor.selectIndex + } + } + + protected virtual void DrawList(EditorWindow editorWindow, Rect windowRect) + { + Event evt = Event.current; + + int i = -1; + foreach (var element in m_Data.GetFilteredList(m_EnteredText)) { + i++; + Rect rect = new Rect(windowRect.x, windowRect.y + k_Margin + i * k_LineHeight + (m_Gravity == Gravity.Top && m_Data.m_AllowCustom ? k_TextFieldHeight : 0), windowRect.width, k_LineHeight); + + switch (evt.type) { + case EventType.Repaint: { + GUIStyle style = element.style; + bool selected = element.selected || element.partiallySelected; + bool focused = false; + bool isHover = i == m_SelectedCompletionIndex; + bool isActive = selected; + + using (new EditorGUI.DisabledScope(!element.enabled)) { + GUIContent content = element.m_Content; + style.Draw(rect, content, isHover, isActive, selected, focused); + } + } + break; + case EventType.MouseDown: { + if (Event.current.button == 0 && rect.Contains(Event.current.mousePosition) && element.enabled) { + // Toggle state + if (m_Data.m_OnSelectCallback != null) + m_Data.m_OnSelectCallback(element); + + evt.Use(); + + // Auto close + if (m_Data.m_CloseOnSelection) + editorWindow.Close(); + } + } + break; + case EventType.MouseMove: { + if (rect.Contains(Event.current.mousePosition)) { + SelectCompletionWithIndex(i); + evt.Use(); + } + } + break; + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs.meta new file mode 100644 index 000000000..c09284797 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fccf7580322170f4096b8b99386e3a6c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs new file mode 100644 index 000000000..9b2e3a493 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs @@ -0,0 +1,75 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using UnityEditor; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace VisualPinball.Unity.Editor +{ + + [CustomPropertyDrawer(typeof(PinballLabel))] + + public class PinballLabelPropertyDrawer : PropertyDrawer + { + private GUIStyle labelStyle = null; + private GUIStyle labelButtonStyle = null; + + protected void OnSelectCallback(PopupListElement element) + { + element.selected = !element.selected; + } + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + if (labelStyle == null) { + labelStyle = GUI.skin.FindStyle("AssetLabel"); + } + + if (labelButtonStyle == null) { + labelButtonStyle = GUI.skin.FindStyle("AssetLabel Icon"); + } + + var fullLabel = property.FindPropertyRelative("_fullLabel"); + + if (fullLabel != null) { + Rect labelRect = position; + + var labelsList = new PopupLabelList.InputData() { m_AllowCustom = true, m_CloseOnSelection = false, m_EnableAutoCompletion = true, m_SortAlphabetically = true, m_OnSelectCallback = OnSelectCallback }; + labelsList.m_ListElements.Add(new PopupListElement("Manufacturers.Bally")); + labelsList.m_ListElements.Add(new PopupListElement("Manufacturers.Stern")); + labelsList.m_ListElements.Add(new PopupListElement("Manufacturers.Williams")); + labelsList.m_ListElements.Add(new PopupListElement("Manufacturers.Sega")); + labelsList.m_ListElements.Add(new PopupListElement("Decades.1980")); + labelsList.m_ListElements.Add(new PopupListElement("Decades.1990")); + labelsList.m_ListElements.Add(new PopupListElement("Decades.2000")); + labelsList.m_ListElements.Add(new PopupListElement("AFM")); + + if (string.IsNullOrEmpty(fullLabel.stringValue)) { + labelRect.width = labelButtonStyle.margin.left + labelButtonStyle.fixedWidth + labelButtonStyle.padding.right; + if (EditorGUI.DropdownButton(labelRect, GUIContent.none, FocusType.Passive, labelButtonStyle)) { + PopupWindow.Show(labelRect, new PopupLabelList(labelsList)); + } + } else { + labelRect.width = labelStyle.CalcSize(new GUIContent(fullLabel.stringValue)).x; + fullLabel.stringValue = GUI.TextField(labelRect, fullLabel.stringValue, labelStyle); + } + + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs.meta new file mode 100644 index 000000000..85e7857de --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ce8a5c9bc2b66e54a823797cfa8438cc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView.meta new file mode 100644 index 000000000..7777da17d --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6a0d4e3a7fb8ae5408f7eb1ea7d3e0b4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs new file mode 100644 index 000000000..480ba4ab3 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs @@ -0,0 +1,89 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using Unity.Mathematics; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + public enum EThumbnailSize + { + Small, + Normal, + Large + } + + public abstract class ThumbnailElement + { + /// + /// This Unique Id is automatically set & increment on each CTor so you don't need to worry about its unicity + /// + /// + /// Could be useful when constructing an array of TreeElemnt in a delegate for instance, without having to manage a local counter + /// Of course, this Id can be overridden afterward + /// + private static int UniqueId = math.abs(typeof(ThumbnailElement).GUID.ToString().GetHashCode()); + + /// + /// Unique ID of this within the structure + /// + public int Id { get; set; } + + /// + /// The element's name + /// + public abstract string Name { get; } + + /// + /// Draw the main thumbnail area for this element. + /// + /// + /// The rect provided by the calling , the draw method has to adapt to this rect. + /// + public abstract void OnGUI(Rect rect, GUIStyle style); + + /// + /// Returns the size of the hovering container for this element. + /// + /// The size of the hovering container in pixels + public abstract Vector2 GetHoverContainerSize(); + + /// + /// Draw the hovering container for this element. + /// + /// + /// The rect provided by the calling , the draw method has to adapt to this rect. + /// + /// + /// The rect width & height has been evaluated by the using . + /// + public abstract void DrawHoverContainer(Rect rect); + + public abstract Dictionary CommonSizes { get; } + + public ThumbnailElement() + { + Id = UniqueId++; + } + + public ThumbnailElement(int id) + { + Id = id; + } + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs.meta new file mode 100644 index 000000000..912da0cd8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 96e62881a731c5d48ae13205547feb11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs new file mode 100644 index 000000000..511300feb --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs @@ -0,0 +1,242 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using System.Linq; +using System; + +namespace VisualPinball.Unity.Editor +{ + /// + /// + /// + public class ThumbnailViewStyles + { + public GUIStyle DefaultStyle; + public GUIStyle SelectedStyle; + public GUIStyle NameStyle; + public GUIStyle HoverStyle; + public bool Inited => DefaultStyle != null && SelectedStyle != null && NameStyle != null && HoverStyle != null; + } + + /// + /// A thumbnail view which can be integrated in any Unity GUI layout + /// It manages on a planar view. + /// It'll use the custom draw methods to display each element in its own rect. + /// + /// a generic class + public abstract class ThumbnailView where T : ThumbnailElement + { + public struct RowCollums + { + public int Rows; + public int Collumns; + + public bool Valid => Rows > 0 && Collumns > 0; + } + + private List _data = new List(); + + private Vector2 _scroll; + + private List _selectedItems = new List(); + public List SelectedItems => _selectedItems; + public T SelectedItem => _selectedItems.Count == 1 ? _selectedItems[0] : null; + + private string _searchFilter = string.Empty; + + public bool ShowToolbar = true; + + public bool MultiSelection = false; + + protected EThumbnailSize _thumbnailSize = EThumbnailSize.Normal; + + protected ThumbnailViewStyles _commonStyles = new ThumbnailViewStyles(); + + public ThumbnailView(IEnumerable data) + { + SetData(data); + } + + public void SetData(IEnumerable data) + { + _data.Clear(); + if (data != null) { + _data.AddRange(data); + } + } + + protected abstract void InitCommonStyles(); + + protected virtual void OnGUIToolbar() { } + + protected virtual bool MatchLabelFilter(T item, string labelFilter) => false; + + + private static int FilterCompare(string f1, string f2) + { + var f1Label = f1.StartsWith("l:", StringComparison.InvariantCultureIgnoreCase); + var f2Label = f2.StartsWith("l:", StringComparison.InvariantCultureIgnoreCase); + if (f1Label != f2Label) + return f1Label ? 1 : -1; + return f1.CompareTo(f2); + } + + private List GetFilteredItems() + { + List filteredNames = new List(); + List filteredLabels = new List(); + filteredNames.AddRange(_data); + var filters = _searchFilter.Split(' ').ToList(); + filters.Sort(FilterCompare); + foreach (var filter in filters) { + if (string.IsNullOrEmpty(filter)) continue; + if (filter.StartsWith("l:", StringComparison.InvariantCultureIgnoreCase)) { + var labelFilter = filter.Split(':')[1]; + if (!string.IsNullOrEmpty(labelFilter)) { + filteredLabels = filteredLabels.Union(_data.Where(I => MatchLabelFilter(I, labelFilter))).ToList(); + } + } else { + filteredNames = filteredNames.Where(I => I.Name.Contains(filter, StringComparison.InvariantCultureIgnoreCase)).ToList(); + } + } + if (filteredLabels.Count == 0) + return filteredNames; + return filteredNames.Intersect(filteredLabels).ToList(); + } + + public void OnGUI(Rect rect) + { + InitCommonStyles(); + + EditorGUILayout.BeginVertical(); + + if (ShowToolbar) { + EditorGUILayout.BeginVertical(); + + EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.Width(rect.width)); + EditorGUILayout.LabelField("Name Filter", GUILayout.Width(100)); + _searchFilter = EditorGUILayout.TextField(_searchFilter, EditorStyles.toolbarSearchField, GUILayout.Width(rect.width-320)); + + var buttonRect = EditorGUILayout.GetControlRect(GUILayout.Width(GUI.skin.label.lineHeight)); + buttonRect.width = GUI.skin.label.lineHeight; + if ((GUI.Button(buttonRect, GUIContent.none, !string.IsNullOrEmpty(_searchFilter) ? "ToolbarSeachCancelButton" : "ToolbarSeachCancelButtonEmpty") && !string.IsNullOrEmpty(_searchFilter))){ + _searchFilter = string.Empty; + GUIUtility.keyboardControl = 0; + } + + EditorGUILayout.LabelField("Thumbnail Size", GUILayout.Width(100)); + _thumbnailSize = (EThumbnailSize)EditorGUILayout.EnumPopup(_thumbnailSize, GUILayout.Width(100)); + EditorGUILayout.EndHorizontal(); + + OnGUIToolbar(); + + EditorGUILayout.EndVertical(); + } + + var filteredItems = GetFilteredItems(); + + _selectedItems = filteredItems.Intersect(_selectedItems).ToList(); + + if (filteredItems.Count > 0) { + var buttonRect = filteredItems[0].CommonSizes[_thumbnailSize]; + var rowcol = ComputeRowCollums(rect.width - buttonRect.x * 2.0f); + + if (rowcol.Valid) { + Rect fullRect = EditorGUILayout.GetControlRect(false, ((buttonRect.y + buttonRect.height + _commonStyles.NameStyle.lineHeight) * rowcol.Rows) + buttonRect.y, GUILayout.Width(rect.width - GUI.skin.box.padding.left)); + Rect viewRect = new Rect(fullRect.x, fullRect.y, fullRect.width + 15, rect.height - fullRect.y); + + _scroll = GUI.BeginScrollView(viewRect, _scroll, fullRect, false, true); + Rect scrolledViewRect = new Rect(viewRect.position + _scroll, viewRect.size); + + for (int i = 0; i < filteredItems.Count; i++) { + var item = filteredItems[i]; + var col = i % rowcol.Collumns; + var row = i / rowcol.Collumns; + Rect itemRect = new Rect(fullRect.x + col * (buttonRect.x + buttonRect.width) + buttonRect.x, fullRect.y + row * (buttonRect.y + buttonRect.height + _commonStyles.NameStyle.lineHeight) + buttonRect.y, buttonRect.width, buttonRect.height); + + HandleEvents(item, itemRect); + + if (itemRect.Overlaps(scrolledViewRect)) { + item.OnGUI(itemRect, _selectedItems.Contains(item) ? _commonStyles.SelectedStyle : _commonStyles.DefaultStyle); + if (!string.IsNullOrEmpty(item.Name)) { + itemRect.y += itemRect.height; + itemRect.height = _commonStyles.NameStyle.lineHeight; + GUI.Label(itemRect, item.Name, _commonStyles.NameStyle); + } + } + } + + GUI.EndScrollView(); + } + } + + EditorGUILayout.EndVertical(); + } + + public void HandleEvents(T item, Rect itemRect) + { + var evt = Event.current; + + switch(evt.type) { + + case EventType.MouseDown: { + if (evt.button == 0 && itemRect.Contains(evt.mousePosition)) { + if (evt.control && MultiSelection) { + if (!_selectedItems.Contains(item)) + _selectedItems.Add(item); + else + _selectedItems.Remove(item); + } else { + _selectedItems.Clear(); + _selectedItems.Add(item); + } + evt.Use(); + } + break; + } + } + + } + + public RowCollums ComputeRowCollums(float viewWidth) + { + if (_data.Count == 0 || viewWidth <= 0.0f) + return new RowCollums() { Rows = 0, Collumns = 0 }; + + var buttonRect = _data[0].CommonSizes[_thumbnailSize]; + int nbCollumns = (int)((viewWidth - 5) / (buttonRect.width + buttonRect.x)); + if (nbCollumns == 0) + return new RowCollums() { Rows = 0, Collumns = 0 }; + int nbRows = _data.Count / nbCollumns; + if (_data.Count % nbCollumns != 0) { + nbRows++; + } + return new RowCollums() { Rows = nbRows, Collumns = nbCollumns }; + } + + public float ComputeViewHeight(float viewWidth) + { + if (_data.Count == 0) + return 0.0f; + var buttonRect = _data[0].CommonSizes[_thumbnailSize]; + var rowcol = ComputeRowCollums(viewWidth); + return (buttonRect.y + buttonRect.height) * rowcol.Rows; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs.meta new file mode 100644 index 000000000..b2485df7b --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 43cca78562f7c3e4e9ebff61e9940925 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Extensions/TextureExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Extensions/TextureExtensions.cs index b66121f94..a62568564 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Extensions/TextureExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Extensions/TextureExtensions.cs @@ -44,6 +44,13 @@ public static string GetUnityFilename(this Engine.VPT.Texture vpTex, string fold : Path.GetFileNameWithoutExtension(fileName) + ext; } + public static Texture2D CreatePixelTexture(Color color) + { + Texture2D tex = new Texture2D(1, 1); + tex.SetPixel(0, 0, color); + tex.Apply(); + return tex; + } private static Texture2D FromBinary(Engine.VPT.Texture vpTex) { From 48988049591e0dff1e3e1fc3f593acdfeff16e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Thu, 23 Dec 2021 12:22:24 +0100 Subject: [PATCH 005/119] prefablibrary : ThumbnailView variable element width support --- .../Labels/PinballLabelCategory.cs | 5 +- .../PrefabLibrary/PrefabThumbnailElement.cs | 13 ++-- .../PrefabLibrary/TagThumbnailElement.cs | 7 +- .../Utils/ThumbnailView/ThumbnailElement.cs | 25 +++++- .../Utils/ThumbnailView/ThumbnailView.cs | 77 +++++++++++-------- 5 files changed, 87 insertions(+), 40 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs index e845988ff..63786e341 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs @@ -22,6 +22,9 @@ namespace VisualPinball.Unity.Editor [Serializable] public class PinballLabelCategory { + [NonSerialized] + public static readonly Color DefaultColor = Color.blue; + [SerializeField] public string Name = string.Empty; @@ -29,6 +32,6 @@ public class PinballLabelCategory public bool MultipleSelection = true; [SerializeField] - public Color Color = Color.blue; + public Color Color = DefaultColor; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs index dd99c1de9..939ce8ab6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs @@ -25,12 +25,13 @@ public class PrefabThumbnailElement : ThumbnailElement private GameObject _prefab = null; public GameObject Prefab => _prefab; - private static Dictionary _commonSizes = new Dictionary() { - { EThumbnailSize.Small, new Rect(3, 3, 64, 64) }, - { EThumbnailSize.Normal, new Rect(3, 3, 128, 128) }, - { EThumbnailSize.Large, new Rect(3, 3, 256, 256) } + private static Dictionary _commonDimensions = new Dictionary() { + { EThumbnailSize.Small, new Dimension(){ Offset = new Vector2(3.0f, 3.0f), Height = 64 } }, + { EThumbnailSize.Normal, new Dimension(){ Offset = new Vector2(3.0f, 3.0f), Height = 128 } }, + { EThumbnailSize.Large, new Dimension(){ Offset = new Vector2(3.0f, 3.0f), Height = 196 } }, }; - public override Dictionary CommonSizes => _commonSizes; + + public override Dictionary CommonDimensions => _commonDimensions; public PrefabThumbnailElement(GameObject prefab) : base() { @@ -39,6 +40,8 @@ public PrefabThumbnailElement(GameObject prefab) : base() public override string Name => _prefab?.name; + public override float GetWidth(EThumbnailSize thumbSize, GUIStyle style) => CommonDimensions[thumbSize].Height; + public override void OnGUI(Rect rect, GUIStyle style) { var boxRect = new Rect(rect.x, rect.y, rect.width, rect.height); diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs index 8a88f422e..af44b291d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs @@ -32,8 +32,6 @@ public TagThumbnailElement(string tag) : base() public override string Name => throw new System.NotImplementedException(); - public override Dictionary CommonSizes => throw new System.NotImplementedException(); - public override void DrawHoverContainer(Rect rect) { throw new System.NotImplementedException(); @@ -44,6 +42,11 @@ public override Vector2 GetHoverContainerSize() throw new System.NotImplementedException(); } + public override float GetWidth(EThumbnailSize thumbSize, GUIStyle style) + { + throw new System.NotImplementedException(); + } + public override void OnGUI(Rect rect, GUIStyle style) { throw new System.NotImplementedException(); diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs index 480ba4ab3..ef303179d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs @@ -26,7 +26,7 @@ public enum EThumbnailSize Normal, Large } - + public abstract class ThumbnailElement { /// @@ -56,6 +56,14 @@ public abstract class ThumbnailElement /// public abstract void OnGUI(Rect rect, GUIStyle style); + /// + /// Return the element width using the provided style. + /// + /// A style used to calcule the element width + /// A thumbnail size enum to calculate the element width + /// The element width + public abstract float GetWidth(EThumbnailSize thumbSize, GUIStyle style); + /// /// Returns the size of the hovering container for this element. /// @@ -73,7 +81,20 @@ public abstract class ThumbnailElement /// public abstract void DrawHoverContainer(Rect rect); - public abstract Dictionary CommonSizes { get; } + public struct Dimension + { + public Vector2 Offset; + public float Height; + } + + private static Dictionary _commonDimensions = new Dictionary() { + { EThumbnailSize.Small, new Dimension(){ Offset = Vector2.zero, Height = 50 } }, + { EThumbnailSize.Normal, new Dimension(){ Offset = Vector2.zero, Height = 100 } }, + { EThumbnailSize.Large, new Dimension(){ Offset = Vector2.zero, Height = 150 } } + }; + + public virtual Dictionary CommonDimensions => _commonDimensions; + public ThumbnailElement() { diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs index 511300feb..f92ab1ee9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs @@ -154,32 +154,41 @@ public void OnGUI(Rect rect) _selectedItems = filteredItems.Intersect(_selectedItems).ToList(); if (filteredItems.Count > 0) { - var buttonRect = filteredItems[0].CommonSizes[_thumbnailSize]; - var rowcol = ComputeRowCollums(rect.width - buttonRect.x * 2.0f); + var dimension = filteredItems[0].CommonDimensions[_thumbnailSize]; - if (rowcol.Valid) { - Rect fullRect = EditorGUILayout.GetControlRect(false, ((buttonRect.y + buttonRect.height + _commonStyles.NameStyle.lineHeight) * rowcol.Rows) + buttonRect.y, GUILayout.Width(rect.width - GUI.skin.box.padding.left)); + var maxRow = ComputeMaxRows(filteredItems, rect.width - dimension.Offset.x * 2.0f); + if (maxRow > 0) { + Rect fullRect = EditorGUILayout.GetControlRect(false, ((dimension.Offset.y + dimension.Height + _commonStyles.NameStyle.lineHeight) * maxRow) + dimension.Offset.y, GUILayout.Width(rect.width - GUI.skin.box.padding.left)); Rect viewRect = new Rect(fullRect.x, fullRect.y, fullRect.width + 15, rect.height - fullRect.y); _scroll = GUI.BeginScrollView(viewRect, _scroll, fullRect, false, true); Rect scrolledViewRect = new Rect(viewRect.position + _scroll, viewRect.size); + int rowCount = 0; + float rowWidth = 0.0f; for (int i = 0; i < filteredItems.Count; i++) { var item = filteredItems[i]; - var col = i % rowcol.Collumns; - var row = i / rowcol.Collumns; - Rect itemRect = new Rect(fullRect.x + col * (buttonRect.x + buttonRect.width) + buttonRect.x, fullRect.y + row * (buttonRect.y + buttonRect.height + _commonStyles.NameStyle.lineHeight) + buttonRect.y, buttonRect.width, buttonRect.height); - - HandleEvents(item, itemRect); - + var style = _selectedItems.Contains(item) ? _commonStyles.SelectedStyle : _commonStyles.DefaultStyle; + var itemW = item.GetWidth(_thumbnailSize, style); + if (itemW > fullRect.width) + break; + if (rowWidth + itemW + dimension.Offset.x > fullRect.width) { + rowCount++; + rowWidth = 0.0f; + } + Rect itemRect = new Rect(fullRect.x + rowWidth + dimension.Offset.x, fullRect.y + rowCount * (dimension.Offset.y + dimension.Height + _commonStyles.NameStyle.lineHeight) + dimension.Offset.y, itemW, dimension.Height); if (itemRect.Overlaps(scrolledViewRect)) { - item.OnGUI(itemRect, _selectedItems.Contains(item) ? _commonStyles.SelectedStyle : _commonStyles.DefaultStyle); + item.OnGUI(itemRect, style); if (!string.IsNullOrEmpty(item.Name)) { - itemRect.y += itemRect.height; - itemRect.height = _commonStyles.NameStyle.lineHeight; - GUI.Label(itemRect, item.Name, _commonStyles.NameStyle); + var nameRect = new Rect(itemRect); + nameRect.y += itemRect.height; + nameRect.height = _commonStyles.NameStyle.lineHeight; + GUI.Label(nameRect, item.Name, _commonStyles.NameStyle); } } + + HandleEvents(item, itemRect); + rowWidth += itemW + dimension.Offset.x; } GUI.EndScrollView(); @@ -214,29 +223,37 @@ public void HandleEvents(T item, Rect itemRect) } - public RowCollums ComputeRowCollums(float viewWidth) + protected int ComputeMaxRows(List items, float viewWidth) { - if (_data.Count == 0 || viewWidth <= 0.0f) - return new RowCollums() { Rows = 0, Collumns = 0 }; - - var buttonRect = _data[0].CommonSizes[_thumbnailSize]; - int nbCollumns = (int)((viewWidth - 5) / (buttonRect.width + buttonRect.x)); - if (nbCollumns == 0) - return new RowCollums() { Rows = 0, Collumns = 0 }; - int nbRows = _data.Count / nbCollumns; - if (_data.Count % nbCollumns != 0) { - nbRows++; + if (items.Count == 0 || viewWidth <= 0.0f) + return 0; + + var rowWidth = 0.0f; + var rowCount = 0; + foreach (var item in items) { + var itemWidth = item.GetWidth(_thumbnailSize, _commonStyles.DefaultStyle); + if (itemWidth > viewWidth) { + return 0; + } + if (rowWidth + itemWidth > viewWidth) { + rowCount++; + rowWidth = itemWidth; + } else { + rowWidth += itemWidth; + } } - return new RowCollums() { Rows = nbRows, Collumns = nbCollumns }; + + return rowCount; } - public float ComputeViewHeight(float viewWidth) + public float ComputeViewHeight(float viewWidth, bool filteredItems = true) { if (_data.Count == 0) return 0.0f; - var buttonRect = _data[0].CommonSizes[_thumbnailSize]; - var rowcol = ComputeRowCollums(viewWidth); - return (buttonRect.y + buttonRect.height) * rowcol.Rows; + var items = filteredItems ? GetFilteredItems() : _data; + if (items.Count == 0) + return 0.0f; + return ComputeMaxRows(items, viewWidth) * items[0].CommonDimensions[_thumbnailSize].Height; } } } From 656b95cedc3255f708238bc32996a205e5450e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Thu, 23 Dec 2021 20:04:21 +0100 Subject: [PATCH 006/119] prefablibrary : new LabelsHandler - LabelsHandler is managing categories & labels from both LabelLibraryAsset and any other asset's labels - new PinballLabelList & PinballLabelCategoryList for fast unique addition (HashSet) --- .../Labels/LabelsHandler.cs | 68 ++++++++++++++++--- .../Labels/PinballLabel.cs | 7 ++ .../Labels/PinballLabelCategory.cs | 13 ++++ .../Labels/PinballLabelCategoryList.cs | 49 +++++++++++++ .../Labels/PinballLabelCategoryList.cs.meta | 11 +++ .../Labels/PinballLabelList.cs | 51 ++++++++++++++ .../Labels/PinballLabelList.cs.meta | 11 +++ .../PrefabLibrary/PrefabLibraryEditor.cs | 21 ++++-- .../Utils/PopupList/PopupList.cs | 6 +- .../PinballLabelPropertyDrawer.cs | 14 ++-- 10 files changed, 229 insertions(+), 22 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs index fc242c6be..0178d6c87 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs @@ -23,20 +23,72 @@ namespace VisualPinball.Unity.Editor { public class LabelsHandler { - private List _pinballLabels = new List(); + public enum LabelType + { + LabelLibraries, + Assets + } - public string[] Categories => _pinballLabels.Select(L => L.Category).Distinct().ToArray(); + private Dictionary _labels = new Dictionary() { + {LabelType.LabelLibraries, new PinballLabelList() }, + {LabelType.Assets, new PinballLabelList() } + }; - public LabelsHandler() { } + private Dictionary _categories = new Dictionary() { + {LabelType.LabelLibraries, new PinballLabelCategoryList() }, + {LabelType.Assets, new PinballLabelCategoryList() } + }; - public void AddLabels(IEnumerable labels) + public LabelsHandler() { - _pinballLabels.Union(labels.Select(L => new PinballLabel(L))); } - public string[] GetLabels(string category) => _pinballLabels.Where(L => string.IsNullOrEmpty(category) || L.Category.Equals(category, StringComparison.InvariantCultureIgnoreCase)) - .Select(L => L.Label).ToArray(); - + private void BuildFromLibraries() + { + ClearAssetLabels(); + var guids = AssetDatabase.FindAssets("t: LabelsLibraryAsset"); + foreach (var guid in guids) { + var asset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); + foreach (var category in asset.Categories) { + if (!string.IsNullOrEmpty(category.Name)) { + _categories[LabelType.LabelLibraries].Add(new PinballLabelCategory(category)); + } + } + foreach(var label in asset.Labels) { + if (!string.IsNullOrEmpty(label.FullLabel)) { + _labels[LabelType.LabelLibraries].Add(new PinballLabel(label.FullLabel)); + } + } + } + } + + public void Init() + { + BuildFromLibraries(); + } + + public void ClearAssetLabels() + { + _categories[LabelType.Assets].Clear(); + _labels[LabelType.Assets].Clear(); + } + + public void AddLabels(string[] labels) + { + foreach(var label in labels) { + PinballLabel pLabel = new PinballLabel(label); + if (!string.IsNullOrEmpty(pLabel.FullLabel)) { + if (!_labels[LabelType.LabelLibraries].Contains(pLabel)) { + if (_labels[LabelType.Assets].Add(pLabel) && !string.IsNullOrEmpty(pLabel.Category)) { + var category = new PinballLabelCategory() { Name = pLabel.Category }; + if (!_categories[LabelType.LabelLibraries].Contains(category)) { + _categories[LabelType.Assets].Add(category); + } + } + } + } + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs index adbd02bb1..37b9bf7ad 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs @@ -15,10 +15,12 @@ // along with this program. If not, see . using System; +using System.Diagnostics; using UnityEngine; namespace VisualPinball.Unity.Editor { + [DebuggerDisplay("Category = {Category}, Label = {Label}")] [Serializable] public class PinballLabel : ISerializationCallbackReceiver { @@ -78,5 +80,10 @@ internal static Tuple Split(string fullLabel) public void OnBeforeSerialize() {} public void OnAfterDeserialize() { Build(); } + + public new string ToString() + { + return FullLabel; + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs index 63786e341..a0ff50998 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs @@ -15,10 +15,12 @@ // along with this program. If not, see . using System; +using System.Diagnostics; using UnityEngine; namespace VisualPinball.Unity.Editor { + [DebuggerDisplay("Name = {Name}, MultipleSelection = {MultipleSelection}, Color = {Color}")] [Serializable] public class PinballLabelCategory { @@ -33,5 +35,16 @@ public class PinballLabelCategory [SerializeField] public Color Color = DefaultColor; + + public PinballLabelCategory() + { + } + + public PinballLabelCategory(PinballLabelCategory category) + { + Name = category.Name; + MultipleSelection = category.MultipleSelection; + Color = category.Color; + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs new file mode 100644 index 000000000..295ca4a5f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace VisualPinball.Unity.Editor +{ + [DebuggerTypeProxy(typeof(PinballLabelCategoryListDebugView))] + public class PinballLabelCategoryList : HashSet + { + private class CategoryComparer : IEqualityComparer + { + public bool Equals(PinballLabelCategory c1, PinballLabelCategory c2) + { + return c1.Name.Equals(c2.Name, StringComparison.InvariantCultureIgnoreCase); + } + + public int GetHashCode(PinballLabelCategory cat) + { + return cat.Name.GetHashCode(); + } + } + + public PinballLabelCategoryList() : base(new CategoryComparer()) { } + + internal class PinballLabelCategoryListDebugView + { + private PinballLabelCategoryList list; + + public PinballLabelCategoryListDebugView(PinballLabelCategoryList list) + { + if (list == null) { + throw new ArgumentNullException("list"); + } + + this.list = list; + } + + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public PinballLabelCategory[] Items + { + get { + return list.ToArray(); + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs.meta new file mode 100644 index 000000000..7e3b3633b --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7424efa5aaf0b341b886bfa93b69d61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs new file mode 100644 index 000000000..4a9c2e577 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace VisualPinball.Unity.Editor +{ + [DebuggerTypeProxy(typeof(PinballLabelListDebugView))] + public class PinballLabelList : HashSet + { + private class LabelComparer : IEqualityComparer + { + public bool Equals(PinballLabel l1, PinballLabel l2) + { + return l1.FullLabel.Equals(l2.FullLabel, StringComparison.InvariantCultureIgnoreCase); + } + + public int GetHashCode(PinballLabel label) + { + return label.FullLabel.GetHashCode(); + } + } + + public PinballLabelList() : base(new LabelComparer()) { } + + internal class PinballLabelListDebugView + { + private PinballLabelList list; + + public PinballLabelListDebugView(PinballLabelList list) + { + if (list == null) { + throw new ArgumentNullException("list"); + } + + this.list = list; + } + + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public PinballLabel[] Items + { + get { + return list.ToArray(); + } + } + } + } + + +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs.meta new file mode 100644 index 000000000..0ffb9ff48 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5cf8a6b26c31a474ba5adba74d856cbf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs index 0090cbfe7..59da2d9e1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs @@ -104,25 +104,32 @@ public class PrefabLibraryEditor : BaseEditorWindow { private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + private LabelsHandler _labelsHandler = new LabelsHandler(); + private List _folderContents = new List(); - private LabelsHandler _labelsHandler = new LabelsHandler(); + private List _filterLabels = new List(); private List _thumbs = new List(); private PrefabThumbnailView _thumbView = new PrefabThumbnailView(null) { MultiSelection = false }; private UnityEditor.Editor _previewEditor = null; + private List _prefabLabels = new List(); + [MenuItem("Visual Pinball/Prefab Library", false, 601)] public static void ShowWindow() { GetWindow().titleContent = new GUIContent("Prefabs Library"); } + public PrefabLibraryEditor() : base() + { + } + public override void OnEnable() { base.OnEnable(); - CheckPrefabSettinbgsAssets(); } @@ -141,7 +148,13 @@ private void DetailsGUI() if (_previewEditor != null) { DestroyImmediate(_previewEditor); } + _previewEditor = UnityEditor.Editor.CreateEditor(_thumbView.SelectedPrefab); + _prefabLabels.Clear(); + if (_thumbView.SelectedPrefab != null) { + var labels = AssetDatabase.GetLabels(_thumbView.SelectedPrefab); + _prefabLabels.AddRange(labels.Select(L => new PinballLabel(L)).ToList()); + } } if (_previewEditor) { @@ -206,7 +219,7 @@ public void OnGUI() private void CheckPrefabSettinbgsAssets() { - PinballMetadataCache.ClearCache(); + _labelsHandler.Init(); var guids = AssetDatabase.FindAssets("t: PrefabLibrarySettingsAsset"); foreach(var guid in guids) { @@ -219,7 +232,6 @@ private void CheckPrefabSettinbgsAssets() _folderContents.Add(newFolder); } } - //LabelHandler add tags from settings assets } _thumbView.SetData(_thumbs); @@ -230,6 +242,7 @@ private void OnFolderPopulate(PrefabLibraryFolderContent folder) { foreach (var prefab in folder.Prefabs) { _thumbs.Add(new PrefabThumbnailElement(prefab.Prefab)); + _labelsHandler.AddLabels(prefab.Labels); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs index b8f095382..4305d1ba0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs @@ -255,14 +255,14 @@ public Styles() public PopupList(InputData inputData) : this(inputData, null) { } - public PopupList(InputData inputData, string initialSelectionLabel) + public PopupList(InputData inputData, string inititalFilter) { m_Data = inputData; m_Data.ResetScores(); SelectNoCompletion(); m_Gravity = Gravity.Top; - if (initialSelectionLabel != null) { - m_EnteredTextCompletion = initialSelectionLabel; + if (inititalFilter != null) { + m_EnteredTextCompletion = inititalFilter; UpdateCompletion(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs index 9b2e3a493..2a7692f4a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs @@ -59,15 +59,15 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten labelsList.m_ListElements.Add(new PopupListElement("Decades.2000")); labelsList.m_ListElements.Add(new PopupListElement("AFM")); - if (string.IsNullOrEmpty(fullLabel.stringValue)) { - labelRect.width = labelButtonStyle.margin.left + labelButtonStyle.fixedWidth + labelButtonStyle.padding.right; - if (EditorGUI.DropdownButton(labelRect, GUIContent.none, FocusType.Passive, labelButtonStyle)) { - PopupWindow.Show(labelRect, new PopupLabelList(labelsList)); - } - } else { + //if (string.IsNullOrEmpty(fullLabel.stringValue)) { + // labelRect.width = labelButtonStyle.margin.left + labelButtonStyle.fixedWidth + labelButtonStyle.padding.right; + // if (EditorGUI.DropdownButton(labelRect, GUIContent.none, FocusType.Passive, labelButtonStyle)) { + // PopupWindow.Show(labelRect, new PopupLabelList(labelsList)); + // } + //} else { labelRect.width = labelStyle.CalcSize(new GUIContent(fullLabel.stringValue)).x; fullLabel.stringValue = GUI.TextField(labelRect, fullLabel.stringValue, labelStyle); - } + //} } } From ba4abcf988198a715b1dc730b32d5e841a80377e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Wed, 5 Jan 2022 15:58:34 +0100 Subject: [PATCH 007/119] assetlibrary : make prefab library a generic asset library with multi libraries selector --- .../AssetsLibrary.meta | 8 + .../AssetsLibrary/AssetLibraryContent.cs | 112 ++++++++ .../AssetLibraryContent.cs.meta} | 2 +- .../AssetThumbnailElement.cs} | 15 +- .../AssetThumbnailElement.cs.meta} | 2 +- .../AssetsLibrary/AssetsLibraryEditor.cs | 235 +++++++++++++++++ .../AssetsLibraryEditor.cs.meta} | 2 +- .../AssetsLibrarySettingsAsset.cs} | 18 +- .../AssetsLibrarySettingsAsset.cs.meta} | 2 +- .../AssetsThumbnailView.cs} | 18 +- .../AssetsLibrary/AssetsThumbnailView.cs.meta | 11 + .../TagThumbnailElement.cs | 0 .../TagThumbnailElement.cs.meta | 0 .../PrefabLibrary/PrefabLibraryEditor.cs | 249 ------------------ .../PrefabLibrary/PrefabLibraryEditor.uxml | 8 - .../PrefabLibraryEditor.uxml.meta | 10 - .../Utils/PopupList/PopupList.cs | 6 + .../Utils/ThumbnailView/ThumbnailView.cs | 9 +- 18 files changed, 412 insertions(+), 295 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs rename VisualPinball.Unity/VisualPinball.Unity.Editor/{PrefabLibrary/PrefabLibrarySettingsAsset.cs.meta => AssetsLibrary/AssetLibraryContent.cs.meta} (83%) rename VisualPinball.Unity/VisualPinball.Unity.Editor/{PrefabLibrary/PrefabThumbnailElement.cs => AssetsLibrary/AssetThumbnailElement.cs} (85%) rename VisualPinball.Unity/VisualPinball.Unity.Editor/{PrefabLibrary/PrefabLibraryEditor.cs.meta => AssetsLibrary/AssetThumbnailElement.cs.meta} (83%) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs rename VisualPinball.Unity/VisualPinball.Unity.Editor/{PrefabLibrary/PrefabThumbnailElement.cs.meta => AssetsLibrary/AssetsLibraryEditor.cs.meta} (83%) rename VisualPinball.Unity/VisualPinball.Unity.Editor/{PrefabLibrary/PrefabLibrarySettingsAsset.cs => AssetsLibrary/AssetsLibrarySettingsAsset.cs} (75%) rename VisualPinball.Unity/VisualPinball.Unity.Editor/{PrefabLibrary/PrefabThumbnailView.cs.meta => AssetsLibrary/AssetsLibrarySettingsAsset.cs.meta} (83%) rename VisualPinball.Unity/VisualPinball.Unity.Editor/{PrefabLibrary/PrefabThumbnailView.cs => AssetsLibrary/AssetsThumbnailView.cs} (68%) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs.meta rename VisualPinball.Unity/VisualPinball.Unity.Editor/{PrefabLibrary => AssetsLibrary}/TagThumbnailElement.cs (100%) rename VisualPinball.Unity/VisualPinball.Unity.Editor/{PrefabLibrary => AssetsLibrary}/TagThumbnailElement.cs.meta (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary.meta new file mode 100644 index 000000000..918f405f8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bfedf022744afd1468174b3c6bc8f1df +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs new file mode 100644 index 000000000..0f1517582 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs @@ -0,0 +1,112 @@ +using NLog; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using UnityEditor; +using Object = UnityEngine.Object; + +namespace VisualPinball.Unity.Editor +{ + public class AssetLibraryContent + { + public class AssetLibraryFolderContent + { + private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + + public class AssetData + { + public Object Asset; + public string[] Labels; + } + + public AssetsLibrarySettingsAsset.FolderSettings FolderSetting; + public List Assets = new List(); + private FileSystemWatcher FolderWatcher = new FileSystemWatcher(); + private string Types; + + public AssetLibraryFolderContent(AssetsLibrarySettingsAsset.FolderSettings folderSetting, List types) + { + Types = string.Join(" ", types.Select(T => $"t:{T}").ToArray()); + FolderSetting = folderSetting; + var folderPath = AssetDatabase.GUIDToAssetPath(FolderSetting.FolderReference.Guid); + if (folderPath != string.Empty) { + FolderWatcher.Path = folderPath; + FolderWatcher.NotifyFilter = NotifyFilters.Attributes + | NotifyFilters.CreationTime + | NotifyFilters.DirectoryName + | NotifyFilters.FileName + | NotifyFilters.LastAccess + | NotifyFilters.LastWrite + | NotifyFilters.Security + | NotifyFilters.Size; + FolderWatcher.Created += OnChanged; + FolderWatcher.Deleted += OnChanged; + FolderWatcher.Renamed += OnRenamed; + FolderWatcher.Changed += OnChanged; + FolderWatcher.EnableRaisingEvents = true; + } + } + + private void OnChanged(object sender, FileSystemEventArgs e) + { + + } + + private void OnRenamed(object sender, RenamedEventArgs e) + { + + } + + public void PopulateAssets() + { + Assets.Clear(); + if (string.IsNullOrEmpty(Types)) return; + var folderpath = AssetDatabase.GUIDToAssetPath(FolderSetting.FolderReference.Guid); + EditorUtility.DisplayProgressBar("Parsing Assets", folderpath, 0.0f); + var guids = AssetDatabase.FindAssets(Types, new[] { folderpath }); + int count = 0; + + foreach (var guid in guids) { + var path = AssetDatabase.GUIDToAssetPath(guid); + if (!FolderSetting.Recursive && !Path.GetDirectoryName(path).Equals(folderpath, StringComparison.InvariantCultureIgnoreCase)) { + continue; + } + var asset = AssetDatabase.LoadMainAssetAtPath(path.Replace("\\", "/")); + if (asset != null) { + //var cachedMetadata = PinballMetadataCache.LoadMetadata(guid); + var assetData = new AssetData() { Asset = asset, Labels = AssetDatabase.GetLabels(new GUID(guid)) }; + Assets.Add(assetData); + } + EditorUtility.DisplayProgressBar($"Parsing Assets {count + 1}/{guids.Length}", path, (float)count++ / guids.Length); + } + + EditorUtility.ClearProgressBar(); + } + } + + public List FolderContents { get; private set; } = new List(); + + public AssetsLibrarySettingsAsset Settings { get; private set; } + + public AssetLibraryContent(AssetsLibrarySettingsAsset settings) + { + Settings = settings; + } + + public Action FolderPopulate; + + public void PopulateAssets() + { + foreach (var folder in Settings.Folders) { + if (!FolderContents.Any(FC => FC.FolderSetting == folder)) { + var newFolder = new AssetLibraryFolderContent(folder, Settings.AssetTypes); + newFolder.PopulateAssets(); + FolderPopulate?.Invoke(newFolder); + FolderContents.Add(newFolder); + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs.meta similarity index 83% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs.meta index c798f3b0a..189a7bba0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e7ef981808f75684c9e9496d55e0971e +guid: 90a8e95592003414f8e58fd6d28b4875 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs similarity index 85% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs rename to VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs index 939ce8ab6..adf2a2b7c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs @@ -17,13 +17,14 @@ using System.Collections.Generic; using UnityEditor; using UnityEngine; +using Object = UnityEngine.Object; namespace VisualPinball.Unity.Editor { - public class PrefabThumbnailElement : ThumbnailElement + public class AssetThumbnailElement : ThumbnailElement { - private GameObject _prefab = null; - public GameObject Prefab => _prefab; + private Object _asset = null; + public Object Asset => _asset; private static Dictionary _commonDimensions = new Dictionary() { { EThumbnailSize.Small, new Dimension(){ Offset = new Vector2(3.0f, 3.0f), Height = 64 } }, @@ -33,19 +34,19 @@ public class PrefabThumbnailElement : ThumbnailElement public override Dictionary CommonDimensions => _commonDimensions; - public PrefabThumbnailElement(GameObject prefab) : base() + public AssetThumbnailElement(Object asset) : base() { - _prefab = prefab; + _asset = asset; } - public override string Name => _prefab?.name; + public override string Name => _asset?.name; public override float GetWidth(EThumbnailSize thumbSize, GUIStyle style) => CommonDimensions[thumbSize].Height; public override void OnGUI(Rect rect, GUIStyle style) { var boxRect = new Rect(rect.x, rect.y, rect.width, rect.height); - var assetPreview = AssetPreview.GetAssetPreview(_prefab); + var assetPreview = AssetPreview.GetAssetPreview(_asset); GUI.Box(boxRect, new GUIContent(), style); boxRect.x += style.border.left; boxRect.y += style.border.top; diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs.meta similarity index 83% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs.meta index 61e5a99db..ad499de2d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 991f30e39fecd70489c60bcd3f45943a +guid: ca1efbac880044b43baee4fd5e710635 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs new file mode 100644 index 000000000..9534e2876 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs @@ -0,0 +1,235 @@ +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using UnityEngine; +using UnityEditor; +using Logger = NLog.Logger; +using Object = UnityEngine.Object; +using System.Linq; +using System; + +namespace VisualPinball.Unity.Editor +{ + public class AssetsLibraryEditor : BaseEditorWindow + { + private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + + private LabelsHandler _labelsHandler = new LabelsHandler(); + + private List _assetLibraries = new List(); + private Dictionary _assetLibrariesSelection = new Dictionary(); + + private List _filterLabels = new List(); + + private List _thumbs = new List(); + private AssetsThumbnailView _thumbView = new AssetsThumbnailView(null) { MultiSelection = false }; + + private UnityEditor.Editor _previewEditor = null; + + private List _assetLabels = new List(); + + [MenuItem("Visual Pinball/Assets Library", false, 601)] + public static void ShowWindow() + { + GetWindow().titleContent = new GUIContent("Assets Library"); + } + + public AssetsLibraryEditor() : base() + { + } + + public override void OnEnable() + { + base.OnEnable(); + CheckSettinbgsAssets(); + } + + private const float DetailsWindowWidth = 400.0f; + + private bool _showDetails = true; + private bool _showLabels = true; + + private void DetailsGUI() + { + + if (_thumbView.SelectedAsset == null) { + DestroyImmediate(_previewEditor); + _previewEditor = null; + } else if (_previewEditor == null || _thumbView.SelectedAsset != _previewEditor.target) { + if (_previewEditor != null) { + DestroyImmediate(_previewEditor); + } + + _previewEditor = UnityEditor.Editor.CreateEditor(_thumbView.SelectedAsset); + _assetLabels.Clear(); + if (_thumbView.SelectedAsset != null) { + var labels = AssetDatabase.GetLabels(_thumbView.SelectedAsset); + _assetLabels.AddRange(labels.Select(L => new PinballLabel(L)).ToList()); + } + } + + if (_previewEditor) { + var previewSize = DetailsWindowWidth - GUI.skin.box.lineHeight - GUI.skin.label.padding.horizontal; + var rect = EditorGUILayout.GetControlRect(false, previewSize, GUILayout.Width(previewSize)); + EditorGUI.PrefixLabel(rect, new GUIContent("Preview")); + rect.yMin += GUI.skin.label.lineHeight + GUI.skin.label.padding.vertical; + _previewEditor.OnInteractivePreviewGUI(rect, GUI.skin.box); + + if (_showDetails = EditorGUILayout.BeginFoldoutHeaderGroup(_showDetails, new GUIContent("Details"))) { + EditorGUI.indentLevel++; + var style = EditorStyles.label; + style.wordWrap = true; + EditorGUILayout.LabelField($"Name : {_thumbView.SelectedAsset.name}", style); + var prefabType = PrefabUtility.GetPrefabAssetType(_thumbView.SelectedAsset); + if (prefabType != PrefabAssetType.NotAPrefab) { + EditorGUILayout.LabelField($"Type : Prefab ({prefabType})", style); + } else { + EditorGUILayout.LabelField($"Type : {_thumbView.SelectedAsset.GetType().Name}", style); + } + EditorGUILayout.LabelField($"Path : {AssetDatabase.GetAssetPath(_thumbView.SelectedAsset)}", style); + EditorGUILayout.Separator(); + if (_thumbView.SelectedAsset is GameObject gameObj) { + var meshRenderer = gameObj.GetComponentInChildren(); + var meshFilter = gameObj.GetComponentInChildren(); + if (meshRenderer && meshFilter) { + EditorGUILayout.LabelField($"Mesh : {meshRenderer.name}", style); + EditorGUI.indentLevel++; + if (meshFilter.sharedMesh != null) { + EditorGUILayout.LabelField($"{meshFilter.sharedMesh.subMeshCount} submesh{(meshFilter.sharedMesh.subMeshCount > 1 ? "es" : "")}", style); + EditorGUILayout.LabelField($"{meshFilter.sharedMesh.vertices.Length} vertices", style); + EditorGUILayout.LabelField($"{meshFilter.sharedMesh.triangles.Length} triangles", style); + } + if (meshRenderer.sharedMaterials != null) { + EditorGUILayout.LabelField($"{meshRenderer.sharedMaterials.Length} material{(meshRenderer.sharedMaterials.Length > 1 ? "s" : "")} : {(meshRenderer.sharedMaterials.Length > 0 ? string.Join(',', meshRenderer.sharedMaterials.Select(M => M ? M.name : "null")) : "")}", style); + } + EditorGUI.indentLevel--; + } + } + EditorGUI.indentLevel--; + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + if (_showLabels = EditorGUILayout.BeginFoldoutHeaderGroup(_showLabels, new GUIContent("Labels"))) { + EditorGUI.indentLevel++; + EditorGUILayout.LabelField(new GUIContent("Labels")); + EditorGUI.indentLevel--; + } + EditorGUILayout.EndFoldoutHeaderGroup(); + + } else { + EditorGUILayout.LabelField(new GUIContent("Select an asset")); + } + } + + public void OnGUI() + { + EditorGUILayout.BeginHorizontal(); + + var thumbRect = new Rect(position); + thumbRect.y += GUI.skin.button.lineHeight; + thumbRect.width -= DetailsWindowWidth; + thumbRect.height -= GUI.skin.button.lineHeight; + + EditorGUILayout.BeginVertical(GUILayout.Width(thumbRect.width)); + //Library selector + if (EditorGUILayout.DropdownButton(new GUIContent("Libraries"), FocusType.Passive, GUILayout.Width(150))) { + DoLibrariesPopup(); + } + + _thumbView.OnGUI(thumbRect); + + EditorGUILayout.EndVertical(); + + EditorGUILayout.BeginVertical(); + DetailsGUI(); + EditorGUILayout.EndVertical(); + + EditorGUILayout.EndHorizontal(); + } + + private void DoLibrariesPopup() + { + var inputdata = new GenericPopupList.InputData() { + m_AllowCustom = false, + m_CloseOnSelection = false, + m_EnableAutoCompletion = false, + m_SortAlphabetically = true, + m_OnSelectCallback = OnLibrarySelection + }; + + inputdata.m_ListElements.AddRange(_assetLibrariesSelection.Select(L => new PopupListElement(L.Key.Settings.Name, L.Value))); + + var popupList = new GenericPopupList(inputdata); + Rect r = GUILayoutUtility.GetRect(GUI.skin.button.fixedWidth, GUI.skin.button.fixedWidth, GUI.skin.button.fixedHeight + 5.0f, GUI.skin.button.fixedHeight + 5.0f); + PopupWindow.Show(r, popupList); + } + + private void OnLibrarySelection(PopupListElement element) + { + element.selected = !element.selected; + _assetLibrariesSelection[_assetLibrariesSelection.FirstOrDefault(L => L.Key.Settings.Name.Equals(element.m_Content.text, StringComparison.InvariantCultureIgnoreCase)).Key] = element.selected; + CreateThumbnailElements(); + } + + private void CheckSettinbgsAssets() + { + _labelsHandler.Init(); + + var guids = AssetDatabase.FindAssets("t:AssetsLibrarySettingsAsset"); + foreach(var guid in guids) { + var asset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); + if (!_assetLibraries.Any(L=>L.Settings == asset)) { + var library = new AssetLibraryContent(asset); + library.FolderPopulate += OnFolderPopulate; + library.PopulateAssets(); + _assetLibraries.Add(library); + _assetLibrariesSelection.Add(library, true); + } + } + + CreateThumbnailElements(); + } + + private void OnFolderPopulate(AssetLibraryContent.AssetLibraryFolderContent folder) + { + foreach(var asset in folder.Assets) { + _labelsHandler.AddLabels(asset.Labels); + } + } + + private void CreateThumbnailElements() + { + _thumbView.SetData(null); + _thumbs.Clear(); + foreach(var tuple in _assetLibrariesSelection) { + if (tuple.Value) { + foreach(var folder in tuple.Key.FolderContents) { + foreach(var asset in folder.Assets) { + if (!_thumbs.Any(T=>T.Asset == asset.Asset)) { + _thumbs.Add(new AssetThumbnailElement(asset.Asset)); + } + } + } + } + } + _thumbView.SetData(_thumbs); + AssetPreview.SetPreviewTextureCacheSize(_thumbs.Count + 1); + Repaint(); + } + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs.meta similarity index 83% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs.meta index a87c2b5b7..2ed32a7ff 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailElement.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 51f12c64012021045a8d04de0d025c61 +guid: b3bb02c5404de27448670326029c2d16 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs similarity index 75% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs rename to VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs index e0b74db1e..52b6cf7f4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibrarySettingsAsset.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs @@ -24,28 +24,30 @@ namespace VisualPinball.Unity.Editor { /// /// An asset containing somme prefab library settings. - /// Prefabs are populated to the using these settings. + /// Prefabs are populated to the using these settings. /// /// /// You can have several PrefabLibrarySettingsAssets, the editor will find all of them into the AssetDatabase. /// - [CreateAssetMenu(fileName = "Prefab Library Settings", menuName = "Visual Pinball/Prefab Library Settings", order = 101)] - public class PrefabLibrarySettingsAsset : ScriptableObject + [CreateAssetMenu(fileName = "Assets Library Settings", menuName = "Visual Pinball/Assets Library Settings", order = 101)] + public class AssetsLibrarySettingsAsset : ScriptableObject { - public string Name = "Prefab Library"; - [Serializable] public class FolderSettings { public ProjectFolderReference FolderReference = new ProjectFolderReference(); - [Tooltip("Prefabs will be searched recursively into this path.")] + + [Tooltip("Assets will be searched recursively into this path.")] public bool Recursive = true; } + public string Name = "Assets Library"; + public bool Locked = false; - public List Folders = new List(); + [Tooltip("List of the asset's types to search for.")] + public List AssetTypes = new List(); - private Dictionary> AssetTags = new Dictionary>(); + public List Folders = new List(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs.meta similarity index 83% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs.meta index 0a330acaf..cb0972e33 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 01f965648d0ef164d981e944d1603dc8 +guid: 95fe9de512f100f40afcdbdb9d42353b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs similarity index 68% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs rename to VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs index 9ef41a4b8..acb045718 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs @@ -4,14 +4,15 @@ using System.Text; using UnityEditor; using UnityEngine; +using Object = UnityEngine.Object; namespace VisualPinball.Unity.Editor { - public class PrefabThumbnailView : ThumbnailView + public class AssetsThumbnailView : ThumbnailView { - public GameObject SelectedPrefab => SelectedItem?.Prefab; + public Object SelectedAsset => SelectedItem?.Asset; - public PrefabThumbnailView(IEnumerable data) : base(data) { } + public AssetsThumbnailView(IEnumerable data) : base(data) { } protected override void InitCommonStyles() { @@ -28,13 +29,18 @@ protected override void InitCommonStyles() } } - protected override void OnGUIToolbar() + protected override void OnGUIToolbarBegin() + { + + } + + protected override void OnGUIToolbarEnd() { } - protected override bool MatchLabelFilter(PrefabThumbnailElement item, string labelFilter) + protected override bool MatchLabelFilter(AssetThumbnailElement item, string labelFilter) { - var labels = AssetDatabase.GetLabels(item.Prefab); + var labels = AssetDatabase.GetLabels(item.Asset); return labels.Any(L => L.Contains(labelFilter, StringComparison.InvariantCultureIgnoreCase)); } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs.meta new file mode 100644 index 000000000..21ce421fa --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 86a2a8714347a7c46b842d4c107c7af1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs rename to VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/TagThumbnailElement.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs deleted file mode 100644 index 59da2d9e1..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.cs +++ /dev/null @@ -1,249 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2021 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using Logger = NLog.Logger; -using System.Linq; -using System.IO; - -namespace VisualPinball.Unity.Editor -{ - internal class PrefabLibraryFolderContent - { - private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); - - public class PrefabData - { - public GameObject Prefab; - public string[] Labels; - } - - public PrefabLibrarySettingsAsset.FolderSettings FolderSetting; - public List Prefabs = new List(); - private FileSystemWatcher FolderWatcher = new FileSystemWatcher(); - - public Action Populate; - - public PrefabLibraryFolderContent(PrefabLibrarySettingsAsset.FolderSettings folderSetting) - { - FolderSetting = folderSetting; - var folderPath = AssetDatabase.GUIDToAssetPath(FolderSetting.FolderReference.Guid); - if (folderPath != string.Empty) { - FolderWatcher.Path = folderPath; - FolderWatcher.NotifyFilter = NotifyFilters.Attributes - | NotifyFilters.CreationTime - | NotifyFilters.DirectoryName - | NotifyFilters.FileName - | NotifyFilters.LastAccess - | NotifyFilters.LastWrite - | NotifyFilters.Security - | NotifyFilters.Size; - FolderWatcher.Created += OnChanged; - FolderWatcher.Deleted += OnChanged; - FolderWatcher.Renamed += OnRenamed; - FolderWatcher.Changed += OnChanged; - FolderWatcher.EnableRaisingEvents = true; - } - } - - private void OnChanged(object sender, FileSystemEventArgs e) - { - - } - - private void OnRenamed(object sender, RenamedEventArgs e) - { - - } - - public void PopulatePrefabs() - { - Prefabs.Clear(); - var folderpath = AssetDatabase.GUIDToAssetPath(FolderSetting.FolderReference.Guid); - EditorUtility.DisplayProgressBar("Parsing Prefabs", folderpath, 0.0f); - var guids = AssetDatabase.FindAssets("t: Prefab", new[] { folderpath }); - int count = 0; - - foreach (var guid in guids) { - var path = AssetDatabase.GUIDToAssetPath(guid); - if (!FolderSetting.Recursive && !Path.GetDirectoryName(path).Equals(folderpath, StringComparison.InvariantCultureIgnoreCase)) { - continue; - } - var asset = AssetDatabase.LoadMainAssetAtPath(path.Replace("\\", "/")) as GameObject; - if (asset != null) { - var cachedMetadata = PinballMetadataCache.LoadMetadata(guid); - var prefabData = new PrefabData() { Prefab = asset, Labels = AssetDatabase.GetLabels(new GUID(guid)) }; - Prefabs.Add(prefabData); - } - EditorUtility.DisplayProgressBar($"Parsing Prefabs {count+1}/{guids.Length}", path, (float)count++/guids.Length); - } - - EditorUtility.ClearProgressBar(); - - Populate?.Invoke(this); - } - } - - public class PrefabLibraryEditor : BaseEditorWindow - { - private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); - - private LabelsHandler _labelsHandler = new LabelsHandler(); - - private List _folderContents = new List(); - - private List _filterLabels = new List(); - - private List _thumbs = new List(); - private PrefabThumbnailView _thumbView = new PrefabThumbnailView(null) { MultiSelection = false }; - - private UnityEditor.Editor _previewEditor = null; - - private List _prefabLabels = new List(); - - [MenuItem("Visual Pinball/Prefab Library", false, 601)] - public static void ShowWindow() - { - GetWindow().titleContent = new GUIContent("Prefabs Library"); - } - - public PrefabLibraryEditor() : base() - { - } - - public override void OnEnable() - { - base.OnEnable(); - CheckPrefabSettinbgsAssets(); - } - - private const float DetailsWindowWidth = 400.0f; - - private bool _showDetails = true; - private bool _showLabels = true; - - private void DetailsGUI() - { - - if (_thumbView.SelectedPrefab == null) { - DestroyImmediate(_previewEditor); - _previewEditor = null; - } else if (_previewEditor == null || _thumbView.SelectedPrefab != _previewEditor.target) { - if (_previewEditor != null) { - DestroyImmediate(_previewEditor); - } - - _previewEditor = UnityEditor.Editor.CreateEditor(_thumbView.SelectedPrefab); - _prefabLabels.Clear(); - if (_thumbView.SelectedPrefab != null) { - var labels = AssetDatabase.GetLabels(_thumbView.SelectedPrefab); - _prefabLabels.AddRange(labels.Select(L => new PinballLabel(L)).ToList()); - } - } - - if (_previewEditor) { - var previewSize = DetailsWindowWidth - GUI.skin.box.lineHeight - GUI.skin.label.padding.horizontal; - var rect = EditorGUILayout.GetControlRect(false, previewSize, GUILayout.Width(previewSize)); - EditorGUI.PrefixLabel(rect, new GUIContent("Preview")); - rect.yMin += GUI.skin.label.lineHeight + GUI.skin.label.padding.vertical; - _previewEditor.OnInteractivePreviewGUI(rect, GUI.skin.box); - - if (_showDetails = EditorGUILayout.BeginFoldoutHeaderGroup(_showDetails, new GUIContent("Details"))) { - EditorGUI.indentLevel++; - var style = EditorStyles.label; - style.wordWrap = true; - EditorGUILayout.LabelField($"Name : {_thumbView.SelectedPrefab.name}", style); - EditorGUILayout.LabelField($"Path : {AssetDatabase.GetAssetPath(_thumbView.SelectedPrefab)}", style); - EditorGUILayout.Separator(); - var meshRenderer = _thumbView.SelectedPrefab.GetComponentInChildren(); - var meshFilter = _thumbView.SelectedPrefab.GetComponentInChildren(); - if (meshRenderer && meshFilter){ - EditorGUILayout.LabelField($"Mesh : {meshRenderer.name}", style); - EditorGUI.indentLevel++; - if (meshFilter.sharedMesh != null) { - EditorGUILayout.LabelField($"{meshFilter.sharedMesh.subMeshCount} submesh{(meshFilter.sharedMesh.subMeshCount>1?"es":"")}", style); - EditorGUILayout.LabelField($"{meshFilter.sharedMesh.vertices.Length} vertices", style); - EditorGUILayout.LabelField($"{meshFilter.sharedMesh.triangles.Length} triangles", style); - } - if (meshRenderer.sharedMaterials != null) { - EditorGUILayout.LabelField($"{meshRenderer.sharedMaterials.Length} material{(meshRenderer.sharedMaterials.Length>1?"s":"")} : {(meshRenderer.sharedMaterials.Length > 0 ? string.Join(',', meshRenderer.sharedMaterials.Select(M => M ? M.name : "null")) : "")}", style); - } - EditorGUI.indentLevel--; - } - EditorGUI.indentLevel--; - } - EditorGUILayout.EndFoldoutHeaderGroup(); - - if (_showLabels = EditorGUILayout.BeginFoldoutHeaderGroup(_showLabels, new GUIContent("Labels"))) { - EditorGUI.indentLevel++; - EditorGUILayout.LabelField(new GUIContent("Labels")); - EditorGUI.indentLevel--; - } - EditorGUILayout.EndFoldoutHeaderGroup(); - - } else { - EditorGUILayout.LabelField(new GUIContent("Select a prefab")); - } - } - - public void OnGUI() - { - EditorGUILayout.BeginHorizontal(); - - var thumbRect = new Rect(position); - thumbRect.width -= DetailsWindowWidth; - _thumbView.OnGUI(thumbRect); - - EditorGUILayout.BeginVertical(); - DetailsGUI(); - EditorGUILayout.EndVertical(); - - EditorGUILayout.EndHorizontal(); - } - - private void CheckPrefabSettinbgsAssets() - { - _labelsHandler.Init(); - - var guids = AssetDatabase.FindAssets("t: PrefabLibrarySettingsAsset"); - foreach(var guid in guids) { - var asset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); - foreach (var folder in asset.Folders) { - if (!_folderContents.Any(FC=>FC.FolderSetting == folder)) { - var newFolder = new PrefabLibraryFolderContent(folder); - newFolder.Populate += OnFolderPopulate; - newFolder.PopulatePrefabs(); - _folderContents.Add(newFolder); - } - } - } - - _thumbView.SetData(_thumbs); - AssetPreview.SetPreviewTextureCacheSize(_thumbs.Count + 10); - } - - private void OnFolderPopulate(PrefabLibraryFolderContent folder) - { - foreach (var prefab in folder.Prefabs) { - _thumbs.Add(new PrefabThumbnailElement(prefab.Prefab)); - _labelsHandler.AddLabels(prefab.Labels); - } - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml deleted file mode 100644 index fd59ac09f..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml.meta deleted file mode 100644 index df0be682e..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PrefabLibrary/PrefabLibraryEditor.uxml.meta +++ /dev/null @@ -1,10 +0,0 @@ -fileFormatVersion: 2 -guid: 7804dd53ff4b519498831fb1664556a8 -ScriptedImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 2 - userData: - assetBundleName: - assetBundleVariant: - script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs index 4305d1ba0..90f84b219 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs @@ -515,4 +515,10 @@ protected virtual void DrawList(EditorWindow editorWindow, Rect windowRect) } } } + + public class GenericPopupList : PopupList + { + public GenericPopupList(InputData inputData) : base(inputData) { } + public GenericPopupList(InputData inputData, string inititalFilter) : base(inputData, inititalFilter) { } + } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs index f92ab1ee9..dbdf691dd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs @@ -83,7 +83,8 @@ public void SetData(IEnumerable data) protected abstract void InitCommonStyles(); - protected virtual void OnGUIToolbar() { } + protected virtual void OnGUIToolbarBegin() { } + protected virtual void OnGUIToolbarEnd() { } protected virtual bool MatchLabelFilter(T item, string labelFilter) => false; @@ -129,6 +130,8 @@ public void OnGUI(Rect rect) if (ShowToolbar) { EditorGUILayout.BeginVertical(); + OnGUIToolbarBegin(); + EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.Width(rect.width)); EditorGUILayout.LabelField("Name Filter", GUILayout.Width(100)); _searchFilter = EditorGUILayout.TextField(_searchFilter, EditorStyles.toolbarSearchField, GUILayout.Width(rect.width-320)); @@ -144,7 +147,7 @@ public void OnGUI(Rect rect) _thumbnailSize = (EThumbnailSize)EditorGUILayout.EnumPopup(_thumbnailSize, GUILayout.Width(100)); EditorGUILayout.EndHorizontal(); - OnGUIToolbar(); + OnGUIToolbarEnd(); EditorGUILayout.EndVertical(); } @@ -229,7 +232,7 @@ protected int ComputeMaxRows(List items, float viewWidth) return 0; var rowWidth = 0.0f; - var rowCount = 0; + var rowCount = 1; foreach (var item in items) { var itemWidth = item.GetWidth(_thumbnailSize, _commonStyles.DefaultStyle); if (itemWidth > viewWidth) { From 39e1379987a93d8ffff6d603ad230406768089ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Wed, 5 Jan 2022 19:57:16 +0100 Subject: [PATCH 008/119] assetlibrary : support for asset types in search filter --- .../AssetsLibrary/AssetsThumbnailView.cs | 5 ++++ .../Utils/ThumbnailView/ThumbnailView.cs | 26 ++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs index acb045718..21e35e097 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs @@ -44,5 +44,10 @@ protected override bool MatchLabelFilter(AssetThumbnailElement item, string labe return labels.Any(L => L.Contains(labelFilter, StringComparison.InvariantCultureIgnoreCase)); } + protected override bool MatchTypeFilter(AssetThumbnailElement item, string typeFilter) + { + return (item.Asset.GetType().Name.Equals(typeFilter, StringComparison.InvariantCultureIgnoreCase)); + } + } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs index dbdf691dd..ddf52ed50 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs @@ -87,14 +87,15 @@ protected virtual void OnGUIToolbarBegin() { } protected virtual void OnGUIToolbarEnd() { } protected virtual bool MatchLabelFilter(T item, string labelFilter) => false; + protected virtual bool MatchTypeFilter(T item, string typeFilter) => false; private static int FilterCompare(string f1, string f2) { - var f1Label = f1.StartsWith("l:", StringComparison.InvariantCultureIgnoreCase); - var f2Label = f2.StartsWith("l:", StringComparison.InvariantCultureIgnoreCase); - if (f1Label != f2Label) - return f1Label ? 1 : -1; + var f1filter = f1.StartsWith("l:", StringComparison.InvariantCultureIgnoreCase) || f1.StartsWith("t:", StringComparison.InvariantCultureIgnoreCase); + var f2filter = f2.StartsWith("l:", StringComparison.InvariantCultureIgnoreCase) || f2.StartsWith("t:", StringComparison.InvariantCultureIgnoreCase); + if (f1filter != f2filter) + return f1filter ? 1 : -1; return f1.CompareTo(f2); } @@ -102,23 +103,34 @@ private List GetFilteredItems() { List filteredNames = new List(); List filteredLabels = new List(); + List filteredTypes = new List(); filteredNames.AddRange(_data); var filters = _searchFilter.Split(' ').ToList(); filters.Sort(FilterCompare); + int labelCnt = 0, typeCnt = 0; foreach (var filter in filters) { if (string.IsNullOrEmpty(filter)) continue; if (filter.StartsWith("l:", StringComparison.InvariantCultureIgnoreCase)) { var labelFilter = filter.Split(':')[1]; if (!string.IsNullOrEmpty(labelFilter)) { + labelCnt++; filteredLabels = filteredLabels.Union(_data.Where(I => MatchLabelFilter(I, labelFilter))).ToList(); } + }else if (filter.StartsWith("t:", StringComparison.InvariantCultureIgnoreCase)) { + var typeFilter = filter.Split(':')[1]; + if (!string.IsNullOrEmpty(typeFilter)) { + typeCnt++; + filteredTypes = filteredTypes.Union(_data.Where(I => MatchTypeFilter(I, typeFilter))).ToList(); + } } else { filteredNames = filteredNames.Where(I => I.Name.Contains(filter, StringComparison.InvariantCultureIgnoreCase)).ToList(); } } - if (filteredLabels.Count == 0) - return filteredNames; - return filteredNames.Intersect(filteredLabels).ToList(); + if (labelCnt > 0) + filteredNames = filteredNames.Intersect(filteredLabels).ToList(); + if (typeCnt > 0) + filteredNames = filteredNames.Intersect(filteredTypes).ToList(); + return filteredNames; } public void OnGUI(Rect rect) From 601637d631767327467be58f9c794651c0f5d630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Fri, 7 Jan 2022 09:51:12 +0100 Subject: [PATCH 009/119] assetlibrary : display labels in details view - upgrade ThumbView & Element (Selectable element, remove name display) - clean LabelPropertyDrawer comments - create LabelsThumbnailView & Element --- .../AssetsLibrary/AssetsLibraryEditor.cs | 10 +++++- .../LabelThumbnailElement.cs} | 29 ++++++++-------- .../LabelThumbnailElement.cs.meta} | 2 +- .../Labels/LabelsThumbnailView.cs | 33 +++++++++++++++++++ .../Labels/LabelsThumbnailView.cs.meta | 11 +++++++ .../PinballLabelPropertyDrawer.cs | 22 ++----------- .../Utils/ThumbnailView/ThumbnailElement.cs | 5 +++ .../Utils/ThumbnailView/ThumbnailView.cs | 29 +++++++++------- 8 files changed, 95 insertions(+), 46 deletions(-) rename VisualPinball.Unity/VisualPinball.Unity.Editor/{AssetsLibrary/TagThumbnailElement.cs => Labels/LabelThumbnailElement.cs} (51%) rename VisualPinball.Unity/VisualPinball.Unity.Editor/{AssetsLibrary/TagThumbnailElement.cs.meta => Labels/LabelThumbnailElement.cs.meta} (83%) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs index 9534e2876..51596108b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs @@ -38,6 +38,8 @@ public class AssetsLibraryEditor : BaseEditorWindow private List _thumbs = new List(); private AssetsThumbnailView _thumbView = new AssetsThumbnailView(null) { MultiSelection = false }; + private LabelsThumbnailView _labelsView = new LabelsThumbnailView(null) { ShowToolbar = false, DisplayNames = false, MultiSelection = false }; + private UnityEditor.Editor _previewEditor = null; private List _assetLabels = new List(); @@ -80,6 +82,8 @@ private void DetailsGUI() var labels = AssetDatabase.GetLabels(_thumbView.SelectedAsset); _assetLabels.AddRange(labels.Select(L => new PinballLabel(L)).ToList()); } + + _labelsView.SetData(_assetLabels.Select(L=>new LabelThumbnailElement(L) { Selectable = false })); } if (_previewEditor) { @@ -125,7 +129,11 @@ private void DetailsGUI() if (_showLabels = EditorGUILayout.BeginFoldoutHeaderGroup(_showLabels, new GUIContent("Labels"))) { EditorGUI.indentLevel++; - EditorGUILayout.LabelField(new GUIContent("Labels")); + + Rect r = new Rect(position); + r.width = DetailsWindowWidth; + _labelsView.OnGUI(r); + EditorGUI.indentLevel--; } EditorGUILayout.EndFoldoutHeaderGroup(); diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs similarity index 51% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs rename to VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs index af44b291d..ed46ca97b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs @@ -20,36 +20,39 @@ namespace VisualPinball.Unity.Editor { - public class TagThumbnailElement : ThumbnailElement + public class LabelThumbnailElement : ThumbnailElement { - private string _tag = string.Empty; - private string _category = string.Empty; + private PinballLabel _label = null; - public TagThumbnailElement(string tag) : base() + private static Dictionary _commonDimensions = new Dictionary() { + { EThumbnailSize.Small, new Dimension(){ Offset = new Vector2(3.0f, 3.0f), Height = GUI.skin.label.lineHeight * 0.75f } }, + { EThumbnailSize.Normal, new Dimension(){ Offset = new Vector2(3.0f, 3.0f), Height = GUI.skin.label.lineHeight } }, + { EThumbnailSize.Large, new Dimension(){ Offset = new Vector2(3.0f, 3.0f), Height = GUI.skin.label.lineHeight * 1.5f } }, + }; + + public override Dictionary CommonDimensions => _commonDimensions; + + public LabelThumbnailElement(PinballLabel label) : base() { - _tag = tag; + _label = label; } - public override string Name => throw new System.NotImplementedException(); + public override string Name => string.Empty; public override void DrawHoverContainer(Rect rect) { - throw new System.NotImplementedException(); } - public override Vector2 GetHoverContainerSize() - { - throw new System.NotImplementedException(); - } + public override Vector2 GetHoverContainerSize() => Vector2.zero; public override float GetWidth(EThumbnailSize thumbSize, GUIStyle style) { - throw new System.NotImplementedException(); + return style.CalcSize(new GUIContent(_label.FullLabel)).x + style.padding.horizontal; } public override void OnGUI(Rect rect, GUIStyle style) { - throw new System.NotImplementedException(); + GUI.Label(rect, _label.FullLabel, style); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs.meta similarity index 83% rename from VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs.meta index 7ceb0da18..178ffd1c8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/TagThumbnailElement.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d96844e6f902b7e4e8b618ddda7638bb +guid: 9c670305acbf84b4a9fdd058882220e5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs new file mode 100644 index 000000000..80aa321b9 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + public class LabelsThumbnailView : ThumbnailView + { + GUIStyle _labelButtonStyle = null; + + public LabelsThumbnailView(IEnumerable data) : base(data) + { + ShowToolbar = false; + } + + protected override void InitCommonStyles() + { + if (!_commonStyles.Inited) { + _commonStyles.DefaultStyle = new GUIStyle(GUI.skin.FindStyle("AssetLabel")); + _commonStyles.SelectedStyle = new GUIStyle(_commonStyles.DefaultStyle); + _commonStyles.SelectedStyle.active.textColor = Color.white; + _commonStyles.SelectedStyle.normal = _commonStyles.SelectedStyle.active; + _commonStyles.SelectedStyle.hover = _commonStyles.SelectedStyle.active; + _commonStyles.SelectedStyle.focused = _commonStyles.SelectedStyle.active; + _commonStyles.NameStyle = new GUIStyle("label"); + _commonStyles.HoverStyle = new GUIStyle(); + _commonStyles.HoverStyle.normal.background = TextureExtensions.CreatePixelTexture(new Color(.25f, .25f, .25f)); + } + } + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs.meta new file mode 100644 index 000000000..4b5ca0183 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85b7a442f85ea83418d090cb99d59c8e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs index 2a7692f4a..c9c91930e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PropertyDrawers/PinballLabelPropertyDrawer.cs @@ -49,26 +49,8 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten if (fullLabel != null) { Rect labelRect = position; - var labelsList = new PopupLabelList.InputData() { m_AllowCustom = true, m_CloseOnSelection = false, m_EnableAutoCompletion = true, m_SortAlphabetically = true, m_OnSelectCallback = OnSelectCallback }; - labelsList.m_ListElements.Add(new PopupListElement("Manufacturers.Bally")); - labelsList.m_ListElements.Add(new PopupListElement("Manufacturers.Stern")); - labelsList.m_ListElements.Add(new PopupListElement("Manufacturers.Williams")); - labelsList.m_ListElements.Add(new PopupListElement("Manufacturers.Sega")); - labelsList.m_ListElements.Add(new PopupListElement("Decades.1980")); - labelsList.m_ListElements.Add(new PopupListElement("Decades.1990")); - labelsList.m_ListElements.Add(new PopupListElement("Decades.2000")); - labelsList.m_ListElements.Add(new PopupListElement("AFM")); - - //if (string.IsNullOrEmpty(fullLabel.stringValue)) { - // labelRect.width = labelButtonStyle.margin.left + labelButtonStyle.fixedWidth + labelButtonStyle.padding.right; - // if (EditorGUI.DropdownButton(labelRect, GUIContent.none, FocusType.Passive, labelButtonStyle)) { - // PopupWindow.Show(labelRect, new PopupLabelList(labelsList)); - // } - //} else { - labelRect.width = labelStyle.CalcSize(new GUIContent(fullLabel.stringValue)).x; - fullLabel.stringValue = GUI.TextField(labelRect, fullLabel.stringValue, labelStyle); - //} - + labelRect.width = labelStyle.CalcSize(new GUIContent(fullLabel.stringValue)).x; + fullLabel.stringValue = GUI.TextField(labelRect, fullLabel.stringValue, labelStyle); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs index ef303179d..bc1a58e7d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs @@ -48,6 +48,11 @@ public abstract class ThumbnailElement /// public abstract string Name { get; } + /// + /// Is the element selectable + /// + public bool Selectable { get; set; } = true; + /// /// Draw the main thumbnail area for this element. /// diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs index ddf52ed50..cd38f4d6c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs @@ -42,6 +42,12 @@ public class ThumbnailViewStyles /// a generic class public abstract class ThumbnailView where T : ThumbnailElement { + public bool ShowToolbar = true; + + public bool DisplayNames = true; + + public bool MultiSelection = false; + public struct RowCollums { public int Rows; @@ -60,10 +66,6 @@ public struct RowCollums private string _searchFilter = string.Empty; - public bool ShowToolbar = true; - - public bool MultiSelection = false; - protected EThumbnailSize _thumbnailSize = EThumbnailSize.Normal; protected ThumbnailViewStyles _commonStyles = new ThumbnailViewStyles(); @@ -99,6 +101,8 @@ private static int FilterCompare(string f1, string f2) return f1.CompareTo(f2); } + private float NameLineHeight => DisplayNames ? _commonStyles.NameStyle.lineHeight : 0.0f; + private List GetFilteredItems() { List filteredNames = new List(); @@ -137,7 +141,7 @@ public void OnGUI(Rect rect) { InitCommonStyles(); - EditorGUILayout.BeginVertical(); + EditorGUILayout.BeginVertical(GUILayout.Width(rect.width),GUILayout.Height(rect.height)); if (ShowToolbar) { EditorGUILayout.BeginVertical(); @@ -173,7 +177,7 @@ public void OnGUI(Rect rect) var maxRow = ComputeMaxRows(filteredItems, rect.width - dimension.Offset.x * 2.0f); if (maxRow > 0) { - Rect fullRect = EditorGUILayout.GetControlRect(false, ((dimension.Offset.y + dimension.Height + _commonStyles.NameStyle.lineHeight) * maxRow) + dimension.Offset.y, GUILayout.Width(rect.width - GUI.skin.box.padding.left)); + Rect fullRect = EditorGUILayout.GetControlRect(false, ((dimension.Offset.y + dimension.Height + NameLineHeight) * maxRow) + dimension.Offset.y, GUILayout.Width(rect.width - GUI.skin.box.padding.left)); Rect viewRect = new Rect(fullRect.x, fullRect.y, fullRect.width + 15, rect.height - fullRect.y); _scroll = GUI.BeginScrollView(viewRect, _scroll, fullRect, false, true); @@ -191,13 +195,13 @@ public void OnGUI(Rect rect) rowCount++; rowWidth = 0.0f; } - Rect itemRect = new Rect(fullRect.x + rowWidth + dimension.Offset.x, fullRect.y + rowCount * (dimension.Offset.y + dimension.Height + _commonStyles.NameStyle.lineHeight) + dimension.Offset.y, itemW, dimension.Height); + Rect itemRect = new Rect(fullRect.x + rowWidth + dimension.Offset.x, fullRect.y + rowCount * (dimension.Offset.y + dimension.Height + NameLineHeight) + dimension.Offset.y, itemW, dimension.Height); if (itemRect.Overlaps(scrolledViewRect)) { item.OnGUI(itemRect, style); - if (!string.IsNullOrEmpty(item.Name)) { + if (!string.IsNullOrEmpty(item.Name) && DisplayNames) { var nameRect = new Rect(itemRect); nameRect.y += itemRect.height; - nameRect.height = _commonStyles.NameStyle.lineHeight; + nameRect.height = NameLineHeight; GUI.Label(nameRect, item.Name, _commonStyles.NameStyle); } } @@ -220,7 +224,7 @@ public void HandleEvents(T item, Rect itemRect) switch(evt.type) { case EventType.MouseDown: { - if (evt.button == 0 && itemRect.Contains(evt.mousePosition)) { + if (evt.button == 0 && item.Selectable && itemRect.Contains(evt.mousePosition)) { if (evt.control && MultiSelection) { if (!_selectedItems.Contains(item)) _selectedItems.Add(item); @@ -240,6 +244,8 @@ public void HandleEvents(T item, Rect itemRect) protected int ComputeMaxRows(List items, float viewWidth) { + InitCommonStyles(); + if (items.Count == 0 || viewWidth <= 0.0f) return 0; @@ -268,7 +274,8 @@ public float ComputeViewHeight(float viewWidth, bool filteredItems = true) var items = filteredItems ? GetFilteredItems() : _data; if (items.Count == 0) return 0.0f; - return ComputeMaxRows(items, viewWidth) * items[0].CommonDimensions[_thumbnailSize].Height; + var dimension = items[0].CommonDimensions[_thumbnailSize]; + return ComputeMaxRows(items, viewWidth) * (dimension.Height + dimension.Offset.y); } } } From b753377f232bb11fa5f3d464e741ad1c25c7199f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Thu, 20 Jan 2022 21:13:27 +0100 Subject: [PATCH 010/119] assetlibrary : remove PinballMetadata --- .../PinballMetadata.meta | 8 -- .../PinballMetadata/PinballMetadata.cs | 80 ------------------- .../PinballMetadata/PinballMetadata.cs.meta | 11 --- .../PinballMetadata/PinballTag.cs | 75 ----------------- .../PinballMetadata/PinballTag.cs.meta | 11 --- .../PinballMetadata/PinballTagsMetaData.cs | 14 ---- .../PinballTagsMetaData.cs.meta | 11 --- 7 files changed, 210 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata.meta deleted file mode 100644 index d64b3f293..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 339883d21b375b64f8356d5d35bba986 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs deleted file mode 100644 index b68e837ec..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using UnityEditor; -using UnityEngine; - -namespace VisualPinball.Unity.Editor -{ - [Serializable] - public class PinballMetadataExtension - { - public int Version = 1; - } - - [Serializable] - public class PinballMetadata - { - [SerializeField] - private JsonPolymorphicList Extensions = new JsonPolymorphicList(); - - public void AddExtenstion(PinballMetadataExtension ext) - { - Remove(ext.GetType()); - Extensions.Items.Add(ext); - } - - public void Remove(Type extType) - { - Extensions.Items.RemoveAll(E => E.GetType() == extType); - } - public ExtType GetExtension() where ExtType : PinballMetadataExtension - { - return (ExtType)Extensions.Items.FirstOrDefault(E => E.GetType() == typeof(ExtType)); - } - } - - public class PinballMetadataCache : Dictionary - { - public static PinballMetadata GetMetadata(string guid) => PinballMetadataMainCache.FirstOrDefault(KV => KV.Key.Equals(guid, StringComparison.InvariantCultureIgnoreCase)).Value; - public static void AddMetadata(string guid, PinballMetadata data) { - if (PinballMetadataMainCache.ContainsKey(guid)) { - PinballMetadataMainCache[guid] = data; - } else { - PinballMetadataMainCache.Add(guid, data); - } - } - - public static void RemoveMetaData(string guid) - { - PinballMetadataMainCache.Remove(guid); - } - - public static void ClearCache() - { - PinballMetadataMainCache.Clear(); - } - - public static PinballMetadata LoadMetadata(string guid) - { - var path = AssetDatabase.GUIDToAssetPath(guid); - var metadata = GetMetadata(guid); - if (metadata == null) { - metadata = new PinballMetadata(); - AddMetadata(guid, metadata); - if (path != "") { - path = path.Replace("\\", "/"); - AssetImporter import = AssetImporter.GetAtPath(path); - if (import.userData != string.Empty) { - EditorJsonUtility.FromJsonOverwrite(import.userData, metadata); - } - } - } - return metadata; - } - - private static PinballMetadataCache PinballMetadataMainCache = new PinballMetadataCache(); - - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs.meta deleted file mode 100644 index a31a5acbc..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballMetadata.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a67bcb20b905c4645b71c88319389365 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs deleted file mode 100644 index 34f538496..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs +++ /dev/null @@ -1,75 +0,0 @@ - -using System; -using System.ComponentModel; -using UnityEditor; -using UnityEditor.UIElements; -using UnityEngine; -using UnityEngine.UIElements; - -namespace VisualPinball.Unity.Editor -{ - [Serializable] - public class PinballTag : ISerializationCallbackReceiver - { - [SerializeField] - private string _fullTag = string.Empty; - public string FullTag { - get { return _fullTag; } - set { _fullTag = value; Build(); } - } - [field: NonSerialized] - public string Tag { get; private set; } = string.Empty; - [field: NonSerialized] - public string Category { get; private set; } = string.Empty; - - public PinballTag(string fullTag) - { - _fullTag = fullTag; - Build(); - } - - public void OnBeforeSerialize() {} - - public void OnAfterDeserialize() { Build(); } - - private void Build() - { - if (string.IsNullOrEmpty(_fullTag)) { - Tag = string.Empty; - Category = string.Empty; - return; - } - var split = _fullTag.Split('.'); - if (split.Length > 1) { - if (split.Length > 2) { - Category = string.Join('_', split, 0, split.Length - 1); - } else { - Category = split[0]; - } - Tag = split[split.Length - 1]; - } - } - } - - //[CustomPropertyDrawer(typeof(PinballTag))] - //public class PinballTagPropertyDrawer : PropertyDrawer - //{ - // private string _tag = string.Empty; - // public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) - // { - // var prop = property.FindPropertyRelative("FullTag"); - // _tag = prop.stringValue; - - // Rect r = EditorGUI.PrefixLabel(position, label); - - // Rect textFieldRect = r; - // textFieldRect.width -= 19f; - - // GUIStyle textFieldStyle = new GUIStyle("TextField") { - // imagePosition = ImagePosition.TextOnly - // }; - - // _tag = GUI.TextField(textFieldRect, _tag); - // } - //} -} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs.meta deleted file mode 100644 index 8cf64f605..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTag.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5a3eac806e853124e842ba4ad79abcc7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs deleted file mode 100644 index 768df1e27..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace VisualPinball.Unity.Editor -{ - [Serializable] - public class PinballTagsMetadata : PinballMetadataExtension - { - public PinballTagsMetadata() : base() {} - public List Tags = new List(); - } - -} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs.meta deleted file mode 100644 index 705dfc188..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/PinballMetadata/PinballTagsMetaData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c577752523210634d9370ab0b1e4ac44 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 4d0f61543ed2478b989c8604068cb19e9b65feb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Thu, 20 Jan 2022 21:16:59 +0100 Subject: [PATCH 011/119] asset library : upgrade PinballLabel to support extended pathes instead of category - better Thumbnailview filtering - cleanup & comments --- .../AssetsLibrary/AssetLibraryContent.cs | 19 ++- .../AssetsLibrary/AssetsLibraryEditor.cs | 3 +- .../AssetsLibrarySettingsAsset.cs | 2 - .../AssetsLibrary/AssetsThumbnailView.cs | 48 ++++++-- .../Labels/LabelThumbnailElement.cs | 1 - .../Labels/LabelsHandler.cs | 21 +++- .../Labels/LabelsThumbnailView.cs | 46 ++++++- .../Labels/PinballLabel.cs | 24 ++-- .../Labels/PinballLabelCategory.cs | 2 + .../Labels/PinballLabelCategoryList.cs | 19 ++- .../Labels/PinballLabelList.cs | 19 ++- .../Labels/PopupLabelsList.cs | 4 +- .../Utils/PopupList/PopupList.cs | 3 +- .../Utils/ThumbnailView/ThumbnailElement.cs | 12 ++ .../Utils/ThumbnailView/ThumbnailView.cs | 113 ++++++++++++++---- 15 files changed, 272 insertions(+), 64 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs index 0f1517582..162c7e12e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs @@ -1,9 +1,24 @@ -using NLog; +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using NLog; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using UnityEditor; using Object = UnityEngine.Object; diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs index 51596108b..534f44d9d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs @@ -18,7 +18,6 @@ using UnityEngine; using UnityEditor; using Logger = NLog.Logger; -using Object = UnityEngine.Object; using System.Linq; using System; @@ -57,6 +56,8 @@ public AssetsLibraryEditor() : base() public override void OnEnable() { base.OnEnable(); + _thumbView.LabelsHandler = _labelsHandler; + _labelsView.LabelsHandler = _labelsHandler; CheckSettinbgsAssets(); } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs index 52b6cf7f4..e1edaf23f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibrarySettingsAsset.cs @@ -16,8 +16,6 @@ using System; using System.Collections.Generic; -using System.ComponentModel; -using UnityEditor; using UnityEngine; namespace VisualPinball.Unity.Editor diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs index 21e35e097..5e28f39c5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs @@ -1,7 +1,22 @@ -using System; +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; using System.Collections.Generic; using System.Linq; -using System.Text; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; @@ -14,6 +29,15 @@ public class AssetsThumbnailView : ThumbnailView public AssetsThumbnailView(IEnumerable data) : base(data) { } + public LabelsHandler LabelsHandler + { + set { + _filteredLabelsView.LabelsHandler = value; + } + } + + private LabelsThumbnailView _filteredLabelsView = new LabelsThumbnailView(null); + protected override void InitCommonStyles() { if (!_commonStyles.Inited) { @@ -29,15 +53,6 @@ protected override void InitCommonStyles() } } - protected override void OnGUIToolbarBegin() - { - - } - - protected override void OnGUIToolbarEnd() - { - } - protected override bool MatchLabelFilter(AssetThumbnailElement item, string labelFilter) { var labels = AssetDatabase.GetLabels(item.Asset); @@ -46,8 +61,17 @@ protected override bool MatchLabelFilter(AssetThumbnailElement item, string labe protected override bool MatchTypeFilter(AssetThumbnailElement item, string typeFilter) { - return (item.Asset.GetType().Name.Equals(typeFilter, StringComparison.InvariantCultureIgnoreCase)); + var prefabType = PrefabUtility.GetPrefabAssetType(item.Asset); + if (prefabType != PrefabAssetType.NotAPrefab && typeFilter.Equals("prefab", StringComparison.InvariantCultureIgnoreCase)) { + return true; + } + return (item.Asset.GetType().Name.Contains(typeFilter, StringComparison.InvariantCultureIgnoreCase)); } + protected override void OnGUIToolbarEnd(Rect r) + { + base.OnGUIToolbarEnd(r); + + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs index ed46ca97b..253ee0e11 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using System.Collections.Generic; -using UnityEditor; using UnityEngine; namespace VisualPinball.Unity.Editor diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs index 0178d6c87..fbe22be3f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; using System.Collections.Generic; using System.Linq; using UnityEditor; @@ -26,7 +25,8 @@ public class LabelsHandler public enum LabelType { LabelLibraries, - Assets + Assets, + All } private Dictionary _labels = new Dictionary() { @@ -52,7 +52,9 @@ private void BuildFromLibraries() var asset = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); foreach (var category in asset.Categories) { if (!string.IsNullOrEmpty(category.Name)) { - _categories[LabelType.LabelLibraries].Add(new PinballLabelCategory(category)); + _categories[LabelType.LabelLibraries].Add(new PinballLabelCategory(category) { + Name = category.Name.Replace(PinballLabel.Separator, PinballLabelCategory.Separator), + }) ; } } foreach(var label in asset.Labels) { @@ -90,5 +92,18 @@ public void AddLabels(string[] labels) } } } + + public List GetLabels(LabelType type = LabelType.All) + { + if (type == LabelType.All) { + var list = new List(); + foreach(var labels in _labels) { + list.AddRange(labels.Value); + } + return list; + } else { + return _labels[type].ToList(); + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs index 80aa321b9..497e1c6a5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs @@ -1,13 +1,33 @@ -using System; +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + using System.Collections.Generic; -using System.Text; +using System.Linq; +using UnityEditor; using UnityEngine; namespace VisualPinball.Unity.Editor { public class LabelsThumbnailView : ThumbnailView { - GUIStyle _labelButtonStyle = null; + GUIStyle _labelButtonStyle; + + public LabelsHandler LabelsHandler = null; + + public bool Editable = false; public LabelsThumbnailView(IEnumerable data) : base(data) { @@ -26,8 +46,28 @@ protected override void InitCommonStyles() _commonStyles.NameStyle = new GUIStyle("label"); _commonStyles.HoverStyle = new GUIStyle(); _commonStyles.HoverStyle.normal.background = TextureExtensions.CreatePixelTexture(new Color(.25f, .25f, .25f)); + + _labelButtonStyle = new GUIStyle(GUI.skin.FindStyle("AssetLabel Icon")); + } + } + + protected override void OnGUIEnd(Rect r) + { + if (Editable && !HasData) { + var popupRect = EditorGUILayout.GetControlRect(false); + if (EditorGUI.DropdownButton(popupRect, new GUIContent(), FocusType.Passive, _labelButtonStyle)) { + if (LabelsHandler != null) { + var labelsList = new PopupLabelList.InputData() { m_AllowCustom = true, m_CloseOnSelection = false, m_EnableAutoCompletion = true, m_SortAlphabetically = true, m_OnSelectCallback = OnSelectLabelCallback }; + labelsList.m_ListElements = LabelsHandler.GetLabels().Select(L => new PopupListElement(L.FullLabel)).ToList(); + PopupWindow.Show(popupRect, new PopupLabelList(labelsList)); + } + } } } + private void OnSelectLabelCallback(PopupListElement element) + { + element.selected = !element.selected; + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs index 37b9bf7ad..2dbcdf548 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs @@ -24,6 +24,8 @@ namespace VisualPinball.Unity.Editor [Serializable] public class PinballLabel : ISerializationCallbackReceiver { + public static readonly char Separator = '.'; + [SerializeField] private string _fullLabel = string.Empty; public string FullLabel @@ -37,7 +39,9 @@ public string FullLabel [field:NonSerialized] public string Label { get; private set; } = string.Empty; - [field:NonSerialized] + [field: NonSerialized] + public string Path { get; private set; } = string.Empty; + [field: NonSerialized] public string Category { get; private set; } = string.Empty; public PinballLabel(string label) @@ -55,26 +59,26 @@ private void Build() } var tuple = Split(_fullLabel); Category = tuple.Item1; - Label = tuple.Item2; + Path = tuple.Item2; + Label = tuple.Item3; } - internal static Tuple Split(string fullLabel) + internal static Tuple Split(string fullLabel) { - var split = fullLabel.Split('.'); - string category = string.Empty, label = string.Empty; + var split = fullLabel.Split(Separator); + string category = string.Empty, path = string.Empty, label; if (split.Length > 1) { + category = split[0]; if (split.Length > 2) { - category = string.Join('_', split, 0, split.Length - 1); - } else { - category = split[0]; - } + path = string.Join(Separator, split, 1, split.Length - 2); + } label = split[split.Length - 1]; } else { label = fullLabel; } - return new Tuple(category, label); + return new Tuple(category, path, label); } public void OnBeforeSerialize() {} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs index a0ff50998..d3fce0c6d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs @@ -24,6 +24,8 @@ namespace VisualPinball.Unity.Editor [Serializable] public class PinballLabelCategory { + public static readonly char Separator = '_'; + [NonSerialized] public static readonly Color DefaultColor = Color.blue; diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs index 295ca4a5f..030ec87af 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategoryList.cs @@ -1,8 +1,23 @@ -using System; +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Text; namespace VisualPinball.Unity.Editor { diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs index 4a9c2e577..d666f21c8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelList.cs @@ -1,8 +1,23 @@ -using System; +// Visual Pinball Engine +// Copyright (C) 2021 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Text; namespace VisualPinball.Unity.Editor { diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs index e418f75cf..cda968c96 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using UnityEditor; using UnityEngine; using Logger = NLog.Logger; @@ -116,7 +115,8 @@ private void HandleLabel(Event evt, string category, PopupListElement element, R bool isActive = selected; using (new EditorGUI.DisabledScope(!element.enabled)) { - GUIContent content = new GUIContent($"{(string.IsNullOrEmpty(category) ? string.Empty : " ")}{PinballLabel.Split(element.text).Item2}"); + var label = PinballLabel.Split(element.text); + GUIContent content = new GUIContent($"{(string.IsNullOrEmpty(category) ? string.Empty : " ")}{label.Item3}"); style.Draw(rect, content, isHover, isActive, selected, false); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs index 90f84b219..f5d4d3e65 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using UnityEditor; using UnityEngine; @@ -187,7 +186,7 @@ public virtual IEnumerable BuildQuery(string prefix) return m_ListElements; else return m_ListElements.Where( - element => element.m_Content.text.StartsWith(prefix, System.StringComparison.OrdinalIgnoreCase) + element => element.m_Content.text.Contains(prefix, System.StringComparison.OrdinalIgnoreCase) ); } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs index bc1a58e7d..3f6e91fa0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailElement.cs @@ -20,6 +20,9 @@ namespace VisualPinball.Unity.Editor { + /// + /// Thumbnail elements display size enum. used by . + /// public enum EThumbnailSize { Small, @@ -27,6 +30,9 @@ public enum EThumbnailSize Large } + /// + /// Default class to display elements within a . + /// public abstract class ThumbnailElement { /// @@ -86,6 +92,9 @@ public abstract class ThumbnailElement /// public abstract void DrawHoverContainer(Rect rect); + /// + /// Description of the element height & offset when displayed, width will be computed by the element itself. + /// public struct Dimension { public Vector2 Offset; @@ -98,6 +107,9 @@ public struct Dimension { EThumbnailSize.Large, new Dimension(){ Offset = Vector2.zero, Height = 150 } } }; + /// + /// Common dimensions used by the + /// public virtual Dictionary CommonDimensions => _commonDimensions; diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs index cd38f4d6c..b0feca5ec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/ThumbnailView/ThumbnailView.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity.Editor { /// - /// + /// Styles used by the view to display elements, elements' names & hover container /// public class ThumbnailViewStyles { @@ -42,10 +42,19 @@ public class ThumbnailViewStyles /// a generic class public abstract class ThumbnailView where T : ThumbnailElement { + /// + /// Displays the toolbar (name filter, thumnail size selector, potential custom pre/port toolbar elements). + /// public bool ShowToolbar = true; + /// + /// Display elements' names under each element. + /// public bool DisplayNames = true; + /// + /// Set single or multiple elements' selection. + /// public bool MultiSelection = false; public struct RowCollums @@ -57,11 +66,21 @@ public struct RowCollums } private List _data = new List(); + /// + /// Does this view contains data to display. + /// + public bool HasData => _data.Count > 0; private Vector2 _scroll; private List _selectedItems = new List(); + /// + /// List of selected items. + /// public List SelectedItems => _selectedItems; + /// + /// Selected item (null in case of multi selection). + /// public T SelectedItem => _selectedItems.Count == 1 ? _selectedItems[0] : null; private string _searchFilter = string.Empty; @@ -70,11 +89,28 @@ public struct RowCollums protected ThumbnailViewStyles _commonStyles = new ThumbnailViewStyles(); + private enum Filters + { + Name, + Label, + Type + } + + private Dictionary> _filters = new Dictionary> { + {Filters.Name , new HashSet()}, + {Filters.Label, new HashSet()}, + {Filters.Type, new HashSet()} + }; + public ThumbnailView(IEnumerable data) { SetData(data); } + /// + /// Fill the view with elements to display. + /// + /// Elements to be displayed. public void SetData(IEnumerable data) { _data.Clear(); @@ -85,8 +121,10 @@ public void SetData(IEnumerable data) protected abstract void InitCommonStyles(); - protected virtual void OnGUIToolbarBegin() { } - protected virtual void OnGUIToolbarEnd() { } + protected virtual void OnGUIToolbarBegin(Rect r) { } + protected virtual void OnGUIToolbarEnd(Rect r) { } + protected virtual void OnGUIBegin(Rect r) { } + protected virtual void OnGUIEnd(Rect r) { } protected virtual bool MatchLabelFilter(T item, string labelFilter) => false; protected virtual bool MatchTypeFilter(T item, string typeFilter) => false; @@ -103,50 +141,71 @@ private static int FilterCompare(string f1, string f2) private float NameLineHeight => DisplayNames ? _commonStyles.NameStyle.lineHeight : 0.0f; - private List GetFilteredItems() + private void SetupFilters() { - List filteredNames = new List(); - List filteredLabels = new List(); - List filteredTypes = new List(); - filteredNames.AddRange(_data); + foreach(var set in _filters.Values) { + set.Clear(); + } + var filters = _searchFilter.Split(' ').ToList(); filters.Sort(FilterCompare); - int labelCnt = 0, typeCnt = 0; foreach (var filter in filters) { if (string.IsNullOrEmpty(filter)) continue; if (filter.StartsWith("l:", StringComparison.InvariantCultureIgnoreCase)) { var labelFilter = filter.Split(':')[1]; if (!string.IsNullOrEmpty(labelFilter)) { - labelCnt++; - filteredLabels = filteredLabels.Union(_data.Where(I => MatchLabelFilter(I, labelFilter))).ToList(); + _filters[Filters.Label].Add(labelFilter); } - }else if (filter.StartsWith("t:", StringComparison.InvariantCultureIgnoreCase)) { + } else if (filter.StartsWith("t:", StringComparison.InvariantCultureIgnoreCase)) { var typeFilter = filter.Split(':')[1]; if (!string.IsNullOrEmpty(typeFilter)) { - typeCnt++; - filteredTypes = filteredTypes.Union(_data.Where(I => MatchTypeFilter(I, typeFilter))).ToList(); + _filters[Filters.Type].Add(typeFilter); } } else { - filteredNames = filteredNames.Where(I => I.Name.Contains(filter, StringComparison.InvariantCultureIgnoreCase)).ToList(); + _filters[Filters.Name].Add(filter); } } - if (labelCnt > 0) - filteredNames = filteredNames.Intersect(filteredLabels).ToList(); - if (typeCnt > 0) - filteredNames = filteredNames.Intersect(filteredTypes).ToList(); - return filteredNames; + } + + private List GetFilteredItems() + { + List filteredByNames = new List(); + List filteredByLabels = new List(); + List filteredByTypes = new List(); + var filteredItems = _filters[Filters.Label].Select(L => _data.Where(I => MatchLabelFilter(I, L))); + foreach (var items in filteredItems) { + filteredByLabels = filteredByLabels.Union(items).ToList(); + } + filteredItems = _filters[Filters.Type].Select(L => _data.Where(I => MatchTypeFilter(I, L))); + foreach (var items in filteredItems) { + filteredByTypes = filteredByTypes.Union(items).ToList(); + } + + if (_filters[Filters.Name].Count > 0) { + filteredByNames = _data.Where(I => _filters[Filters.Name].Any(F => I.Name.Contains(F, StringComparison.InvariantCultureIgnoreCase))).ToList(); + } else { + filteredByNames.AddRange(_data); + } + + if (_filters[Filters.Label].Count > 0) + filteredByNames = filteredByNames.Intersect(filteredByLabels).ToList(); + if (_filters[Filters.Type].Count > 0) + filteredByNames = filteredByNames.Intersect(filteredByTypes).ToList(); + return filteredByNames; } public void OnGUI(Rect rect) { InitCommonStyles(); + OnGUIBegin(rect); + EditorGUILayout.BeginVertical(GUILayout.Width(rect.width),GUILayout.Height(rect.height)); if (ShowToolbar) { EditorGUILayout.BeginVertical(); - OnGUIToolbarBegin(); + OnGUIToolbarBegin(rect); EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.Width(rect.width)); EditorGUILayout.LabelField("Name Filter", GUILayout.Width(100)); @@ -159,11 +218,13 @@ public void OnGUI(Rect rect) GUIUtility.keyboardControl = 0; } + SetupFilters(); + EditorGUILayout.LabelField("Thumbnail Size", GUILayout.Width(100)); _thumbnailSize = (EThumbnailSize)EditorGUILayout.EnumPopup(_thumbnailSize, GUILayout.Width(100)); EditorGUILayout.EndHorizontal(); - OnGUIToolbarEnd(); + OnGUIToolbarEnd(rect); EditorGUILayout.EndVertical(); } @@ -215,6 +276,8 @@ public void OnGUI(Rect rect) } EditorGUILayout.EndVertical(); + + OnGUIEnd(rect); } public void HandleEvents(T item, Rect itemRect) @@ -267,6 +330,12 @@ protected int ComputeMaxRows(List items, float viewWidth) return rowCount; } + /// + /// Will return the computed view height based on view's elements + /// + /// The wiew width needed to evaluate how many rows are needed. + /// If true, will be computed only with filtered elements base on the toolbar's name filter. + /// The height of the view to display all needed elements. public float ComputeViewHeight(float viewWidth, bool filteredItems = true) { if (_data.Count == 0) From 4dbaac666a2f6528992edd8e20bad51c037a8dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Thu, 20 Jan 2022 22:05:48 +0100 Subject: [PATCH 012/119] assetlibrary : more comments --- .../AssetsLibrary/AssetLibraryContent.cs | 11 +- .../AssetsLibrary/AssetThumbnailElement.cs | 3 + .../AssetsLibrary/AssetsLibraryEditor.cs | 105 ++++++++++++------ .../AssetsLibrary/AssetsThumbnailView.cs | 3 + 4 files changed, 83 insertions(+), 39 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs index 162c7e12e..0e0660613 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetLibraryContent.cs @@ -24,8 +24,15 @@ namespace VisualPinball.Unity.Editor { + /// + /// AssetLibraryContent will host all populated assets from a + /// public class AssetLibraryContent { + /// + /// Within the , each AssetLibraryFolderContent will host assets from each + /// It'll also watch for any changes within this folder to automatically update assets' list. + /// public class AssetLibraryFolderContent { private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); @@ -66,12 +73,12 @@ public AssetLibraryFolderContent(AssetsLibrarySettingsAsset.FolderSettings folde private void OnChanged(object sender, FileSystemEventArgs e) { - + //TODO } private void OnRenamed(object sender, RenamedEventArgs e) { - + //TODO } public void PopulateAssets() diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs index adf2a2b7c..44e7bd0e5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetThumbnailElement.cs @@ -21,6 +21,9 @@ namespace VisualPinball.Unity.Editor { + /// + /// A dedicated for displaying assets + /// public class AssetThumbnailElement : ThumbnailElement { private Object _asset = null; diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs index 534f44d9d..65923b767 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs @@ -23,31 +23,62 @@ namespace VisualPinball.Unity.Editor { + /// + /// The AssetsLibraryEditor is the main window for VPE Assets Libray + /// public class AssetsLibraryEditor : BaseEditorWindow { + #region Menu Item + [MenuItem("Visual Pinball/Assets Library", false, 601)] + public static void ShowWindow() + { + GetWindow().titleContent = new GUIContent("Assets Library"); + } + #endregion + private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + #region Assets Management + /// + /// This handler will manage all Populated Pinball labels and provide helpers for categories + /// private LabelsHandler _labelsHandler = new LabelsHandler(); + /// + /// Populated assets libraries from all found within the AssetDatabase + /// private List _assetLibraries = new List(); - private Dictionary _assetLibrariesSelection = new Dictionary(); + #endregion - private List _filterLabels = new List(); + #region Assets Thumbnail View + /// + /// Keep selections from the Libraries dropdown selector + /// + private Dictionary _assetLibrariesSelection = new Dictionary(); - private List _thumbs = new List(); + /// + /// Editor left side assets thumbnail view + /// private AssetsThumbnailView _thumbView = new AssetsThumbnailView(null) { MultiSelection = false }; + private List _thumbs = new List(); + #endregion - private LabelsThumbnailView _labelsView = new LabelsThumbnailView(null) { ShowToolbar = false, DisplayNames = false, MultiSelection = false }; - + #region Details Panel + /// + /// Preview from the Details panel + /// private UnityEditor.Editor _previewEditor = null; - private List _assetLabels = new List(); + /// + /// Labels list from the Details panel + /// + private LabelsThumbnailView _labelsView = new LabelsThumbnailView(null) { ShowToolbar = false, DisplayNames = false, MultiSelection = false }; - [MenuItem("Visual Pinball/Assets Library", false, 601)] - public static void ShowWindow() - { - GetWindow().titleContent = new GUIContent("Assets Library"); - } + /// + /// List of selected asset's labels. + /// + private List _assetLabels = new List(); + #endregion public AssetsLibraryEditor() : base() { @@ -66,6 +97,32 @@ public override void OnEnable() private bool _showDetails = true; private bool _showLabels = true; + public void OnGUI() + { + EditorGUILayout.BeginHorizontal(); + + var thumbRect = new Rect(position); + thumbRect.y += GUI.skin.button.lineHeight; + thumbRect.width -= DetailsWindowWidth; + thumbRect.height -= GUI.skin.button.lineHeight; + + EditorGUILayout.BeginVertical(GUILayout.Width(thumbRect.width)); + //Library selector + if (EditorGUILayout.DropdownButton(new GUIContent("Libraries"), FocusType.Passive, GUILayout.Width(150))) { + DoLibrariesPopup(); + } + + _thumbView.OnGUI(thumbRect); + + EditorGUILayout.EndVertical(); + + EditorGUILayout.BeginVertical(); + DetailsGUI(); + EditorGUILayout.EndVertical(); + + EditorGUILayout.EndHorizontal(); + } + private void DetailsGUI() { @@ -144,32 +201,6 @@ private void DetailsGUI() } } - public void OnGUI() - { - EditorGUILayout.BeginHorizontal(); - - var thumbRect = new Rect(position); - thumbRect.y += GUI.skin.button.lineHeight; - thumbRect.width -= DetailsWindowWidth; - thumbRect.height -= GUI.skin.button.lineHeight; - - EditorGUILayout.BeginVertical(GUILayout.Width(thumbRect.width)); - //Library selector - if (EditorGUILayout.DropdownButton(new GUIContent("Libraries"), FocusType.Passive, GUILayout.Width(150))) { - DoLibrariesPopup(); - } - - _thumbView.OnGUI(thumbRect); - - EditorGUILayout.EndVertical(); - - EditorGUILayout.BeginVertical(); - DetailsGUI(); - EditorGUILayout.EndVertical(); - - EditorGUILayout.EndHorizontal(); - } - private void DoLibrariesPopup() { var inputdata = new GenericPopupList.InputData() { diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs index 5e28f39c5..1fbd75d42 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsThumbnailView.cs @@ -23,6 +23,9 @@ namespace VisualPinball.Unity.Editor { + /// + /// A dedicated for displaying assets + /// public class AssetsThumbnailView : ThumbnailView { public Object SelectedAsset => SelectedItem?.Asset; From 078ed93de7abc025c7373438c40175ab2235da22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vr=C3=B4=C3=95nsh?= Date: Thu, 20 Jan 2022 22:13:33 +0100 Subject: [PATCH 013/119] asset library : more comments --- .../Labels/LabelThumbnailElement.cs | 3 +++ .../VisualPinball.Unity.Editor/Labels/LabelsHandler.cs | 3 +++ .../Labels/LabelsLibraryAsset.cs | 3 +++ .../Labels/LabelsThumbnailView.cs | 9 +++++++++ .../VisualPinball.Unity.Editor/Labels/PinballLabel.cs | 6 +++++- .../Labels/PinballLabelCategory.cs | 3 +++ .../VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs | 3 +++ .../Utils/PopupList/PopupList.cs | 9 +++++++++ 8 files changed, 38 insertions(+), 1 deletion(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs index 253ee0e11..6646aa0d2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelThumbnailElement.cs @@ -19,6 +19,9 @@ namespace VisualPinball.Unity.Editor { + /// + /// A dedicated for displaying PinballLabels. + /// public class LabelThumbnailElement : ThumbnailElement { private PinballLabel _label = null; diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs index fbe22be3f..eacb8fbee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsHandler.cs @@ -20,6 +20,9 @@ namespace VisualPinball.Unity.Editor { + /// + /// The LabelHandler stores PinballLabels from both and parsed assets from the + /// public class LabelsHandler { public enum LabelType diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs index d507b0e70..51b3b529e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsLibraryAsset.cs @@ -22,6 +22,9 @@ namespace VisualPinball.Unity.Editor { + /// + /// LabelsLibraryAsset stores categories identifiers and pre-built labels to help Labels proposal and Categories formatting + /// [CreateAssetMenu(fileName = "Labels Library", menuName = "Visual Pinball/Label Library", order = 101)] public class LabelsLibraryAsset : ScriptableObject { diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs index 497e1c6a5..fcef8dcbb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/LabelsThumbnailView.cs @@ -21,12 +21,21 @@ namespace VisualPinball.Unity.Editor { + /// + /// A dedicated for labels displaying, using Unity's AssetLabel styles + /// public class LabelsThumbnailView : ThumbnailView { GUIStyle _labelButtonStyle; + /// + /// Handler used to populate the labels dropdown + /// public LabelsHandler LabelsHandler = null; + /// + /// If true, will authorize to open a label dropdown to add/remove labels. + /// public bool Editable = false; public LabelsThumbnailView(IEnumerable data) : base(data) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs index 2dbcdf548..262593c5f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabel.cs @@ -20,7 +20,11 @@ namespace VisualPinball.Unity.Editor { - [DebuggerDisplay("Category = {Category}, Label = {Label}")] + /// + /// Expose classic Unity's labels (strings) as categorized labels + /// Provide helpers to split directly a string into PinballLabel parts following proper format. + /// + [DebuggerDisplay("Category = {Category}, Path = {Path}, Label = {Label}")] [Serializable] public class PinballLabel : ISerializationCallbackReceiver { diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs index d3fce0c6d..d9b12aced 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PinballLabelCategory.cs @@ -20,6 +20,9 @@ namespace VisualPinball.Unity.Editor { + /// + /// category settings used to help PinballLabels browsing. + /// [DebuggerDisplay("Name = {Name}, MultipleSelection = {MultipleSelection}, Color = {Color}")] [Serializable] public class PinballLabelCategory diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs index cda968c96..27ea994a6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Labels/PopupLabelsList.cs @@ -23,6 +23,9 @@ namespace VisualPinball.Unity.Editor { + /// + /// A used for displaying PinballLabel & PinballLabelsCategory in a + /// public class PopupLabelList : PopupList { private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs index f5d4d3e65..b8332664f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/PopupList/PopupList.cs @@ -22,6 +22,9 @@ namespace VisualPinball.Unity.Editor { + /// + /// Base class for elements used in a + /// public class PopupListElement { public GUIContent m_Content; @@ -141,6 +144,12 @@ public void ResetScore() } } + /// + /// Base class for displaying a selectable list within a + /// Manage name filtering & custom items rendering + /// Heavily inspired by internal PopupList class. + /// + /// A child class of public class PopupList : PopupWindowContent where T : PopupListElement, new() { public delegate void OnSelectCallback(T element); From e484f6fb12ac56a0f210ebeb84b83acf0cd6852d Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 14 Mar 2022 22:43:24 +0100 Subject: [PATCH 014/119] assets: Add test UI. --- .../VisualPinball.Engine.csproj | 3 + .../AssetBrowser.meta | 3 + .../AssetBrowser/AssetBrowser.cs | 96 ++++++++++++++++++ .../AssetBrowser/AssetBrowser.cs.meta | 11 +++ .../AssetBrowser/AssetBrowserX.cs | 65 +++++++++++++ .../AssetBrowser/AssetBrowserX.cs.meta | 11 +++ .../AssetBrowser/AssetBrowserX.uss | 41 ++++++++ .../AssetBrowser/AssetBrowserX.uss.meta | 11 +++ .../AssetBrowser/AssetBrowserX.uxml | 13 +++ .../AssetBrowser/AssetBrowserX.uxml.meta | 10 ++ .../AssetBrowser/AssetBrowserX_Init.cs | 97 +++++++++++++++++++ .../AssetBrowser/AssetBrowserX_Init.cs.meta | 11 +++ .../AssetBrowser/AssetLibrary.cs | 63 ++++++++++++ .../AssetBrowser/AssetLibrary.cs.meta | 11 +++ .../AssetsLibrary/AssetsLibraryEditor.cs | 10 +- 15 files changed, 448 insertions(+), 8 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowser.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowser.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs.meta diff --git a/VisualPinball.Engine/VisualPinball.Engine.csproj b/VisualPinball.Engine/VisualPinball.Engine.csproj index 14209754f..e7a2b2a75 100644 --- a/VisualPinball.Engine/VisualPinball.Engine.csproj +++ b/VisualPinball.Engine/VisualPinball.Engine.csproj @@ -29,6 +29,8 @@ + + @@ -57,6 +59,7 @@ + diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser.meta new file mode 100644 index 000000000..21a87c0d6 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 72b6e71ef81848578f7a444569738193 +timeCreated: 1647207526 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowser.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowser.cs new file mode 100644 index 000000000..049bfda8a --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowser.cs @@ -0,0 +1,96 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace VisualPinball.Unity.Editor +{ + public class AssetBrowser : EditorWindow + { + private VisualElement _rightPane; + + [SerializeField] + private int selectedIndex = -1; + + + [MenuItem("Visual Pinball/Asset Browser")] + public static void Init() + { + var wnd = GetWindow("Asset Browser"); + + // Limit size of the window + wnd.minSize = new Vector2(450, 200); + wnd.maxSize = new Vector2(1920, 720); + } + + public void CreateGUI() + { + // Get a list of all sprites in the project + var allObjectGuids = AssetDatabase.FindAssets("t:Texture", new [] { + "Packages/org.visualpinball.unity.assetlibrary/Assets" + }); + + var allObjects = allObjectGuids.Select(guid => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid))).ToList(); + + // Create a two-pane view with the left pane being fixed with + var splitView = new TwoPaneSplitView(0, 250, TwoPaneSplitViewOrientation.Horizontal); + + // Add the view to the visual tree by adding it as a child to the root element + rootVisualElement.Add(splitView); + + // A TwoPaneSplitView always needs exactly two child elements + var leftPane = new ListView(); + splitView.Add(leftPane); + + _rightPane = new ScrollView(ScrollViewMode.VerticalAndHorizontal); + splitView.Add(_rightPane); + + // Initialize the list view with all sprites' names + leftPane.makeItem = () => new Label(); + leftPane.bindItem = (item, index) => { (item as Label)!.text = allObjects[index].name; }; + leftPane.itemsSource = allObjects; + leftPane.onSelectionChange += OnSpriteSelectionChange; + leftPane.onSelectionChange += _ => { selectedIndex = leftPane.selectedIndex; }; + leftPane.selectedIndex = selectedIndex; + } + + private void OnSpriteSelectionChange(IEnumerable selectedItems) + { + // Clear all previous content from the pane + _rightPane.Clear(); + + // Get the selected sprite + var selectedTexture = selectedItems.First() as Texture; + if (selectedTexture == null) { + return; + } + + // Add a new Image control and display the sprite + var spriteImage = new Image { + scaleMode = ScaleMode.ScaleToFit, + image = selectedTexture + }; + + // Add the Image control to the right-hand pane + _rightPane.Add(spriteImage); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowser.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowser.cs.meta new file mode 100644 index 000000000..02d4eddb1 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21e51012f555e1440a8d425b574a4615 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs new file mode 100644 index 000000000..dce6f0eaa --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs @@ -0,0 +1,65 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.Plastic.Antlr3.Runtime.Debug; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + + +namespace VisualPinball.Unity.Editor +{ + public partial class AssetBrowserX : EditorWindow + { + [SerializeField] + private int selectedIndex = -1; + + private ToolbarButton _refreshButton; + private VisualElement _rightPane; + + private List _assetLibraries; + + [MenuItem("Visual Pinball/Asset Browser X")] + public static void Init() + { + var wnd = GetWindow("Asset Browser X"); + + // Limit size of the window + wnd.minSize = new Vector2(450, 200); + wnd.maxSize = new Vector2(1920, 720); + } + + private void OnEnable() + { + _assetLibraries = AssetDatabase.FindAssets($"t:{typeof(AssetLibrary)}") + .Select(AssetDatabase.GUIDToAssetPath) + .Select(AssetDatabase.LoadAssetAtPath) + .Where(asset => asset != null).ToList(); + } + + private void Refresh() + { + Debug.Log($"Found {_assetLibraries.Count} asset libraries:"); + foreach (var assetLibrary in _assetLibraries) { + Debug.Log($"{assetLibrary.Name}: {assetLibrary._dbPath}"); + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs.meta new file mode 100644 index 000000000..5771d2a01 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 681ba8a5561dfea4497a01e5b5e1b801 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss new file mode 100644 index 000000000..808b48839 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss @@ -0,0 +1,41 @@ +.assetGridHeaderRow { + flex-direction: row; + height:22px; + align-items: center; + flex-shrink: 0; + justify-content: space-between; + padding-left:4px; + border-bottom-width: 1px; + border-color: #222; + + background-color: #3c3c3c; /* TODO (CLEANUP): This should come from the attached unity-toolbar class; but that class isn't showing up in ui debugger. not sure what I need to do... */ +} + +.leftSide { + flex-direction: row; + flex-shrink: 1; + margin-bottom:1px; +} + +.rightSide { + flex-direction: row; + margin-right:4px; + margin-bottom:1px; + flex-shrink: 0; +} + +/***********************/ +/** Split view styles **/ +/***********************/ + +ListView { + flex-grow: 1; +} + +.unity-two-pane-split-view { + flex-grow: 1; +} + +.unity-two-pane-split-view__dragline-anchor { + background-color: #1d1d1d; +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss.meta new file mode 100644 index 000000000..ed016fa45 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98b5afa4f7306e04fb160371138d6662 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} + disableValidation: 0 diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml new file mode 100644 index 000000000..6840a67fe --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml.meta new file mode 100644 index 000000000..f50e51df0 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 466b5f13746a85b4ba3ed622cfc5198c +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs new file mode 100644 index 000000000..928ef4ca4 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs @@ -0,0 +1,97 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + +namespace VisualPinball.Unity.Editor +{ + public partial class AssetBrowserX + { + public void CreateGUI() + { + // import UXML + var visualTree = AssetDatabase.LoadAssetAtPath("Packages/org.visualpinball.engine.unity/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml"); + visualTree.CloneTree(rootVisualElement); + + var ui = rootVisualElement; + + // import style sheet + var styleSheet = AssetDatabase.LoadAssetAtPath("Packages/org.visualpinball.engine.unity/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss"); + ui.styleSheets.Add(styleSheet); + + InitLeftPane(ui.Q("leftPane")); + _rightPane = ui.Q("rightPane"); + + _refreshButton = ui.Q("refreshButton"); + Debug.Log("Got refresh button: " + _refreshButton); + _refreshButton.clicked += Refresh; + } + + + private void OnDestroy() + { + _refreshButton.clicked -= Refresh; + } + + private void InitLeftPane(BaseVerticalCollectionView leftPane) + { + var allObjectGuids = AssetDatabase.FindAssets("t:Texture", new [] { + "Packages/org.visualpinball.unity.assetlibrary/Assets" + }); + var allObjects = allObjectGuids.Select(guid => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid))).ToList(); + + leftPane.makeItem = () => new Label(); + leftPane.bindItem = (item, index) => { + (item as Label)!.text = allObjects[index].name; + }; + leftPane.itemsSource = allObjects; + leftPane.onSelectionChange += OnSpriteSelectionChange; + leftPane.onSelectionChange += _ => { + selectedIndex = leftPane.selectedIndex; + }; + leftPane.selectedIndex = selectedIndex; + + leftPane.RefreshItems(); + } + + private void OnSpriteSelectionChange(IEnumerable selectedItems) + { + // Clear all previous content from the pane + _rightPane?.Clear(); + + // Get the selected sprite + var selectedTexture = selectedItems.First() as Texture; + if (selectedTexture == null) { + return; + } + + // Add a new Image control and display the sprite + var spriteImage = new Image { + scaleMode = ScaleMode.ScaleToFit, + image = selectedTexture + }; + + // Add the Image control to the right-hand pane + _rightPane?.Add(spriteImage); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs.meta new file mode 100644 index 000000000..a923a77c0 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8d98d4620f8776048a59fe0d28811083 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs new file mode 100644 index 000000000..c646ed66e --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs @@ -0,0 +1,63 @@ +// Visual Pinball Engine +// Copyright (C) 2022 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.IO; +using LiteDB; +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + [CreateAssetMenu(fileName = "Library", menuName = "Visual Pinball/Asset Library", order = 300)] + public class AssetLibrary : ScriptableObject, ISerializationCallbackReceiver + { + public string Name; + + public string LibraryRoot; + + public string _dbPath { + get { + var thisPath = AssetDatabase.GetAssetPath(this); + return Path.GetDirectoryName(thisPath) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(thisPath) + ".db"; + } + } + + public void Test() + { + Debug.Log($"DB PATH = {_dbPath}"); + // using (var db = new LiteDatabase(@"MyData.db")) { + // + // } + // var col = db.GetCollection("customers"); + } + public void OnBeforeSerialize() + { + if (string.IsNullOrEmpty(LibraryRoot)) { + LibraryRoot = Path.GetDirectoryName(AssetDatabase.GetAssetPath(this)); + } + } + + public void OnAfterDeserialize() + { + } + } + + public class LibraryAsset + { + public string Guid { get; set; } + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs.meta new file mode 100644 index 000000000..db0300d86 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b98ec5a8d987a83479bb91a2f3ff526e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs index 65923b767..db48b78b3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetsLibrary/AssetsLibraryEditor.cs @@ -36,18 +36,16 @@ public static void ShowWindow() } #endregion - private static readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger(); - #region Assets Management /// /// This handler will manage all Populated Pinball labels and provide helpers for categories /// - private LabelsHandler _labelsHandler = new LabelsHandler(); + private readonly LabelsHandler _labelsHandler = new LabelsHandler(); /// /// Populated assets libraries from all found within the AssetDatabase /// - private List _assetLibraries = new List(); + private readonly List _assetLibraries = new List(); #endregion #region Assets Thumbnail View @@ -80,10 +78,6 @@ public static void ShowWindow() private List _assetLabels = new List(); #endregion - public AssetsLibraryEditor() : base() - { - } - public override void OnEnable() { base.OnEnable(); From 12f22bc51e217244107cdf38bce90227e4056e13 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 16 Mar 2022 00:24:24 +0100 Subject: [PATCH 015/119] assets: Enable drag and drop and save to DB. --- .../AssetBrowser/AssetBrowserX.cs | 48 +++++++++++-- .../AssetBrowser/AssetBrowserX_Init.cs | 58 ++++++++------- .../AssetBrowser/AssetLibrary.cs | 70 ++++++++++++++++--- 3 files changed, 135 insertions(+), 41 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs index dce6f0eaa..3eeb20a52 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs @@ -14,16 +14,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; using System.Collections.Generic; +using System.IO; using System.Linq; -using Unity.Plastic.Antlr3.Runtime.Debug; using UnityEditor; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; - namespace VisualPinball.Unity.Editor { public partial class AssetBrowserX : EditorWindow @@ -31,6 +29,8 @@ public partial class AssetBrowserX : EditorWindow [SerializeField] private int selectedIndex = -1; + private List _assets; + private ToolbarButton _refreshButton; private VisualElement _rightPane; @@ -56,9 +56,45 @@ private void OnEnable() private void Refresh() { - Debug.Log($"Found {_assetLibraries.Count} asset libraries:"); - foreach (var assetLibrary in _assetLibraries) { - Debug.Log($"{assetLibrary.Name}: {assetLibrary._dbPath}"); + _assets = _assetLibraries.SelectMany(lib => lib.GetAssets()).ToList(); + var leftPane = rootVisualElement.Q("leftPane"); + + leftPane.itemsSource = _assets; + leftPane.RefreshItems(); + } + + private void OnDragUpdatedEvent(DragUpdatedEvent evt) + { + DragAndDrop.visualMode = DragAndDrop.objectReferences != null + ? DragAndDropVisualMode.Move + : DragAndDropVisualMode.Copy; + } + + private void OnDragPerformEvent(DragPerformEvent evt) + { + DragAndDrop.AcceptDrag(); + + // Disallow adding from outside of Unity + foreach (var path in DragAndDrop.paths) { + var libraryFound = false; + foreach (var assetLibrary in _assetLibraries) { + if (path.Replace('\\', '/').StartsWith(assetLibrary.LibraryRoot.Replace('\\', '/'))) { + libraryFound = true; + var guid = AssetDatabase.AssetPathToGUID(path); + var type = AssetDatabase.GetMainAssetTypeAtPath(path); + + if (assetLibrary.AddAsset(guid, type, path)) { + Debug.Log($"{Path.GetFileName(path)} added to library {assetLibrary.Name}."); + } else { + Debug.Log($"{Path.GetFileName(path)} updated in library {assetLibrary.Name}."); + } + + Refresh(); + } + } + if (!libraryFound) { + Debug.LogError($"Cannot find a VPE library at path {Path.GetDirectoryName(path)}, ignoring asset {Path.GetFileName(path)}."); + } } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs index 928ef4ca4..8f81bb77f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; using System.Collections.Generic; +using System.IO; using System.Linq; using UnityEditor; using UnityEditor.UIElements; @@ -44,27 +44,33 @@ public void CreateGUI() _refreshButton = ui.Q("refreshButton"); Debug.Log("Got refresh button: " + _refreshButton); _refreshButton.clicked += Refresh; + + _rightPane.RegisterCallback(OnDragUpdatedEvent); + _rightPane.RegisterCallback(OnDragPerformEvent); } private void OnDestroy() { + _rightPane.UnregisterCallback(OnDragPerformEvent); + _rightPane.UnregisterCallback(OnDragUpdatedEvent); _refreshButton.clicked -= Refresh; + + foreach (var assetLibrary in _assetLibraries) { + assetLibrary.Dispose(); + } } private void InitLeftPane(BaseVerticalCollectionView leftPane) { - var allObjectGuids = AssetDatabase.FindAssets("t:Texture", new [] { - "Packages/org.visualpinball.unity.assetlibrary/Assets" - }); - var allObjects = allObjectGuids.Select(guid => AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid))).ToList(); + _assets = _assetLibraries.SelectMany(lib => lib.GetAssets()).ToList(); leftPane.makeItem = () => new Label(); leftPane.bindItem = (item, index) => { - (item as Label)!.text = allObjects[index].name; + (item as Label)!.text = Path.GetFileName(_assets[index].Path); }; - leftPane.itemsSource = allObjects; - leftPane.onSelectionChange += OnSpriteSelectionChange; + leftPane.itemsSource = _assets; + leftPane.onSelectionChange += OnAssetSelectionChange; leftPane.onSelectionChange += _ => { selectedIndex = leftPane.selectedIndex; }; @@ -73,25 +79,25 @@ private void InitLeftPane(BaseVerticalCollectionView leftPane) leftPane.RefreshItems(); } - private void OnSpriteSelectionChange(IEnumerable selectedItems) + private void OnAssetSelectionChange(IEnumerable selectedItems) { - // Clear all previous content from the pane - _rightPane?.Clear(); - - // Get the selected sprite - var selectedTexture = selectedItems.First() as Texture; - if (selectedTexture == null) { - return; - } - - // Add a new Image control and display the sprite - var spriteImage = new Image { - scaleMode = ScaleMode.ScaleToFit, - image = selectedTexture - }; - - // Add the Image control to the right-hand pane - _rightPane?.Add(spriteImage); + // // Clear all previous content from the pane + // _rightPane?.Clear(); + // + // // Get the selected asset + // var selectedTexture = selectedItems.First() as Texture; + // if (selectedTexture == null) { + // return; + // } + // + // // Add a new Image control and display the asset + // var spriteImage = new Image { + // scaleMode = ScaleMode.ScaleToFit, + // image = selectedTexture + // }; + // + // // Add the Image control to the right-hand pane + // _rightPane?.Add(spriteImage); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs index c646ed66e..562b476e7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetLibrary.cs @@ -14,6 +14,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +// ReSharper disable InconsistentNaming + +using System; +using System.Collections.Generic; using System.IO; using LiteDB; using UnityEditor; @@ -22,27 +26,74 @@ namespace VisualPinball.Unity.Editor { [CreateAssetMenu(fileName = "Library", menuName = "Visual Pinball/Asset Library", order = 300)] - public class AssetLibrary : ScriptableObject, ISerializationCallbackReceiver + public class AssetLibrary : ScriptableObject, ISerializationCallbackReceiver, IDisposable { public string Name; public string LibraryRoot; - public string _dbPath { + private LiteDatabase _db { + get { + if (_dbInstance != null) { + return _dbInstance; + } + _dbInstance = new LiteDatabase(_dbPath); + return _dbInstance; + } + } + + private void OnDestroy() + { + Dispose(); + } + + public void Dispose() + { + _dbInstance?.Dispose(); + _dbInstance = null; + } + + private string _dbPath { get { var thisPath = AssetDatabase.GetAssetPath(this); return Path.GetDirectoryName(thisPath) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(thisPath) + ".db"; } } - public void Test() + private LiteDatabase _dbInstance; + + public bool AddAsset(string guid, Type type, string path) { - Debug.Log($"DB PATH = {_dbPath}"); - // using (var db = new LiteDatabase(@"MyData.db")) { - // - // } - // var col = db.GetCollection("customers"); + var collection = _db.GetCollection("assets"); + + var existingAsset = collection.FindOne(x => x.Guid == guid); + if (existingAsset != null) { + existingAsset.Type = type.ToString(); + existingAsset.Path = path; + collection.Update(existingAsset); + return false; + } + + + var asset = new LibraryAsset { + Guid = guid, + Type = type.ToString(), + Path = path, + }; + + collection.EnsureIndex(x => x.Guid, true); + collection.EnsureIndex(x => x.Type); + collection.Insert(asset); + + return true; } + + public IEnumerable GetAssets() + { + var collection = _db.GetCollection("assets"); + return collection.FindAll(); + } + public void OnBeforeSerialize() { if (string.IsNullOrEmpty(LibraryRoot)) { @@ -58,6 +109,7 @@ public void OnAfterDeserialize() public class LibraryAsset { public string Guid { get; set; } - + public string Type { get; set; } + public string Path { get; set; } } } From e1c738997cfe6967347221851acfedaf696cb221 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 16 Mar 2022 00:35:30 +0100 Subject: [PATCH 016/119] assets: Reorganize code. --- .../AssetBrowser/AssetBrowserX.cs | 28 +++++++++++------ .../AssetBrowser/AssetBrowserX.uxml | 4 +-- .../AssetBrowser/AssetBrowserX_Init.cs | 30 +++++-------------- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs index 3eeb20a52..efdbf07e1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs @@ -30,14 +30,10 @@ public partial class AssetBrowserX : EditorWindow private int selectedIndex = -1; private List _assets; - - private ToolbarButton _refreshButton; - private VisualElement _rightPane; - private List _assetLibraries; [MenuItem("Visual Pinball/Asset Browser X")] - public static void Init() + public static void ShowWindow() { var wnd = GetWindow("Asset Browser X"); @@ -54,13 +50,27 @@ private void OnEnable() .Where(asset => asset != null).ToList(); } - private void Refresh() + private void Init() { _assets = _assetLibraries.SelectMany(lib => lib.GetAssets()).ToList(); - var leftPane = rootVisualElement.Q("leftPane"); - leftPane.itemsSource = _assets; - leftPane.RefreshItems(); + _rightPane.makeItem = () => new Label(); + _rightPane.bindItem = (item, index) => { + (item as Label)!.text = Path.GetFileName(_assets[index].Path); + }; + _rightPane.itemsSource = _assets; + _rightPane.onSelectionChange += OnAssetSelectionChange; + _rightPane.onSelectionChange += _ => { + selectedIndex = _rightPane.selectedIndex; + }; + _rightPane.selectedIndex = selectedIndex; + } + + private void Refresh() + { + _assets = _assetLibraries.SelectMany(lib => lib.GetAssets()).ToList(); + _rightPane.itemsSource = _assets; + _rightPane.RefreshItems(); } private void OnDragUpdatedEvent(DragUpdatedEvent evt) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml index 6840a67fe..357afaaf4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml @@ -7,7 +7,7 @@ - - + + diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs index 8f81bb77f..5cedd2ded 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs @@ -26,6 +26,10 @@ namespace VisualPinball.Unity.Editor { public partial class AssetBrowserX { + private ToolbarButton _refreshButton; + private VisualElement _leftPane; + private ListView _rightPane; + public void CreateGUI() { // import UXML @@ -38,17 +42,17 @@ public void CreateGUI() var styleSheet = AssetDatabase.LoadAssetAtPath("Packages/org.visualpinball.engine.unity/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss"); ui.styleSheets.Add(styleSheet); - InitLeftPane(ui.Q("leftPane")); - _rightPane = ui.Q("rightPane"); + _leftPane = ui.Q("leftPane"); + _rightPane = ui.Q("rightPane"); _refreshButton = ui.Q("refreshButton"); - Debug.Log("Got refresh button: " + _refreshButton); _refreshButton.clicked += Refresh; _rightPane.RegisterCallback(OnDragUpdatedEvent); _rightPane.RegisterCallback(OnDragPerformEvent); - } + Init(); + } private void OnDestroy() { @@ -61,24 +65,6 @@ private void OnDestroy() } } - private void InitLeftPane(BaseVerticalCollectionView leftPane) - { - _assets = _assetLibraries.SelectMany(lib => lib.GetAssets()).ToList(); - - leftPane.makeItem = () => new Label(); - leftPane.bindItem = (item, index) => { - (item as Label)!.text = Path.GetFileName(_assets[index].Path); - }; - leftPane.itemsSource = _assets; - leftPane.onSelectionChange += OnAssetSelectionChange; - leftPane.onSelectionChange += _ => { - selectedIndex = leftPane.selectedIndex; - }; - leftPane.selectedIndex = selectedIndex; - - leftPane.RefreshItems(); - } - private void OnAssetSelectionChange(IEnumerable selectedItems) { // // Clear all previous content from the pane From 303e9a6c63fddf0e285c3e4c3e9cfaaf924c3f12 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 17 Mar 2022 23:05:50 +0100 Subject: [PATCH 017/119] assets: Fix grid poor man's grid layout. --- .../AssetBrowser/AssetBrowserX.cs | 41 ++++++++++++------- .../AssetBrowser/AssetBrowserX.uss | 31 +++----------- .../AssetBrowser/AssetBrowserX.uxml | 11 +++-- .../AssetBrowser/AssetBrowserX_Init.cs | 19 +++++++-- 4 files changed, 54 insertions(+), 48 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs index efdbf07e1..95b53f126 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.cs @@ -18,7 +18,6 @@ using System.IO; using System.Linq; using UnityEditor; -using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; @@ -50,29 +49,41 @@ private void OnEnable() .Where(asset => asset != null).ToList(); } - private void Init() + private void Search() { _assets = _assetLibraries.SelectMany(lib => lib.GetAssets()).ToList(); + } + + private void Init() + { + Search(); - _rightPane.makeItem = () => new Label(); - _rightPane.bindItem = (item, index) => { - (item as Label)!.text = Path.GetFileName(_assets[index].Path); - }; - _rightPane.itemsSource = _assets; - _rightPane.onSelectionChange += OnAssetSelectionChange; - _rightPane.onSelectionChange += _ => { - selectedIndex = _rightPane.selectedIndex; - }; - _rightPane.selectedIndex = selectedIndex; + // _rightPane.makeItem = () => new Label(); + // _rightPane.bindItem = (item, index) => { + // (item as Label)!.text = Path.GetFileName(_assets[index].Path); + // }; + // _rightPane.itemsSource = _assets; + // _rightPane.onSelectionChange += OnAssetSelectionChange; + // _rightPane.onSelectionChange += _ => { + // selectedIndex = _rightPane.selectedIndex; + // }; + // _rightPane.selectedIndex = selectedIndex; } private void Refresh() { - _assets = _assetLibraries.SelectMany(lib => lib.GetAssets()).ToList(); - _rightPane.itemsSource = _assets; - _rightPane.RefreshItems(); + OnDestroy(); + rootVisualElement.Clear(); + CreateGUI(); + _rightPane.Clear(); + foreach (var a in _assets) { + var obj = AssetDatabase.LoadAssetAtPath(a.Path, TypeByName(a.Type)); + var tex = AssetPreview.GetAssetPreview(obj); + _rightPane.Add(new Image { image = tex }); + } } + private void OnDragUpdatedEvent(DragUpdatedEvent evt) { DragAndDrop.visualMode = DragAndDrop.objectReferences != null diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss index 808b48839..b3b4a3baa 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss @@ -1,33 +1,14 @@ -.assetGridHeaderRow { +#rightPane .unity-scroll-view__content-container { flex-direction: row; - height:22px; - align-items: center; - flex-shrink: 0; - justify-content: space-between; - padding-left:4px; - border-bottom-width: 1px; - border-color: #222; - - background-color: #3c3c3c; /* TODO (CLEANUP): This should come from the attached unity-toolbar class; but that class isn't showing up in ui debugger. not sure what I need to do... */ -} - -.leftSide { - flex-direction: row; - flex-shrink: 1; - margin-bottom:1px; + flex-wrap: wrap; } -.rightSide { - flex-direction: row; - margin-right:4px; - margin-bottom:1px; - flex-shrink: 0; +#rightPane .unity-image { + width: 200px; + height: 200px; + background-color: #1c2298; } -/***********************/ -/** Split view styles **/ -/***********************/ - ListView { flex-grow: 1; } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml index 357afaaf4..ce04467fc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml @@ -1,13 +1,16 @@ - + - + - + - + + + diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs index 5cedd2ded..cd2a597d0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using System.Collections.Generic; -using System.IO; using System.Linq; using UnityEditor; using UnityEditor.UIElements; -using UnityEngine; using UnityEngine.UIElements; namespace VisualPinball.Unity.Editor @@ -28,7 +27,9 @@ public partial class AssetBrowserX { private ToolbarButton _refreshButton; private VisualElement _leftPane; - private ListView _rightPane; + private VisualElement _rightPane; + + private static readonly Dictionary _types = new(); public void CreateGUI() { @@ -43,7 +44,7 @@ public void CreateGUI() ui.styleSheets.Add(styleSheet); _leftPane = ui.Q("leftPane"); - _rightPane = ui.Q("rightPane"); + _rightPane = ui.Q("rightPane"); _refreshButton = ui.Q("refreshButton"); _refreshButton.clicked += Refresh; @@ -85,5 +86,15 @@ private void OnAssetSelectionChange(IEnumerable selectedItems) // // Add the Image control to the right-hand pane // _rightPane?.Add(spriteImage); } + + private static Type TypeByName(string name) + { + if (_types.ContainsKey(name)) { + return _types[name]; + } + _types[name] = AppDomain.CurrentDomain.GetAssemblies().Reverse().Select(assembly => assembly.GetType(name)).FirstOrDefault(tt => tt != null); + + return _types[name]; + } } } From 549d0828ac520575030f2a41ed42eebd2a3ce790 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 18 Mar 2022 23:11:43 +0100 Subject: [PATCH 018/119] assets: Fix margins. --- .../VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss index b3b4a3baa..17f79b4a8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss @@ -1,12 +1,14 @@ #rightPane .unity-scroll-view__content-container { flex-direction: row; flex-wrap: wrap; + padding: 10px; } #rightPane .unity-image { width: 200px; height: 200px; background-color: #1c2298; + margin: 10px; } ListView { From 8d6f08a725782f6d39ea645db4e92d7f0ac9f043 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 18 Mar 2022 23:53:52 +0100 Subject: [PATCH 019/119] assets: Add bottom bar and fix colors and white space. --- .../AssetBrowser/AssetBrowserX.uss | 22 ++++++++++++++++++- .../AssetBrowser/AssetBrowserX.uxml | 8 +++++-- .../AssetBrowser/AssetBrowserX_Init.cs | 5 +++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss index 17f79b4a8..193e2be5f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uss @@ -1,3 +1,8 @@ +#rightPane { + flex-grow: 1; + background-color: #333333; /* sampled from project window */ +} + #rightPane .unity-scroll-view__content-container { flex-direction: row; flex-wrap: wrap; @@ -7,10 +12,25 @@ #rightPane .unity-image { width: 200px; height: 200px; - background-color: #1c2298; margin: 10px; } +#bottomToolbar { + justify-content: space-between; + border-top-width: 1px; + border-bottom-width: 0; + padding: 0 5px; + background-color: #383838; /* sampled from background */ +} + +#sizeSlider { + width: 75px; +} + + + + + ListView { flex-grow: 1; } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml index ce04467fc..61bae48df 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX.uxml @@ -9,8 +9,12 @@ - - + + + + + + diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs index cd2a597d0..97a11a77a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/AssetBrowser/AssetBrowserX_Init.cs @@ -28,6 +28,8 @@ public partial class AssetBrowserX private ToolbarButton _refreshButton; private VisualElement _leftPane; private VisualElement _rightPane; + private Label _bottomLabel; + private Slider _sizeSlider; private static readonly Dictionary _types = new(); @@ -46,6 +48,9 @@ public void CreateGUI() _leftPane = ui.Q("leftPane"); _rightPane = ui.Q("rightPane"); + _bottomLabel = ui.Q