From 10f8718268a7e34844ba7d59792117c28d75a99b Mon Sep 17 00:00:00 2001 From: Unity Technologies Date: Thu, 29 May 2025 09:29:54 +0000 Subject: [PATCH 1/3] Unity 6000.2.0b3 C# reference source code --- .../2D/SpriteAtlas/SpriteAtlasInspector.cs | 5 - .../Animation/AnimationUtility.bindings.cs | 6 +- .../AddCurvesPopupHierarchy.cs | 3 + .../AddCurvesPopupHierarchyBuilder.cs | 2 + .../AddCurvesPopupHierarchyDataSource.cs | 2 + .../AddCurvesPopupHierarchyGUI.cs | 3 + .../AnimationWindowHierarchy.cs | 3 + .../AnimationWindowHierarchyDataSource.cs | 5 + .../AnimationWindowHierarchyGUI.cs | 4 + .../AnimationWindowHierarchyNode.cs | 2 + .../AnimationWindow/AnimationWindowState.cs | 9 +- .../AnimationWindow/AnimationWindowUtility.cs | 4 + Editor/Mono/AssemblyInfo/AssemblyInfo.cs | 7 + Editor/Mono/AttributeHelper.cs | 2 +- .../Mixer/GUI/AudioMixerGroupTreeView.cs | 5 + .../Mono/Audio/Mixer/GUI/AudioMixerWindow.cs | 1 + .../Audio/Mixer/GUI/AudioMixersTreeView.cs | 8 + .../ReorderableListWithRenameAndScrollView.cs | 1 + .../Mixer/GUI/TreeViewForAudioMixerGroups.cs | 5 + Editor/Mono/BuildPlayerSceneTreeView.cs | 3 + Editor/Mono/BuildPlayerWindow.cs | 5 +- Editor/Mono/BuildProfile/BuildProfile.cs | 7 + .../Mono/BuildProfile/BuildProfileContext.cs | 2 +- .../BuildProfileSceneListTreeView.cs | 1 + Editor/Mono/BuildProfile/BuildProfileState.cs | 5 + Editor/Mono/BuildProfile/Events.cs | 4 +- Editor/Mono/BuildTargetDiscovery.bindings.cs | 20 +- Editor/Mono/ConsoleWindow.cs | 1 + Editor/Mono/EditorGUI.cs | 19 +- Editor/Mono/GI/Lightmapping.bindings.cs | 20 +- Editor/Mono/GUI/DockArea.cs | 69 ++- Editor/Mono/GUI/PackageExport.cs | 1 + Editor/Mono/GUI/PackageExportTreeView.cs | 7 + Editor/Mono/GUI/PackageImport.cs | 1 + Editor/Mono/GUI/PackageImportTreeView.cs | 6 + Editor/Mono/GUI/PopupWindow.cs | 2 +- Editor/Mono/GUI/RenameOverlay.cs | 12 +- .../AssetOrGameObjectTreeViewDragging.cs | 4 + .../GUI/TreeView/AssetsTreeViewDataSource.cs | 7 + Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs | 6 + .../TreeView/GameObjectTreeViewDataSource.cs | 5 + .../GUI/TreeView/GameObjectTreeViewGUI.cs | 4 + .../GUI/TreeView/GameObjectTreeViewItem.cs | 2 + .../Mono/GUI/TreeView/ITreeViewDataSource.cs | 47 +- Editor/Mono/GUI/TreeView/ITreeViewDragging.cs | 8 +- Editor/Mono/GUI/TreeView/ITreeViewGUI.cs | 15 +- .../GUI/TreeView/LazyTreeViewDataSource.cs | 34 +- Editor/Mono/GUI/TreeView/ToggleTreeView.cs | 3 + .../TreeViewControl/TreeViewControl.cs | 271 ++++++----- .../TreeViewControlDataSource.cs | 26 +- .../TreeViewControlDefaults.cs | 4 +- .../TreeViewControlDragging.cs | 16 +- .../TreeViewControl/TreeViewControlGUI.cs | 24 +- .../TreeView/TreeViewControl/TreeViewOld.cs | 402 ++++++++++++++++ .../Mono/GUI/TreeView/TreeViewController.cs | 190 ++++---- .../Mono/GUI/TreeView/TreeViewDataSource.cs | 126 ++--- Editor/Mono/GUI/TreeView/TreeViewDragging.cs | 91 ++-- .../GUI/TreeView/TreeViewExpandAnimator.cs | 22 +- Editor/Mono/GUI/TreeView/TreeViewGUI.cs | 65 +-- .../TreeViewGUIWithCustomItemHeights.cs | 4 + Editor/Mono/GUI/TreeView/TreeViewItem.cs | 48 +- .../TreeView/TreeViewTests/TreeViewTest.cs | 6 +- .../TreeViewTests/TreeViewTestDataSource.cs | 3 + .../TreeViewTests/TreeViewTestDragging.cs | 4 + .../TreeView/TreeViewTests/TreeViewTestGUI.cs | 5 + .../TreeViewTests/TreeViewTestGUICustom.cs | 2 + .../TreeViewTestLazyDataSource.cs | 4 +- .../TreeViewTestWithCustomHeight.cs | 3 +- Editor/Mono/GUI/TreeView/TreeViewUtililty.cs | 60 +-- Editor/Mono/Handles/ConeHandle.cs | 27 +- .../ImportSettings/ExposeTransformEditor.cs | 3 + Editor/Mono/Inspector/AvatarMaskInspector.cs | 3 + .../Implementations/ExposedReferenceDrawer.cs | 8 + .../Inspector/LineRendererPositionsView.cs | 3 + .../PlayerSettingsEditor.cs | 36 +- .../WebTemplateManagerBase.cs | 8 +- Editor/Mono/Inspector/UnityEventDrawer.cs | 21 +- .../Modules/DefaultBuildProfileExtension.cs | 6 +- .../PlayerConnection/ConnectionDropDown.cs | 3 + Editor/Mono/ObjectListArea.cs | 1 + Editor/Mono/ObjectListLocalGroup.cs | 1 + Editor/Mono/ObjectNames.cs | 1 + Editor/Mono/ObjectSelector.cs | 19 +- Editor/Mono/ObjectTreeForSelector.cs | 4 + Editor/Mono/Overlays/Overlay.cs | 87 +++- Editor/Mono/Overlays/OverlayCanvas.cs | 31 +- Editor/Mono/Overlays/OverlayPlacement.cs | 2 +- Editor/Mono/Overlays/OverlayPopup.cs | 265 +++++------ Editor/Mono/Overlays/OverlayUtilities.cs | 20 +- Editor/Mono/PerformanceTools/FrameDebugger.cs | 13 + .../PerformanceTools/FrameDebuggerTreeView.cs | 5 + Editor/Mono/PlayerSettings.bindings.cs | 16 + .../PrefabOverridesTreeView.cs | 5 +- .../PrefabOverrides/PrefabOverridesWindow.cs | 1 + .../PresetLibraries/PresetLibraryEditor.cs | 1 + Editor/Mono/Progress/AssemblyInfo.cs | 6 + Editor/Mono/ProjectBrowser/ProjectBrowser.cs | 2 + .../ProjectBrowser/ProjectBrowserColumnOne.cs | 5 + .../Mono/ProjectBrowser/SavedSearchFilter.cs | 3 + ...raphicsSettingsCollectionPropertyDrawer.cs | 10 +- ...nderPipelineGraphicsSettingsContextMenu.cs | 188 ++++++-- Editor/Mono/SceneHierarchy.cs | 10 +- Editor/Mono/SceneHierarchyStageHandling.cs | 2 + .../StageManager/PrefabStage/PrefabStage.cs | 1 + .../Mono/SceneView/SceneOrientationGizmo.cs | 13 +- Editor/Mono/SceneView/SceneView.cs | 43 +- Editor/Mono/SceneView/SceneViewViewpoint.cs | 21 +- .../SceneVisibilityHierarchyGUI.cs | 2 + .../SerializedPropertyTable.cs | 1 + .../SerializedPropertyTreeView.cs | 4 + Editor/Mono/Settings/SettingsTreeView.cs | 3 + Editor/Mono/Settings/SettingsWindow.cs | 1 + .../Drawers/Internal/UnityEventItem.cs | 8 +- External/NiceIO/NiceIO.cs | 2 + .../builds/lib/net40/Unity.Cecil.Mdb.dll | Bin 44544 -> 44544 bytes .../builds/lib/net40/Unity.Cecil.Pdb.dll | Bin 88064 -> 88064 bytes .../builds/lib/net40/Unity.Cecil.Rocks.dll | Bin 28672 -> 28672 bytes .../builds/lib/net40/Unity.Cecil.dll | Bin 350720 -> 351232 bytes .../AnimationStreamHandles.bindings.cs | 85 +++- .../Editor/V2/Managed/ImportActivityWindow.cs | 4 +- .../ImportSettings/AssetImporterEditor.cs | 2 +- .../ModelImporterMaterialEditor.cs | 5 + .../BuildProfileEditor/BuildProfileWindow.cs | 21 +- .../Elements/BuildProfileSceneList.cs | 1 + Modules/BuildProfileEditor/Events.cs | 10 +- .../Handlers/BuildProfileDataSource.cs | 4 +- .../PlatformDiscoveryWindow.cs | 7 +- .../Controls/AIDropdownContent.cs | 30 +- .../EditorToolbar/Controls/LoadingSpinner.cs | 58 +++ .../ToolbarElements/AIDropdown.cs | 4 - Modules/IMGUI/GUIStyle.bindings.cs | 1 + Modules/IMGUI/GUIUtility.cs | 8 +- Modules/IMGUI/IMGUITextHandle.cs | 6 +- Modules/IMGUI/TextEditor.cs | 11 +- .../Editor/Managed/PackageManager.bindings.cs | 2 + .../Editor/External/SemVersionExtension.cs | 6 +- .../Editor/Services/Upm/UpmPackageData.cs | 2 + .../Editor/Services/Upm/UpmPackageVersion.cs | 10 +- .../Editor/UI/PackageManagerWindow.cs | 4 +- .../ParticleSystemEditor/ParticleEffectUI.cs | 14 +- .../ScriptBindings/Physics2D.bindings.cs | 9 +- Modules/PhysicsEditor/PhysicsDebugWindow.cs | 7 +- .../PhysicsEditor/PhysicsManagerInspector.cs | 24 +- .../PresetsUIEditor/PresetSearchProvider.cs | 6 +- .../ProfilerDetailedCallsView.cs | 3 + .../ProfilerDetailedObjectsView.cs | 3 + .../ProfilerFrameDataTreeView.cs | 3 + .../ProfilerFrameHierarchyView.cs | 1 + .../Audio/AudioProfilerView.cs | 8 + .../FileIO/AssetLoadingProfilerView.cs | 1 + .../FileIO/AssetMarkerTreeView.cs | 3 + .../FileIO/FileAccessTreeView.cs | 3 + .../FileIO/FileIOProfilerView.cs | 1 + .../FileIO/FileSummaryTreeView.cs | 3 + .../ProfilerModules/uGui/UISystemProfiler.cs | 1 + .../uGui/UISystemProfilerTreeView.cs | 3 + .../Editor/Indexing/SearchDatabase.cs | 2 - .../PropertyDatabase/PropertyDatabaseStore.cs | 3 + .../Editor/Providers/FindProvider.cs | 32 +- .../Editor/QueryBuilder/QuerySelector.cs | 22 +- Modules/QuickSearch/Editor/SearchMonitor.cs | 2 - Modules/QuickSearch/Editor/SearchUtils.cs | 2 +- .../QuickSearch/Editor/Table/ITableView.cs | 19 +- Modules/QuickSearch/Editor/UI/Icons.cs | 14 +- .../Editor/UITK/SearchDetailView.cs | 2 +- .../Editor/UITK/SearchEmptyView.cs | 2 +- Modules/SceneView/SceneViewToolbarElements.cs | 8 + .../ShortcutManagerWindowView.cs | 4 +- .../ConflictResolverWindow.cs | 3 + Modules/ShortcutManagerEditor/PromptWindow.cs | 6 +- .../SketchUpEditor/Mono/SketchUpImportDlg.cs | 5 + .../TerrainTransientToolbarOverlay.cs | 14 +- .../PaintTools/PaintDetailsTool.cs | 9 + .../PaintTools/PaintTreesTool.cs | 9 + .../TerrainEditor/PaintTools/SetHeightTool.cs | 2 +- Modules/TerrainEditor/TerrainInspector.cs | 82 +--- .../Managed/FontEngine.bindings.cs | 22 + .../Managed/MeshInfo.bindings.cs | 2 +- .../TextCoreTextEngine/Managed/MeshInfo.cs | 292 +----------- .../Managed/TextAssets/FontAsset.cs | 39 +- .../FontAsset/FontAssetAtlasPopulation.cs | 2 +- .../TextAssets/FontAsset/FontAssetFactory.cs | 2 +- .../Managed/TextAssets/FontAssetUtilities.cs | 30 ++ .../Managed/TextElementInfo.cs | 4 +- .../Managed/TextGenerator.cs | 12 +- .../TextGenerator/TextGenerationSettings.cs | 138 ++---- .../TextGenerator/TextGeneratorCommon.cs | 4 +- .../TextGeneratorHtmlTagValidation.cs | 117 +++-- .../TextGenerator/TextGeneratorInternal.cs | 196 +------- .../TextGenerator/TextGeneratorLayout.cs | 170 +------ .../TextGenerator/TextGeneratorParsing.cs | 197 +++----- .../TextGeneratorPreferredValues.cs | 71 ++- .../TextGenerator/TextGeneratorPrepare.cs | 43 +- .../TextGenerator/TextGeneratorUtilities.cs | 217 +-------- .../TextCoreTextEngine/Managed/TextHandle.cs | 76 ++- .../Managed/TextHandlePermanentCache.cs | 2 +- .../Managed/TextHandleTemporaryCache.cs | 2 +- .../TextCoreTextEngine/Managed/TextInfo.cs | 73 +-- .../Managed/TextShaderUtilities.cs | 13 +- .../Managed/FontAssetCreatorWindow.cs | 6 +- .../Managed/FontAssetEditor.cs | 14 +- .../UxmlBatchedChangesController.cs | 441 ++++++++++++++++++ .../Draggers/BuilderStyleSheetsDragger.cs | 3 + .../Binding/BuilderBindingUtility.cs | 1 + .../Builder/Inspector/BuilderInspector.cs | 10 +- .../Inspector/BuilderInspectorStyleFields.cs | 23 +- .../Utilities/BuilderCommandHandler.cs | 6 + .../Utilities/BuilderElementContextMenu.cs | 3 +- .../BuilderUxmlAttributesView.cs | 367 +++++---------- .../IBatchedUxmlChangesListener.cs | 18 + .../Core/BackgroundPropertyHelper.cs | 3 + .../Core/Bindings/DataBindingManager.cs | 9 +- .../DynamicHeightVirtualizationController.cs | 34 +- .../FixedHeightVirtualizationController.cs | 37 +- .../VerticalVirtualizationController.cs | 28 ++ .../Core/Controls/BasePopupField.cs | 15 +- .../Controls/BaseVerticalCollectionView.cs | 3 +- Modules/UIElements/Core/Controls/Image.cs | 4 + .../Core/Controls/InputField/BaseField.cs | 2 + .../MultiColumnCollectionHeader.cs | 32 +- .../MultiColumn/MultiColumnController.cs | 7 + .../Core/Controls/RadioButtonGroup.cs | 38 +- .../UIElements/Core/Controls/ScrollView.cs | 2 + .../Core/DragAndDrop/DragEventsProcessor.cs | 30 +- .../DragAndDrop/ListViewDraggerAnimated.cs | 6 +- Modules/UIElements/Core/FocusController.cs | 3 + .../DefaultEventSystem.InputForUIProcessor.cs | 32 +- .../Core/GameObjects/PanelSettings.cs | 31 +- .../Core/GameObjects/RuntimePanelUtils.cs | 3 +- .../UIElements/Core/GameObjects/UIDocument.cs | 173 ++++++- Modules/UIElements/Core/IMGUIContainer.cs | 7 +- .../UIElements/Core/Layout/LayoutManager.cs | 35 +- Modules/UIElements/Core/Panel.cs | 6 + .../Core/Renderer/UIRLayoutUpdater.cs | 42 +- .../Core/Renderer/UIRMeshGenerationContext.cs | 4 + .../Core/Renderer/UIRMeshGenerator.cs | 4 +- .../Core/Style/Generated/ComputedStyle.cs | 25 - .../Core/Style/Generated/IResolvedStyle.cs | 4 +- .../Core/Style/Generated/StylePropertyUtil.cs | 2 +- Modules/UIElements/Core/Style/IStyle.cs | 4 + Modules/UIElements/Core/StyleEnums.cs | 8 + .../UIElements/Core/StylePropertyAnimation.cs | 2 +- .../Core/StylePropertyAnimationSystem.cs | 6 +- Modules/UIElements/Core/Text/ATGTextHandle.cs | 5 +- .../UIElements/Core/Text/UITKTextHandle.cs | 5 - Modules/UIElements/Core/TextElement.cs | 52 ++- Modules/UIElements/Core/TextElementEdition.cs | 10 +- .../Core/UIElementsRuntimeUtility.cs | 30 +- Modules/UIElements/Core/UIElementsUtility.cs | 2 +- .../UIElements/Core/UXML/UxmlAttributes.cs | 1 + Modules/UIElements/Core/VisualElement.cs | 24 +- .../UIElements/Core/VisualElementHierarchy.cs | 30 ++ .../Core/VisualTreeHierarchyFlagsUpdater.cs | 2 +- Modules/UIElementsEditor/ATGAnalytics.cs | 48 ++ .../SerializedObjectBindingContext.cs | 53 ++- .../SerializedObjectReferenceBinding.cs | 4 +- .../Bindings/SerializedPropertyHelper.cs | 6 +- .../Debugger/OverlayPainter.cs | 13 +- .../Debugger/PanelDebugger.cs | 1 + .../Debugger/StylesDebugger.cs | 79 +--- .../Debugger/UIElementsDebugger.cs | 323 ++++++++++++- .../Delegates/EditorDelegateRegistration.cs | 7 +- .../Inspector/UIDocumentInspector.cs | 11 +- .../UIElementsEditor/Text/TextInfoOverlay.cs | 427 ++++++----------- .../UIToolkitProjectSettings.cs | 21 + .../UIToolkitSettingsProvider.cs | 8 + .../UXML/UxmlSerializedDataCreator.cs | 7 +- .../Snippets/ListViewSnippet.cs | 11 +- .../Snippets/MultiColumnListViewSnippet.cs | 18 +- .../Snippets/MultiColumnTreeViewSnippet.cs | 28 +- .../Snippets/TreeViewSnippet.cs | 16 +- .../VisualEffectResource.bindings.cs | 2 + Projects/CSharp/UnityEditor.csproj | 20 +- README.md | 2 +- .../Animation/AnimationCurve.bindings.cs | 35 +- Runtime/Export/AssemblyInfo.cs | 8 + Runtime/Export/Graphics/GraphicsEnums.cs | 10 +- Runtime/Export/Math/Gradient.bindings.cs | 57 ++- .../RenderPipeline/RenderPipelineManager.cs | 45 +- .../Export/Unsafe/UnsafeUtility.bindings.cs | 15 + .../ProfilerUnsafeUtility.bindings.cs | 34 ++ .../BeeDriver2/Bee.BeeDriver2.dll | Bin 120320 -> 120320 bytes .../Unity.CompilationPipeline.Common.dll | Bin 283 files changed, 4835 insertions(+), 3196 deletions(-) create mode 100644 Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewOld.cs create mode 100644 Editor/Mono/Progress/AssemblyInfo.cs create mode 100644 Modules/EditorToolbar/Controls/LoadingSpinner.cs create mode 100644 Modules/UIBuilder/Editor/Builder/Controllers/UxmlBatchedChangesController.cs create mode 100644 Modules/UIBuilder/Editor/Builder/UxmlAttributesView/IBatchedUxmlChangesListener.cs create mode 100644 Modules/UIElementsEditor/ATGAnalytics.cs rename artifacts/Stevedore/{unity-compiler-win-x64_666e => unity-compiler-win-x64_34ed}/Unity.CompilationPipeline.Common/Unity.CompilationPipeline.Common.dll (100%) diff --git a/Editor/Mono/2D/SpriteAtlas/SpriteAtlasInspector.cs b/Editor/Mono/2D/SpriteAtlas/SpriteAtlasInspector.cs index 9620e4ac71..cebb1e79ff 100644 --- a/Editor/Mono/2D/SpriteAtlas/SpriteAtlasInspector.cs +++ b/Editor/Mono/2D/SpriteAtlas/SpriteAtlasInspector.cs @@ -132,7 +132,6 @@ private enum AtlasType { Undefined = -1, Master = 0, Variant = 1 } private string m_Hash; private int m_PreviewPage = 0; private int m_TotalPages = 0; - const float kPrefixLabelWidth = 290f; private int[] m_OptionValues = null; private string[] m_OptionDisplays = null; private Texture2D[] m_PreviewTextures = null; @@ -365,9 +364,6 @@ public override void OnInspectorGUI() serializedObject.Update(); - var oldWidth = EditorGUIUtility.labelWidth; - EditorGUIUtility.labelWidth = kPrefixLabelWidth; - HandleCommonSettingUI(); GUILayout.Space(EditorGUI.kSpacing); @@ -418,7 +414,6 @@ public override void OnInspectorGUI() } } - EditorGUIUtility.labelWidth = oldWidth; serializedObject.ApplyModifiedProperties(); } diff --git a/Editor/Mono/Animation/AnimationUtility.bindings.cs b/Editor/Mono/Animation/AnimationUtility.bindings.cs index 28e6a2a34b..0b40f052e6 100644 --- a/Editor/Mono/Animation/AnimationUtility.bindings.cs +++ b/Editor/Mono/Animation/AnimationUtility.bindings.cs @@ -188,11 +188,11 @@ internal static System.Type GetEditorCurveValueType(ScriptableObject scriptableO extern public static bool GetDiscreteIntValue([NotNull] GameObject root, EditorCurveBinding binding, out int data); public static bool GetObjectReferenceValue(GameObject root, EditorCurveBinding binding, out Object data) { - data = Internal_GetObjectReferenceValue(root, binding); - return data != null; + data = Internal_GetObjectReferenceValue(root, binding, out bool result); + return result; } - extern private static Object Internal_GetObjectReferenceValue([NotNull] GameObject root, EditorCurveBinding binding); + extern private static Object Internal_GetObjectReferenceValue([NotNull] GameObject root, EditorCurveBinding binding, out bool result); extern public static Object GetAnimatedObject([NotNull] GameObject root, EditorCurveBinding binding); diff --git a/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchy.cs b/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchy.cs index 4adb9ff208..cd32c12f4d 100644 --- a/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchy.cs +++ b/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchy.cs @@ -5,6 +5,9 @@ using UnityEditor; using UnityEditor.IMGUI.Controls; using UnityEngine; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditorInternal { diff --git a/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyBuilder.cs b/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyBuilder.cs index 55a8c81379..51618a0dbd 100644 --- a/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyBuilder.cs +++ b/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyBuilder.cs @@ -9,6 +9,8 @@ using System.Linq; using UnityEditor.IMGUI.Controls; using Object = UnityEngine.Object; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; namespace UnityEditorInternal { diff --git a/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyDataSource.cs b/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyDataSource.cs index 312076b97d..cb9654a3ff 100644 --- a/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyDataSource.cs +++ b/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyDataSource.cs @@ -4,6 +4,8 @@ using UnityEditor; using UnityEditor.IMGUI.Controls; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewDataSource = UnityEditor.IMGUI.Controls.TreeViewDataSource; namespace UnityEditorInternal { diff --git a/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyGUI.cs b/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyGUI.cs index b1b39169dc..bd964f16b6 100644 --- a/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyGUI.cs +++ b/Editor/Mono/Animation/AnimationWindow/AddCurvesPopupHierarchyGUI.cs @@ -7,6 +7,9 @@ using UnityEngine; using System.Collections.Generic; using UnityEditor.ShortcutManagement; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; namespace UnityEditorInternal { diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchy.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchy.cs index 634f44d4e2..a5e353264b 100644 --- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchy.cs +++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchy.cs @@ -6,6 +6,9 @@ using UnityEditor; using System.Collections.Generic; using UnityEditor.IMGUI.Controls; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditorInternal { diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyDataSource.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyDataSource.cs index 9352c8c9d7..00dbb47ccd 100644 --- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyDataSource.cs +++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyDataSource.cs @@ -7,6 +7,11 @@ using UnityEditor.IMGUI.Controls; using UnityEngine; using Object = UnityEngine.Object; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; +using TreeViewDataSource = UnityEditor.IMGUI.Controls.TreeViewDataSource; + namespace UnityEditorInternal { diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyGUI.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyGUI.cs index c525aec8b5..af65ed17fd 100644 --- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyGUI.cs +++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyGUI.cs @@ -9,6 +9,10 @@ using System.Linq; using UnityEditor.IMGUI.Controls; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; + namespace UnityEditorInternal { internal class AnimationWindowHierarchyGUI : TreeViewGUI diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyNode.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyNode.cs index bcd960f940..833ebd9bc4 100644 --- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyNode.cs +++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowHierarchyNode.cs @@ -6,6 +6,8 @@ using UnityEngine; using System.Collections.Generic; using UnityEditor.IMGUI.Controls; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; + namespace UnityEditorInternal { diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowState.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowState.cs index 1aa918d1b0..6de5dd2e79 100644 --- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowState.cs +++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowState.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using UnityEditor.IMGUI.Controls; using Object = UnityEngine.Object; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; namespace UnityEditorInternal { @@ -903,14 +904,14 @@ public CurveWrapper[] activeCurveWrappers { List activeCurveWrappers = new List(); foreach (AnimationWindowCurve curve in activeCurves) - if (!curve.isDiscreteCurve) - activeCurveWrappers.Add(AnimationWindowUtility.GetCurveWrapper(curve, curve.clip)); + if (AnimationWindowUtility.GetCurveWrapper(curve, curve.clip) is CurveWrapper wrapper) + activeCurveWrappers.Add(wrapper); // If there are no active curves, we would end up with empty curve editor so we just give all curves insteads if (!activeCurveWrappers.Any()) foreach (AnimationWindowCurve curve in filteredCurves) - if (!curve.isDiscreteCurve) - activeCurveWrappers.Add(AnimationWindowUtility.GetCurveWrapper(curve, curve.clip)); + if (AnimationWindowUtility.GetCurveWrapper(curve, curve.clip) is CurveWrapper wrapper) + activeCurveWrappers.Add(wrapper); m_ActiveCurveWrappersCache = activeCurveWrappers.ToArray(); } diff --git a/Editor/Mono/Animation/AnimationWindow/AnimationWindowUtility.cs b/Editor/Mono/Animation/AnimationWindow/AnimationWindowUtility.cs index 09e02c7084..df9a25a1a8 100644 --- a/Editor/Mono/Animation/AnimationWindow/AnimationWindowUtility.cs +++ b/Editor/Mono/Animation/AnimationWindow/AnimationWindowUtility.cs @@ -1279,6 +1279,10 @@ private static CurveWrapper.PreProcessKeyMovement CreateKeyPreprocessorForCurve( public static CurveWrapper GetCurveWrapper(AnimationWindowCurve curve, AnimationClip clip) { + //Discrete and PPtr curves are not allowed to create curve wrappers. + if (curve.isDiscreteCurve || curve.isPPtrCurve) + return null; + CurveWrapper curveWrapper = new CurveWrapper(); curveWrapper.renderer = CreateRendererForCurve(curve); curveWrapper.preProcessKeyMovementDelegate = CreateKeyPreprocessorForCurve(curve); diff --git a/Editor/Mono/AssemblyInfo/AssemblyInfo.cs b/Editor/Mono/AssemblyInfo/AssemblyInfo.cs index 4845bebebe..5a99613788 100644 --- a/Editor/Mono/AssemblyInfo/AssemblyInfo.cs +++ b/Editor/Mono/AssemblyInfo/AssemblyInfo.cs @@ -35,6 +35,7 @@ [assembly: InternalsVisibleTo("Unity.PureCSharpTests")] [assembly: InternalsVisibleTo("Unity.IntegrationTests")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.Android")] +[assembly: InternalsVisibleTo("Unity.IntegrationTests.Android.CommonUtils")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.Animation")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.AssetImporting")] [assembly: InternalsVisibleTo("Unity.IntegrationTests.BuildPipeline")] @@ -199,9 +200,15 @@ [assembly: InternalsVisibleTo("Unity.GraphToolsAuthoringFramework.InternalEditorBridge")] // Module test assemblies +[assembly: InternalsVisibleTo("Unity.Modules.iOSExtensions.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Modules.Licensing.Tests.Editor")] +[assembly: InternalsVisibleTo("Unity.Modules.PlatformIcons.Tests.Editor")] // This should move with the AnimationWindow to a module at some point [assembly: InternalsVisibleTo("Unity.Modules.Animation.AnimationWindow.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Modules.Physics.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.Tests.Shared")] +// Test Assemblies +[assembly: InternalsVisibleTo("Unity.Core.UnityEvent.Tests.Editor")] +[assembly: InternalsVisibleTo("Unity.Core.Scripting.AssemblyVersion.Tests.Editor")] + diff --git a/Editor/Mono/AttributeHelper.cs b/Editor/Mono/AttributeHelper.cs index 95d72e45d3..2719d77a50 100644 --- a/Editor/Mono/AttributeHelper.cs +++ b/Editor/Mono/AttributeHelper.cs @@ -112,7 +112,7 @@ static MonoGizmoMethod[] ExtractGizmos(Assembly assembly) } [RequiredByNativeCode] - static string GetComponentMenuName(Type type) + static object GetComponentMenuName(Type type) { var attrs = type.GetCustomAttributes(typeof(AddComponentMenu), false); if (attrs.Length > 0) diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixerGroupTreeView.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixerGroupTreeView.cs index cd6ce63f34..f0f9a7aa30 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixerGroupTreeView.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixerGroupTreeView.cs @@ -11,6 +11,11 @@ using UnityEditor.Audio; using UnityEditor.IMGUI.Controls; using Object = UnityEngine.Object; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; +using TreeViewDataSource = UnityEditor.IMGUI.Controls.TreeViewDataSource; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs index 925f4f8075..f9f6f8381e 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixerWindow.cs @@ -10,6 +10,7 @@ using UnityEditor.Audio; using UnityEditor.IMGUI.Controls; using RequiredByNativeCodeAttribute = UnityEngine.Scripting.RequiredByNativeCodeAttribute; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/Audio/Mixer/GUI/AudioMixersTreeView.cs b/Editor/Mono/Audio/Mixer/GUI/AudioMixersTreeView.cs index c76b2cc774..7682fb265f 100644 --- a/Editor/Mono/Audio/Mixer/GUI/AudioMixersTreeView.cs +++ b/Editor/Mono/Audio/Mixer/GUI/AudioMixersTreeView.cs @@ -12,6 +12,14 @@ using UnityEditor.IMGUI.Controls; using UnityEngine.Audio; using Object = UnityEngine.Object; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; +using TreeViewDragging = UnityEditor.IMGUI.Controls.TreeViewDragging; +using TreeViewDataSource = UnityEditor.IMGUI.Controls.TreeViewDataSource; +using TreeViewItemAlphaNumericSort = UnityEditor.IMGUI.Controls.TreeViewItemAlphaNumericSort; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/Audio/Mixer/GUI/ReorderableListWithRenameAndScrollView.cs b/Editor/Mono/Audio/Mixer/GUI/ReorderableListWithRenameAndScrollView.cs index 35856f88a7..3dc0abfae2 100644 --- a/Editor/Mono/Audio/Mixer/GUI/ReorderableListWithRenameAndScrollView.cs +++ b/Editor/Mono/Audio/Mixer/GUI/ReorderableListWithRenameAndScrollView.cs @@ -5,6 +5,7 @@ using UnityEngine; using UnityEditor; using System; +using RenameOverlay = UnityEditor.RenameOverlay; namespace UnityEditorInternal { diff --git a/Editor/Mono/Audio/Mixer/GUI/TreeViewForAudioMixerGroups.cs b/Editor/Mono/Audio/Mixer/GUI/TreeViewForAudioMixerGroups.cs index 6c06fbcaa7..089900dd25 100644 --- a/Editor/Mono/Audio/Mixer/GUI/TreeViewForAudioMixerGroups.cs +++ b/Editor/Mono/Audio/Mixer/GUI/TreeViewForAudioMixerGroups.cs @@ -8,6 +8,11 @@ using System.Collections.Generic; using UnityEditor.IMGUI.Controls; using UnityEngine.Audio; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; +using TreeViewDataSource = UnityEditor.IMGUI.Controls.TreeViewDataSource; + namespace UnityEditor { diff --git a/Editor/Mono/BuildPlayerSceneTreeView.cs b/Editor/Mono/BuildPlayerSceneTreeView.cs index 19a5695959..783ec04149 100644 --- a/Editor/Mono/BuildPlayerSceneTreeView.cs +++ b/Editor/Mono/BuildPlayerSceneTreeView.cs @@ -6,6 +6,9 @@ using System.Collections.Generic; using System.IO; using UnityEditor.IMGUI.Controls; +using TreeView = UnityEditor.IMGUI.Controls.TreeView; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/BuildPlayerWindow.cs b/Editor/Mono/BuildPlayerWindow.cs index 96e7e90327..dc53720206 100644 --- a/Editor/Mono/BuildPlayerWindow.cs +++ b/Editor/Mono/BuildPlayerWindow.cs @@ -21,6 +21,7 @@ using UnityEditor.Connect; using UnityEditor.Utils; using UnityEditor.Build.Profile; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { @@ -220,13 +221,13 @@ public BuildPlayerWindow() BuildPlayerSceneTreeView m_TreeView; [SerializeField] - IMGUI.Controls.TreeViewState m_TreeViewState; + TreeViewState m_TreeViewState; void ActiveScenesGUI() { if (m_TreeView == null) { if (m_TreeViewState == null) - m_TreeViewState = new IMGUI.Controls.TreeViewState(); + m_TreeViewState = new TreeViewState(); m_TreeView = new BuildPlayerSceneTreeView(m_TreeViewState); m_TreeView.Reload(); } diff --git a/Editor/Mono/BuildProfile/BuildProfile.cs b/Editor/Mono/BuildProfile/BuildProfile.cs index 78c49d6f6e..591568d85c 100644 --- a/Editor/Mono/BuildProfile/BuildProfile.cs +++ b/Editor/Mono/BuildProfile/BuildProfile.cs @@ -403,6 +403,13 @@ void ValidateDataConsistency() } CheckSceneListConsistency(); + + // On disk changes to active profile may change platform guid. + // Specifically copying the entire YAML of a valid build profile. + if (this == BuildProfileContext.activeProfile && platformGuid != EditorUserBuildSettings.activePlatformGuid) + { + EditorUserBuildSettings.SwitchActiveBuildTargetGuid(this); + } } /// diff --git a/Editor/Mono/BuildProfile/BuildProfileContext.cs b/Editor/Mono/BuildProfile/BuildProfileContext.cs index bc5edaaec5..f33b55afca 100644 --- a/Editor/Mono/BuildProfile/BuildProfileContext.cs +++ b/Editor/Mono/BuildProfile/BuildProfileContext.cs @@ -153,7 +153,7 @@ internal void ClearPackageAddInfo(BuildProfile profile) } } - string GetProfileGUID(BuildProfile profile) + static string GetProfileGUID(BuildProfile profile) { var profilePath = AssetDatabase.GetAssetPath(profile); var profileGuid = AssetDatabase.AssetPathToGUID(profilePath); diff --git a/Editor/Mono/BuildProfile/BuildProfileSceneListTreeView.cs b/Editor/Mono/BuildProfile/BuildProfileSceneListTreeView.cs index 3be7cc31a8..4b07d9d534 100644 --- a/Editor/Mono/BuildProfile/BuildProfileSceneListTreeView.cs +++ b/Editor/Mono/BuildProfile/BuildProfileSceneListTreeView.cs @@ -8,6 +8,7 @@ using UnityEngine; using UnityEngine.Bindings; using UnityEngine.SceneManagement; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor.Build.Profile { diff --git a/Editor/Mono/BuildProfile/BuildProfileState.cs b/Editor/Mono/BuildProfile/BuildProfileState.cs index 7e0753d06f..1654b04f14 100644 --- a/Editor/Mono/BuildProfile/BuildProfileState.cs +++ b/Editor/Mono/BuildProfile/BuildProfileState.cs @@ -67,6 +67,11 @@ public BuildProfileWorkflowState(Action onStateChange /// public ActionState buildAndRunAction { get; set; } = ActionState.Enabled; + /// + /// Allows invoking of Cloud Build for the selected profile. + /// + public ActionState buildInCloudPackageAction { get; set; } = ActionState.Enabled; + /// /// Additional actions shown in the Build Profile Window as generally defined by the Build Profile Extension. /// diff --git a/Editor/Mono/BuildProfile/Events.cs b/Editor/Mono/BuildProfile/Events.cs index ca6d8cb4c0..9ddd66afc4 100644 --- a/Editor/Mono/BuildProfile/Events.cs +++ b/Editor/Mono/BuildProfile/Events.cs @@ -20,7 +20,7 @@ internal struct Payload : IAnalytic.IData /// /// Platform ID of the target build profile. /// - public GUID platformId; + public string platformId; /// /// Platform display name of the target build profile. @@ -60,7 +60,7 @@ public static void SendBuildProfile() EditorAnalytics.SendAnalytic(new BuildProfileBuildTimeEvent(new BuildProfileBuildTimeEvent.Payload { - platformId = profile.platformGuid, + platformId = profile.platformId, platformDisplayName = BuildProfileModuleUtil.GetClassicPlatformDisplayName(profile.platformGuid), profileAssetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(profile)) })); diff --git a/Editor/Mono/BuildTargetDiscovery.bindings.cs b/Editor/Mono/BuildTargetDiscovery.bindings.cs index 481bd784dd..182d7e3f10 100644 --- a/Editor/Mono/BuildTargetDiscovery.bindings.cs +++ b/Editor/Mono/BuildTargetDiscovery.bindings.cs @@ -256,7 +256,7 @@ public PlatformInfo() {} static GUID EmptyGuid = new GUID(""); - static Dictionary s_PlatformGUIDDataQuickLookup = new Dictionary(); + static Dictionary s_BuildTargetToPlatformGUID = new Dictionary(); // This list should not be exposed ouside of BuildTargetDiscovery to avoid NDA spillage, provide a access function for data here instead. // Changes here should be synced with the usage of @@ -662,10 +662,7 @@ public static GUID GetGUIDFromBuildTarget(NamedBuildTarget namedBuildTarget, Bui /// The platform GUID. Derived platform GUID when the active platform is a derived platform. Base platform GUID otherwise. public static GUID GetGUIDFromBuildTarget(BuildTarget buildTarget) { - if (buildTarget == BuildTarget.StandaloneWindows) //workaround for win64 and win having the same guid in new Build Target system - buildTarget = BuildTarget.StandaloneWindows64; - - if (s_PlatformGUIDDataQuickLookup.TryGetValue(buildTarget, out GUID value)) + if (s_BuildTargetToPlatformGUID.TryGetValue(buildTarget, out GUID value)) { var module = ModuleManager.FindPlatformSupportModule(value); if (module != null && module is IDerivedBuildTargetProvider) @@ -704,7 +701,7 @@ internal static GUID GetBasePlatformGUIDFromBuildTarget(NamedBuildTarget namedBu if (TryGetServerGUIDFromBuildTarget(namedBuildTarget, buildTarget, out var value)) return value; - if (s_PlatformGUIDDataQuickLookup.TryGetValue(buildTarget, out GUID guid)) + if (s_BuildTargetToPlatformGUID.TryGetValue(buildTarget, out GUID guid)) return guid; return EmptyGuid; @@ -723,7 +720,7 @@ internal static GUID GetBasePlatformGUID(GUID platformGuid) if (!platformInfo.HasFlag(PlatformAttributes.IsDerivedBuildTarget)) return platformGuid; - if (s_PlatformGUIDDataQuickLookup.TryGetValue(platformInfo.buildTarget, out GUID basePlatformGuid)) + if (s_BuildTargetToPlatformGUID.TryGetValue(platformInfo.buildTarget, out GUID basePlatformGuid)) return basePlatformGuid; return EmptyGuid; @@ -741,12 +738,15 @@ static void PreloadBuildPlatformInstalledData() { foreach (var platform in allPlatforms) { + // Capture BuildTarget to GUID mapping for all platforms. + // Considers that StandaloneWindows and StandaloneWindows64 are the same platform. if (platform.Value.buildTarget != BuildTarget.StandaloneWindows && platform.Value.subtarget != StandaloneBuildSubtarget.Server - && !platform.Value.HasFlag(PlatformAttributes.IsDerivedBuildTarget) - ) //workaround for win64 and win having the same guid in new Build Target system and for derived build targets + && !platform.Value.HasFlag(PlatformAttributes.IsDerivedBuildTarget)) { - s_PlatformGUIDDataQuickLookup.Add(platform.Value.buildTarget, platform.Key); + s_BuildTargetToPlatformGUID.Add(platform.Value.buildTarget, platform.Key); + if (platform.Value.buildTarget == BuildTarget.StandaloneWindows64) + s_BuildTargetToPlatformGUID.Add(BuildTarget.StandaloneWindows, platform.Key); } var playbackEngineDirectory = BuildPipeline.GetPlaybackEngineDirectory(platform.Value.buildTarget, BuildOptions.None, false); diff --git a/Editor/Mono/ConsoleWindow.cs b/Editor/Mono/ConsoleWindow.cs index 11e3fc40df..1dce794d1d 100644 --- a/Editor/Mono/ConsoleWindow.cs +++ b/Editor/Mono/ConsoleWindow.cs @@ -746,6 +746,7 @@ const bool { SetActiveEntry(entry); m_LastActiveEntryIndex = entry.globalLineIndex; + m_TextScroll = Vector2.zero; activeEntryChanged?.Invoke(); } diff --git a/Editor/Mono/EditorGUI.cs b/Editor/Mono/EditorGUI.cs index fe7b603a76..5a47df25a7 100644 --- a/Editor/Mono/EditorGUI.cs +++ b/Editor/Mono/EditorGUI.cs @@ -2012,12 +2012,11 @@ public ScrollableAreaScope(int id, ref Rect position, string text, ref Vector2 s this.style = style; this.scrollPosition = scrollPosition; + position = IndentedRect(position); float fullTextHeight = style.CalcHeight(GUIContent.Temp(text), position.width); Rect viewRect = new Rect(0, 0, position.width, fullTextHeight); oldScrollValue = style.contentOffset; - - position = IndentedRect(position); if (position.height < viewRect.height) { //Scroll bar position @@ -2082,7 +2081,23 @@ internal static void ScrollableLabelAreaInternal(Rect position, string text, ref RecycledTextEditor.s_AllowContextCutOrPaste = false; if (sendEventToTextEditor) + { + bool isMouseDown = Event.current.rawType == EventType.MouseDown && Event.current.button == 0; + bool isEditingControl = s_RecycledEditor.IsEditingControl(id); + DoTextField(s_RecycledEditor, id, position, text, style, string.Empty, out _, false, true, false); + + if (isMouseDown && Event.current.type == EventType.Used) + { + // We just took control over the Scrollable label + if (!isEditingControl && s_RecycledEditor.IsEditingControl(id)) + { + // Properly set the scroll offset as it was set to 0 in the editor.BeginEditing + // Move the recycled Editor offset to match our scrollbar + s_RecycledEditor.scrollOffset = scrollPosition; + } + } + } } //Only update the out scrollPosition if the user has interacted with the TextArea (the current event was used) diff --git a/Editor/Mono/GI/Lightmapping.bindings.cs b/Editor/Mono/GI/Lightmapping.bindings.cs index 112fbb67cc..9fc30918f9 100644 --- a/Editor/Mono/GI/Lightmapping.bindings.cs +++ b/Editor/Mono/GI/Lightmapping.bindings.cs @@ -241,12 +241,24 @@ internal static FilterMode filterMode // Starts an asynchronous bake job. [FreeFunction] - public static extern bool BakeAsync(); + internal static extern bool BakeAsyncImpl(); - // Stars a synchronous bake job. + // Starts a synchronous bake job. [FreeFunction] - public static extern bool Bake(); + internal static extern bool BakeImpl(); + + public static bool BakeAsync() + { + RenderPipelineManager.TryPrepareRenderPipeline(GraphicsSettings.currentRenderPipeline); + return BakeAsyncImpl(); + } + public static bool Bake() + { + RenderPipelineManager.TryPrepareRenderPipeline(GraphicsSettings.currentRenderPipeline); + return BakeImpl(); + } + // Cancels the currently running asynchronous bake job. [FreeFunction("CancelLightmapping")] public static extern void Cancel(); @@ -716,6 +728,7 @@ public static bool extractAmbientOcclusion public static bool BakeAsync(Scene targetScene) { + RenderPipelineManager.TryPrepareRenderPipeline(GraphicsSettings.currentRenderPipeline); return BakeSceneAsync(targetScene); } @@ -726,6 +739,7 @@ public static bool BakeAsync(Scene targetScene) public static bool Bake(Scene targetScene) { + RenderPipelineManager.TryPrepareRenderPipeline(GraphicsSettings.currentRenderPipeline); return BakeScene(targetScene); } diff --git a/Editor/Mono/GUI/DockArea.cs b/Editor/Mono/GUI/DockArea.cs index b228143302..3a59e157fe 100644 --- a/Editor/Mono/GUI/DockArea.cs +++ b/Editor/Mono/GUI/DockArea.cs @@ -4,10 +4,8 @@ using System; using UnityEngine; -using System.Collections; using System.Collections.Generic; using System.Linq; -using System.IO; using UnityEditor.StyleSheets; using UnityEditor.Experimental; using UnityEditorInternal; @@ -103,6 +101,7 @@ private static bool s_HasStaticTabsCapability private float m_HoldScrollOffset; private double m_HoldScrollTimestamp; private Rect m_TabAreaRect = Rect.zero; + private int? newlyAddedTabIndex = null; internal int pendingSelect = -1; internal int pendingSelectVersion = 0; @@ -209,6 +208,11 @@ public void AddTab(int idx, EditorWindow pane, bool sendPaneEvents = true) Invoke("OnAddedAsTab", pane); Repaint(); window?.UnsavedStateChanged(); + + // Make sure the newly added tab is visible. + // We can skip the first one to gain some performance. + if (idx > 0) + newlyAddedTabIndex = idx; } public void RemoveTab(EditorWindow pane) { RemoveTab(pane, killIfEmpty: true); } @@ -358,6 +362,12 @@ protected override void OldOnGUI() if (window == null) return; + if (newlyAddedTabIndex.HasValue) + { + EnsureNewlyAddedTabIsVisible(newlyAddedTabIndex.Value); + newlyAddedTabIndex = null; + } + if (actualView) GUI.color = actualView.rootVisualElement.playModeTintColor; @@ -774,6 +784,61 @@ private int GetTabAtMousePos(GUIStyle tabStyle, Vector2 mousePos, Rect tabAreaRe return -1; } + void EnsureNewlyAddedTabIsVisible(int index) + { + if (m_TabAreaRect.xMax == 0.0f) + return; + + if (index < 0 || index >= m_Panes.Count) + return; + + // Get the X position and width of the selected tab. + var selectedTabX = CalculateTabXPosition(index); + var selectedTabWidth = GetTabWidth(Styles.dragTab, index); + + // Calculate the left and right edges of the tab. + var leftEdge = selectedTabX; + var rightEdge = selectedTabX + selectedTabWidth; + + // Adjust the scroll offset if the tab is outside the visible range. + if (leftEdge < m_TabAreaRect.xMin + m_ScrollOffset) + { + m_ScrollOffset = leftEdge - m_TabAreaRect.xMin; + } + else if (rightEdge > m_TabAreaRect.xMax + m_ScrollOffset) + { + m_ScrollOffset = rightEdge - m_TabAreaRect.xMax; + } + } + + float CalculateTabXPosition(int index) + { + var xPos = m_TabAreaRect.xMin; + for (var i = 0; i < index; i++) + { + float tabWidth = GetTabWidth(Styles.dragTab, i); + xPos += tabWidth; + } + + return xPos; + } + + // internal method for testing. + internal bool IsTabVisible(int index) + { + var tabPosition = CalculateTabXPosition(index); + var tabWidth = GetTabWidth(Styles.dragTab, index); + + // Calculate the left and right edges of the tab. + var leftEdge = tabPosition; + var rightEdge = tabPosition + tabWidth; + + if (leftEdge >= m_TabAreaRect.xMin + m_ScrollOffset && rightEdge <= m_TabAreaRect.xMax + m_ScrollOffset) + return true; + + return false; + } + // Hack to get around Unity crashing when we have circular references in saved stuff internal override void Initialize(ContainerWindow win) { diff --git a/Editor/Mono/GUI/PackageExport.cs b/Editor/Mono/GUI/PackageExport.cs index d5e85c0af1..5f10cd897c 100644 --- a/Editor/Mono/GUI/PackageExport.cs +++ b/Editor/Mono/GUI/PackageExport.cs @@ -11,6 +11,7 @@ using UnityEngine.Analytics; using UnityEngine.Scripting; using UnityEngine.UIElements; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/GUI/PackageExportTreeView.cs b/Editor/Mono/GUI/PackageExportTreeView.cs index af69826ed1..a6a26f0bac 100644 --- a/Editor/Mono/GUI/PackageExportTreeView.cs +++ b/Editor/Mono/GUI/PackageExportTreeView.cs @@ -12,6 +12,13 @@ using UnityEditorInternal; using UnityEditor.Experimental; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; +using TreeViewDataSource = UnityEditor.IMGUI.Controls.TreeViewDataSource; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; + namespace UnityEditor { internal class PackageExportTreeView diff --git a/Editor/Mono/GUI/PackageImport.cs b/Editor/Mono/GUI/PackageImport.cs index 60f8ccd2ab..f9737fa9c1 100644 --- a/Editor/Mono/GUI/PackageImport.cs +++ b/Editor/Mono/GUI/PackageImport.cs @@ -8,6 +8,7 @@ using UnityEditor.IMGUI.Controls; using UnityEngine; using UnityEngine.Scripting; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/GUI/PackageImportTreeView.cs b/Editor/Mono/GUI/PackageImportTreeView.cs index 3aae22adb0..a2426d5182 100644 --- a/Editor/Mono/GUI/PackageImportTreeView.cs +++ b/Editor/Mono/GUI/PackageImportTreeView.cs @@ -11,6 +11,12 @@ using UnityEngine; using UnityEditorInternal; using UnityEditor.Experimental; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; +using TreeViewDataSource = UnityEditor.IMGUI.Controls.TreeViewDataSource; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/GUI/PopupWindow.cs b/Editor/Mono/GUI/PopupWindow.cs index abad91694e..944e5bd75e 100644 --- a/Editor/Mono/GUI/PopupWindow.cs +++ b/Editor/Mono/GUI/PopupWindow.cs @@ -79,7 +79,7 @@ internal static void Show(Rect activatorRect, PopupWindowContent windowContent, { win.Init(activatorRect, windowContent, locationPriorityOrder, showMode, true); } - if (Event.current != null) + if (Event.current != null && !GUIUtility.isUITK) { EditorGUIUtility.ExitGUI(); // Needed to prevent GUILayout errors on OSX } diff --git a/Editor/Mono/GUI/RenameOverlay.cs b/Editor/Mono/GUI/RenameOverlay.cs index dff6fae5a0..b6cdfd9c6b 100644 --- a/Editor/Mono/GUI/RenameOverlay.cs +++ b/Editor/Mono/GUI/RenameOverlay.cs @@ -19,8 +19,10 @@ namespace UnityEditor // OnEvent () - Should be called early in an OnGUI of an EditorWindow that is using this RenameOverlay (handles closing if clicking outside and closing while receving any input while delayed, and caches controlID for text field) // OnGUI (GUIStyle textFieldStyle) - Should be called late to ensure rendered on top and early for non-repaint event to handle input before other ui logic + internal class RenameOverlay : RenameOverlay{} + [System.Serializable] - internal class RenameOverlay + internal class RenameOverlay { [SerializeField] bool m_UserAcceptedRename; @@ -31,7 +33,7 @@ internal class RenameOverlay [SerializeField] Rect m_EditFieldRect; [SerializeField] - int m_UserData; + TValue m_UserData; [SerializeField] bool m_IsWaitingForDelay; [SerializeField] @@ -56,7 +58,7 @@ internal class RenameOverlay public string name { get {return m_Name; } internal set { m_Name = value; } } public string originalName { get {return m_OriginalName; }} public bool userAcceptedRename { get {return m_UserAcceptedRename; }} - public int userData { get {return m_UserData; }} + public TValue userData { get {return m_UserData; }} public bool isWaitingForDelay { get {return m_IsWaitingForDelay; }} public Rect editFieldRect { get {return m_EditFieldRect; } set {m_EditFieldRect = value; }} public bool isRenamingFilename {get {return m_IsRenamingFilename; } set {m_IsRenamingFilename = value; }} @@ -71,7 +73,7 @@ public bool trimLeadingAndTrailingWhitespace private int m_TextFieldControlID; // Returns true if started renaming - public bool BeginRename(string name, int userData, float delay) + public bool BeginRename(string name, TValue userData, float delay) { if (m_IsRenaming) { @@ -154,7 +156,7 @@ public void Clear() m_Name = ""; m_OriginalName = ""; m_EditFieldRect = new Rect(); - m_UserData = 0; + m_UserData = default; m_IsWaitingForDelay = false; m_OriginalEventType = EventType.Ignore; Undo.undoRedoEvent -= UndoRedoWasPerformed; diff --git a/Editor/Mono/GUI/TreeView/AssetOrGameObjectTreeViewDragging.cs b/Editor/Mono/GUI/TreeView/AssetOrGameObjectTreeViewDragging.cs index 040e596a46..20b82ec5cf 100644 --- a/Editor/Mono/GUI/TreeView/AssetOrGameObjectTreeViewDragging.cs +++ b/Editor/Mono/GUI/TreeView/AssetOrGameObjectTreeViewDragging.cs @@ -13,6 +13,10 @@ using UnityEngine.Assertions; using Object = UnityEngine.Object; +using TreeViewDragging = UnityEditor.IMGUI.Controls.TreeViewDragging; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; + namespace UnityEditor { // Implements dragging behavior for HierarchyProperty based data: Assets or GameObjects diff --git a/Editor/Mono/GUI/TreeView/AssetsTreeViewDataSource.cs b/Editor/Mono/GUI/TreeView/AssetsTreeViewDataSource.cs index 7871eaea45..fd088bdd81 100644 --- a/Editor/Mono/GUI/TreeView/AssetsTreeViewDataSource.cs +++ b/Editor/Mono/GUI/TreeView/AssetsTreeViewDataSource.cs @@ -13,6 +13,13 @@ using UnityEditor.Experimental; using AssetReference = UnityEditorInternal.InternalEditorUtility.AssetReference; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using LazyTreeViewDataSource = UnityEditor.IMGUI.Controls.LazyTreeViewDataSource; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; +using TreeViewSelectState = UnityEditor.IMGUI.Controls.TreeViewSelectState; + + namespace UnityEditor { // AssetsTreeViewDataSource only fetches current visible items of the asset database tree, because we derive from LazyTreeViewDataSource diff --git a/Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs b/Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs index 9473b54b09..63d0ed788b 100644 --- a/Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs +++ b/Editor/Mono/GUI/TreeView/AssetsTreeViewGUI.cs @@ -14,6 +14,12 @@ using static UnityEditor.AssetsTreeViewDataSource; using static UnityEditorInternal.InternalEditorUtility; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; + + namespace UnityEditor { internal class AssetsTreeViewGUI : TreeViewGUI diff --git a/Editor/Mono/GUI/TreeView/GameObjectTreeViewDataSource.cs b/Editor/Mono/GUI/TreeView/GameObjectTreeViewDataSource.cs index ddef1e8721..8596e7275b 100644 --- a/Editor/Mono/GUI/TreeView/GameObjectTreeViewDataSource.cs +++ b/Editor/Mono/GUI/TreeView/GameObjectTreeViewDataSource.cs @@ -12,6 +12,11 @@ using UnityEngine.Assertions; using UnityEngine.Profiling; using Object = UnityEngine.Object; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using LazyTreeViewDataSource = UnityEditor.IMGUI.Controls.LazyTreeViewDataSource; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; +using TreeViewItemAlphaNumericSort = UnityEditor.IMGUI.Controls.TreeViewItemAlphaNumericSort; namespace UnityEditor { diff --git a/Editor/Mono/GUI/TreeView/GameObjectTreeViewGUI.cs b/Editor/Mono/GUI/TreeView/GameObjectTreeViewGUI.cs index c84038c285..cb121a9438 100644 --- a/Editor/Mono/GUI/TreeView/GameObjectTreeViewGUI.cs +++ b/Editor/Mono/GUI/TreeView/GameObjectTreeViewGUI.cs @@ -14,6 +14,10 @@ using UnityEngine; using UnityEngine.SceneManagement; using Object = UnityEngine.Object; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; + namespace UnityEditor { diff --git a/Editor/Mono/GUI/TreeView/GameObjectTreeViewItem.cs b/Editor/Mono/GUI/TreeView/GameObjectTreeViewItem.cs index 3817e6c94a..3f832bdf4f 100644 --- a/Editor/Mono/GUI/TreeView/GameObjectTreeViewItem.cs +++ b/Editor/Mono/GUI/TreeView/GameObjectTreeViewItem.cs @@ -5,6 +5,8 @@ using UnityEditor.IMGUI.Controls; using UnityEngine; using UnityEngine.SceneManagement; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; + namespace UnityEditor { diff --git a/Editor/Mono/GUI/TreeView/ITreeViewDataSource.cs b/Editor/Mono/GUI/TreeView/ITreeViewDataSource.cs index d8486cfc8b..4be8a4833f 100644 --- a/Editor/Mono/GUI/TreeView/ITreeViewDataSource.cs +++ b/Editor/Mono/GUI/TreeView/ITreeViewDataSource.cs @@ -2,6 +2,7 @@ // Copyright (c) Unity Technologies. For terms of use, see // https://unity3d.com/legal/licenses/Unity_Reference_Only_License +using System; using System.Collections.Generic; using UnityEngine; @@ -15,12 +16,12 @@ namespace UnityEditor.IMGUI.Controls { // Represents a complete data tree - internal interface ITreeViewDataSource + internal interface ITreeViewDataSource where TIdentifier : unmanaged, System.IEquatable { void OnInitialize(); // Return root of tree - TreeViewItem root { get; } + TreeViewItem root { get; } // For data sources where GetRows() might be an expensive operation int rowCount { get; } @@ -31,44 +32,44 @@ internal interface ITreeViewDataSource void InitIfNeeded(); // Find Item by id - TreeViewItem FindItem(int id); + TreeViewItem FindItem(TIdentifier id); // Get current row of an item (using the current expanded state in TreeViewState) // Returns -1 if not found - int GetRow(int id); + int GetRow(TIdentifier id); // Check rowCount before requesting - TreeViewItem GetItem(int row); + TreeViewItem GetItem(int row); // Get the flattened tree of visible items. If possible use GetItem(int row) instead - IList GetRows(); + IList> GetRows(); - bool IsRevealed(int id); + bool IsRevealed(TIdentifier id); - void RevealItem(int id); - void RevealItems(int[] ids); + void RevealItem(TIdentifier id); + void RevealItems(TIdentifier[] ids); // Expand / collapse interface // The DataSource has the interface for this because it should be able to rebuild // tree when expanding - void SetExpandedWithChildren(TreeViewItem item, bool expand); - void SetExpanded(TreeViewItem item, bool expand); - bool IsExpanded(TreeViewItem item); - bool IsExpandable(TreeViewItem item); - void SetExpandedWithChildren(int id, bool expand); - int[] GetExpandedIDs(); - void SetExpandedIDs(int[] ids); - bool SetExpanded(int id, bool expand); - bool IsExpanded(int id); + void SetExpandedWithChildren(TreeViewItem item, bool expand); + void SetExpanded(TreeViewItem item, bool expand); + bool IsExpanded(TreeViewItem item); + bool IsExpandable(TreeViewItem item); + void SetExpandedWithChildren(TIdentifier id, bool expand); + TIdentifier[] GetExpandedIDs(); + void SetExpandedIDs(TIdentifier[] ids); + bool SetExpanded(TIdentifier id, bool expand); + bool IsExpanded(TIdentifier id); // Selection - bool CanBeMultiSelected(TreeViewItem item); - bool CanBeParent(TreeViewItem item); - List GetNewSelection(TreeViewItem clickedItem, TreeViewSelectState selectState); + bool CanBeMultiSelected(TreeViewItem item); + bool CanBeParent(TreeViewItem item); + List GetNewSelection(TreeViewItem clickedItem, TreeViewSelectState selectState); // Renaming - bool IsRenamingItemAllowed(TreeViewItem item); - void InsertFakeItem(int id, int parentID, string name, Texture2D icon); + bool IsRenamingItemAllowed(TreeViewItem item); + void InsertFakeItem(TIdentifier id, TIdentifier parentID, string name, Texture2D icon); void RemoveFakeItem(); bool HasFakeItem(); diff --git a/Editor/Mono/GUI/TreeView/ITreeViewDragging.cs b/Editor/Mono/GUI/TreeView/ITreeViewDragging.cs index f7fad5c91f..f8dbdb00c4 100644 --- a/Editor/Mono/GUI/TreeView/ITreeViewDragging.cs +++ b/Editor/Mono/GUI/TreeView/ITreeViewDragging.cs @@ -16,12 +16,12 @@ namespace UnityEditor.IMGUI.Controls // DragNDrop interface for tree views - internal interface ITreeViewDragging + internal interface ITreeViewDragging { void OnInitialize(); - bool CanStartDrag(TreeViewItem targetItem, List draggedItemIDs, Vector2 mouseDownPosition); - void StartDrag(TreeViewItem draggedItem, List draggedItemIDs); - bool DragElement(TreeViewItem targetItem, Rect targetItemRect, int row); // 'targetItem' is null when not hovering over any target Item. Returns true if drag was handled. + bool CanStartDrag(TreeViewItem targetItem, List draggedItemIDs, Vector2 mouseDownPosition); + void StartDrag(TreeViewItem draggedItem, List draggedItemIDs); + bool DragElement(TreeViewItem targetItem, Rect targetItemRect, int row); // 'targetItem' is null when not hovering over any target Item. Returns true if drag was handled. void DragCleanup(bool revertExpanded); int GetDropTargetControlID(); int GetRowMarkerControlID(); diff --git a/Editor/Mono/GUI/TreeView/ITreeViewGUI.cs b/Editor/Mono/GUI/TreeView/ITreeViewGUI.cs index 5a58489427..2ad929f095 100644 --- a/Editor/Mono/GUI/TreeView/ITreeViewGUI.cs +++ b/Editor/Mono/GUI/TreeView/ITreeViewGUI.cs @@ -2,6 +2,7 @@ // Copyright (c) Unity Technologies. For terms of use, see // https://unity3d.com/legal/licenses/Unity_Reference_Only_License +using System; using UnityEngine; // The TreeView requires implementations from the following three interfaces: @@ -13,7 +14,7 @@ namespace UnityEditor.IMGUI.Controls { - internal interface ITreeViewGUI + internal interface ITreeViewGUI where TIdentifier : unmanaged, System.IEquatable { void OnInitialize(); @@ -29,23 +30,23 @@ internal interface ITreeViewGUI Rect GetRowRect(int row, float rowWidth); Rect GetRectForFraming(int row); - int GetNumRowsOnPageUpDown(TreeViewItem fromItem, bool pageUp, float heightOfTreeView); + int GetNumRowsOnPageUpDown(TreeViewItem fromItem, bool pageUp, float heightOfTreeView); // OnGUI: Implement to handle TreeView OnGUI - void OnRowGUI(Rect rowRect, TreeViewItem item, int row, bool selected, bool focused); + void OnRowGUI(Rect rowRect, TreeViewItem item, int row, bool selected, bool focused); void BeginRowGUI(); // use for e.g clearing state before OnRowGUI calls void EndRowGUI(); // use for handling stuff after all rows have had their OnRowGUI // Ping Item interface (implement a rendering of a 'ping' for a Item). - void BeginPingItem(TreeViewItem item, float topPixelOfRow, float availableWidth); + void BeginPingItem(TreeViewItem item, float topPixelOfRow, float availableWidth); void EndPingItem(); // Rename interface (BeginRename should return true if rename is handled) - bool BeginRename(TreeViewItem item, float delay); + bool BeginRename(TreeViewItem item, float delay); void EndRename(); - Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item); + Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item); - float GetContentIndent(TreeViewItem item); + float GetContentIndent(TreeViewItem item); float halfDropBetweenHeight { get; } float topRowMargin { get; } diff --git a/Editor/Mono/GUI/TreeView/LazyTreeViewDataSource.cs b/Editor/Mono/GUI/TreeView/LazyTreeViewDataSource.cs index 738e569928..78553d83be 100644 --- a/Editor/Mono/GUI/TreeView/LazyTreeViewDataSource.cs +++ b/Editor/Mono/GUI/TreeView/LazyTreeViewDataSource.cs @@ -16,16 +16,16 @@ namespace UnityEditor.IMGUI.Controls // // Note: if dealing with small trees consider using TreeViewDataSource instead: it assumes that the tree contains all items. - internal abstract class LazyTreeViewDataSource : TreeViewDataSource + internal abstract class LazyTreeViewDataSource : TreeViewDataSource where TIdentifier : unmanaged, System.IEquatable { - static readonly List s_ChildListForCollapsedParent = new List(); + static readonly List> s_ChildListForCollapsedParent = new List>(); - public LazyTreeViewDataSource(TreeViewController treeView) + public LazyTreeViewDataSource(TreeViewController treeView) : base(treeView) { } - public static List CreateChildListForCollapsedParent() + public static List> CreateChildListForCollapsedParent() { // To mark a collapsed parent we use a list with one element that is null. // The null element in the children list ensures we show the collapse arrow. @@ -38,21 +38,21 @@ public static List CreateChildListForCollapsedParent() return s_ChildListForCollapsedParent; } - public static bool IsChildListForACollapsedParent(IList childList) + public static bool IsChildListForACollapsedParent(IList> childList) { return (childList != null && childList.Count == 1 && childList[0] == null); // see CreateChildListForCollapsedParent } // Return all ancestor items of the Item with 'id' - protected abstract void GetParentsAbove(int id, HashSet parentsAbove); + protected abstract void GetParentsAbove(TIdentifier id, HashSet parentsAbove); // Return all descendant items that have children from the Item with 'id' - protected abstract void GetParentsBelow(int id, HashSet parentsBelow); + protected abstract void GetParentsBelow(TIdentifier id, HashSet parentsBelow); - override public void RevealItem(int itemID) + override public void RevealItem(TIdentifier itemID) { // Get existing expanded in hashset - HashSet expandedSet = new HashSet(expandedIDs); + HashSet expandedSet = new HashSet(expandedIDs); int orgSize = expandedSet.Count; // Add all parents above id @@ -69,10 +69,10 @@ override public void RevealItem(int itemID) } } - override public void RevealItems(int[] itemIDs) + override public void RevealItems(TIdentifier[] itemIDs) { // Get existing expanded in hashset - HashSet expandedSet = new HashSet(expandedIDs); + HashSet expandedSet = new HashSet(expandedIDs); int orgSize = expandedSet.Count; foreach (var itemID in itemIDs) @@ -90,7 +90,7 @@ override public void RevealItems(int[] itemIDs) } } - override public TreeViewItem FindItem(int itemID) + override public TreeViewItem FindItem(TIdentifier itemID) { // Since this is a LazyTreeViewDataSource that only knows about expanded items // we need to reveal the item before searching for it (expand its ancestors) @@ -100,7 +100,7 @@ override public TreeViewItem FindItem(int itemID) return base.FindItem(itemID); } - override public void SetExpandedWithChildren(TreeViewItem item, bool expand) + override public void SetExpandedWithChildren(TreeViewItem item, bool expand) { SetExpandedWithChildren(item.id, expand); } @@ -108,13 +108,13 @@ override public void SetExpandedWithChildren(TreeViewItem item, bool expand) // Override for special handling of recursion // We cannot recurse normally to tree Item children because we have not loaded children of collapsed items // therefore let client implement GetParentsBelow to fetch ids instead - override public void SetExpandedWithChildren(int id, bool expand) + override public void SetExpandedWithChildren(TIdentifier id, bool expand) { // Get existing expanded in hashset - HashSet oldExpandedSet = new HashSet(expandedIDs); + HashSet oldExpandedSet = new HashSet(expandedIDs); // Add all children expanded ids to hashset - HashSet candidates = new HashSet(); + HashSet candidates = new HashSet(); GetParentsBelow(id, candidates); if (expand) oldExpandedSet.UnionWith(candidates); @@ -144,7 +144,7 @@ public override void InitIfNeeded() } // Get the flattened tree of visible items. Use GetFirstAndLastRowVisible to cull invisible items - override public IList GetRows() + override public IList> GetRows() { InitIfNeeded(); return m_Rows; diff --git a/Editor/Mono/GUI/TreeView/ToggleTreeView.cs b/Editor/Mono/GUI/TreeView/ToggleTreeView.cs index 5b7fa7c612..10ca027863 100644 --- a/Editor/Mono/GUI/TreeView/ToggleTreeView.cs +++ b/Editor/Mono/GUI/TreeView/ToggleTreeView.cs @@ -8,6 +8,9 @@ using UnityEditor; using UnityEditor.IMGUI.Controls; using UnityEngine; +using TreeView = UnityEditor.IMGUI.Controls.TreeView; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; internal abstract class ToggleTreeViewItem : TreeViewItem { diff --git a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControl.cs b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControl.cs index d981fa2618..e19401fffe 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControl.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControl.cs @@ -19,10 +19,10 @@ namespace UnityEditor.IMGUI.Controls // - Override the virtual methods for further customization (rendering, dragging, renaming etc) // - Adjust layout properties - public abstract partial class TreeView + public abstract partial class TreeView where TIdentifier : unmanaged, System.IEquatable { public delegate bool DoFoldoutCallback(Rect position, bool expandedState, GUIStyle style); - public delegate List GetNewSelectionFunction(TreeViewItem clickedItem, bool keepMultiSelection, bool useActionKeyAsShift); + public delegate List GetNewSelectionFunction(TreeViewItem clickedItem, bool keepMultiSelection, bool useActionKeyAsShift); protected GetNewSelectionFunction getNewSelectionOverride { @@ -38,34 +38,34 @@ internal bool deselectOnUnhandledMouseDown } } - TreeViewController m_TreeView; + internal TreeViewController m_TreeView; TreeViewControlDataSource m_DataSource; TreeViewControlGUI m_GUI; TreeViewControlDragging m_Dragging; MultiColumnHeader m_MultiColumnHeader; - List m_DefaultRows; + List> m_DefaultRows; int m_TreeViewKeyControlID; OverriddenMethods m_OverriddenMethods; protected DoFoldoutCallback foldoutOverride { get; set; } - public TreeView(TreeViewState state) + public TreeView(TreeViewState state) { Init(state); } - public TreeView(TreeViewState state, MultiColumnHeader multiColumnHeader) + public TreeView(TreeViewState state, MultiColumnHeader multiColumnHeader) { m_MultiColumnHeader = multiColumnHeader; Init(state); } - void Init(TreeViewState state) + void Init(TreeViewState state) { if (state == null) throw new ArgumentNullException("state", "Invalid TreeViewState: it is null"); - m_TreeView = new TreeViewController(null, state); + m_TreeView = new TreeViewController(null, state); m_DataSource = new TreeViewControlDataSource(m_TreeView, this); m_GUI = new TreeViewControlGUI(m_TreeView, this); m_Dragging = new TreeViewControlDragging(m_TreeView, this); @@ -93,15 +93,16 @@ void Init(TreeViewState state) // b) Override BuildRows to handle how the rows are generated: Create the rows list // only visiting expanded items. Also override GetAncestors and GetDescendantsWithChildren // to use the backend data to fetch this information (since it might not be available in the TreeView) - protected abstract TreeViewItem BuildRoot(); + protected abstract TreeViewItem BuildRoot(); // Default implementation of BuildRows assumes full tree was built in BuildRoot. With full tree we can also support search out of the box - protected virtual IList BuildRows(TreeViewItem root) + protected virtual IList> BuildRows(TreeViewItem root) => BuildRowsInternal(root); + internal virtual IList> BuildRowsInternal(TreeViewItem root) { // Reuse cached list (for capacity) if (m_DefaultRows == null) - m_DefaultRows = new List(100); + m_DefaultRows = new List>(100); m_DefaultRows.Clear(); if (hasSearch) @@ -123,18 +124,18 @@ public void Repaint() m_TreeView.Repaint(); } - public TreeViewState state { get { return m_TreeView.state; } } + public TreeViewState state { get { return m_TreeView.state; } } public MultiColumnHeader multiColumnHeader { get { return m_MultiColumnHeader; } set { m_MultiColumnHeader = value; }} // internal for testing - internal TreeViewController controller => m_TreeView; + internal TreeViewController controller => m_TreeView; - protected TreeViewItem rootItem + protected TreeViewItem rootItem { get { return m_TreeView.data.root; } } - protected TreeViewItem hoveredItem + protected TreeViewItem hoveredItem { get { return m_TreeView.hoveredItem; } } @@ -261,7 +262,9 @@ protected Rect GetRowRect(int row) return m_TreeView.gui.GetRowRect(row, GUIClip.visibleRect.width); } - public virtual IList GetRows() + public virtual IList> GetRows() => GetRowsInternal(); + + internal virtual IList> GetRowsInternal() { if (!isInitialized) return null; @@ -269,17 +272,17 @@ public virtual IList GetRows() return m_TreeView.data.GetRows(); } - protected IList FindRows(IList ids) + protected IList> FindRows(IList ids) { return GetRows().Where(item => ids.Contains(item.id)).ToList(); } - protected TreeViewItem FindItem(int id, TreeViewItem searchFromThisItem) + protected TreeViewItem FindItem(TIdentifier id, TreeViewItem searchFromThisItem) { - return TreeViewUtility.FindItem(id, searchFromThisItem); + return TreeViewUtility.FindItem(id, searchFromThisItem); } - protected int FindRowOfItem(TreeViewItem item) + protected int FindRowOfItem(TreeViewItem item) { return GetRows().IndexOf(item); } @@ -297,30 +300,30 @@ public void ExpandAll() public void CollapseAll() { - SetExpanded(new int[0]); + SetExpanded(new TIdentifier[0]); } - public void SetExpandedRecursive(int id, bool expanded) + public void SetExpandedRecursive(TIdentifier id, bool expanded) { m_DataSource.SetExpandedWithChildren(id, expanded); } - public bool SetExpanded(int id, bool expanded) + public bool SetExpanded(TIdentifier id, bool expanded) { return m_DataSource.SetExpanded(id, expanded); } - public void SetExpanded(IList ids) + public void SetExpanded(IList ids) { m_DataSource.SetExpandedIDs(ids.ToArray()); } - public IList GetExpanded() + public IList GetExpanded() { return m_DataSource.GetExpandedIDs(); } - public bool IsExpanded(int id) + public bool IsExpanded(TIdentifier id) { return m_DataSource.IsExpanded(id); } @@ -338,17 +341,17 @@ public string searchString } // Selection interface - public IList GetSelection() + public IList GetSelection() { return m_TreeView.GetSelection(); } - public void SetSelection(IList selectedIDs) + public void SetSelection(IList selectedIDs) { SetSelection(selectedIDs, TreeViewSelectionOptions.None); } - public void SetSelection(IList selectedIDs, TreeViewSelectionOptions options) + public void SetSelection(IList selectedIDs, TreeViewSelectionOptions options) { bool fireSelectionChanged = (options & TreeViewSelectionOptions.FireSelectionChanged) != 0; bool revealSelectionAndFrameLastSelected = (options & TreeViewSelectionOptions.RevealAndFrame) != 0; @@ -359,7 +362,7 @@ public void SetSelection(IList selectedIDs, TreeViewSelectionOptions option m_TreeView.NotifyListenersThatSelectionChanged(); } - public bool IsSelected(int id) + public bool IsSelected(TIdentifier id) { return m_TreeView.IsSelected(id); } @@ -393,18 +396,18 @@ public void SetFocusAndEnsureSelectedItem() } } - protected void SelectionClick(TreeViewItem item, bool keepMultiSelection) + protected void SelectionClick(TreeViewItem item, bool keepMultiSelection) { m_TreeView.SelectionClick(item, keepMultiSelection); } // Rename interface - public bool BeginRename(TreeViewItem item) + public bool BeginRename(TreeViewItem item) { return BeginRename(item, 0f); } - public bool BeginRename(TreeViewItem item, float delay) + public bool BeginRename(TreeViewItem item, float delay) { return m_GUI.BeginRename(item, delay); } @@ -415,7 +418,7 @@ public void EndRename() } // Frame interface - public void FrameItem(int id) + public void FrameItem(TIdentifier id) { bool animated = false; m_TreeView.Frame(id, true, false, animated); @@ -478,17 +481,17 @@ void TreeViewWithMultiColumnHeader(Rect rect) // GUI helper methods (for custon drawing) - protected float GetFoldoutIndent(TreeViewItem item) + protected float GetFoldoutIndent(TreeViewItem item) { return m_GUI.GetFoldoutIndent(item); } - protected float GetContentIndent(TreeViewItem item) + protected float GetContentIndent(TreeViewItem item) { return m_GUI.GetContentIndent(item); } - protected IList SortItemIDsInRowOrder(IList ids) + protected IList SortItemIDsInRowOrder(IList ids) { return m_TreeView.SortIDsInVisiblityOrder(ids); } @@ -503,7 +506,7 @@ protected void CenterRectUsingSingleLineHeight(ref Rect rect) } } - protected void AddExpandedRows(TreeViewItem root, IList rows) + protected void AddExpandedRows(TreeViewItem root, IList> rows) { if (root == null) throw new ArgumentNullException("root", "root is null"); @@ -512,35 +515,35 @@ protected void AddExpandedRows(TreeViewItem root, IList rows) throw new ArgumentNullException("rows", "rows is null"); if (root.hasChildren) - foreach (TreeViewItem child in root.children) + foreach (TreeViewItem child in root.children) GetExpandedRowsRecursive(child, rows); } - void GetExpandedRowsRecursive(TreeViewItem item, IList expandedRows) + void GetExpandedRowsRecursive(TreeViewItem item, IList> expandedRows) { if (item == null) - Debug.LogError("Found a TreeViewItem that is null. Invalid use of AddExpandedRows(): This method is only valid to call if you have built the full tree of TreeViewItems."); + Debug.LogError("Found a TreeViewItem that is null. Invalid use of AddExpandedRows(): This method is only valid to call if you have built the full tree of TreeViewItems."); expandedRows.Add(item); if (item.hasChildren && IsExpanded(item.id)) - foreach (TreeViewItem child in item.children) + foreach (TreeViewItem child in item.children) GetExpandedRowsRecursive(child, expandedRows); } - protected virtual void SelectionChanged(IList selectedIds) + protected virtual void SelectionChanged(IList selectedIds) { } - protected virtual void SingleClickedItem(int id) + protected virtual void SingleClickedItem(TIdentifier id) { } - protected virtual void DoubleClickedItem(int id) + protected virtual void DoubleClickedItem(TIdentifier id) { } - protected virtual void ContextClickedItem(int id) + protected virtual void ContextClickedItem(TIdentifier id) { } @@ -561,43 +564,47 @@ protected virtual void KeyEvent() } // Used to reveal an item - protected virtual IList GetAncestors(int id) + protected virtual IList GetAncestors(TIdentifier id) { var item = FindItem(id); if (item == null) - return new List(); + return new List(); // Default behavior assumes complete tree - HashSet parentsAbove = new HashSet(); - TreeViewUtility.GetParentsAboveItem(item, parentsAbove); + HashSet parentsAbove = new HashSet(); + TreeViewUtility.GetParentsAboveItem(item, parentsAbove); return parentsAbove.ToArray(); } // Used to expand children recursively below an item - protected virtual IList GetDescendantsThatHaveChildren(int id) + protected virtual IList GetDescendantsThatHaveChildren(TIdentifier id) { // Default behavior assumes complete tree - HashSet parentsBelow = new HashSet(); - TreeViewUtility.GetParentsBelowItem(FindItem(id), parentsBelow); + HashSet parentsBelow = new HashSet(); + TreeViewUtility.GetParentsBelowItem(FindItem(id), parentsBelow); return parentsBelow.ToArray(); } - TreeViewItem FindItem(int id) + TreeViewItem FindItem(TIdentifier id) { if (rootItem == null) throw new InvalidOperationException("FindItem failed: root item has not been created yet"); - return TreeViewUtility.FindItem(id, rootItem); + return TreeViewUtility.FindItem(id, rootItem); } // Selection - protected virtual bool CanMultiSelect(TreeViewItem item) + protected virtual bool CanMultiSelect(TreeViewItem item) => CanMultiSelectInternal(item); + + internal virtual bool CanMultiSelectInternal(TreeViewItem item) { return true; // default behavior } // Renaming - protected virtual bool CanRename(TreeViewItem item) + protected virtual bool CanRename(TreeViewItem item) => CanRenameInternal(item); + + internal virtual bool CanRenameInternal(TreeViewItem item) { return false; // Default to false so user have to enable renaming if wanted } @@ -607,7 +614,9 @@ protected virtual void RenameEnded(RenameEndedArgs args) } // Dragging - protected virtual bool CanStartDrag(CanStartDragArgs args) + protected virtual bool CanStartDrag(CanStartDragArgs args) => CanStartDragInternal(args); + + internal virtual bool CanStartDragInternal(CanStartDragArgs args) { return false; } @@ -616,17 +625,22 @@ protected virtual void SetupDragAndDrop(SetupDragAndDropArgs args) { } - protected virtual DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args) + protected virtual DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args) => HandleDragAndDropInternal(args); + internal virtual DragAndDropVisualMode HandleDragAndDropInternal(DragAndDropArgs args) { return DragAndDropVisualMode.None; } - protected virtual bool CanBeParent(TreeViewItem item) + protected virtual bool CanBeParent(TreeViewItem item) => CanBeParentInternal(item); + + internal virtual bool CanBeParentInternal(TreeViewItem item) { return true; // default behavior } - protected virtual bool CanChangeExpandedState(TreeViewItem item) + protected virtual bool CanChangeExpandedState(TreeViewItem item) => CanChangeExpandedStateInternal(item); + + internal virtual bool CanChangeExpandedStateInternal(TreeViewItem item) { // Default: Ignore expansion (foldout arrow) when showing search results if (m_TreeView.isSearching) @@ -634,13 +648,17 @@ protected virtual bool CanChangeExpandedState(TreeViewItem item) return item.hasChildren; } - protected virtual bool DoesItemMatchSearch(TreeViewItem item, string search) + protected virtual bool DoesItemMatchSearch(TreeViewItem item, string search) => DoesItemMatchSearchInternal(item, search); + + internal virtual bool DoesItemMatchSearchInternal(TreeViewItem item, string search) { return item.displayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0; } // Custom GUI - protected virtual void RowGUI(RowGUIArgs args) + protected virtual void RowGUI(RowGUIArgs args) => RowGUIInternal(args); + + internal virtual void RowGUIInternal(RowGUIArgs args) { m_GUI.DefaultRowGUI(args); } @@ -662,12 +680,16 @@ protected virtual void RefreshCustomRowHeights() m_GUI.RefreshRowRects(GetRows()); } - protected virtual float GetCustomRowHeight(int row, TreeViewItem item) + protected virtual float GetCustomRowHeight(int row, TreeViewItem item) => GetCustomRowHeightInternal(row, item); + + internal virtual float GetCustomRowHeightInternal(int row, TreeViewItem item) { return rowHeight; } - protected virtual Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) + protected virtual Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) => GetRenameRectInternal(rowRect, row, item); + + internal virtual Rect GetRenameRectInternal(Rect rowRect, int row, TreeViewItem item) { return m_GUI.DefaultRenameRect(rowRect, row, item); } @@ -704,24 +726,24 @@ protected virtual void CommandEventHandling() } } - protected static void SetupParentsAndChildrenFromDepths(TreeViewItem root, IList rows) + protected static void SetupParentsAndChildrenFromDepths(TreeViewItem root, IList> rows) { - TreeViewUtility.SetChildParentReferences(rows, root); + TreeViewUtility.SetChildParentReferences(rows, root); } - protected static void SetupDepthsFromParentsAndChildren(TreeViewItem root) + protected static void SetupDepthsFromParentsAndChildren(TreeViewItem root) { - TreeViewUtility.SetDepthValuesForItems(root); + TreeViewUtility.SetDepthValuesForItems(root); } - protected static List CreateChildListForCollapsedParent() + protected static List> CreateChildListForCollapsedParent() { - return LazyTreeViewDataSource.CreateChildListForCollapsedParent(); + return LazyTreeViewDataSource.CreateChildListForCollapsedParent(); } - protected static bool IsChildListForACollapsedParent(IList childList) + protected static bool IsChildListForACollapsedParent(IList> childList) { - return LazyTreeViewDataSource.IsChildListForACollapsedParent(childList); + return LazyTreeViewDataSource.IsChildListForACollapsedParent(childList); } class OverriddenMethods @@ -732,33 +754,68 @@ class OverriddenMethods public readonly bool hasBuildRows; public readonly bool hasGetCustomRowHeight; - public OverriddenMethods(TreeView treeView) + public OverriddenMethods(TreeView treeView) { Type type = treeView.GetType(); - hasRowGUI = IsOverridden(type, "RowGUI"); - hasHandleDragAndDrop = IsOverridden(type, "HandleDragAndDrop"); - hasGetRenameRect = IsOverridden(type, "GetRenameRect"); - hasBuildRows = IsOverridden(type, "BuildRows"); - hasGetCustomRowHeight = IsOverridden(type, "GetCustomRowHeight"); - ValidateOverriddenMethods(treeView); - } - - static bool IsOverridden(Type type, string methodName) - { - var methodInfo = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); - if (methodInfo != null) - return methodInfo.GetBaseDefinition().DeclaringType != methodInfo.DeclaringType; - - Debug.LogError("IsOverridden: method name not found: " + methodName + " (check spelling against method declaration)"); - return false; - } + var methods = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance); + bool hasCanRename = false, hasRenameEnded = false; + bool hasCanStartDragAndDrop = false, hasSetupDragAndDrop = false; - void ValidateOverriddenMethods(TreeView treeView) - { - Type type = treeView.GetType(); + foreach (var method in methods) + { + if (method.GetBaseDefinition().DeclaringType == method.DeclaringType) + continue; + + switch (method.Name) + { + case "RowGUI": + { + hasRowGUI = true; + break; + } + case "HandleDragAndDrop": + { + hasHandleDragAndDrop = true; + break; + } + case "GetRenameRect": + { + hasGetRenameRect = true; + break; + } + case "BuildRows": + { + hasBuildRows = true; + break; + } + case "GetCustomRowHeight": + { + hasGetCustomRowHeight = true; + break; + } + case "CanRename": + { + hasCanRename = true; + break; + } + case "RenameEnded": + { + hasRenameEnded = true; + break; + } + case "CanStartDrag": + { + hasCanStartDragAndDrop = true; + break; + } + case "SetupDragAndDrop": + { + hasSetupDragAndDrop = true; + break; + } + } + } - bool hasCanRename = IsOverridden(type, "CanRename"); - bool hasRenameEnded = IsOverridden(type, "RenameEnded"); if (hasRenameEnded != hasCanRename) { if (hasCanRename) @@ -768,8 +825,6 @@ void ValidateOverriddenMethods(TreeView treeView) Debug.LogError(type.Name + ": If you are overriding RenameEnded you should also override CanRename (to allow renaming)."); } - bool hasCanStartDragAndDrop = IsOverridden(type, "CanStartDrag"); - bool hasSetupDragAndDrop = IsOverridden(type, "SetupDragAndDrop"); if (hasCanStartDragAndDrop != hasSetupDragAndDrop) { if (hasCanStartDragAndDrop) @@ -782,9 +837,9 @@ void ValidateOverriddenMethods(TreeView treeView) } // Nested because they are used by protected methods - protected struct RowGUIArgs + protected internal struct RowGUIArgs { - public TreeViewItem item; + public TreeViewItem item; public string label; public Rect rowRect; public int row; @@ -835,34 +890,34 @@ internal MultiColumnInfo(MultiColumnHeaderState multiColumnHeaderState, Rect[] c } } - protected struct DragAndDropArgs + protected internal struct DragAndDropArgs { public DragAndDropPosition dragAndDropPosition; - public TreeViewItem parentItem; + public TreeViewItem parentItem; public int insertAtIndex; public bool performDrop; } protected struct SetupDragAndDropArgs { - public IList draggedItemIDs; + public IList draggedItemIDs; } - protected struct CanStartDragArgs + protected internal struct CanStartDragArgs { - public TreeViewItem draggedItem; - public IList draggedItemIDs; + public TreeViewItem draggedItem; + public IList draggedItemIDs; } protected struct RenameEndedArgs { public bool acceptedRename; - public int itemID; + public TIdentifier itemID; public string originalName; public string newName; } - protected enum DragAndDropPosition + protected internal enum DragAndDropPosition { UponItem, BetweenItems, diff --git a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDataSource.cs b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDataSource.cs index b34bc50d9a..f68ea86638 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDataSource.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDataSource.cs @@ -8,13 +8,13 @@ namespace UnityEditor.IMGUI.Controls { - public partial class TreeView + public partial class TreeView where TIdentifier : unmanaged, System.IEquatable { - internal class TreeViewControlDataSource : LazyTreeViewDataSource + internal class TreeViewControlDataSource : LazyTreeViewDataSource { - readonly TreeView m_Owner; + readonly TreeView m_Owner; - public TreeViewControlDataSource(TreeViewController treeView, TreeView owner) : base(treeView) + public TreeViewControlDataSource(TreeViewController treeView, TreeView owner) : base(treeView) { m_Owner = owner; @@ -68,7 +68,7 @@ public override void FetchData() m_Owner.m_GUI.RefreshRowRects(m_Rows); } - public void SearchFullTree(string search, List result) + public void SearchFullTree(string search, List> result) { if (string.IsNullOrEmpty(search)) throw new ArgumentException("Invalid search: cannot be null or empty", "search"); @@ -76,11 +76,11 @@ public void SearchFullTree(string search, List result) if (result == null) throw new ArgumentException("Invalid list: cannot be null", "result"); - var stack = new Stack(); + var stack = new Stack>(); stack.Push(m_RootItem); while (stack.Count > 0) { - TreeViewItem current = stack.Pop(); + TreeViewItem current = stack.Pop(); if (current.children != null) { foreach (var child in current.children) @@ -99,34 +99,34 @@ public void SearchFullTree(string search, List result) result.Sort((x, y) => EditorUtility.NaturalCompare(x.displayName, y.displayName)); } - protected override void GetParentsAbove(int id, HashSet ancestors) + protected override void GetParentsAbove(TIdentifier id, HashSet ancestors) { foreach (var ancestor in m_Owner.GetAncestors(id)) ancestors.Add(ancestor); } - protected override void GetParentsBelow(int id, HashSet children) + protected override void GetParentsBelow(TIdentifier id, HashSet children) { foreach (var child in m_Owner.GetDescendantsThatHaveChildren(id)) children.Add(child); } - public override bool IsExpandable(TreeViewItem item) + public override bool IsExpandable(TreeViewItem item) { return m_Owner.CanChangeExpandedState(item); } - public override bool CanBeMultiSelected(TreeViewItem item) + public override bool CanBeMultiSelected(TreeViewItem item) { return m_Owner.CanMultiSelect(item); } - public override bool CanBeParent(TreeViewItem item) + public override bool CanBeParent(TreeViewItem item) { return m_Owner.CanBeParent(item); } - public override bool IsRenamingItemAllowed(TreeViewItem item) + public override bool IsRenamingItemAllowed(TreeViewItem item) { return m_Owner.CanRename(item); } diff --git a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDefaults.cs b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDefaults.cs index 518c64ea7f..f3467d52b7 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDefaults.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDefaults.cs @@ -6,7 +6,7 @@ namespace UnityEditor.IMGUI.Controls { - public partial class TreeView + public partial class TreeView where TIdentifier : unmanaged, System.IEquatable { public static class DefaultGUI { @@ -62,7 +62,7 @@ static DefaultStyles() { // Make a copy of lineStyle since left padding is being dynamically changed on that // Note the left padding of 0 for exact placement of content after foldout or icon - foldoutLabel = new GUIStyle(TreeViewGUI.Styles.lineStyle); + foldoutLabel = new GUIStyle(TreeViewGUI.Styles.lineStyle); foldoutLabel.padding.left = 0; // For generic labels use same padding values as the standard EditorStyles.label for consistency diff --git a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDragging.cs b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDragging.cs index 63963bc86e..38fac46d76 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDragging.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDragging.cs @@ -8,29 +8,29 @@ namespace UnityEditor.IMGUI.Controls { - public partial class TreeView + public partial class TreeView where TIdentifier : unmanaged, System.IEquatable { - private class TreeViewControlDragging : TreeViewDragging + private class TreeViewControlDragging : TreeViewDragging { - private TreeView m_Owner; + private TreeView m_Owner; - public TreeViewControlDragging(TreeViewController treeView, TreeView owner) + public TreeViewControlDragging(TreeViewController treeView, TreeView owner) : base(treeView) { m_Owner = owner; } - public override bool CanStartDrag(TreeViewItem targetItem, List draggedItemIDs, Vector2 mouseDownPosition) + public override bool CanStartDrag(TreeViewItem targetItem, List draggedItemIDs, Vector2 mouseDownPosition) { return m_Owner.CanStartDrag(new CanStartDragArgs { draggedItem = targetItem, draggedItemIDs = draggedItemIDs }); } - public override void StartDrag(TreeViewItem draggedItem, List draggedItemIDs) + public override void StartDrag(TreeViewItem draggedItem, List draggedItemIDs) { m_Owner.SetupDragAndDrop(new SetupDragAndDropArgs { draggedItemIDs = draggedItemIDs}); } - public override DragAndDropVisualMode DoDrag(TreeViewItem parentItem, TreeViewItem targetItem, bool perform, DropPosition dropPosition) + public override DragAndDropVisualMode DoDrag(TreeViewItem parentItem, TreeViewItem targetItem, bool perform, DropPosition dropPosition) { if (m_Owner.m_OverriddenMethods.hasHandleDragAndDrop) { @@ -48,7 +48,7 @@ public override DragAndDropVisualMode DoDrag(TreeViewItem parentItem, TreeViewIt return DragAndDropVisualMode.None; } - DragAndDropPosition GetDragAndDropPosition(TreeViewItem parentItem, TreeViewItem targetItem) + DragAndDropPosition GetDragAndDropPosition(TreeViewItem parentItem, TreeViewItem targetItem) { if (parentItem == null) return DragAndDropPosition.OutsideItems; diff --git a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlGUI.cs b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlGUI.cs index 3d9369f05c..8822540e82 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlGUI.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlGUI.cs @@ -8,24 +8,24 @@ namespace UnityEditor.IMGUI.Controls { - public partial class TreeView + public partial class TreeView where TIdentifier : unmanaged, System.IEquatable { - class TreeViewControlGUI : TreeViewGUI + class TreeViewControlGUI : TreeViewGUI { - readonly TreeView m_Owner; + readonly TreeView m_Owner; List m_RowRects; // If m_RowRects is null fixed row height is used Rect[] m_CellRects; // Allocated once and reused const float k_BackgroundWidth = 100000f; // The TreeView can have a horizontal scrollbar so ensure to fill out the entire width of the background public float borderWidth = 1f; - public TreeViewControlGUI(TreeViewController treeView, TreeView owner) + public TreeViewControlGUI(TreeViewController treeView, TreeView owner) : base(treeView) { m_Owner = owner; cellMargin = MultiColumnHeader.DefaultGUI.columnContentMargin; } - public void RefreshRowRects(IList rows) + public void RefreshRowRects(IList> rows) { if (m_RowRects == null) m_RowRects = new List(rows.Count); @@ -83,7 +83,7 @@ float customRowsTotalHeight } // We only override DrawIconAndLabel (and not OnRowGUI) so the user only have to care about item content rendering; and not drag marker rendering, renaming and foldout button - protected override void OnContentGUI(Rect rect, int row, TreeViewItem item, string label, bool selected, bool focused, bool useBoldFont, bool isPinging) + protected override void OnContentGUI(Rect rect, int row, TreeViewItem item, string label, bool selected, bool focused, bool useBoldFont, bool isPinging) { // We do not support pinging in the TreeView (to simplify api) if (isPinging) @@ -91,7 +91,7 @@ protected override void OnContentGUI(Rect rect, int row, TreeViewItem item, stri // Make sure the GUI contents for each row is starting with its own controlID unique to its item. This prevents key-focus of a control (e.g a float field) // to jump from row to row when mouse scrolling (due to culling of rows and the assigning of controlIDs in call-order) - GUIUtility.GetControlID(TreeViewController.GetItemControlID(item), FocusType.Passive); + GUIUtility.GetControlID(TreeViewController.GetItemControlID(item), FocusType.Passive); if (m_Owner.m_OverriddenMethods.hasRowGUI) { @@ -151,7 +151,7 @@ internal void DefaultRowGUI(RowGUIArgs args) base.OnContentGUI(args.rowRect, args.row, args.item, args.label, args.selected, args.focused, false, false); } - protected override Rect DoFoldout(Rect rowRect, TreeViewItem item, int row) + protected override Rect DoFoldout(Rect rowRect, TreeViewItem item, int row) { // For multicolumn setup we need to ensure foldouts are clipped so they are not in the next column if (m_Owner.multiColumnHeader != null) @@ -160,7 +160,7 @@ protected override Rect DoFoldout(Rect rowRect, TreeViewItem item, int row) return base.DoFoldout(rowRect, item, row); } - Rect DoMultiColumnFoldout(Rect rowRect, TreeViewItem item, int row) + Rect DoMultiColumnFoldout(Rect rowRect, TreeViewItem item, int row) { if (!m_Owner.multiColumnHeader.IsColumnVisible(columnIndexForTreeFoldouts)) return new Rect(); @@ -180,7 +180,7 @@ Rect DoMultiColumnFoldout(Rect rowRect, TreeViewItem item, int row) return base.DoFoldout(cellRect, item, row); } - public override Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) + public override Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) { if (m_Owner.m_OverriddenMethods.hasGetRenameRect) { @@ -190,7 +190,7 @@ public override Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) return base.GetRenameRect(rowRect, row, item); } - public Rect DefaultRenameRect(Rect rowRect, int row, TreeViewItem item) + public Rect DefaultRenameRect(Rect rowRect, int row, TreeViewItem item) { return base.GetRenameRect(rowRect, row, item); } @@ -305,7 +305,7 @@ public override void GetFirstAndLastRowVisible(out int firstRowVisible, out int } } - protected override void DrawItemBackground(Rect rect, int row, TreeViewItem item, bool selected, bool focused) + protected override void DrawItemBackground(Rect rect, int row, TreeViewItem item, bool selected, bool focused) { base.DrawItemBackground(rect, row, item, selected, focused); diff --git a/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewOld.cs b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewOld.cs new file mode 100644 index 0000000000..15657c2b29 --- /dev/null +++ b/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewOld.cs @@ -0,0 +1,402 @@ +// Unity C# reference source +// Copyright (c) Unity Technologies. For terms of use, see +// https://unity3d.com/legal/licenses/Unity_Reference_Only_License + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace UnityEditor.IMGUI.Controls; + +// [Obsolete("TreeView is now deprecated. You can likely now use TreeView instead and not think more about it. But if you were using that identifier to store InstanceID data, you should instead opt to upgrade your TreeViews to use TreeView to get the proper typing.")] +public abstract partial class TreeView : TreeViewInternal +{ + protected TreeView(TreeViewState state) + : base(state) { } + + protected TreeView(TreeViewState state, MultiColumnHeader multiColumnHeader) + : base(state, multiColumnHeader) { } + + protected new struct RowGUIArgs + { + public TreeViewItem item; + public string label; + public Rect rowRect; + public int row; + public bool selected; + public bool focused; + public bool isRenaming; + internal TreeView.RowGUIArgs.MultiColumnInfo columnInfo; + + public int GetNumVisibleColumns()=> ((TreeView.RowGUIArgs)this).GetNumVisibleColumns(); + public int GetColumn(int visibleColumnIndex) => ((TreeView.RowGUIArgs)this).GetColumn(visibleColumnIndex); + public Rect GetCellRect(int visibleColumnIndex) => ((TreeView.RowGUIArgs)this).GetCellRect(visibleColumnIndex); + + // a cast from RowGUIArgs to TreeView.RowGUIArgs + public static implicit operator TreeView.RowGUIArgs(RowGUIArgs args) => new() + { + item = args.item, + label = args.label, + rowRect = args.rowRect, + row = args.row, + selected = args.selected, + focused = args.focused, + isRenaming = args.isRenaming, + columnInfo = args.columnInfo + }; + + public static implicit operator RowGUIArgs(TreeView.RowGUIArgs args) => new() + { + item = args.item as TreeViewItem, + label = args.label, + rowRect = args.rowRect, + row = args.row, + selected = args.selected, + focused = args.focused, + isRenaming = args.isRenaming, + columnInfo = args.columnInfo + }; + } + + protected new struct DragAndDropArgs + { + public DragAndDropPosition dragAndDropPosition; + public TreeViewItem parentItem; + public int insertAtIndex; + public bool performDrop; + + // a cast from DragAndDropArgs to TreeView.DragAndDropArgs + public static implicit operator TreeView.DragAndDropArgs(DragAndDropArgs args) + { + return new TreeView.DragAndDropArgs + { + dragAndDropPosition = args.dragAndDropPosition, + parentItem = args.parentItem, + insertAtIndex = args.insertAtIndex, + performDrop = args.performDrop + }; + } + public static implicit operator DragAndDropArgs(TreeView.DragAndDropArgs args) + { + return new DragAndDropArgs + { + dragAndDropPosition = args.dragAndDropPosition, + parentItem = args.parentItem as TreeViewItem, + insertAtIndex = args.insertAtIndex, + performDrop = args.performDrop + }; + } + } + + protected new struct CanStartDragArgs + { + public TreeViewItem draggedItem; + public IList draggedItemIDs; + + // a cast from CanStartDragArgs to TreeView.CanStartDragArgs + public static implicit operator TreeView.CanStartDragArgs(CanStartDragArgs args) + { + return new TreeView.CanStartDragArgs + { + draggedItem = args.draggedItem, + draggedItemIDs = args.draggedItemIDs + }; + } + + public static implicit operator CanStartDragArgs(TreeView.CanStartDragArgs args) + { + return new CanStartDragArgs + { + draggedItem = args.draggedItem as TreeViewItem, + draggedItemIDs = args.draggedItemIDs + }; + } + } + + public new delegate List GetNewSelectionFunction(TreeViewItem clickedItem, bool keepMultiSelection, bool useActionKeyAsShift); + + protected new GetNewSelectionFunction getNewSelectionOverride + { + set + { + m_TreeView.getNewSelectionOverride = (x, y, z) => value(x as TreeViewItem, y, z); + } + } + + protected new abstract TreeViewItem BuildRoot(); + + internal override TreeViewItem BuildRootInternal() => BuildRoot(); + + internal override IList> BuildRowsInternal(TreeViewItem root) => BuildRows(root as TreeViewItem).ToGenericIList(); + protected virtual IList BuildRows(TreeViewItem root) => base.BuildRowsInternal(root).ToNonGenericIList(); + + public new TreeViewState state => base.state as TreeViewState; + protected new TreeViewItem rootItem => base.rootItem as TreeViewItem; + protected new TreeViewItem hoveredItem => base.hoveredItem as TreeViewItem; + + public new virtual IList GetRows() => base.GetRowsInternal().ToNonGenericIList(); + internal override IList> GetRowsInternal() => GetRows().ToGenericIList(); + + protected new IList FindRows(IList ids) => base.FindRows(ids).ToNonGenericIList(); + protected TreeViewItem FindItem(int id, TreeViewItem searchFromThisItem) => base.FindItem(id, searchFromThisItem) as TreeViewItem; + protected int FindRowOfItem(TreeViewItem item) => base.FindRowOfItem(item); + protected void SelectionClick(TreeViewItem item, bool keepMultiSelection) => base.SelectionClick(item, keepMultiSelection); + public bool BeginRename(TreeViewItem item) => base.BeginRename(item); + public bool BeginRename(TreeViewItem item, float delay) => base.BeginRename(item, delay); + protected float GetFoldoutIndent(TreeViewItem item) => base.GetFoldoutIndent(item); + protected float GetContentIndent(TreeViewItem item) => base.GetContentIndent(item); + protected void AddExpandedRows(TreeViewItem root, IList rows) => base.AddExpandedRows(root, rows.ToGenericIList()); + + protected virtual bool CanMultiSelect(TreeViewItem item) => base.CanMultiSelectInternal(item); + internal override bool CanMultiSelectInternal(TreeViewItem item) => CanMultiSelect(item as TreeViewItem); + protected virtual bool CanRename(TreeViewItem item) => base.CanRenameInternal(item); + internal override bool CanRenameInternal(TreeViewItem item) => CanRename(item as TreeViewItem); + + protected virtual bool CanStartDrag(CanStartDragArgs args) => base.CanStartDragInternal(args); + + internal override bool CanStartDragInternal(TreeView.CanStartDragArgs args) => CanStartDrag(args); + protected virtual DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args) => base.HandleDragAndDropInternal(args); + internal override DragAndDropVisualMode HandleDragAndDropInternal(TreeView.DragAndDropArgs args) => HandleDragAndDrop(args); + protected virtual bool CanBeParent(TreeViewItem item) => base.CanBeParentInternal(item); + internal override bool CanBeParentInternal(TreeViewItem item) => CanBeParent(item as TreeViewItem); + protected virtual bool CanChangeExpandedState(TreeViewItem item) => base.CanChangeExpandedStateInternal(item); + internal override bool CanChangeExpandedStateInternal(TreeViewItem item) => CanChangeExpandedState(item as TreeViewItem); + protected virtual bool DoesItemMatchSearch(TreeViewItem item, string search) => base.DoesItemMatchSearchInternal(item, search); + internal override bool DoesItemMatchSearchInternal(TreeViewItem item, string search) => DoesItemMatchSearch(item as TreeViewItem, search); + protected virtual void RowGUI(RowGUIArgs args) => base.RowGUIInternal(args); + internal override void RowGUIInternal(TreeView.RowGUIArgs args) => RowGUI(args); + protected virtual float GetCustomRowHeight(int row, TreeViewItem item) => base.GetCustomRowHeightInternal(row, item); + internal override float GetCustomRowHeightInternal(int row, TreeViewItem item) => GetCustomRowHeight(row, item as TreeViewItem); + protected virtual Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) => base.GetRenameRectInternal(rowRect, row, item); + internal override Rect GetRenameRectInternal(Rect rowRect, int row, TreeViewItem item) => GetRenameRect(rowRect, row, item as TreeViewItem); + protected static void SetupParentsAndChildrenFromDepths(TreeViewItem root, IList rows) => TreeView.SetupParentsAndChildrenFromDepths(root, rows.ToGenericIList()); + protected static void SetupDepthsFromParentsAndChildren(TreeViewItem root) => TreeView.SetupDepthsFromParentsAndChildren(root); + protected new static List CreateChildListForCollapsedParent() => TreeView.CreateChildListForCollapsedParent().ToNonGenericList(); + protected static bool IsChildListForACollapsedParent(IList childList) => TreeView.IsChildListForACollapsedParent(childList.ToGenericIList()); +} + +// [Obsolete("TreeView is now deprecated. You can likely now use TreeView instead and not think more about it. But if you were using that identifier to store InstanceID data, you should instead opt to upgrade your TreeViews to use TreeView to get the proper typing.")] +public abstract class TreeViewInternal : TreeView +{ + protected TreeViewInternal(TreeViewState state) + : base(state) { } + + protected TreeViewInternal(TreeViewState state, MultiColumnHeader multiColumnHeader) + : base(state, multiColumnHeader) { } + + protected override TreeViewItem BuildRoot() => BuildRootInternal(); + + internal abstract TreeViewItem BuildRootInternal(); +} + +// [Obsolete] +static class TreeViewItemConvertUtility { + public static List ToNonGenericList(this List> items) => (GenericTreeViewItemToNonGenericTreeViewItemList)items; + public static List> ToGenericList(this List items) => (GenericTreeViewItemToNonGenericTreeViewItemList)items; + public static IList ToNonGenericIList(this IList> items) => new GenericTreeViewItemToNonGenericTreeViewItemIList(items).nonGeneric; + public static IList> ToGenericIList(this IList items) => new GenericTreeViewItemToNonGenericTreeViewItemIList(items).generic; +} + +[StructLayout(LayoutKind.Explicit)] +// [Obsolete] +struct GenericTreeViewItemToNonGenericTreeViewItemList +{ + [FieldOffset(0)] public List nonGeneric; + [FieldOffset(0)] public List> generic; + + public static implicit operator GenericTreeViewItemToNonGenericTreeViewItemList(List items) => new() {nonGeneric=items}; + public static implicit operator GenericTreeViewItemToNonGenericTreeViewItemList(List> items) => new() {generic = items}; + public static implicit operator List(GenericTreeViewItemToNonGenericTreeViewItemList value) => value.nonGeneric; + public static implicit operator List>(GenericTreeViewItemToNonGenericTreeViewItemList value) => value.generic; +} + +[StructLayout(LayoutKind.Explicit)] +// [Obsolete] +struct GenericTreeViewItemToNonGenericTreeViewItemIList +{ + [FieldOffset(0)] public IList nonGeneric; + [FieldOffset(0)] public IList> generic; + + public GenericTreeViewItemToNonGenericTreeViewItemIList(IList items) + { + generic = null; + nonGeneric=items; + } + + public GenericTreeViewItemToNonGenericTreeViewItemIList(IList> items) + { + nonGeneric = null; + generic = items; + } +} + +// [Obsolete("TreeViewItem is now deprecated. You can likely now use TreeViewItem instead and not think more about it. But if you were using that identifier to store InstanceID data, you should instead opt to upgrade your TreeViews to use TreeViewItem to get the proper typing.")] +public class TreeViewItem : TreeViewItem +{ + public new virtual List children + { + get => base.childrenInternal.ToNonGenericList(); + set => base.childrenInternal = value.ToGenericList(); + } + internal override List> childrenInternal + { + get => children.ToGenericList(); + set => children = value.ToNonGenericList(); + } + + + internal override TreeViewItem ParentInternal + { + get => parent; + set => parent = value as TreeViewItem; + } + + public new virtual TreeViewItem parent { get { return base.ParentInternal as TreeViewItem; } set { base.ParentInternal = value; } } + + public void AddChild(TreeViewItem child) => base.AddChild(child); + + + internal override int CompareToInternal(TreeViewItem other) => CompareTo(other as TreeViewItem); + + public virtual int CompareTo(TreeViewItem other) => base.CompareToInternal(other); + + public TreeViewItem() { } + + public TreeViewItem(int id) : base(id){} + public TreeViewItem(int id, int depth): base(id, depth) { } + public TreeViewItem(int id, int depth, string displayName) : base(id, depth, displayName) { } + internal TreeViewItem(int id, int depth, TreeViewItem parent, string displayName) : base(id, depth, parent, displayName) { } +} + +// [Obsolete("TreeViewState is now deprecated. You can likely now use TreeViewState instead and not think more about it. But if you were using that identifier to store InstanceID data, you should instead opt to upgrade your TreeViews to use TreeViewState to get the proper typing.")] +public class TreeViewState : TreeViewState {} + +// [Obsolete] +internal class TreeViewController : TreeViewController +{ + public TreeViewController(EditorWindow editorWindow, TreeViewState treeViewState) : base(editorWindow, treeViewState) + { + + } + + public void Init(Rect rect, ITreeViewDataSource data, ITreeViewGUI gui, ITreeViewDragging dragging) => base.Init(rect, data, new TreeViewGUIAbstract(gui), dragging); + public new ITreeViewDataSource data { get =>base.data as ITreeViewDataSource; set => base.data = value; } + public new TreeViewState state { get =>base.state as TreeViewState; set => base.state = value; } +} + +// [Obsolete] +internal abstract class TreeViewDataSource : TreeViewDataSource, ITreeViewDataSource +{ + protected TreeViewDataSource(TreeViewController treeView) + : base(treeView) { } + + public new TreeViewItem root => base.root as TreeViewItem; + public new virtual IList GetRows() => base.GetRowsInternal().ToNonGenericIList(); + public override IList> GetRowsInternal() => GetRows().ToGenericIList(); + protected new TreeViewItem m_RootItem { get => base.m_RootItem as TreeViewItem; set => base.m_RootItem = value; } + protected new TreeViewController m_TreeView { get => m_TreeViewInternal as TreeViewController; set => m_TreeViewInternal = value; } + public virtual bool IsExpanded(TreeViewItem item) => base.IsExpandedInternal(item); + public override bool IsExpandedInternal(TreeViewItem item) => IsExpanded(item as TreeViewItem); + public virtual bool IsExpandable(TreeViewItem item) => base.IsExpandableInternal(item); + public override bool IsExpandableInternal(TreeViewItem item) => IsExpandable(item as TreeViewItem); + public virtual bool CanBeParent(TreeViewItem item) => base.CanBeParentInternal(item); + public override bool CanBeParentInternal(TreeViewItem item) => CanBeParent(item as TreeViewItem); +} + +// [Obsolete] +internal abstract class TreeViewDragging : TreeViewDragging +{ + public TreeViewDragging(TreeViewController treeView) : base(treeView) + { + } + + public virtual bool CanStartDrag(TreeViewItem targetItem, List draggedItemIDs, Vector2 mouseDownPosition) => base.CanStartDragInternal(targetItem, draggedItemIDs, mouseDownPosition); + public override bool CanStartDragInternal(TreeViewItem targetItem, List draggedItemIDs, Vector2 mouseDownPosition)=> CanStartDrag(targetItem as TreeViewItem, draggedItemIDs, mouseDownPosition); + public override void StartDragInternal(TreeViewItem draggedItem, List draggedItemIDs) => StartDrag(draggedItem as TreeViewItem, draggedItemIDs); + public virtual void StartDrag(TreeViewItem draggedItem, List draggedItemIDs) => base.StartDragInternal(draggedItem, draggedItemIDs); + public virtual DragAndDropVisualMode DoDrag(TreeViewItem parentItem, TreeViewItem targetItem, bool perform, DropPosition dropPosition) => base.DoDragInternal(parentItem, targetItem, perform, dropPosition); + public override DragAndDropVisualMode DoDragInternal(TreeViewItem parentItem, TreeViewItem targetItem, bool perform, DropPosition dropPosition) => DoDrag(parentItem as TreeViewItem, targetItem as TreeViewItem, perform, dropPosition); + public virtual bool DragElement(TreeViewItem targetItem, Rect targetItemRect, int row) => base.DragElementInternal(targetItem, targetItemRect, row); + public override bool DragElementInternal(TreeViewItem targetItem, Rect targetItemRect, int row) => DragElement(targetItem as TreeViewItem, targetItemRect, row); +} + +// [Obsolete] +internal interface ITreeViewGUI +{ + void OnInitialize(); + Vector2 GetTotalSize(); + void GetFirstAndLastRowVisible(out int firstRowVisible, out int lastRowVisible); + Rect GetRowRect(int row, float rowWidth); + Rect GetRectForFraming(int row); + + void BeginPingItem(TreeViewItem item, float topPixelOfRow, float availableWidth); + void EndPingItem(); + bool BeginRename(TreeViewItem item, float delay); + void EndRename(); + float GetContentIndent(TreeViewItem item); + int GetNumRowsOnPageUpDown(TreeViewItem fromItem, bool pageUp, float heightOfTreeView); + Rect GetRenameRect(Rect rect, int row, TreeViewItem item); + void OnRowGUI(Rect rect, TreeViewItem item, int row, bool selected, bool focused); + void BeginRowGUI(); // use for e.g clearing state before OnRowGUI calls + void EndRowGUI(); // use for handling stuff after all rows have had their OnRowGUI + float halfDropBetweenHeight { get; } + float topRowMargin { get; } + float bottomRowMargin { get; } +} + +// [Obsolete] +internal class TreeViewGUIAbstract : ITreeViewGUI +{ + ITreeViewGUI treeViewGUI; + + public TreeViewGUIAbstract(ITreeViewGUI treeViewGUI) + { + this.treeViewGUI = treeViewGUI; + } + + public void OnInitialize() => treeViewGUI.OnInitialize(); + public Vector2 GetTotalSize() => treeViewGUI.GetTotalSize(); + public void GetFirstAndLastRowVisible(out int firstRowVisible, out int lastRowVisible) => treeViewGUI.GetFirstAndLastRowVisible(out firstRowVisible, out lastRowVisible); + public Rect GetRowRect(int row, float rowWidth) => treeViewGUI.GetRowRect(row, rowWidth); + public Rect GetRectForFraming(int row) => treeViewGUI.GetRectForFraming(row); + public int GetNumRowsOnPageUpDown(TreeViewItem fromItem, bool pageUp, float heightOfTreeView) => treeViewGUI.GetNumRowsOnPageUpDown(fromItem as TreeViewItem, pageUp, heightOfTreeView); + public void OnRowGUI(Rect rowRect, TreeViewItem item, int row, bool selected, bool focused) => treeViewGUI.OnRowGUI(rowRect, item as TreeViewItem, row, selected, focused); + public void BeginRowGUI() => treeViewGUI.BeginRowGUI(); + public void EndRowGUI() => treeViewGUI.EndRowGUI(); + public void BeginPingItem(TreeViewItem item, float topPixelOfRow, float availableWidth) => treeViewGUI.BeginPingItem(item as TreeViewItem, topPixelOfRow, availableWidth); + public void EndPingItem() => treeViewGUI.EndPingItem(); + public bool BeginRename(TreeViewItem item, float delay) => treeViewGUI.BeginRename(item as TreeViewItem, delay); + public void EndRename() => treeViewGUI.EndRename(); + public Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) => treeViewGUI.GetRenameRect(rowRect, row, item as TreeViewItem); + public float GetContentIndent(TreeViewItem item) => treeViewGUI.GetContentIndent(item as TreeViewItem); + public float halfDropBetweenHeight => treeViewGUI.halfDropBetweenHeight; + public float topRowMargin => treeViewGUI.topRowMargin; + public float bottomRowMargin => treeViewGUI.bottomRowMargin; +} + +// [Obsolete] +internal abstract class TreeViewGUI : TreeViewGUI +{ + protected TreeViewGUI(TreeViewController treeView) + : base(treeView) { } + + protected TreeViewGUI(TreeViewController treeView, bool useHorizontalScroll) + : base(treeView, useHorizontalScroll) { } + + public new System.Action iconOverlayGUI { get; set; } + + virtual public void OnRowGUI(Rect rowRect, TreeViewItem item, int row, bool selected, bool focused) => base.OnRowGUIInternal(rowRect, item, row, selected, focused); + override public void OnRowGUIInternal(Rect rowRect, TreeViewItem item, int row, bool selected, bool focused) => OnRowGUI(rowRect, item as TreeViewItem, row, selected, focused); + virtual public bool BeginRename(TreeViewItem item, float delay) => base.BeginRenameInternal(item, delay); + override public bool BeginRenameInternal(TreeViewItem item, float delay) => BeginRename(item as TreeViewItem, delay); + protected virtual Texture GetIconForItem(TreeViewItem item) => base.GetIconForItemInternal(item); + protected override Texture GetIconForItemInternal(TreeViewItem item) => GetIconForItem(item as TreeViewItem); +} + +// [Obsolete] +internal interface ITreeViewDataSource : ITreeViewDataSource +{ + new TreeViewItem root { get; } + new IList GetRows(); +} diff --git a/Editor/Mono/GUI/TreeView/TreeViewController.cs b/Editor/Mono/GUI/TreeView/TreeViewController.cs index a41d620416..f1c721b94c 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewController.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewController.cs @@ -29,25 +29,25 @@ namespace UnityEditor.IMGUI.Controls */ [System.Serializable] - public class TreeViewState + public class TreeViewState where TIdentifier : unmanaged, System.IEquatable { - public List selectedIDs { get { return m_SelectedIDs; } set { m_SelectedIDs = value; } } - public int lastClickedID { get { return m_LastClickedID; } set { m_LastClickedID = value; } } - public List expandedIDs { get { return m_ExpandedIDs; } set { m_ExpandedIDs = value; } } - internal RenameOverlay renameOverlay { get { return m_RenameOverlay; } set { m_RenameOverlay = value; } } + public List selectedIDs { get { return m_SelectedIDs; } set { m_SelectedIDs = value; } } + public TIdentifier lastClickedID { get { return m_LastClickedID; } set { m_LastClickedID = value; } } + public List expandedIDs { get { return m_ExpandedIDs; } set { m_ExpandedIDs = value; } } + internal RenameOverlay renameOverlay { get { return m_RenameOverlay; } set { m_RenameOverlay = value; } } public string searchString { get { return m_SearchString; } set { m_SearchString = value; } } public Vector2 scrollPos; // Selection state - [SerializeField] private List m_SelectedIDs = new List(); - [SerializeField] private int m_LastClickedID; // used for navigation + [SerializeField] private List m_SelectedIDs = new List(); + [SerializeField] private TIdentifier m_LastClickedID; // used for navigation // Expanded state (assumed sorted) - [SerializeField] private List m_ExpandedIDs = new List(); + [SerializeField] private List m_ExpandedIDs = new List(); // Rename and create asset state - [SerializeField] private RenameOverlay m_RenameOverlay = new RenameOverlay(); + [SerializeField] private RenameOverlay m_RenameOverlay = new RenameOverlay(); // Search state (can be used by Datasource to filter tree when reloading) [SerializeField] private string m_SearchString; @@ -59,41 +59,41 @@ internal virtual void OnAwake() } } - internal struct TreeViewSelectState + internal struct TreeViewSelectState { - public List selectedIDs; - public int lastClickedID; + public List selectedIDs; + public TIdentifier lastClickedID; public bool keepMultiSelection; public bool useShiftAsActionKey; } - internal class TreeViewController + internal class TreeViewController where TIdentifier : unmanaged, System.IEquatable { - public System.Action selectionChangedCallback { get; set; } // ids - public System.Action itemSingleClickedCallback { get; set; } // id - public System.Action itemDoubleClickedCallback { get; set; } // id - public System.Action dragEndedCallback { get; set; } // dragged ids, if null then drag was not allowed, bool == true if dragging tree view items from own treeview, false if drag was started outside - public System.Action contextClickItemCallback { get; set; } // clicked item id + public System.Action selectionChangedCallback { get; set; } // ids + public System.Action itemSingleClickedCallback { get; set; } // id + public System.Action itemDoubleClickedCallback { get; set; } // id + public System.Action dragEndedCallback { get; set; } // dragged ids, if null then drag was not allowed, bool == true if dragging tree view items from own treeview, false if drag was started outside + public System.Action contextClickItemCallback { get; set; } // clicked item id public System.Action contextClickOutsideItemsCallback { get; set; } public System.Action keyboardInputCallback { get; set; } public System.Action expandedStateChanged { get; set; } public System.Action searchChanged { get; set; } public System.Action scrollChanged { get; set; } - public System.Action onGUIRowCallback { get; set; } // + public System.Action onGUIRowCallback { get; set; } // - internal System.Action onFoldoutButton { get; set; } // + internal System.Action onFoldoutButton { get; set; } // // Main state GUIView m_GUIView; // Containing view for this tree: used for checking if we have focus and for requesting repaints - public ITreeViewDataSource data { get; set; } // Data provider for this tree: handles data fetching - public ITreeViewDragging dragging { get; set; } // Handle dragging - public ITreeViewGUI gui { get; set; } // Handles GUI (input and rendering) - public TreeViewState state { get; set; } // State that persists script reloads + public ITreeViewDataSource data { get; set; } // Data provider for this tree: handles data fetching + public ITreeViewDragging dragging { get; set; } // Handle dragging + public ITreeViewGUI gui { get; set; } // Handles GUI (input and rendering) + public TreeViewState state { get; set; } // State that persists script reloads public GUIStyle horizontalScrollbarStyle { get; set; } public GUIStyle verticalScrollbarStyle { get; set; } public GUIStyle scrollViewStyle { get; set; } - public TreeViewItemExpansionAnimator expansionAnimator { get { return m_ExpansionAnimator; } } - readonly TreeViewItemExpansionAnimator m_ExpansionAnimator = new TreeViewItemExpansionAnimator(); + public TreeViewItemExpansionAnimator expansionAnimator { get { return m_ExpansionAnimator; } } + readonly TreeViewItemExpansionAnimator m_ExpansionAnimator = new TreeViewItemExpansionAnimator(); AnimFloat m_FramingAnimFloat; bool m_StopIteratingItems; @@ -106,10 +106,10 @@ internal class TreeViewController struct IntegerCache { - List m_List; - HashSet m_HashSet; + List m_List; + HashSet m_HashSet; - public bool Contains(int id) + public bool Contains(TIdentifier id) { if (m_HashSet == null) return false; @@ -117,19 +117,19 @@ public bool Contains(int id) return m_HashSet.Contains(id); } - public void Set(List list) + public void Set(List list) { if (list == null) throw new ArgumentNullException(nameof(list)); if (!Equals(list)) { - m_List = new List(list); - m_HashSet = new HashSet(list); + m_List = new List(list); + m_HashSet = new HashSet(list); } } - public List Get() + public List Get() { return m_List; } @@ -151,7 +151,7 @@ public bool HasValues() return m_List.Count > 0; } - bool Equals(List list) + bool Equals(List list) { if (m_List == null || list == null) return false; @@ -162,7 +162,7 @@ bool Equals(List list) for (int i = 0; i < count; ++i) { - if (list[i] != m_List[i]) + if (!list[i].Equals(m_List[i])) return false; } @@ -188,15 +188,15 @@ bool Equals(List list) const double kSlowSelectTimeout = 0.2; const float kSpaceForScrollBar = 16f; - public TreeViewItem hoveredItem { get; set; } + public TreeViewItem hoveredItem { get; set; } - public TreeViewController(EditorWindow editorWindow, TreeViewState treeViewState) + public TreeViewController(EditorWindow editorWindow, TreeViewState treeViewState) { m_GUIView = editorWindow ? editorWindow.m_Parent : GUIView.current; state = treeViewState; } - public void Init(Rect rect, ITreeViewDataSource data, ITreeViewGUI gui, ITreeViewDragging dragging) + public void Init(Rect rect, ITreeViewDataSource data, ITreeViewGUI gui, ITreeViewDragging dragging) { this.data = data; this.gui = gui; @@ -229,7 +229,7 @@ public bool isDragging get { return m_DragSelection.HasValues(); } } - public bool IsDraggingItem(TreeViewItem item) + public bool IsDraggingItem(TreeViewItem item) { return m_DragSelection.Contains(item.id); } @@ -276,7 +276,7 @@ public Rect visibleRect get { return m_VisibleRect; } } - public bool IsSelected(int id) + public bool IsSelected(TIdentifier id) { return state.selectedIDs.Contains(id); } @@ -286,23 +286,23 @@ public bool HasSelection() return state.selectedIDs.Count > 0; } - public int[] GetSelection() + public TIdentifier[] GetSelection() { return state.selectedIDs.ToArray(); } - public int[] GetRowIDs() + public TIdentifier[] GetRowIDs() { return (from item in data.GetRows() select item.id).ToArray(); } - public void SetSelection(int[] selectedIDs, bool revealSelectionAndFrameLastSelected) + public void SetSelection(TIdentifier[] selectedIDs, bool revealSelectionAndFrameLastSelected) { const bool animatedFraming = false; SetSelection(selectedIDs, revealSelectionAndFrameLastSelected, animatedFraming); } - public void SetSelection(int[] selectedIDs, bool revealSelectionAndFrameLastSelected, bool animatedFraming) + public void SetSelection(TIdentifier[] selectedIDs, bool revealSelectionAndFrameLastSelected, bool animatedFraming) { // Keep for debugging //Debug.Log ("SetSelection: new selection: " + DebugUtils.ListToString(new List(selectedIDs))); @@ -315,21 +315,21 @@ public void SetSelection(int[] selectedIDs, bool revealSelectionAndFrameLastSele data.RevealItems(selectedIDs); } - state.selectedIDs = new List(selectedIDs); + state.selectedIDs = new List(selectedIDs); // Ensure that our key navigation is setup bool hasLastClicked = state.selectedIDs.IndexOf(state.lastClickedID) >= 0; if (!hasLastClicked) { // See if we can find a valid id, we check the last selected (selectedids might contain invalid ids e.g scene objects in project browser and vice versa) - int lastSelectedID = selectedIDs.Last(); + TIdentifier lastSelectedID = selectedIDs.Last(); if (data.GetRow(lastSelectedID) != -1) { state.lastClickedID = lastSelectedID; hasLastClicked = true; } else - state.lastClickedID = 0; + state.lastClickedID = default; } if (revealSelectionAndFrameLastSelected && hasLastClicked) @@ -338,14 +338,14 @@ public void SetSelection(int[] selectedIDs, bool revealSelectionAndFrameLastSele else { state.selectedIDs.Clear(); - state.lastClickedID = 0; + state.lastClickedID = default; } // Should not fire callback since this is called from outside // NotifyListenersThatSelectionChanged () } - public TreeViewItem FindItem(int id) + public TreeViewItem FindItem(TIdentifier id) { return data.FindItem(id); } @@ -384,12 +384,12 @@ public bool HasFocus() return hasKeyFocus && (GUIUtility.keyboardControl == m_KeyboardControlID); } - static internal int GetItemControlID(TreeViewItem item) + static internal int GetItemControlID(TreeViewItem item) { - return ((item != null) ? item.id : 0) + 10000000; + return ((item != null) ? item.id.GetHashCode() : 0) + 10000000; } - public void HandleUnusedMouseEventsForItem(Rect rect, TreeViewItem item, int row) + public void HandleUnusedMouseEventsForItem(Rect rect, TreeViewItem item, int row) { int itemControlID = GetItemControlID(item); @@ -434,7 +434,7 @@ public void HandleUnusedMouseEventsForItem(Rect rect, TreeViewItem item, int row m_DragSelection.Clear(); if (m_AllowRenameOnMouseUp) - m_AllowRenameOnMouseUp = (state.selectedIDs.Count == 1 && state.selectedIDs[0] == item.id); // If first time selection then prevent starting a rename on the following mouse up after this mouse down + m_AllowRenameOnMouseUp = (state.selectedIDs.Count == 1 && state.selectedIDs[0].Equals(item.id)); // If first time selection then prevent starting a rename on the following mouse up after this mouse down SelectionClick(item, false); @@ -485,8 +485,8 @@ public void HandleUnusedMouseEventsForItem(Rect rect, TreeViewItem item, int row if (rect.Contains(evt.mousePosition)) { Rect renameActivationRect = gui.GetRenameRect(rect, row, item); - List selected = state.selectedIDs; - if (m_AllowRenameOnMouseUp && selected != null && selected.Count == 1 && selected[0] == item.id && renameActivationRect.Contains(evt.mousePosition) && !EditorGUIUtility.HasHolddownKeyModifiers(evt)) + List selected = state.selectedIDs; + if (m_AllowRenameOnMouseUp && selected != null && selected.Count == 1 && selected[0].Equals(item.id) && renameActivationRect.Contains(evt.mousePosition) && !EditorGUIUtility.HasHolddownKeyModifiers(evt)) { BeginNameEditing(0.5f); } @@ -533,7 +533,7 @@ public void NotifyListenersThatSelectionChanged() selectionChangedCallback(state.selectedIDs.ToArray()); } - public void NotifyListenersThatDragEnded(int[] draggedIDs, bool draggedItemsFromOwnTreeView) + public void NotifyListenersThatDragEnded(TIdentifier[] draggedIDs, bool draggedItemsFromOwnTreeView) { if (dragEndedCallback != null) dragEndedCallback(draggedIDs, draggedItemsFromOwnTreeView); @@ -554,14 +554,14 @@ public void SetTotalRect(Rect rect) m_TotalRect = rect; } - public bool IsItemDragSelectedOrSelected(TreeViewItem item) + public bool IsItemDragSelectedOrSelected(TreeViewItem item) { return m_DragSelection.HasValues() ? m_DragSelection.Contains(item.id) : m_CachedSelection.Contains(item.id); } public bool animatingExpansion { get { return m_UseExpansionAnimation && m_ExpansionAnimator.isAnimating; } } - void DoItemGUI(TreeViewItem item, int row, float rowWidth, bool hasFocus) + void DoItemGUI(TreeViewItem item, int row, float rowWidth, bool hasFocus) { // Check valid row if (row < 0 || row >= data.rowCount) @@ -787,7 +787,7 @@ void IterateVisibleItems(int firstRow, int numVisibleRows, float rowWidth, bool // This can happen e.g when dragging items or items are expanding/collapsing. m_StopIteratingItems = false; - TreeViewItem currentHoveredItem = null; + TreeViewItem currentHoveredItem = null; int rowOffset = 0; for (int i = 0; i < numVisibleRows; ++i) @@ -847,7 +847,7 @@ void IterateVisibleItems(int firstRow, int numVisibleRows, float rowWidth, bool hoveredItem = currentHoveredItem; } - private void ExpansionAnimationEnded(TreeViewAnimationInput setup) + private void ExpansionAnimationEnded(TreeViewAnimationInput setup) { // When collapsing we delay the actual collapse until the animation is done if (!setup.expanding) @@ -866,7 +866,7 @@ float GetAnimationDuration(float height) return (height > kThreshold) ? kMaxDuration : (height * kMaxDuration / kThreshold); } - public void UserInputChangedExpandedState(TreeViewItem item, int row, bool expand) + public void UserInputChangedExpandedState(TreeViewItem item, int row, bool expand) { var includeChildren = Event.current.alt; if (useExpansionAnimation) @@ -881,7 +881,7 @@ public void UserInputChangedExpandedState(TreeViewItem item, int row, bool expan Rect allRowsRect = GetRectForRows(rowStart, rowEnd, rowWidth); float duration = GetAnimationDuration(allRowsRect.height); - var input = new TreeViewAnimationInput + var input = new TreeViewAnimationInput { animationDuration = duration, startRow = rowStart, @@ -903,7 +903,7 @@ public void UserInputChangedExpandedState(TreeViewItem item, int row, bool expan } } - internal void ChangeExpandedState(TreeViewItem item, bool expand, bool includeChildren) + internal void ChangeExpandedState(TreeViewItem item, bool expand, bool includeChildren) { if (includeChildren) data.SetExpandedWithChildren(item, expand); @@ -970,7 +970,7 @@ void HandleUnusedEvents() } if (deselectOnUnhandledMouseDown && containsMouse && Event.current.button == 0 && state.selectedIDs.Count > 0) { - SetSelection(new int[0], false); + SetSelection(new TIdentifier[0], false); NotifyListenersThatSelectionChanged(); } @@ -997,11 +997,11 @@ public bool BeginNameEditing(float delay) return false; var visibleItems = data.GetRows(); - TreeViewItem visibleAndSelectedItem = null; + TreeViewItem visibleAndSelectedItem = null; - foreach (int id in state.selectedIDs) + foreach (TIdentifier id in state.selectedIDs) { - TreeViewItem item = visibleItems.FirstOrDefault(i => i.id == id); + TreeViewItem item = visibleItems.FirstOrDefault(i => i.id.Equals(id)); if (visibleAndSelectedItem == null) visibleAndSelectedItem = item; else if (item != null) @@ -1024,7 +1024,7 @@ public void EndNameEditing(bool acceptChanges) } } - TreeViewItem GetItemAndRowIndex(int id, out int row) + TreeViewItem GetItemAndRowIndex(TIdentifier id, out int row) { row = data.GetRow(id); if (row == -1) @@ -1032,7 +1032,7 @@ TreeViewItem GetItemAndRowIndex(int id, out int row) return data.GetItem(row); } - void HandleFastCollapse(TreeViewItem item, int row) + void HandleFastCollapse(TreeViewItem item, int row) { if (item.depth == 0) { @@ -1060,7 +1060,7 @@ void HandleFastCollapse(TreeViewItem item, int row) } } - void HandleFastExpand(TreeViewItem item, int row) + void HandleFastExpand(TreeViewItem item, int row) { int rowCount = data.rowCount; @@ -1075,7 +1075,7 @@ void HandleFastExpand(TreeViewItem item, int row) } } - private void ChangeFolding(int[] ids, bool expand) + private void ChangeFolding(TIdentifier[] ids, bool expand) { // Handle folding of single item and multiple items separately // Animation is only supported for folding of single item @@ -1085,7 +1085,7 @@ private void ChangeFolding(int[] ids, bool expand) ChangeFoldingForMultipleItems(ids, expand); } - private void ChangeFoldingForSingleItem(int id, bool expand) + private void ChangeFoldingForSingleItem(TIdentifier id, bool expand) { // Skip any ongoing animation first because it could affect the row count. // I.e. if the item to be collapsed is in a row that no longer exists after the animation is done and the rows refreshed in InitIfNeeded, skiping the animation later would cause an IndexOufOfBounds in HandleFastCollapse @@ -1093,7 +1093,7 @@ private void ChangeFoldingForSingleItem(int id, bool expand) expansionAnimator.SkipAnimating(); int row; - TreeViewItem item = GetItemAndRowIndex(id, out row); + TreeViewItem item = GetItemAndRowIndex(id, out row); if (item != null) { if (data.IsExpandable(item) && data.IsExpanded(item) != expand) @@ -1108,14 +1108,14 @@ private void ChangeFoldingForSingleItem(int id, bool expand) } } - private void ChangeFoldingForMultipleItems(int[] ids, bool expand) + private void ChangeFoldingForMultipleItems(TIdentifier[] ids, bool expand) { // Collect items that should be expanded/collapsed - var parents = new HashSet(); + var parents = new HashSet(); foreach (var id in ids) { int row; - TreeViewItem item = GetItemAndRowIndex(id, out row); + TreeViewItem item = GetItemAndRowIndex(id, out row); if (item != null) { if (data.IsExpandable(item) && data.IsExpanded(item) != expand) @@ -1132,7 +1132,7 @@ private void ChangeFoldingForMultipleItems(int[] ids, bool expand) } else { - var expandedIDs = new HashSet(data.GetExpandedIDs()); + var expandedIDs = new HashSet(data.GetExpandedIDs()); if (expand) expandedIDs.UnionWith(parents); else @@ -1193,7 +1193,7 @@ void KeyboardGUI() case KeyCode.PageUp: { Event.current.Use(); - TreeViewItem lastClickedItem = data.FindItem(state.lastClickedID); + TreeViewItem lastClickedItem = data.FindItem(state.lastClickedID); if (lastClickedItem != null) { int numRowsPageUp = gui.GetNumRowsOnPageUpDown(lastClickedItem, true, m_TotalRect.height); @@ -1205,7 +1205,7 @@ void KeyboardGUI() case KeyCode.PageDown: { Event.current.Use(); - TreeViewItem lastClickedItem = data.FindItem(state.lastClickedID); + TreeViewItem lastClickedItem = data.FindItem(state.lastClickedID); if (lastClickedItem != null) { int numRowsPageDown = gui.GetNumRowsOnPageUpDown(lastClickedItem, true, m_TotalRect.height); @@ -1237,10 +1237,10 @@ void KeyboardGUI() } } - static internal int GetIndexOfID(IList items, int id) + static internal int GetIndexOfID(IList> items, TIdentifier id) { for (int i = 0; i < items.Count; ++i) - if (items[i].id == id) + if (items[i].id.Equals(id)) return i; return -1; } @@ -1269,15 +1269,15 @@ public void OffsetSelection(int offset) SelectionByKey(visibleRows[newIndex]); } - public Func> getNewSelectionOverride { private get; set; } + public Func, bool, bool, List> getNewSelectionOverride { private get; set; } // Returns list of selected ids - List GetNewSelection(TreeViewItem clickedItem, bool keepMultiSelection, bool useShiftAsActionKey) + List GetNewSelection(TreeViewItem clickedItem, bool keepMultiSelection, bool useShiftAsActionKey) { if (getNewSelectionOverride != null) return getNewSelectionOverride(clickedItem, keepMultiSelection, useShiftAsActionKey); - var selectState = new TreeViewSelectState() { + var selectState = new TreeViewSelectState() { selectedIDs = state.selectedIDs, lastClickedID = state.lastClickedID, keepMultiSelection = keepMultiSelection, @@ -1287,19 +1287,19 @@ List GetNewSelection(TreeViewItem clickedItem, bool keepMultiSelection, boo return data.GetNewSelection(clickedItem, selectState); } - void SelectionByKey(TreeViewItem itemSelected) + void SelectionByKey(TreeViewItem itemSelected) { var newSelection = GetNewSelection(itemSelected, false, true); NewSelectionFromUserInteraction(newSelection, itemSelected.id); } - public void SelectionClick(TreeViewItem itemClicked, bool keepMultiSelection) + public void SelectionClick(TreeViewItem itemClicked, bool keepMultiSelection) { var newSelection = GetNewSelection(itemClicked, keepMultiSelection, false); - NewSelectionFromUserInteraction(newSelection, itemClicked != null ? itemClicked.id : 0); + NewSelectionFromUserInteraction(newSelection, itemClicked != null ? itemClicked.id : default); } - void NewSelectionFromUserInteraction(List newSelection, int itemID) + void NewSelectionFromUserInteraction(List newSelection, TIdentifier itemID) { state.lastClickedID = itemID; @@ -1370,13 +1370,13 @@ void ChangeScrollValue(float targetScrollPos, bool animated) } } - public void Frame(int id, bool frame, bool ping) + public void Frame(TIdentifier id, bool frame, bool ping) { const bool animated = false; Frame(id, frame, ping, animated); } - public void Frame(int id, bool frame, bool ping, bool animated) + public void Frame(TIdentifier id, bool frame, bool ping, bool animated) { float topPixelOfRow = -1f; @@ -1404,7 +1404,7 @@ public void Frame(int id, bool frame, bool ping, bool animated) if (topPixelOfRow >= 0f && row >= 0 && row < data.rowCount) { - TreeViewItem item = data.GetRows()[row]; + TreeViewItem item = data.GetRows()[row]; float scrollBarOffset = GetContentSize().y > m_TotalRect.height ? -kSpaceForScrollBar : 0f; gui.BeginPingItem(item, topPixelOfRow, m_TotalRect.width + scrollBarOffset); } @@ -1422,19 +1422,19 @@ public void EndPing() // Hidden items (under collapsed items) are added last - public List SortIDsInVisiblityOrder(IList ids) + public List SortIDsInVisiblityOrder(IList ids) { if (ids.Count <= 1) return ids.ToList(); // no sorting needed var visibleRows = data.GetRows(); - List sorted = new List(); + List sorted = new List(); for (int i = 0; i < visibleRows.Count; ++i) { - int id = visibleRows[i].id; + var id = visibleRows[i].id; for (int j = 0; j < ids.Count; ++j) { - if (ids[j] == id) + if (ids[j].Equals(id)) { sorted.Add(id); break; diff --git a/Editor/Mono/GUI/TreeView/TreeViewDataSource.cs b/Editor/Mono/GUI/TreeView/TreeViewDataSource.cs index 4c0c9d6b46..2ccff101e4 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewDataSource.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewDataSource.cs @@ -2,6 +2,7 @@ // Copyright (c) Unity Technologies. For terms of use, see // https://unity3d.com/legal/licenses/Unity_Reference_Only_License +using System; using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -16,27 +17,28 @@ namespace UnityEditor.IMGUI.Controls // // Note: if dealing with very large trees use LazyTreeViewDataSource instead: it assumes that tree only contains visible items. - internal abstract class TreeViewDataSource : ITreeViewDataSource +internal abstract class TreeViewDataSource : ITreeViewDataSource where TIdentifier : unmanaged, System.IEquatable { - protected readonly TreeViewController m_TreeView; // TreeView using this data source - protected TreeViewItem m_RootItem; - protected IList m_Rows; + protected TreeViewController m_TreeView { get { return m_TreeViewInternal; } set { m_TreeViewInternal = value; } } // TreeView using this data source + protected TreeViewController m_TreeViewInternal; // TreeView using this data source + protected TreeViewItem m_RootItem; + protected IList> m_Rows; protected bool m_NeedRefreshRows = true; - protected TreeViewItem m_FakeItem; + protected TreeViewItem m_FakeItem; public bool showRootItem { get; set; } public bool rootIsCollapsable { get; set; } public bool alwaysAddFirstItemToSearchResult { get; set; } // is only used in searches when showRootItem is false. It Doesn't make sense for visible roots - public TreeViewItem root { get { return m_RootItem; } } + public TreeViewItem root { get { return m_RootItem; } } public System.Action onVisibleRowsChanged; - protected List expandedIDs + protected List expandedIDs { get {return m_TreeView.state.expandedIDs; } set { m_TreeView.state.expandedIDs = value; } } - public TreeViewDataSource(TreeViewController treeView) + public TreeViewDataSource(TreeViewController treeView) { m_TreeView = treeView; showRootItem = true; @@ -58,27 +60,27 @@ public virtual void ReloadData() FetchData(); } - virtual public TreeViewItem FindItem(int id) + virtual public TreeViewItem FindItem(TIdentifier id) { - return TreeViewUtility.FindItem(id, m_RootItem); + return TreeViewUtility.FindItem(id, m_RootItem); } - virtual public bool IsRevealed(int id) + virtual public bool IsRevealed(TIdentifier id) { - IList rows = GetRows(); - return TreeViewController.GetIndexOfID(rows, id) >= 0; + IList> rows = GetRows(); + return TreeViewController.GetIndexOfID(rows, id) >= 0; } - virtual public void RevealItem(int id) + virtual public void RevealItem(TIdentifier id) { if (IsRevealed(id)) return; // Reveal (expand parents up to root) - TreeViewItem item = FindItem(id); + TreeViewItem item = FindItem(id); if (item != null) { - TreeViewItem parent = item.parent; + TreeViewItem parent = item.parent; while (parent != null) { SetExpanded(parent, true); @@ -87,9 +89,9 @@ virtual public void RevealItem(int id) } } - virtual public void RevealItems(int[] ids) + virtual public void RevealItems(TIdentifier[] ids) { - HashSet expandedSet = new HashSet(expandedIDs); + HashSet expandedSet = new HashSet(expandedIDs); int orgSize = expandedSet.Count; // Add all parents above id @@ -98,10 +100,10 @@ virtual public void RevealItems(int[] ids) if (IsRevealed(id)) continue; // Reveal (expand parents up to root) - TreeViewItem item = FindItem(id); + TreeViewItem item = FindItem(id); if (item != null) { - TreeViewItem parent = item.parent; + TreeViewItem parent = item.parent; while (parent != null) { expandedSet.Add(parent.id); @@ -129,42 +131,42 @@ virtual public void OnSearchChanged() //---------------------------- // Visible Item section - protected void GetVisibleItemsRecursive(TreeViewItem item, IList items) + protected void GetVisibleItemsRecursive(TreeViewItem item, IList> items) { if (item != m_RootItem || showRootItem) items.Add(item); if (item.hasChildren && IsExpanded(item)) - foreach (TreeViewItem child in item.children) + foreach (TreeViewItem child in item.children) GetVisibleItemsRecursive(child, items); } - protected void SearchRecursive(TreeViewItem item, string search, IList searchResult) + protected void SearchRecursive(TreeViewItem item, string search, IList> searchResult) { if (item.displayName.ToLower().Contains(search)) searchResult.Add(item); if (item.children != null) - foreach (TreeViewItem child in item.children) + foreach (TreeViewItem child in item.children) SearchRecursive(child, search, searchResult); } - virtual protected List ExpandedRows(TreeViewItem root) + virtual protected List> ExpandedRows(TreeViewItem root) { - var result = new List(); + var result = new List>(); GetVisibleItemsRecursive(m_RootItem, result); return result; } // Searches the current tree by displayName. - virtual protected List Search(TreeViewItem root, string search) + virtual protected List> Search(TreeViewItem root, string search) { - var result = new List(); + var result = new List>(); if (showRootItem) { SearchRecursive(root, search, result); - result.Sort(new TreeViewItemAlphaNumericSort()); + result.Sort(new TreeViewItemAlphaNumericSort()); } else { @@ -176,7 +178,7 @@ virtual protected List Search(TreeViewItem root, string search) { SearchRecursive(root.children[i], search, result); } - result.Sort(new TreeViewItemAlphaNumericSort()); + result.Sort(new TreeViewItemAlphaNumericSort()); if (alwaysAddFirstItemToSearchResult) result.Insert(0, root.children[0]); @@ -194,24 +196,25 @@ virtual public int rowCount } } - virtual public int GetRow(int id) + virtual public int GetRow(TIdentifier id) { var rows = GetRows(); for (int row = 0; row < rows.Count; ++row) { - if (rows[row].id == id) + if (rows[row].id.Equals(id)) return row; } return -1; } - virtual public TreeViewItem GetItem(int row) + virtual public TreeViewItem GetItem(int row) { return GetRows()[row]; } // Get the flattend tree of visible items. - virtual public IList GetRows() + virtual public IList> GetRows() => GetRowsInternal(); + virtual public IList> GetRowsInternal() { InitIfNeeded(); return m_Rows; @@ -232,7 +235,7 @@ virtual public void InitIfNeeded() else { Debug.LogError("TreeView root item is null. Ensure that your TreeViewDataSource sets up at least a root item."); - m_Rows = new List(); + m_Rows = new List>(); } m_NeedRefreshRows = false; @@ -254,25 +257,25 @@ public bool isInitialized //---------------------------- // Expanded/collapsed section - virtual public int[] GetExpandedIDs() + virtual public TIdentifier[] GetExpandedIDs() { return expandedIDs.ToArray(); } - virtual public void SetExpandedIDs(int[] ids) + virtual public void SetExpandedIDs(TIdentifier[] ids) { - expandedIDs = new List(ids); + expandedIDs = new List(ids); expandedIDs.Sort(); m_NeedRefreshRows = true; OnExpandedStateChanged(); } - virtual public bool IsExpanded(int id) + virtual public bool IsExpanded(TIdentifier id) { return expandedIDs.BinarySearch(id) >= 0; } - virtual public bool SetExpanded(int id, bool expand) + virtual public bool SetExpanded(TIdentifier id, bool expand) { bool expanded = IsExpanded(id); if (expand != expanded) @@ -294,12 +297,12 @@ virtual public bool SetExpanded(int id, bool expand) return false; } - virtual public void SetExpandedWithChildren(int id, bool expand) + virtual public void SetExpandedWithChildren(TIdentifier id, bool expand) { SetExpandedWithChildren(FindItem(id), expand); } - virtual public void SetExpandedWithChildren(TreeViewItem fromItem, bool expand) + virtual public void SetExpandedWithChildren(TreeViewItem fromItem, bool expand) { if (fromItem == null) { @@ -307,11 +310,11 @@ virtual public void SetExpandedWithChildren(TreeViewItem fromItem, bool expand) return; } - HashSet parents = new HashSet(); - TreeViewUtility.GetParentsBelowItem(fromItem, parents); + HashSet parents = new HashSet(); + TreeViewUtility.GetParentsBelowItem(fromItem, parents); // Get existing expanded in hashset - HashSet oldExpandedSet = new HashSet(expandedIDs); + HashSet oldExpandedSet = new HashSet(expandedIDs); if (expand) oldExpandedSet.UnionWith(parents); @@ -322,17 +325,19 @@ virtual public void SetExpandedWithChildren(TreeViewItem fromItem, bool expand) SetExpandedIDs(oldExpandedSet.ToArray()); } - virtual public void SetExpanded(TreeViewItem item, bool expand) + virtual public void SetExpanded(TreeViewItem item, bool expand) { SetExpanded(item.id, expand); } - virtual public bool IsExpanded(TreeViewItem item) + virtual public bool IsExpanded(TreeViewItem item) => IsExpandedInternal(item); + virtual public bool IsExpandedInternal(TreeViewItem item) { return IsExpanded(item.id); } - virtual public bool IsExpandable(TreeViewItem item) + virtual public bool IsExpandable(TreeViewItem item) => IsExpandableInternal(item); + virtual public bool IsExpandableInternal(TreeViewItem item) { // Ignore expansion (foldout arrow) when showing search results if (m_TreeView.isSearching) @@ -340,27 +345,36 @@ virtual public bool IsExpandable(TreeViewItem item) return item.hasChildren; } - virtual public bool CanBeMultiSelected(TreeViewItem item) + virtual public bool CanBeMultiSelected(TreeViewItem item) { return true; } - virtual public bool CanBeParent(TreeViewItem item) + virtual public bool CanBeParent(TreeViewItem item) => CanBeParentInternal(item); + virtual public bool CanBeParentInternal(TreeViewItem item) { return true; } - virtual public List GetNewSelection(TreeViewItem clickedItem, TreeViewSelectState selectState) + virtual public List GetNewSelection(TreeViewItem clickedItem, TreeViewSelectState selectState) { // Get ids from items var visibleRows = GetRows(); - List allIDs = new List(visibleRows.Count); + List allIDs = new List(visibleRows.Count); for (int i = 0; i < visibleRows.Count; ++i) allIDs.Add(visibleRows[i].id); bool allowMultiselection = CanBeMultiSelected(clickedItem); - return InternalEditorUtility.GetNewSelection(clickedItem.id, allIDs, selectState.selectedIDs, selectState.lastClickedID, selectState.keepMultiSelection, selectState.useShiftAsActionKey, allowMultiselection); + // todo: add support for other types of TIdentifier, Importantly 'InstanceID' + if (clickedItem.id is int clickedIntID && selectState.lastClickedID is int lastClickedIntID) + return InternalEditorUtility.GetNewSelection( + clickedIntID, allIDs as List, + selectState.selectedIDs as List, + lastClickedIntID, selectState.keepMultiSelection, selectState.useShiftAsActionKey, allowMultiselection + ) as List; + + throw new System.NotImplementedException("InternalEditorUtility.GetNewSelection not implemented for type " + clickedItem.id.GetType()); } virtual public void OnExpandedStateChanged() @@ -372,7 +386,7 @@ virtual public void OnExpandedStateChanged() //---------------------------- // Renaming section - virtual public bool IsRenamingItemAllowed(TreeViewItem item) + virtual public bool IsRenamingItemAllowed(TreeViewItem item) { return true; } @@ -381,7 +395,7 @@ virtual public bool IsRenamingItemAllowed(TreeViewItem item) // Insert tempoary Item section // Fake Item should be inserted into the m_VisibleRows (not the tree itself). - virtual public void InsertFakeItem(int id, int parentID, string name, Texture2D icon) + virtual public void InsertFakeItem(TIdentifier id, TIdentifier parentID, string name, Texture2D icon) { Debug.LogError("InsertFakeItem missing implementation"); } @@ -397,7 +411,7 @@ virtual public void RemoveFakeItem() return; var visibleRows = GetRows(); - int index = TreeViewController.GetIndexOfID(visibleRows, m_FakeItem.id); + int index = TreeViewController.GetIndexOfID(visibleRows, m_FakeItem.id); if (index != -1) { visibleRows.RemoveAt(index); diff --git a/Editor/Mono/GUI/TreeView/TreeViewDragging.cs b/Editor/Mono/GUI/TreeView/TreeViewDragging.cs index 086f9ca587..4680c4c22b 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewDragging.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewDragging.cs @@ -19,13 +19,13 @@ namespace UnityEditor.IMGUI.Controls // - internal abstract class TreeViewDragging : ITreeViewDragging + internal abstract class TreeViewDragging : ITreeViewDragging where TIdentifier : unmanaged, IEquatable { - protected TreeViewController m_TreeView; + protected TreeViewController m_TreeView; protected class DropData { - public int[] expandedArrayBeforeDrag; + public TIdentifier[] expandedArrayBeforeDrag; public int lastControlID = -1; public int dropTargetControlID = -1; public int rowMarkerControlID = -1; @@ -33,7 +33,7 @@ protected class DropData public double expandItemBeginTimer; public Vector2 expandItemBeginPosition; public float insertionMarkerYPosition; - public TreeViewItem insertRelativeToSibling; + public TreeViewItem insertRelativeToSibling; public void ClearPerEventState() { @@ -60,7 +60,7 @@ static class Constants public const string GetInsertionIndexNotFound = "Did not find targetItem,; should be a child of parentItem"; } - public TreeViewDragging(TreeViewController treeView) + public TreeViewDragging(TreeViewController treeView) { m_TreeView = treeView; } @@ -86,18 +86,20 @@ public int GetAncestorControlID() public bool drawRowMarkerAbove { get; set; } public float insertionMarkerYPosition { get { return m_DropData.insertionMarkerYPosition; } } - public TreeViewItem insertRelativeToSibling { get { return m_DropData.insertRelativeToSibling; } } + public TreeViewItem insertRelativeToSibling { get { return m_DropData.insertRelativeToSibling; } } public Func getIndentLevelForMouseCursor; - public virtual bool CanStartDrag(TreeViewItem targetItem, List draggedItemIDs, Vector2 mouseDownPosition) + public virtual bool CanStartDrag(TreeViewItem targetItem, List draggedItemIDs, Vector2 mouseDownPosition) => CanStartDragInternal(targetItem, draggedItemIDs, mouseDownPosition); + public virtual bool CanStartDragInternal(TreeViewItem targetItem, List draggedItemIDs, Vector2 mouseDownPosition) { return true; } // This method is called from TreeView when a drag is started // Client should setup the drag data - public abstract void StartDrag(TreeViewItem draggedItem, List draggedItemIDs); + public virtual void StartDragInternal(TreeViewItem draggedItem, List draggedItemIDs){} + public virtual void StartDrag(TreeViewItem draggedItem, List draggedItemIDs) => StartDragInternal(draggedItem, draggedItemIDs); // This method is called from within DragElement when it has determined what is the parent item of the current targetItem // (This depends on if dropPosition is above, below or upon) @@ -110,14 +112,15 @@ public virtual bool CanStartDrag(TreeViewItem targetItem, List draggedItemI // if targetItem is null then parent can be null if root is visible // if targetitem is null then parent might be valid if root is hidden - public abstract DragAndDropVisualMode DoDrag(TreeViewItem parentItem, TreeViewItem targetItem, bool perform, DropPosition dropPosition); + public virtual DragAndDropVisualMode DoDrag(TreeViewItem parentItem, TreeViewItem targetItem, bool perform, DropPosition dropPosition) => DoDragInternal(parentItem, targetItem, perform, dropPosition); + public virtual DragAndDropVisualMode DoDragInternal(TreeViewItem parentItem, TreeViewItem targetItem, bool perform, DropPosition dropPosition) => throw new NotImplementedException(); - protected float GetDropBetweenHalfHeight(TreeViewItem item, Rect itemRect) + protected float GetDropBetweenHalfHeight(TreeViewItem item, Rect itemRect) { return m_TreeView.data.CanBeParent(item) ? m_TreeView.gui.halfDropBetweenHeight : itemRect.height * 0.5f; } - void GetPreviousAndNextItemsIgnoringDraggedItems(int targetRow, DropPosition dropPosition, out TreeViewItem previousItem, out TreeViewItem nextItem) + void GetPreviousAndNextItemsIgnoringDraggedItems(int targetRow, DropPosition dropPosition, out TreeViewItem previousItem, out TreeViewItem nextItem) { if (dropPosition != DropPosition.Above && dropPosition != DropPosition.Below) throw new ArgumentException("Invalid argument: " + dropPosition); @@ -149,14 +152,14 @@ void GetPreviousAndNextItemsIgnoringDraggedItems(int targetRow, DropPosition dro } } - internal void HandleSiblingInsertionAtAvailableDepthsAndChangeTargetIfNeeded(ref TreeViewItem targetItem, int targetItemRow, ref DropPosition dropPosition, int cursorDepth, out bool didChangeTargetToAncestor) + internal void HandleSiblingInsertionAtAvailableDepthsAndChangeTargetIfNeeded(ref TreeViewItem targetItem, int targetItemRow, ref DropPosition dropPosition, int cursorDepth, out bool didChangeTargetToAncestor) { if (dropPosition != DropPosition.Above && dropPosition != DropPosition.Below) throw new ArgumentException("Invalid argument: " + dropPosition); didChangeTargetToAncestor = false; - TreeViewItem prevItem, nextItem; + TreeViewItem prevItem, nextItem; GetPreviousAndNextItemsIgnoringDraggedItems(targetItemRow, dropPosition, out prevItem, out nextItem); if (prevItem == null) @@ -205,7 +208,7 @@ internal void HandleSiblingInsertionAtAvailableDepthsAndChangeTargetIfNeeded(ref targetItem = target; } - protected bool TryGetDropPosition(TreeViewItem item, Rect itemRect, int row, out DropPosition dropPosition) + protected bool TryGetDropPosition(TreeViewItem item, Rect itemRect, int row, out DropPosition dropPosition) { Vector2 currentMousePos = Event.current.mousePosition; @@ -266,7 +269,8 @@ protected bool TryGetDropPosition(TreeViewItem item, Rect itemRect, int row, out // - Auto expansion of collapsed items when hovering over them // - Setting up the render markers for drop location (horizontal lines) // 'targetItem' is null when not hovering over any target Item, if so the rest of the arguments are invalid - public virtual bool DragElement(TreeViewItem targetItem, Rect targetItemRect, int row) + public virtual bool DragElement(TreeViewItem targetItem, Rect targetItemRect, int row) => DragElementInternal(targetItem, targetItemRect, row); + public virtual bool DragElementInternal(TreeViewItem targetItem, Rect targetItemRect, int row) { bool perform = Event.current.type == EventType.DragPerform; @@ -291,8 +295,8 @@ public virtual bool DragElement(TreeViewItem targetItem, Rect targetItemRect, in if (!TryGetDropPosition(targetItem, targetItemRect, row, out dropPosition)) return false; - TreeViewItem parentItem = null; - TreeViewItem dropRelativeToItem = targetItem; + TreeViewItem parentItem = null; + TreeViewItem dropRelativeToItem = targetItem; bool didChangeTargetToAncestor = false; DropPosition originalDropPosition = dropPosition; switch (dropPosition) @@ -360,7 +364,7 @@ public virtual bool DragElement(TreeViewItem targetItem, Rect targetItemRect, in // Try drop on top of items if (dropPosition == DropPosition.Upon) { - int itemControlID = TreeViewController.GetItemControlID(dropRelativeToItem); + int itemControlID = TreeViewController.GetItemControlID(dropRelativeToItem); HandleAutoExpansion(itemControlID, dropRelativeToItem, targetItemRect); var mode = DoDrag(dropRelativeToItem, dropRelativeToItem, false, dropPosition); @@ -377,12 +381,12 @@ public virtual bool DragElement(TreeViewItem targetItem, Rect targetItemRect, in if (mode != DragAndDropVisualMode.None) { drawRowMarkerAbove = dropPosition == DropPosition.Above; - m_DropData.rowMarkerControlID = TreeViewController.GetItemControlID(dropRelativeToItem); + m_DropData.rowMarkerControlID = TreeViewController.GetItemControlID(dropRelativeToItem); m_DropData.insertionMarkerYPosition = originalDropPosition == DropPosition.Above ? targetItemRect.y : targetItemRect.yMax; m_DropData.insertRelativeToSibling = dropRelativeToItem; if (didChangeTargetToAncestor) { - m_DropData.ancestorControlID = TreeViewController.GetItemControlID(dropRelativeToItem); + m_DropData.ancestorControlID = TreeViewController.GetItemControlID(dropRelativeToItem); } DragAndDrop.visualMode = mode; @@ -401,27 +405,32 @@ void FinalizeDragPerformed(bool revertExpanded) DragCleanup(revertExpanded); DragAndDrop.AcceptDrag(); - List objs = new List(DragAndDrop.objectReferences); // TODO, what about when dragging non objects... + if (m_TreeView is TreeViewController instanceIDTreeView) // todo: change to EntityId + { + List objs = new List(DragAndDrop.objectReferences); // TODO, what about when dragging non objects... - bool draggedItemsFromOwnTreeView = true; - if (objs.Count > 0 && objs[0] != null && TreeViewUtility.FindItemInList(objs[0].GetInstanceID(), m_TreeView.data.GetRows()) == null) - draggedItemsFromOwnTreeView = false; + bool draggedItemsFromOwnTreeView = true; + if (objs.Count > 0 && objs[0] != null && TreeViewUtility.FindItemInList(objs[0].GetInstanceID(), instanceIDTreeView.data.GetRows()) == null) + draggedItemsFromOwnTreeView = false; - int[] newSelection = new int[objs.Count]; - for (int i = 0; i < objs.Count; ++i) - { - if (objs[i] == null) - continue; + int[] newSelection = new int[objs.Count]; + for (int i = 0; i < objs.Count; ++i) + { + if (objs[i] == null) + continue; - newSelection[i] = (objs[i].GetInstanceID()); + newSelection[i] = (objs[i].GetInstanceID()); + } + + instanceIDTreeView.NotifyListenersThatDragEnded(newSelection, draggedItemsFromOwnTreeView); + if (objs.Count == 1) + undoActionName = "Drag and Drop " + objs[0].name; } - m_TreeView.NotifyListenersThatDragEnded(newSelection, draggedItemsFromOwnTreeView); - if (objs.Count == 1) - undoActionName = "Drag and Drop " + objs[0].name; + Undo.SetCurrentGroupName(undoActionName); } - protected virtual void HandleAutoExpansion(int itemControlID, TreeViewItem targetItem, Rect targetItemRect) + protected virtual void HandleAutoExpansion(int itemControlID, TreeViewItem targetItem, Rect targetItemRect) { Vector2 currentMousePos = Event.current.mousePosition; @@ -447,7 +456,7 @@ protected virtual void HandleAutoExpansion(int itemControlID, TreeViewItem targe // Store the expanded array prior to drag so we can revert it with a delay later if (m_DropData.expandedArrayBeforeDrag == null) { - List expandedIDs = GetCurrentExpanded(); + List expandedIDs = GetCurrentExpanded(); m_DropData.expandedArrayBeforeDrag = expandedIDs.ToArray(); } @@ -463,30 +472,30 @@ public virtual void DragCleanup(bool revertExpanded) { if (m_DropData.expandedArrayBeforeDrag != null && revertExpanded) { - RestoreExpanded(new List(m_DropData.expandedArrayBeforeDrag)); + RestoreExpanded(new List(m_DropData.expandedArrayBeforeDrag)); } m_DropData = new DropData(); } } - public List GetCurrentExpanded() + public List GetCurrentExpanded() { var visibleItems = m_TreeView.data.GetRows(); - List expandedIDs = (from item in visibleItems + List expandedIDs = (from item in visibleItems where m_TreeView.data.IsExpanded(item) select item.id).ToList(); return expandedIDs; } // We assume that we can only have expanded items during dragging - public void RestoreExpanded(List ids) + public void RestoreExpanded(List ids) { var visibleItems = m_TreeView.data.GetRows(); - foreach (TreeViewItem item in visibleItems) + foreach (TreeViewItem item in visibleItems) m_TreeView.data.SetExpanded(item, ids.Contains(item.id)); } - internal static int GetInsertionIndex(TreeViewItem parentItem, TreeViewItem targetItem, DropPosition dropPosition) + internal static int GetInsertionIndex(TreeViewItem parentItem, TreeViewItem targetItem, DropPosition dropPosition) { if (parentItem == null) return -1; diff --git a/Editor/Mono/GUI/TreeView/TreeViewExpandAnimator.cs b/Editor/Mono/GUI/TreeView/TreeViewExpandAnimator.cs index 7d9565121f..1842983f7b 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewExpandAnimator.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewExpandAnimator.cs @@ -11,18 +11,18 @@ namespace UnityEditor.IMGUI.Controls // Setup animation, tracks animation, fires callback when done (fully expanded/collapsed) // - internal class TreeViewItemExpansionAnimator + internal class TreeViewItemExpansionAnimator where TIdentifier : unmanaged, System.IEquatable { - TreeViewAnimationInput m_Setup; // when null we are not animating + TreeViewAnimationInput m_Setup; // when null we are not animating bool m_InsideGUIClip; Rect m_CurrentClipRect; static bool s_Debug = false; - public void BeginAnimating(TreeViewAnimationInput setup) + public void BeginAnimating(TreeViewAnimationInput setup) { if (m_Setup != null) { - if (m_Setup.item.id == setup.item.id && m_Setup.expanding != setup.expanding) + if (m_Setup.item.id.Equals(setup.item.id) && m_Setup.expanding != setup.expanding) { // If same item (changed expand/collapse while animating) then just change direction, but skip the time that already passed if (m_Setup.elapsedTime >= 0) @@ -64,7 +64,7 @@ public void SkipAnimating() } // Returns true if row should be culled - public bool CullRow(int row, ITreeViewGUI gui) + public bool CullRow(int row, ITreeViewGUI gui) { if (!isAnimating) { @@ -198,12 +198,12 @@ public void OnAfterAllRowsGUI() } } - public bool IsAnimating(int itemID) + public bool IsAnimating(TIdentifier itemID) { if (!isAnimating) return false; - return m_Setup.item.id == itemID; + return m_Setup.item.id.Equals(itemID); } // 1 fully expanded, 0 fully collapsed @@ -259,7 +259,7 @@ string DebugItemName(int row) } } - internal class TreeViewAnimationInput + internal class TreeViewAnimationInput where TIdentifier : unmanaged, System.IEquatable { public TreeViewAnimationInput() { @@ -302,10 +302,10 @@ public double elapsedTime public double animationDuration { get; set; } public bool expanding { get; set; } public bool includeChildren { get; set; } - public TreeViewItem item { get; set; } - public TreeViewController treeView { get; set; } + public TreeViewItem item { get; set; } + public TreeViewController treeView { get; set; } - public System.Action animationEnded; // set to get a callback when animation ends + public System.Action> animationEnded; // set to get a callback when animation ends public void FireAnimationEndedEvent() { diff --git a/Editor/Mono/GUI/TreeView/TreeViewGUI.cs b/Editor/Mono/GUI/TreeView/TreeViewGUI.cs index 007ef5531c..3ec4cc95c5 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewGUI.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewGUI.cs @@ -10,9 +10,9 @@ namespace UnityEditor.IMGUI.Controls { - internal abstract class TreeViewGUI : ITreeViewGUI + internal abstract class TreeViewGUI : ITreeViewGUI where TIdentifier : unmanaged, IEquatable { - protected TreeViewController m_TreeView; + protected TreeViewController m_TreeView; protected PingData m_Ping = new PingData(); protected Rect m_DraggingInsertionMarkerRect; protected Rect m_DraggingAncestorMarkerRect; @@ -22,8 +22,8 @@ internal abstract class TreeViewGUI : ITreeViewGUI public float iconLeftPadding { get; set; } public float iconRightPadding { get; set; } public float iconTotalPadding { get { return iconLeftPadding + iconRightPadding; } } - public System.Action iconOverlayGUI { get; set; } // Rect includes iconLeftPadding and iconRightPadding - public System.Action labelOverlayGUI { get; set; } + public System.Action , Rect> iconOverlayGUI { get; set; } // Rect includes iconLeftPadding and iconRightPadding + public System.Action , Rect> labelOverlayGUI { get; set; } private bool m_AnimateScrollBarOnExpandCollapse = true; @@ -153,12 +153,12 @@ protected float foldoutStyleWidth get { return foldoutStyle.fixedWidth; } } - public TreeViewGUI(TreeViewController treeView) + public TreeViewGUI(TreeViewController treeView) { m_TreeView = treeView; } - public TreeViewGUI(TreeViewController treeView, bool useHorizontalScroll) + public TreeViewGUI(TreeViewController treeView, bool useHorizontalScroll) { m_TreeView = treeView; m_UseHorizontalScroll = useHorizontalScroll; @@ -166,7 +166,7 @@ public TreeViewGUI(TreeViewController treeView, bool useHorizontalScroll) virtual public void OnInitialize() { - var dragging = m_TreeView.dragging as TreeViewDragging; + var dragging = m_TreeView.dragging as TreeViewDragging ; if (dragging != null) dragging.getIndentLevelForMouseCursor = GetIndentLevelForMouseCursor; } @@ -178,7 +178,7 @@ int GetIndentLevelForMouseCursor() return Mathf.FloorToInt((mousePosX - contentStartX) / indentWidth); } - internal Texture GetEffectiveIcon(TreeViewItem item, bool selected, bool focused) + internal Texture GetEffectiveIcon(TreeViewItem item, bool selected, bool focused) { var icon = GetIconForItem(item); @@ -193,12 +193,13 @@ internal Texture GetEffectiveIcon(TreeViewItem item, bool selected, bool focused return icon; } - protected virtual Texture GetIconForItem(TreeViewItem item) + protected virtual Texture GetIconForItem(TreeViewItem item) => GetIconForItemInternal(item); + protected virtual Texture GetIconForItemInternal(TreeViewItem item) { return item.icon; } - internal virtual Texture GetIconForSelectedItem(TreeViewItem item) + internal virtual Texture GetIconForSelectedItem(TreeViewItem item) { return EditorUtility.GetIconInActiveState(GetIconForItem(item)); } @@ -229,11 +230,11 @@ virtual public Vector2 GetTotalSize() return new Vector2(width, height); } - protected float GetMaxWidth(IList rows) + protected float GetMaxWidth(IList> rows) { float maxWidth = 1f; - foreach (TreeViewItem item in rows) + foreach (TreeViewItem item in rows) { float width = 0f; @@ -256,7 +257,7 @@ protected float GetMaxWidth(IList rows) return maxWidth; } - virtual public int GetNumRowsOnPageUpDown(TreeViewItem fromItem, bool pageUp, float heightOfTreeView) + virtual public int GetNumRowsOnPageUpDown(TreeViewItem fromItem, bool pageUp, float heightOfTreeView) { return (int)Mathf.Floor(heightOfTreeView / k_LineHeight); } @@ -309,7 +310,7 @@ void DrawDraggingInsertionMarkerIfNeeded() return; // If an inheriting class already set the m_DraggingInsertionMarkerRect we don't overwrite it - var dragging = m_TreeView.dragging as TreeViewDragging; + var dragging = m_TreeView.dragging as TreeViewDragging; if (dragging != null && dragging.insertionMarkerYPosition > 0 && m_DraggingInsertionMarkerRect.x == -1) { float xPos = GetContentIndent(dragging.insertRelativeToSibling) + extraInsertionMarkerIndent; @@ -341,13 +342,14 @@ virtual public void EndRowGUI() HandlePing(); } - virtual public void OnRowGUI(Rect rowRect, TreeViewItem item, int row, bool selected, bool focused) + virtual public void OnRowGUI(Rect rowRect, TreeViewItem item, int row, bool selected, bool focused) => OnRowGUIInternal(rowRect, item, row, selected, focused); + virtual public void OnRowGUIInternal(Rect rowRect, TreeViewItem item, int row, bool selected, bool focused) { DoItemGUI(rowRect, row, item, selected, focused, false); } // Override this method for custom rendering of background behind selection and drop effect rendering - protected virtual void DrawItemBackground(Rect rect, int row, TreeViewItem item, bool selected, bool focused) + protected virtual void DrawItemBackground(Rect rect, int row, TreeViewItem item, bool selected, bool focused) { if (item == m_TreeView.hoveredItem) { @@ -358,7 +360,7 @@ protected virtual void DrawItemBackground(Rect rect, int row, TreeViewItem item, } } - public virtual Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) + public virtual Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) { float offset = GetContentIndent(item) + extraSpaceBeforeIconAndLabel; @@ -370,11 +372,11 @@ public virtual Rect GetRenameRect(Rect rowRect, int row, TreeViewItem item) rowRect.height); } - virtual protected void DoItemGUI(Rect rect, int row, TreeViewItem item, bool selected, bool focused, bool useBoldFont) + virtual protected void DoItemGUI(Rect rect, int row, TreeViewItem item, bool selected, bool focused, bool useBoldFont) { EditorGUIUtility.SetIconSize(new Vector2(k_IconWidth, k_IconWidth)); // If not set we see icons scaling down if text is being cropped - int itemControlID = TreeViewController.GetItemControlID(item); + int itemControlID = TreeViewController.GetItemControlID(item); bool isRenamingThisItem = IsRenaming(item.id); bool showFoldout = m_TreeView.data.IsExpandable(item); @@ -411,7 +413,7 @@ virtual protected void DoItemGUI(Rect rect, int row, TreeViewItem item, bool sel } // Ancestor item marker is rendered after all rows in RowEndGUI - extra visual helper marker when previous sibling is far away from the cursor - var dragging = m_TreeView.dragging as TreeViewDragging; + var dragging = m_TreeView.dragging as TreeViewDragging; if (dragging != null && dragging.GetAncestorControlID() == itemControlID && dragging.insertRelativeToSibling != null) { m_DraggingAncestorMarkerRect = rect; @@ -462,7 +464,7 @@ float GetFoldoutYPosition(float rectY) return rectY + customFoldoutYOffset; } - protected virtual Rect DoFoldout(Rect rect, TreeViewItem item, int row) + protected virtual Rect DoFoldout(Rect rect, TreeViewItem item, int row) { float indent = GetFoldoutIndent(item); Rect foldoutRect = new Rect(rect.x + indent, GetFoldoutYPosition(rect.y), foldoutStyleWidth, k_LineHeight); @@ -470,7 +472,7 @@ protected virtual Rect DoFoldout(Rect rect, TreeViewItem item, int row) return foldoutRect; } - protected virtual void FoldoutButton(Rect foldoutRect, TreeViewItem item, int row, GUIStyle foldoutStyle) + protected virtual void FoldoutButton(Rect foldoutRect, TreeViewItem item, int row, GUIStyle foldoutStyle) { var expansionAnimator = m_TreeView.expansionAnimator; @@ -491,11 +493,11 @@ protected virtual bool DoFoldoutButton(Rect foldoutRect, bool expandedState, GUI return GUI.Toggle(foldoutRect, expandedState, GUIContent.none, foldoutStyle); } - protected virtual void OnAdditionalGUI(Rect rect, int row, TreeViewItem item, bool selected, bool focused) + protected virtual void OnAdditionalGUI(Rect rect, int row, TreeViewItem item, bool selected, bool focused) { } - protected virtual void OnContentGUI(Rect rect, int row, TreeViewItem item, string label, bool selected, bool focused, bool useBoldFont, bool isPinging) + protected virtual void OnContentGUI(Rect rect, int row, TreeViewItem item, string label, bool selected, bool focused, bool useBoldFont, bool isPinging) { if (Event.current.rawType != EventType.Repaint) return; @@ -542,7 +544,7 @@ protected virtual void OnContentGUI(Rect rect, int row, TreeViewItem item, strin // Ping Item // ------------- - virtual public void BeginPingItem(TreeViewItem item, float topPixelOfRow, float availableWidth) + virtual public void BeginPingItem(TreeViewItem item, float topPixelOfRow, float availableWidth) { if (item == null) return; @@ -592,17 +594,18 @@ void HandlePing() //------------------- // Rename section - protected RenameOverlay GetRenameOverlay() + protected RenameOverlay GetRenameOverlay() { return m_TreeView.state.renameOverlay; } - virtual protected bool IsRenaming(int id) + virtual protected bool IsRenaming(TIdentifier id) { - return GetRenameOverlay().IsRenaming() && GetRenameOverlay().userData == id && !GetRenameOverlay().isWaitingForDelay; + return GetRenameOverlay().IsRenaming() && GetRenameOverlay().userData.Equals(id) && !GetRenameOverlay().isWaitingForDelay; } - virtual public bool BeginRename(TreeViewItem item, float delay) + virtual public bool BeginRename(TreeViewItem item, float delay) => BeginRenameInternal(item, delay); + virtual public bool BeginRenameInternal(TreeViewItem item, float delay) { return GetRenameOverlay().BeginRename(item.displayName, item.id, delay); } @@ -635,7 +638,7 @@ virtual protected void ClearRenameAndNewItemState() GetRenameOverlay().Clear(); } - virtual public float GetFoldoutIndent(TreeViewItem item) + virtual public float GetFoldoutIndent(TreeViewItem item) { // Ignore depth when showing search results if (m_TreeView.isSearching) @@ -644,7 +647,7 @@ virtual public float GetFoldoutIndent(TreeViewItem item) return k_BaseIndent + item.depth * indentWidth; } - virtual public float GetContentIndent(TreeViewItem item) + virtual public float GetContentIndent(TreeViewItem item) { return GetFoldoutIndent(item) + foldoutStyleWidth + lineStyle.margin.left; } diff --git a/Editor/Mono/GUI/TreeView/TreeViewGUIWithCustomItemHeights.cs b/Editor/Mono/GUI/TreeView/TreeViewGUIWithCustomItemHeights.cs index f4f50e3e0b..0160532277 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewGUIWithCustomItemHeights.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewGUIWithCustomItemHeights.cs @@ -7,6 +7,10 @@ using UnityEditor.IMGUI.Controls; using UnityEngine; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using ITreeViewGUI = UnityEditor.IMGUI.Controls.ITreeViewGUI; + namespace UnityEditor { diff --git a/Editor/Mono/GUI/TreeView/TreeViewItem.cs b/Editor/Mono/GUI/TreeView/TreeViewItem.cs index 07e00b1518..e6697eaacf 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewItem.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewItem.cs @@ -8,36 +8,36 @@ namespace UnityEditor.IMGUI.Controls { - public class TreeViewItem : System.IComparable + public class TreeViewItem : System.IComparable> { - int m_ID; // The id should be unique for all items in TreeView because it is used for searching, selection etc. - TreeViewItem m_Parent; - List m_Children = null; + TIdentifier m_ID; // The id should be unique for all items in TreeView because it is used for searching, selection etc. + TreeViewItem m_Parent; + List> m_Children = null; int m_Depth; string m_DisplayName; Texture2D m_Icon; public TreeViewItem() { } - public TreeViewItem(int id) + public TreeViewItem(TIdentifier id) { m_ID = id; } - public TreeViewItem(int id, int depth) + public TreeViewItem(TIdentifier id, int depth) { m_ID = id; m_Depth = depth; } - public TreeViewItem(int id, int depth, string displayName) + public TreeViewItem(TIdentifier id, int depth, string displayName) { m_Depth = depth; m_ID = id; m_DisplayName = displayName; } - internal TreeViewItem(int id, int depth, TreeViewItem parent, string displayName) + internal TreeViewItem(TIdentifier id, int depth, TreeViewItem parent, string displayName) { m_Depth = depth; m_Parent = parent; @@ -45,18 +45,25 @@ internal TreeViewItem(int id, int depth, TreeViewItem parent, string displayName m_DisplayName = displayName; } - public virtual int id { get { return m_ID; } set { m_ID = value; } } + public virtual TIdentifier id { get { return m_ID; } set { m_ID = value; } } public virtual string displayName { get { return m_DisplayName; } set { m_DisplayName = value; } } public virtual int depth { get { return m_Depth; } set { m_Depth = value; } } public virtual bool hasChildren { get { return m_Children != null && m_Children.Count > 0; } } - public virtual List children { get { return m_Children; } set { m_Children = value; } } - public virtual TreeViewItem parent { get { return m_Parent; } set { m_Parent = value; } } + + internal virtual List> childrenInternal { get { return m_Children; } set { m_Children = value; } } + + public virtual List> children { get { return childrenInternal; } set { childrenInternal = value; } } + + internal virtual TreeViewItem ParentInternal { get { return m_Parent; } set { m_Parent = value; } } + + public virtual TreeViewItem parent { get => ParentInternal; set { ParentInternal = value; } } + public virtual Texture2D icon { get { return m_Icon; } set { m_Icon = value; } } - public void AddChild(TreeViewItem child) + public void AddChild(TreeViewItem child) { if (m_Children == null) - m_Children = new List(); + m_Children = new List>(); m_Children.Add(child); @@ -64,11 +71,16 @@ public void AddChild(TreeViewItem child) child.parent = this; } - public virtual int CompareTo(TreeViewItem other) + internal virtual int CompareToInternal(TreeViewItem other) { return displayName.CompareTo(other.displayName); } + public virtual int CompareTo(TreeViewItem other) + { + return CompareToInternal(other); + } + public override string ToString() { return string.Format("Item: '{0}' ({1}), has {2} children, depth {3}, parent id {4}", displayName, id, hasChildren ? children.Count : 0, depth, (parent != null) ? parent.id : -1); @@ -77,9 +89,9 @@ public override string ToString() internal static class TreeViewItemExtension { - internal static bool Exists(this TreeViewItem parentItem, Func condition) + internal static bool Exists(this TreeViewItem parentItem, Func, bool> condition) { - foreach (TreeViewItem tvitem in parentItem.hasChildren ? parentItem.children : new List()) + foreach (TreeViewItem tvitem in parentItem.hasChildren ? parentItem.children : new List>()) { if (condition(tvitem)) return true; @@ -91,9 +103,9 @@ internal static bool Exists(this TreeViewItem parentItem, Func + class TreeViewItemAlphaNumericSort : IComparer> { - public int Compare(TreeViewItem lhs, TreeViewItem rhs) + public int Compare(TreeViewItem lhs, TreeViewItem rhs) { if (lhs == rhs) return 0; if (lhs == null) return -1; diff --git a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTest.cs b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTest.cs index e1cf5d1224..f30d5a0de2 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTest.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTest.cs @@ -5,7 +5,11 @@ using UnityEditor.IMGUI.Controls; using UnityEngine; using UnityEngine.Profiling; - +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using ITreeViewGUI = UnityEditor.IMGUI.Controls.ITreeViewGUI; +using ITreeViewDragging = UnityEditor.IMGUI.Controls.ITreeViewDragging; +using ITreeViewDataSource = UnityEditor.IMGUI.Controls.ITreeViewDataSource; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor.TreeViewExamples { diff --git a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestDataSource.cs b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestDataSource.cs index 6fccb91416..aac6964149 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestDataSource.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestDataSource.cs @@ -5,6 +5,9 @@ using System.Collections.Generic; using UnityEditor.IMGUI.Controls; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewDataSource = UnityEditor.IMGUI.Controls.TreeViewDataSource; namespace UnityEditor.TreeViewExamples { diff --git a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestDragging.cs b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestDragging.cs index e48657c331..85413e725e 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestDragging.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestDragging.cs @@ -6,6 +6,10 @@ using System.Linq; using UnityEditor.IMGUI.Controls; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; +using TreeViewDragging = UnityEditor.IMGUI.Controls.TreeViewDragging; namespace UnityEditor.TreeViewExamples { diff --git a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestGUI.cs b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestGUI.cs index ef3cba4ea5..91d85dd09b 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestGUI.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestGUI.cs @@ -6,6 +6,11 @@ using UnityEditor.Experimental; using UnityEngine; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewGUI = UnityEditor.IMGUI.Controls.TreeViewGUI; + + namespace UnityEditor.TreeViewExamples { internal class FooTreeViewItem : TreeViewItem diff --git a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestGUICustom.cs b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestGUICustom.cs index 5b1e51a302..2f527e10a8 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestGUICustom.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestGUICustom.cs @@ -5,6 +5,8 @@ using System.ComponentModel; using UnityEditor.IMGUI.Controls; using UnityEngine; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; namespace UnityEditor.TreeViewExamples diff --git a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestLazyDataSource.cs b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestLazyDataSource.cs index 762c50d276..9879c2e91c 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestLazyDataSource.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestLazyDataSource.cs @@ -4,7 +4,9 @@ using System.Collections.Generic; using UnityEditor.IMGUI.Controls; - +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using LazyTreeViewDataSource = UnityEditor.IMGUI.Controls.LazyTreeViewDataSource; namespace UnityEditor.TreeViewExamples { diff --git a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestWithCustomHeight.cs b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestWithCustomHeight.cs index 700b25b8d1..d0903dd71f 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestWithCustomHeight.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewTests/TreeViewTestWithCustomHeight.cs @@ -4,7 +4,8 @@ using UnityEditor.IMGUI.Controls; using UnityEngine; - +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor.TreeViewExamples { diff --git a/Editor/Mono/GUI/TreeView/TreeViewUtililty.cs b/Editor/Mono/GUI/TreeView/TreeViewUtililty.cs index cf30e897fa..8b32e213a4 100644 --- a/Editor/Mono/GUI/TreeView/TreeViewUtililty.cs +++ b/Editor/Mono/GUI/TreeView/TreeViewUtililty.cs @@ -8,24 +8,24 @@ namespace UnityEditor.IMGUI.Controls { - internal static class TreeViewUtility + internal static class TreeViewUtility where TIdentifier : unmanaged, IEquatable { - internal static void SetParentAndChildrenForItems(IList rows, TreeViewItem root) + internal static void SetParentAndChildrenForItems(IList> rows, TreeViewItem root) { SetChildParentReferences(rows, root); } // For setting depths values based on children state of the items - internal static void SetDepthValuesForItems(TreeViewItem root) + internal static void SetDepthValuesForItems(TreeViewItem root) { if (root == null) throw new ArgumentNullException("root", "The root is null"); - Stack stack = new Stack(); + Stack> stack = new Stack>(); stack.Push(root); while (stack.Count > 0) { - TreeViewItem current = stack.Pop(); + TreeViewItem current = stack.Pop(); if (current.children != null) { foreach (var child in current.children) @@ -40,36 +40,36 @@ internal static void SetDepthValuesForItems(TreeViewItem root) } } - internal static List FindItemsInList(IEnumerable itemIDs, IList treeViewItems) + internal static List> FindItemsInList(IEnumerable itemIDs, IList> treeViewItems) { return (from x in treeViewItems where itemIDs.Contains(x.id) select x).ToList(); } - internal static TreeViewItem FindItemInList(int id, IList treeViewItems) where T : TreeViewItem + internal static TreeViewItem FindItemInList(TIdentifier id, IList treeViewItems) where T : TreeViewItem { - return treeViewItems.FirstOrDefault(t => t.id == id); + return treeViewItems.FirstOrDefault(t => t.id.Equals(id)); } // Assumes full tree - internal static TreeViewItem FindItem(int id, TreeViewItem searchFromThisItem) + internal static TreeViewItem FindItem(TIdentifier id, TreeViewItem searchFromThisItem) { return FindItemRecursive(id, searchFromThisItem); } - static TreeViewItem FindItemRecursive(int id, TreeViewItem item) + static TreeViewItem FindItemRecursive(TIdentifier id, TreeViewItem item) { if (item == null) return null; - if (item.id == id) + if (item.id.Equals(id)) return item; if (!item.hasChildren) return null; - foreach (TreeViewItem child in item.children) + foreach (TreeViewItem child in item.children) { - TreeViewItem result = FindItemRecursive(id, child); + TreeViewItem result = FindItemRecursive(id, child); if (result != null) return result; } @@ -77,12 +77,12 @@ static TreeViewItem FindItemRecursive(int id, TreeViewItem item) } // Assumes full tree - internal static void GetParentsAboveItem(TreeViewItem fromItem, HashSet parentsAbove) + internal static void GetParentsAboveItem(TreeViewItem fromItem, HashSet parentsAbove) { if (fromItem == null) throw new ArgumentNullException("fromItem"); - TreeViewItem parent = fromItem.parent; + TreeViewItem parent = fromItem.parent; while (parent != null) { parentsAbove.Add(parent.id); @@ -91,21 +91,21 @@ internal static void GetParentsAboveItem(TreeViewItem fromItem, HashSet par } // Assumes full tree - internal static void GetParentsBelowItem(TreeViewItem fromItem, HashSet parentsBelow) + internal static void GetParentsBelowItem(TreeViewItem fromItem, HashSet parentsBelow) { if (fromItem == null) throw new ArgumentNullException("fromItem"); - Stack stack = new Stack(); + Stack> stack = new Stack>(); stack.Push(fromItem); while (stack.Count > 0) { - TreeViewItem current = stack.Pop(); + TreeViewItem current = stack.Pop(); if (current.hasChildren) { parentsBelow.Add(current.id); - if (LazyTreeViewDataSource.IsChildListForACollapsedParent(current.children)) + if (LazyTreeViewDataSource.IsChildListForACollapsedParent(current.children)) throw new InvalidOperationException("Invalid tree for finding descendants: Ensure a complete tree when using this utillity method."); foreach (var foo in current.children) @@ -116,7 +116,7 @@ internal static void GetParentsBelowItem(TreeViewItem fromItem, HashSet par } } - internal static void DebugPrintToEditorLogRecursive(TreeViewItem item) + internal static void DebugPrintToEditorLogRecursive(TreeViewItem item) { if (item == null) return; @@ -125,14 +125,14 @@ internal static void DebugPrintToEditorLogRecursive(TreeViewItem item) if (!item.hasChildren) return; - foreach (TreeViewItem child in item.children) + foreach (TreeViewItem child in item.children) { DebugPrintToEditorLogRecursive(child); } } // Setup child and parent references based on the depth of the tree view items in 'visibleItems' - internal static void SetChildParentReferences(IList visibleItems, TreeViewItem root) + internal static void SetChildParentReferences(IList> visibleItems, TreeViewItem root) { for (int i = 0; i < visibleItems.Count; i++) visibleItems[i].parent = null; @@ -150,7 +150,7 @@ internal static void SetChildParentReferences(IList visibleItems, // Ensure items without a parent gets 'root' as parent if (rootChildCount > 0) { - var rootChildren = new List(rootChildCount); + var rootChildren = new List>(rootChildCount); for (int i = 0; i < visibleItems.Count; i++) { if (visibleItems[i].parent == null) @@ -162,21 +162,21 @@ internal static void SetChildParentReferences(IList visibleItems, root.children = rootChildren; } else - root.children = new List(); + root.children = new List>(); } - static void SetChildren(TreeViewItem item, List newChildList) + static void SetChildren(TreeViewItem item, List> newChildList) { // Do not touch children if we have a LazyParent and did not find any children == keep lazy children - if (LazyTreeViewDataSource.IsChildListForACollapsedParent(item.children) && newChildList == null) + if (LazyTreeViewDataSource.IsChildListForACollapsedParent(item.children) && newChildList == null) return; item.children = newChildList; } - static void SetChildParentReferences(int parentIndex, IList visibleItems) + static void SetChildParentReferences(int parentIndex, IList> visibleItems) { - TreeViewItem parent = visibleItems[parentIndex]; + TreeViewItem parent = visibleItems[parentIndex]; bool alreadyHasValidChildren = parent.children != null && parent.children.Count > 0 && parent.children[0] != null; if (alreadyHasValidChildren) return; @@ -194,10 +194,10 @@ static void SetChildParentReferences(int parentIndex, IList visibl } // Fill child array - List childList = null; + List> childList = null; if (childCount != 0) { - childList = new List(childCount); // Allocate once + childList = new List>(childCount); // Allocate once childCount = 0; for (int i = parentIndex + 1; i < visibleItems.Count; i++) { diff --git a/Editor/Mono/Handles/ConeHandle.cs b/Editor/Mono/Handles/ConeHandle.cs index 520ea1e943..0701aec6ac 100644 --- a/Editor/Mono/Handles/ConeHandle.cs +++ b/Editor/Mono/Handles/ConeHandle.cs @@ -9,6 +9,9 @@ namespace UnityEditor { public sealed partial class Handles { + static readonly int[] k_HandleIndices = { 0, 1, 0, 2, 0, 3, 0, 4 }; + static Vector3[] s_HandlePoints = new Vector3[5]; + internal static Vector2 DoConeHandle(Quaternion rotation, Vector3 position, Vector2 angleAndRange, float angleScale, float rangeScale, bool handlesOnly) { float spotAngle = angleAndRange.x; @@ -31,23 +34,27 @@ internal static Vector2 DoConeHandle(Quaternion rotation, Vector3 position, Vect temp = GUI.changed; GUI.changed = false; + var centerPos = position + forward * actualRange; float lightDisc = actualRange * Mathf.Tan(Mathf.Deg2Rad * spotAngle / 2.0f) * angleScale; - lightDisc = SizeSlider(position + forward * actualRange, up, lightDisc); - lightDisc = SizeSlider(position + forward * actualRange, -up, lightDisc); - lightDisc = SizeSlider(position + forward * actualRange, right, lightDisc); - lightDisc = SizeSlider(position + forward * actualRange, -right, lightDisc); + lightDisc = SizeSlider(centerPos, up, lightDisc); + lightDisc = SizeSlider(centerPos, -up, lightDisc); + lightDisc = SizeSlider(centerPos, right, lightDisc); + lightDisc = SizeSlider(centerPos, -right, lightDisc); if (GUI.changed) spotAngle = Mathf.Clamp((Mathf.Rad2Deg * Mathf.Atan(lightDisc / (actualRange * angleScale)) * 2), 0.0F, 179F); GUI.changed |= temp; // Draw disc - if (!handlesOnly) + if (!handlesOnly && Event.current.type == EventType.Repaint) { - Handles.DrawLine(position, (position + forward * actualRange) + up * lightDisc); - Handles.DrawLine(position, (position + forward * actualRange) - up * lightDisc); - Handles.DrawLine(position, (position + forward * actualRange) + right * lightDisc); - Handles.DrawLine(position, (position + forward * actualRange) - right * lightDisc); - DrawWireDisc(position + actualRange * forward, forward, lightDisc); + s_HandlePoints[0] = centerPos; + s_HandlePoints[1] = centerPos + up * lightDisc; + s_HandlePoints[2] = centerPos - up * lightDisc; + s_HandlePoints[3] = centerPos + right * lightDisc; + s_HandlePoints[4] = centerPos - right * lightDisc; + + DrawLines(s_HandlePoints, k_HandleIndices); + DrawWireDisc(centerPos, forward, lightDisc); } return new Vector2(spotAngle, range); diff --git a/Editor/Mono/ImportSettings/ExposeTransformEditor.cs b/Editor/Mono/ImportSettings/ExposeTransformEditor.cs index 1826944a34..5b4d7c1562 100644 --- a/Editor/Mono/ImportSettings/ExposeTransformEditor.cs +++ b/Editor/Mono/ImportSettings/ExposeTransformEditor.cs @@ -7,6 +7,9 @@ using System.Linq; using UnityEditor.IMGUI.Controls; using UnityEngine; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/Inspector/AvatarMaskInspector.cs b/Editor/Mono/Inspector/AvatarMaskInspector.cs index b5add5117b..7251d85b6a 100644 --- a/Editor/Mono/Inspector/AvatarMaskInspector.cs +++ b/Editor/Mono/Inspector/AvatarMaskInspector.cs @@ -8,6 +8,9 @@ using System.Linq; using UnityEditor.IMGUI.Controls; using UnityEngine.Profiling; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewUtility = UnityEditor.IMGUI.Controls.TreeViewUtility; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/Inspector/Core/ScriptAttributeGUI/Implementations/ExposedReferenceDrawer.cs b/Editor/Mono/Inspector/Core/ScriptAttributeGUI/Implementations/ExposedReferenceDrawer.cs index 4aaafc633b..e1e4ac1afa 100644 --- a/Editor/Mono/Inspector/Core/ScriptAttributeGUI/Implementations/ExposedReferenceDrawer.cs +++ b/Editor/Mono/Inspector/Core/ScriptAttributeGUI/Implementations/ExposedReferenceDrawer.cs @@ -4,6 +4,7 @@ using System; using UnityEditor; +using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; using ObjectField = UnityEditor.UIElements.ObjectField; @@ -156,16 +157,23 @@ public override VisualElement CreatePropertyGUI(SerializedProperty prop) obj.RegisterValueChangedCallback(SetReference); obj.AddManipulator(new ContextualMenuManipulator(BuildContextualMenu)); + obj.AddToClassList(ObjectField.alignedFieldUssClassName); + // Track for Undo/Redo changes which can come from exposedPropertyTable Undo.UndoRedoCallback undoRedoCallback = () => { m_Item.UpdateValue(); obj.SetValueWithoutNotify(m_Item.currentReferenceValue); }; + // Track the property for external changed including Undo/Redo + obj.TrackPropertyValue(prop, _ => undoRedoCallback()); obj.RegisterCallback(evt => Undo.undoRedoPerformed += undoRedoCallback); obj.RegisterCallback(evt => Undo.undoRedoPerformed -= undoRedoCallback); + // Set the serialized property so we can support drag and drop + obj.SetProperty(ObjectField.serializedPropertyKey, m_Item.exposedPropertyDefault); + return obj; } diff --git a/Editor/Mono/Inspector/LineRendererPositionsView.cs b/Editor/Mono/Inspector/LineRendererPositionsView.cs index daa98f69bd..445366004a 100644 --- a/Editor/Mono/Inspector/LineRendererPositionsView.cs +++ b/Editor/Mono/Inspector/LineRendererPositionsView.cs @@ -7,6 +7,9 @@ using System.Linq; using UnityEditor.IMGUI.Controls; using UnityEngine; +using TreeView = UnityEditor.IMGUI.Controls.TreeView; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor { diff --git a/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs b/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs index 6624dca5ec..5574480666 100644 --- a/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs +++ b/Editor/Mono/Inspector/PlayerSettingsEditor/PlayerSettingsEditor.cs @@ -165,6 +165,7 @@ class SettingsContent public static readonly GUIContent graphicsJobsNonExperimental = EditorGUIUtility.TrTextContent("Graphics Jobs"); public static readonly GUIContent graphicsJobsExperimental = EditorGUIUtility.TrTextContent("Graphics Jobs (Experimental)"); public static readonly GUIContent graphicsJobsMode = EditorGUIUtility.TrTextContent("Graphics Jobs Mode"); + public static readonly GUIContent graphicsJobsSyncAfterKick = EditorGUIUtility.TrTextContent("Sync after kick (fallback)", "This prevents graphics jobs from running in parallel to the render thread. Enable this if you see artifacts with graphics jobs."); public static readonly GUIContent applicationIdentifierWarning = EditorGUIUtility.TrTextContent("Invalid characters have been removed from the Application Identifier."); public static readonly GUIContent applicationIdentifierError = EditorGUIUtility.TrTextContent("The Application Identifier must follow the convention 'com.YourCompanyName.YourProductName' and must contain only alphanumeric and hyphen characters."); public static readonly GUIContent packageNameError = EditorGUIUtility.TrTextContent("The Package Name must follow the convention 'com.YourCompanyName.YourProductName' and must contain only alphanumeric and underscore characters. Each segment must start with an alphabetical character."); @@ -210,7 +211,7 @@ class SettingsContent public static readonly GUIContent managedStrippingLevel = EditorGUIUtility.TrTextContent("Managed Stripping Level", "If scripting backend is IL2CPP, managed stripping can't be disabled."); public static readonly GUIContent il2cppCompilerConfiguration = EditorGUIUtility.TrTextContent("C++ Compiler Configuration"); public static readonly GUIContent il2cppCodeGeneration = EditorGUIUtility.TrTextContent("IL2CPP Code Generation", "Determines whether IL2CPP should generate code optimized for runtime performance or build size/iteration."); - public static readonly GUIContent[] il2cppCodeGenerationNames = new GUIContent[] { EditorGUIUtility.TrTextContent("Faster runtime"), EditorGUIUtility.TrTextContent("Faster (smaller) builds") }; + public static readonly GUIContent[] il2cppCodeGenerationNames = new GUIContent[] { EditorGUIUtility.TrTextContent("Optimize for runtime speed"), EditorGUIUtility.TrTextContent("Optimize for code size and build time") }; public static readonly GUIContent il2cppStacktraceInformation = EditorGUIUtility.TrTextContent("IL2CPP Stacktrace Information", "Which information to include in stack traces. Including the file name and line number may increase build size."); public static readonly GUIContent scriptingMono2x = EditorGUIUtility.TrTextContent("Mono"); public static readonly GUIContent scriptingIL2CPP = EditorGUIUtility.TrTextContent("IL2CPP"); @@ -1028,7 +1029,7 @@ private bool HasReasonToCompile() private bool SupportsRunInBackground(NamedBuildTarget buildTarget) { - return buildTarget == NamedBuildTarget.Standalone; + return buildTarget == NamedBuildTarget.Standalone || buildTarget == NamedBuildTarget.VisionOS; } private void OnPresetSelectorClosed() @@ -2121,10 +2122,12 @@ private void OtherSectionShaderSettingsGUI(BuildPlatform platform) SettingsContent.shaderPrecisionModelOptions); if (EditorGUI.EndChangeCheck() && currShaderPrecisionModel != newShaderPrecisionModel) { - m_ShaderPrecisionModel.intValue = (int) newShaderPrecisionModel; + m_ShaderPrecisionModel.intValue = (int)newShaderPrecisionModel; serializedObject.ApplyModifiedProperties(); if (IsActivePlayerSettingsEditor()) - PlayerSettings.SyncShaderPrecisionModel(); + { + EditorApplication.delayCall += () => PlayerSettings.SyncShaderPrecisionModel(); + } } } @@ -2408,6 +2411,9 @@ private void OtherSectionRenderingGUI(BuildPlatform platform, ISettingEditorExte platform.namedBuildTarget.ToBuildTargetGroup() == BuildTargetGroup.Standalone ? EditorUserBuildSettings.selectedStandaloneTarget : platform.defaultTarget); bool newGraphicsJobs = graphicsJobs; + bool graphicsJobsSyncAfterKick = PlayerSettings.GetSwitchGraphicsJobsSyncAfterKick(); + bool newGraphicsJobsSyncAfterKick = graphicsJobsSyncAfterKick; + if (platform.namedBuildTarget == NamedBuildTarget.XboxOne) { // on XBoxOne, we only have kGfxJobModeNative active for DX12 API and kGfxJobModeLegacy for the DX11 API @@ -2464,6 +2470,23 @@ private void OtherSectionRenderingGUI(BuildPlatform platform, ISettingEditorExte { EditorGUILayout.Toggle(graphicsJobsGUI, graphicsJobs); } + // Optional fallback to previous graphics jobs implementation on Switch. + if (platform.namedBuildTarget == NamedBuildTarget.NintendoSwitch && newGraphicsJobs) + { + using (new EditorGUI.IndentLevelScope()) + { + /* (kaychang) Currently disabled. + if (GUI.enabled) + { + newGraphicsJobsSyncAfterKick = EditorGUILayout.Toggle(SettingsContent.graphicsJobsSyncAfterKick, graphicsJobsSyncAfterKick); + } + else + { + EditorGUILayout.Toggle(SettingsContent.graphicsJobsSyncAfterKick, graphicsJobsSyncAfterKick); + } + */ + } + } } if (EditorGUI.EndChangeCheck() && (newGraphicsJobs != graphicsJobs)) { @@ -2479,6 +2502,11 @@ private void OtherSectionRenderingGUI(BuildPlatform platform, ISettingEditorExte GUIUtility.ExitGUI(); } } + if (EditorGUI.EndChangeCheck() && (newGraphicsJobsSyncAfterKick != graphicsJobsSyncAfterKick)) + { + Undo.RecordObject(target, SettingsContent.undoChangedGraphicsJobsString); + PlayerSettings.SetSwitchGraphicsJobsSyncAfterKick(newGraphicsJobsSyncAfterKick); + } } if (gfxJobModesSupported && newGraphicsJobs) { diff --git a/Editor/Mono/Inspector/PlayerSettingsEditor/WebTemplateManagerBase.cs b/Editor/Mono/Inspector/PlayerSettingsEditor/WebTemplateManagerBase.cs index d065869d12..58df07491c 100644 --- a/Editor/Mono/Inspector/PlayerSettingsEditor/WebTemplateManagerBase.cs +++ b/Editor/Mono/Inspector/PlayerSettingsEditor/WebTemplateManagerBase.cs @@ -167,7 +167,7 @@ private List ListTemplates(string path) return templates; } - public void SelectionUI(SerializedProperty templateProp) + public void SelectionUI(SerializedProperty templateProp, PlayerSettings playerSettings) { if (s_Styles == null) s_Styles = new Styles(); @@ -219,9 +219,9 @@ public void SelectionUI(SerializedProperty templateProp) templateCustomKeys = Templates[GetTemplateIndex(templateProp.stringValue)].CustomKeys; foreach (string key in templateCustomKeys) { - string value = PlayerSettings.GetTemplateCustomValue(key); + string value = playerSettings.GetTemplateCustomValue_Internal(key); value = EditorGUILayout.TextField(PrettyTemplateKeyName(key), value); - PlayerSettings.SetTemplateCustomValue(key, value); + playerSettings.SetTemplateCustomValue_Internal(key, value); } } @@ -234,7 +234,7 @@ public void SelectionUI(SerializedProperty templateProp) GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; templateProp.serializedObject.ApplyModifiedProperties(); - PlayerSettings.templateCustomKeys = templateCustomKeys; + playerSettings.SetTemplateCustomKeys_Internal(templateCustomKeys); templateProp.serializedObject.Update(); } } diff --git a/Editor/Mono/Inspector/UnityEventDrawer.cs b/Editor/Mono/Inspector/UnityEventDrawer.cs index 8eff642116..edb3b4aa88 100644 --- a/Editor/Mono/Inspector/UnityEventDrawer.cs +++ b/Editor/Mono/Inspector/UnityEventDrawer.cs @@ -369,6 +369,23 @@ static PersistentListenerMode GetMode(SerializedProperty mode) return (PersistentListenerMode)mode.enumValueIndex; } + internal static bool ShouldClearMethodAfterTargetChanged(SerializedProperty listener, Object newValue) + { + // If the type is the same we dont need to clear the method + var typeProperty = listener.FindPropertyRelative(kInstanceTypePath); + var typeString = typeProperty.stringValue; + if (!string.IsNullOrEmpty(typeString)) + { + var objType = Type.GetType(typeString, false); + + if (objType == null || newValue == null || newValue.GetType() != objType) + return true; + } + + // Clear if the value is null + return newValue == null; + } + protected virtual void DrawEvent(Rect rect, int index, bool isActive, bool isFocused) { var pListener = m_ListenersArray.GetArrayElementAtIndex(index); @@ -396,8 +413,10 @@ protected virtual void DrawEvent(Rect rect, int index, bool isActive, bool isFoc { GUI.Box(goRect, GUIContent.none); EditorGUI.PropertyField(goRect, listenerTarget, GUIContent.none); - if (EditorGUI.EndChangeCheck()) + if (EditorGUI.EndChangeCheck() && ShouldClearMethodAfterTargetChanged(pListener, listenerTarget.objectReferenceValue)) + { methodName.stringValue = null; + } } SerializedProperty argument = GetArgument(pListener); diff --git a/Editor/Mono/Modules/DefaultBuildProfileExtension.cs b/Editor/Mono/Modules/DefaultBuildProfileExtension.cs index 62c7a08245..b2fbeb940f 100644 --- a/Editor/Mono/Modules/DefaultBuildProfileExtension.cs +++ b/Editor/Mono/Modules/DefaultBuildProfileExtension.cs @@ -102,6 +102,10 @@ public virtual bool ShouldDrawLinkTimeOptimization() public virtual bool ShouldDrawExplicitNullCheckbox() => false; public virtual bool ShouldDrawExplicitDivideByZeroCheckbox() => false; public virtual bool ShouldDrawExplicitArrayBoundsCheckbox() => false; + public virtual bool ShouldDrawInstallInBuildFolderCheckbox() + { + return Unsupported.IsSourceBuild() && PostprocessBuildPlayer.SupportsInstallInBuildFolder(m_BuildTarget); + } protected virtual string GetPlatformProfileInfoMessage() { @@ -271,7 +275,7 @@ public void ShowCommonBuildOptions(BuildProfileWorkflowState workflowState) } } - if (Unsupported.IsSourceBuild() && PostprocessBuildPlayer.SupportsInstallInBuildFolder(m_BuildTarget)) + if (ShouldDrawInstallInBuildFolderCheckbox()) { using (new EditorGUILayout.HorizontalScope()) { diff --git a/Editor/Mono/Networking/PlayerConnection/ConnectionDropDown.cs b/Editor/Mono/Networking/PlayerConnection/ConnectionDropDown.cs index ce8e7aacec..471ab1c342 100644 --- a/Editor/Mono/Networking/PlayerConnection/ConnectionDropDown.cs +++ b/Editor/Mono/Networking/PlayerConnection/ConnectionDropDown.cs @@ -9,6 +9,9 @@ using UnityEditor.IMGUI.Controls; using UnityEditorInternal; using UnityEngine; +using TreeView = UnityEditor.IMGUI.Controls.TreeView; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; namespace UnityEditor.Networking.PlayerConnection { diff --git a/Editor/Mono/ObjectListArea.cs b/Editor/Mono/ObjectListArea.cs index 6de6b9415a..1b60892df3 100644 --- a/Editor/Mono/ObjectListArea.cs +++ b/Editor/Mono/ObjectListArea.cs @@ -10,6 +10,7 @@ using UnityEditorInternal; using AssetReference = UnityEditorInternal.InternalEditorUtility.AssetReference; using Object = UnityEngine.Object; +using RenameOverlay = UnityEditor.RenameOverlay; namespace UnityEditor { diff --git a/Editor/Mono/ObjectListLocalGroup.cs b/Editor/Mono/ObjectListLocalGroup.cs index 489cc06173..2f6007d459 100644 --- a/Editor/Mono/ObjectListLocalGroup.cs +++ b/Editor/Mono/ObjectListLocalGroup.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using Math = System.Math; using AssetReference = UnityEditorInternal.InternalEditorUtility.AssetReference; +using RenameOverlay = UnityEditor.RenameOverlay; namespace UnityEditor { diff --git a/Editor/Mono/ObjectNames.cs b/Editor/Mono/ObjectNames.cs index 07f1b878b1..6fda23fda4 100644 --- a/Editor/Mono/ObjectNames.cs +++ b/Editor/Mono/ObjectNames.cs @@ -111,6 +111,7 @@ private static string GetObjectTypeName([NotNull] Object o, bool multiObjectEdit public static string GetInspectorTitle(Object obj, bool multiObjectEditing) { + // Note: The following condition is true when the native MonoBehaviour/ScriptableObject is destroyed but not its managed counterpart if (obj == null && (object)obj != null && (obj is MonoBehaviour || obj is ScriptableObject)) return L10n.Tr(" (Script)"); diff --git a/Editor/Mono/ObjectSelector.cs b/Editor/Mono/ObjectSelector.cs index 40ba07442c..e43d9c5f19 100644 --- a/Editor/Mono/ObjectSelector.cs +++ b/Editor/Mono/ObjectSelector.cs @@ -19,6 +19,7 @@ using UnityEngine.UIElements; using UnityObject = UnityEngine.Object; using Scene = UnityEngine.SceneManagement.Scene; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; namespace UnityEditor { @@ -628,6 +629,12 @@ internal void Show(UnityObject obj, Type[] requiredTypes, UnityObject objectBein }; Action onSelectorClosed = (selectedObj, canceled) => { + bool notifySelectorClosedOnly = false; + if (m_SearchSessionHandler.context is ObjectSelectorSearchContext c) + { + notifySelectorClosedOnly = (c.endSessionModes & ObjectSelectorSearchEndSessionModes.CloseSelector) == ObjectSelectorSearchEndSessionModes.CloseSelector; + } + m_SearchSessionHandler.EndSession(); if (canceled) { @@ -643,9 +650,17 @@ internal void Show(UnityObject obj, Type[] requiredTypes, UnityObject objectBein } m_EditedProperty = null; - NotifySelectorClosed(false); - ObjectSelector.DestroySharedSelector(); + // When force closing the selector because we are opening a new ObjectSelector, we must not destroy the shared selector. + if (notifySelectorClosedOnly) + { + NotifySelectorClosed(false); + } + else + { + // This will call OnDisable, which will call NotifySelectorClosed(false) + DestroySharedSelector(); + } }; if (m_SearchSessionHandler.SelectObject(onSelectorClosed, onSelectionChanged)) diff --git a/Editor/Mono/ObjectTreeForSelector.cs b/Editor/Mono/ObjectTreeForSelector.cs index fe23d612d0..d343a05751 100644 --- a/Editor/Mono/ObjectTreeForSelector.cs +++ b/Editor/Mono/ObjectTreeForSelector.cs @@ -8,6 +8,10 @@ using UnityEditor.IMGUI.Controls; using UnityEngine; using UnityEngine.Events; +using TreeViewController = UnityEditor.IMGUI.Controls.TreeViewController; +using TreeViewItem = UnityEditor.IMGUI.Controls.TreeViewItem; +using TreeViewState = UnityEditor.IMGUI.Controls.TreeViewState; + namespace UnityEditor { diff --git a/Editor/Mono/Overlays/Overlay.cs b/Editor/Mono/Overlays/Overlay.cs index 01e17de559..2a145d453c 100644 --- a/Editor/Mono/Overlays/Overlay.cs +++ b/Editor/Mono/Overlays/Overlay.cs @@ -27,11 +27,14 @@ public abstract partial class Overlay public static readonly string ussClassName = "unity-overlay"; const string k_Highlight = "overlay-box-highlight"; const string k_Floating = "overlay--floating"; - internal const string headerTitle = "overlay-header__title"; + internal const string k_HeaderTitle = "overlay-header__title"; + internal const string k_HeaderIcon = "overlay-header__icon"; const string k_Collapsed = "unity-overlay--collapsed"; internal const string k_Header = "overlay-header"; const string k_Expanded = "unity-overlay--expanded"; internal const string k_CollapsedContent = "overlay-collapsed-content"; + internal const string k_UnfoldedContent = "overlay-panel-foldout-content-expanded"; + internal const string k_FoldedContent = "overlay-panel-foldout-content-collapsed"; const string k_CollapsedIconButton = "unity-overlay-collapsed-dropdown__icon"; internal const string k_ToolbarHorizontalLayout = "overlay-layout--toolbar-horizontal"; internal const string k_ToolbarVerticalLayout = "overlay-layout--toolbar-vertical"; @@ -49,6 +52,8 @@ public abstract partial class Overlay [SerializeField] bool m_Collapsed; [SerializeField] + bool m_Folded; + [SerializeField] bool m_Floating; [SerializeField] Vector2 m_FloatingSnapOffset; @@ -84,6 +89,7 @@ public abstract partial class Overlay VisualElement m_CollapsedContent; OverlayPopup m_ModalPopup; // collapsed popup root VisualElement m_RootVisualElement; + Toggle m_ToggleElement; VisualElement m_ResizeTarget; internal VisualElement resizeTarget => m_ResizeTarget; @@ -136,19 +142,7 @@ public Texture2D collapsedIcon if (m_CollapsedContent == null) return; - - var iconElement = collapsedContent.Q