Revive support for rotation of elements

The rotation-angle/rotation-origin-x/y properties are lowered to an
injected Rotate element, that we already had.

This needs further fixes for transforming input events and an
implementation of rotation in Skia.
This commit is contained in:
Simon Hausmann 2022-08-11 09:48:07 +02:00 committed by Simon Hausmann
parent 3b9309a0dd
commit 686df50e9f
5 changed files with 45 additions and 16 deletions

View file

@ -64,9 +64,9 @@ export ClippedImage := ImageItem {
export { ClippedImage as Image }
export Rotate := _ {
property <angle> angle;
property <length> origin-x;
property <length> origin-y;
property <angle> rotation-angle;
property <length> rotation-origin-x;
property <length> rotation-origin-y;
property <length> width;
property <length> height;
//-default_size_binding:expands_to_parent_geometry

View file

@ -139,6 +139,13 @@ pub async fn run_passes(
diag,
);
lower_shadows::lower_shadow_properties(component, &doc.local_registry, diag);
lower_property_to_element::lower_property_to_element(
component,
"rotation-angle",
"Rotate",
&global_type_registry.borrow(),
diag,
);
clip::handle_clip(component, &global_type_registry.borrow(), diag);
visible::handle_visible(component, &global_type_registry.borrow());
if compiler_config.accessibility {

View file

@ -10,7 +10,7 @@ use std::rc::Rc;
use crate::diagnostics::BuildDiagnostics;
use crate::expression_tree::{BindingExpression, NamedReference};
use crate::langtype::Type;
use crate::object_tree::{self, Component, Element, ElementRc};
use crate::object_tree::{self, BindingsMap, Component, Element, ElementRc};
use crate::typeregister::TypeRegister;
pub(crate) fn lower_property_to_element(
@ -84,15 +84,30 @@ fn create_property_element(
element_name: &str,
type_register: &TypeRegister,
) -> ElementRc {
let mut bindings: BindingsMap = std::iter::once((
property_name.to_owned(),
BindingExpression::new_two_way(NamedReference::new(child, property_name)).into(),
))
.collect();
if let Some((prefix, _)) = property_name.split_once("-") {
bindings.extend(child.borrow().bindings.keys().flat_map(|prop_name| {
if prop_name != property_name && prop_name.starts_with(prefix) {
Some((
prop_name.to_owned(),
BindingExpression::new_two_way(NamedReference::new(child, prop_name)).into(),
))
} else {
None
}
}));
}
let element = Element {
id: format!("{}-{}", child.borrow().id, property_name),
base_type: type_register.lookup_element(element_name).unwrap(),
enclosing_component: child.borrow().enclosing_component.clone(),
bindings: std::iter::once((
property_name.to_owned(),
BindingExpression::new_two_way(NamedReference::new(child, property_name)).into(),
))
.collect(),
bindings,
..Default::default()
};
Rc::new(RefCell::new(element))

View file

@ -86,6 +86,12 @@ pub(crate) const RESERVED_DROP_SHADOW_PROPERTIES: &[(&str, Type)] = &[
("drop-shadow-color", Type::Color),
];
pub(crate) const RESERVED_ROTATION_PROPERTIES: &[(&str, Type)] = &[
("rotation-angle", Type::Angle),
("rotation-origin-x", Type::LogicalLength),
("rotation-origin-y", Type::LogicalLength),
];
pub(crate) const RESERVED_ACCESSIBILITY_PROPERTIES: &[(&str, Type)] = &[
//("accessible-role", ...)
("accessible-checkable", Type::Bool),
@ -106,6 +112,7 @@ pub fn reserved_properties() -> impl Iterator<Item = (&'static str, Type)> {
.chain(RESERVED_LAYOUT_PROPERTIES.iter())
.chain(RESERVED_OTHER_PROPERTIES.iter())
.chain(RESERVED_DROP_SHADOW_PROPERTIES.iter())
.chain(RESERVED_ROTATION_PROPERTIES.iter())
.chain(RESERVED_ACCESSIBILITY_PROPERTIES.iter())
.map(|(k, v)| (*k, v.clone()))
.chain(IntoIterator::into_iter([

View file

@ -832,9 +832,9 @@ declare_item_vtable! {
#[pin]
/// The implementation of the `Rotate` element
pub struct Rotate {
pub angle: Property<f32>,
pub origin_x: Property<Coord>,
pub origin_y: Property<Coord>,
pub rotation_angle: Property<f32>,
pub rotation_origin_x: Property<Coord>,
pub rotation_origin_y: Property<Coord>,
pub width: Property<Coord>,
pub height: Property<Coord>,
pub cached_rendering_data: CachedRenderingData,
@ -844,7 +844,7 @@ impl Item for Rotate {
fn init(self: Pin<&Self>, _window: &WindowRc) {}
fn geometry(self: Pin<&Self>) -> Rect {
euclid::rect(0, 0, 0, 0).cast()
euclid::rect(0 as _, 0 as _, self.width(), self.height())
}
fn layout_info(self: Pin<&Self>, _orientation: Orientation, _window: &WindowRc) -> LayoutInfo {
@ -882,9 +882,9 @@ impl Item for Rotate {
backend: &mut ItemRendererRef,
_self_rc: &ItemRc,
) -> RenderingResult {
(*backend).translate(self.origin_x(), self.origin_y());
(*backend).rotate(self.angle());
(*backend).translate(-self.origin_x(), -self.origin_y());
(*backend).translate(self.rotation_origin_x(), self.rotation_origin_y());
(*backend).rotate(self.rotation_angle());
(*backend).translate(-self.rotation_origin_x(), -self.rotation_origin_y());
RenderingResult::ContinueRenderingChildren
}
}