slint icon indicating copy to clipboard operation
slint copied to clipboard

Add the ability to rotate items and their children

Open tronical opened this issue 3 years ago • 10 comments

For certain types of UIs - like for example a compass - we need the ability to rotate an item and its children. https://github.com/slint-ui/slint/pull/1478 revives some old code to bring back this feature as:

`rotation-angle`
`rotation-origin-x`
`rotation-origin-y`

properties on any items, resulting in an injected hidden Rotate element that applies the rotation when rendering.

Commit 7b50e38e533289c1fd05150715956a7930902397 implements the rotation also for the Skia backend.

There are a few things left before this issue can be considered complete:

  • [ ] The API needs to be reviewed / discussed. Is this the correct approach, or do we need a more general "transform" API? Could we start with this and generalise later?
  • [ ] Input events need to be subjected to the rotation as well.
  • [ ] These properties need to be documented, preferably with an inline example.

tronical avatar Aug 12 '22 14:08 tronical

Regarding the origin, i wonder if it would not be better to have, instead of

rotation-origin-x: width / 2;
rotation-origin-y: height / 2;

Maybe something like one property of type point:

rotation-origin: { x: width / 2, y: height / 2 };

One day if we add tuple to the langage, we could even shorten it to rotation-origin: (width / 2, height / 2); But what we can already do is use the % as rotation-origin: { x: 50%, y: 50% }; although that would then be easier with two different properties.

Edit: Should the default not be (50%,50%) anyway?

ogoffart avatar Aug 29 '22 07:08 ogoffart

Maybe it is also better in the first release to limit rotation to Image elements, that do not have any children.

This would solve the issue with translating input events. And this would make it easier for the implementation in the software renderer if only images can be rotated. (Rotating Rectangle (possibily with border), Clip and Text is each some work to do)

Image rotation is the primary use case for this feature anyway.

ogoffart avatar Aug 29 '22 07:08 ogoffart

Regarding the origin, i wonder if it would not be better to have, instead of

rotation-origin-x: width / 2;
rotation-origin-y: height / 2;

Maybe something like one property of type point:

rotation-origin: { x: width / 2, y: height / 2 };

Yes. I think this would apply to quite a few places where we have foo-bar-baz that would be better written as

foo-bar: { baz: 42; blub: 100; }

I've been thinking that this is something that we could perhaps implement generically in the compiler. We maintain to have individual rotation-origin-x and rotation-origin-y properties in the implementation, but we allow for the syntactic sugar to write rotation-origin: { x: ...; y: ... }.

If for some reason that's a little too "magic" then we could at least annotate these kind of property groups where we allow that in builtins.slint, for example for all the font-XXX properties.

One day if we add tuple to the langage, we could even shorten it to rotation-origin: (width / 2, height / 2); But what we can already do is use the % as rotation-origin: { x: 50%, y: 50% }; although that would then be easier with two different properties.

Edit: Should the default not be (50%,50%) anyway?

Yes!!

tronical avatar Aug 29 '22 08:08 tronical

Maybe it is also better in the first release to limit rotation to Image elements, that do not have any children.

This would solve the issue with translating input events. And this would make it easier for the implementation in the software renderer if only images can be rotated. (Rotating Rectangle (possibily with border), Clip and Text is each some work to do)

Image rotation is the primary use case for this feature anyway.

For the record, that's fine with me :)

tronical avatar Aug 29 '22 08:08 tronical

Now it is implemented and documented but it only work on childless Images. I keep this open for rotating arbitrary item that may include clip and mouse event and the like.

ogoffart avatar Aug 30 '22 10:08 ogoffart

I would like to see this for text. But also for arbitrary widgets since it will be a requirement on Android and iOS.

flukejones avatar Mar 13 '24 08:03 flukejones

Actually a specific use I have right now for text is to rotate to label a Y axis in a graph.

flukejones avatar Mar 13 '24 08:03 flukejones

I would like to see the progress bar rotatable, as the above has stated labels on other axis is another use case

lmnewey avatar May 22 '24 07:05 lmnewey

So if I understand this correctly, the main things preventing rotation from working outside images are:

  • software renderer
  • event handling

right?

Disabling the check and modifying examples a bit, rendering seems fine on Linux (tested only qt and winit backends, so no software renderer): image but ofc the button barely works.

I'd be willing to make a PR with the necessary changes if nobody is working on that.

Also maybe to make it more manageable and easier to review, non-interactive elements first? If I understand the problem correctly that would boil down to adding support in the software renderer.

maciek134 avatar Jun 22 '24 18:06 maciek134

@maciek134 yes, that's correct. The blocker I'd say is event handling that needs to understand the rotation. I think that feature would not be useful without that. Or what are you trying to do?

I'd be happy to review PR, thanks for that.

I think we could merge any PR that does any of the following:

  • Ability to rotate Text element that don't have children
  • Ability to rotate arbitrary element with children, if this is gated with compiler_config.enable_experimental (SLINT_ENABLE_EXPERIMENTAL_FEATURES env variable)
  • Add image rotation support in the software renderer (#3068)
  • Add the ability to rotate arbitrary element and forward their input correctly, even if the software renderer implementation is lacking (this is already documented as a limitation)

Regarding the software renderer, one tricky part will also be to compute dirty regions. In addition to support image rotating, and drawing of rotated (rounded) rectangle.

ogoffart avatar Jun 24 '24 09:06 ogoffart

The ability to rotate Text element that don't have children is implemented now for FemtVG/Skia/Qt (as part of #5532).

tronical avatar Jul 03 '24 08:07 tronical

Thanks @ogoffart , makes sense.

In that case I'll start with arbitrary element rotation with input and follow with the software renderer implementation later - the math for dirty region calculation should have a lot of overlap with event handling.

maciek134 avatar Jul 03 '24 10:07 maciek134