Skip to content

Commit

Permalink
event transform and rotation
Browse files Browse the repository at this point in the history
  • Loading branch information
jrmoulton committed Nov 5, 2024
1 parent e14eca8 commit f1d5cf9
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 120 deletions.
83 changes: 43 additions & 40 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,12 +427,15 @@ impl<'a> EventCx<'a> {
pub(crate) fn offset_event(&self, id: ViewId, event: Event) -> Event {
let state = id.state();
let viewport = state.borrow().viewport;
let transform = state.borrow().transform;

if let Some(layout) = id.get_layout() {
event.offset((
layout.location.x as f64 - viewport.map(|rect| rect.x0).unwrap_or(0.0),
layout.location.y as f64 - viewport.map(|rect| rect.y0).unwrap_or(0.0),
))
event.transform(
Affine::translate((
layout.location.x as f64 - viewport.map(|rect| rect.x0).unwrap_or(0.0),
layout.location.y as f64 - viewport.map(|rect| rect.y0).unwrap_or(0.0),
)) * transform,
)
} else {
event
}
Expand Down Expand Up @@ -634,6 +637,40 @@ impl<'a> StyleCx<'a> {

view_state.borrow_mut().combined_style = modified;

let mut transform = Affine::IDENTITY;

let transform_x = match view_state.borrow().layout_props.translate_x() {
crate::unit::PxPct::Px(px) => px,
crate::unit::PxPct::Pct(pct) => pct / 100.,
};
let transform_y = match view_state.borrow().layout_props.translate_y() {
crate::unit::PxPct::Px(px) => px,
crate::unit::PxPct::Pct(pct) => pct / 100.,
};
transform *= Affine::translate(Vec2 {
x: transform_x,
y: transform_y,
});

let scale_x = view_state.borrow().layout_props.scale_x().0 / 100.;
let scale_y = view_state.borrow().layout_props.scale_y().0 / 100.;
let size = view_id.layout_rect();
let center_x = size.width() / 2.;
let center_y = size.height() / 2.;
transform *= Affine::translate(Vec2 {
x: center_x,
y: center_y,
});
transform *= Affine::scale_non_uniform(scale_x, scale_y);
let rotation = view_state.borrow().layout_props.rotation().0;
transform *= Affine::rotate(rotation);
transform *= Affine::translate(Vec2 {
x: -center_x,
y: -center_y,
});

view_state.borrow_mut().transform = transform;

self.restore();
}

Expand Down Expand Up @@ -800,6 +837,7 @@ impl<'a> ComputeLayoutCx<'a> {
};

view_state.borrow_mut().layout_rect = layout_rect;

self.restore();

Some(layout_rect)
Expand Down Expand Up @@ -1095,43 +1133,8 @@ impl<'a> PaintCx<'a> {
x: offset.x as f64,
y: offset.y as f64,
});
self.transform *= id.state().borrow().transform;

let view_state = id.state();
let transform_x = match view_state.borrow().layout_props.translate_x() {
crate::unit::PxPct::Px(px) => px,
crate::unit::PxPct::Pct(pct) => pct / 100.,
};
let transform_y = match view_state.borrow().layout_props.translate_y() {
crate::unit::PxPct::Px(px) => px,
crate::unit::PxPct::Pct(pct) => pct / 100.,
};
self.transform *= Affine::translate(Vec2 {
x: transform_x,
y: transform_y,
});

let scale_x = match view_state.borrow().layout_props.scale_x() {
crate::unit::PxPct::Px(px) => px / layout.size.width as f64,
crate::unit::PxPct::Pct(pct) => pct / 100.,
};
let scale_y = match view_state.borrow().layout_props.scale_y() {
crate::unit::PxPct::Px(px) => px / layout.size.height as f64,
crate::unit::PxPct::Pct(pct) => pct / 100.,
};
let center_x = layout.size.width as f64 / 2.0;
let center_y = layout.size.height as f64 / 2.0;
self.transform *= Affine::translate(Vec2 {
x: center_x,
y: center_y,
});
self.transform *= Affine::scale_non_uniform(scale_x, scale_y);
self.transform *= Affine::translate(Vec2 {
x: -center_x,
y: -center_y,
});

// let rotation = view_state.borrow().layout_props.rotation().0;
// self.transform *= Affine::rotate(rotation);
self.paint_state.renderer_mut().transform(self.transform);

if let Some(rect) = self.clip.as_mut() {
Expand Down
50 changes: 6 additions & 44 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use floem_winit::{
keyboard::{KeyCode, PhysicalKey},
window::Theme,
};
use peniko::kurbo::{Point, Size};
use peniko::kurbo::{Affine, Point, Size};

use crate::{
dropped_file::DroppedFileEvent,
Expand Down Expand Up @@ -247,57 +247,19 @@ impl Event {
}
}

pub fn scale(mut self, scale: f64) -> Event {
pub fn transform(mut self, transform: Affine) -> Event {
match &mut self {
Event::PointerDown(pointer_event) | Event::PointerUp(pointer_event) => {
pointer_event.pos.x /= scale;
pointer_event.pos.y /= scale;
pointer_event.pos = transform.inverse() * pointer_event.pos;
}
Event::PointerMove(pointer_event) => {
pointer_event.pos.x /= scale;
pointer_event.pos.y /= scale;
pointer_event.pos = transform.inverse() * pointer_event.pos;
}
Event::PointerWheel(pointer_event) => {
pointer_event.pos.x /= scale;
pointer_event.pos.y /= scale;
pointer_event.pos = transform.inverse() * pointer_event.pos;
}
Event::DroppedFile(event) => {
event.pos.x /= scale;
event.pos.y /= scale;
}
Event::PointerLeave
| Event::KeyDown(_)
| Event::KeyUp(_)
| Event::FocusGained
| Event::FocusLost
| Event::ImeEnabled
| Event::ImeDisabled
| Event::ImePreedit { .. }
| Event::ThemeChanged(_)
| Event::ImeCommit(_)
| Event::WindowClosed
| Event::WindowResized(_)
| Event::WindowMoved(_)
| Event::WindowMaximizeChanged(_)
| Event::WindowGotFocus
| Event::WindowLostFocus => {}
}
self
}

pub fn offset(mut self, offset: (f64, f64)) -> Event {
match &mut self {
Event::PointerDown(pointer_event) | Event::PointerUp(pointer_event) => {
pointer_event.pos -= offset;
}
Event::PointerMove(pointer_event) => {
pointer_event.pos -= offset;
}
Event::PointerWheel(pointer_event) => {
pointer_event.pos -= offset;
}
Event::DroppedFile(event) => {
event.pos -= offset;
event.pos = transform.inverse() * event.pos;
}
Event::PointerLeave
| Event::KeyDown(_)
Expand Down
22 changes: 16 additions & 6 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use taffy::{
use crate::context::InteractionState;
use crate::easing::*;
use crate::responsive::{ScreenSize, ScreenSizeBp};
use crate::unit::{Px, PxPct, PxPctAuto, UnitExt};
use crate::unit::{Pct, Px, PxPct, PxPctAuto, UnitExt};
use crate::view::{IntoView, View};
use crate::views::{empty, stack, text, Decorators};

Expand Down Expand Up @@ -164,6 +164,14 @@ impl StylePropValue for Px {
self.0.interpolate(&other.0, value).map(Px)
}
}
impl StylePropValue for Pct {
fn debug_view(&self) -> Option<Box<dyn View>> {
Some(text(format!("{}%", self.0)).into_any())
}
fn interpolate(&self, other: &Self, value: f64) -> Option<Self> {
self.0.interpolate(&other.0, value).map(Pct)
}
}
impl StylePropValue for PxPctAuto {
fn debug_view(&self) -> Option<Box<dyn View>> {
let label = match self {
Expand Down Expand Up @@ -1651,11 +1659,11 @@ define_builtin_props!(
AspectRatio aspect_ratio: Option<f32> {} = None,
ColGap col_gap nocb: PxPct {} = PxPct::Px(0.),
RowGap row_gap nocb: PxPct {} = PxPct::Px(0.),
ScaleX scale_x: PxPct {} = PxPct::Pct(100.),
ScaleY scale_y: PxPct {} = PxPct::Pct(100.),
ScaleX scale_x: Pct {} = Pct(100.),
ScaleY scale_y: Pct {} = Pct(100.),
TranslateX translate_x: PxPct {} = PxPct::Px(0.),
TranslateY translate_y: PxPct {} = PxPct::Px(0.),
// Rotation rotate: Px {} = Px(0.),
Rotation rotate: Px {} = Px(0.),
);

prop_extractor! {
Expand Down Expand Up @@ -1711,9 +1719,11 @@ prop_extractor! {
pub translate_x: TranslateX,
pub translate_y: TranslateY,

// pub rotation: Rotation,
pub rotation: Rotation,

}
}

impl LayoutProps {
pub fn to_style(&self) -> Style {
Style::new()
Expand Down Expand Up @@ -2261,7 +2271,7 @@ impl Style {
self.set(ZIndex, Some(z_index))
}

pub fn scale(self, scale: impl Into<PxPct>) -> Self {
pub fn scale(self, scale: impl Into<Pct>) -> Self {
let val = scale.into();
self.scale_x(val).scale_y(val)
}
Expand Down
4 changes: 3 additions & 1 deletion src/view_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
};
use bitflags::bitflags;
use im::HashSet;
use peniko::kurbo::{Point, Rect};
use peniko::kurbo::{Affine, Point, Rect};
use smallvec::SmallVec;
use std::{cell::RefCell, collections::HashMap, marker::PhantomData, rc::Rc};
use taffy::tree::NodeId;
Expand Down Expand Up @@ -174,6 +174,7 @@ pub struct ViewState {
pub(crate) is_hidden_state: IsHiddenState,
pub(crate) num_waiting_animations: u16,
pub(crate) disable_default_events: HashSet<EventListener>,
pub(crate) transform: Affine,
pub(crate) debug_name: SmallVec<[String; 1]>,
}

Expand Down Expand Up @@ -205,6 +206,7 @@ impl ViewState {
is_hidden_state: IsHiddenState::None,
num_waiting_animations: 0,
disable_default_events: HashSet::new(),
transform: Affine::IDENTITY,
debug_name: Default::default(),
}
}
Expand Down
15 changes: 6 additions & 9 deletions src/window_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ impl WindowHandle {

pub fn event(&mut self, event: Event) {
set_current_view(self.id);
let event = event.scale(self.app_state.scale);
let event = event.transform(Affine::scale(self.app_state.scale));

let mut cx = EventCx {
app_state: &mut self.app_state,
Expand Down Expand Up @@ -297,14 +297,11 @@ impl WindowHandle {
let window_origin = id.state().borrow().window_origin;
let layout = id.get_layout().unwrap_or_default();
let viewport = id.state().borrow().viewport.unwrap_or_default();
cx.unconditional_view_event(
id,
event.clone().offset((
window_origin.x - layout.location.x as f64 + viewport.x0,
window_origin.y - layout.location.y as f64 + viewport.y0,
)),
true,
);
let transform = Affine::translate((
window_origin.x - layout.location.x as f64 + viewport.x0,
window_origin.y - layout.location.y as f64 + viewport.y0,
));
cx.unconditional_view_event(id, event.clone().transform(transform), true);
}

if let Event::PointerUp(_) = &event {
Expand Down
Loading

0 comments on commit f1d5cf9

Please sign in to comment.