Pārlūkot izejas kodu

Optimized large scene modify operations in the editor.

Lasse Öörni 14 gadi atpakaļ
vecāks
revīzija
cbac6a30a5

+ 30 - 27
Bin/Data/Scripts/Editor/EditorScene.as

@@ -274,21 +274,45 @@ bool SceneDelete()
     if (!CheckSceneWindowFocus() || (selectedComponents.empty && selectedNodes.empty))
         return false;
 
-    ListView@ list = sceneWindow.GetChild("NodeList", true);
     BeginSelectionModify();
+    ListView@ list = sceneWindow.GetChild("NodeList", true);
+    list.contentElement.DisableLayoutUpdate();
+
+    // Remove nodes
+    for (uint i = 0; i < selectedNodes.length; ++i)
+    {
+        Node@ node = selectedNodes[i];
+        if (node.parent is null || node.scene is null)
+            continue; // Root or already deleted
+
+        uint id = node.id;
+        uint nodeIndex = GetNodeListIndex(node);
+
+        BeginModify(id);
+        node.Remove();
+        EndModify(id);
+
+        UpdateSceneWindowNode(nodeIndex, null);
 
-    // Remove components first
+        // If deleting only one node, select the next item in the same index
+        if (selectedNodes.length == 1 && selectedComponents.empty)
+            list.selection = nodeIndex;
+    }
+
+    // Then remove components, if they still remain
     for (uint i = 0; i < selectedComponents.length; ++i)
     {
-        // Do not allow to remove the Octree, PhysicsWorld or DebugRenderer from the root node
         Component@ component = selectedComponents[i];
         Node@ node = component.node;
-        
+        if (node is null)
+            continue; // Already deleted
+
         uint index = GetComponentListIndex(component);
         uint nodeIndex = GetNodeListIndex(node);
         if (index == NO_ITEM || nodeIndex == NO_ITEM)
             continue;
 
+        // Do not allow to remove the Octree, PhysicsWorld or DebugRenderer from the root node
         if (node is editorScene && (component.typeName == "Octree" || component.typeName == "PhysicsWorld" ||
             component.typeName == "DebugRenderer"))
             continue;
@@ -305,29 +329,8 @@ bool SceneDelete()
             list.selection = index;
     }
 
-    // Remove (parented) nodes last
-    for (uint i = 0; i < selectedNodes.length; ++i)
-    {
-        Node@ node = selectedNodes[i];
-        if (node.parent is null)
-            continue;
-
-        uint id = node.id;
-        uint nodeIndex = GetNodeListIndex(node);
-
-        BeginModify(id);
-        node.Remove();
-        EndModify(id);
-
-        UpdateSceneWindowNode(nodeIndex, null);
-
-        // Select the next item in the same index
-
-        // If deleting only one node, select the next item in the same index
-        if (selectedNodes.length == 1 && selectedComponents.empty)
-            list.selection = nodeIndex;
-    }
-
+    list.contentElement.EnableLayoutUpdate();
+    list.contentElement.UpdateLayout();
     EndSelectionModify();
     return true;
 }

+ 2 - 3
Bin/Data/Scripts/Editor/EditorSceneWindow.as

@@ -49,8 +49,7 @@ void CreateSceneWindow()
     SubscribeToEvent(sceneWindow.GetChild("CloseButton", true), "Released", "HideSceneWindow");
     SubscribeToEvent(sceneWindow.GetChild("ExpandAllButton", true), "Released", "ExpandSceneHierarchy");
     SubscribeToEvent(sceneWindow.GetChild("CollapseAllButton", true), "Released", "CollapseSceneHierarchy");
-    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "ItemSelected", "HandleSceneWindowSelectionChange");
-    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "ItemDeselected", "HandleSceneWindowSelectionChange");
+    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "SelectionChanged", "HandleSceneWindowSelectionChange");
     SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "ItemDoubleClicked", "HandleSceneWindowItemDoubleClick");
     SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "UnhandledKey", "HandleSceneWindowKey");
     SubscribeToEvent(newNodeList, "ItemSelected", "HandleCreateNode");
@@ -479,7 +478,7 @@ void HandleSceneWindowSelectionChange()
 {
     if (inSelectionModify)
         return;
-
+    
     ClearSelection();
 
     ListView@ list = sceneWindow.GetChild("NodeList", true);

+ 2 - 0
Engine/UI/ListView.cpp

@@ -432,6 +432,8 @@ void ListView::SetSelections(const Set<unsigned>& indices)
             break;
     }
     
+    SendEvent(E_SELECTIONCHANGED);
+    
     UpdateSelectionEffect();
 }
 

+ 7 - 1
Engine/UI/UIEvents.h

@@ -154,13 +154,19 @@ EVENT(E_ITEMSELECTED, ItemSelected)
     PARAM(P_SELECTION, Selection);          // int
 }
 
-/// Listview item deselected
+/// Listview item deselected.
 EVENT(E_ITEMDESELECTED, ItemDeselected)
 {
     PARAM(P_ELEMENT, Element);              // UIElement pointer
     PARAM(P_SELECTION, Selection);          // int
 }
 
+/// Listview selection change finished.
+EVENT(E_SELECTIONCHANGED, SelectionChanged)
+{
+    PARAM(P_ELEMENT, Element);              // UIElement pointer
+}
+
 /// Listview item doubleclicked.
 EVENT(E_ITEMDOUBLECLICKED, ItemDoubleClicked)
 {