From 13e210c897048b7bd4c626d9eea49a72d8e614d6 Mon Sep 17 00:00:00 2001 From: Michael Ragazzon Date: Mon, 28 Oct 2024 23:33:36 +0100 Subject: [PATCH] Text widget changes (squash) Use separate bool for layout_dirty vs box just opened, as these two states are not really mutually exclusive. Fixes a bug where the box was not considered just opened since the "open" state was overwritten by the "switch" state. Use center vertical alignment for a just opened box. This is admittedly a subjective matter. However, it looked a bit weird to me how it would scroll past the first few elements when you select, say, just the second or third element. With center, both the first few, and the last items, are shown when selecting something near the beginning or the end respectively. This also feels more symmetrical when the selection box ends up being placed above the select element. --- Source/Core/Elements/WidgetDropDown.cpp | 26 ++++++++++++++----------- Source/Core/Elements/WidgetDropDown.h | 12 +++--------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Source/Core/Elements/WidgetDropDown.cpp b/Source/Core/Elements/WidgetDropDown.cpp index 5b14d80eb..065a99714 100644 --- a/Source/Core/Elements/WidgetDropDown.cpp +++ b/Source/Core/Elements/WidgetDropDown.cpp @@ -48,7 +48,8 @@ WidgetDropDown::WidgetDropDown(ElementFormControl* element) lock_selection = false; selection_dirty = false; - box_layout_dirty = DropDownBoxLayoutType::None; + box_layout_dirty = false; + box_opened_since_last_format = false; value_rml_dirty = false; value_layout_dirty = false; box_visible = false; @@ -151,7 +152,7 @@ void WidgetDropDown::OnUpdate() void WidgetDropDown::OnRender() { - if (box_visible && box_layout_dirty != DropDownBoxLayoutType::None) + if (box_visible && box_layout_dirty) { // Layout the selection box. // The following procedure should ensure that the selection box is never (partly) outside of the context's window. @@ -235,13 +236,15 @@ void WidgetDropDown::OnRender() // Scroll selected element into view, if we have one if (selection != -1) { - Rml::ScrollIntoViewOptions scrollOptions { - box_layout_dirty == DropDownBoxLayoutType::Open ? Rml::ScrollAlignment::Start : Rml::ScrollAlignment::Nearest + ScrollIntoViewOptions scroll_options = { + box_opened_since_last_format ? ScrollAlignment::Center : ScrollAlignment::Nearest, + ScrollAlignment::Nearest, + ScrollBehavior::Instant, }; - GetOption(selection)->ScrollIntoView(scrollOptions); + GetOption(selection)->ScrollIntoView(scroll_options); } - - box_layout_dirty = DropDownBoxLayoutType::None; + box_opened_since_last_format = false; + box_layout_dirty = false; } if (value_layout_dirty) @@ -278,7 +281,7 @@ void WidgetDropDown::OnLayout() value_element->SetOffset(parent_element->GetBox().GetPosition(BoxArea::Content), parent_element); value_element->SetBox(Box(size)); - box_layout_dirty = DropDownBoxLayoutType::Switch; + box_layout_dirty = true; value_layout_dirty = true; } @@ -460,7 +463,7 @@ void WidgetDropDown::OnChildAdd(Element* element) SetSelection(element, true); selection_dirty = true; - box_layout_dirty = DropDownBoxLayoutType::Switch; + box_layout_dirty = true; } void WidgetDropDown::OnChildRemove(Element* element) @@ -474,7 +477,7 @@ void WidgetDropDown::OnChildRemove(Element* element) SetSelection(nullptr); selection_dirty = true; - box_layout_dirty = DropDownBoxLayoutType::Switch; + box_layout_dirty = true; } void WidgetDropDown::AttachScrollEvent() @@ -629,7 +632,8 @@ void WidgetDropDown::ShowSelectBox() selection_element->SetPseudoClass("checked", true); value_element->SetPseudoClass("checked", true); button_element->SetPseudoClass("checked", true); - box_layout_dirty = DropDownBoxLayoutType::Open; + box_layout_dirty = true; + box_opened_since_last_format = true; AttachScrollEvent(); box_visible = true; diff --git a/Source/Core/Elements/WidgetDropDown.h b/Source/Core/Elements/WidgetDropDown.h index 5b0143ffe..2914160d6 100644 --- a/Source/Core/Elements/WidgetDropDown.h +++ b/Source/Core/Elements/WidgetDropDown.h @@ -40,12 +40,6 @@ class ElementFormControl; @author Lloyd Weehuizen */ -enum class DropDownBoxLayoutType { - None, - Open, // we just opened the drop-down menu - Switch // we're switching the selected value -}; - class WidgetDropDown : public EventListener { public: WidgetDropDown(ElementFormControl* element); @@ -105,7 +99,7 @@ class WidgetDropDown : public EventListener { /// Processes the incoming event. void ProcessEvent(Event& event) override; - + /// Shows the selection box. void ShowSelectBox(); /// Hides the selection box. @@ -114,7 +108,6 @@ class WidgetDropDown : public EventListener { bool IsSelectBoxVisible(); private: - void AttachScrollEvent(); void DetachScrollEvent(); @@ -130,7 +123,8 @@ class WidgetDropDown : public EventListener { bool selection_dirty; bool value_rml_dirty; bool value_layout_dirty; - DropDownBoxLayoutType box_layout_dirty; + bool box_layout_dirty; + bool box_opened_since_last_format; bool box_visible; };