diff --git a/Source/Engine/UI/GUI/Common/Dropdown.cs b/Source/Engine/UI/GUI/Common/Dropdown.cs index 917e51f6e..3bb00990f 100644 --- a/Source/Engine/UI/GUI/Common/Dropdown.cs +++ b/Source/Engine/UI/GUI/Common/Dropdown.cs @@ -8,8 +8,8 @@ namespace FlaxEngine.GUI /// /// Dropdown menu control allows to choose one item from the provided collection of options. /// - /// - public class Dropdown : Control + /// + public class Dropdown : ContainerControl { /// /// The root control used by the to show the items collections and track item selecting event. @@ -18,7 +18,7 @@ namespace FlaxEngine.GUI [HideInEditor] protected class DropdownRoot : Panel { - private bool isMouseDown; + private bool _isMouseDown; /// /// Occurs when item gets clicked. Argument is item index. @@ -38,9 +38,9 @@ namespace FlaxEngine.GUI /// public override bool OnMouseDown(Vector2 location, MouseButton button) { - isMouseDown = true; + _isMouseDown = true; var result = base.OnMouseDown(location, button); - isMouseDown = false; + _isMouseDown = false; if (!result) return false; @@ -57,8 +57,10 @@ namespace FlaxEngine.GUI { base.OnLostFocus(); - if (!isMouseDown) - LostFocus(); + if (!_isMouseDown) + { + LostFocus?.Invoke(); + } } /// @@ -82,7 +84,7 @@ namespace FlaxEngine.GUI /// protected DropdownRoot _popup; - private bool _mouseDown; + private bool _touchDown; /// /// The selected index of the item (-1 for no selection). @@ -118,13 +120,9 @@ namespace FlaxEngine.GUI get => _selectedIndex; set { - // Clamp index value = Mathf.Min(value, _items.Count - 1); - - // Check if index will change if (value != _selectedIndex) { - // Select _selectedIndex = value; OnSelectedIndexChanged(); } @@ -225,6 +223,8 @@ namespace FlaxEngine.GUI public Dropdown() : base(0, 0, 120, 18.0f) { + AutoFocus = false; + var style = Style.Current; Font = new FontReference(style.FontMedium); TextColor = style.Foreground; @@ -334,6 +334,7 @@ namespace FlaxEngine.GUI } */ var itemsWidth = Width; + var height = container.Margin.Height; for (int i = 0; i < _items.Count; i++) { @@ -347,35 +348,51 @@ namespace FlaxEngine.GUI var label = new Label { X = itemsMargin, - Width = itemsWidth - itemsMargin, + Size = new Vector2(itemsWidth - itemsMargin, itemsHeight), Font = Font, TextColor = Color.White * 0.9f, TextColorHighlighted = Color.White, HorizontalAlignment = TextAlignment.Near, - AnchorPreset = AnchorPresets.VerticalStretchRight, Text = _items[i], Parent = item, }; + height += itemsHeight; + if (i != 0) + height += container.Spacing; if (_selectedIndex == i) { var icon = new Image { Brush = CheckedImage, - Width = itemsMargin, + Size = new Vector2(itemsMargin, itemsHeight), Margin = new Margin(4.0f, 6.0f, 4.0f, 4.0f), - AnchorPreset = AnchorPresets.VerticalStretchLeft, + //AnchorPreset = AnchorPresets.VerticalStretchLeft, Parent = item, }; } } - popup.Size = new Vector2(itemsWidth, (itemsHeight + container.Spacing) * _items.Count + container.Margin.Height); + popup.Size = new Vector2(itemsWidth, height); popup.ItemsContainer = container; return popup; } + /// + /// Called when popup menu gets shown. + /// + protected virtual void OnPopupShow() + { + } + + /// + /// Called when popup menu gets hidden. + /// + protected virtual void OnPopupHide() + { + } + /// /// Destroys the popup. /// @@ -383,11 +400,59 @@ namespace FlaxEngine.GUI { if (_popup != null) { + OnPopupHide(); _popup.Dispose(); _popup = null; } } + /// + /// Shows the popup. + /// + public void ShowPopup() + { + var root = Root; + if (_items.Count == 0 || root == null) + return; + + // Setup popup + DestroyPopup(); + _popup = CreatePopup(); + + // Update layout + _popup.UnlockChildrenRecursive(); + _popup.PerformLayout(); + + // Bind events + _popup.ItemClicked += index => + { + OnItemClicked(index); + DestroyPopup(); + }; + _popup.LostFocus += DestroyPopup; + + // Show dropdown popup + Vector2 locationRootSpace = Location + new Vector2(0, Height); + var parent = Parent; + while (parent != null && parent != Root) + { + locationRootSpace = parent.PointToParent(ref locationRootSpace); + parent = parent.Parent; + } + _popup.Location = locationRootSpace; + _popup.Parent = root; + _popup.Focus(); + OnPopupShow(); + } + + /// + /// Hides the popup. + /// + public void HidePopup() + { + DestroyPopup(); + } + /// public override void OnDestroy() { @@ -397,7 +462,7 @@ namespace FlaxEngine.GUI } /// - public override void Draw() + public override void DrawSelf() { // Cache data var clientRect = new Rectangle(Vector2.Zero, Size); @@ -413,7 +478,7 @@ namespace FlaxEngine.GUI backgroundColor *= 0.5f; arrowColor *= 0.7f; } - else if (isOpened || _mouseDown) + else if (isOpened || _touchDown) { backgroundColor = BackgroundColorSelected; borderColor = BorderColorSelected; @@ -448,17 +513,15 @@ namespace FlaxEngine.GUI /// public override void OnLostFocus() { - base.OnLostFocus(); + _touchDown = false; - // Clear flags - _mouseDown = false; + base.OnLostFocus(); } /// public override void OnMouseLeave() { - // Clear flags - _mouseDown = false; + _touchDown = false; base.OnMouseLeave(); } @@ -466,59 +529,60 @@ namespace FlaxEngine.GUI /// public override bool OnMouseDown(Vector2 location, MouseButton button) { - // Check mouse buttons + if (base.OnMouseDown(location, button)) + return true; + if (button == MouseButton.Left) { - // Set flag - _mouseDown = true; + _touchDown = true; + return true; } - return base.OnMouseDown(location, button); + return false; } /// public override bool OnMouseUp(Vector2 location, MouseButton button) { - // Check flags - if (_mouseDown) + if (_touchDown && button == MouseButton.Left) { - // Clear flag - _mouseDown = false; - - var root = Root; - if (_items.Count > 0 && root != null) - { - // Setup popup - DestroyPopup(); - _popup = CreatePopup(); - - // Update layout - _popup.UnlockChildrenRecursive(); - _popup.PerformLayout(); - - // Bind events - _popup.ItemClicked += (index) => - { - OnItemClicked(index); - DestroyPopup(); - }; - _popup.LostFocus += DestroyPopup; - - // Show dropdown popup - Vector2 locationRootSpace = Location + new Vector2(0, Height); - var parent = Parent; - while (parent != null && parent != Root) - { - locationRootSpace = parent.PointToParent(ref location); - parent = parent.Parent; - } - _popup.Location = locationRootSpace; - _popup.Parent = root; - _popup.Focus(); - } + _touchDown = false; + ShowPopup(); + return true; } + return base.OnMouseUp(location, button); + } + + /// + public override bool OnTouchDown(Vector2 location, int pointerId) + { + if (base.OnTouchDown(location, pointerId)) + return true; + + _touchDown = true; return true; } + + /// + public override bool OnTouchUp(Vector2 location, int pointerId) + { + if (base.OnTouchUp(location, pointerId)) + return true; + + if (_touchDown) + { + ShowPopup(); + } + return true; + } + + /// + public override void OnTouchLeave(int pointerId) + { + _touchDown = false; + + base.OnTouchLeave(pointerId); + } } }