Skip to content

Commit

Permalink
dont send pointer events to overlap siblings
Browse files Browse the repository at this point in the history
  • Loading branch information
jrmoulton committed Oct 28, 2024
1 parent 160811b commit 18bb178
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 14 deletions.
82 changes: 68 additions & 14 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use floem_reactive::Scope;
use floem_renderer::gpu_resources::{GpuResourceError, GpuResources};
use floem_renderer::Renderer as FloemRenderer;
use peniko::kurbo::{Affine, Point, Rect, RoundedRect, Shape, Size, Vec2};
use std::collections::HashMap;
use std::{
ops::{Deref, DerefMut},
rc::Rc,
Expand Down Expand Up @@ -479,23 +480,52 @@ impl<'a> EventCx<'a> {
if id.style_has_hidden() || (self.app_state.is_disabled(&id) && !event.allow_disabled()) {
return false;
}
if let Some(point) = event.point() {
let layout_rect = id.layout_rect();
if let Some(layout) = id.get_layout() {
if layout_rect
.with_origin(Point::new(
layout.location.x as f64,
layout.location.y as f64,
))
.contains(point)
{
return true;

let Some(point) = event.point() else {
return true;
};

let layout_rect = id.layout_rect();
let Some(layout) = id.get_layout() else {
return false;
};

// Check if point is within current view's bounds
let current_rect = layout_rect.with_origin(Point::new(
layout.location.x as f64,
layout.location.y as f64,
));

if !current_rect.contains(point) {
return false;
}

// Check for overlapping elements
let Some(parent) = id.parent() else {
return true;
};

let state = parent.state();

if let Some(overlap) = state.borrow().child_overlaps.get(&id) {
for &overlapping_id in overlap {
let overlap_rect = overlapping_id.layout_rect();
let Some(overlap_layout) = overlapping_id.get_layout() else {
continue;
};

let overlap_bounds = overlap_rect.with_origin(Point::new(
overlap_layout.location.x as f64,
overlap_layout.location.y as f64,
));

if overlap_bounds.contains(point) {
return false;
}
}
false
} else {
true
}

true
}
}

Expand Down Expand Up @@ -829,6 +859,30 @@ impl<'a> ComputeLayoutCx<'a> {
} else {
layout_rect
};

let children = id.children();
let child_overlaps: HashMap<_, _> = children
.iter()
.enumerate()
.filter_map(|(i, child)| {
let child_rect = child.layout_rect().inflate(-1., -1.);

// Find all later siblings that overlap with this child
let overlapping: Vec<_> = children
.iter()
.skip(i + 1)
.filter(|sibling| !sibling.style_has_hidden())
.filter(|sibling| {
let sibling_rect = sibling.layout_rect().inflate(-1., -1.);
child_rect.overlaps(sibling_rect)
})
.copied()
.collect();
(!overlapping.is_empty()).then_some((*child, overlapping))
})
.collect();

id.state().borrow_mut().child_overlaps = child_overlaps;
view_state.borrow_mut().layout_rect = layout_rect;

self.restore();
Expand Down
3 changes: 3 additions & 0 deletions src/view_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
Background, BorderColor, BorderRadius, BoxShadowProp, LayoutProps, Outline, OutlineColor,
Style, StyleClassRef, StyleSelectors,
},
ViewId,
};
use bitflags::bitflags;
use peniko::kurbo::{Point, Rect};
Expand Down Expand Up @@ -172,6 +173,7 @@ pub struct ViewState {
pub(crate) last_pointer_down: Option<PointerInputEvent>,
pub(crate) is_hidden_state: IsHiddenState,
pub(crate) num_waiting_animations: u16,
pub(crate) child_overlaps: HashMap<ViewId, Vec<ViewId>>,
pub(crate) debug_name: SmallVec<[String; 1]>,
}

Expand Down Expand Up @@ -202,6 +204,7 @@ impl ViewState {
window_origin: Point::ZERO,
is_hidden_state: IsHiddenState::None,
num_waiting_animations: 0,
child_overlaps: HashMap::new(),
debug_name: Default::default(),
}
}
Expand Down

0 comments on commit 18bb178

Please sign in to comment.