Ver código fonte

Added select/deselect all in the editor.

Lasse Öörni 14 anos atrás
pai
commit
35e58c42f9

+ 36 - 10
Bin/Data/Scripts/Editor/EditorScene.as

@@ -26,6 +26,8 @@ Array<XMLFile@> copyBuffer;
 bool copyBufferLocal = false;
 bool copyBufferExpanded = false;
 
+bool inSelectionModify = false;
+
 void ClearSelection()
 {
     selectedNodes.Clear();
@@ -254,12 +256,26 @@ void EndModify(uint nodeID)
     }
 }
 
+void BeginSelectionModify()
+{
+    // A large operation on selected nodes is about to begin. Disable intermediate selection updates
+    inSelectionModify = true;
+}
+
+void EndSelectionModify()
+{
+    // The large operation on selected nodes has ended. Update node/component selection now
+    inSelectionModify = false;
+    HandleSceneWindowSelectionChange();
+}
+
 bool SceneDelete()
 {
     if (!CheckSceneWindowFocus() || (selectedComponents.empty && selectedNodes.empty))
         return false;
 
     ListView@ list = sceneWindow.GetChild("NodeList", true);
+    BeginSelectionModify();
 
     // Remove components first
     for (uint i = 0; i < selectedComponents.length; ++i)
@@ -286,10 +302,7 @@ bool SceneDelete()
 
         // If deleting only one component, select the next item in the same index
         if (selectedComponents.length == 1 && selectedNodes.empty)
-        {
             list.selection = index;
-            return true;
-        }
     }
 
     // Remove (parented) nodes last
@@ -312,16 +325,10 @@ bool SceneDelete()
 
         // If deleting only one node, select the next item in the same index
         if (selectedNodes.length == 1 && selectedComponents.empty)
-        {
             list.selection = nodeIndex;
-            return true;
-        }
     }
 
-    // If any kind of multi-delete was performed, the list selection should be clear now.
-    // Unfortunately that also means we did not get selection change events, so must update the selection arrays manually.
-    // Otherwise nodes/components may be left in the scene even after delete, as the selection arrays keep them alive.
-    HandleNodeListSelectionChange();
+    EndSelectionModify();
     return true;
 }
 
@@ -441,6 +448,25 @@ bool ScenePaste()
     return true;
 }
 
+void SceneSelectAll()
+{
+    ListView@ list = sceneWindow.GetChild("NodeList", true);
+    if (!list.selections.empty)
+    {
+        BeginSelectionModify();
+        list.ClearSelection();
+        EndSelectionModify();
+    }
+    else
+    {
+        BeginSelectionModify();
+        Array<Node@> rootLevelNodes = editorScene.GetChildren();
+        for (uint i = 0; i < rootLevelNodes.length; ++i)
+            list.AddSelection(GetNodeListIndex(rootLevelNodes[i]));
+        EndSelectionModify();
+    }
+}
+
 void CalculateNewTransform(Node@ source, Node@ target, Vector3& pos, Quaternion& rot, Vector3& scale)
 {
     Vector3 sourceWorldPos = source.worldPosition;

+ 11 - 7
Bin/Data/Scripts/Editor/EditorSceneWindow.as

@@ -49,10 +49,10 @@ 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", "HandleNodeListSelectionChange");
-    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "ItemDeselected", "HandleNodeListSelectionChange");
-    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "ItemDoubleClicked", "HandleNodeListItemDoubleClick");
-    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "UnhandledKey", "HandleNodeListKey");
+    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "ItemSelected", "HandleSceneWindowSelectionChange");
+    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "ItemDeselected", "HandleSceneWindowSelectionChange");
+    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "ItemDoubleClicked", "HandleSceneWindowItemDoubleClick");
+    SubscribeToEvent(sceneWindow.GetChild("NodeList", true), "UnhandledKey", "HandleSceneWindowKey");
     SubscribeToEvent(newNodeList, "ItemSelected", "HandleCreateNode");
     SubscribeToEvent(newComponentList, "ItemSelected", "HandleCreateComponent");
     SubscribeToEvent("DragDropTest", "HandleDragDropTest");
@@ -100,6 +100,7 @@ void ClearSceneWindow()
 {
     if (sceneWindow is null)
         return;
+
     ListView@ list = sceneWindow.GetChild("NodeList", true);
     list.RemoveAllItems();
 }
@@ -474,8 +475,11 @@ void SelectComponent(Component@ component, bool multiselect)
     }
 }
 
-void HandleNodeListSelectionChange()
+void HandleSceneWindowSelectionChange()
 {
+    if (inSelectionModify)
+        return;
+
     ClearSelection();
 
     ListView@ list = sceneWindow.GetChild("NodeList", true);
@@ -568,7 +572,7 @@ void HandleNodeListSelectionChange()
     UpdateNodeWindow();
 }
 
-void HandleNodeListItemDoubleClick(StringHash eventType, VariantMap& eventData)
+void HandleSceneWindowItemDoubleClick(StringHash eventType, VariantMap& eventData)
 {
     ListView@ list = sceneWindow.GetChild("NodeList", true);
 
@@ -584,7 +588,7 @@ void HandleNodeListItemDoubleClick(StringHash eventType, VariantMap& eventData)
         list.ToggleChildItemsVisible(index);
 }
 
-void HandleNodeListKey(StringHash eventType, VariantMap& eventData)
+void HandleSceneWindowKey(StringHash eventType, VariantMap& eventData)
 {
     int key = eventData["Key"].GetInt();
 }

+ 5 - 1
Bin/Data/Scripts/Editor/EditorUI.as

@@ -77,6 +77,7 @@ void CreateMenuBar()
         editPopup.AddChild(CreateMenuItem("Copy", 'C', QUAL_CTRL));
         editPopup.AddChild(CreateMenuItem("Paste", 'V', QUAL_CTRL));
         editPopup.AddChild(CreateMenuItem("Delete", KEY_DELETE, QUAL_ANY));
+        editPopup.AddChild(CreateMenuItem("Select all", 'A', QUAL_CTRL));
         editPopup.AddChild(CreateMenuDivider());
         editPopup.AddChild(CreateMenuItem("Toggle update", 'P', QUAL_CTRL));
         uiMenuBar.AddChild(editMenu);
@@ -280,7 +281,10 @@ void HandleMenuSelected(StringHash eventType, VariantMap& eventData)
     
     if (action == "Delete")
         SceneDelete();
-    
+        
+    if (action == "Select all")
+        SceneSelectAll();
+
     if (action == "Toggle update")
         ToggleUpdate();
 

+ 1 - 0
Docs/GettingStarted.dox

@@ -519,6 +519,7 @@ Ctrl+plus/minus - Scale node uniformly (scale mode only)
 Ctrl+O          - Open scene
 Ctrl+S          - Save scene
 Ctrl+Shift+S    - Save scene as
+Ctrl+A          - Select/deselect all root level nodes
 Ctrl+X,C,V      - Cut/copy/paste node or component
 Ctrl+H	        - Open the scene hierarchy window
 Ctrl+N	        - Open the node / component edit window

+ 5 - 5
Engine/Graphics/View.cpp

@@ -1017,13 +1017,13 @@ void View::ProcessShadowCasters(Light* light, unsigned splitIndex, const PODVect
 bool View::IsShadowCasterVisible(Drawable* drawable, BoundingBox lightViewBox, Camera* shadowCamera, const Matrix3x4& lightView,
     const Frustum& lightViewFrustum, const BoundingBox& lightViewFrustumBox)
 {
-    // If shadow caster is also an occluder, must let it be visible, because it has potentially already culled
-    // away other shadow casters (could also check the actual shadow occluder vector, but that would be slower)
-    if (drawable->IsOccluder())
-        return true;
-    
     if (shadowCamera->IsOrthographic())
     {
+        // If shadow caster is also an occluder, must let it be visible, because it has potentially already culled
+        // away other shadow casters (could also check the actual shadow occluder vector, but that would be slower)
+        if (drawable->IsOccluder())
+            return true;
+        
         // Extrude the light space bounding box up to the far edge of the frustum's light space bounding box
         lightViewBox.max_.z_ = Max(lightViewBox.max_.z_,lightViewFrustumBox.max_.z_);
         return lightViewFrustum.IsInsideFast(lightViewBox) != OUTSIDE;