mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 06:11: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);
|
||||
}
|
||||
|
||||
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:
|
||||
cbindgen_private::ComponentWindowOpaque inner;
|
||||
};
|
||||
|
@ -215,6 +222,11 @@ public:
|
|||
|
||||
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>`
|
||||
|
|
|
@ -326,12 +326,12 @@ Note: it is not allowed to access properties on element within the popup from ou
|
|||
|
||||
```60
|
||||
Example := Window {
|
||||
width: 270px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
|
||||
popup := PopupWindow {
|
||||
Rectangle { height:100%; width: 100%; color: yellow; }
|
||||
x: 20px; y: 20px; height: 50px; width: 150px;
|
||||
x: 20px; y: 20px; height: 50px; width: 50px;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
|
|
|
@ -640,6 +640,15 @@ fn generate_component(
|
|||
let component_id = component_id(component);
|
||||
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 mut init = vec!["[[maybe_unused]] auto self = this;".into()];
|
||||
|
||||
|
@ -747,10 +756,8 @@ fn generate_component(
|
|||
if !is_root {
|
||||
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);
|
||||
|
||||
if !parent_element.borrow().repeated.as_ref().map_or(false, |r| r.is_conditional_element) {
|
||||
component_struct.members.push((
|
||||
Access::Private,
|
||||
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(
|
||||
&component
|
||||
|
@ -793,18 +822,6 @@ fn generate_component(
|
|||
}),
|
||||
));
|
||||
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_height = access_member(&component.root_element, "height", component, "this");
|
||||
|
@ -829,7 +846,7 @@ fn generate_component(
|
|||
..Function::default()
|
||||
}),
|
||||
));
|
||||
} else {
|
||||
} else if parent_element.borrow().repeated.is_some() {
|
||||
let p_x = access_member(&component.root_element, "x", component, "this");
|
||||
component_struct.members.push((
|
||||
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")
|
||||
}
|
||||
}
|
||||
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));
|
||||
|
||||
|
|
|
@ -155,6 +155,7 @@ fn gen_corelib(include_dir: &Path) -> anyhow::Result<()> {
|
|||
"sixtyfps_component_window_free_graphics_resources",
|
||||
"sixtyfps_component_window_set_focus_item",
|
||||
"sixtyfps_component_window_set_component",
|
||||
"sixtyfps_component_window_show_popup",
|
||||
"sixtyfps_new_path_elements",
|
||||
"sixtyfps_new_path_events",
|
||||
]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue