diff --git a/crates/ui/src/components/data_table.rs b/crates/ui/src/components/data_table.rs index b6363c82386f70d1178610936175d7ac80ab9f13..3e052296aca29e304024a0976a71e49978aee855 100644 --- a/crates/ui/src/components/data_table.rs +++ b/crates/ui/src/components/data_table.rs @@ -2,13 +2,13 @@ use std::{ops::Range, rc::Rc}; use crate::{ ActiveTheme as _, AnyElement, App, Button, ButtonCommon as _, ButtonStyle, Color, Component, - ComponentScope, Context, Div, ElementId, FixedWidth as _, FluentBuilder as _, HeaderResizeInfo, - Indicator, InteractiveElement, IntoElement, ParentElement, Pixels, RESIZE_COLUMN_WIDTH, - RESIZE_DIVIDER_WIDTH, RedistributableColumnsState, RegisterComponent, RenderOnce, ScrollAxes, - ScrollableHandle, Scrollbars, SharedString, StatefulInteractiveElement, Styled, StyledExt as _, - StyledTypography, TableResizeBehavior, Window, WithScrollbar, bind_redistributable_columns, - div, example_group_with_title, h_flex, px, render_redistributable_columns_resize_handles, - single_example, + ComponentScope, Context, Div, DraggedColumn, ElementId, FixedWidth as _, FluentBuilder as _, + HeaderResizeInfo, Indicator, InteractiveElement, IntoElement, ParentElement, Pixels, + RESIZE_COLUMN_WIDTH, RESIZE_DIVIDER_WIDTH, RedistributableColumnsState, RegisterComponent, + RenderOnce, ScrollAxes, ScrollableHandle, Scrollbars, SharedString, StatefulInteractiveElement, + Styled, StyledExt as _, StyledTypography, TableResizeBehavior, Window, WithScrollbar, + bind_redistributable_columns, div, example_group_with_title, h_flex, px, + render_redistributable_columns_resize_handles, single_example, table_row::{IntoTableRow as _, TableRow}, v_flex, }; @@ -23,10 +23,6 @@ pub mod table_row; #[cfg(test)] mod tests; -/// Used as the drag payload when resizing columns in `Resizable` mode. -#[derive(Debug)] -pub(crate) struct DraggedResizableColumn(pub(crate) usize); - /// Represents an unchecked table row, which is a vector of elements. /// Will be converted into `TableRow` internally pub type UncheckedTableRow = Vec; @@ -69,11 +65,11 @@ impl ResizableColumnsState { pub(crate) fn on_drag_move( &mut self, - drag_event: &DragMoveEvent, + drag_event: &DragMoveEvent, window: &mut Window, cx: &mut Context, ) { - let col_idx = drag_event.drag(cx).0; + let col_idx = drag_event.drag(cx).col_idx; let rem_size = window.rem_size(); let drag_x = drag_event.event.position.x - drag_event.bounds.left(); @@ -755,14 +751,20 @@ fn render_resize_handles_resizable( cx.stop_propagation(); } }) - .on_drag(DraggedResizableColumn(col_idx), { - let is_highlighted = is_highlighted.clone(); - move |_, _offset, _window, cx| { - is_highlighted.write(cx, true); - cx.new(|_cx| Empty) - } - }) - .on_drop::(move |_, _, cx| { + .on_drag( + DraggedColumn { + col_idx, + state_id: columns_state.entity_id(), + }, + { + let is_highlighted = is_highlighted.clone(); + move |_, _offset, _window, cx| { + is_highlighted.write(cx, true); + cx.new(|_cx| Empty) + } + }, + ) + .on_drop::(move |_, _, cx| { is_highlighted.write(cx, false); }); } @@ -851,7 +853,10 @@ impl RenderOnce for Table { bind_redistributable_columns(this, widths) }) .when_some(resizable_entity, |this, entity| { - this.on_drag_move::(move |event, window, cx| { + this.on_drag_move::(move |event, window, cx| { + if event.drag(cx).state_id != entity.entity_id() { + return; + } entity.update(cx, |state, cx| state.on_drag_move(event, window, cx)); }) }) diff --git a/crates/ui/src/components/redistributable_columns.rs b/crates/ui/src/components/redistributable_columns.rs index 3253ead001275c5f1c17ab31be7a59576dcdad2b..e73711feca2740a03b0e31e9edf439d229a52b97 100644 --- a/crates/ui/src/components/redistributable_columns.rs +++ b/crates/ui/src/components/redistributable_columns.rs @@ -1,8 +1,8 @@ use std::rc::Rc; use gpui::{ - AbsoluteLength, AppContext as _, Bounds, DefiniteLength, DragMoveEvent, Empty, Entity, Length, - WeakEntity, + AbsoluteLength, AppContext as _, Bounds, DefiniteLength, DragMoveEvent, Empty, Entity, + EntityId, Length, WeakEntity, }; use itertools::intersperse_with; @@ -19,8 +19,14 @@ use crate::{ pub(crate) const RESIZE_COLUMN_WIDTH: f32 = 8.0; pub(crate) const RESIZE_DIVIDER_WIDTH: f32 = 1.0; +/// Drag payload for column resize handles. +/// Includes the `EntityId` of the owning column state so that +/// `on_drag_move` handlers on unrelated tables ignore the event. #[derive(Debug)] -struct DraggedColumn(usize); +pub(crate) struct DraggedColumn { + pub(crate) col_idx: usize, + pub(crate) state_id: EntityId, +} #[derive(Debug, Copy, Clone, PartialEq)] pub enum TableResizeBehavior { @@ -276,7 +282,7 @@ impl RedistributableColumnsState { let mut col_position = 0.0; let rem_size = window.rem_size(); - let col_idx = drag_event.drag(cx).0; + let col_idx = drag_event.drag(cx).col_idx; let divider_width = Self::get_fraction( &DefiniteLength::Absolute(AbsoluteLength::Pixels(px(RESIZE_DIVIDER_WIDTH))), @@ -387,6 +393,9 @@ pub fn bind_redistributable_columns( .on_drag_move::({ let columns_state = columns_state.clone(); move |event, window, cx| { + if event.drag(cx).state_id != columns_state.entity_id() { + return; + } columns_state.update(cx, |columns, cx| { columns.on_drag_move(event, window, cx); }); @@ -478,13 +487,19 @@ pub fn render_redistributable_columns_resize_handles( cx.stop_propagation(); } }) - .on_drag(DraggedColumn(current_column_ix), { - let is_highlighted = is_highlighted.clone(); - move |_, _offset, _window, cx| { - is_highlighted.write(cx, true); - cx.new(|_cx| Empty) - } - }) + .on_drag( + DraggedColumn { + col_idx: current_column_ix, + state_id: columns_state.entity_id(), + }, + { + let is_highlighted = is_highlighted.clone(); + move |_, _offset, _window, cx| { + is_highlighted.write(cx, true); + cx.new(|_cx| Empty) + } + }, + ) .on_drop::(move |_, _, cx| { is_highlighted.write(cx, false); columns_state.update(cx, |state, _| {