diff --git a/Source/Editor/GUI/Docking/DockPanelProxy.cs b/Source/Editor/GUI/Docking/DockPanelProxy.cs
index fbc9d7bee..2bed8251b 100644
--- a/Source/Editor/GUI/Docking/DockPanelProxy.cs
+++ b/Source/Editor/GUI/Docking/DockPanelProxy.cs
@@ -42,7 +42,7 @@ namespace FlaxEditor.GUI.Docking
///
/// The mouse position.
///
- public Vector2 MousePosition;
+ public Vector2 MousePosition = Vector2.Minimum;
///
/// The start drag asynchronous window.
@@ -192,7 +192,7 @@ namespace FlaxEditor.GUI.Docking
var tab = _panel.GetTab(0);
// Draw header
- bool isMouseOver = IsMouseOver && headerRect.Contains(MousePosition);
+ bool isMouseOver = headerRect.Contains(MousePosition);
Render2D.FillRectangle(headerRect, containsFocus ? style.BackgroundSelected : isMouseOver ? style.BackgroundHighlighted : style.LightBackground);
float iconWidth = tab.Icon.IsValid ? DockPanel.DefaultButtonsSize + DockPanel.DefaultLeftTextMargin : 0;
@@ -238,7 +238,7 @@ namespace FlaxEditor.GUI.Docking
var iconWidth = tab.Icon.IsValid ? DockPanel.DefaultButtonsSize + DockPanel.DefaultLeftTextMargin : 0;
var width = titleSize.X + DockPanel.DefaultButtonsSize + 2 * DockPanel.DefaultButtonsMargin + DockPanel.DefaultLeftTextMargin + DockPanel.DefaultRightTextMargin + iconWidth;
var tabRect = new Rectangle(x, 0, width, DockPanel.DefaultHeaderHeight);
- var isMouseOver = IsMouseOver && tabRect.Contains(MousePosition);
+ var isMouseOver = tabRect.Contains(MousePosition);
var isSelected = _panel.SelectedTab == tab;
// Check if tab is selected
@@ -294,11 +294,11 @@ namespace FlaxEditor.GUI.Docking
///
public override void OnLostFocus()
{
- // Clear
IsMouseLeftButtonDown = false;
IsMouseRightButtonDown = false;
IsMouseMiddleButtonDown = false;
MouseDownWindow = null;
+ MousePosition = Vector2.Minimum;
base.OnLostFocus();
}
@@ -306,7 +306,6 @@ namespace FlaxEditor.GUI.Docking
///
public override void OnMouseEnter(Vector2 location)
{
- // Cache mouse
MousePosition = location;
base.OnMouseEnter(location);
@@ -403,10 +402,7 @@ namespace FlaxEditor.GUI.Docking
///
public override void OnMouseMove(Vector2 location)
{
- // Cache mouse
MousePosition = location;
-
- // Check if mouse is down
if (IsMouseLeftButtonDown)
{
// Check if mouse is outside the header
@@ -453,10 +449,8 @@ namespace FlaxEditor.GUI.Docking
///
public override void OnMouseLeave()
{
- // Check if mouse is down
if (IsMouseLeftButtonDown)
{
- // Clear flag
IsMouseLeftButtonDown = false;
// Check tabs under mouse position
@@ -466,6 +460,7 @@ namespace FlaxEditor.GUI.Docking
}
IsMouseRightButtonDown = false;
IsMouseMiddleButtonDown = false;
+ MousePosition = Vector2.Minimum;
base.OnMouseLeave();
}
diff --git a/Source/Editor/GUI/Tree/TreeNode.cs b/Source/Editor/GUI/Tree/TreeNode.cs
index 7fdc1c746..d65848589 100644
--- a/Source/Editor/GUI/Tree/TreeNode.cs
+++ b/Source/Editor/GUI/Tree/TreeNode.cs
@@ -889,19 +889,16 @@ namespace FlaxEditor.GUI.Tree
///
public override void OnChildResized(Control control)
{
+ // Optimize if child is tree node that is not visible
+ if (!_opened && control is TreeNode)
+ return;
+
PerformLayout();
ParentTree.UpdateSize();
+
base.OnChildResized(control);
}
- ///
- public override void OnParentResized()
- {
- base.OnParentResized();
-
- Width = Parent.Width;
- }
-
///
public override DragDropEffect OnDragEnter(ref Vector2 location, DragData data)
{
@@ -1018,56 +1015,82 @@ namespace FlaxEditor.GUI.Tree
///
public override void PerformLayout(bool force = false)
{
- // Check if update is locked
- if (IsLayoutLocked && !force)
+ if (_isLayoutLocked && !force)
return;
- // Update the nodes nesting level before the actual positioning
- float xOffset = _xOffset + ChildrenIndent;
- for (int i = 0; i < _children.Count; i++)
+ bool wasLocked = _isLayoutLocked;
+ if (!wasLocked)
+ LockChildrenRecursive();
+
+ // Optimize layout logic if node is collapsed
+ if (_opened || _animationProgress < 1.0f)
{
- if (_children[i] is TreeNode node && node.Visible)
- node._xOffset = xOffset;
+ PerformLayoutBeforeChildren();
+ for (int i = 0; i < _children.Count; i++)
+ _children[i].PerformLayout(true);
+ PerformLayoutAfterChildren();
+ }
+ else
+ {
+ // TODO: perform layout for any non-TreeNode controls
+ _cachedHeight = _headerHeight;
+ _cachedTextColor = CacheTextColor();
+ Size = new Vector2(Parent?.Width ?? Width, _headerHeight);
}
- base.PerformLayout(force);
+ if (!wasLocked)
+ UnlockChildrenRecursive();
+ }
+
+ ///
+ protected override void PerformLayoutBeforeChildren()
+ {
+ if (_opened)
+ {
+ // Update the nodes nesting level before the actual positioning
+ float xOffset = _xOffset + ChildrenIndent;
+ for (int i = 0; i < _children.Count; i++)
+ {
+ if (_children[i] is TreeNode node)
+ node._xOffset = xOffset;
+ }
+ }
+
+ base.PerformLayoutBeforeChildren();
}
///
protected override void PerformLayoutAfterChildren()
{
- _cachedTextColor = CacheTextColor();
-
- // Prepare
float y = _headerHeight;
float height = _headerHeight;
float xOffset = _xOffset + ChildrenIndent;
- y -= _cachedHeight * (_opened ? 1.0f - _animationProgress : _animationProgress);
- // Arrange children
- for (int i = 0; i < _children.Count; i++)
+ // Skip full layout if it's fully collapsed
+ if (_opened || _animationProgress < 1.0f)
{
- if (_children[i] is TreeNode node && node.Visible)
+ y -= _cachedHeight * (_opened ? 1.0f - _animationProgress : _animationProgress);
+
+ // Arrange children
+ for (int i = 0; i < _children.Count; i++)
{
- node._xOffset = xOffset;
- node.Location = new Vector2(0, y);
- float nodeHeight = node.Height + DefaultNodeOffsetY;
- y += nodeHeight;
- height += nodeHeight;
+ if (_children[i] is TreeNode node && node.Visible)
+ {
+ node._xOffset = xOffset;
+ node.Location = new Vector2(0, y);
+ float nodeHeight = node.Height + DefaultNodeOffsetY;
+ y += nodeHeight;
+ height += nodeHeight;
+ }
}
}
- // Cache calculated height
+ // Cache data
_cachedHeight = height;
+ _cachedTextColor = CacheTextColor();
- // Force to be closed
- if (_animationProgress >= 1.0f && !_opened)
- {
- y = _headerHeight;
- }
-
- // Set height
- Height = Mathf.Max(_headerHeight, y);
+ // Set bounds
+ Size = new Vector2(Parent?.Width ?? Width, Mathf.Max(_headerHeight, y));
}
///
diff --git a/Source/Editor/Modules/SceneModule.cs b/Source/Editor/Modules/SceneModule.cs
index d144c5a7e..ffbd876fe 100644
--- a/Source/Editor/Modules/SceneModule.cs
+++ b/Source/Editor/Modules/SceneModule.cs
@@ -486,7 +486,6 @@ namespace FlaxEditor.Modules
var node = SceneGraphFactory.BuildActorNode(actor);
if (node != null)
{
- node.TreeNode.UnlockChildrenRecursive();
node.ParentNode = parentNode;
}
}
@@ -544,13 +543,8 @@ namespace FlaxEditor.Modules
return;
// Get the new parent node (may be missing)
- if (parentNode != null)
- {
- // Change parent
- node.TreeNode.UnlockChildrenRecursive();
- node.ParentNode = parentNode;
- }
- else
+ node.ParentNode = parentNode;
+ if (parentNode == null)
{
// Check if actor is selected in editor
if (Editor.SceneEditing.Selection.Contains(node))
diff --git a/Source/Editor/SceneGraph/ActorNode.cs b/Source/Editor/SceneGraph/ActorNode.cs
index a9720a7d5..b7dcee312 100644
--- a/Source/Editor/SceneGraph/ActorNode.cs
+++ b/Source/Editor/SceneGraph/ActorNode.cs
@@ -14,7 +14,7 @@ namespace FlaxEditor.SceneGraph
/// It's part of the Scene Graph.
///
///
- ///
+ ///
[HideInEditor]
public class ActorNode : SceneGraphNode
{
@@ -228,6 +228,7 @@ namespace FlaxEditor.SceneGraph
set => _actor.Transform = value;
}
+#if false
///
public override SceneGraphNode ParentNode
{
@@ -238,6 +239,7 @@ namespace FlaxEditor.SceneGraph
base.ParentNode = value;
}
}
+#endif
///
public override object EditableObject => _actor;
@@ -250,7 +252,7 @@ namespace FlaxEditor.SceneGraph
// Skip actors that should not be selected
if (hit != null && _actor != null && (_actor.HideFlags & HideFlags.DontSelect) == HideFlags.DontSelect)
{
- hit = ParentNode;
+ hit = parentNode;
}
return hit;
@@ -306,22 +308,43 @@ namespace FlaxEditor.SceneGraph
///
protected override void OnParentChanged()
{
- // Update UI node connections
- _treeNode.Parent = (ParentNode as ActorNode)?.TreeNode;
-
- // Check if it's a new node and parent has been already ready
- // (eg. we build new node for spawned actor and link it to the game)
- if (_treeNode.Parent != null && !_treeNode.Parent.IsLayoutLocked)
- {
- _treeNode.IndexInParent = _actor.OrderInParent;
- _treeNode.Parent.SortChildren();
-
- // Update UI
- _treeNode.IsLayoutLocked = false;
- _treeNode.PerformLayout();
- }
-
base.OnParentChanged();
+
+ // Update UI (special case if actor is spawned and added to existing scene tree)
+ var parentTreeNode = (parentNode as ActorNode)?.TreeNode;
+ if (parentTreeNode != null && !parentTreeNode.IsLayoutLocked)
+ {
+ parentTreeNode.IsLayoutLocked = true;
+ _treeNode.Parent = parentTreeNode;
+ _treeNode.IndexInParent = _actor.OrderInParent;
+ parentTreeNode.IsLayoutLocked = false;
+
+ // Skip UI update if node won't be in a view
+ if (parentTreeNode.IsCollapsed)
+ {
+ TreeNode.UnlockChildrenRecursive();
+ }
+ else
+ {
+ // Try to perform layout at the level where it makes it the most performant (the least computations)
+ var tree = parentTreeNode.ParentTree;
+ if (tree != null)
+ {
+ if (tree.Parent is FlaxEngine.GUI.Panel treeParent)
+ treeParent.PerformLayout();
+ else
+ tree.PerformLayout();
+ }
+ else
+ {
+ parentTreeNode.PerformLayout();
+ }
+ }
+ }
+ else
+ {
+ _treeNode.Parent = parentTreeNode;
+ }
}
///
diff --git a/Source/Engine/Core/Math/Math.h b/Source/Engine/Core/Math/Math.h
index b5320dd35..936623385 100644
--- a/Source/Engine/Core/Math/Math.h
+++ b/Source/Engine/Core/Math/Math.h
@@ -489,7 +489,7 @@ namespace Math
static bool NearEqual(float a, float b)
{
// Check if the numbers are really close - needed when comparing numbers near zero
- if (Abs(a) < ZeroTolerance)
+ if (Abs(a - b) < ZeroTolerance)
return true;
// Original from Bruce Dawson: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
diff --git a/Source/Engine/Core/Math/Vector2.cs b/Source/Engine/Core/Math/Vector2.cs
index bc193a034..c93c0c275 100644
--- a/Source/Engine/Core/Math/Vector2.cs
+++ b/Source/Engine/Core/Math/Vector2.cs
@@ -1816,7 +1816,7 @@ namespace FlaxEngine
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vector2 left, Vector2 right)
{
- return left.Equals(ref right);
+ return Mathf.NearEqual(left.X, left.X) && Mathf.NearEqual(left.Y, right.Y);
}
///
@@ -1831,7 +1831,7 @@ namespace FlaxEngine
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Vector2 left, Vector2 right)
{
- return !left.Equals(ref right);
+ return !Mathf.NearEqual(left.X, left.X) || !Mathf.NearEqual(left.Y, right.Y);
}
///
@@ -1953,7 +1953,7 @@ namespace FlaxEngine
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Vector2 other)
{
- return Equals(ref other);
+ return Mathf.NearEqual(X, X) && Mathf.NearEqual(other.Y, other.Y);
}
///
@@ -1965,11 +1965,9 @@ namespace FlaxEngine
///
public override bool Equals(object value)
{
- if (!(value is Vector2))
+ if (!(value is Vector2 other))
return false;
-
- var strongValue = (Vector2)value;
- return Equals(ref strongValue);
+ return Mathf.NearEqual(X, X) && Mathf.NearEqual(other.Y, other.Y);
}
}
}
diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs
index 2674b30e6..7ef13c344 100644
--- a/Source/Engine/Core/Math/Vector3.cs
+++ b/Source/Engine/Core/Math/Vector3.cs
@@ -2049,7 +2049,7 @@ namespace FlaxEngine
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vector3 left, Vector3 right)
{
- return left.Equals(ref right);
+ return Mathf.NearEqual(left.X, right.X) && Mathf.NearEqual(left.Y, right.Y) && Mathf.NearEqual(left.Z, right.Z);
}
///
@@ -2061,7 +2061,7 @@ namespace FlaxEngine
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Vector3 left, Vector3 right)
{
- return !left.Equals(ref right);
+ return !Mathf.NearEqual(left.X, right.X) || !Mathf.NearEqual(left.Y, right.Y) || !Mathf.NearEqual(left.Z, right.Z);
}
///
@@ -2162,7 +2162,7 @@ namespace FlaxEngine
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Vector3 other)
{
- return Equals(ref other);
+ return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z);
}
///
@@ -2172,10 +2172,9 @@ namespace FlaxEngine
/// true if the specified is equal to this instance; otherwise, false.
public override bool Equals(object value)
{
- if (!(value is Vector3))
+ if (!(value is Vector3 other))
return false;
- var strongValue = (Vector3)value;
- return Equals(ref strongValue);
+ return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z);
}
}
}
diff --git a/Source/Engine/Core/Math/Vector4.cs b/Source/Engine/Core/Math/Vector4.cs
index 6d1521e85..f7d605a8f 100644
--- a/Source/Engine/Core/Math/Vector4.cs
+++ b/Source/Engine/Core/Math/Vector4.cs
@@ -1680,7 +1680,7 @@ namespace FlaxEngine
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(Vector4 other)
{
- return Equals(ref other);
+ return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z) && Mathf.NearEqual(other.W, W);
}
///
@@ -1692,11 +1692,9 @@ namespace FlaxEngine
///
public override bool Equals(object value)
{
- if (!(value is Vector4))
+ if (!(value is Vector4 other))
return false;
-
- var strongValue = (Vector4)value;
- return Equals(ref strongValue);
+ return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z) && Mathf.NearEqual(other.W, W);
}
}
}
diff --git a/Source/Engine/UI/GUI/ContainerControl.cs b/Source/Engine/UI/GUI/ContainerControl.cs
index 0b02d0c21..9d27851dc 100644
--- a/Source/Engine/UI/GUI/ContainerControl.cs
+++ b/Source/Engine/UI/GUI/ContainerControl.cs
@@ -23,12 +23,21 @@ namespace FlaxEngine.GUI
[NoSerialize]
protected bool _containsFocus;
+ ///
+ /// The layout locking flag.
+ ///
+ [NoSerialize]
+ protected bool _isLayoutLocked;
+
+ private bool _clipChildren = true;
+ private bool _cullChildren = true;
+
///
/// Initializes a new instance of the class.
///
public ContainerControl()
{
- IsLayoutLocked = true;
+ _isLayoutLocked = true;
}
///
@@ -37,7 +46,7 @@ namespace FlaxEngine.GUI
public ContainerControl(float x, float y, float width, float height)
: base(x, y, width, height)
{
- IsLayoutLocked = true;
+ _isLayoutLocked = true;
}
///
@@ -46,14 +55,14 @@ namespace FlaxEngine.GUI
public ContainerControl(Vector2 location, Vector2 size)
: base(location, size)
{
- IsLayoutLocked = true;
+ _isLayoutLocked = true;
}
///
public ContainerControl(Rectangle bounds)
: base(bounds)
{
- IsLayoutLocked = true;
+ _isLayoutLocked = true;
}
///
@@ -80,30 +89,39 @@ namespace FlaxEngine.GUI
/// True if automatic updates for control layout are locked (useful when creating a lot of GUI control to prevent lags).
///
[HideInEditor, NoSerialize]
- public bool IsLayoutLocked { get; set; }
+ public bool IsLayoutLocked
+ {
+ get => _isLayoutLocked;
+ set => _isLayoutLocked = value;
+ }
///
/// Gets or sets a value indicating whether apply clipping mask on children during rendering.
///
[EditorOrder(530), Tooltip("If checked, control will apply clipping mask on children during rendering.")]
- public bool ClipChildren { get; set; } = true;
+ public bool ClipChildren
+ {
+ get => _clipChildren;
+ set => _clipChildren = value;
+ }
///
/// Gets or sets a value indicating whether perform view culling on children during rendering.
///
[EditorOrder(540), Tooltip("If checked, control will perform view culling on children during rendering.")]
- public bool CullChildren { get; set; } = true;
+ public bool CullChildren
+ {
+ get => _cullChildren;
+ set => _cullChildren = value;
+ }
///
/// Locks all child controls layout and itself.
///
[NoAnimate]
- public virtual void LockChildrenRecursive()
+ public void LockChildrenRecursive()
{
- // Itself
- IsLayoutLocked = true;
-
- // Every child container control
+ _isLayoutLocked = true;
for (int i = 0; i < _children.Count; i++)
{
if (_children[i] is ContainerControl child)
@@ -115,12 +133,9 @@ namespace FlaxEngine.GUI
/// Unlocks all the child controls layout and itself.
///
[NoAnimate]
- public virtual void UnlockChildrenRecursive()
+ public void UnlockChildrenRecursive()
{
- // Itself
- IsLayoutLocked = false;
-
- // Every child container control
+ _isLayoutLocked = false;
for (int i = 0; i < _children.Count; i++)
{
if (_children[i] is ContainerControl child)
@@ -134,8 +149,8 @@ namespace FlaxEngine.GUI
[NoAnimate]
public virtual void RemoveChildren()
{
- bool wasLayoutLocked = IsLayoutLocked;
- IsLayoutLocked = true;
+ bool wasLayoutLocked = _isLayoutLocked;
+ _isLayoutLocked = true;
// Delete children
while (_children.Count > 0)
@@ -143,7 +158,7 @@ namespace FlaxEngine.GUI
_children[0].Parent = null;
}
- IsLayoutLocked = wasLayoutLocked;
+ _isLayoutLocked = wasLayoutLocked;
PerformLayout();
}
@@ -152,8 +167,8 @@ namespace FlaxEngine.GUI
///
public virtual void DisposeChildren()
{
- bool wasLayoutLocked = IsLayoutLocked;
- IsLayoutLocked = true;
+ bool wasLayoutLocked = _isLayoutLocked;
+ _isLayoutLocked = true;
// Delete children
while (_children.Count > 0)
@@ -161,7 +176,7 @@ namespace FlaxEngine.GUI
_children[0].Dispose();
}
- IsLayoutLocked = wasLayoutLocked;
+ _isLayoutLocked = wasLayoutLocked;
PerformLayout();
}
@@ -253,7 +268,6 @@ namespace FlaxEngine.GUI
return;
_children.RemoveAt(oldIndex);
- // Check if index is invalid
if (newIndex < 0 || newIndex >= _children.Count)
{
// Append at the end
@@ -279,8 +293,6 @@ namespace FlaxEngine.GUI
for (int i = _children.Count - 1; i >= 0; i--)
{
var child = _children[i];
-
- // Check collision
if (IntersectsChildContent(child, point, out var childLocation))
{
result = i;
@@ -499,10 +511,7 @@ namespace FlaxEngine.GUI
// Check if state has been changed
if (result != _containsFocus)
{
- // Cache flag
_containsFocus = result;
-
- // Fire event
if (result)
{
OnStartContainsFocus();
@@ -563,24 +572,6 @@ namespace FlaxEngine.GUI
_children.Clear();
}
- ///
- public override bool IsMouseOver
- {
- get
- {
- if (base.IsMouseOver)
- return true;
-
- for (int i = 0; i < _children.Count && _children.Count > 0; i++)
- {
- if (_children[i].IsMouseOver)
- return true;
- }
-
- return false;
- }
- }
-
///
public override bool IsTouchOver
{
@@ -619,7 +610,7 @@ namespace FlaxEngine.GUI
{
DrawSelf();
- if (ClipChildren)
+ if (_clipChildren)
{
GetDesireClientArea(out var clientArea);
Render2D.PushClip(ref clientArea);
@@ -646,7 +637,7 @@ namespace FlaxEngine.GUI
protected virtual void DrawChildren()
{
// Draw all visible child controls
- if (CullChildren)
+ if (_cullChildren)
{
Render2D.PeekClip(out var globalClipping);
Render2D.PeekTransform(out var globalTransform);
@@ -684,10 +675,10 @@ namespace FlaxEngine.GUI
///
public override void PerformLayout(bool force = false)
{
- if (IsLayoutLocked && !force)
+ if (_isLayoutLocked && !force)
return;
- bool wasLocked = IsLayoutLocked;
+ bool wasLocked = _isLayoutLocked;
if (!wasLocked)
LockChildrenRecursive();
@@ -711,7 +702,6 @@ namespace FlaxEngine.GUI
var child = _children[i];
if (child.Visible && child.Enabled)
{
- // Fire event
if (IntersectsChildContent(child, location, out var childLocation))
{
// Enter
@@ -732,7 +722,6 @@ namespace FlaxEngine.GUI
var child = _children[i];
if (child.Visible && child.Enabled)
{
- // Fire events
if (IntersectsChildContent(child, location, out var childLocation))
{
if (child.IsMouseOver)
@@ -1035,7 +1024,6 @@ namespace FlaxEngine.GUI
var child = _children[i];
if (child.Visible && child.Enabled)
{
- // Fire event
if (IntersectsChildContent(child, location, out var childLocation))
{
// Enter
@@ -1061,7 +1049,6 @@ namespace FlaxEngine.GUI
var child = _children[i];
if (child.Visible && child.Enabled)
{
- // Fire events
if (IntersectsChildContent(child, location, out var childLocation))
{
if (child.IsDragOver)
@@ -1120,7 +1107,6 @@ namespace FlaxEngine.GUI
var child = _children[i];
if (child.Visible && child.Enabled)
{
- // Fire event
if (IntersectsChildContent(child, location, out var childLocation))
{
// Enter
@@ -1138,10 +1124,9 @@ namespace FlaxEngine.GUI
protected override void OnSizeChanged()
{
// Lock updates to prevent additional layout calculations
- bool wasLayoutLocked = IsLayoutLocked;
- IsLayoutLocked = true;
+ bool wasLayoutLocked = _isLayoutLocked;
+ _isLayoutLocked = true;
- // Base
base.OnSizeChanged();
// Fire event
@@ -1151,7 +1136,7 @@ namespace FlaxEngine.GUI
}
// Restore state
- IsLayoutLocked = wasLayoutLocked;
+ _isLayoutLocked = wasLayoutLocked;
// Arrange child controls
PerformLayout();
diff --git a/Source/Engine/UI/GUI/Control.Bounds.cs b/Source/Engine/UI/GUI/Control.Bounds.cs
index 1fe4117f8..b4b612bf6 100644
--- a/Source/Engine/UI/GUI/Control.Bounds.cs
+++ b/Source/Engine/UI/GUI/Control.Bounds.cs
@@ -150,7 +150,13 @@ namespace FlaxEngine.GUI
public Vector2 Location
{
get => _bounds.Location;
- set => Bounds = new Rectangle(value, _bounds.Size);
+ set
+ {
+ if (_bounds.Location.Equals(ref value))
+ return;
+ var bounds = new Rectangle(value, _bounds.Size);
+ SetBounds(ref bounds);
+ }
}
///
@@ -170,7 +176,13 @@ namespace FlaxEngine.GUI
public float Width
{
get => _bounds.Size.X;
- set => Bounds = new Rectangle(_bounds.Location, value, _bounds.Size.Y);
+ set
+ {
+ if (Mathf.NearEqual(_bounds.Size.X, value))
+ return;
+ var bounds = new Rectangle(_bounds.Location, value, _bounds.Size.Y);
+ SetBounds(ref bounds);
+ }
}
///
@@ -180,7 +192,13 @@ namespace FlaxEngine.GUI
public float Height
{
get => _bounds.Size.Y;
- set => Bounds = new Rectangle(_bounds.Location, _bounds.Size.X, value);
+ set
+ {
+ if (Mathf.NearEqual(_bounds.Size.Y, value))
+ return;
+ var bounds = new Rectangle(_bounds.Location, _bounds.Size.X, value);
+ SetBounds(ref bounds);
+ }
}
///
@@ -190,7 +208,13 @@ namespace FlaxEngine.GUI
public Vector2 Size
{
get => _bounds.Size;
- set => Bounds = new Rectangle(_bounds.Location, value);
+ set
+ {
+ if (_bounds.Size.Equals(ref value))
+ return;
+ var bounds = new Rectangle(_bounds.Location, value);
+ SetBounds(ref bounds);
+ }
}
///
@@ -425,12 +449,12 @@ namespace FlaxEngine.GUI
UpdateTransform();
// Handle location/size changes
- if (_bounds.Location != prevBounds.Location)
+ if (!_bounds.Location.Equals(ref prevBounds.Location))
{
OnLocationChanged();
}
- if (_bounds.Size != prevBounds.Size)
+ if (!_bounds.Size.Equals(ref prevBounds.Size))
{
OnSizeChanged();
}
diff --git a/Source/Engine/UI/GUI/Panels/Panel.cs b/Source/Engine/UI/GUI/Panels/Panel.cs
index eff9e99b8..946e3e9e4 100644
--- a/Source/Engine/UI/GUI/Panels/Panel.cs
+++ b/Source/Engine/UI/GUI/Panels/Panel.cs
@@ -177,15 +177,15 @@ namespace FlaxEngine.GUI
///
protected override void SetViewOffset(ref Vector2 value)
{
- bool wasLocked = IsLayoutLocked;
- IsLayoutLocked = true;
+ bool wasLocked = _isLayoutLocked;
+ _isLayoutLocked = true;
if (HScrollBar != null)
HScrollBar.Value = -value.X;
if (VScrollBar != null)
VScrollBar.Value = -value.Y;
- IsLayoutLocked = wasLocked;
+ _isLayoutLocked = wasLocked;
base.SetViewOffset(ref value);
}
@@ -239,15 +239,15 @@ namespace FlaxEngine.GUI
/// True of scroll to the item quickly without smoothing.
public void ScrollViewTo(Rectangle bounds, bool fastScroll = false)
{
- bool wasLocked = IsLayoutLocked;
- IsLayoutLocked = true;
+ bool wasLocked = _isLayoutLocked;
+ _isLayoutLocked = true;
if (HScrollBar != null && HScrollBar.Enabled)
HScrollBar.ScrollViewTo(bounds.Left, bounds.Right, fastScroll);
if (VScrollBar != null && VScrollBar.Enabled)
VScrollBar.ScrollViewTo(bounds.Top, bounds.Bottom, fastScroll);
- IsLayoutLocked = wasLocked;
+ _isLayoutLocked = wasLocked;
PerformLayout();
}
@@ -406,14 +406,14 @@ namespace FlaxEngine.GUI
return;
_layoutUpdateLock++;
- if (!IsLayoutLocked)
+ if (!_isLayoutLocked)
{
_layoutChanged = false;
}
base.PerformLayout(force);
- if (!IsLayoutLocked && _layoutChanged)
+ if (!_isLayoutLocked && _layoutChanged)
{
_layoutChanged = false;
PerformLayout(true);