From 0a9f746abb662975ff6bddf00aa7ac8600b141c5 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 11 Mar 2024 19:10:13 +0100 Subject: [PATCH] Refactor UI Control actor active state mirroring in UI via `Visible` properties rather than unlinked from parent #2242 #851 --- Source/Engine/UI/UIControl.cpp | 10 +++++----- Source/Engine/UI/UIControl.cs | 35 +++++++--------------------------- Source/Engine/UI/UIControl.h | 2 +- 3 files changed, 13 insertions(+), 34 deletions(-) diff --git a/Source/Engine/UI/UIControl.cpp b/Source/Engine/UI/UIControl.cpp index aa54e3fc2..72eed1f27 100644 --- a/Source/Engine/UI/UIControl.cpp +++ b/Source/Engine/UI/UIControl.cpp @@ -17,7 +17,7 @@ MMethod* UIControl_Deserialize = nullptr; MMethod* UIControl_ParentChanged = nullptr; MMethod* UIControl_TransformChanged = nullptr; MMethod* UIControl_OrderInParentChanged = nullptr; -MMethod* UIControl_ActiveInTreeChanged = nullptr; +MMethod* UIControl_ActiveChanged = nullptr; MMethod* UIControl_BeginPlay = nullptr; MMethod* UIControl_EndPlay = nullptr; @@ -46,7 +46,7 @@ UIControl::UIControl(const SpawnParams& params) UIControl_ParentChanged = mclass->GetMethod("ParentChanged"); UIControl_TransformChanged = mclass->GetMethod("TransformChanged"); UIControl_OrderInParentChanged = mclass->GetMethod("OrderInParentChanged"); - UIControl_ActiveInTreeChanged = mclass->GetMethod("ActiveInTreeChanged"); + UIControl_ActiveChanged = mclass->GetMethod("ActiveChanged"); UIControl_BeginPlay = mclass->GetMethod("BeginPlay"); UIControl_EndPlay = mclass->GetMethod("EndPlay"); UIControl_Serialize = mclass->GetMethod("Serialize", 2); @@ -207,12 +207,12 @@ void UIControl::OnOrderInParentChanged() UICONTROL_INVOKE(OrderInParentChanged); } -void UIControl::OnActiveInTreeChanged() +void UIControl::OnActiveChanged() { - UICONTROL_INVOKE(ActiveInTreeChanged); + UICONTROL_INVOKE(ActiveChanged); // Base - Actor::OnActiveInTreeChanged(); + Actor::OnActiveChanged(); } #if !COMPILE_WITHOUT_CSHARP diff --git a/Source/Engine/UI/UIControl.cs b/Source/Engine/UI/UIControl.cs index 981c18685..b2c6a4cce 100644 --- a/Source/Engine/UI/UIControl.cs +++ b/Source/Engine/UI/UIControl.cs @@ -1,12 +1,7 @@ // Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. using System; -using System.Globalization; -using System.IO; -using System.Text; using FlaxEngine.GUI; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; namespace FlaxEngine { @@ -49,20 +44,21 @@ namespace FlaxEngine var containerControl = _control as ContainerControl; if (containerControl != null) containerControl.UnlockChildrenRecursive(); + _control.Visible = IsActive; _control.Parent = GetParent(); _control.IndexInParent = OrderInParent; _control.Location = new Float2(LocalPosition); _control.LocationChanged += OnControlLocationChanged; // Link children UI controls - if (containerControl != null && IsActiveInHierarchy) + if (containerControl != null) { var children = ChildrenCount; var parent = Parent; for (int i = 0; i < children; i++) { var child = GetChild(i) as UIControl; - if (child != null && child.IsActiveInHierarchy && child.HasControl && child != parent) + if (child != null && child.HasControl && child != parent) { child.Control.Parent = containerControl; } @@ -108,7 +104,6 @@ namespace FlaxEngine p2 = c.PointToParent(ref p2); p3 = c.PointToParent(ref p3); p4 = c.PointToParent(ref p4); - c = c.Parent; } var min = Float2.Min(Float2.Min(p1, p2), Float2.Min(p3, p4)); @@ -120,7 +115,6 @@ namespace FlaxEngine { Extents = new Vector3(size * 0.5f, Mathf.Epsilon) }; - canvasRoot.Canvas.GetWorldMatrix(out Matrix world); Matrix.Translation(min.X + size.X * 0.5f, min.Y + size.Y * 0.5f, 0, out Matrix offset); Matrix.Multiply(ref offset, ref world, out var boxWorld); @@ -297,15 +291,6 @@ namespace FlaxEngine private ContainerControl GetParent() { - // Don't link disabled actors - if (!IsActiveInHierarchy) - return null; -#if FLAX_EDITOR - // Prefab editor doesn't fire BeginPlay so for disabled actors we don't unlink them so do it here - if (!IsActive) - return null; -#endif - var parent = Parent; if (parent is UIControl uiControl && uiControl.Control is ContainerControl uiContainerControl) return uiContainerControl; @@ -357,6 +342,7 @@ namespace FlaxEngine { if (_control != null && !_blockEvents) { + _control.Visible = IsActive; _control.Parent = GetParent(); _control.IndexInParent = OrderInParent; } @@ -370,19 +356,11 @@ namespace FlaxEngine } } - internal void ActiveInTreeChanged() + internal void ActiveChanged() { if (_control != null && !_blockEvents) { - // Skip if this control is inactive and it's parent too (parent will unlink from hierarchy but children will stay connected while being inactive) - if (!IsActiveInHierarchy && Parent && !Parent.IsActive) - { - return; - } - - // Link or unlink control (won't modify Enable/Visible state) - _control.Parent = GetParent(); - _control.IndexInParent = OrderInParent; + _control.Visible = IsActive; } } @@ -398,6 +376,7 @@ namespace FlaxEngine { if (_control != null) { + _control.Visible = IsActive; _control.Parent = GetParent(); _control.IndexInParent = OrderInParent; Internal_GetNavTargets(__unmanagedPtr, out UIControl up, out UIControl down, out UIControl left, out UIControl right); diff --git a/Source/Engine/UI/UIControl.h b/Source/Engine/UI/UIControl.h index 8df4a578d..e76aca65a 100644 --- a/Source/Engine/UI/UIControl.h +++ b/Source/Engine/UI/UIControl.h @@ -30,7 +30,7 @@ protected: void OnBeginPlay() override; void OnEndPlay() override; void OnOrderInParentChanged() override; - void OnActiveInTreeChanged() override; + void OnActiveChanged() override; private: #if !COMPILE_WITHOUT_CSHARP