mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 18:58:36 +00:00
PopopWindow: Fix close-policy and close-on-click when inheriting
This commit is contained in:
parent
72b11af08c
commit
0f15a26f35
3 changed files with 701 additions and 87 deletions
|
@ -3,14 +3,17 @@
|
|||
|
||||
//! Passe that transform the PopupWindow element into a component
|
||||
|
||||
use crate::diagnostics::BuildDiagnostics;
|
||||
use crate::expression_tree::{Expression, NamedReference};
|
||||
use crate::diagnostics::{BuildDiagnostics, SourceLocation};
|
||||
use crate::expression_tree::{BindingExpression, Expression, NamedReference};
|
||||
use crate::langtype::{ElementType, EnumerationValue, Type};
|
||||
use crate::object_tree::*;
|
||||
use crate::typeregister::TypeRegister;
|
||||
use smol_str::{format_smolstr, SmolStr};
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
const CLOSE_ON_CLICK: &str = "close-on-click";
|
||||
const CLOSE_POLICY: &str = "close-policy";
|
||||
|
||||
pub fn lower_popups(
|
||||
component: &Rc<Component>,
|
||||
type_register: &TypeRegister,
|
||||
|
@ -42,6 +45,28 @@ fn lower_popup_window(
|
|||
window_type: &ElementType,
|
||||
diag: &mut BuildDiagnostics,
|
||||
) {
|
||||
if let Some(binding) = popup_window_element.borrow().bindings.get(CLOSE_ON_CLICK) {
|
||||
if popup_window_element.borrow().bindings.get(CLOSE_POLICY).is_some() {
|
||||
diag.push_error(
|
||||
"close-policy and close-on-click cannot be set at the same time".into(),
|
||||
&binding.borrow().span,
|
||||
);
|
||||
} else {
|
||||
diag.push_property_deprecation_warning(
|
||||
CLOSE_ON_CLICK,
|
||||
CLOSE_POLICY,
|
||||
&binding.borrow().span,
|
||||
);
|
||||
if !matches!(binding.borrow().expression, Expression::BoolLiteral(_)) {
|
||||
report_const_error(CLOSE_ON_CLICK, &binding.borrow().span, diag);
|
||||
}
|
||||
}
|
||||
} else if let Some(binding) = popup_window_element.borrow().bindings.get(CLOSE_POLICY) {
|
||||
if !matches!(binding.borrow().expression, Expression::EnumerationValue(_)) {
|
||||
report_const_error(CLOSE_POLICY, &binding.borrow().span, diag);
|
||||
}
|
||||
}
|
||||
|
||||
let parent_component = popup_window_element.borrow().enclosing_component.upgrade().unwrap();
|
||||
let parent_element = match parent_element {
|
||||
None => {
|
||||
|
@ -76,103 +101,73 @@ fn lower_popup_window(
|
|||
popup_window_element.borrow_mut().base_type = window_type.clone();
|
||||
}
|
||||
|
||||
const CLOSE_ON_CLICK: &str = "close-on-click";
|
||||
let close_on_click = popup_window_element.borrow_mut().bindings.remove(CLOSE_ON_CLICK);
|
||||
|
||||
// Take a reference to the close on click
|
||||
let close_on_click = close_on_click
|
||||
.map(|b| {
|
||||
diag.push_property_deprecation_warning(
|
||||
"close-on-click",
|
||||
"close-policy",
|
||||
&b.borrow().span,
|
||||
);
|
||||
let b = b.into_inner();
|
||||
(b.expression, b.span)
|
||||
let map_close_on_click_value = |b: &BindingExpression| {
|
||||
let Expression::BoolLiteral(v) = b.expression else {
|
||||
assert!(diag.has_errors());
|
||||
return None;
|
||||
};
|
||||
let enum_ty = crate::typeregister::BUILTIN.with(|e| e.enums.PopupClosePolicy.clone());
|
||||
let s = if v { "close-on-click" } else { "no-auto-close" };
|
||||
Some(EnumerationValue {
|
||||
value: enum_ty.values.iter().position(|v| v == s).unwrap(),
|
||||
enumeration: enum_ty,
|
||||
})
|
||||
.or_else(|| {
|
||||
let mut base = popup_window_element.borrow().base_type.clone();
|
||||
while let ElementType::Component(b) = base {
|
||||
base = b.root_element.borrow().base_type.clone();
|
||||
if let Some(binding) = b.root_element.borrow().bindings.get(CLOSE_ON_CLICK) {
|
||||
let b = binding.borrow();
|
||||
return Some((b.expression.clone(), b.span.clone()));
|
||||
}
|
||||
};
|
||||
|
||||
let close_policy =
|
||||
popup_window_element.borrow_mut().bindings.remove(CLOSE_POLICY).and_then(|b| {
|
||||
let b = b.into_inner();
|
||||
if let Expression::EnumerationValue(v) = b.expression {
|
||||
Some(v)
|
||||
} else {
|
||||
assert!(diag.has_errors());
|
||||
None
|
||||
}
|
||||
None
|
||||
});
|
||||
|
||||
const CLOSE_POLICY: &str = "close-policy";
|
||||
let close_policy = popup_window_element.borrow_mut().bindings.remove(CLOSE_POLICY);
|
||||
|
||||
// Take a reference to the close policy
|
||||
let close_policy = close_policy
|
||||
.map(|b| {
|
||||
let b = b.into_inner();
|
||||
(b.expression, b.span)
|
||||
.or_else(|| {
|
||||
popup_window_element
|
||||
.borrow_mut()
|
||||
.bindings
|
||||
.remove(CLOSE_ON_CLICK)
|
||||
.and_then(|b| map_close_on_click_value(&b.borrow()))
|
||||
})
|
||||
.or_else(|| {
|
||||
// check bases
|
||||
let mut base = popup_window_element.borrow().base_type.clone();
|
||||
while let ElementType::Component(b) = base {
|
||||
base = b.root_element.borrow().base_type.clone();
|
||||
if let Some(binding) = b.root_element.borrow().bindings.get(CLOSE_POLICY) {
|
||||
let b = binding.borrow();
|
||||
return Some((b.expression.clone(), b.span.clone()));
|
||||
let base_policy = b
|
||||
.root_element
|
||||
.borrow()
|
||||
.bindings
|
||||
.get(CLOSE_POLICY)
|
||||
.and_then(|b| {
|
||||
let b = b.borrow();
|
||||
if let Expression::EnumerationValue(v) = &b.expression {
|
||||
return Some(v.clone());
|
||||
}
|
||||
assert!(diag.has_errors());
|
||||
None
|
||||
})
|
||||
.or_else(|| {
|
||||
b.root_element
|
||||
.borrow()
|
||||
.bindings
|
||||
.get(CLOSE_ON_CLICK)
|
||||
.and_then(|b| map_close_on_click_value(&b.borrow()))
|
||||
});
|
||||
if let Some(base_policy) = base_policy {
|
||||
return Some(base_policy);
|
||||
}
|
||||
base = b.root_element.borrow().base_type.clone();
|
||||
}
|
||||
None
|
||||
})
|
||||
.unwrap_or_else(|| EnumerationValue {
|
||||
value: 0,
|
||||
enumeration: crate::typeregister::BUILTIN.with(|e| e.enums.PopupClosePolicy.clone()),
|
||||
});
|
||||
|
||||
if close_policy.is_some() && close_on_click.is_some() {
|
||||
diag.push_error(
|
||||
"close-policy and close-on-click cannot be set at the same time".into(),
|
||||
&close_on_click.unwrap().1,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let close_on_click = match close_on_click {
|
||||
Some((expr, location)) => match expr {
|
||||
Expression::BoolLiteral(value) => Some(value),
|
||||
_ => {
|
||||
diag.push_error(
|
||||
"The close-on-click property only supports constants at the moment".into(),
|
||||
&location,
|
||||
);
|
||||
return;
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let close_policy = match close_policy {
|
||||
Some((expr, location)) => match expr {
|
||||
Expression::EnumerationValue(value) => value,
|
||||
_ => {
|
||||
diag.push_error(
|
||||
"The close-policy property only supports constants at the moment".into(),
|
||||
&location,
|
||||
);
|
||||
return;
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let enum_ty = crate::typeregister::BUILTIN.with(|e| e.enums.PopupClosePolicy.clone());
|
||||
|
||||
let mut value = String::from("close-on-click");
|
||||
|
||||
if let Some(close_on_click) = close_on_click {
|
||||
if !close_on_click {
|
||||
value = "no-auto-close".into()
|
||||
}
|
||||
}
|
||||
EnumerationValue {
|
||||
value: enum_ty.values.iter().position(|v| v == value.as_str()).unwrap(),
|
||||
enumeration: enum_ty,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let popup_comp = Rc::new(Component {
|
||||
root_element: popup_window_element.clone(),
|
||||
parent_element: Rc::downgrade(parent_element),
|
||||
|
@ -235,6 +230,10 @@ fn lower_popup_window(
|
|||
});
|
||||
}
|
||||
|
||||
fn report_const_error(prop: &str, span: &Option<SourceLocation>, diag: &mut BuildDiagnostics) {
|
||||
diag.push_error(format!("The {} property only supports constants at the moment", prop), span);
|
||||
}
|
||||
|
||||
fn check_element(
|
||||
element: &ElementRc,
|
||||
popup_comp: &Weak<Component>,
|
||||
|
|
|
@ -1,6 +1,35 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
component DeprecatedDerives inherits PopupWindow {
|
||||
close-on-click: false;
|
||||
// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead}
|
||||
}
|
||||
|
||||
|
||||
component Derives inherits PopupWindow {
|
||||
close-policy: close-on-click-outside;
|
||||
}
|
||||
|
||||
component D1 inherits PopupWindow {
|
||||
close-on-click: false;
|
||||
// ^error{close-policy and close-on-click cannot be set at the same }
|
||||
close-policy: close-on-click-outside;
|
||||
}
|
||||
|
||||
component D2 inherits PopupWindow {
|
||||
close-on-click: (!false);
|
||||
// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead}
|
||||
// ^^error{The close-on-click property only supports constants at the moment}
|
||||
}
|
||||
|
||||
component D3 inherits PopupWindow {
|
||||
in property <PopupClosePolicy> pp;
|
||||
close-policy: pp;
|
||||
// ^error{The close-policy property only supports constants at the moment}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export component Bar {
|
||||
in property <bool> external;
|
||||
|
@ -10,13 +39,51 @@ export component Bar {
|
|||
init => {
|
||||
xx.close-on-click = true;
|
||||
// ^error{The property must be known at compile time and cannot be changed at runtime}
|
||||
|
||||
xx.close-policy = PopupClosePolicy.close-on-click;
|
||||
// ^error{The property must be known at compile time and cannot be changed at runtime}
|
||||
}
|
||||
}
|
||||
PopupWindow {
|
||||
close-on-click: root.external;
|
||||
// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead}
|
||||
// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead}
|
||||
// ^^error{The close-on-click property only supports constants at the moment}
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
PopupWindow {
|
||||
close-policy: close-on-click-outside;
|
||||
close-on-click: true;
|
||||
// ^error{close-policy and close-on-click cannot be set at the same time}
|
||||
}
|
||||
|
||||
DeprecatedDerives {
|
||||
close-policy: close-on-click-outside;
|
||||
}
|
||||
Derives {
|
||||
close-on-click: false;
|
||||
// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead}
|
||||
}
|
||||
DeprecatedDerives {
|
||||
close-on-click: true;
|
||||
// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead}
|
||||
}
|
||||
|
||||
DeprecatedDerives {
|
||||
close-on-click: !true;
|
||||
// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead}
|
||||
// ^^error{The close-on-click property only supports constants at the moment}
|
||||
}
|
||||
|
||||
D1{}
|
||||
D2{}
|
||||
D3{}
|
||||
D1{}
|
||||
D2{}
|
||||
D3{ close-on-click: true; }
|
||||
// ^warning{The property 'close-on-click' has been deprecated. Please use 'close-policy' instead}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
548
tests/cases/elements/popupwindow_close_policy_inherited.slint
Normal file
548
tests/cases/elements/popupwindow_close_policy_inherited.slint
Normal file
|
@ -0,0 +1,548 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
|
||||
component DerivesNoClose inherits PopupWindow {
|
||||
close-policy: no-auto-close;
|
||||
}
|
||||
|
||||
component DerivesNoCloseLegacy inherits PopupWindow {
|
||||
close-on-click: false;
|
||||
}
|
||||
|
||||
component DerivesAutoClose inherits DerivesNoClose {
|
||||
close-on-click: true;
|
||||
}
|
||||
|
||||
component DerivesDerivesNoClose inherits DerivesNoClose {
|
||||
}
|
||||
|
||||
|
||||
export component TestCase {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
|
||||
in-out property <bool> popup-created;
|
||||
in-out property <int> click-count;
|
||||
in-out property <int> popup-selector: 0;
|
||||
in-out property <int> popup-clicked;
|
||||
out property <length> last-underneath-mouse-x: ta.mouse-x;
|
||||
out property <length> last-underneath-mouse-y: ta.mouse-y;
|
||||
|
||||
callback do-close;
|
||||
do-close => {
|
||||
close-from-outside.close();
|
||||
}
|
||||
|
||||
default-popup := DerivesAutoClose {
|
||||
x: 10px;
|
||||
y: 10px;
|
||||
width: parent.width - 20px;
|
||||
height: parent.height - 20px;
|
||||
Text {
|
||||
text: "I'm a default";
|
||||
}
|
||||
init => {
|
||||
root.popup-created = true;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
width: 7px; x: 0px;
|
||||
clicked => {
|
||||
popup-clicked += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self-closing-popup := DerivesDerivesNoClose {
|
||||
x: 10px;
|
||||
y: 10px;
|
||||
width: parent.width - 20px;
|
||||
height: parent.height - 20px;
|
||||
Text {
|
||||
text: "I'm a self-closing popup";
|
||||
}
|
||||
TouchArea {
|
||||
clicked => {
|
||||
self-closing-popup.close();
|
||||
}
|
||||
}
|
||||
init => {
|
||||
root.popup-created = true;
|
||||
}
|
||||
}
|
||||
|
||||
close-from-outside := DerivesAutoClose {
|
||||
close-policy: no-auto-close;
|
||||
x: 10px;
|
||||
y: 10px;
|
||||
width: parent.width - 20px;
|
||||
height: parent.height - 20px;
|
||||
Text {
|
||||
text: "I'm a popup that only close from outside";
|
||||
}
|
||||
TouchArea {
|
||||
clicked => {
|
||||
popup-clicked += 1000;
|
||||
}
|
||||
}
|
||||
init => {
|
||||
root.popup-created = true;
|
||||
}
|
||||
}
|
||||
|
||||
close-click-outside := DerivesNoCloseLegacy {
|
||||
x: 10px;
|
||||
y: 10px;
|
||||
width: parent.width - 20px;
|
||||
height: parent.height - 20px;
|
||||
close-policy: close-on-click-outside;
|
||||
Text {
|
||||
text: "I close on outside click";
|
||||
}
|
||||
init => {
|
||||
root.popup-created = true;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
width: 7px; x: 0px;
|
||||
clicked => {
|
||||
popup-clicked += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ta := TouchArea {
|
||||
clicked => {
|
||||
root.click-count = root.click-count + 1;
|
||||
if (root.popup-selector == 0) {
|
||||
root.popup-selector = 4;
|
||||
default-popup.show();
|
||||
} else if (root.popup-selector == 1) {
|
||||
root.popup-selector = 4;
|
||||
self-closing-popup.show();
|
||||
} else if (root.popup-selector == 2) {
|
||||
root.popup-selector = 4;
|
||||
close-from-outside.show();
|
||||
} else if (root.popup-selector == 3) {
|
||||
root.popup-selector = 4;
|
||||
close-click-outside.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
```rust
|
||||
use slint::{platform::WindowEvent, platform::PointerEventButton, LogicalPosition};
|
||||
|
||||
let instance = TestCase::new().unwrap();
|
||||
|
||||
assert_eq!(instance.get_click_count(), 0);
|
||||
assert_eq!(instance.get_popup_created(), false);
|
||||
|
||||
// --------- Default popup
|
||||
instance.set_popup_selector(0);
|
||||
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(), 0);
|
||||
|
||||
// Click to close
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq!(instance.get_click_count(), 1);
|
||||
// Subsequent click to verify that it was closed
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq!(instance.get_click_count(), 2);
|
||||
assert_eq!(instance.get_popup_clicked(), 1);
|
||||
|
||||
// --------- Default popup but verify closed on press when outside
|
||||
instance.set_popup_selector(0);
|
||||
instance.set_popup_created(false);
|
||||
instance.set_click_count(0);
|
||||
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq!(instance.get_last_underneath_mouse_x(), 15.);
|
||||
assert_eq!(instance.get_last_underneath_mouse_y(), 15.);
|
||||
assert_eq!(instance.get_click_count(), 1);
|
||||
assert_eq!(instance.get_popup_created(), true);
|
||||
assert_eq!(instance.get_popup_clicked(), 1);
|
||||
|
||||
// mouse grabbed, underneath won't notice
|
||||
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(1.0, 1.0) });
|
||||
assert_eq!(instance.get_last_underneath_mouse_x(), 15.);
|
||||
assert_eq!(instance.get_last_underneath_mouse_y(), 15.);
|
||||
|
||||
// press should close
|
||||
instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(1.0, 1.0), button: PointerEventButton::Left });
|
||||
|
||||
// if it was closed, the underneath should receive the move event
|
||||
instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(12.0, 12.0) });
|
||||
assert_eq!(instance.get_last_underneath_mouse_x(), 12.);
|
||||
assert_eq!(instance.get_last_underneath_mouse_y(), 12.);
|
||||
|
||||
slint_testing::mock_elapsed_time(50);
|
||||
instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(12.0, 12.0), button: PointerEventButton::Left });
|
||||
|
||||
assert_eq!(instance.get_click_count(), 1);
|
||||
|
||||
// Subsequent click to verify that it was closed
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq!(instance.get_click_count(), 2);
|
||||
assert_eq!(instance.get_popup_clicked(), 1);
|
||||
|
||||
// --------- Popup with close-policy: no-auto-close
|
||||
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);
|
||||
assert_eq!(instance.get_popup_clicked(), 1);
|
||||
|
||||
// Click outside, nothing happens
|
||||
slint_testing::send_mouse_click(&instance, 1., 1.);
|
||||
assert_eq!(instance.get_click_count(), 1);
|
||||
// Click outside again, nothing happens
|
||||
slint_testing::send_mouse_click(&instance, 295., 295.);
|
||||
assert_eq!(instance.get_click_count(), 1);
|
||||
assert_eq!(instance.get_popup_clicked(), 1);
|
||||
|
||||
// Click on the popup, it's registered and the custom TouchArea calls close()
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq!(instance.get_click_count(), 1);
|
||||
|
||||
// Subsequent click to verify that it was closed
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq!(instance.get_click_count(), 2);
|
||||
assert_eq!(instance.get_popup_clicked(), 1);
|
||||
|
||||
// --------- Popup with close-policy: no-auto-close closed externally
|
||||
instance.set_popup_selector(2);
|
||||
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(), 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(), 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(), 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(), 3001);
|
||||
|
||||
// Close manually and verify that subsequent click is passed through
|
||||
instance.invoke_do_close();
|
||||
slint_testing::send_mouse_click(&instance, 5., 5.);
|
||||
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(), 3001);
|
||||
|
||||
|
||||
// --------- 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(), 3001);
|
||||
|
||||
// click inside
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
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(), 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);
|
||||
|
||||
```
|
||||
|
||||
```cpp
|
||||
auto handle = TestCase::create();
|
||||
const TestCase &instance = *handle;
|
||||
|
||||
assert_eq(instance.get_click_count(), 0);
|
||||
assert_eq(instance.get_popup_created(), false);
|
||||
|
||||
// --------- Default popup
|
||||
instance.set_popup_selector(0);
|
||||
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(), 0);
|
||||
|
||||
// Click to close
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq(instance.get_click_count(), 1);
|
||||
// Subsequent click to verify that it was closed
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq(instance.get_click_count(), 2);
|
||||
assert_eq(instance.get_popup_clicked(), 1);
|
||||
|
||||
// --------- Default popup but verify closed on press when outside
|
||||
instance.set_popup_selector(0);
|
||||
instance.set_popup_created(false);
|
||||
instance.set_click_count(0);
|
||||
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq(instance.get_last_underneath_mouse_x(), 15.);
|
||||
assert_eq(instance.get_last_underneath_mouse_y(), 15.);
|
||||
assert_eq(instance.get_click_count(), 1);
|
||||
assert_eq(instance.get_popup_created(), true);
|
||||
assert_eq(instance.get_popup_clicked(), 1);
|
||||
|
||||
// mouse grabbed, underneath won't notice
|
||||
instance.window().dispatch_pointer_move_event(slint::LogicalPosition({1.0, 1.0}));
|
||||
assert_eq(instance.get_last_underneath_mouse_x(), 15.);
|
||||
assert_eq(instance.get_last_underneath_mouse_y(), 15.);
|
||||
|
||||
// press should close
|
||||
instance.window().dispatch_pointer_press_event(slint::LogicalPosition({1.0, 1.0}), slint::PointerEventButton::Left);
|
||||
|
||||
// if it was closed, the underneath should receive the move event
|
||||
instance.window().dispatch_pointer_move_event(slint::LogicalPosition({12.0, 12.0}));
|
||||
assert_eq(instance.get_last_underneath_mouse_x(), 12.);
|
||||
assert_eq(instance.get_last_underneath_mouse_y(), 12.);
|
||||
|
||||
slint_testing::mock_elapsed_time(50);
|
||||
instance.window().dispatch_pointer_release_event(slint::LogicalPosition({12.0, 12.0}), slint::PointerEventButton::Left);
|
||||
|
||||
assert_eq(instance.get_click_count(), 1);
|
||||
|
||||
// Subsequent click to verify that it was closed
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq(instance.get_click_count(), 2);
|
||||
assert_eq(instance.get_popup_clicked(), 1);
|
||||
|
||||
// --------- Popup with close-policy: no-auto-close
|
||||
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);
|
||||
assert_eq(instance.get_popup_clicked(), 1);
|
||||
|
||||
// Click outside, nothing happens
|
||||
slint_testing::send_mouse_click(&instance, 1., 1.);
|
||||
assert_eq(instance.get_click_count(), 1);
|
||||
// Click outside again, nothing happens
|
||||
slint_testing::send_mouse_click(&instance, 295., 295.);
|
||||
assert_eq(instance.get_click_count(), 1);
|
||||
assert_eq(instance.get_popup_clicked(), 1);
|
||||
|
||||
// Click on the popup, it's registered and the custom TouchArea calls close()
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq(instance.get_click_count(), 1);
|
||||
|
||||
// Subsequent click to verify that it was closed
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
assert_eq(instance.get_click_count(), 2);
|
||||
assert_eq(instance.get_popup_clicked(), 1);
|
||||
|
||||
// --------- Popup with close-policy: no-auto-close closed externally
|
||||
instance.set_popup_selector(2);
|
||||
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(), 1);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// Close manually and verify that subsequent click is passed through
|
||||
instance.invoke_do_close();
|
||||
slint_testing::send_mouse_click(&instance, 15., 15.);
|
||||
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);
|
||||
|
||||
|
||||
// --------- 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
|
||||
var instance = new slint.TestCase({});
|
||||
|
||||
assert.equal(instance.click_count, 0);
|
||||
assert.equal(instance.popup_created, false);
|
||||
|
||||
instance.popup_selector = 0;
|
||||
instance.popup_created = false;
|
||||
instance.click_count = 0;
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 1);
|
||||
assert.equal(instance.popup_created, true);
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 1);
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 2);
|
||||
|
||||
instance.popup_selector = 1;
|
||||
instance.popup_created = false;
|
||||
instance.click_count = 0;
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 1);
|
||||
assert.equal(instance.popup_created, true);
|
||||
slintlib.private_api.send_mouse_click(instance, 1., 1.);
|
||||
assert.equal(instance.click_count, 1);
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 1);
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 2);
|
||||
|
||||
instance.popup_selector = 2;
|
||||
instance.popup_created = false;
|
||||
instance.click_count = 0;
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 1);
|
||||
assert.equal(instance.popup_created, true);
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 1);
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 1);
|
||||
|
||||
instance.do_close();
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 2);
|
||||
instance.do_close();
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.click_count, 3);
|
||||
|
||||
|
||||
// --------- Close outside click popup
|
||||
instance.set_popup_selector(3);
|
||||
instance.set_popup_created(false);
|
||||
instance.set_click_count(0);
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.get_click_count(), 1);
|
||||
assert.equal(instance.get_popup_created(), true);
|
||||
assert.equal(instance.get_popup_clicked(), 2001);
|
||||
|
||||
// click inside
|
||||
slintlib.private_api.send_mouse_click(instance, 15., 15.);
|
||||
assert.equal(instance.get_popup_clicked(), 2003);
|
||||
|
||||
// Click outside to close
|
||||
slintlib.private_api.send_mouse_click(instance, 5., 5.);
|
||||
assert.equal(instance.get_click_count(), 1);
|
||||
// Subsequent click to verify that it was closed
|
||||
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);
|
||||
```
|
||||
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue