diff --git a/Source/Editor/Content/GUI/ContentView.cs b/Source/Editor/Content/GUI/ContentView.cs index bf9fb1715..a7dc7b18f 100644 --- a/Source/Editor/Content/GUI/ContentView.cs +++ b/Source/Editor/Content/GUI/ContentView.cs @@ -716,19 +716,24 @@ namespace FlaxEditor.Content.GUI case ContentViewType.Tiles: { float defaultItemsWidth = ContentItem.DefaultWidth * viewScale; - int itemsToFit = Mathf.FloorToInt(width / defaultItemsWidth); + int itemsToFit = Mathf.FloorToInt(width / defaultItemsWidth) - 1; + if (itemsToFit < 1) + itemsToFit = 1; float itemsWidth = width / Mathf.Max(itemsToFit, 1); + itemsWidth = Mathf.Floor(itemsWidth); float itemsHeight = itemsWidth / defaultItemsWidth * (ContentItem.DefaultHeight * viewScale); + itemsHeight = Mathf.Floor(itemsHeight); + x = itemsToFit == 1 ? 0 : itemsWidth / itemsToFit; for (int i = 0; i < _children.Count; i++) { var c = _children[i]; c.Bounds = new Rectangle(x, y, itemsWidth, itemsHeight); - x += itemsWidth; + x += itemsWidth + itemsWidth / itemsToFit; if (x + itemsWidth > width) { - x = 0; - y += itemsHeight + 1; + x = itemsToFit == 1 ? 0 : itemsWidth / itemsToFit; + y += itemsHeight + 5; } } if (x > 0) @@ -743,7 +748,7 @@ namespace FlaxEditor.Content.GUI { var c = _children[i]; c.Bounds = new Rectangle(x, y, width, itemsHeight); - y += itemsHeight + 1; + y += itemsHeight + 5; } y += 40.0f; diff --git a/Source/Editor/CustomEditors/GUI/PropertiesList.cs b/Source/Editor/CustomEditors/GUI/PropertiesList.cs index 68c503c1b..9ff1f2533 100644 --- a/Source/Editor/CustomEditors/GUI/PropertiesList.cs +++ b/Source/Editor/CustomEditors/GUI/PropertiesList.cs @@ -31,6 +31,7 @@ namespace FlaxEditor.CustomEditors.GUI private float _splitterValue; private Rectangle _splitterRect; private bool _splitterClicked, _mouseOverSplitter; + private bool _cursorChanged; /// /// Gets or sets the splitter value (always in range [0; 1]). @@ -124,6 +125,18 @@ namespace FlaxEditor.CustomEditors.GUI if (_splitterClicked) { SplitterValue = location.X / Width; + Cursor = CursorType.SizeWE; + _cursorChanged = true; + } + else if (_mouseOverSplitter) + { + Cursor = CursorType.SizeWE; + _cursorChanged = true; + } + else if (_cursorChanged) + { + Cursor = CursorType.Default; + _cursorChanged = false; } base.OnMouseMove(location); @@ -162,6 +175,12 @@ namespace FlaxEditor.CustomEditors.GUI { // Clear flag _mouseOverSplitter = false; + + if (_cursorChanged) + { + Cursor = CursorType.Default; + _cursorChanged = false; + } base.OnMouseLeave(); } diff --git a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs index 2edff5c92..1093b50b7 100644 --- a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs +++ b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs @@ -155,11 +155,19 @@ namespace FlaxEditor.GUI.ContextMenu if (parent is ContextMenu menu && menu._childCM != null) locationSS.Y += 30.0f * dpiScale; } - if (monitorBounds.Right < rightBottomLocationSS.X) + if (monitorBounds.Right < rightBottomLocationSS.X || _parentCM?.Direction == ContextMenuDirection.LeftDown || _parentCM?.Direction == ContextMenuDirection.LeftUp) { // Direction: left isLeft = true; - locationSS.X -= dpiSize.X; + + if (IsSubMenu && _parentCM != null) + { + locationSS.X -= _parentCM.Width + dpiSize.X; + } + else + { + locationSS.X -= dpiSize.X; + } } } diff --git a/Source/Editor/GUI/ContextMenu/ContextMenuChildMenu.cs b/Source/Editor/GUI/ContextMenu/ContextMenuChildMenu.cs index 13451fc02..4fef7313b 100644 --- a/Source/Editor/GUI/ContextMenu/ContextMenuChildMenu.cs +++ b/Source/Editor/GUI/ContextMenu/ContextMenuChildMenu.cs @@ -26,6 +26,7 @@ namespace FlaxEditor.GUI.ContextMenu : base(parent, text) { Text = text; + CloseMenuOnClick = false; } /// diff --git a/Source/Editor/GUI/Input/ValueBox.cs b/Source/Editor/GUI/Input/ValueBox.cs index 50cdd529c..5038dab20 100644 --- a/Source/Editor/GUI/Input/ValueBox.cs +++ b/Source/Editor/GUI/Input/ValueBox.cs @@ -57,6 +57,7 @@ namespace FlaxEditor.GUI.Input private Float2 _startSlideLocation; private double _clickStartTime = -1; private bool _cursorChanged; + private Float2 _mouseClickedPosition; /// /// Occurs when value gets changed. @@ -228,7 +229,7 @@ namespace FlaxEditor.GUI.Input // Update UpdateText(); } - + Cursor = CursorType.Default; ResetViewOffset(); @@ -244,8 +245,12 @@ namespace FlaxEditor.GUI.Input _startSlideLocation = location; _startSlideValue = _value; StartMouseCapture(true); - Cursor = CursorType.SizeWE; + + // Hide cursor and cache location + Cursor = CursorType.Hidden; + _mouseClickedPosition = location; _cursorChanged = true; + SlidingStart?.Invoke(); return true; } @@ -266,9 +271,9 @@ namespace FlaxEditor.GUI.Input ApplySliding(Mathf.RoundToInt(slideLocation.X - _startSlideLocation.X) * _slideSpeed); return; } - + // Update cursor type so user knows they can slide value - if (CanUseSliding && SlideRect.Contains(location)) + if (CanUseSliding && SlideRect.Contains(location) && !_isSliding) { Cursor = CursorType.SizeWE; _cursorChanged = true; @@ -287,7 +292,8 @@ namespace FlaxEditor.GUI.Input { if (button == MouseButton.Left && _isSliding) { - // End sliding + // End sliding and return mouse to original location + Root.MousePosition = ScreenPos + _mouseClickedPosition; EndSliding(); return true; } diff --git a/Source/Editor/Modules/SceneEditingModule.cs b/Source/Editor/Modules/SceneEditingModule.cs index 9ffbc514f..7b28367ff 100644 --- a/Source/Editor/Modules/SceneEditingModule.cs +++ b/Source/Editor/Modules/SceneEditingModule.cs @@ -450,7 +450,13 @@ namespace FlaxEditor.Modules SelectionDeleteEnd?.Invoke(); if (isSceneTreeFocus) + { Editor.Windows.SceneWin.Focus(); + } + + // fix scene window layout + Editor.Windows.SceneWin.PerformLayout(); + Editor.Windows.SceneWin.PerformLayout(); } /// @@ -514,6 +520,9 @@ namespace FlaxEditor.Modules Undo.AddAction(new MultiUndoAction(pasteAction, selectAction)); OnSelectionChanged(); } + + // Scroll to new selected node while pasting + Editor.Windows.SceneWin.ScrollToSelectedNode(); } /// @@ -611,6 +620,9 @@ namespace FlaxEditor.Modules Undo.AddAction(new MultiUndoAction(undoActions)); OnSelectionChanged(); } + + // Scroll to new selected node while duplicating + Editor.Windows.SceneWin.ScrollToSelectedNode(); } /// diff --git a/Source/Editor/Options/GeneralOptions.cs b/Source/Editor/Options/GeneralOptions.cs index c3f38f34b..5f05cae2c 100644 --- a/Source/Editor/Options/GeneralOptions.cs +++ b/Source/Editor/Options/GeneralOptions.cs @@ -137,9 +137,9 @@ namespace FlaxEditor.Options /// /// Gets or sets an order of script properties/fields in properties panel. /// - [DefaultValue(MembersOrder.Alphabetical)] + [DefaultValue(MembersOrder.Declaration)] [EditorDisplay("Scripting", "Script Members Order"), EditorOrder(503), Tooltip("Order of script properties/fields in properties panel")] - public MembersOrder ScriptMembersOrder { get; set; } = MembersOrder.Alphabetical; + public MembersOrder ScriptMembersOrder { get; set; } = MembersOrder.Declaration; /// /// Gets or sets a value indicating whether automatically save the Visual Script asset editors when starting the play mode in editor. diff --git a/Source/Editor/Surface/Archetypes/Math.cs b/Source/Editor/Surface/Archetypes/Math.cs index 4518a3090..caedbdc2a 100644 --- a/Source/Editor/Surface/Archetypes/Math.cs +++ b/Source/Editor/Surface/Archetypes/Math.cs @@ -47,7 +47,7 @@ namespace FlaxEditor.Surface.Archetypes Description = desc, Flags = NodeFlags.AllGraphs, AlternativeTitles = altTitles, - Size = new Float2(110, 40), + Size = new Float2(140, 40), DefaultType = new ScriptType(inputType), ConnectionsHints = hints, IndependentBoxes = new[] { 0, 1 }, diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs index eb82a42bf..a375bdd60 100644 --- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs +++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs @@ -223,6 +223,22 @@ namespace FlaxEditor.Viewport editor.SceneEditing.SelectionChanged += OnSelectionChanged; + // Initialize snapping enabled from cached values + if (_editor.ProjectCache.TryGetCustomData("TranslateSnapState", out var cachedState)) + TransformGizmo.TranslationSnapEnable = bool.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("RotationSnapState", out cachedState)) + TransformGizmo.RotationSnapEnabled = bool.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("ScaleSnapState", out cachedState)) + TransformGizmo.ScaleSnapEnabled = bool.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("TranslateSnapValue", out cachedState)) + TransformGizmo.TranslationSnapValue = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("RotationSnapValue", out cachedState)) + TransformGizmo.RotationSnapValue = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("ScaleSnapValue", out cachedState)) + TransformGizmo.ScaleSnapValue = float.Parse(cachedState); + if (_editor.ProjectCache.TryGetCustomData("TransformSpaceState", out cachedState) && Enum.TryParse(cachedState, out TransformGizmoBase.TransformSpace space)) + TransformGizmo.ActiveTransformSpace = space; + // Transform space widget var transformSpaceWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight); var transformSpaceToggle = new ViewportWidgetButton(string.Empty, editor.Icons.Globe32, null, true) @@ -523,21 +539,29 @@ namespace FlaxEditor.Viewport private void OnTranslateSnappingToggle(ViewportWidgetButton button) { TransformGizmo.TranslationSnapEnable = !TransformGizmo.TranslationSnapEnable; + // cache value + _editor.ProjectCache.SetCustomData("TranslateSnapState", TransformGizmo.TranslationSnapEnable.ToString()); } private void OnRotateSnappingToggle(ViewportWidgetButton button) { TransformGizmo.RotationSnapEnabled = !TransformGizmo.RotationSnapEnabled; + // cache value + _editor.ProjectCache.SetCustomData("RotationSnapState", TransformGizmo.RotationSnapEnabled.ToString()); } private void OnScaleSnappingToggle(ViewportWidgetButton button) { TransformGizmo.ScaleSnapEnabled = !TransformGizmo.ScaleSnapEnabled; + // cache value + _editor.ProjectCache.SetCustomData("ScaleSnapState", TransformGizmo.ScaleSnapEnabled.ToString()); } private void OnTransformSpaceToggle(ViewportWidgetButton button) { TransformGizmo.ToggleTransformSpace(); + // cache value + _editor.ProjectCache.SetCustomData("TransformSpaceState", TransformGizmo.ActiveTransformSpace.ToString()); } private void OnGizmoModeChanged() @@ -567,6 +591,8 @@ namespace FlaxEditor.Viewport var v = (float)button.Tag; TransformGizmo.ScaleSnapValue = v; _scaleSnapping.Text = v.ToString(); + // cache value + _editor.ProjectCache.SetCustomData("ScaleSnapValue", TransformGizmo.ScaleSnapValue.ToString("N")); } private void OnWidgetScaleSnapShowHide(Control control) @@ -604,6 +630,8 @@ namespace FlaxEditor.Viewport var v = (float)button.Tag; TransformGizmo.RotationSnapValue = v; _rotateSnapping.Text = v.ToString(); + // cache value + _editor.ProjectCache.SetCustomData("RotationSnapValue", TransformGizmo.RotationSnapValue.ToString("N")); } private void OnWidgetRotateSnapShowHide(Control control) @@ -640,6 +668,8 @@ namespace FlaxEditor.Viewport var v = (float)button.Tag; TransformGizmo.TranslationSnapValue = v; _translateSnapping.Text = v.ToString(); + // cache value + _editor.ProjectCache.SetCustomData("TranslateSnapValue", TransformGizmo.TranslationSnapValue.ToString("N")); } private void OnWidgetTranslateSnapShowHide(Control control) diff --git a/Source/Editor/Windows/EditGameWindow.cs b/Source/Editor/Windows/EditGameWindow.cs index 737b13728..3c0d40c9d 100644 --- a/Source/Editor/Windows/EditGameWindow.cs +++ b/Source/Editor/Windows/EditGameWindow.cs @@ -150,9 +150,23 @@ namespace FlaxEditor.Windows }; Viewport.Task.ViewFlags = ViewFlags.DefaultEditor; + Editor.SceneEditing.SelectionChanged += OnSelectionChanged; Editor.Scene.ActorRemoved += SceneOnActorRemoved; } + /// + public override void OnEditorStateChanged() + { + base.OnEditorStateChanged(); + + UpdateCameraPreview(); + } + + private void OnSelectionChanged() + { + UpdateCameraPreview(); + } + /// /// Gets a value indicating whether actor pilot feature is active and in use. /// @@ -376,9 +390,6 @@ namespace FlaxEditor.Windows /// public override void Update(float deltaTime) { - // TODO: call camera preview update only on selection change, or state change - UpdateCameraPreview(); - if (Root.GetKeyDown(KeyboardKeys.F12)) { Viewport.TakeScreenshot(); diff --git a/Source/Editor/Windows/SceneTreeWindow.cs b/Source/Editor/Windows/SceneTreeWindow.cs index b0bed2002..396bd3747 100644 --- a/Source/Editor/Windows/SceneTreeWindow.cs +++ b/Source/Editor/Windows/SceneTreeWindow.cs @@ -210,6 +210,20 @@ namespace FlaxEditor.Windows _sceneTreePanel.HScrollBar.ThumbEnabled = enabled; } + /// + /// Scrolls to the selected node in the scene tree. + /// + public void ScrollToSelectedNode() + { + // Scroll to node + var nodeSelection = _tree.Selection; + if (nodeSelection.Count != 0) + { + var scrollControl = nodeSelection[nodeSelection.Count - 1]; + _sceneTreePanel.ScrollViewTo(scrollControl); + } + } + private void OnSearchBoxTextChanged() { // Skip events during setup or init stuff diff --git a/Source/Engine/Graphics/GPUDevice.cpp b/Source/Engine/Graphics/GPUDevice.cpp index 6a77fe858..b9f1aeba2 100644 --- a/Source/Engine/Graphics/GPUDevice.cpp +++ b/Source/Engine/Graphics/GPUDevice.cpp @@ -3,6 +3,7 @@ #include "GPUDevice.h" #include "RenderTargetPool.h" #include "GPUPipelineState.h" +#include "GPUSwapChain.h" #include "RenderTask.h" #include "RenderTools.h" #include "Graphics.h" @@ -12,7 +13,6 @@ #include "Engine/Content/Assets/Material.h" #include "Engine/Content/Content.h" #include "Engine/Content/SoftAssetReference.h" -#include "Engine/Platform/Windows/WindowsWindow.h" #include "Engine/Render2D/Render2D.h" #include "Engine/Engine/CommandLine.h" #include "Engine/Engine/Engine.h" @@ -408,7 +408,7 @@ void GPUDevice::DrawEnd() for (int32 i = RenderTask::Tasks.Count() - 1; i >= 0; i--) { const auto task = RenderTask::Tasks[i]; - if (task && task->LastUsedFrame == Engine::FrameCount && task->SwapChain) + if (task && task->LastUsedFrame == Engine::FrameCount && task->SwapChain && task->SwapChain->IsReady()) { lastWindowIndex = i; break; @@ -421,7 +421,7 @@ void GPUDevice::DrawEnd() for (int32 i = 0; i < RenderTask::Tasks.Count(); i++) { const auto task = RenderTask::Tasks[i]; - if (task && task->LastUsedFrame == Engine::FrameCount && task->SwapChain) + if (task && task->LastUsedFrame == Engine::FrameCount && task->SwapChain && task->SwapChain->IsReady()) { bool vsync = useVSync; if (lastWindowIndex != i)