Skip to content

Commit

Permalink
popup: close popup on escape press. (slint-ui#6978)
Browse files Browse the repository at this point in the history
* Update internal/common/enums.rs

Co-authored-by: Arnold Loubriat <datatriny@gmail.com>

---------

Co-authored-by: Arnold Loubriat <datatriny@gmail.com>
  • Loading branch information
FloVanGH and DataTriny authored Dec 3, 2024
1 parent 45e83d3 commit 0bd242c
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 10 deletions.
6 changes: 3 additions & 3 deletions internal/common/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,13 @@ macro_rules! for_each_enums {

// This enum describes the close behaviour of [`PopupWindow`](elements.md#popupwindow)
enum PopupClosePolicy {
/// Closes the `PopupWindow` when user clicks.
/// Closes the `PopupWindow` when user clicks or presses the escape key.
CloseOnClick,

/// Closed the `PopupWindow` when user clicks outside of the popup.
/// Closes the `PopupWindow` when user clicks outside of the popup or presses the escape key.
CloseOnClickOutside,

/// Does not close the `PopupWindow` automatically when user clicks
/// Does not close the `PopupWindow` automatically when user clicks.
NoAutoClose,
}
];
Expand Down
14 changes: 14 additions & 0 deletions internal/core/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,20 @@ impl WindowInner {
&& !extra_mod
{
self.focus_previous_item();
} else if event.event_type == KeyEventType::KeyPressed
&& event.text.starts_with(key_codes::Escape)
{
// Closes top most popup on esc key pressed when policy is not no-auto-close
let close_on_escape = if let Some(popup) = self.active_popups.borrow().last() {
popup.close_policy == PopupClosePolicy::CloseOnClick
|| popup.close_policy == PopupClosePolicy::CloseOnClickOutside
} else {
false
};

if close_on_escape {
self.close_top_popup();
}
}
crate::properties::ChangeTracker::run_change_handlers();
}
Expand Down
91 changes: 84 additions & 7 deletions tests/cases/elements/popupwindow_close_policy.slint
Original file line number Diff line number Diff line change
Expand Up @@ -213,19 +213,25 @@ assert_eq!(instance.get_click_count(), 1);
assert_eq!(instance.get_popup_created(), true);
assert_eq!(instance.get_popup_clicked(), 1);
// Press esc nothing happen
slint_testing::send_keyboard_string_sequence(&instance, "\u{001b}");
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq!(instance.get_click_count(), 1);
assert_eq!(instance.get_popup_clicked(), 1001);
// Click outside, nothing happens
slint_testing::send_mouse_click(&instance, 1., 1.);
assert_eq!(instance.get_click_count(), 1);
assert_eq!(instance.get_popup_clicked(), 1);
assert_eq!(instance.get_popup_clicked(), 1001);
// Click on the popup, it's registered but nothing is done
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq!(instance.get_click_count(), 1);
assert_eq!(instance.get_popup_clicked(), 1001);
assert_eq!(instance.get_popup_clicked(), 2001);
// Click again to verify that it was _not_ closed
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq!(instance.get_click_count(), 1);
assert_eq!(instance.get_popup_clicked(), 2001);
assert_eq!(instance.get_popup_clicked(), 3001);
// Close manually and verify that subsequent click is passed through
instance.invoke_do_close();
Expand All @@ -234,7 +240,7 @@ assert_eq!(instance.get_click_count(), 2);
instance.invoke_do_close();
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq!(instance.get_click_count(), 3);
assert_eq!(instance.get_popup_clicked(), 2001);
assert_eq!(instance.get_popup_clicked(), 3001);
// --------- Close outside click popup
Expand All @@ -244,20 +250,35 @@ instance.set_click_count(0);
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq!(instance.get_click_count(), 1);
assert_eq!(instance.get_popup_created(), true);
assert_eq!(instance.get_popup_clicked(), 2001);
assert_eq!(instance.get_popup_clicked(), 3001);
// click inside
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq!(instance.get_popup_clicked(), 2003);
assert_eq!(instance.get_popup_clicked(), 3003);
// Click outside to close
slint_testing::send_mouse_click(&instance, 5., 5.);
assert_eq!(instance.get_click_count(), 1);
// Subsequent click to verify that it was closed
slint_testing::send_mouse_click(&instance, 5., 5.);
assert_eq!(instance.get_click_count(), 2);
assert_eq!(instance.get_popup_clicked(), 2003);
assert_eq!(instance.get_popup_clicked(), 3003);
// --------- Close outside click popup by esc
instance.set_popup_selector(3);
instance.set_click_count(0);
slint_testing::send_mouse_click(&instance, 5., 5.);
assert_eq!(instance.get_click_count(), 1);
// click inside
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq!(instance.get_popup_clicked(), 3005);
// close by esc
slint_testing::send_keyboard_string_sequence(&instance, "\u{001b}");
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq!(instance.get_click_count(), 2);
```
Expand Down Expand Up @@ -325,6 +346,8 @@ instance.set_popup_selector(1);
instance.set_popup_created(false);
instance.set_click_count(0);
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq(instance.get_click_count(), 1);
assert_eq(instance.get_popup_created(), true);
Expand Down Expand Up @@ -379,6 +402,44 @@ instance.invoke_do_close();
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq(instance.get_click_count(), 3);
assert_eq(instance.get_popup_clicked(), 2001);
// --------- Close outside click popup
instance.set_popup_selector(3);
instance.set_popup_created(false);
instance.set_click_count(0);
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq(instance.get_click_count(), 1);
assert_eq(instance.get_popup_created(), true);
assert_eq(instance.get_popup_clicked(), 2001);
// click inside
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq(instance.get_popup_clicked(), 2003);
// Click outside to close
slint_testing::send_mouse_click(&instance, 5., 5.);
assert_eq(instance.get_click_count(), 1);
// Subsequent click to verify that it was closed
slint_testing::send_mouse_click(&instance, 5., 5.);
assert_eq(instance.get_click_count(), 2);
assert_eq(instance.get_popup_clicked(), 2003);
// --------- Close outside click popup by esc
instance.set_popup_selector(3);
instance.set_click_count(0);
slint_testing::send_mouse_click(&instance, 5., 5.);
assert_eq(instance.get_click_count(), 1);
// click inside
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq(instance.get_popup_clicked(), 2005);
// close by esc
slint_testing::send_keyboard_string_sequence(&instance, "\u001b");
slint_testing::send_mouse_click(&instance, 15., 15.);
assert_eq(instance.get_click_count(), 2);
```
```disable-because-nodejs-runs-with-qt-and-send-mouse-click-wont-send-to-popup-qwindow
Expand Down Expand Up @@ -450,6 +511,22 @@ assert.equal(instance.get_click_count(), 1);
slintlib.private_api.send_mouse_click(instance, 15., 15.);
assert.equal(instance.get_click_count(), 2);
assert.equal(instance.get_popup_clicked(), 2003);
// --------- Close outside click popup by esc
instance.set_popup_selector(3);
instance.set_click_count(0);
slintlib.private_api.send_mouse_click(instance, 5., 5.);
assert.equal(instance.get_click_count(), 1);
// click inside
slintlib.private_api.send_mouse_click(instance, 15., 15.);
assert.equal(instance.get_popup_clicked(), 2005);
// close by esc
slintlib.private_api.send_keyboard_string_sequence(instance, "\u{001b}");
slintlib.private_api.send_mouse_click(instance, 15., 15.);
assert.equal(instance.get_click_count(), 2);
```
*/
15 changes: 15 additions & 0 deletions tests/cases/elements/popupwindow_nested.slint
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,21 @@ instance.set_result("".into());
slint_testing::send_mouse_click(&instance, 210., 90.);
assert_eq!(instance.get_result(), "P1");
instance.set_result("".into());
// close popup1
slint_testing::send_mouse_click(&instance, 150., 210. + 40.);
// open both popups
slint_testing::send_mouse_click(&instance, 380., 10.);
// close popup1 by esc
slint_testing::send_keyboard_string_sequence(&instance, "\u{001b}");
// popup2 is still open
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
assert_eq!(instance.get_result(), "C2");
instance.set_result("".into());
```
```cpp
Expand Down

0 comments on commit 0bd242c

Please sign in to comment.