From 81473c25415dd23b78cba9fd43b1e29f7043386c Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 4 May 2021 15:33:04 +0200 Subject: [PATCH] Remove implicit_size from the Item vtable Use the preferred size in the layouting_info instead. --- sixtyfps_compiler/expression_tree.rs | 16 ++----- sixtyfps_compiler/generator/cpp.rs | 12 ++--- sixtyfps_compiler/generator/rust.rs | 10 ++-- sixtyfps_compiler/passes/default_geometry.rs | 12 ++--- sixtyfps_runtime/corelib/items.rs | 47 ------------------- sixtyfps_runtime/corelib/items/image.rs | 12 +---- sixtyfps_runtime/corelib/items/text.rs | 33 +++---------- sixtyfps_runtime/interpreter/eval.rs | 12 +---- .../rendering_backends/qt/widgets.rs | 36 -------------- 9 files changed, 31 insertions(+), 159 deletions(-) diff --git a/sixtyfps_compiler/expression_tree.rs b/sixtyfps_compiler/expression_tree.rs index c6a4629bb..1eb8f0fed 100644 --- a/sixtyfps_compiler/expression_tree.rs +++ b/sixtyfps_compiler/expression_tree.rs @@ -43,7 +43,7 @@ pub enum BuiltinFunction { ColorBrighter, ColorDarker, Rgb, - ImplicitItemSize, + ImplicitLayoutInfo, RegisterCustomFontByPath, RegisterCustomFontByMemory, } @@ -97,18 +97,8 @@ impl BuiltinFunction { BuiltinFunction::StringIsFloat => { Type::Function { return_type: Box::new(Type::Bool), args: vec![Type::String] } } - BuiltinFunction::ImplicitItemSize => Type::Function { - return_type: Box::new(Type::Struct { - fields: [ - ("width".to_string(), Type::LogicalLength), - ("height".to_string(), Type::LogicalLength), - ] - .iter() - .cloned() - .collect(), - name: Some("Size".to_string()), - node: None, - }), + BuiltinFunction::ImplicitLayoutInfo => Type::Function { + return_type: Box::new(crate::layout::layout_info_type()), args: vec![Type::ElementReference], }, BuiltinFunction::ColorBrighter => Type::Function { diff --git a/sixtyfps_compiler/generator/cpp.rs b/sixtyfps_compiler/generator/cpp.rs index f72201060..ad3a80592 100644 --- a/sixtyfps_compiler/generator/cpp.rs +++ b/sixtyfps_compiler/generator/cpp.rs @@ -1434,7 +1434,7 @@ fn compile_expression( "[](const auto &a){ auto e1 = std::end(a); auto e2 = const_cast(e1); auto r = std::strtod(std::begin(a), &e2); return e1 == e2 ? r : 0; }" .into() } - BuiltinFunction::ImplicitItemSize => { + BuiltinFunction::ImplicitLayoutInfo => { unreachable!() } BuiltinFunction::ColorBrighter => { @@ -1570,21 +1570,21 @@ fn compile_expression( panic!("internal error: argument to SetFocusItem must be an element") } } - Expression::BuiltinFunctionReference(BuiltinFunction::ImplicitItemSize) => { + Expression::BuiltinFunctionReference(BuiltinFunction::ImplicitLayoutInfo) => { if arguments.len() != 1 { - panic!("internal error: incorrect argument count to ImplicitItemSize call"); + panic!("internal error: incorrect argument count to ImplicitLayoutInfo call"); } if let Expression::ElementReference(item) = &arguments[0] { let item = item.upgrade().unwrap(); let item = item.borrow(); let native_item = item.base_type.as_native(); - format!("{vt}->implicit_size({{{vt}, const_cast(&self->{id})}}, &window)", + format!("{vt}->layouting_info({{&sixtyfps::private_api::{vt}, const_cast(&self->{id})}}, &window)", vt = native_item.cpp_vtable_getter, ty = native_item.class_name, id = item.id ) } else { - panic!("internal error: argument to ImplicitItemSize must be an element") + panic!("internal error: argument to ImplicitLayoutInfo must be an element") } } Expression::BuiltinFunctionReference(BuiltinFunction::RegisterCustomFontByPath) => { @@ -2474,4 +2474,4 @@ fn return_compile_expression( format!("return {}", e) } } -} +} \ No newline at end of file diff --git a/sixtyfps_compiler/generator/rust.rs b/sixtyfps_compiler/generator/rust.rs index 32e1ce5cd..aa4a69852 100644 --- a/sixtyfps_compiler/generator/rust.rs +++ b/sixtyfps_compiler/generator/rust.rs @@ -1101,7 +1101,7 @@ fn compile_expression(expr: &Expression, component: &Rc) -> TokenStre BuiltinFunction::ASin => quote!((|a| (a as f64).asin().to_degrees())), BuiltinFunction::ACos => quote!((|a| (a as f64).acos().to_degrees())), BuiltinFunction::ATan => quote!((|a| (a as f64).atan().to_degrees())), - BuiltinFunction::SetFocusItem | BuiltinFunction::ShowPopupWindow | BuiltinFunction::ImplicitItemSize => { + BuiltinFunction::SetFocusItem | BuiltinFunction::ShowPopupWindow | BuiltinFunction::ImplicitLayoutInfo => { panic!("internal error: should be handled directly in CallFunction") } BuiltinFunction::StringToFloat => { @@ -1225,19 +1225,19 @@ fn compile_expression(expr: &Expression, component: &Rc) -> TokenStre panic!("internal error: argument to SetFocusItem must be an element") } } - Expression::BuiltinFunctionReference(BuiltinFunction::ImplicitItemSize) => { + Expression::BuiltinFunctionReference(BuiltinFunction::ImplicitLayoutInfo) => { if arguments.len() != 1 { - panic!("internal error: incorrect argument count to ImplicitItemSize call"); + panic!("internal error: incorrect argument count to ImplicitLayoutInfo call"); } if let Expression::ElementReference(item) = &arguments[0] { let item = item.upgrade().unwrap(); let item = item.borrow(); let item_id = format_ident!("{}", item.id); quote!( - Self::FIELD_OFFSETS.#item_id.apply_pin(_self).implicit_size(&_self.window) + Self::FIELD_OFFSETS.#item_id.apply_pin(_self).layouting_info(&_self.window) ) } else { - panic!("internal error: argument to ImplicitItemSize must be an element") + panic!("internal error: argument to ImplicitLayoutInfo must be an element") } } Expression::BuiltinFunctionReference(BuiltinFunction::RegisterCustomFontByPath) => { diff --git a/sixtyfps_compiler/passes/default_geometry.rs b/sixtyfps_compiler/passes/default_geometry.rs index c937db5be..22aa45ba9 100644 --- a/sixtyfps_compiler/passes/default_geometry.rs +++ b/sixtyfps_compiler/passes/default_geometry.rs @@ -159,13 +159,13 @@ fn make_default_implicit(elem: &ElementRc, property: &str) { Expression::StructFieldAccess { base: Expression::FunctionCall { function: Box::new(Expression::BuiltinFunctionReference( - BuiltinFunction::ImplicitItemSize, + BuiltinFunction::ImplicitLayoutInfo, )), arguments: vec![Expression::ElementReference(Rc::downgrade(elem))], source_location: None, } .into(), - name: property.into(), + name: format!("preferred_{}", property), } .into() }); @@ -189,7 +189,7 @@ fn make_default_aspect_ratio_preserving_binding( let implicit_size_var = Box::new(Expression::ReadLocalVariable { name: "image_implicit_size".into(), - ty: match BuiltinFunction::ImplicitItemSize.ty() { + ty: match BuiltinFunction::ImplicitLayoutInfo.ty() { Type::Function { return_type, .. } => *return_type, _ => panic!("invalid type for ImplicitItemSize built-in function"), }, @@ -200,7 +200,7 @@ fn make_default_aspect_ratio_preserving_binding( name: "image_implicit_size".into(), value: Box::new(Expression::FunctionCall { function: Box::new(Expression::BuiltinFunctionReference( - BuiltinFunction::ImplicitItemSize, + BuiltinFunction::ImplicitLayoutInfo, )), arguments: vec![Expression::ElementReference(Rc::downgrade(elem))], source_location: None, @@ -215,13 +215,13 @@ fn make_default_aspect_ratio_preserving_binding( .into(), rhs: Box::new(Expression::StructFieldAccess { base: implicit_size_var.clone(), - name: missing_size_property.to_string(), + name: format!("preferred_{}", missing_size_property), }), op: '*', }), rhs: Box::new(Expression::StructFieldAccess { base: implicit_size_var, - name: given_size_property.to_string(), + name: format!("preferred_{}", given_size_property), }), op: '/', }, diff --git a/sixtyfps_runtime/corelib/items.rs b/sixtyfps_runtime/corelib/items.rs index 5ed7089ec..ec8649089 100644 --- a/sixtyfps_runtime/corelib/items.rs +++ b/sixtyfps_runtime/corelib/items.rs @@ -95,9 +95,6 @@ pub struct ItemVTable { pub layouting_info: extern "C" fn(core::pin::Pin>, window: &ComponentWindow) -> LayoutInfo, - pub implicit_size: - extern "C" fn(core::pin::Pin>, window: &ComponentWindow) -> Size, - /// Event handler for mouse and touch event. This function is called before being called on children. /// Then, depending on the return value, it is called for the children, and their children, then /// [`Self::input_event`] is called on the children, and finaly [`Self::input_event`] is called @@ -214,10 +211,6 @@ impl Item for Rectangle { LayoutInfo { horizontal_stretch: 1., vertical_stretch: 1., ..LayoutInfo::default() } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -285,10 +278,6 @@ impl Item for BorderRectangle { LayoutInfo { horizontal_stretch: 1., vertical_stretch: 1., ..LayoutInfo::default() } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -374,10 +363,6 @@ impl Item for TouchArea { LayoutInfo::default() } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, event: MouseEvent, @@ -492,10 +477,6 @@ impl Item for FocusScope { LayoutInfo::default() } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -587,10 +568,6 @@ impl Item for Clip { LayoutInfo { horizontal_stretch: 1., vertical_stretch: 1., ..LayoutInfo::default() } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -659,10 +636,6 @@ impl Item for Opacity { LayoutInfo { horizontal_stretch: 1., vertical_stretch: 1., ..LayoutInfo::default() } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -727,10 +700,6 @@ impl Item for Rotate { LayoutInfo { horizontal_stretch: 1., vertical_stretch: 1., ..LayoutInfo::default() } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -815,10 +784,6 @@ impl Item for Path { LayoutInfo::default() } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -901,10 +866,6 @@ impl Item for Flickable { LayoutInfo { horizontal_stretch: 1., vertical_stretch: 1., ..LayoutInfo::default() } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, event: MouseEvent, @@ -1025,10 +986,6 @@ impl Item for Window { LayoutInfo::default() } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -1128,10 +1085,6 @@ impl Item for BoxShadow { LayoutInfo { horizontal_stretch: 1., vertical_stretch: 1., ..LayoutInfo::default() } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, diff --git a/sixtyfps_runtime/corelib/items/image.rs b/sixtyfps_runtime/corelib/items/image.rs index c1aea4f7f..43acaeb92 100644 --- a/sixtyfps_runtime/corelib/items/image.rs +++ b/sixtyfps_runtime/corelib/items/image.rs @@ -72,7 +72,7 @@ impl Item for Image { } fn layouting_info(self: Pin<&Self>, window: &ComponentWindow) -> LayoutInfo { - let natural_size = self.implicit_size(window); + let natural_size = window.0.image_size(Self::FIELD_OFFSETS.source.apply_pin(self)); LayoutInfo { preferred_width: natural_size.width, preferred_height: natural_size.height, @@ -80,10 +80,6 @@ impl Item for Image { } } - fn implicit_size(self: Pin<&Self>, window: &ComponentWindow) -> Size { - window.0.image_size(Self::FIELD_OFFSETS.source.apply_pin(self)) - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -147,7 +143,7 @@ impl Item for ClippedImage { } fn layouting_info(self: Pin<&Self>, window: &ComponentWindow) -> LayoutInfo { - let natural_size = self.implicit_size(window); + let natural_size = window.0.image_size(Self::FIELD_OFFSETS.source.apply_pin(self)); LayoutInfo { preferred_width: natural_size.width, preferred_height: natural_size.height, @@ -155,10 +151,6 @@ impl Item for ClippedImage { } } - fn implicit_size(self: Pin<&Self>, window: &ComponentWindow) -> Size { - window.0.image_size(Self::FIELD_OFFSETS.source.apply_pin(self)) - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, diff --git a/sixtyfps_runtime/corelib/items/text.rs b/sixtyfps_runtime/corelib/items/text.rs index 6c994638e..d2bf6943c 100644 --- a/sixtyfps_runtime/corelib/items/text.rs +++ b/sixtyfps_runtime/corelib/items/text.rs @@ -133,7 +133,8 @@ impl Item for Text { &|| self.unresolved_font_request(), Self::FIELD_OFFSETS.text.apply_pin(self), ) { - let mut min_size = font_metrics.text_size(&self.text()); + let implicit_size = font_metrics.text_size(&self.text()); + let mut min_size = implicit_size; match self.overflow() { TextOverflow::elide => { min_size.width = font_metrics.text_size("…").width; @@ -146,6 +147,8 @@ impl Item for Text { LayoutInfo { min_width: min_size.width.ceil(), min_height: min_size.height.ceil(), + preferred_width: implicit_size.width.ceil(), + preferred_height: implicit_size.height.ceil(), ..LayoutInfo::default() } } else { @@ -153,18 +156,6 @@ impl Item for Text { } } - fn implicit_size(self: Pin<&Self>, window: &ComponentWindow) -> Size { - window - .0 - .font_metrics( - &self.cached_rendering_data, - &|| self.unresolved_font_request(), - Self::FIELD_OFFSETS.text.apply_pin(self), - ) - .map(|metrics| metrics.text_size(&self.text()).ceil()) - .unwrap_or_default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -276,11 +267,13 @@ impl Item for TextInput { &|| self.unresolved_font_request(), Self::FIELD_OFFSETS.text.apply_pin(self), ) { - let size = font_metrics.text_size("********************"); + let size = font_metrics.text_size("********************").ceil(); LayoutInfo { min_width: size.width, min_height: size.height, + preferred_width: size.width, + preferred_height: size.height, horizontal_stretch: 1., ..LayoutInfo::default() } @@ -289,18 +282,6 @@ impl Item for TextInput { } } - fn implicit_size(self: Pin<&Self>, window: &ComponentWindow) -> Size { - window - .0 - .font_metrics( - &self.cached_rendering_data, - &|| self.unresolved_font_request(), - Self::FIELD_OFFSETS.text.apply_pin(self), - ) - .map(|metrics| metrics.text_size(&self.text()).ceil()) - .unwrap_or_default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, diff --git a/sixtyfps_runtime/interpreter/eval.rs b/sixtyfps_runtime/interpreter/eval.rs index fd6551e6b..25f9f7c57 100644 --- a/sixtyfps_runtime/interpreter/eval.rs +++ b/sixtyfps_runtime/interpreter/eval.rs @@ -389,7 +389,7 @@ pub fn eval_expression(e: &Expression, local_context: &mut EvalLocalContext) -> let a: u8 = (255. * a).max(0.).min(255.) as u8; Value::Brush(Brush::SolidColor(Color::from_argb_u8(a, r, g, b))) } - Expression::BuiltinFunctionReference(BuiltinFunction::ImplicitItemSize) => { + Expression::BuiltinFunctionReference(BuiltinFunction::ImplicitLayoutInfo) => { if arguments.len() != 1 { panic!("internal error: incorrect argument count to ImplicitItemSize") } @@ -408,15 +408,7 @@ pub fn eval_expression(e: &Expression, local_context: &mut EvalLocalContext) -> let item_ref = unsafe { item_info.item_from_component(enclosing_component.as_ptr()) }; let window = window_ref(component).unwrap(); - - let size = item_ref.as_ref().implicit_size(&window); - let values = [ - ("width".to_string(), Value::Number(size.width as f64)), - ("height".to_string(), Value::Number(size.height as f64)), - ] - .iter() - .map(|(name, value)| (name.clone(), value.clone())).collect(); - Value::Struct(values) + item_ref.as_ref().layouting_info(&window).into() } else { panic!("internal error: argument to ImplicitItemWidth must be an element") } diff --git a/sixtyfps_runtime/rendering_backends/qt/widgets.rs b/sixtyfps_runtime/rendering_backends/qt/widgets.rs index 2997d4c16..4630952a0 100644 --- a/sixtyfps_runtime/rendering_backends/qt/widgets.rs +++ b/sixtyfps_runtime/rendering_backends/qt/widgets.rs @@ -190,10 +190,6 @@ impl Item for NativeButton { } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -320,10 +316,6 @@ impl Item for NativeCheckBox { } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -478,10 +470,6 @@ impl Item for NativeSpinBox { } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -692,10 +680,6 @@ impl Item for NativeSlider { } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -946,10 +930,6 @@ impl Item for NativeGroupBox { } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -1095,10 +1075,6 @@ impl Item for NativeLineEdit { } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -1254,10 +1230,6 @@ impl Item for NativeScrollView { } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -1581,10 +1553,6 @@ impl Item for NativeStandardListViewItem { result } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent, @@ -1694,10 +1662,6 @@ impl Item for NativeComboBox { } } - fn implicit_size(self: Pin<&Self>, _window: &ComponentWindow) -> Size { - Default::default() - } - fn input_event_filter_before_children( self: Pin<&Self>, _: MouseEvent,