mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-16 15:11:25 +00:00
Fix detection of topmost region under the dragged item
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
cbce49ff68
commit
6f5b1064ee
2 changed files with 46 additions and 20 deletions
|
@ -763,6 +763,11 @@ impl InteractiveBounds {
|
|||
pub fn visibly_contains(&self, point: &Point<Pixels>, cx: &WindowContext) -> bool {
|
||||
self.bounds.contains(point) && cx.was_top_layer(&point, &self.stacking_order)
|
||||
}
|
||||
|
||||
pub fn drag_target_contains(&self, point: &Point<Pixels>, cx: &WindowContext) -> bool {
|
||||
self.bounds.contains(point)
|
||||
&& cx.was_top_layer_under_active_drag(&point, &self.stacking_order)
|
||||
}
|
||||
}
|
||||
|
||||
impl Interactivity {
|
||||
|
@ -888,30 +893,32 @@ impl Interactivity {
|
|||
if cx.active_drag.is_some() {
|
||||
let drop_listeners = mem::take(&mut self.drop_listeners);
|
||||
let interactive_bounds = interactive_bounds.clone();
|
||||
cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& interactive_bounds.visibly_contains(&event.position, &cx)
|
||||
{
|
||||
if let Some(drag_state_type) =
|
||||
cx.active_drag.as_ref().map(|drag| drag.view.entity_type())
|
||||
if !drop_listeners.is_empty() {
|
||||
cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| {
|
||||
if phase == DispatchPhase::Bubble
|
||||
&& interactive_bounds.drag_target_contains(&event.position, cx)
|
||||
{
|
||||
for (drop_state_type, listener) in &drop_listeners {
|
||||
if *drop_state_type == drag_state_type {
|
||||
let drag = cx
|
||||
.active_drag
|
||||
.take()
|
||||
.expect("checked for type drag state type above");
|
||||
if let Some(drag_state_type) =
|
||||
cx.active_drag.as_ref().map(|drag| drag.view.entity_type())
|
||||
{
|
||||
for (drop_state_type, listener) in &drop_listeners {
|
||||
if *drop_state_type == drag_state_type {
|
||||
let drag = cx
|
||||
.active_drag
|
||||
.take()
|
||||
.expect("checked for type drag state type above");
|
||||
|
||||
listener(drag.view.clone(), cx);
|
||||
cx.notify();
|
||||
cx.stop_propagation();
|
||||
listener(drag.view.clone(), cx);
|
||||
cx.notify();
|
||||
cx.stop_propagation();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cx.active_drag = None;
|
||||
}
|
||||
} else {
|
||||
cx.active_drag = None;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let click_listeners = mem::take(&mut self.click_listeners);
|
||||
|
|
|
@ -38,6 +38,8 @@ use std::{
|
|||
};
|
||||
use util::ResultExt;
|
||||
|
||||
const ACTIVE_DRAG_Z_INDEX: u32 = 1;
|
||||
|
||||
/// A global stacking order, which is created by stacking successive z-index values.
|
||||
/// Each z-index will always be interpreted in the context of its parent z-index.
|
||||
#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Default, Debug)]
|
||||
|
@ -907,6 +909,23 @@ impl<'a> WindowContext<'a> {
|
|||
false
|
||||
}
|
||||
|
||||
pub fn was_top_layer_under_active_drag(
|
||||
&self,
|
||||
point: &Point<Pixels>,
|
||||
level: &StackingOrder,
|
||||
) -> bool {
|
||||
for (stack, bounds) in self.window.rendered_frame.depth_map.iter() {
|
||||
if stack.starts_with(&[ACTIVE_DRAG_Z_INDEX]) {
|
||||
continue;
|
||||
}
|
||||
if bounds.contains(point) {
|
||||
return level.starts_with(stack) || stack.starts_with(level);
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Called during painting to get the current stacking order.
|
||||
pub fn stacking_order(&self) -> &StackingOrder {
|
||||
&self.window.next_frame.z_index_stack
|
||||
|
@ -1238,7 +1257,7 @@ impl<'a> WindowContext<'a> {
|
|||
});
|
||||
|
||||
if let Some(active_drag) = self.app.active_drag.take() {
|
||||
self.with_z_index(1, |cx| {
|
||||
self.with_z_index(ACTIVE_DRAG_Z_INDEX, |cx| {
|
||||
let offset = cx.mouse_position() - active_drag.cursor_offset;
|
||||
let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent);
|
||||
active_drag.view.draw(offset, available_space, cx);
|
||||
|
|
Loading…
Reference in a new issue