Split and move to pane working
This commit is contained in:
parent
9abfa037fd
commit
738893c527
11 changed files with 206 additions and 123 deletions
|
@ -1,4 +1,4 @@
|
|||
use drag_and_drop::{shared_payloads::DraggedProjectEntry, DragAndDrop};
|
||||
use drag_and_drop::DragAndDrop;
|
||||
use gpui::{
|
||||
color::Color,
|
||||
elements::{Canvas, MouseEventHandler, ParentElement, Stack},
|
||||
|
@ -7,9 +7,13 @@ use gpui::{
|
|||
AppContext, Element, ElementBox, EventContext, MouseButton, MouseState, Quad, RenderContext,
|
||||
WeakViewHandle,
|
||||
};
|
||||
use project::ProjectEntryId;
|
||||
use settings::Settings;
|
||||
|
||||
use crate::{MoveItem, Pane, SplitDirection, SplitWithItem, Workspace};
|
||||
use crate::{
|
||||
MoveItem, OpenProjectEntryInPane, Pane, SplitDirection, SplitWithItem, SplitWithProjectEntry,
|
||||
Workspace,
|
||||
};
|
||||
|
||||
use super::DraggedItem;
|
||||
|
||||
|
@ -34,7 +38,7 @@ where
|
|||
.map(|(drag_position, _)| drag_position)
|
||||
.or_else(|| {
|
||||
cx.global::<DragAndDrop<Workspace>>()
|
||||
.currently_dragged::<DraggedProjectEntry>(cx.window_id())
|
||||
.currently_dragged::<ProjectEntryId>(cx.window_id())
|
||||
.map(|(drag_position, _)| drag_position)
|
||||
})
|
||||
} else {
|
||||
|
@ -82,7 +86,7 @@ where
|
|||
.currently_dragged::<DraggedItem>(cx.window_id())
|
||||
.is_some()
|
||||
|| drag_and_drop
|
||||
.currently_dragged::<DraggedProjectEntry>(cx.window_id())
|
||||
.currently_dragged::<ProjectEntryId>(cx.window_id())
|
||||
.is_some()
|
||||
{
|
||||
cx.notify();
|
||||
|
@ -100,30 +104,59 @@ pub fn handle_dropped_item(
|
|||
split_margin: Option<f32>,
|
||||
cx: &mut EventContext,
|
||||
) {
|
||||
if let Some((_, dragged_item)) = cx
|
||||
.global::<DragAndDrop<Workspace>>()
|
||||
.currently_dragged::<DraggedItem>(cx.window_id)
|
||||
enum Action {
|
||||
Move(WeakViewHandle<Pane>, usize),
|
||||
Open(ProjectEntryId),
|
||||
}
|
||||
let drag_and_drop = cx.global::<DragAndDrop<Workspace>>();
|
||||
let action = if let Some((_, dragged_item)) =
|
||||
drag_and_drop.currently_dragged::<DraggedItem>(cx.window_id)
|
||||
{
|
||||
if let Some(split_direction) = split_margin
|
||||
.and_then(|margin| drop_split_direction(event.position, event.region, margin))
|
||||
{
|
||||
cx.dispatch_action(SplitWithItem {
|
||||
from: dragged_item.pane.clone(),
|
||||
item_id_to_move: dragged_item.item.id(),
|
||||
pane_to_split: pane.clone(),
|
||||
split_direction,
|
||||
});
|
||||
} else if pane != &dragged_item.pane || allow_same_pane {
|
||||
// If no split margin or not close enough to the edge, just move the item
|
||||
cx.dispatch_action(MoveItem {
|
||||
item_id: dragged_item.item.id(),
|
||||
from: dragged_item.pane.clone(),
|
||||
to: pane.clone(),
|
||||
destination_index: index,
|
||||
})
|
||||
}
|
||||
Action::Move(dragged_item.pane.clone(), dragged_item.item.id())
|
||||
} else if let Some((_, project_entry)) =
|
||||
drag_and_drop.currently_dragged::<ProjectEntryId>(cx.window_id)
|
||||
{
|
||||
Action::Open(*project_entry)
|
||||
} else {
|
||||
cx.propagate_event();
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(split_direction) =
|
||||
split_margin.and_then(|margin| drop_split_direction(event.position, event.region, margin))
|
||||
{
|
||||
let pane_to_split = pane.clone();
|
||||
match action {
|
||||
Action::Move(from, item_id_to_move) => cx.dispatch_action(SplitWithItem {
|
||||
from,
|
||||
item_id_to_move,
|
||||
pane_to_split,
|
||||
split_direction,
|
||||
}),
|
||||
Action::Open(project_entry) => cx.dispatch_action(SplitWithProjectEntry {
|
||||
pane_to_split,
|
||||
split_direction,
|
||||
project_entry,
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
match action {
|
||||
Action::Move(from, item_id) => {
|
||||
if pane != &from || allow_same_pane {
|
||||
cx.dispatch_action(MoveItem {
|
||||
item_id,
|
||||
from,
|
||||
to: pane.clone(),
|
||||
destination_index: index,
|
||||
})
|
||||
} else {
|
||||
cx.propagate_event();
|
||||
}
|
||||
}
|
||||
Action::Open(project_entry) => cx.dispatch_action(OpenProjectEntryInPane {
|
||||
pane: pane.clone(),
|
||||
project_entry,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,12 +128,25 @@ pub struct OpenSharedScreen {
|
|||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct SplitWithItem {
|
||||
from: WeakViewHandle<Pane>,
|
||||
pane_to_split: WeakViewHandle<Pane>,
|
||||
split_direction: SplitDirection,
|
||||
from: WeakViewHandle<Pane>,
|
||||
item_id_to_move: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct SplitWithProjectEntry {
|
||||
pane_to_split: WeakViewHandle<Pane>,
|
||||
split_direction: SplitDirection,
|
||||
project_entry: ProjectEntryId,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct OpenProjectEntryInPane {
|
||||
pane: WeakViewHandle<Pane>,
|
||||
project_entry: ProjectEntryId,
|
||||
}
|
||||
|
||||
impl_internal_actions!(
|
||||
workspace,
|
||||
[
|
||||
|
@ -143,6 +156,8 @@ impl_internal_actions!(
|
|||
OpenSharedScreen,
|
||||
RemoveWorktreeFromProject,
|
||||
SplitWithItem,
|
||||
SplitWithProjectEntry,
|
||||
OpenProjectEntryInPane,
|
||||
]
|
||||
);
|
||||
impl_actions!(workspace, [ActivatePane]);
|
||||
|
@ -234,6 +249,57 @@ pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
|
|||
},
|
||||
);
|
||||
|
||||
cx.add_async_action(
|
||||
|workspace: &mut Workspace,
|
||||
SplitWithProjectEntry {
|
||||
pane_to_split,
|
||||
split_direction,
|
||||
project_entry,
|
||||
}: &_,
|
||||
cx| {
|
||||
pane_to_split.upgrade(cx).and_then(|pane_to_split| {
|
||||
let new_pane = workspace.add_pane(cx);
|
||||
workspace
|
||||
.center
|
||||
.split(&pane_to_split, &new_pane, *split_direction)
|
||||
.unwrap();
|
||||
|
||||
workspace
|
||||
.project
|
||||
.read(cx)
|
||||
.path_for_entry(*project_entry, cx)
|
||||
.map(|path| {
|
||||
let task = workspace.open_path(path, Some(new_pane.downgrade()), true, cx);
|
||||
cx.foreground().spawn(async move {
|
||||
task.await?;
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
cx.add_async_action(
|
||||
|workspace: &mut Workspace,
|
||||
OpenProjectEntryInPane {
|
||||
pane,
|
||||
project_entry,
|
||||
}: &_,
|
||||
cx| {
|
||||
workspace
|
||||
.project
|
||||
.read(cx)
|
||||
.path_for_entry(*project_entry, cx)
|
||||
.map(|path| {
|
||||
let task = workspace.open_path(path, Some(pane.clone()), true, cx);
|
||||
cx.foreground().spawn(async move {
|
||||
task.await?;
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
let client = &app_state.client;
|
||||
client.add_view_request_handler(Workspace::handle_follow);
|
||||
client.add_view_message_handler(Workspace::handle_unfollow);
|
||||
|
@ -1399,7 +1465,7 @@ impl Workspace {
|
|||
mut abs_paths: Vec<PathBuf>,
|
||||
visible: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Task<Vec<Option<Result<Box<dyn ItemHandle>, Arc<anyhow::Error>>>>> {
|
||||
) -> Task<Vec<Option<Result<Box<dyn ItemHandle>, anyhow::Error>>>> {
|
||||
let fs = self.fs.clone();
|
||||
|
||||
// Sort the paths to ensure we add worktrees for parents before their children.
|
||||
|
@ -1429,7 +1495,7 @@ impl Workspace {
|
|||
if fs.is_file(&abs_path).await {
|
||||
Some(
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.open_path(project_path, true, cx)
|
||||
this.open_path(project_path, None, true, cx)
|
||||
})
|
||||
.await,
|
||||
)
|
||||
|
@ -1749,10 +1815,11 @@ impl Workspace {
|
|||
pub fn open_path(
|
||||
&mut self,
|
||||
path: impl Into<ProjectPath>,
|
||||
pane: Option<WeakViewHandle<Pane>>,
|
||||
focus_item: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Task<Result<Box<dyn ItemHandle>, Arc<anyhow::Error>>> {
|
||||
let pane = self.active_pane().downgrade();
|
||||
) -> Task<Result<Box<dyn ItemHandle>, anyhow::Error>> {
|
||||
let pane = pane.unwrap_or_else(|| self.active_pane().downgrade());
|
||||
let task = self.load_path(path.into(), cx);
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let (project_entry_id, build_item) = task.await?;
|
||||
|
@ -2874,7 +2941,7 @@ pub fn open_paths(
|
|||
cx: &mut MutableAppContext,
|
||||
) -> Task<(
|
||||
ViewHandle<Workspace>,
|
||||
Vec<Option<Result<Box<dyn ItemHandle>, Arc<anyhow::Error>>>>,
|
||||
Vec<Option<Result<Box<dyn ItemHandle>, anyhow::Error>>>,
|
||||
)> {
|
||||
log::info!("open paths {:?}", abs_paths);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue