diff --git a/Include/RmlUi/Core/Elements/ElementFormControlSelect.h b/Include/RmlUi/Core/Elements/ElementFormControlSelect.h index 7488b317c..b5f55ba4b 100644 --- a/Include/RmlUi/Core/Elements/ElementFormControlSelect.h +++ b/Include/RmlUi/Core/Elements/ElementFormControlSelect.h @@ -93,6 +93,13 @@ class RMLUICORE_API ElementFormControlSelect : public ElementFormControl { /// Removes all options from the select control. void RemoveAll(); + + /// Show the selection box. + void ShowSelectBox(); + /// Hide the selection box. + void HideSelectBox(); + /// Check whether the select box is opened or not. + bool IsSelectBoxVisible(); protected: /// Moves all children to be under control of the widget. diff --git a/Source/Core/Elements/ElementFormControlSelect.cpp b/Source/Core/Elements/ElementFormControlSelect.cpp index d447614b5..c7353f1c6 100644 --- a/Source/Core/Elements/ElementFormControlSelect.cpp +++ b/Source/Core/Elements/ElementFormControlSelect.cpp @@ -110,6 +110,21 @@ void ElementFormControlSelect::RemoveAll() widget->ClearOptions(); } +void ElementFormControlSelect::ShowSelectBox() +{ + widget->ShowSelectBox(); +} + +void ElementFormControlSelect::HideSelectBox() +{ + widget->HideSelectBox(); +} + +bool ElementFormControlSelect::IsSelectBoxVisible() +{ + return widget->IsSelectBoxVisible(); +} + void ElementFormControlSelect::OnUpdate() { ElementFormControl::OnUpdate(); diff --git a/Source/Core/Elements/WidgetDropDown.cpp b/Source/Core/Elements/WidgetDropDown.cpp index b4c0fc31e..065a99714 100644 --- a/Source/Core/Elements/WidgetDropDown.cpp +++ b/Source/Core/Elements/WidgetDropDown.cpp @@ -49,6 +49,7 @@ WidgetDropDown::WidgetDropDown(ElementFormControl* element) lock_selection = false; selection_dirty = false; box_layout_dirty = false; + box_opened_since_last_format = false; value_rml_dirty = false; value_layout_dirty = false; box_visible = false; @@ -230,6 +231,19 @@ void WidgetDropDown::OnRender() selection_element->SetOffset(Vector2f(offset_x, offset_y), parent_element); } + int selection = GetSelection(); + + // Scroll selected element into view, if we have one + if (selection != -1) + { + ScrollIntoViewOptions scroll_options = { + box_opened_since_last_format ? ScrollAlignment::Center : ScrollAlignment::Nearest, + ScrollAlignment::Nearest, + ScrollBehavior::Instant, + }; + GetOption(selection)->ScrollIntoView(scroll_options); + } + box_opened_since_last_format = false; box_layout_dirty = false; } @@ -502,7 +516,7 @@ void WidgetDropDown::ProcessEvent(Event& event) SetSelection(current_element); event.StopPropagation(); - ShowSelectBox(false); + HideSelectBox(); parent_element->Focus(); } } @@ -523,9 +537,9 @@ void WidgetDropDown::ProcessEvent(Event& event) } if (selection_element->GetComputedValues().visibility() == Style::Visibility::Hidden) - ShowSelectBox(true); + ShowSelectBox(); else - ShowSelectBox(false); + HideSelectBox(); } } break; @@ -542,7 +556,7 @@ void WidgetDropDown::ProcessEvent(Event& event) { if (event.GetTargetElement() == parent_element) { - ShowSelectBox(false); + HideSelectBox(); value_element->SetPseudoClass("focus", false); button_element->SetPseudoClass("focus", false); } @@ -604,7 +618,7 @@ void WidgetDropDown::ProcessEvent(Event& event) } if (!scrolls_selection_box) - ShowSelectBox(false); + HideSelectBox(); } } break; @@ -612,28 +626,34 @@ void WidgetDropDown::ProcessEvent(Event& event) } } -void WidgetDropDown::ShowSelectBox(bool show) +void WidgetDropDown::ShowSelectBox() { - if (show) - { - selection_element->SetProperty(PropertyId::Visibility, Property(Style::Visibility::Visible)); - selection_element->SetPseudoClass("checked", true); - value_element->SetPseudoClass("checked", true); - button_element->SetPseudoClass("checked", true); - box_layout_dirty = true; - AttachScrollEvent(); - } - else - { - selection_element->SetProperty(PropertyId::Visibility, Property(Style::Visibility::Hidden)); - selection_element->RemoveProperty(PropertyId::Height); - selection_element->SetPseudoClass("checked", false); - value_element->SetPseudoClass("checked", false); - button_element->SetPseudoClass("checked", false); - DetachScrollEvent(); - } + selection_element->SetProperty(PropertyId::Visibility, Property(Style::Visibility::Visible)); + selection_element->SetPseudoClass("checked", true); + value_element->SetPseudoClass("checked", true); + button_element->SetPseudoClass("checked", true); + box_layout_dirty = true; + box_opened_since_last_format = true; + AttachScrollEvent(); - box_visible = show; + box_visible = true; +} + +void WidgetDropDown::HideSelectBox() +{ + selection_element->SetProperty(PropertyId::Visibility, Property(Style::Visibility::Hidden)); + selection_element->RemoveProperty(PropertyId::Height); + selection_element->SetPseudoClass("checked", false); + value_element->SetPseudoClass("checked", false); + button_element->SetPseudoClass("checked", false); + DetachScrollEvent(); + + box_visible = false; +} + +bool WidgetDropDown::IsSelectBoxVisible() +{ + return box_visible; } } // namespace Rml diff --git a/Source/Core/Elements/WidgetDropDown.h b/Source/Core/Elements/WidgetDropDown.h index 97564ec26..2914160d6 100644 --- a/Source/Core/Elements/WidgetDropDown.h +++ b/Source/Core/Elements/WidgetDropDown.h @@ -100,10 +100,14 @@ class WidgetDropDown : public EventListener { /// Processes the incoming event. void ProcessEvent(Event& event) override; -private: - // Shows or hides the selection box. - void ShowSelectBox(bool show); + /// Shows the selection box. + void ShowSelectBox(); + /// Hides the selection box. + void HideSelectBox(); + /// Check whether the select box is visible or not. + bool IsSelectBoxVisible(); +private: void AttachScrollEvent(); void DetachScrollEvent(); @@ -120,6 +124,7 @@ class WidgetDropDown : public EventListener { bool value_rml_dirty; bool value_layout_dirty; bool box_layout_dirty; + bool box_opened_since_last_format; bool box_visible; };