Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,7 @@ export component WidgetLoader {
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
scale-x: scaler;
scale-y: scaler;
transform-scale: scaler;
}

if root.type == WidgetType.powerInfo: PowerInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,7 @@ export component WidgetLoaderSoftwareRenderer {
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
scale-x: scaler;
scale-y: scaler;
transform-scale: scaler;
}

if root.type == WidgetType.powerInfo && root.is-visible: PowerInfo {
Expand Down
19 changes: 15 additions & 4 deletions docs/astro/src/content/docs/reference/common.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,21 @@ The y component of the origin to rotate and scale around.

In the future this will be deprecated in favour of a transform-origin property.
</SlintProperty>
#### scale-x
<SlintProperty propName="scale-x" typeName="percent" defaultValue='100%'/>
#### scale-y
<SlintProperty propName="scale-y" typeName="percent" defaultValue='100%'/>

#### transform-scale
<SlintProperty propName="transform-scale" typeName="float" defaultValue='100%'>
The scale factor to apply to the element and all its children.

This doesn't affect the geometry (width, height) of the element, but affects the rendering.
The scale is done around the `rotation-origin` point.

It is also possible to use the `transform-scale-x` and `transform-scale-y` properties to specify the scale factors for the x and y axis.
</SlintProperty>

#### transform-scale-x
<SlintProperty propName="transform-scale-x" typeName="float" defaultValue='self.scale'/>
#### transform-scale-y
<SlintProperty propName="transform-scale-y" typeName="float" defaultValue='self.scale'/>

### opacity
<CodeSnippetMD imagePath="/src/assets/generated/rectangle-opacity.png" scale="3" imageWidth="100" imageHeight="310" imageAlt='rectangle opacity'>
Expand Down
10 changes: 4 additions & 6 deletions examples/fancy-switches/DarkModeSwitch.slint
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,13 @@ export component DarkModeSwitch {
frameBacker.background: #2A2A2A;
moon.rotation-angle: -20deg;
sun.color: #fc7a10;
sun.scale-x: 0.8;
sun.scale-y: 0.8;
sun.transform-scale: 0.8;
in {
animate thumb.x, thumb.background, frameBacker.background, sun.color {
duration: 200ms;
easing: ease-out-sine;
}
animate moon.rotation-angle, sun.scale-x, sun.scale-y {
animate moon.rotation-angle, sun.transform-scale {
duration: 1200ms;
easing: ease-out-elastic;
}
Expand All @@ -143,14 +142,13 @@ export component DarkModeSwitch {
frameBacker.background: transparent;
moon.rotation-angle: 20deg;
sun.color: #2A2A2A;
sun.scale-x: 1;
sun.scale-y: 1;
sun.transform-scale: 1;
in {
animate thumb.x, thumb.background, frameBacker.background, moon.rotation-angle {
duration: 200ms;
easing: ease-out-sine;
}
animate sun.scale-x, sun.scale-y {
animate sun.transform-scale {
duration: 1200ms;
easing: ease-out-elastic;
}
Expand Down
4 changes: 2 additions & 2 deletions internal/compiler/builtins.slint
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ export component ComponentContainer inherits Empty {

export component Transform inherits Empty {
in property <angle> rotation-angle;
in property <percent> scale-x;
in property <percent> scale-y;
in property <percent> transform-scale-x;
in property <percent> transform-scale-y;
in property <length> rotation-origin-x;
in property <length> rotation-origin-y;
//-default_size_binding:expands_to_parent_geometry
Expand Down
25 changes: 1 addition & 24 deletions internal/compiler/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ mod visible;
mod z_order;

use crate::expression_tree::Expression;
use crate::namedreference::NamedReference;
use smol_str::SmolStr;

pub fn ignore_debug_hooks(expr: &Expression) -> &Expression {
Expand Down Expand Up @@ -166,30 +165,8 @@ pub async fn run_passes(
);
visible::handle_visible(component, &global_type_registry.borrow(), diag);
lower_shadows::lower_shadow_properties(component, &doc.local_registry, diag);
lower_property_to_element::lower_property_to_element(
lower_property_to_element::lower_transform_properties(
component,
crate::typeregister::RESERVED_TRANSFORM_PROPERTIES[..3]
.iter()
.map(|(prop_name, _)| *prop_name),
crate::typeregister::RESERVED_TRANSFORM_PROPERTIES[3..]
.iter()
.map(|(prop_name, _)| *prop_name),
Some(&|e, prop| {
let prop_div_2 = |prop: &str| Expression::BinaryExpression {
lhs: Expression::PropertyReference(NamedReference::new(e, prop.into())).into(),
op: '/',
rhs: Expression::NumberLiteral(2., Default::default()).into(),
};

match prop {
"rotation-origin-x" => prop_div_2("width"),
"rotation-origin-y" => prop_div_2("height"),
"scale-x" | "scale-y" => Expression::NumberLiteral(1., Default::default()),
"rotation-angle" => Expression::NumberLiteral(0., Default::default()),
_ => unreachable!(),
}
}),
&SmolStr::new_static("Transform"),
&global_type_registry.borrow(),
diag,
);
Expand Down
55 changes: 52 additions & 3 deletions internal/compiler/passes/lower_property_to_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub(crate) fn lower_property_to_element(
component: &Rc<Component>,
property_names: impl Iterator<Item = &'static str> + Clone,
extra_properties: impl Iterator<Item = &'static str> + Clone,
default_value_for_extra_properties: Option<&dyn Fn(&ElementRc, &str) -> Expression>,
default_value_for_extra_properties: Option<&dyn Fn(&ElementRc, &str) -> Option<Expression>>,
element_name: &SmolStr,
type_register: &TypeRegister,
diag: &mut BuildDiagnostics,
Expand Down Expand Up @@ -95,7 +95,7 @@ pub(crate) fn lower_property_to_element(
fn create_property_element(
child: &ElementRc,
properties: impl Iterator<Item = &'static str>,
default_value_for_extra_properties: Option<&dyn Fn(&ElementRc, &str) -> Expression>,
default_value_for_extra_properties: Option<&dyn Fn(&ElementRc, &str) -> Option<Expression>>,
element_name: &SmolStr,
type_register: &TypeRegister,
) -> ElementRc {
Expand All @@ -105,7 +105,9 @@ fn create_property_element(
BindingExpression::new_two_way(NamedReference::new(child, property_name.into()));
if let Some(default_value_for_extra_properties) = default_value_for_extra_properties {
if !child.borrow().bindings.contains_key(property_name) {
bind.expression = default_value_for_extra_properties(child, property_name)
if let Some(e) = default_value_for_extra_properties(child, property_name) {
bind.expression = e;
}
}
}
(property_name.into(), bind.into())
Expand All @@ -121,3 +123,50 @@ fn create_property_element(
};
element.make_rc()
}

/// Wrapper around lower_property_to_element for the Transform element
pub fn lower_transform_properties(
component: &Rc<Component>,
tr: &TypeRegister,
diag: &mut BuildDiagnostics,
) {
lower_property_to_element(
component,
crate::typeregister::RESERVED_TRANSFORM_PROPERTIES[..4]
.iter()
.map(|(prop_name, _)| *prop_name),
crate::typeregister::RESERVED_TRANSFORM_PROPERTIES[4..]
.iter()
.map(|(prop_name, _)| *prop_name),
Some(&|e, prop| {
let prop_div_2 = |prop: &str| {
Some(Expression::BinaryExpression {
lhs: Expression::PropertyReference(NamedReference::new(e, prop.into())).into(),
op: '/',
rhs: Expression::NumberLiteral(2., Default::default()).into(),
})
};

match prop {
"rotation-origin-x" => prop_div_2("width"),
"rotation-origin-y" => prop_div_2("height"),
"transform-scale-x" | "transform-scale-y" => {
if e.borrow().is_binding_set("transform-scale", true) {
Some(Expression::PropertyReference(NamedReference::new(
e,
SmolStr::new_static("transform-scale"),
)))
} else {
Some(Expression::NumberLiteral(1., Default::default()))
}
}
"transform-scale" => None,
"rotation-angle" => Some(Expression::NumberLiteral(0., Default::default())),
_ => unreachable!(),
}
}),
&SmolStr::new_static("Transform"),
tr,
diag,
);
}
5 changes: 3 additions & 2 deletions internal/compiler/typeregister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,9 @@ pub const RESERVED_DROP_SHADOW_PROPERTIES: &[(&str, Type)] = &[

pub const RESERVED_TRANSFORM_PROPERTIES: &[(&str, Type)] = &[
("rotation-angle", Type::Angle),
("scale-x", Type::Float32),
("scale-y", Type::Float32),
("transform-scale-x", Type::Float32),
("transform-scale-y", Type::Float32),
("transform-scale", Type::Float32),
("rotation-origin-x", Type::LogicalLength),
("rotation-origin-y", Type::LogicalLength),
];
Expand Down
4 changes: 2 additions & 2 deletions internal/core/item_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -825,8 +825,8 @@ impl ItemRc {
ItemTransform::translation(-origin.x, -origin.y)
.cast()
.then_scale(
transform_item.as_pin_ref().scale_x(),
transform_item.as_pin_ref().scale_y(),
transform_item.as_pin_ref().transform_scale_x(),
transform_item.as_pin_ref().transform_scale_y(),
)
.then_rotate(euclid::Angle {
radians: transform_item.as_pin_ref().rotation_angle().to_radians(),
Expand Down
6 changes: 3 additions & 3 deletions internal/core/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,8 +1027,8 @@ declare_item_vtable! {
/// The implementation of the `Rotate` element
pub struct Transform {
pub rotation_angle: Property<f32>,
pub scale_x: Property<f32>,
pub scale_y: Property<f32>,
pub transform_scale_x: Property<f32>,
pub transform_scale_y: Property<f32>,
pub rotation_origin_x: Property<LogicalLength>,
pub rotation_origin_y: Property<LogicalLength>,
pub cached_rendering_data: CachedRenderingData,
Expand Down Expand Up @@ -1100,7 +1100,7 @@ impl Item for Transform {
let origin =
LogicalVector::from_lengths(self.rotation_origin_x(), self.rotation_origin_y());
(*backend).translate(origin);
(*backend).scale(self.scale_x(), self.scale_y());
(*backend).scale(self.transform_scale_x(), self.transform_scale_y());
(*backend).rotate(self.rotation_angle());
(*backend).translate(-origin);
RenderingResult::ContinueRenderingChildren
Expand Down
4 changes: 2 additions & 2 deletions tests/cases/elements/event_scaling.slint
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export component TestCase {
y: 0px;
width: 50px;
height: 50px;
scale-x: 200%;
scale-y: 400%;
transform-scale-x: 200%;
transform-scale-y: 400%;
rotation-origin-x: 0px;
rotation-origin-y: 0px;
area1 := TouchArea {
Expand Down
64 changes: 64 additions & 0 deletions tests/cases/elements/scaling2.slint
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright © SixtyFPS GmbH <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0

export component TestCase {
width: 800px;
height: 600px;

in-out property <string> result;

r-a := Rectangle {
x: 10px;
y: 10px;
width: 20px;
height: 20px;
rotation-origin-x: 0;
rotation-origin-y: 0;
transform-scale: 2;
TouchArea {
clicked => { result += "A"}
}
}


r-b := Rectangle {
x: 100px;
y: 100px;
width: 20px;
height: 20px;
transform-scale: 3;
transform-scale-x: 0.5;
TouchArea {
clicked => { result += "B"}
}
}

out property <bool> test:
r-a.transform-scale == 2 && r-a.transform-scale-x == 2 && r-a.transform-scale-y == 2 &&
r-b.transform-scale-x == 0.5 && r-b.transform-scale-y == 3;


}

/*
```rust
let instance = TestCase::new().unwrap();

assert_eq!(instance.get_test(), true);

slint_testing::send_mouse_click(&instance, 10.0 + 39.0 , 10.0 + 39.0);
assert_eq!(instance.get_result(), "A", "was just clicked inside");
slint_testing::send_mouse_click(&instance, 10.0 + 19.0 , 10.0 + 41.0);
assert_eq!(instance.get_result(), "A", "was just clicked outside");
slint_testing::send_mouse_click(&instance, 10.0 + 41.0 , 10.0 + 19.0);
assert_eq!(instance.get_result(), "A", "was just clicked outside again");


slint_testing::send_mouse_click(&instance, 100.0 + 6. , 100.0 - 19.0);
assert_eq!(instance.get_result(), "AB", "was just clicked inside");
slint_testing::send_mouse_click(&instance, 100.0 + 4., 100.0);
assert_eq!(instance.get_result(), "AB", "was just clicked outside");
slint_testing::send_mouse_click(&instance, 100.0 + 10., 100. - 21.);
assert_eq!(instance.get_result(), "AB", "was just clicked outside again");
```
*/