mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21:16 +00:00
Fix Popup in C++
This commit is contained in:
parent
99e66a6b55
commit
564d6a0744
4 changed files with 68 additions and 20 deletions
|
@ -120,6 +120,13 @@ public:
|
||||||
sixtyfps_component_window_set_component(&inner, &self_rc);
|
sixtyfps_component_window_set_component(&inner, &self_rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Component, typename Parent>
|
||||||
|
void show_popup(const Parent *parent_component, cbindgen_private::Point p) const
|
||||||
|
{
|
||||||
|
auto popup = Component::create(parent_component).into_dyn();
|
||||||
|
cbindgen_private::sixtyfps_component_window_show_popup(&inner, &popup, p);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cbindgen_private::ComponentWindowOpaque inner;
|
cbindgen_private::ComponentWindowOpaque inner;
|
||||||
};
|
};
|
||||||
|
@ -215,6 +222,11 @@ public:
|
||||||
|
|
||||||
const T *operator->() const { return inner.operator->(); }
|
const T *operator->() const { return inner.operator->(); }
|
||||||
const T &operator*() const { return inner.operator*(); }
|
const T &operator*() const { return inner.operator*(); }
|
||||||
|
|
||||||
|
/// internal function that returns the internal handle
|
||||||
|
vtable::VRc<private_api::ComponentVTable> into_dyn() const {
|
||||||
|
return inner.into_dyn();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A weak reference to the component. Can be constructed from a `ComponentHandle<T>`
|
/// A weak reference to the component. Can be constructed from a `ComponentHandle<T>`
|
||||||
|
|
|
@ -326,12 +326,12 @@ Note: it is not allowed to access properties on element within the popup from ou
|
||||||
|
|
||||||
```60
|
```60
|
||||||
Example := Window {
|
Example := Window {
|
||||||
width: 270px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
|
|
||||||
popup := PopupWindow {
|
popup := PopupWindow {
|
||||||
Rectangle { height:100%; width: 100%; color: yellow; }
|
Rectangle { height:100%; width: 100%; color: yellow; }
|
||||||
x: 20px; y: 20px; height: 50px; width: 150px;
|
x: 20px; y: 20px; height: 50px; width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
TouchArea {
|
TouchArea {
|
||||||
|
|
|
@ -640,6 +640,15 @@ fn generate_component(
|
||||||
let component_id = component_id(component);
|
let component_id = component_id(component);
|
||||||
let mut component_struct = Struct { name: component_id.clone(), ..Default::default() };
|
let mut component_struct = Struct { name: component_id.clone(), ..Default::default() };
|
||||||
|
|
||||||
|
for c in component.popup_windows.borrow().iter() {
|
||||||
|
let mut friends = vec![self::component_id(&c.component)];
|
||||||
|
generate_component(file, &c.component, diag, Some(&mut friends));
|
||||||
|
if let Some(sub_components) = sub_components.as_mut() {
|
||||||
|
sub_components.extend_from_slice(friends.as_slice());
|
||||||
|
}
|
||||||
|
component_struct.friends.append(&mut friends);
|
||||||
|
}
|
||||||
|
|
||||||
let is_root = component.parent_element.upgrade().is_none();
|
let is_root = component.parent_element.upgrade().is_none();
|
||||||
let mut init = vec!["[[maybe_unused]] auto self = this;".into()];
|
let mut init = vec!["[[maybe_unused]] auto self = this;".into()];
|
||||||
|
|
||||||
|
@ -747,10 +756,8 @@ fn generate_component(
|
||||||
if !is_root {
|
if !is_root {
|
||||||
let parent_element = component.parent_element.upgrade().unwrap();
|
let parent_element = component.parent_element.upgrade().unwrap();
|
||||||
|
|
||||||
let mut update_statements = vec![];
|
if parent_element.borrow().repeated.as_ref().map_or(false, |r| !r.is_conditional_element) {
|
||||||
let cpp_model_data_type = model_data_type(&parent_element, diag);
|
let cpp_model_data_type = model_data_type(&parent_element, diag);
|
||||||
|
|
||||||
if !parent_element.borrow().repeated.as_ref().map_or(false, |r| r.is_conditional_element) {
|
|
||||||
component_struct.members.push((
|
component_struct.members.push((
|
||||||
Access::Private,
|
Access::Private,
|
||||||
Declaration::Var(Var {
|
Declaration::Var(Var {
|
||||||
|
@ -769,7 +776,29 @@ fn generate_component(
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
|
||||||
update_statements = vec!["index.set(i);".into(), "model_data.set(data);".into()];
|
let update_statements = vec!["index.set(i);".into(), "model_data.set(data);".into()];
|
||||||
|
component_struct.members.push((
|
||||||
|
Access::Public, // Because Repeater accesses it
|
||||||
|
Declaration::Function(Function {
|
||||||
|
name: "update_data".into(),
|
||||||
|
signature: format!(
|
||||||
|
"(int i, const {} &data) const -> void",
|
||||||
|
cpp_model_data_type
|
||||||
|
),
|
||||||
|
statements: Some(update_statements),
|
||||||
|
..Function::default()
|
||||||
|
}),
|
||||||
|
));
|
||||||
|
} else if parent_element.borrow().repeated.is_some() {
|
||||||
|
component_struct.members.push((
|
||||||
|
Access::Public, // Because Repeater accesses it
|
||||||
|
Declaration::Function(Function {
|
||||||
|
name: "update_data".into(),
|
||||||
|
signature: "(int, int) const -> void".into(),
|
||||||
|
statements: Some(vec![]),
|
||||||
|
..Function::default()
|
||||||
|
}),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let parent_component_id = self::component_id(
|
let parent_component_id = self::component_id(
|
||||||
&component
|
&component
|
||||||
|
@ -793,18 +822,6 @@ fn generate_component(
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
component_struct.friends.push(parent_component_id);
|
component_struct.friends.push(parent_component_id);
|
||||||
component_struct.members.push((
|
|
||||||
Access::Public, // Because Repeater accesses it
|
|
||||||
Declaration::Function(Function {
|
|
||||||
name: "update_data".into(),
|
|
||||||
signature: format!(
|
|
||||||
"([[maybe_unused]] int i, [[maybe_unused]] const {} &data) const -> void",
|
|
||||||
cpp_model_data_type
|
|
||||||
),
|
|
||||||
statements: Some(update_statements),
|
|
||||||
..Function::default()
|
|
||||||
}),
|
|
||||||
));
|
|
||||||
|
|
||||||
let p_y = access_member(&component.root_element, "y", component, "this");
|
let p_y = access_member(&component.root_element, "y", component, "this");
|
||||||
let p_height = access_member(&component.root_element, "height", component, "this");
|
let p_height = access_member(&component.root_element, "height", component, "this");
|
||||||
|
@ -829,7 +846,7 @@ fn generate_component(
|
||||||
..Function::default()
|
..Function::default()
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
} else {
|
} else if parent_element.borrow().repeated.is_some() {
|
||||||
let p_x = access_member(&component.root_element, "x", component, "this");
|
let p_x = access_member(&component.root_element, "x", component, "this");
|
||||||
component_struct.members.push((
|
component_struct.members.push((
|
||||||
Access::Public, // Because Repeater accesses it
|
Access::Public, // Because Repeater accesses it
|
||||||
|
@ -1409,6 +1426,24 @@ fn compile_expression(e: &crate::expression_tree::Expression, component: &Rc<Com
|
||||||
panic!("internal error: argument to SetFocusItem must be an element")
|
panic!("internal error: argument to SetFocusItem must be an element")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Expression::BuiltinFunctionReference(BuiltinFunction::ShowPopupWindow) => {
|
||||||
|
if arguments.len() != 1 {
|
||||||
|
panic!("internal error: incorrect argument count to SetFocusItem call");
|
||||||
|
}
|
||||||
|
if let Expression::ElementReference(popup_window) = &arguments[0] {
|
||||||
|
let popup_window = popup_window.upgrade().unwrap();
|
||||||
|
let pop_comp = popup_window.borrow().enclosing_component.upgrade().unwrap();
|
||||||
|
let popup_window_id = component_id(&pop_comp);
|
||||||
|
let parent_component = pop_comp.parent_element.upgrade().unwrap().borrow().enclosing_component.upgrade().unwrap();
|
||||||
|
let popup_list = parent_component.popup_windows.borrow();
|
||||||
|
let popup = popup_list.iter().find(|p| Rc::ptr_eq(&p.component, &pop_comp)).unwrap();
|
||||||
|
let x = access_named_reference(&popup.x, component, "self");
|
||||||
|
let y = access_named_reference(&popup.y, component, "self");
|
||||||
|
format!("self->window.show_popup<{}>(self, {{ {}.get(), {}.get() }} );", popup_window_id, x, y)
|
||||||
|
} else {
|
||||||
|
panic!("internal error: argument to SetFocusItem must be an element")
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let mut args = arguments.iter().map(|e| compile_expression(e, component));
|
let mut args = arguments.iter().map(|e| compile_expression(e, component));
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,7 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> {
|
||||||
"sixtyfps_component_window_free_graphics_resources",
|
"sixtyfps_component_window_free_graphics_resources",
|
||||||
"sixtyfps_component_window_set_focus_item",
|
"sixtyfps_component_window_set_focus_item",
|
||||||
"sixtyfps_component_window_set_component",
|
"sixtyfps_component_window_set_component",
|
||||||
|
"sixtyfps_component_window_show_popup",
|
||||||
"sixtyfps_new_path_elements",
|
"sixtyfps_new_path_elements",
|
||||||
"sixtyfps_new_path_events",
|
"sixtyfps_new_path_events",
|
||||||
]
|
]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue