project panel: Fix rendering of groups of dragged project panel entries (#20686)
This PR introduces a new parameter for `on_drag` in gpui, which is an offset from the element origin to the mouse event origin. Release Notes: - Fixed rendering of dragged project panel entries
This commit is contained in:
parent
43999c47e1
commit
56c93be4de
5 changed files with 30 additions and 17 deletions
|
@ -2521,7 +2521,7 @@ impl CollabPanel {
|
||||||
.flex()
|
.flex()
|
||||||
.w_full()
|
.w_full()
|
||||||
.when(!channel.is_root_channel(), |el| {
|
.when(!channel.is_root_channel(), |el| {
|
||||||
el.on_drag(channel.clone(), move |channel, cx| {
|
el.on_drag(channel.clone(), move |channel, _, cx| {
|
||||||
cx.new_view(|_| DraggedChannelView {
|
cx.new_view(|_| DraggedChannelView {
|
||||||
channel: channel.clone(),
|
channel: channel.clone(),
|
||||||
width,
|
width,
|
||||||
|
|
|
@ -443,7 +443,7 @@ impl Interactivity {
|
||||||
pub fn on_drag<T, W>(
|
pub fn on_drag<T, W>(
|
||||||
&mut self,
|
&mut self,
|
||||||
value: T,
|
value: T,
|
||||||
constructor: impl Fn(&T, &mut WindowContext) -> View<W> + 'static,
|
constructor: impl Fn(&T, Point<Pixels>, &mut WindowContext) -> View<W> + 'static,
|
||||||
) where
|
) where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
T: 'static,
|
T: 'static,
|
||||||
|
@ -455,7 +455,9 @@ impl Interactivity {
|
||||||
);
|
);
|
||||||
self.drag_listener = Some((
|
self.drag_listener = Some((
|
||||||
Box::new(value),
|
Box::new(value),
|
||||||
Box::new(move |value, cx| constructor(value.downcast_ref().unwrap(), cx).into()),
|
Box::new(move |value, offset, cx| {
|
||||||
|
constructor(value.downcast_ref().unwrap(), offset, cx).into()
|
||||||
|
}),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,14 +968,15 @@ pub trait StatefulInteractiveElement: InteractiveElement {
|
||||||
|
|
||||||
/// On drag initiation, this callback will be used to create a new view to render the dragged value for a
|
/// On drag initiation, this callback will be used to create a new view to render the dragged value for a
|
||||||
/// drag and drop operation. This API should also be used as the equivalent of 'on drag start' with
|
/// drag and drop operation. This API should also be used as the equivalent of 'on drag start' with
|
||||||
/// the [`Self::on_drag_move`] API
|
/// the [`Self::on_drag_move`] API.
|
||||||
|
/// The callback also has access to the offset of triggering click from the origin of parent element.
|
||||||
/// The fluent API equivalent to [`Interactivity::on_drag`]
|
/// The fluent API equivalent to [`Interactivity::on_drag`]
|
||||||
///
|
///
|
||||||
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback.
|
/// See [`ViewContext::listener`](crate::ViewContext::listener) to get access to a view's state from this callback.
|
||||||
fn on_drag<T, W>(
|
fn on_drag<T, W>(
|
||||||
mut self,
|
mut self,
|
||||||
value: T,
|
value: T,
|
||||||
constructor: impl Fn(&T, &mut WindowContext) -> View<W> + 'static,
|
constructor: impl Fn(&T, Point<Pixels>, &mut WindowContext) -> View<W> + 'static,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
|
@ -1056,7 +1059,8 @@ pub(crate) type ScrollWheelListener =
|
||||||
|
|
||||||
pub(crate) type ClickListener = Box<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>;
|
pub(crate) type ClickListener = Box<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>;
|
||||||
|
|
||||||
pub(crate) type DragListener = Box<dyn Fn(&dyn Any, &mut WindowContext) -> AnyView + 'static>;
|
pub(crate) type DragListener =
|
||||||
|
Box<dyn Fn(&dyn Any, Point<Pixels>, &mut WindowContext) -> AnyView + 'static>;
|
||||||
|
|
||||||
type DropListener = Box<dyn Fn(&dyn Any, &mut WindowContext) + 'static>;
|
type DropListener = Box<dyn Fn(&dyn Any, &mut WindowContext) + 'static>;
|
||||||
|
|
||||||
|
@ -1818,7 +1822,8 @@ impl Interactivity {
|
||||||
if let Some((drag_value, drag_listener)) = drag_listener.take() {
|
if let Some((drag_value, drag_listener)) = drag_listener.take() {
|
||||||
*clicked_state.borrow_mut() = ElementClickedState::default();
|
*clicked_state.borrow_mut() = ElementClickedState::default();
|
||||||
let cursor_offset = event.position - hitbox.origin;
|
let cursor_offset = event.position - hitbox.origin;
|
||||||
let drag = (drag_listener)(drag_value.as_ref(), cx);
|
let drag =
|
||||||
|
(drag_listener)(drag_value.as_ref(), cursor_offset, cx);
|
||||||
cx.active_drag = Some(AnyDrag {
|
cx.active_drag = Some(AnyDrag {
|
||||||
view: drag,
|
view: drag,
|
||||||
value: drag_value,
|
value: drag_value,
|
||||||
|
|
|
@ -240,6 +240,7 @@ struct DraggedProjectEntryView {
|
||||||
selection: SelectedEntry,
|
selection: SelectedEntry,
|
||||||
details: EntryDetails,
|
details: EntryDetails,
|
||||||
width: Pixels,
|
width: Pixels,
|
||||||
|
click_offset: Point<Pixels>,
|
||||||
selections: Arc<BTreeSet<SelectedEntry>>,
|
selections: Arc<BTreeSet<SelectedEntry>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2681,10 +2682,11 @@ impl ProjectPanel {
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.on_drag(dragged_selection, move |selection, cx| {
|
.on_drag(dragged_selection, move |selection, click_offset, cx| {
|
||||||
cx.new_view(|_| DraggedProjectEntryView {
|
cx.new_view(|_| DraggedProjectEntryView {
|
||||||
details: details.clone(),
|
details: details.clone(),
|
||||||
width,
|
width,
|
||||||
|
click_offset,
|
||||||
selection: selection.active_selection,
|
selection: selection.active_selection,
|
||||||
selections: selection.marked_selections.clone(),
|
selections: selection.marked_selections.clone(),
|
||||||
})
|
})
|
||||||
|
@ -3559,15 +3561,21 @@ impl Render for DraggedProjectEntryView {
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||||
let settings = ProjectPanelSettings::get_global(cx);
|
let settings = ProjectPanelSettings::get_global(cx);
|
||||||
let ui_font = ThemeSettings::get_global(cx).ui_font.clone();
|
let ui_font = ThemeSettings::get_global(cx).ui_font.clone();
|
||||||
|
|
||||||
h_flex().font(ui_font).map(|this| {
|
h_flex().font(ui_font).map(|this| {
|
||||||
if self.selections.contains(&self.selection) {
|
if self.selections.len() > 1 && self.selections.contains(&self.selection) {
|
||||||
this.flex_shrink()
|
this.flex_none()
|
||||||
|
.w(self.width)
|
||||||
|
.child(div().w(self.click_offset.x))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
.p_1()
|
.p_1()
|
||||||
.items_end()
|
.rounded_xl()
|
||||||
.rounded_md()
|
.bg(cx.theme().colors().background)
|
||||||
.child(self.selections.len().to_string())
|
.child(Label::new(format!("{} entries", self.selections.len()))),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
this.bg(cx.theme().colors().background).w(self.width).child(
|
this.w(self.width).bg(cx.theme().colors().background).child(
|
||||||
ListItem::new(self.selection.entry_id.to_proto() as usize)
|
ListItem::new(self.selection.entry_id.to_proto() as usize)
|
||||||
.indent_level(self.details.depth)
|
.indent_level(self.details.depth)
|
||||||
.indent_step_size(px(settings.indent_size))
|
.indent_step_size(px(settings.indent_size))
|
||||||
|
|
|
@ -605,7 +605,7 @@ impl Render for Dock {
|
||||||
let create_resize_handle = || {
|
let create_resize_handle = || {
|
||||||
let handle = div()
|
let handle = div()
|
||||||
.id("resize-handle")
|
.id("resize-handle")
|
||||||
.on_drag(DraggedDock(position), |dock, cx| {
|
.on_drag(DraggedDock(position), |dock, _, cx| {
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
cx.new_view(|_| dock.clone())
|
cx.new_view(|_| dock.clone())
|
||||||
})
|
})
|
||||||
|
|
|
@ -1950,7 +1950,7 @@ impl Pane {
|
||||||
is_active,
|
is_active,
|
||||||
ix,
|
ix,
|
||||||
},
|
},
|
||||||
|tab, cx| cx.new_view(|_| tab.clone()),
|
|tab, _, cx| cx.new_view(|_| tab.clone()),
|
||||||
)
|
)
|
||||||
.drag_over::<DraggedTab>(|tab, _, cx| {
|
.drag_over::<DraggedTab>(|tab, _, cx| {
|
||||||
tab.bg(cx.theme().colors().drop_target_background)
|
tab.bg(cx.theme().colors().drop_target_background)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue