Skip to content
Open
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
28 changes: 24 additions & 4 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ impl EventCx<'_> {
// e.g. pointer events, so that the position is relative
// to the view, taking into account of the layout location
// of the view and the viewport of the view if it's in a scroll.
let original_event = event.clone();
let event = self.offset_event(view_id, event);
let event_no_transform = self.offset_event_no_transform(view_id, original_event);

let view = view_id.view();
let view_state = view_id.state();
Expand Down Expand Up @@ -327,10 +329,9 @@ impl EventCx<'_> {
}
Event::PointerUp(pointer_event) => {
if pointer_event.button.is_primary() {
let rect = view_id.get_size().unwrap_or_default().to_rect();
let on_view = rect.contains(pointer_event.pos);
let rect_no_transform = view_id.get_size().unwrap_or_default().to_rect();
let on_view = rect_no_transform.contains(pointer_event.pos);

// if id_path.is_none() {
if !directed {
if on_view {
if let Some(dragging) = self.app_state.dragging.as_mut() {
Expand Down Expand Up @@ -377,7 +378,11 @@ impl EventCx<'_> {
}

if let Some(handlers) = event_listeners.get(&EventListener::Click) {
if on_view
// we need to check if it is on the view,
// or if it `was` on the view or would have
// been on the view before a transform was applied to offset/scale the event
if (on_view
|| rect_no_transform.contains(event_no_transform.point().unwrap()))
&& self.app_state.is_clicking(&view_id)
&& last_pointer_down.is_some()
&& handlers.iter().fold(false, |handled, handler| {
Expand Down Expand Up @@ -482,6 +487,21 @@ impl EventCx<'_> {
}
}

/// translate a window-positioned event to the local coordinate system of a view without a view transform
pub(crate) fn offset_event_no_transform(&self, id: ViewId, event: Event) -> Event {
let state = id.state();
let viewport = state.borrow().viewport;

if let Some(layout) = id.get_layout() {
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),
)))
} else {
event
}
}

/// Used to determine if you should send an event to another view. This is basically a check for pointer events to see if the pointer is inside a child view and to make sure the current view isn't hidden or disabled.
/// Usually this is used if you want to propagate an event to a child view
pub fn should_send(&mut self, id: ViewId, event: &Event) -> bool {
Expand Down