eww
eww copied to clipboard
Implement explicitly setting a center of rotation
Description
The transform-Widget provides "rotate" to rotate its child. However, the default center of rotation is (0, 0) (aka top-left), so it was not possible to, for example, rotate a child in-place.
This commit implements the additional options rotation-center-x
and rotation-center-y
. Both are optional, and the default value is 0.0 for each, so previous configurations should produce the same results.
Usage
(defwindow grid
:stacking "fg"
:windowtype "dock"
:wm-ignore true
:geometry (geometry
:x "10px"
:y "10px"
:width "100px"
:height "100px")
(transform
;:rotate {-0.5 * percentloop}
:rotate 15
:transform-origin-x "50%"
:transform-origin-y "50%"
(box :orientation 'v' :style 'padding: 5px;'
(box :orientation 'h'
(label :style 'background-color: grey;' ' ')
(label :style 'background-color: green;' ' '))
(box :orientation 'h'
(label :style 'background-color: red;' ' ')
(transform
:rotate {2*percentloop}
:transform-origin-x "30%"
:transform-origin-y "50%"
:translate-x "-20%"
(box
(box :space-evenly true
(label :style 'background-color: yellow;' ' ')
(label :style 'background-color: black;' ' ')
(label :style 'background-color: yellow;' ' '))))))))
(deflisten percentloop :initial 0 `i=0; while true; do let i=$i+1; echo $i; sleep .05; done`)
* {
all: unset;
margin: 0px;
padding: 0px;
}
Showcase
I made a 5 second video of above configuration, but can't embed it here.
Additional Notes
- There are artifacts, if, for example in the above configuration, the transform of the whole grid would be a static rotate. As this does not happen when everything is moving, maybe a redraw is missing somewhere.
- The behaviour if both
rotation-center-*
andtranslate-*
needs to be mentioned, though it is not "wrong". If an in-place/centered rotation is wanted, and a shift to the right, the shift to the right needs to be added on top of the rotation-center-value to get an in-place rotation.
Checklist
Please make sure you can check all the boxes that apply to this PR.
- [ ] All widgets I've added are correctly documented.
- [x] I added my changes to CHANGELOG.md, if appropriate.
- [ ] The documentation in the
docs/content/main
directory has been adjusted to reflect my changes. - [x] I used
cargo fmt
to automatically format all code before committing
- I feel like we would want the origin to be relative to the position of the widget, such that you don't need to add the translation to the rotation-center value -- especially given that you'll most likely want to use percentages for the origin
- I'd just call it
transform-origin
, keeping the consistency with how the same thing is called in CSS - I'm not sure if I correctly understand the kind of artifacts you're referring to -- I'll see if I can reproduce them, but obviously optimally, there wouldn't be any visual artifacts here 😉
Hi, sorry for the late response; I'll try to answer point by point:
- If I understand correctly, then the translate-x/-y values should be added onto the origin, so that e.g. 50%/50% origin will always turn out to be an in-place rotation? As for units, the current implementation understands both percentages and pixels, so maximum flexibility for the user.
- I renamed the variables to
transform-origin
. I am a bit unsure, if this is the same as in CSS, though that may be based on my inexperience with CSS in general. - IIRC I only changed the first :rotate value to 95 or something similar.
According to the documentation, the current transform-order is: rotate -> translate -> scale. But, looking at the code (https://github.com/elkowar/eww/blob/master/crates/eww/src/widgets/transform.rs#L165) it seems to be: scale -> rotate -> translate Point 1 might affect this order too; scale after all changes the size of a widget, so any other transformation might possibly be affected. On the other hand, the current implementation retrieves the allocated_width/height exactly once, and uses that same value for all transformations, so the transformation might currently actually be independent of each other (somewhat)?
Update: I noticed #1103 when I looked at this project regarding the wrong EWW_NET values, and decided to renew this PR a bit.
- rebased to master, fixed any hiccups due to a different way of defining properties since I last worked on this
- updated the example rotation config
please do not merge yet, I want to double-check it's correct
Ok, that was a bit close for comfort, but re-checking what I did was the right decision.
The non-warping version is the one with the previously documented method-order, rotate->translate->scale.
I have rebuild this newest force-pushed commit both with nix build
and nix develop -> cargo build --bin eww
, both times yielding the desired result of the contents not being warped.
Sry for the mix-up.
thank you for double-checking!
just as a heads-up: there should be no difference in how you build if you execute the commands the way you stated ^^