Browse Source

Added a toolbar to the editor.

primitivewaste 12 years ago
parent
commit
53f6483931

+ 1 - 0
Bin/Data/Scripts/Editor.as

@@ -9,6 +9,7 @@
 #include "Scripts/Editor/EditorMaterial.as"
 #include "Scripts/Editor/EditorSettings.as"
 #include "Scripts/Editor/EditorPreferences.as"
+#include "Scripts/Editor/EditorToolBar.as"
 #include "Scripts/Editor/EditorUI.as"
 #include "Scripts/Editor/EditorImport.as"
 

+ 20 - 29
Bin/Data/Scripts/Editor/EditorGizmo.as

@@ -323,6 +323,14 @@ bool MoveNodes(Vector3 adjust)
     {
         for (uint i = 0; i < editNodes.length; ++i)
         {
+            if (moveSnap)
+            {
+                float moveStepScaled = moveStep * snapScale;
+                adjust.x = Floor(adjust.x / moveStepScaled + 0.5) * moveStepScaled;
+                adjust.y = Floor(adjust.y / moveStepScaled + 0.5) * moveStepScaled;
+                adjust.z = Floor(adjust.z / moveStepScaled + 0.5) * moveStepScaled;
+            }
+
             Node@ node = editNodes[i];
             Vector3 nodeAdjust = adjust;
             if (axisMode == AXIS_LOCAL && editNodes.length == 1)
@@ -331,26 +339,7 @@ bool MoveNodes(Vector3 adjust)
             Vector3 worldPos = node.worldPosition;
             Vector3 oldPos = node.position;
 
-            if (!moveSnap)
-                worldPos += nodeAdjust;
-            else
-            {
-                if (nodeAdjust.x != 0)
-                {
-                    worldPos.x += nodeAdjust.x * moveStep;
-                    worldPos.x = Floor(worldPos.x / moveStep + 0.5) * moveStep;
-                }
-                if (nodeAdjust.y != 0)
-                {
-                    worldPos.y += nodeAdjust.y * moveStep;
-                    worldPos.y = Floor(worldPos.y / moveStep + 0.5) * moveStep;
-                }
-                if (nodeAdjust.z != 0)
-                {
-                    worldPos.z += nodeAdjust.z * moveStep;
-                    worldPos.z = Floor(worldPos.z / moveStep + 0.5) * moveStep;
-                }
-            }
+            worldPos += nodeAdjust;
 
             if (node.parent is null)
                 node.position = worldPos;
@@ -371,9 +360,10 @@ bool RotateNodes(Vector3 adjust)
 
     if (rotateSnap)
     {
-        adjust.x = Floor(adjust.x / rotateStep + 0.5) * rotateStep;
-        adjust.y = Floor(adjust.y / rotateStep + 0.5) * rotateStep;
-        adjust.z = Floor(adjust.z / rotateStep + 0.5) * rotateStep;
+        float rotateStepScaled = rotateStep * snapScale;
+        adjust.x = Floor(adjust.x / rotateStepScaled + 0.5) * rotateStepScaled;
+        adjust.y = Floor(adjust.y / rotateStepScaled + 0.5) * rotateStepScaled;
+        adjust.z = Floor(adjust.z / rotateStepScaled + 0.5) * rotateStepScaled;
     }
 
     if (adjust.length > M_EPSILON)
@@ -420,20 +410,21 @@ bool ScaleNodes(Vector3 adjust)
                 scale += adjust;
             else
             {
+                float scaleStepScaled = scaleStep * snapScale;
                 if (adjust.x != 0)
                 {
-                    scale.x += adjust.x * scaleStep;
-                    scale.x = Floor(scale.x / scaleStep + 0.5) * scaleStep;
+                    scale.x += adjust.x * scaleStepScaled;
+                    scale.x = Floor(scale.x / scaleStepScaled + 0.5) * scaleStepScaled;
                 }
                 if (adjust.y != 0)
                 {
-                    scale.y += adjust.y * scaleStep;
-                    scale.y = Floor(scale.y / scaleStep + 0.5) * scaleStep;
+                    scale.y += adjust.y * scaleStepScaled;
+                    scale.y = Floor(scale.y / scaleStepScaled + 0.5) * scaleStepScaled;
                 }
                 if (adjust.z != 0)
                 {
-                    scale.z += adjust.z * scaleStep;
-                    scale.z = Floor(scale.z / scaleStep + 0.5) * scaleStep;
+                    scale.z += adjust.z * scaleStepScaled;
+                    scale.z = Floor(scale.z / scaleStepScaled + 0.5) * scaleStepScaled;
                 }
             }
 

+ 1 - 1
Bin/Data/Scripts/Editor/EditorHierarchyWindow.as

@@ -57,7 +57,7 @@ void CreateHierarchyWindow()
     ui.root.AddChild(hierarchyWindow);
     int height = Min(ui.root.height - 60, 500);
     hierarchyWindow.SetSize(300, height);
-    hierarchyWindow.SetPosition(20, 60);
+    hierarchyWindow.SetPosition(10, 100);
     hierarchyWindow.opacity = uiMaxOpacity;
     hierarchyWindow.BringToFront();
 

+ 1 - 1
Bin/Data/Scripts/Editor/EditorInspectorWindow.as

@@ -115,7 +115,7 @@ void CreateAttributeInspectorWindow()
     ui.root.AddChild(attributeInspectorWindow);
     int height = Min(ui.root.height - 60, 500);
     attributeInspectorWindow.SetSize(300, height);
-    attributeInspectorWindow.SetPosition(ui.root.width - 20 - attributeInspectorWindow.width, 60);
+    attributeInspectorWindow.SetPosition(ui.root.width - 10 - attributeInspectorWindow.width, 100);
     attributeInspectorWindow.opacity = uiMaxOpacity;
     attributeInspectorWindow.BringToFront();
 

+ 2 - 0
Bin/Data/Scripts/Editor/EditorScene.as

@@ -349,6 +349,8 @@ bool ToggleSceneUpdate()
         audio.Play();
     else
         audio.Stop();
+
+    toolBarDirty = true;
     return true;
 }
 

+ 3 - 0
Bin/Data/Scripts/Editor/EditorSettings.as

@@ -208,18 +208,21 @@ void EditMoveSnap(StringHash eventType, VariantMap& eventData)
 {
     CheckBox@ edit = eventData["Element"].GetUIElement();
     moveSnap = edit.checked;
+    toolBarDirty = true;
 }
 
 void EditRotateSnap(StringHash eventType, VariantMap& eventData)
 {
     CheckBox@ edit = eventData["Element"].GetUIElement();
     rotateSnap = edit.checked;
+    toolBarDirty = true;
 }
 
 void EditScaleSnap(StringHash eventType, VariantMap& eventData)
 {
     CheckBox@ edit = eventData["Element"].GetUIElement();
     scaleSnap = edit.checked;
+    toolBarDirty = true;
 }
 
 void EditRememberResourcePath(StringHash eventType, VariantMap& eventData)

+ 436 - 0
Bin/Data/Scripts/Editor/EditorToolBar.as

@@ -0,0 +1,436 @@
+
+bool subscribedToEditorToolBar = false;
+bool toolBarDirty = true;
+UIElement@ toolBar;
+
+void CreateToolBar()
+{
+    toolBar = BorderImage("ToolBar");
+    toolBar.style = "EditorToolBar";
+    toolBar.SetLayout(LM_HORIZONTAL);
+    toolBar.layoutSpacing = 4;
+    toolBar.layoutBorder = IntRect(8, 4, 4, 8);
+    toolBar.opacity = uiMaxOpacity;
+    toolBar.SetFixedSize(graphics.width, 42);
+    toolBar.SetPosition(0, uiMenuBar.height);
+    ui.root.AddChild(toolBar);
+
+    UIElement@ runUpdateGroup = CreateGroup("RunUpdateGroup", LM_HORIZONTAL);
+    runUpdateGroup.AddChild(CreateToolBarToggle("RunUpdatePlay"));
+    runUpdateGroup.AddChild(CreateToolBarToggle("RunUpdatePause"));
+    FinalizeGroupHorizontal(runUpdateGroup, "ToolBarToggle");
+    toolBar.AddChild(runUpdateGroup);
+
+    toolBar.AddChild(CreateToolBarSpacer(4));
+    UIElement@ editModeGroup = CreateGroup("EditModeGroup", LM_HORIZONTAL);
+    editModeGroup.AddChild(CreateToolBarToggle("EditMove"));
+    editModeGroup.AddChild(CreateToolBarToggle("EditRotate"));
+    editModeGroup.AddChild(CreateToolBarToggle("EditScale"));
+    editModeGroup.AddChild(CreateToolBarToggle("EditSelect"));
+    FinalizeGroupHorizontal(editModeGroup, "ToolBarToggle");
+    toolBar.AddChild(editModeGroup);
+
+    UIElement@ axisModeGroup = CreateGroup("AxisModeGroup", LM_HORIZONTAL);
+    axisModeGroup.AddChild(CreateToolBarToggle("AxisWorld"));
+    axisModeGroup.AddChild(CreateToolBarToggle("AxisLocal"));
+    FinalizeGroupHorizontal(axisModeGroup, "ToolBarToggle");
+    toolBar.AddChild(axisModeGroup);
+
+    toolBar.AddChild(CreateToolBarSpacer(4));
+    toolBar.AddChild(CreateToolBarToggle("MoveSnap"));
+    toolBar.AddChild(CreateToolBarToggle("RotateSnap"));
+    toolBar.AddChild(CreateToolBarToggle("ScaleSnap"));
+
+    UIElement@ snapScaleModeGroup = CreateGroup("SnapScaleModeGroup", LM_HORIZONTAL);
+    snapScaleModeGroup.AddChild(CreateToolBarToggle("SnapScaleHalf"));
+    snapScaleModeGroup.AddChild(CreateToolBarToggle("SnapScaleQuarter"));
+    FinalizeGroupHorizontal(snapScaleModeGroup, "ToolBarToggle");
+    toolBar.AddChild(snapScaleModeGroup);
+
+    toolBar.AddChild(CreateToolBarSpacer(4));
+    UIElement@ pickModeGroup = CreateGroup("PickModeGroup", LM_HORIZONTAL);
+    pickModeGroup.AddChild(CreateToolBarToggle("PickGeometries"));
+    pickModeGroup.AddChild(CreateToolBarToggle("PickLights"));
+    pickModeGroup.AddChild(CreateToolBarToggle("PickZones"));
+    pickModeGroup.AddChild(CreateToolBarToggle("PickRigidBodies"));
+    pickModeGroup.AddChild(CreateToolBarToggle("PickUIElements"));
+    FinalizeGroupHorizontal(pickModeGroup, "ToolBarToggle");
+    toolBar.AddChild(pickModeGroup);
+
+    toolBar.AddChild(CreateToolBarSpacer(4));
+    UIElement@ fillModeGroup = CreateGroup("FillModeGroup", LM_HORIZONTAL);
+    fillModeGroup.AddChild(CreateToolBarToggle("FillPoint"));
+    fillModeGroup.AddChild(CreateToolBarToggle("FillWireFrame"));
+    fillModeGroup.AddChild(CreateToolBarToggle("FillSolid"));
+    FinalizeGroupHorizontal(fillModeGroup, "ToolBarToggle");
+    toolBar.AddChild(fillModeGroup);
+}
+
+Button@ CreateToolBarButton(const String&in title)
+{
+    Button@ button = Button(title);
+    button.defaultStyle = uiStyle;
+    button.style = "ToolBarButton";
+
+    CreateToolBarIcon(button);
+    return button;
+}
+
+CheckBox@ CreateToolBarToggle(const String&in title)
+{
+    CheckBox@ toggle = CheckBox(title);
+    toggle.defaultStyle = uiStyle;
+    toggle.style = "ToolBarToggle";
+
+    CreateToolBarIcon(toggle);
+    return toggle;
+}
+
+void CreateToolBarIcon(UIElement@ element)
+{
+    BorderImage@ icon = BorderImage("Icon");
+    icon.defaultStyle = iconStyle;
+    icon.style = element.name;
+    icon.SetFixedSize(30, 30);
+    element.AddChild(icon);
+}
+
+UIElement@ CreateGroup(const String&in title, LayoutMode layoutMode)
+{
+    UIElement@ group = UIElement(title);
+    group.defaultStyle = uiStyle;
+    group.layoutMode = layoutMode;
+    return group;
+}
+
+void FinalizeGroupHorizontal(UIElement@ group, const String&in baseStyle)
+{
+    for (uint i = 0; i < group.numChildren; ++i)
+    {
+        UIElement@ child = group.children[i];
+
+        if (i == 0 && i < group.numChildren - 1)
+            child.style = baseStyle + "GroupLeft";
+        else if (i < group.numChildren - 1)
+            child.style = baseStyle + "GroupMiddle";
+        else
+            child.style = baseStyle + "GroupRight";
+    }
+
+    group.maxSize = group.size;
+}
+
+UIElement@ CreateToolBarSpacer(uint width)
+{
+    UIElement@ spacer = UIElement();
+    spacer.SetFixedWidth(width);
+    return spacer;
+}
+
+void ToolBarRunUpdatePlay(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        runUpdate = true;
+    toolBarDirty = true;
+}
+
+void ToolBarRunUpdatePause(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        runUpdate = false;
+    toolBarDirty = true;
+}
+
+void ToolBarEditModeMove(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        editMode = EDIT_MOVE;
+    toolBarDirty = true;
+}
+
+void ToolBarEditModeRotate(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        editMode = EDIT_ROTATE;
+    toolBarDirty = true;
+}
+
+void ToolBarEditModeScale(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        editMode = EDIT_SCALE;
+    toolBarDirty = true;
+}
+
+void ToolBarEditModeSelect(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        editMode = EDIT_SELECT;
+    toolBarDirty = true;
+}
+
+void ToolBarAxisModeWorld(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        axisMode = AXIS_WORLD;
+    toolBarDirty = true;
+}
+
+void ToolBarAxisModeLocal(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        axisMode = AXIS_LOCAL;
+    toolBarDirty = true;
+}
+
+void ToolBarMoveSnap(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    moveSnap = edit.checked;
+    toolBarDirty = true;
+}
+
+void ToolBarRotateSnap(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    rotateSnap = edit.checked;
+    toolBarDirty = true;
+}
+
+void ToolBarScaleSnap(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    scaleSnap = edit.checked;
+    toolBarDirty = true;
+}
+
+void ToolBarSnapScaleModeHalf(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+    {
+        snapScaleMode = SNAP_SCALE_HALF;
+        snapScale = 0.5;
+    }
+    else if (snapScaleMode == SNAP_SCALE_HALF)
+    {
+        snapScaleMode = SNAP_SCALE_FULL;
+        snapScale = 1.0;
+    }
+    toolBarDirty = true;
+}
+
+void ToolBarSnapScaleModeQuarter(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+    {
+        snapScaleMode = SNAP_SCALE_QUARTER;
+        snapScale = 0.25;
+    }
+    else if (snapScaleMode == SNAP_SCALE_QUARTER)
+    {
+        snapScaleMode = SNAP_SCALE_FULL;
+        snapScale = 1.0;
+    }
+    toolBarDirty = true;
+}
+
+void ToolBarPickModeGeometries(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        pickMode = PICK_GEOMETRIES;
+    toolBarDirty = true;
+}
+
+void ToolBarPickModeLights(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        pickMode = PICK_LIGHTS;
+    toolBarDirty = true;
+}
+
+void ToolBarPickModeZones(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        pickMode = PICK_ZONES;
+    toolBarDirty = true;
+}
+
+void ToolBarPickModeRigidBodies(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        pickMode = PICK_RIGIDBODIES;
+    toolBarDirty = true;
+}
+
+void ToolBarPickModeUIElements(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+        pickMode = PICK_UI_ELEMENTS;
+    toolBarDirty = true;
+}
+
+void ToolBarFillModePoint(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+    {
+        fillMode = FILL_POINT;
+        camera.fillMode = fillMode;
+    }
+    toolBarDirty = true;
+}
+
+void ToolBarFillModeWireFrame(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+    {
+        fillMode = FILL_WIREFRAME;
+        camera.fillMode = fillMode;
+    }
+    toolBarDirty = true;
+}
+
+void ToolBarFillModeSolid(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    if (edit.checked)
+    {
+        fillMode = FILL_SOLID;
+        camera.fillMode = fillMode;
+    }
+    toolBarDirty = true;
+}
+
+void UpdateDirtyToolBar()
+{
+    if (toolBar is null || !toolBarDirty)
+        return;
+
+    CheckBox@ runUpdatePlayToggle = toolBar.GetChild("RunUpdatePlay", true);
+    if (runUpdatePlayToggle.checked != runUpdate)
+        runUpdatePlayToggle.checked = runUpdate;
+
+    CheckBox@ runUpdatePauseToggle = toolBar.GetChild("RunUpdatePause", true);
+    if (runUpdatePauseToggle.checked != (runUpdate == false))
+        runUpdatePauseToggle.checked = runUpdate == false;
+
+    CheckBox@ editMoveToggle = toolBar.GetChild("EditMove", true);
+    if (editMoveToggle.checked != (editMode == EDIT_MOVE))
+        editMoveToggle.checked = editMode == EDIT_MOVE;
+
+    CheckBox@ editRotateToggle = toolBar.GetChild("EditRotate", true);
+    if (editRotateToggle.checked != (editMode == EDIT_ROTATE))
+        editRotateToggle.checked = editMode == EDIT_ROTATE;
+
+    CheckBox@ editScaleToggle = toolBar.GetChild("EditScale", true);
+    if (editScaleToggle.checked != (editMode == EDIT_SCALE))
+        editScaleToggle.checked = editMode == EDIT_SCALE;
+
+    CheckBox@ editSelectToggle = toolBar.GetChild("EditSelect", true);
+    if (editSelectToggle.checked != (editMode == EDIT_SELECT))
+        editSelectToggle.checked = editMode == EDIT_SELECT;
+
+    CheckBox@ axisWorldToggle = toolBar.GetChild("AxisWorld", true);
+    if (axisWorldToggle.checked != (axisMode == AXIS_WORLD))
+        axisWorldToggle.checked = axisMode == AXIS_WORLD;
+
+    CheckBox@ axisLocalToggle = toolBar.GetChild("AxisLocal", true);
+    if (axisLocalToggle.checked != (axisMode == AXIS_LOCAL))
+        axisLocalToggle.checked = axisMode == AXIS_LOCAL;
+
+    CheckBox@ moveSnapToggle = toolBar.GetChild("MoveSnap", true);
+    if (moveSnapToggle.checked != moveSnap)
+        moveSnapToggle.checked = moveSnap;
+
+    CheckBox@ rotateSnapToggle = toolBar.GetChild("RotateSnap", true);
+    if (rotateSnapToggle.checked != rotateSnap)
+        rotateSnapToggle.checked = rotateSnap;
+
+    CheckBox@ scaleSnapToggle = toolBar.GetChild("ScaleSnap", true);
+    if (scaleSnapToggle.checked != scaleSnap)
+        scaleSnapToggle.checked = scaleSnap;
+
+    CheckBox@ snapStepHalfToggle = toolBar.GetChild("SnapScaleHalf", true);
+    if (snapStepHalfToggle.checked != (snapScaleMode == SNAP_SCALE_HALF))
+        snapStepHalfToggle.checked = snapScaleMode == SNAP_SCALE_HALF;
+
+    CheckBox@ snapStepQuarterToggle = toolBar.GetChild("SnapScaleQuarter", true);
+    if (snapStepQuarterToggle.checked != (snapScaleMode == SNAP_SCALE_QUARTER))
+        snapStepQuarterToggle.checked = snapScaleMode == SNAP_SCALE_QUARTER;
+
+    CheckBox@ pickGeometriesToggle = toolBar.GetChild("PickGeometries", true);
+    if (pickGeometriesToggle.checked != (pickMode == PICK_GEOMETRIES))
+        pickGeometriesToggle.checked = pickMode == PICK_GEOMETRIES;
+
+    CheckBox@ pickLightsToggle = toolBar.GetChild("PickLights", true);
+    if (pickLightsToggle.checked != (pickMode == PICK_LIGHTS))
+        pickLightsToggle.checked = pickMode == PICK_LIGHTS;
+
+    CheckBox@ pickZonesToggle = toolBar.GetChild("PickZones", true);
+    if (pickZonesToggle.checked != (pickMode == PICK_ZONES))
+        pickZonesToggle.checked = pickMode == PICK_ZONES;
+
+    CheckBox@ pickRigidBodiesToggle = toolBar.GetChild("PickRigidBodies", true);
+    if (pickRigidBodiesToggle.checked != (pickMode == PICK_RIGIDBODIES))
+        pickRigidBodiesToggle.checked = pickMode == PICK_RIGIDBODIES;
+
+    CheckBox@ pickUIElementsToggle = toolBar.GetChild("PickUIElements", true);
+    if (pickUIElementsToggle.checked != (pickMode == PICK_UI_ELEMENTS))
+        pickUIElementsToggle.checked = pickMode == PICK_UI_ELEMENTS;
+
+    CheckBox@ fillPointToggle = toolBar.GetChild("FillPoint", true);
+    if (fillPointToggle.checked != (fillMode == FILL_POINT))
+        fillPointToggle.checked = fillMode == FILL_POINT;
+
+    CheckBox@ fillWireFrameToggle = toolBar.GetChild("FillWireFrame", true);
+    if (fillWireFrameToggle.checked != (fillMode == FILL_WIREFRAME))
+        fillWireFrameToggle.checked = fillMode == FILL_WIREFRAME;
+
+    CheckBox@ fillSolidToggle = toolBar.GetChild("FillSolid", true);
+    if (fillSolidToggle.checked != (fillMode == FILL_SOLID))
+        fillSolidToggle.checked = fillMode == FILL_SOLID;
+
+    if (!subscribedToEditorToolBar)
+    {
+        SubscribeToEvent(runUpdatePlayToggle, "Toggled", "ToolBarRunUpdatePlay");
+        SubscribeToEvent(runUpdatePauseToggle, "Toggled", "ToolBarRunUpdatePause");
+        SubscribeToEvent(editMoveToggle, "Toggled", "ToolBarEditModeMove");
+        SubscribeToEvent(editRotateToggle, "Toggled", "ToolBarEditModeRotate");
+        SubscribeToEvent(editScaleToggle, "Toggled", "ToolBarEditModeScale");
+        SubscribeToEvent(editSelectToggle, "Toggled", "ToolBarEditModeSelect");
+        SubscribeToEvent(axisWorldToggle, "Toggled", "ToolBarAxisModeWorld");
+        SubscribeToEvent(axisLocalToggle, "Toggled", "ToolBarAxisModeLocal");
+        SubscribeToEvent(moveSnapToggle, "Toggled", "ToolBarMoveSnap");
+        SubscribeToEvent(rotateSnapToggle, "Toggled", "ToolBarRotateSnap");
+        SubscribeToEvent(scaleSnapToggle, "Toggled", "ToolBarScaleSnap");
+        SubscribeToEvent(snapStepHalfToggle, "Toggled", "ToolBarSnapScaleModeHalf");
+        SubscribeToEvent(snapStepQuarterToggle, "Toggled", "ToolBarSnapScaleModeQuarter");
+        SubscribeToEvent(pickGeometriesToggle, "Toggled", "ToolBarPickModeGeometries");
+        SubscribeToEvent(pickLightsToggle, "Toggled", "ToolBarPickModeLights");
+        SubscribeToEvent(pickZonesToggle, "Toggled", "ToolBarPickModeZones");
+        SubscribeToEvent(pickRigidBodiesToggle, "Toggled", "ToolBarPickModeRigidBodies");
+        SubscribeToEvent(pickUIElementsToggle, "Toggled", "ToolBarPickModeUIElements");
+        SubscribeToEvent(fillPointToggle, "Toggled", "ToolBarFillModePoint");
+        SubscribeToEvent(fillWireFrameToggle, "Toggled", "ToolBarFillModeWireFrame");
+        SubscribeToEvent(fillSolidToggle, "Toggled", "ToolBarFillModeSolid");
+        subscribedToEditorToolBar = true;
+    }
+
+    toolBarDirty = false;
+}

+ 4 - 0
Bin/Data/Scripts/Editor/EditorUI.as

@@ -53,6 +53,7 @@ void CreateUI()
 
     CreateCursor();
     CreateMenuBar();
+    CreateToolBar();
     CreateQuickMenu();
     CreateHierarchyWindow();
     CreateAttributeInspectorWindow();
@@ -1078,6 +1079,7 @@ void HandleKeyDown(StringHash eventType, VariantMap& eventData)
         }
         else
             SteppedObjectManipulation(key);
+        toolBarDirty = true;
     }
 }
 
@@ -1199,6 +1201,8 @@ void SetIconEnabledColor(UIElement@ element, bool enabled, bool partial = false)
 
 void UpdateDirtyUI()
 {
+    UpdateDirtyToolBar();
+
     // Perform hierarchy selection latently after the new selections are finalized (used in undo/redo action)
     if (!hierarchyUpdateSelections.empty)
     {

+ 20 - 17
Bin/Data/Scripts/Editor/EditorView.as

@@ -17,6 +17,13 @@ enum AxisMode
     AXIS_LOCAL
 }
 
+enum SnapScaleMode
+{
+    SNAP_SCALE_FULL = 0,
+    SNAP_SCALE_HALF,
+    SNAP_SCALE_QUARTER
+}
+
 Text@ editorModeText;
 Text@ renderStatsText;
 Text@ cameraPosText;
@@ -24,6 +31,7 @@ Text@ cameraPosText;
 EditMode editMode = EDIT_MOVE;
 AxisMode axisMode = AXIS_WORLD;
 FillMode fillMode = FILL_SOLID;
+SnapScaleMode snapScaleMode = SNAP_SCALE_FULL;
 
 float cameraBaseSpeed = 10;
 float cameraBaseRotationSpeed = 0.2;
@@ -34,6 +42,7 @@ float newNodeDistance = 20;
 float moveStep = 0.5;
 float rotateStep = 5;
 float scaleStep = 0.1;
+float snapScale = 1.0;
 bool moveSnap = false;
 bool rotateSnap = false;
 bool scaleSnap = false;
@@ -109,13 +118,13 @@ void CreateStatsBar()
 
     if (ui.root.width >= 1200)
     {
-        SetupStatsBarText(editorModeText, font, 0, 24, HA_LEFT, VA_TOP);
-        SetupStatsBarText(renderStatsText, font, 0, 24, HA_RIGHT, VA_TOP);
+        SetupStatsBarText(editorModeText, font, 4, 64, HA_LEFT, VA_TOP);
+        SetupStatsBarText(renderStatsText, font, -4, 64, HA_RIGHT, VA_TOP);
     }
     else
     {
-        SetupStatsBarText(editorModeText, font, 0, 24, HA_LEFT, VA_TOP);
-        SetupStatsBarText(renderStatsText, font, 0, 36, HA_LEFT, VA_TOP);
+        SetupStatsBarText(editorModeText, font, 4, 64, HA_LEFT, VA_TOP);
+        SetupStatsBarText(renderStatsText, font, 4, 78, HA_LEFT, VA_TOP);
     }
 
     SetupStatsBarText(cameraPosText, font, 0, 0, HA_LEFT, VA_BOTTOM);
@@ -251,13 +260,7 @@ void UpdateView(float timeStep)
 
         case EDIT_ROTATE:
             if (!rotateSnap)
-            {
-                Vector3 rotAdjust;
-                rotAdjust.x = adjust.z * rotateStep;
-                rotAdjust.y = adjust.x * rotateStep;
-                rotAdjust.z = adjust.y * rotateStep;
-                moved = RotateNodes(rotAdjust);
-            }
+                moved = RotateNodes(adjust * rotateStep);
             break;
 
         case EDIT_SCALE:
@@ -318,16 +321,16 @@ void SteppedObjectManipulation(int key)
 
     case EDIT_ROTATE:
         {
-            Vector3 rotAdjust;
-            rotAdjust.x = adjust.z * rotateStep;
-            rotAdjust.y = adjust.x * rotateStep;
-            rotAdjust.z = adjust.y * rotateStep;
-            moved = RotateNodes(rotAdjust);
+            float rotateStepScaled = rotateStep * snapScale;
+            moved = RotateNodes(adjust * rotateStepScaled);
         }
         break;
 
     case EDIT_SCALE:
-        moved = ScaleNodes(adjust * scaleStep);
+        {
+            float scaleStepScaled = scaleStep * snapScale;
+            moved = ScaleNodes(adjust * scaleStepScaled);
+        }
         break;
     }
 

BIN
Bin/Data/Textures/EditorIcons.png


BIN
Bin/Data/Textures/UI.png


+ 26 - 0
Bin/Data/UI/DefaultStyle.xml

@@ -258,5 +258,31 @@
         <attribute name="Selection Color" value="0.2 0.225 0.35 1" />
         <attribute name="Hover Color" value="0.3 0.4 0.7 1" />
     </element>
+    <element type="EditorToolBar" style="BorderImage">
+        <attribute name="Image Rect" value="48 0 64 16" />
+        <attribute name="Border" value="4 4 4 4" />
+    </element>
+    <element type="ToolBarButton" style="Button">
+        <attribute name="Min Size" value="34 34" />
+        <attribute name="Max Size" value="34 34" />
+        <attribute name="Layout Mode" value="Horizontal" />
+        <attribute name="Layout Border" value="2 2 2 2" />
+    </element>
+    <element type="ToolBarToggle" style="CheckBox">
+        <attribute name="Min Size" value="34 34" />
+        <attribute name="Max Size" value="34 34" />
+        <attribute name="Image Rect" value="208 0 224 16" />
+        <attribute name="Layout Mode" value="Horizontal" />
+        <attribute name="Layout Border" value="2 2 2 2" />
+    </element>
+    <element type="ToolBarToggleGroupLeft" style="ToolBarToggle">
+        <attribute name="Image Rect" value="160 32 176 48" />
+    </element>
+    <element type="ToolBarToggleGroupMiddle" style="ToolBarToggle">
+        <attribute name="Image Rect" value="192 32 208 48" />
+    </element>
+    <element type="ToolBarToggleGroupRight" style="ToolBarToggle">
+        <attribute name="Image Rect" value="224 32 240 48" />
+    </element>
     <element type="EditorAttributeEdit" style="LineEdit" auto="false" />
 </elements>

+ 84 - 0
Bin/Data/UI/EditorIcons.xml

@@ -203,4 +203,88 @@
         <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
         <attribute name="Image Rect" value="240 64 254 78" />
     </element>
+    <element type="EditMove">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="0 96 30 126" />
+    </element>
+    <element type="EditRotate">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="32 96 62 126" />
+    </element>
+    <element type="EditScale">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="64 96 94 126" />
+    </element>
+    <element type="EditSelect">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="96 96 126 126" />
+    </element>
+    <element type="MoveSnap">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="128 96 158 126" />
+    </element>
+    <element type="RotateSnap">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="160 96 190 126" />
+    </element>
+    <element type="ScaleSnap">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="192 96 222 126" />
+    </element>
+    <element type="SnapScaleHalf">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="224 96 254 126" />
+    </element>
+    <element type="SnapScaleQuarter">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="0 128 30 158" />
+    </element>
+    <element type="RunUpdatePlay">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="32 128 62 158" />
+    </element>
+    <element type="RunUpdatePause">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="64 128 94 158" />
+    </element>
+    <element type="PickGeometries">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="96 128 126 158" />
+    </element>
+    <element type="PickLights">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="128 128 158 158" />
+    </element>
+    <element type="PickZones">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="160 128 190 158" />
+    </element>
+    <element type="PickRigidBodies">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="192 128 222 158" />
+    </element>
+    <element type="PickUIElements">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="224 128 254 158" />
+    </element>
+    <element type="FillPoint">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="0 160 30 190" />
+    </element>
+    <element type="FillWireFrame">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="32 160 62 190" />
+    </element>
+    <element type="FillSolid">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="64 160 94 190" />
+    </element>
+    <element type="AxisWorld">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="96 160 126 190" />
+    </element>
+    <element type="AxisLocal">
+        <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
+        <attribute name="Image Rect" value="128 160 158 190" />
+    </element>
 </elements>