More drag'n'drop fixes

Conrad Irwin and Max created

Co-Authored-By: Max <max@zed.dev>

Change summary

crates/collab_ui2/src/collab_panel.rs | 25 ++++++++++++++++---------
crates/gpui2/src/elements/div.rs      | 15 +++++++--------
2 files changed, 23 insertions(+), 17 deletions(-)

Detailed changes

crates/collab_ui2/src/collab_panel.rs 🔗

@@ -179,8 +179,8 @@ use project::Fs;
 use serde_derive::{Deserialize, Serialize};
 use settings::{Settings, SettingsStore};
 use ui::{
-    h_stack, v_stack, Avatar, Button, Color, ContextMenu, Icon, IconButton, IconElement, Label,
-    List, ListHeader, ListItem, Toggle, Tooltip,
+    h_stack, v_stack, Avatar, Button, Color, ContextMenu, Icon, IconButton, IconElement, IconSize,
+    Label, List, ListHeader, ListItem, Toggle, Tooltip,
 };
 use util::{maybe, ResultExt, TryFutureExt};
 use workspace::{
@@ -2802,6 +2802,9 @@ impl CollabPanel {
                     cx.build_view({ |cx| DraggedChannelView { channel, width } })
                 }
             })
+            .drag_over::<DraggedChannelView>(|style| {
+                style.bg(cx.theme().colors().ghost_element_hover)
+            })
             .on_drop(
                 cx.listener(move |this, view: &View<DraggedChannelView>, cx| {
                     this.channel_store
@@ -3588,13 +3591,17 @@ impl Render for DraggedChannelView {
             .w(self.width)
             .p_1()
             .gap_1()
-            .child(IconElement::new(
-                if self.channel.visibility == proto::ChannelVisibility::Public {
-                    Icon::Public
-                } else {
-                    Icon::Hash
-                },
-            ))
+            .child(
+                IconElement::new(
+                    if self.channel.visibility == proto::ChannelVisibility::Public {
+                        Icon::Public
+                    } else {
+                        Icon::Hash
+                    },
+                )
+                .size(IconSize::Small)
+                .color(Color::Muted),
+            )
             .child(Label::new(self.channel.name.clone()))
     }
 }

crates/gpui2/src/elements/div.rs 🔗

@@ -824,7 +824,6 @@ impl Interactivity {
             .and_then(|group_hover| GroupBounds::get(&group_hover.group, cx));
 
         if let Some(group_bounds) = hover_group_bounds {
-            // todo!() needs cx.was_top_layer
             let hovered = group_bounds.contains_point(&cx.mouse_position());
             cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| {
                 if phase == DispatchPhase::Capture {
@@ -836,13 +835,13 @@ impl Interactivity {
         }
 
         if self.hover_style.is_some()
-            || (cx.active_drag.is_some() && !self.drag_over_styles.is_empty())
+            || cx.active_drag.is_some() && !self.drag_over_styles.is_empty()
         {
-            let interactive_bounds = interactive_bounds.clone();
-            let hovered = interactive_bounds.visibly_contains(&cx.mouse_position(), cx);
+            let bounds = bounds.intersect(&cx.content_mask().bounds);
+            let hovered = bounds.contains_point(&cx.mouse_position());
             cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| {
                 if phase == DispatchPhase::Capture {
-                    if interactive_bounds.visibly_contains(&event.position, cx) != hovered {
+                    if bounds.contains_point(&event.position) != hovered {
                         cx.notify();
                     }
                 }
@@ -1143,7 +1142,9 @@ impl Interactivity {
             let mouse_position = cx.mouse_position();
             if let Some(group_hover) = self.group_hover_style.as_ref() {
                 if let Some(group_bounds) = GroupBounds::get(&group_hover.group, cx) {
-                    if group_bounds.contains_point(&mouse_position) {
+                    if group_bounds.contains_point(&mouse_position)
+                        && cx.was_top_layer(&mouse_position, cx.stacking_order())
+                    {
                         style.refine(&group_hover.style);
                     }
                 }
@@ -1162,7 +1163,6 @@ impl Interactivity {
                 for (state_type, group_drag_style) in &self.group_drag_over_styles {
                     if let Some(group_bounds) = GroupBounds::get(&group_drag_style.group, cx) {
                         if *state_type == drag.view.entity_type()
-                        // todo!() needs to handle cx.content_mask() and cx.is_top()
                             && group_bounds.contains_point(&mouse_position)
                         {
                             style.refine(&group_drag_style.style);
@@ -1175,7 +1175,6 @@ impl Interactivity {
                         && bounds
                             .intersect(&cx.content_mask().bounds)
                             .contains_point(&mouse_position)
-                        && cx.was_top_layer(&mouse_position, cx.stacking_order())
                     {
                         style.refine(drag_over_style);
                     }