mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21:16 +00:00
Fix calls to BuiltinFunction::ImplicitLayoutInfo for sub-components in C++
Provide a layout_info implementation for sub-components and call it. This disables the lowering the implicit_layout_info call again, also to ensure that when this is installed from the use-site of the sub-component, the self can be used to obtain the info (by calling the new generated function).
This commit is contained in:
parent
08c49a5ff4
commit
ae25dd3d07
3 changed files with 85 additions and 29 deletions
|
@ -751,8 +751,7 @@ fn generate_component(
|
||||||
let mut component_struct = Struct { name: component_id.clone(), ..Default::default() };
|
let mut component_struct = Struct { name: component_id.clone(), ..Default::default() };
|
||||||
|
|
||||||
let is_child_component = component.parent_element.upgrade().is_some();
|
let is_child_component = component.parent_element.upgrade().is_some();
|
||||||
let is_sub_component =
|
let is_sub_component = component.is_sub_component();
|
||||||
!component.is_root_component.get() && !is_child_component && !component.is_global();
|
|
||||||
|
|
||||||
for c in component.popup_windows.borrow().iter() {
|
for c in component.popup_windows.borrow().iter() {
|
||||||
let mut friends = vec![self::component_id(&c.component)];
|
let mut friends = vec![self::component_id(&c.component)];
|
||||||
|
@ -1339,6 +1338,22 @@ fn generate_component(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
component_struct.members.push((
|
||||||
|
Access::Public,
|
||||||
|
Declaration::Function(Function {
|
||||||
|
name: "layout_info".into(),
|
||||||
|
signature:
|
||||||
|
"(sixtyfps::Orientation o, sixtyfps::private_api::WindowRc *window_handle) -> sixtyfps::LayoutInfo"
|
||||||
|
.into(),
|
||||||
|
statements: Some(layout_info_function_body(
|
||||||
|
&component,
|
||||||
|
"auto self = this;".to_owned(),
|
||||||
|
Some("window_handle"),
|
||||||
|
)),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let used_types = component.used_types.borrow();
|
let used_types = component.used_types.borrow();
|
||||||
|
@ -1497,13 +1512,10 @@ fn generate_component_vtable(
|
||||||
"([[maybe_unused]] sixtyfps::private_api::ComponentRef component, sixtyfps::Orientation o) -> sixtyfps::LayoutInfo"
|
"([[maybe_unused]] sixtyfps::private_api::ComponentRef component, sixtyfps::Orientation o) -> sixtyfps::LayoutInfo"
|
||||||
.into(),
|
.into(),
|
||||||
is_static: true,
|
is_static: true,
|
||||||
statements: Some(vec![
|
statements: Some(layout_info_function_body(&component, format!(
|
||||||
format!("[[maybe_unused]] auto self = reinterpret_cast<const {}*>(component.instance);", component_id),
|
"[[maybe_unused]] auto self = reinterpret_cast<const {}*>(component.instance);",
|
||||||
format!("if (o == sixtyfps::Orientation::Horizontal) return {};",
|
component_id
|
||||||
get_layout_info(&component.root_element, component, &component.root_constraints.borrow(), Orientation::Horizontal)),
|
), None)),
|
||||||
format!("else return {};",
|
|
||||||
get_layout_info(&component.root_element, component, &component.root_constraints.borrow(), Orientation::Vertical))
|
|
||||||
]),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
@ -1896,6 +1908,12 @@ fn compile_expression(
|
||||||
if let Expression::ElementReference(item) = &arguments[0] {
|
if let Expression::ElementReference(item) = &arguments[0] {
|
||||||
let item = item.upgrade().unwrap();
|
let item = item.upgrade().unwrap();
|
||||||
let item = item.borrow();
|
let item = item.borrow();
|
||||||
|
if item.sub_component().is_some() {
|
||||||
|
format!("self->{compo}.layout_info({o}, &m_window.window_handle())",
|
||||||
|
compo = ident(&item.id),
|
||||||
|
o = to_cpp_orientation(*orientation)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
let native_item = item.base_type.as_native();
|
let native_item = item.base_type.as_native();
|
||||||
format!("{vt}->layouting_info({{{vt}, const_cast<sixtyfps::cbindgen_private::{ty}*>(&self->{id})}}, {o}, &m_window.window_handle())",
|
format!("{vt}->layouting_info({{{vt}, const_cast<sixtyfps::cbindgen_private::{ty}*>(&self->{id})}}, {o}, &m_window.window_handle())",
|
||||||
vt = native_item.cpp_vtable_getter,
|
vt = native_item.cpp_vtable_getter,
|
||||||
|
@ -1903,6 +1921,7 @@ fn compile_expression(
|
||||||
id = ident(&item.id),
|
id = ident(&item.id),
|
||||||
o = to_cpp_orientation(*orientation),
|
o = to_cpp_orientation(*orientation),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("internal error: argument to ImplicitLayoutInfo must be an element")
|
panic!("internal error: argument to ImplicitLayoutInfo must be an element")
|
||||||
}
|
}
|
||||||
|
@ -2252,7 +2271,7 @@ fn grid_layout_cell_data(
|
||||||
"sixtyfps::GridLayoutCellData {{ {}, {}, {} }}",
|
"sixtyfps::GridLayoutCellData {{ {}, {}, {} }}",
|
||||||
col_or_row,
|
col_or_row,
|
||||||
span,
|
span,
|
||||||
get_layout_info(&c.item.element, component, &c.item.constraints, orientation),
|
get_layout_info(&c.item.element, component, &c.item.constraints, orientation, None),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.join(", ")
|
.join(", ")
|
||||||
|
@ -2279,7 +2298,7 @@ fn box_layout_data(
|
||||||
let mut cells = layout.elems.iter().map(|li| {
|
let mut cells = layout.elems.iter().map(|li| {
|
||||||
format!(
|
format!(
|
||||||
"sixtyfps::BoxLayoutCellData{{ {} }}",
|
"sixtyfps::BoxLayoutCellData{{ {} }}",
|
||||||
get_layout_info(&li.element, component, &li.constraints, orientation)
|
get_layout_info(&li.element, component, &li.constraints, orientation, None)
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
if let Some((ri, _)) = &mut repeated_indices {
|
if let Some((ri, _)) = &mut repeated_indices {
|
||||||
|
@ -2320,7 +2339,7 @@ fn box_layout_data(
|
||||||
} else {
|
} else {
|
||||||
push_code += &format!(
|
push_code += &format!(
|
||||||
"cells.push_back({{ {} }});",
|
"cells.push_back({{ {} }});",
|
||||||
get_layout_info(&item.element, component, &item.constraints, orientation)
|
get_layout_info(&item.element, component, &item.constraints, orientation, None)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2362,24 +2381,32 @@ fn get_layout_info(
|
||||||
component: &Rc<Component>,
|
component: &Rc<Component>,
|
||||||
constraints: &crate::layout::LayoutConstraints,
|
constraints: &crate::layout::LayoutConstraints,
|
||||||
orientation: Orientation,
|
orientation: Orientation,
|
||||||
|
custom_window_handle_accessor: Option<&'_ str>,
|
||||||
) -> String {
|
) -> String {
|
||||||
|
let window_handle = if let Some(custom_accessor) = custom_window_handle_accessor {
|
||||||
|
custom_accessor
|
||||||
|
} else {
|
||||||
|
"&self->m_window.window_handle()"
|
||||||
|
};
|
||||||
let mut layout_info = if let Some(layout_info_prop) =
|
let mut layout_info = if let Some(layout_info_prop) =
|
||||||
&elem.borrow().layout_info_prop(orientation)
|
&elem.borrow().layout_info_prop(orientation)
|
||||||
{
|
{
|
||||||
format!("{}.get()", access_named_reference(layout_info_prop, component, "self"))
|
format!("{}.get()", access_named_reference(layout_info_prop, component, "self"))
|
||||||
} else if let Type::Component(_sub_component) = &elem.borrow().base_type {
|
} else if elem.borrow().sub_component().is_some() {
|
||||||
format!(
|
format!(
|
||||||
"self->{id}.layouting_info({o}, &self->m_window.window_handle())",
|
"self->{id}.layout_info({o}, {window_handle})",
|
||||||
id = ident(&elem.borrow().id),
|
id = ident(&elem.borrow().id),
|
||||||
o = to_cpp_orientation(orientation),
|
o = to_cpp_orientation(orientation),
|
||||||
|
window_handle = window_handle
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"{vt}->layouting_info({{{vt}, const_cast<sixtyfps::cbindgen_private::{ty}*>(&self->{id})}}, {o}, &self->m_window.window_handle())",
|
"{vt}->layouting_info({{{vt}, const_cast<sixtyfps::cbindgen_private::{ty}*>(&self->{id})}}, {o}, {window_handle})",
|
||||||
vt = elem.borrow().base_type.as_native().cpp_vtable_getter,
|
vt = elem.borrow().base_type.as_native().cpp_vtable_getter,
|
||||||
ty = elem.borrow().base_type.as_native().class_name,
|
ty = elem.borrow().base_type.as_native().class_name,
|
||||||
id = ident(&elem.borrow().id),
|
id = ident(&elem.borrow().id),
|
||||||
o = to_cpp_orientation(orientation),
|
o = to_cpp_orientation(orientation),
|
||||||
|
window_handle = window_handle
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2397,6 +2424,36 @@ fn get_layout_info(
|
||||||
layout_info
|
layout_info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn layout_info_function_body(
|
||||||
|
component: &Rc<Component>,
|
||||||
|
self_accessor: String,
|
||||||
|
custom_window_accessor: Option<&'_ str>,
|
||||||
|
) -> Vec<String> {
|
||||||
|
vec![
|
||||||
|
self_accessor,
|
||||||
|
format!(
|
||||||
|
"if (o == sixtyfps::Orientation::Horizontal) return {};",
|
||||||
|
get_layout_info(
|
||||||
|
&component.root_element,
|
||||||
|
component,
|
||||||
|
&component.root_constraints.borrow(),
|
||||||
|
Orientation::Horizontal,
|
||||||
|
custom_window_accessor
|
||||||
|
)
|
||||||
|
),
|
||||||
|
format!(
|
||||||
|
"else return {};",
|
||||||
|
get_layout_info(
|
||||||
|
&component.root_element,
|
||||||
|
component,
|
||||||
|
&component.root_constraints.borrow(),
|
||||||
|
Orientation::Vertical,
|
||||||
|
custom_window_accessor
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
fn compile_path(path: &crate::expression_tree::Path, component: &Rc<Component>) -> String {
|
fn compile_path(path: &crate::expression_tree::Path, component: &Rc<Component>) -> String {
|
||||||
match path {
|
match path {
|
||||||
crate::expression_tree::Path::Elements(elements) => {
|
crate::expression_tree::Path::Elements(elements) => {
|
||||||
|
|
|
@ -482,13 +482,6 @@ pub fn layout_info_type() -> Type {
|
||||||
/// Get the implicit layout info of a particular element
|
/// Get the implicit layout info of a particular element
|
||||||
pub fn implicit_layout_info_call(elem: &ElementRc, orientation: Orientation) -> Expression {
|
pub fn implicit_layout_info_call(elem: &ElementRc, orientation: Orientation) -> Expression {
|
||||||
match &elem.borrow().base_type {
|
match &elem.borrow().base_type {
|
||||||
Type::Component(base_comp) => match &base_comp.root_element.borrow().layout_info_prop {
|
|
||||||
Some((hor, vert)) => Expression::PropertyReference(match orientation {
|
|
||||||
Orientation::Horizontal => hor.clone(),
|
|
||||||
Orientation::Vertical => vert.clone(),
|
|
||||||
}),
|
|
||||||
None => implicit_layout_info_call(&base_comp.root_element, orientation),
|
|
||||||
},
|
|
||||||
Type::Builtin(base_type) if base_type.name == "Rectangle" => {
|
Type::Builtin(base_type) if base_type.name == "Rectangle" => {
|
||||||
// hard-code the value for rectangle because many rectangle end up optimized away and we
|
// hard-code the value for rectangle because many rectangle end up optimized away and we
|
||||||
// don't want to depend on the element.
|
// don't want to depend on the element.
|
||||||
|
|
|
@ -293,6 +293,12 @@ impl Component {
|
||||||
.map(|name| name.original_name())
|
.map(|name| name.original_name())
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_sub_component(&self) -> bool {
|
||||||
|
!self.is_root_component.get()
|
||||||
|
&& self.parent_element.upgrade().is_none()
|
||||||
|
&& !self.is_global()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue