Skip to content

Commit

Permalink
Add CancelSelectBox() method to <select> element, see #566
Browse files Browse the repository at this point in the history
This reverts the value to the one set when the selection box was opened. This is particularly helpful for use cases where e.g. the "Escape" key should cancel the selection.

Added example usage to the demo sample.
  • Loading branch information
mikke89 committed Oct 31, 2024
1 parent b32980a commit 347773b
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 3 deletions.
6 changes: 4 additions & 2 deletions Include/RmlUi/Core/Elements/ElementFormControlSelect.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class RMLUICORE_API ElementFormControlSelect : public ElementFormControl {
int GetSelection() const;

/// Returns one of the select control's option elements.
/// @param[in] The index of the desired option.
/// @param[in] index The index of the desired option.
/// @return The option element or nullptr if the index was out of bounds.
Element* GetOption(int index);
/// Returns the number of options in the select control.
Expand All @@ -93,11 +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();
/// Revert to the value selected when the selection box was opened, then hide the box.
void CancelSelectBox();
/// Check whether the select box is opened or not.
bool IsSelectBoxVisible();

Expand Down
2 changes: 1 addition & 1 deletion Samples/basic/demo/data/demo.rml
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ form .nav-auto, form input.checkbox, form input.radio
</div>
<h2>Subject</h2>
<div>
<select name="subject">
<select name="subject" onkeydown="cancel_selection_on_escape">
<option value="none" selected>Choose your subject</option>
<option value="feature">Feature request</option>
<option value="bug">Bug report</option>
Expand Down
13 changes: 13 additions & 0 deletions Samples/basic/demo/src/DemoEventListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "DemoWindow.h"
#include <RmlUi/Core/Element.h>
#include <RmlUi/Core/Elements/ElementFormControl.h>
#include <RmlUi/Core/Elements/ElementFormControlSelect.h>
#include <RmlUi_Backend.h>

DemoEventListener::DemoEventListener(const Rml::String& value, Rml::Element* element, DemoWindow* demo_window) :
Expand Down Expand Up @@ -178,6 +179,18 @@ void DemoEventListener::ProcessEvent(Rml::Event& event)
demo_window->SetSandboxStylesheet(value);
}
}
else if (value == "cancel_selection_on_escape")
{
if (event.GetParameter("key_identifier", 0) == Input::KeyIdentifier ::KI_ESCAPE)
{
auto select_control = rmlui_dynamic_cast<Rml::ElementFormControlSelect*>(element);
if (select_control && select_control->IsSelectBoxVisible())
{
select_control->CancelSelectBox();
event.StopPropagation();
}
}
}
}

void DemoEventListener::OnDetach(Rml::Element* /*element*/)
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/Elements/ElementFormControlSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ void ElementFormControlSelect::HideSelectBox()
{
widget->HideSelectBox();
}
void ElementFormControlSelect::CancelSelectBox()
{
widget->CancelSelectBox();
}

bool ElementFormControlSelect::IsSelectBoxVisible()
{
Expand Down
18 changes: 18 additions & 0 deletions Source/Core/Elements/WidgetDropDown.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,10 @@ void WidgetDropDown::ProcessEvent(Event& event)

void WidgetDropDown::ShowSelectBox()
{
if (box_visible)
return;

selected_value_on_box_open = parent_element->GetAttribute<String>("value", "");
selection_element->SetProperty(PropertyId::Visibility, Property(Style::Visibility::Visible));
selection_element->SetPseudoClass("checked", true);
value_element->SetPseudoClass("checked", true);
Expand All @@ -647,6 +651,9 @@ void WidgetDropDown::ShowSelectBox()

void WidgetDropDown::HideSelectBox()
{
if (!box_visible)
return;

selection_element->SetProperty(PropertyId::Visibility, Property(Style::Visibility::Hidden));
selection_element->RemoveProperty(PropertyId::Height);
selection_element->SetPseudoClass("checked", false);
Expand All @@ -657,6 +664,17 @@ void WidgetDropDown::HideSelectBox()
box_visible = false;
}

void WidgetDropDown::CancelSelectBox()
{
if (!box_visible)
return;

if (parent_element->GetAttribute<String>("value", "") != selected_value_on_box_open)
parent_element->SetAttribute("value", selected_value_on_box_open);

HideSelectBox();
}

bool WidgetDropDown::IsSelectBoxVisible()
{
return box_visible;
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/Elements/WidgetDropDown.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class WidgetDropDown : public EventListener {
void ShowSelectBox();
/// Hides the selection box.
void HideSelectBox();
/// Revert to the value selected when the selection box was opened, then hide the box.
void CancelSelectBox();
/// Check whether the select box is visible or not.
bool IsSelectBoxVisible();

Expand All @@ -119,6 +121,8 @@ class WidgetDropDown : public EventListener {
Element* selection_element;
Element* value_element;

String selected_value_on_box_open;

bool lock_selection = false;
bool selection_dirty = false;
bool value_rml_dirty = false;
Expand Down

0 comments on commit 347773b

Please sign in to comment.