From 5010597bd2f8505e0544b83f8cf72157067313c5 Mon Sep 17 00:00:00 2001 From: Saas Date: Thu, 21 May 2026 00:20:52 +0200 Subject: [PATCH 1/3] add being able to rotate view with direction gizmo --- Source/Editor/Gizmo/DirectionGizmo.cs | 48 +++++++++++++++++-- Source/Editor/Options/ViewportOptions.cs | 2 +- .../Viewport/MainEditorGizmoViewport.cs | 4 +- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/Source/Editor/Gizmo/DirectionGizmo.cs b/Source/Editor/Gizmo/DirectionGizmo.cs index aedfe73d0..ecdd19e66 100644 --- a/Source/Editor/Gizmo/DirectionGizmo.cs +++ b/Source/Editor/Gizmo/DirectionGizmo.cs @@ -36,8 +36,10 @@ internal class DirectionGizmo : ContainerControl private List _axisData = new List(); private int _hoveredAxisIndex = -1; + private bool _mouseDown; + private Float2 _mouseDownLocation; + private SpriteHandle _posHandle; - private SpriteHandle _negHandle; private FontReference _fontReference; @@ -110,7 +112,6 @@ internal class DirectionGizmo : ContainerControl var editor = Editor.Instance; _posHandle = editor.Icons.VisjectBoxClosed32; - _negHandle = editor.Icons.VisjectBoxOpen32; _fontReference = new FontReference(Style.Current.FontSmall); @@ -142,7 +143,25 @@ internal class DirectionGizmo : ContainerControl public override void OnMouseMove(Float2 location) { _hoveredAxisIndex = -1; + + if (_mouseDown) + { + StartMouseCapture(); + Cursor = CursorType.Hidden; + const float sensitivity = 0.125f; + Float2 delta = Input.MousePositionDelta; + delta *= Mathf.DegreesToRadians; + delta *= sensitivity; + + const float orbitRadius = 500f; + Quaternion newOrientation = _viewport.ViewOrientation * Quaternion.RotationYawPitchRoll(delta.X , delta.Y, 0f); + Vector3 orbitCenter = _viewport.ViewPosition + _viewport.ViewDirection * orbitRadius; + _viewport.ViewportCamera.SetArcBallView(newOrientation, orbitCenter, orbitRadius); + + return; + } + // Check which axis is being hovered - check from closest to farthest for proper layering for (int i = _spritePositions.Count - 1; i >= 0; i--) { @@ -156,9 +175,27 @@ internal class DirectionGizmo : ContainerControl base.OnMouseMove(location); } + public override bool OnMouseDown(Float2 location, MouseButton button) + { + _mouseDown = true; + _mouseDownLocation = location; + return true; + } + /// public override bool OnMouseUp(Float2 location, MouseButton button) { + if (_mouseDown && _mouseDownLocation != location) + { + _mouseDown = false; + EndMouseCapture(); + Root.MousePosition = PointToParent(Root, _mouseDownLocation); + Cursor = CursorType.Default; + return true; + } + + _mouseDown = false; + if (base.OnMouseUp(location, button)) return true; @@ -269,7 +306,12 @@ internal class DirectionGizmo : ContainerControl // Rebuild sprite positions list for hover detection _spritePositions.Clear(); - Render2D.DrawSprite(_posHandle, new Rectangle(0, 0, Size), Color.Black.AlphaMultiplied(_backgroundOpacity)); + if (IsMouseOver) + { + Rectangle backgroundRect = new Rectangle(0, 0, Size); + Color backgroundColor = Color.DarkGray.AlphaMultiplied(_backgroundOpacity); + Render2D.DrawSprite(_posHandle, backgroundRect, backgroundColor); + } // Draw in order from farthest to closest for (int i = 0; i < _axisData.Count; i++) diff --git a/Source/Editor/Options/ViewportOptions.cs b/Source/Editor/Options/ViewportOptions.cs index c7f6ba544..2dd08b6d1 100644 --- a/Source/Editor/Options/ViewportOptions.cs +++ b/Source/Editor/Options/ViewportOptions.cs @@ -187,7 +187,7 @@ namespace FlaxEditor.Options public float DirectionGizmoScale { get; set; } = 1f; /// - /// Gets or sets a value for the opacity of the main viewports background. + /// Gets or sets a value for the opacity of the main viewports background. Background will only show when the gizmo is hovered. /// [DefaultValue(0.1f), Limit(0.0f, 1.0f)] [EditorDisplay("Direction Gizmo"), EditorOrder(502), Tooltip("The background opacity of the of the direction gizmo in the main viewport.")] diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs index f171840b5..51b240202 100644 --- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs +++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs @@ -706,7 +706,7 @@ namespace FlaxEditor.Viewport { base.OnLeftMouseButtonDown(); - if (!IsAltKeyDown) + if (!IsAltKeyDown && !_directionGizmo.IsMouseOver) _rubberBandSelector.TryStartingRubberBandSelection(_viewMousePos); } @@ -714,7 +714,7 @@ namespace FlaxEditor.Viewport protected override void OnLeftMouseButtonUp() { // Skip if was controlling mouse or mouse is not over the area - if (_prevInput.IsControllingMouse || !Bounds.Contains(ref _viewMousePos)) + if (_prevInput.IsControllingMouse || !Bounds.Contains(ref _viewMousePos) || _directionGizmo.IsMouseOver) return; // Select rubberbanded rect actor nodes or pick with gizmo From 637f3dc1761b66404dd34b4f7b5bb9bca0186f1c Mon Sep 17 00:00:00 2001 From: Saas Date: Thu, 21 May 2026 00:26:45 +0200 Subject: [PATCH 2/3] make code a bit nicer --- Source/Editor/Gizmo/DirectionGizmo.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Source/Editor/Gizmo/DirectionGizmo.cs b/Source/Editor/Gizmo/DirectionGizmo.cs index ecdd19e66..b8e90f36e 100644 --- a/Source/Editor/Gizmo/DirectionGizmo.cs +++ b/Source/Editor/Gizmo/DirectionGizmo.cs @@ -185,17 +185,20 @@ internal class DirectionGizmo : ContainerControl /// public override bool OnMouseUp(Float2 location, MouseButton button) { - if (_mouseDown && _mouseDownLocation != location) + if (_mouseDown) { _mouseDown = false; - EndMouseCapture(); - Root.MousePosition = PointToParent(Root, _mouseDownLocation); - Cursor = CursorType.Default; - return true; + + if (_mouseDownLocation != location) + { + _mouseDown = false; + EndMouseCapture(); + Root.MousePosition = PointToParent(Root, _mouseDownLocation); + Cursor = CursorType.Default; + return true; + } } - _mouseDown = false; - if (base.OnMouseUp(location, button)) return true; From 96a081bf93d54c4260607436eae42bd88a57d483 Mon Sep 17 00:00:00 2001 From: Saas Date: Thu, 21 May 2026 21:43:26 +0200 Subject: [PATCH 3/3] use mouse wrapping and rename mouse wrapping function parameter --- Source/Editor/Gizmo/DirectionGizmo.cs | 2 +- Source/Engine/UI/GUI/Control.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Editor/Gizmo/DirectionGizmo.cs b/Source/Editor/Gizmo/DirectionGizmo.cs index b8e90f36e..0eee9f916 100644 --- a/Source/Editor/Gizmo/DirectionGizmo.cs +++ b/Source/Editor/Gizmo/DirectionGizmo.cs @@ -146,7 +146,7 @@ internal class DirectionGizmo : ContainerControl if (_mouseDown) { - StartMouseCapture(); + StartMouseCapture(true); Cursor = CursorType.Hidden; const float sensitivity = 0.125f; diff --git a/Source/Engine/UI/GUI/Control.cs b/Source/Engine/UI/GUI/Control.cs index f3eae8a24..8ae3b3616 100644 --- a/Source/Engine/UI/GUI/Control.cs +++ b/Source/Engine/UI/GUI/Control.cs @@ -572,12 +572,12 @@ namespace FlaxEngine.GUI /// /// Starts the mouse tracking. Used by the scrollbars, splitters, etc. /// - /// If set to true will use mouse screen offset. + /// If set to true will wrap when it hits a screen border. [NoAnimate] - public void StartMouseCapture(bool useMouseScreenOffset = false) + public void StartMouseCapture(bool screenSpaceMouseWrap = false) { var parent = Root; - parent?.StartTrackingMouse(this, useMouseScreenOffset); + parent?.StartTrackingMouse(this, screenSpaceMouseWrap); } ///