From 590f3f7493f8fff78e83256f43fef417540035fa Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sat, 28 Oct 2023 10:29:39 -0500 Subject: [PATCH 1/3] Fix Dropdown scaling with CanvasScalar. Add limiting number of items to show in the dropdown. --- Source/Engine/UI/GUI/Common/Dropdown.cs | 57 ++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/Source/Engine/UI/GUI/Common/Dropdown.cs b/Source/Engine/UI/GUI/Common/Dropdown.cs index aea4e173a..bf2dbc0ef 100644 --- a/Source/Engine/UI/GUI/Common/Dropdown.cs +++ b/Source/Engine/UI/GUI/Common/Dropdown.cs @@ -22,6 +22,11 @@ namespace FlaxEngine.GUI /// Occurs when popup lost focus. /// public Action LostFocus; + + /// + /// The selected control. Used to scroll to the control on popup creation. + /// + public ContainerControl SelectedControl = null; /// public override void OnEndContainsFocus() @@ -233,6 +238,18 @@ namespace FlaxEngine.GUI } } + /// + /// Gets or sets whether to show all of the items. + /// + [EditorOrder(3), Tooltip("Whether to show all of the items in the drop down.")] + public bool ShowAllItems { get; set; } = true; + + /// + /// Gets or sets the number of items to show. Only used if ShowAllItems is false. + /// + [EditorOrder(4), VisibleIf(nameof(ShowAllItems), true), Limit(1), Tooltip("The number of items to show in the drop down.")] + public int NumberOfItemsToShow { get; set; } = 5; + /// /// Event fired when selected index gets changed. /// @@ -411,13 +428,22 @@ namespace FlaxEngine.GUI // TODO: support item templates - var container = new VerticalPanel + var panel = new Panel { AnchorPreset = AnchorPresets.StretchAll, BackgroundColor = BackgroundColor, - AutoSize = false, + ScrollBars = ScrollBars.Vertical, Parent = popup, }; + + var container = new VerticalPanel + { + AnchorPreset = AnchorPresets.StretchAll, + BackgroundColor = Color.Transparent, + IsScrollable = true, + AutoSize = true, + Parent = panel, + }; var border = new Border { BorderColor = BorderColorHighlighted, @@ -482,10 +508,20 @@ namespace FlaxEngine.GUI //AnchorPreset = AnchorPresets.VerticalStretchLeft, Parent = item, }; + popup.SelectedControl = item; } } - popup.Size = new Float2(itemsWidth, height); + if (ShowAllItems || _items.Count < NumberOfItemsToShow) + { + popup.Size = new Float2(itemsWidth, height); + panel.Size = popup.Size; + } + else + { + popup.Size = new Float2(itemsWidth, (itemsHeight + container.Spacing) * NumberOfItemsToShow); + panel.Size = popup.Size; + } return popup; } @@ -527,7 +563,16 @@ namespace FlaxEngine.GUI /// public void ShowPopup() { - var root = Root; + // Find canvas scalar and set as root if it exists. + ContainerControl c = Parent; + while(c.Parent != Root && c.Parent != null) + { + c = c.Parent; + if (c is CanvasScaler scalar) + break; + } + var root = c is CanvasScaler ? c : Root; + if (_items.Count == 0 || root == null) return; @@ -542,7 +587,7 @@ namespace FlaxEngine.GUI // Show dropdown popup var locationRootSpace = Location + new Float2(0, Height); var parent = Parent; - while (parent != null && parent != Root) + while (parent != null && parent != root) { locationRootSpace = parent.PointToParent(ref locationRootSpace); parent = parent.Parent; @@ -551,6 +596,8 @@ namespace FlaxEngine.GUI _popup.Parent = root; _popup.Focus(); _popup.StartMouseCapture(); + if (_popup.SelectedControl != null && _popup.Children[0] is Panel panel) + panel.ScrollViewTo(_popup.SelectedControl, true); OnPopupShow(); } From 1fa03a0de285ee0a3443cc627dfeeaf880de8ef9 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Sat, 28 Oct 2023 11:25:14 -0500 Subject: [PATCH 2/3] Fix focus issues to allow panel scroll bar to be clicked and used. --- Source/Engine/UI/GUI/Common/Dropdown.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/Engine/UI/GUI/Common/Dropdown.cs b/Source/Engine/UI/GUI/Common/Dropdown.cs index bf2dbc0ef..a6c79ea3f 100644 --- a/Source/Engine/UI/GUI/Common/Dropdown.cs +++ b/Source/Engine/UI/GUI/Common/Dropdown.cs @@ -32,7 +32,13 @@ namespace FlaxEngine.GUI public override void OnEndContainsFocus() { base.OnEndContainsFocus(); - + + // Dont lose focus when using panel. Does prevent LostFocus even from being called if clicking inside of the panel. + if (Children[0] is Panel panel && panel.IsMouseOver && !panel.ContainsFocus) + { + panel.Focus(); + return; + } // Call event after this 'focus contains flag' propagation ends to prevent focus issues if (LostFocus != null) Scripting.RunOnUpdate(LostFocus); @@ -433,6 +439,7 @@ namespace FlaxEngine.GUI AnchorPreset = AnchorPresets.StretchAll, BackgroundColor = BackgroundColor, ScrollBars = ScrollBars.Vertical, + AutoFocus = true, Parent = popup, }; From 0930671e909e51454b20323d5d78e8e1d2ebc36b Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 6 Nov 2023 06:25:17 -0600 Subject: [PATCH 3/3] Cache main panel, cleanup cached variables. --- Source/Engine/UI/GUI/Common/Dropdown.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Source/Engine/UI/GUI/Common/Dropdown.cs b/Source/Engine/UI/GUI/Common/Dropdown.cs index a6c79ea3f..92067398d 100644 --- a/Source/Engine/UI/GUI/Common/Dropdown.cs +++ b/Source/Engine/UI/GUI/Common/Dropdown.cs @@ -28,15 +28,20 @@ namespace FlaxEngine.GUI /// public ContainerControl SelectedControl = null; + /// + /// The main panel used to hold the items. + /// + public Panel MainPanel = null; + /// public override void OnEndContainsFocus() { base.OnEndContainsFocus(); // Dont lose focus when using panel. Does prevent LostFocus even from being called if clicking inside of the panel. - if (Children[0] is Panel panel && panel.IsMouseOver && !panel.ContainsFocus) + if (MainPanel != null && MainPanel.IsMouseOver && !MainPanel.ContainsFocus) { - panel.Focus(); + MainPanel.Focus(); return; } // Call event after this 'focus contains flag' propagation ends to prevent focus issues @@ -136,6 +141,8 @@ namespace FlaxEngine.GUI public override void OnDestroy() { LostFocus = null; + MainPanel = null; + SelectedControl = null; base.OnDestroy(); } @@ -442,6 +449,7 @@ namespace FlaxEngine.GUI AutoFocus = true, Parent = popup, }; + popup.MainPanel = panel; var container = new VerticalPanel { @@ -603,8 +611,8 @@ namespace FlaxEngine.GUI _popup.Parent = root; _popup.Focus(); _popup.StartMouseCapture(); - if (_popup.SelectedControl != null && _popup.Children[0] is Panel panel) - panel.ScrollViewTo(_popup.SelectedControl, true); + if (_popup.SelectedControl != null && _popup.MainPanel != null) + _popup.MainPanel.ScrollViewTo(_popup.SelectedControl, true); OnPopupShow(); }