Make Pane::add_item
a proper Pane
method
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
edf8e276af
commit
6d3464fd1f
6 changed files with 219 additions and 331 deletions
|
@ -5264,6 +5264,20 @@ impl Project {
|
||||||
Some(ProjectPath { worktree_id, path })
|
Some(ProjectPath { worktree_id, path })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn absolute_path(&self, project_path: &ProjectPath, cx: &AppContext) -> Option<PathBuf> {
|
||||||
|
let workspace_root = self
|
||||||
|
.worktree_for_id(project_path.worktree_id, cx)?
|
||||||
|
.read(cx)
|
||||||
|
.abs_path();
|
||||||
|
let project_path = project_path.path.as_ref();
|
||||||
|
|
||||||
|
Some(if project_path == Path::new("") {
|
||||||
|
workspace_root.to_path_buf()
|
||||||
|
} else {
|
||||||
|
workspace_root.join(project_path)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// RPC message handlers
|
// RPC message handlers
|
||||||
|
|
||||||
async fn handle_unshare_project(
|
async fn handle_unshare_project(
|
||||||
|
|
|
@ -50,6 +50,7 @@ impl TerminalPanel {
|
||||||
let window_id = cx.window_id();
|
let window_id = cx.window_id();
|
||||||
let mut pane = Pane::new(
|
let mut pane = Pane::new(
|
||||||
workspace.weak_handle(),
|
workspace.weak_handle(),
|
||||||
|
workspace.project().clone(),
|
||||||
workspace.app_state().background_actions,
|
workspace.app_state().background_actions,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
cx,
|
cx,
|
||||||
|
@ -176,8 +177,9 @@ impl TerminalPanel {
|
||||||
(panel, pane, items)
|
(panel, pane, items)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let pane = pane.downgrade();
|
||||||
let items = futures::future::join_all(items).await;
|
let items = futures::future::join_all(items).await;
|
||||||
workspace.update(&mut cx, |workspace, cx| {
|
pane.update(&mut cx, |pane, cx| {
|
||||||
let active_item_id = serialized_panel
|
let active_item_id = serialized_panel
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|panel| panel.active_item_id);
|
.and_then(|panel| panel.active_item_id);
|
||||||
|
@ -185,17 +187,15 @@ impl TerminalPanel {
|
||||||
for item in items {
|
for item in items {
|
||||||
if let Some(item) = item.log_err() {
|
if let Some(item) = item.log_err() {
|
||||||
let item_id = item.id();
|
let item_id = item.id();
|
||||||
Pane::add_item(workspace, &pane, Box::new(item), false, false, None, cx);
|
pane.add_item(Box::new(item), false, false, None, cx);
|
||||||
if Some(item_id) == active_item_id {
|
if Some(item_id) == active_item_id {
|
||||||
active_ix = Some(pane.read(cx).items_len() - 1);
|
active_ix = Some(pane.items_len() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(active_ix) = active_ix {
|
if let Some(active_ix) = active_ix {
|
||||||
pane.update(cx, |pane, cx| {
|
|
||||||
pane.activate_item(active_ix, false, false, cx)
|
pane.activate_item(active_ix, false, false, cx)
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -240,8 +240,10 @@ impl TerminalPanel {
|
||||||
Box::new(cx.add_view(|cx| {
|
Box::new(cx.add_view(|cx| {
|
||||||
TerminalView::new(terminal, workspace.database_id(), cx)
|
TerminalView::new(terminal, workspace.database_id(), cx)
|
||||||
}));
|
}));
|
||||||
let focus = pane.read(cx).has_focus();
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, terminal, true, focus, None, cx);
|
let focus = pane.has_focus();
|
||||||
|
pane.add_item(terminal, true, focus, None, cx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
this.update(&mut cx, |this, cx| this.serialize(cx))?;
|
this.update(&mut cx, |this, cx| this.serialize(cx))?;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
item::WeakItemHandle, toolbar::Toolbar, AutosaveSetting, Item, NewFile, NewSearch, NewTerminal,
|
item::WeakItemHandle, toolbar::Toolbar, AutosaveSetting, Item, NewFile, NewSearch, NewTerminal,
|
||||||
ToggleZoom, Workspace, WorkspaceSettings,
|
ToggleZoom, Workspace, WorkspaceSettings,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::Result;
|
||||||
use collections::{HashMap, HashSet, VecDeque};
|
use collections::{HashMap, HashSet, VecDeque};
|
||||||
use context_menu::{ContextMenu, ContextMenuItem};
|
use context_menu::{ContextMenu, ContextMenuItem};
|
||||||
use drag_and_drop::{DragAndDrop, Draggable};
|
use drag_and_drop::{DragAndDrop, Draggable};
|
||||||
|
@ -161,6 +161,7 @@ pub struct Pane {
|
||||||
tab_context_menu: ViewHandle<ContextMenu>,
|
tab_context_menu: ViewHandle<ContextMenu>,
|
||||||
_background_actions: BackgroundActions,
|
_background_actions: BackgroundActions,
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
|
project: ModelHandle<Project>,
|
||||||
has_focus: bool,
|
has_focus: bool,
|
||||||
can_drop: Rc<dyn Fn(&DragAndDrop<Workspace>, &WindowContext) -> bool>,
|
can_drop: Rc<dyn Fn(&DragAndDrop<Workspace>, &WindowContext) -> bool>,
|
||||||
can_split: bool,
|
can_split: bool,
|
||||||
|
@ -241,6 +242,7 @@ impl TabBarContextMenu {
|
||||||
impl Pane {
|
impl Pane {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
workspace: WeakViewHandle<Workspace>,
|
workspace: WeakViewHandle<Workspace>,
|
||||||
|
project: ModelHandle<Project>,
|
||||||
background_actions: BackgroundActions,
|
background_actions: BackgroundActions,
|
||||||
next_timestamp: Arc<AtomicUsize>,
|
next_timestamp: Arc<AtomicUsize>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
|
@ -277,6 +279,7 @@ impl Pane {
|
||||||
tab_context_menu: cx.add_view(|cx| ContextMenu::new(pane_view_id, cx)),
|
tab_context_menu: cx.add_view(|cx| ContextMenu::new(pane_view_id, cx)),
|
||||||
_background_actions: background_actions,
|
_background_actions: background_actions,
|
||||||
workspace,
|
workspace,
|
||||||
|
project,
|
||||||
has_focus: false,
|
has_focus: false,
|
||||||
can_drop: Rc::new(|_, _| true),
|
can_drop: Rc::new(|_, _| true),
|
||||||
can_split: true,
|
can_split: true,
|
||||||
|
@ -502,21 +505,8 @@ impl Pane {
|
||||||
pane.active_item().map(|p| p.id())
|
pane.active_item().map(|p| p.id())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let item = workspace.update(&mut cx, |workspace, cx| {
|
|
||||||
let pane = pane
|
|
||||||
.upgrade(cx)
|
|
||||||
.ok_or_else(|| anyhow!("pane was dropped"))?;
|
|
||||||
anyhow::Ok(Self::open_item(
|
|
||||||
workspace,
|
|
||||||
pane.clone(),
|
|
||||||
project_entry_id,
|
|
||||||
true,
|
|
||||||
cx,
|
|
||||||
build_item,
|
|
||||||
))
|
|
||||||
})??;
|
|
||||||
|
|
||||||
pane.update(&mut cx, |pane, cx| {
|
pane.update(&mut cx, |pane, cx| {
|
||||||
|
let item = pane.open_item(project_entry_id, true, cx, build_item);
|
||||||
navigated |= Some(item.id()) != prev_active_item_id;
|
navigated |= Some(item.id()) != prev_active_item_id;
|
||||||
pane.nav_history
|
pane.nav_history
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -543,62 +533,46 @@ impl Pane {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn open_item(
|
pub(crate) fn open_item(
|
||||||
workspace: &mut Workspace,
|
&mut self,
|
||||||
pane: ViewHandle<Pane>,
|
|
||||||
project_entry_id: ProjectEntryId,
|
project_entry_id: ProjectEntryId,
|
||||||
focus_item: bool,
|
focus_item: bool,
|
||||||
cx: &mut ViewContext<Workspace>,
|
cx: &mut ViewContext<Self>,
|
||||||
build_item: impl FnOnce(&mut ViewContext<Pane>) -> Box<dyn ItemHandle>,
|
build_item: impl FnOnce(&mut ViewContext<Pane>) -> Box<dyn ItemHandle>,
|
||||||
) -> Box<dyn ItemHandle> {
|
) -> Box<dyn ItemHandle> {
|
||||||
let existing_item = pane.update(cx, |pane, cx| {
|
let mut existing_item = None;
|
||||||
for (index, item) in pane.items.iter().enumerate() {
|
for (index, item) in self.items.iter().enumerate() {
|
||||||
if item.is_singleton(cx)
|
if item.is_singleton(cx) && item.project_entry_ids(cx).as_slice() == [project_entry_id]
|
||||||
&& item.project_entry_ids(cx).as_slice() == [project_entry_id]
|
|
||||||
{
|
{
|
||||||
let item = item.boxed_clone();
|
let item = item.boxed_clone();
|
||||||
return Some((index, item));
|
existing_item = Some((index, item));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some((index, existing_item)) = existing_item {
|
if let Some((index, existing_item)) = existing_item {
|
||||||
pane.update(cx, |pane, cx| {
|
self.activate_item(index, focus_item, focus_item, cx);
|
||||||
pane.activate_item(index, focus_item, focus_item, cx);
|
|
||||||
});
|
|
||||||
existing_item
|
existing_item
|
||||||
} else {
|
} else {
|
||||||
let new_item = pane.update(cx, |_, cx| build_item(cx));
|
let new_item = build_item(cx);
|
||||||
Pane::add_item(
|
self.add_item(new_item.clone(), true, focus_item, None, cx);
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
new_item.clone(),
|
|
||||||
true,
|
|
||||||
focus_item,
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
new_item
|
new_item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_item(
|
pub fn add_item(
|
||||||
workspace: &mut Workspace,
|
&mut self,
|
||||||
pane: &ViewHandle<Pane>,
|
|
||||||
item: Box<dyn ItemHandle>,
|
item: Box<dyn ItemHandle>,
|
||||||
activate_pane: bool,
|
activate_pane: bool,
|
||||||
focus_item: bool,
|
focus_item: bool,
|
||||||
destination_index: Option<usize>,
|
destination_index: Option<usize>,
|
||||||
cx: &mut ViewContext<Workspace>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
if item.is_singleton(cx) {
|
if item.is_singleton(cx) {
|
||||||
if let Some(&entry_id) = item.project_entry_ids(cx).get(0) {
|
if let Some(&entry_id) = item.project_entry_ids(cx).get(0) {
|
||||||
if let Some(project_path) =
|
let project = self.project.read(cx);
|
||||||
workspace.project().read(cx).path_for_entry(entry_id, cx)
|
if let Some(project_path) = project.path_for_entry(entry_id, cx) {
|
||||||
{
|
let abs_path = project.absolute_path(&project_path, cx);
|
||||||
let abs_path = workspace.absolute_path(&project_path, cx);
|
self.nav_history
|
||||||
pane.read(cx)
|
|
||||||
.nav_history
|
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.paths_by_item
|
.paths_by_item
|
||||||
.insert(item.id(), (project_path, abs_path));
|
.insert(item.id(), (project_path, abs_path));
|
||||||
|
@ -607,19 +581,16 @@ impl Pane {
|
||||||
}
|
}
|
||||||
// If no destination index is specified, add or move the item after the active item.
|
// If no destination index is specified, add or move the item after the active item.
|
||||||
let mut insertion_index = {
|
let mut insertion_index = {
|
||||||
let pane = pane.read(cx);
|
|
||||||
cmp::min(
|
cmp::min(
|
||||||
if let Some(destination_index) = destination_index {
|
if let Some(destination_index) = destination_index {
|
||||||
destination_index
|
destination_index
|
||||||
} else {
|
} else {
|
||||||
pane.active_item_index + 1
|
self.active_item_index + 1
|
||||||
},
|
},
|
||||||
pane.items.len(),
|
self.items.len(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
item.added_to_pane(workspace, pane.clone(), cx);
|
|
||||||
|
|
||||||
// Does the item already exist?
|
// Does the item already exist?
|
||||||
let project_entry_id = if item.is_singleton(cx) {
|
let project_entry_id = if item.is_singleton(cx) {
|
||||||
item.project_entry_ids(cx).get(0).copied()
|
item.project_entry_ids(cx).get(0).copied()
|
||||||
|
@ -627,7 +598,7 @@ impl Pane {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let existing_item_index = pane.read(cx).items.iter().position(|existing_item| {
|
let existing_item_index = self.items.iter().position(|existing_item| {
|
||||||
if existing_item.id() == item.id() {
|
if existing_item.id() == item.id() {
|
||||||
true
|
true
|
||||||
} else if existing_item.is_singleton(cx) {
|
} else if existing_item.is_singleton(cx) {
|
||||||
|
@ -644,45 +615,42 @@ impl Pane {
|
||||||
|
|
||||||
if let Some(existing_item_index) = existing_item_index {
|
if let Some(existing_item_index) = existing_item_index {
|
||||||
// If the item already exists, move it to the desired destination and activate it
|
// If the item already exists, move it to the desired destination and activate it
|
||||||
pane.update(cx, |pane, cx| {
|
|
||||||
if existing_item_index != insertion_index {
|
if existing_item_index != insertion_index {
|
||||||
let existing_item_is_active = existing_item_index == pane.active_item_index;
|
let existing_item_is_active = existing_item_index == self.active_item_index;
|
||||||
|
|
||||||
// If the caller didn't specify a destination and the added item is already
|
// If the caller didn't specify a destination and the added item is already
|
||||||
// the active one, don't move it
|
// the active one, don't move it
|
||||||
if existing_item_is_active && destination_index.is_none() {
|
if existing_item_is_active && destination_index.is_none() {
|
||||||
insertion_index = existing_item_index;
|
insertion_index = existing_item_index;
|
||||||
} else {
|
} else {
|
||||||
pane.items.remove(existing_item_index);
|
self.items.remove(existing_item_index);
|
||||||
if existing_item_index < pane.active_item_index {
|
if existing_item_index < self.active_item_index {
|
||||||
pane.active_item_index -= 1;
|
self.active_item_index -= 1;
|
||||||
}
|
}
|
||||||
insertion_index = insertion_index.min(pane.items.len());
|
insertion_index = insertion_index.min(self.items.len());
|
||||||
|
|
||||||
pane.items.insert(insertion_index, item.clone());
|
self.items.insert(insertion_index, item.clone());
|
||||||
|
|
||||||
if existing_item_is_active {
|
if existing_item_is_active {
|
||||||
pane.active_item_index = insertion_index;
|
self.active_item_index = insertion_index;
|
||||||
} else if insertion_index <= pane.active_item_index {
|
} else if insertion_index <= self.active_item_index {
|
||||||
pane.active_item_index += 1;
|
self.active_item_index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
pane.activate_item(insertion_index, activate_pane, focus_item, cx);
|
self.activate_item(insertion_index, activate_pane, focus_item, cx);
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
pane.update(cx, |pane, cx| {
|
self.items.insert(insertion_index, item);
|
||||||
pane.items.insert(insertion_index, item);
|
if insertion_index <= self.active_item_index {
|
||||||
if insertion_index <= pane.active_item_index {
|
self.active_item_index += 1;
|
||||||
pane.active_item_index += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pane.activate_item(insertion_index, activate_pane, focus_item, cx);
|
self.activate_item(insertion_index, activate_pane, focus_item, cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,7 +942,12 @@ impl Pane {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_item(&mut self, item_index: usize, activate_pane: bool, cx: &mut ViewContext<Self>) {
|
pub fn remove_item(
|
||||||
|
&mut self,
|
||||||
|
item_index: usize,
|
||||||
|
activate_pane: bool,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
self.activation_history
|
self.activation_history
|
||||||
.retain(|&history_entry| history_entry != self.items[item_index].id());
|
.retain(|&history_entry| history_entry != self.items[item_index].id());
|
||||||
|
|
||||||
|
@ -1148,48 +1121,6 @@ impl Pane {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_item(
|
|
||||||
workspace: &mut Workspace,
|
|
||||||
from: ViewHandle<Pane>,
|
|
||||||
to: ViewHandle<Pane>,
|
|
||||||
item_id_to_move: usize,
|
|
||||||
destination_index: usize,
|
|
||||||
cx: &mut ViewContext<Workspace>,
|
|
||||||
) {
|
|
||||||
let item_to_move = from
|
|
||||||
.read(cx)
|
|
||||||
.items()
|
|
||||||
.enumerate()
|
|
||||||
.find(|(_, item_handle)| item_handle.id() == item_id_to_move);
|
|
||||||
|
|
||||||
if item_to_move.is_none() {
|
|
||||||
log::warn!("Tried to move item handle which was not in `from` pane. Maybe tab was closed during drop");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let (item_ix, item_handle) = item_to_move.unwrap();
|
|
||||||
let item_handle = item_handle.clone();
|
|
||||||
|
|
||||||
if from != to {
|
|
||||||
// Close item from previous pane
|
|
||||||
from.update(cx, |from, cx| {
|
|
||||||
from.remove_item(item_ix, false, cx);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// This automatically removes duplicate items in the pane
|
|
||||||
Pane::add_item(
|
|
||||||
workspace,
|
|
||||||
&to,
|
|
||||||
item_handle,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
Some(destination_index),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
|
|
||||||
cx.focus(&to);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn split(&mut self, direction: SplitDirection, cx: &mut ViewContext<Self>) {
|
pub fn split(&mut self, direction: SplitDirection, cx: &mut ViewContext<Self>) {
|
||||||
cx.emit(Event::Split(direction));
|
cx.emit(Event::Split(direction));
|
||||||
}
|
}
|
||||||
|
@ -2124,11 +2055,9 @@ mod tests {
|
||||||
|
|
||||||
// 1. Add with a destination index
|
// 1. Add with a destination index
|
||||||
// a. Add before the active item
|
// a. Add before the active item
|
||||||
set_labeled_items(&workspace, &pane, ["A", "B*", "C"], cx);
|
set_labeled_items(&pane, ["A", "B*", "C"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(
|
pane.add_item(
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -2139,11 +2068,9 @@ mod tests {
|
||||||
assert_item_labels(&pane, ["D*", "A", "B", "C"], cx);
|
assert_item_labels(&pane, ["D*", "A", "B", "C"], cx);
|
||||||
|
|
||||||
// b. Add after the active item
|
// b. Add after the active item
|
||||||
set_labeled_items(&workspace, &pane, ["A", "B*", "C"], cx);
|
set_labeled_items(&pane, ["A", "B*", "C"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(
|
pane.add_item(
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -2154,11 +2081,9 @@ mod tests {
|
||||||
assert_item_labels(&pane, ["A", "B", "D*", "C"], cx);
|
assert_item_labels(&pane, ["A", "B", "D*", "C"], cx);
|
||||||
|
|
||||||
// c. Add at the end of the item list (including off the length)
|
// c. Add at the end of the item list (including off the length)
|
||||||
set_labeled_items(&workspace, &pane, ["A", "B*", "C"], cx);
|
set_labeled_items(&pane, ["A", "B*", "C"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(
|
pane.add_item(
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -2170,11 +2095,9 @@ mod tests {
|
||||||
|
|
||||||
// 2. Add without a destination index
|
// 2. Add without a destination index
|
||||||
// a. Add with active item at the start of the item list
|
// a. Add with active item at the start of the item list
|
||||||
set_labeled_items(&workspace, &pane, ["A*", "B", "C"], cx);
|
set_labeled_items(&pane, ["A*", "B", "C"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(
|
pane.add_item(
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -2182,14 +2105,12 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
set_labeled_items(&workspace, &pane, ["A", "D*", "B", "C"], cx);
|
set_labeled_items(&pane, ["A", "D*", "B", "C"], cx);
|
||||||
|
|
||||||
// b. Add with active item at the end of the item list
|
// b. Add with active item at the end of the item list
|
||||||
set_labeled_items(&workspace, &pane, ["A", "B", "C*"], cx);
|
set_labeled_items(&pane, ["A", "B", "C*"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(
|
pane.add_item(
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
Box::new(cx.add_view(|_| TestItem::new().with_label("D"))),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
@ -2212,66 +2133,66 @@ mod tests {
|
||||||
|
|
||||||
// 1. Add with a destination index
|
// 1. Add with a destination index
|
||||||
// 1a. Add before the active item
|
// 1a. Add before the active item
|
||||||
let [_, _, _, d] = set_labeled_items(&workspace, &pane, ["A", "B*", "C", "D"], cx);
|
let [_, _, _, d] = set_labeled_items(&pane, ["A", "B*", "C", "D"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, d, false, false, Some(0), cx);
|
pane.add_item(d, false, false, Some(0), cx);
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["D*", "A", "B", "C"], cx);
|
assert_item_labels(&pane, ["D*", "A", "B", "C"], cx);
|
||||||
|
|
||||||
// 1b. Add after the active item
|
// 1b. Add after the active item
|
||||||
let [_, _, _, d] = set_labeled_items(&workspace, &pane, ["A", "B*", "C", "D"], cx);
|
let [_, _, _, d] = set_labeled_items(&pane, ["A", "B*", "C", "D"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, d, false, false, Some(2), cx);
|
pane.add_item(d, false, false, Some(2), cx);
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["A", "B", "D*", "C"], cx);
|
assert_item_labels(&pane, ["A", "B", "D*", "C"], cx);
|
||||||
|
|
||||||
// 1c. Add at the end of the item list (including off the length)
|
// 1c. Add at the end of the item list (including off the length)
|
||||||
let [a, _, _, _] = set_labeled_items(&workspace, &pane, ["A", "B*", "C", "D"], cx);
|
let [a, _, _, _] = set_labeled_items(&pane, ["A", "B*", "C", "D"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, a, false, false, Some(5), cx);
|
pane.add_item(a, false, false, Some(5), cx);
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["B", "C", "D", "A*"], cx);
|
assert_item_labels(&pane, ["B", "C", "D", "A*"], cx);
|
||||||
|
|
||||||
// 1d. Add same item to active index
|
// 1d. Add same item to active index
|
||||||
let [_, b, _] = set_labeled_items(&workspace, &pane, ["A", "B*", "C"], cx);
|
let [_, b, _] = set_labeled_items(&pane, ["A", "B*", "C"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, b, false, false, Some(1), cx);
|
pane.add_item(b, false, false, Some(1), cx);
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["A", "B*", "C"], cx);
|
assert_item_labels(&pane, ["A", "B*", "C"], cx);
|
||||||
|
|
||||||
// 1e. Add item to index after same item in last position
|
// 1e. Add item to index after same item in last position
|
||||||
let [_, _, c] = set_labeled_items(&workspace, &pane, ["A", "B*", "C"], cx);
|
let [_, _, c] = set_labeled_items(&pane, ["A", "B*", "C"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, c, false, false, Some(2), cx);
|
pane.add_item(c, false, false, Some(2), cx);
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["A", "B", "C*"], cx);
|
assert_item_labels(&pane, ["A", "B", "C*"], cx);
|
||||||
|
|
||||||
// 2. Add without a destination index
|
// 2. Add without a destination index
|
||||||
// 2a. Add with active item at the start of the item list
|
// 2a. Add with active item at the start of the item list
|
||||||
let [_, _, _, d] = set_labeled_items(&workspace, &pane, ["A*", "B", "C", "D"], cx);
|
let [_, _, _, d] = set_labeled_items(&pane, ["A*", "B", "C", "D"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, d, false, false, None, cx);
|
pane.add_item(d, false, false, None, cx);
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["A", "D*", "B", "C"], cx);
|
assert_item_labels(&pane, ["A", "D*", "B", "C"], cx);
|
||||||
|
|
||||||
// 2b. Add with active item at the end of the item list
|
// 2b. Add with active item at the end of the item list
|
||||||
let [a, _, _, _] = set_labeled_items(&workspace, &pane, ["A", "B", "C", "D*"], cx);
|
let [a, _, _, _] = set_labeled_items(&pane, ["A", "B", "C", "D*"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, a, false, false, None, cx);
|
pane.add_item(a, false, false, None, cx);
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["B", "C", "D", "A*"], cx);
|
assert_item_labels(&pane, ["B", "C", "D", "A*"], cx);
|
||||||
|
|
||||||
// 2c. Add active item to active item at end of list
|
// 2c. Add active item to active item at end of list
|
||||||
let [_, _, c] = set_labeled_items(&workspace, &pane, ["A", "B", "C*"], cx);
|
let [_, _, c] = set_labeled_items(&pane, ["A", "B", "C*"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, c, false, false, None, cx);
|
pane.add_item(c, false, false, None, cx);
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["A", "B", "C*"], cx);
|
assert_item_labels(&pane, ["A", "B", "C*"], cx);
|
||||||
|
|
||||||
// 2d. Add active item to active item at start of list
|
// 2d. Add active item to active item at start of list
|
||||||
let [a, _, _] = set_labeled_items(&workspace, &pane, ["A*", "B", "C"], cx);
|
let [a, _, _] = set_labeled_items(&pane, ["A*", "B", "C"], cx);
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(workspace, &pane, a, false, false, None, cx);
|
pane.add_item(a, false, false, None, cx);
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["A*", "B", "C"], cx);
|
assert_item_labels(&pane, ["A*", "B", "C"], cx);
|
||||||
}
|
}
|
||||||
|
@ -2287,97 +2208,56 @@ mod tests {
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
// singleton view
|
// singleton view
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
let item = TestItem::new()
|
let item = TestItem::new()
|
||||||
.with_singleton(true)
|
.with_singleton(true)
|
||||||
.with_label("buffer 1")
|
.with_label("buffer 1")
|
||||||
.with_project_items(&[TestProjectItem::new(1, "one.txt", cx)]);
|
.with_project_items(&[TestProjectItem::new(1, "one.txt", cx)]);
|
||||||
|
|
||||||
Pane::add_item(
|
pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx);
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| item)),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["buffer 1*"], cx);
|
assert_item_labels(&pane, ["buffer 1*"], cx);
|
||||||
|
|
||||||
// new singleton view with the same project entry
|
// new singleton view with the same project entry
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
let item = TestItem::new()
|
let item = TestItem::new()
|
||||||
.with_singleton(true)
|
.with_singleton(true)
|
||||||
.with_label("buffer 1")
|
.with_label("buffer 1")
|
||||||
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]);
|
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]);
|
||||||
|
|
||||||
Pane::add_item(
|
pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx);
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| item)),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["buffer 1*"], cx);
|
assert_item_labels(&pane, ["buffer 1*"], cx);
|
||||||
|
|
||||||
// new singleton view with different project entry
|
// new singleton view with different project entry
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
let item = TestItem::new()
|
let item = TestItem::new()
|
||||||
.with_singleton(true)
|
.with_singleton(true)
|
||||||
.with_label("buffer 2")
|
.with_label("buffer 2")
|
||||||
.with_project_items(&[TestProjectItem::new(2, "2.txt", cx)]);
|
.with_project_items(&[TestProjectItem::new(2, "2.txt", cx)]);
|
||||||
|
pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx);
|
||||||
Pane::add_item(
|
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| item)),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["buffer 1", "buffer 2*"], cx);
|
assert_item_labels(&pane, ["buffer 1", "buffer 2*"], cx);
|
||||||
|
|
||||||
// new multibuffer view with the same project entry
|
// new multibuffer view with the same project entry
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
let item = TestItem::new()
|
let item = TestItem::new()
|
||||||
.with_singleton(false)
|
.with_singleton(false)
|
||||||
.with_label("multibuffer 1")
|
.with_label("multibuffer 1")
|
||||||
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]);
|
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]);
|
||||||
|
|
||||||
Pane::add_item(
|
pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx);
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| item)),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
assert_item_labels(&pane, ["buffer 1", "buffer 2", "multibuffer 1*"], cx);
|
assert_item_labels(&pane, ["buffer 1", "buffer 2", "multibuffer 1*"], cx);
|
||||||
|
|
||||||
// another multibuffer view with the same project entry
|
// another multibuffer view with the same project entry
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
let item = TestItem::new()
|
let item = TestItem::new()
|
||||||
.with_singleton(false)
|
.with_singleton(false)
|
||||||
.with_label("multibuffer 1b")
|
.with_label("multibuffer 1b")
|
||||||
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]);
|
.with_project_items(&[TestProjectItem::new(1, "1.txt", cx)]);
|
||||||
|
|
||||||
Pane::add_item(
|
pane.add_item(Box::new(cx.add_view(|_| item)), false, false, None, cx);
|
||||||
workspace,
|
|
||||||
&pane,
|
|
||||||
Box::new(cx.add_view(|_| item)),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
assert_item_labels(
|
assert_item_labels(
|
||||||
&pane,
|
&pane,
|
||||||
|
@ -2395,14 +2275,14 @@ mod tests {
|
||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
add_labeled_item(&workspace, &pane, "A", false, cx);
|
add_labeled_item(&pane, "A", false, cx);
|
||||||
add_labeled_item(&workspace, &pane, "B", false, cx);
|
add_labeled_item(&pane, "B", false, cx);
|
||||||
add_labeled_item(&workspace, &pane, "C", false, cx);
|
add_labeled_item(&pane, "C", false, cx);
|
||||||
add_labeled_item(&workspace, &pane, "D", false, cx);
|
add_labeled_item(&pane, "D", false, cx);
|
||||||
assert_item_labels(&pane, ["A", "B", "C", "D*"], cx);
|
assert_item_labels(&pane, ["A", "B", "C", "D*"], cx);
|
||||||
|
|
||||||
pane.update(cx, |pane, cx| pane.activate_item(1, false, false, cx));
|
pane.update(cx, |pane, cx| pane.activate_item(1, false, false, cx));
|
||||||
add_labeled_item(&workspace, &pane, "1", false, cx);
|
add_labeled_item(&pane, "1", false, cx);
|
||||||
assert_item_labels(&pane, ["A", "B", "1*", "C", "D"], cx);
|
assert_item_labels(&pane, ["A", "B", "1*", "C", "D"], cx);
|
||||||
|
|
||||||
pane.update(cx, |pane, cx| pane.close_active_item(&CloseActiveItem, cx))
|
pane.update(cx, |pane, cx| pane.close_active_item(&CloseActiveItem, cx))
|
||||||
|
@ -2442,7 +2322,7 @@ mod tests {
|
||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
set_labeled_items(&workspace, &pane, ["A", "B", "C*", "D", "E"], cx);
|
set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx);
|
||||||
|
|
||||||
pane.update(cx, |pane, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
pane.close_inactive_items(&CloseInactiveItems, cx)
|
pane.close_inactive_items(&CloseInactiveItems, cx)
|
||||||
|
@ -2462,11 +2342,11 @@ mod tests {
|
||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
add_labeled_item(&workspace, &pane, "A", true, cx);
|
add_labeled_item(&pane, "A", true, cx);
|
||||||
add_labeled_item(&workspace, &pane, "B", false, cx);
|
add_labeled_item(&pane, "B", false, cx);
|
||||||
add_labeled_item(&workspace, &pane, "C", true, cx);
|
add_labeled_item(&pane, "C", true, cx);
|
||||||
add_labeled_item(&workspace, &pane, "D", false, cx);
|
add_labeled_item(&pane, "D", false, cx);
|
||||||
add_labeled_item(&workspace, &pane, "E", false, cx);
|
add_labeled_item(&pane, "E", false, cx);
|
||||||
assert_item_labels(&pane, ["A^", "B", "C^", "D", "E*"], cx);
|
assert_item_labels(&pane, ["A^", "B", "C^", "D", "E*"], cx);
|
||||||
|
|
||||||
pane.update(cx, |pane, cx| pane.close_clean_items(&CloseCleanItems, cx))
|
pane.update(cx, |pane, cx| pane.close_clean_items(&CloseCleanItems, cx))
|
||||||
|
@ -2485,7 +2365,7 @@ mod tests {
|
||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
set_labeled_items(&workspace, &pane, ["A", "B", "C*", "D", "E"], cx);
|
set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx);
|
||||||
|
|
||||||
pane.update(cx, |pane, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
pane.close_items_to_the_left(&CloseItemsToTheLeft, cx)
|
pane.close_items_to_the_left(&CloseItemsToTheLeft, cx)
|
||||||
|
@ -2505,7 +2385,7 @@ mod tests {
|
||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
set_labeled_items(&workspace, &pane, ["A", "B", "C*", "D", "E"], cx);
|
set_labeled_items(&pane, ["A", "B", "C*", "D", "E"], cx);
|
||||||
|
|
||||||
pane.update(cx, |pane, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
pane.close_items_to_the_right(&CloseItemsToTheRight, cx)
|
pane.close_items_to_the_right(&CloseItemsToTheRight, cx)
|
||||||
|
@ -2525,9 +2405,9 @@ mod tests {
|
||||||
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
let (_, workspace) = cx.add_window(|cx| Workspace::test_new(project.clone(), cx));
|
||||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||||
|
|
||||||
add_labeled_item(&workspace, &pane, "A", false, cx);
|
add_labeled_item(&pane, "A", false, cx);
|
||||||
add_labeled_item(&workspace, &pane, "B", false, cx);
|
add_labeled_item(&pane, "B", false, cx);
|
||||||
add_labeled_item(&workspace, &pane, "C", false, cx);
|
add_labeled_item(&pane, "C", false, cx);
|
||||||
assert_item_labels(&pane, ["A", "B", "C*"], cx);
|
assert_item_labels(&pane, ["A", "B", "C*"], cx);
|
||||||
|
|
||||||
pane.update(cx, |pane, cx| pane.close_all_items(&CloseAllItems, cx))
|
pane.update(cx, |pane, cx| pane.close_all_items(&CloseAllItems, cx))
|
||||||
|
@ -2546,41 +2426,26 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_labeled_item(
|
fn add_labeled_item(
|
||||||
workspace: &ViewHandle<Workspace>,
|
|
||||||
pane: &ViewHandle<Pane>,
|
pane: &ViewHandle<Pane>,
|
||||||
label: &str,
|
label: &str,
|
||||||
is_dirty: bool,
|
is_dirty: bool,
|
||||||
cx: &mut TestAppContext,
|
cx: &mut TestAppContext,
|
||||||
) -> Box<ViewHandle<TestItem>> {
|
) -> Box<ViewHandle<TestItem>> {
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
let labeled_item =
|
let labeled_item =
|
||||||
Box::new(cx.add_view(|_| TestItem::new().with_label(label).with_dirty(is_dirty)));
|
Box::new(cx.add_view(|_| TestItem::new().with_label(label).with_dirty(is_dirty)));
|
||||||
|
pane.add_item(labeled_item.clone(), false, false, None, cx);
|
||||||
Pane::add_item(
|
|
||||||
workspace,
|
|
||||||
pane,
|
|
||||||
labeled_item.clone(),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
|
|
||||||
labeled_item
|
labeled_item
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_labeled_items<const COUNT: usize>(
|
fn set_labeled_items<const COUNT: usize>(
|
||||||
workspace: &ViewHandle<Workspace>,
|
|
||||||
pane: &ViewHandle<Pane>,
|
pane: &ViewHandle<Pane>,
|
||||||
labels: [&str; COUNT],
|
labels: [&str; COUNT],
|
||||||
cx: &mut TestAppContext,
|
cx: &mut TestAppContext,
|
||||||
) -> [Box<ViewHandle<TestItem>>; COUNT] {
|
) -> [Box<ViewHandle<TestItem>>; COUNT] {
|
||||||
pane.update(cx, |pane, _| {
|
pane.update(cx, |pane, cx| {
|
||||||
pane.items.clear();
|
pane.items.clear();
|
||||||
});
|
|
||||||
|
|
||||||
workspace.update(cx, |workspace, cx| {
|
|
||||||
let mut active_item_index = 0;
|
let mut active_item_index = 0;
|
||||||
|
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
@ -2591,22 +2456,12 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
let labeled_item = Box::new(cx.add_view(|_| TestItem::new().with_label(label)));
|
let labeled_item = Box::new(cx.add_view(|_| TestItem::new().with_label(label)));
|
||||||
Pane::add_item(
|
pane.add_item(labeled_item.clone(), false, false, None, cx);
|
||||||
workspace,
|
|
||||||
pane,
|
|
||||||
labeled_item.clone(),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
index += 1;
|
index += 1;
|
||||||
labeled_item
|
labeled_item
|
||||||
});
|
});
|
||||||
|
|
||||||
pane.update(cx, |pane, cx| {
|
pane.activate_item(active_item_index, false, false, cx);
|
||||||
pane.activate_item(active_item_index, false, false, cx)
|
|
||||||
});
|
|
||||||
|
|
||||||
items
|
items
|
||||||
})
|
})
|
||||||
|
|
|
@ -183,7 +183,7 @@ pub fn handle_dropped_item<V: View>(
|
||||||
.zip(pane.upgrade(cx))
|
.zip(pane.upgrade(cx))
|
||||||
{
|
{
|
||||||
workspace.update(cx, |workspace, cx| {
|
workspace.update(cx, |workspace, cx| {
|
||||||
Pane::move_item(workspace, from, to, item_id, index, cx);
|
workspace.move_item(from, to, item_id, index, cx);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{item::ItemHandle, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId};
|
use crate::{item::ItemHandle, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId};
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use async_recursion::async_recursion;
|
use async_recursion::async_recursion;
|
||||||
use db::sqlez::{
|
use db::sqlez::{
|
||||||
bindable::{Bind, Column, StaticColumnCount},
|
bindable::{Bind, Column, StaticColumnCount},
|
||||||
|
@ -230,7 +230,7 @@ impl SerializedPane {
|
||||||
pub async fn deserialize_to(
|
pub async fn deserialize_to(
|
||||||
&self,
|
&self,
|
||||||
project: &ModelHandle<Project>,
|
project: &ModelHandle<Project>,
|
||||||
pane_handle: &WeakViewHandle<Pane>,
|
pane: &WeakViewHandle<Pane>,
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: WorkspaceId,
|
||||||
workspace: &WeakViewHandle<Workspace>,
|
workspace: &WeakViewHandle<Workspace>,
|
||||||
cx: &mut AsyncAppContext,
|
cx: &mut AsyncAppContext,
|
||||||
|
@ -239,7 +239,7 @@ impl SerializedPane {
|
||||||
let mut active_item_index = None;
|
let mut active_item_index = None;
|
||||||
for (index, item) in self.children.iter().enumerate() {
|
for (index, item) in self.children.iter().enumerate() {
|
||||||
let project = project.clone();
|
let project = project.clone();
|
||||||
let item_handle = pane_handle
|
let item_handle = pane
|
||||||
.update(cx, |_, cx| {
|
.update(cx, |_, cx| {
|
||||||
if let Some(deserializer) = cx.global::<ItemDeserializers>().get(&item.kind) {
|
if let Some(deserializer) = cx.global::<ItemDeserializers>().get(&item.kind) {
|
||||||
deserializer(project, workspace.clone(), workspace_id, item.item_id, cx)
|
deserializer(project, workspace.clone(), workspace_id, item.item_id, cx)
|
||||||
|
@ -256,13 +256,9 @@ impl SerializedPane {
|
||||||
items.push(item_handle.clone());
|
items.push(item_handle.clone());
|
||||||
|
|
||||||
if let Some(item_handle) = item_handle {
|
if let Some(item_handle) = item_handle {
|
||||||
workspace.update(cx, |workspace, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
let pane_handle = pane_handle
|
pane.add_item(item_handle.clone(), true, true, None, cx);
|
||||||
.upgrade(cx)
|
})?;
|
||||||
.ok_or_else(|| anyhow!("pane was dropped"))?;
|
|
||||||
Pane::add_item(workspace, &pane_handle, item_handle, true, true, None, cx);
|
|
||||||
anyhow::Ok(())
|
|
||||||
})??;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.active {
|
if item.active {
|
||||||
|
@ -271,7 +267,7 @@ impl SerializedPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(active_item_index) = active_item_index {
|
if let Some(active_item_index) = active_item_index {
|
||||||
pane_handle.update(cx, |pane, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
pane.activate_item(active_item_index, false, false, cx);
|
pane.activate_item(active_item_index, false, false, cx);
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -583,6 +583,7 @@ impl Workspace {
|
||||||
let center_pane = cx.add_view(|cx| {
|
let center_pane = cx.add_view(|cx| {
|
||||||
Pane::new(
|
Pane::new(
|
||||||
weak_handle.clone(),
|
weak_handle.clone(),
|
||||||
|
project.clone(),
|
||||||
app_state.background_actions,
|
app_state.background_actions,
|
||||||
pane_history_timestamp.clone(),
|
pane_history_timestamp.clone(),
|
||||||
cx,
|
cx,
|
||||||
|
@ -1307,22 +1308,6 @@ impl Workspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn absolute_path(&self, project_path: &ProjectPath, cx: &AppContext) -> Option<PathBuf> {
|
|
||||||
let workspace_root = self
|
|
||||||
.project()
|
|
||||||
.read(cx)
|
|
||||||
.worktree_for_id(project_path.worktree_id, cx)?
|
|
||||||
.read(cx)
|
|
||||||
.abs_path();
|
|
||||||
let project_path = project_path.path.as_ref();
|
|
||||||
|
|
||||||
Some(if project_path == Path::new("") {
|
|
||||||
workspace_root.to_path_buf()
|
|
||||||
} else {
|
|
||||||
workspace_root.join(project_path)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_folder_to_project(&mut self, _: &AddFolderToProject, cx: &mut ViewContext<Self>) {
|
fn add_folder_to_project(&mut self, _: &AddFolderToProject, cx: &mut ViewContext<Self>) {
|
||||||
let mut paths = cx.prompt_for_paths(PathPromptOptions {
|
let mut paths = cx.prompt_for_paths(PathPromptOptions {
|
||||||
files: false,
|
files: false,
|
||||||
|
@ -1588,6 +1573,7 @@ impl Workspace {
|
||||||
let pane = cx.add_view(|cx| {
|
let pane = cx.add_view(|cx| {
|
||||||
Pane::new(
|
Pane::new(
|
||||||
self.weak_handle(),
|
self.weak_handle(),
|
||||||
|
self.project.clone(),
|
||||||
self.app_state.background_actions,
|
self.app_state.background_actions,
|
||||||
self.pane_history_timestamp.clone(),
|
self.pane_history_timestamp.clone(),
|
||||||
cx,
|
cx,
|
||||||
|
@ -1607,7 +1593,7 @@ impl Workspace {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if let Some(center_pane) = self.last_active_center_pane.clone() {
|
if let Some(center_pane) = self.last_active_center_pane.clone() {
|
||||||
if let Some(center_pane) = center_pane.upgrade(cx) {
|
if let Some(center_pane) = center_pane.upgrade(cx) {
|
||||||
Pane::add_item(self, ¢er_pane, item, true, true, None, cx);
|
center_pane.update(cx, |pane, cx| pane.add_item(item, true, true, None, cx));
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -1618,8 +1604,8 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_item(&mut self, item: Box<dyn ItemHandle>, cx: &mut ViewContext<Self>) {
|
pub fn add_item(&mut self, item: Box<dyn ItemHandle>, cx: &mut ViewContext<Self>) {
|
||||||
let active_pane = self.active_pane().clone();
|
self.active_pane
|
||||||
Pane::add_item(self, &active_pane, item, true, true, None, cx);
|
.update(cx, |pane, cx| pane.add_item(item, true, true, None, cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_abs_path(
|
pub fn open_abs_path(
|
||||||
|
@ -1669,13 +1655,10 @@ impl Workspace {
|
||||||
});
|
});
|
||||||
|
|
||||||
let task = self.load_path(path.into(), cx);
|
let task = self.load_path(path.into(), cx);
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|_, mut cx| async move {
|
||||||
let (project_entry_id, build_item) = task.await?;
|
let (project_entry_id, build_item) = task.await?;
|
||||||
let pane = pane
|
pane.update(&mut cx, |pane, cx| {
|
||||||
.upgrade(&cx)
|
pane.open_item(project_entry_id, focus_item, cx, build_item)
|
||||||
.ok_or_else(|| anyhow!("pane was closed"))?;
|
|
||||||
this.update(&mut cx, |this, cx| {
|
|
||||||
Pane::open_item(this, pane, project_entry_id, focus_item, cx, build_item)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1732,8 +1715,9 @@ impl Workspace {
|
||||||
|
|
||||||
pub fn open_shared_screen(&mut self, peer_id: PeerId, cx: &mut ViewContext<Self>) {
|
pub fn open_shared_screen(&mut self, peer_id: PeerId, cx: &mut ViewContext<Self>) {
|
||||||
if let Some(shared_screen) = self.shared_screen_for_peer(peer_id, &self.active_pane, cx) {
|
if let Some(shared_screen) = self.shared_screen_for_peer(peer_id, &self.active_pane, cx) {
|
||||||
let pane = self.active_pane.clone();
|
self.active_pane.update(cx, |pane, cx| {
|
||||||
Pane::add_item(self, &pane, Box::new(shared_screen), false, true, None, cx);
|
pane.add_item(Box::new(shared_screen), false, true, None, cx)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1874,7 +1858,7 @@ impl Workspace {
|
||||||
let item = pane.read(cx).active_item()?;
|
let item = pane.read(cx).active_item()?;
|
||||||
let maybe_pane_handle = if let Some(clone) = item.clone_on_split(self.database_id(), cx) {
|
let maybe_pane_handle = if let Some(clone) = item.clone_on_split(self.database_id(), cx) {
|
||||||
let new_pane = self.add_pane(cx);
|
let new_pane = self.add_pane(cx);
|
||||||
Pane::add_item(self, &new_pane, clone, true, true, None, cx);
|
new_pane.update(cx, |pane, cx| pane.add_item(clone, true, true, None, cx));
|
||||||
self.center.split(&pane, &new_pane, direction).unwrap();
|
self.center.split(&pane, &new_pane, direction).unwrap();
|
||||||
Some(new_pane)
|
Some(new_pane)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1896,7 +1880,7 @@ impl Workspace {
|
||||||
let Some(from) = from.upgrade(cx) else { return; };
|
let Some(from) = from.upgrade(cx) else { return; };
|
||||||
|
|
||||||
let new_pane = self.add_pane(cx);
|
let new_pane = self.add_pane(cx);
|
||||||
Pane::move_item(self, from.clone(), new_pane.clone(), item_id_to_move, 0, cx);
|
self.move_item(from.clone(), new_pane.clone(), item_id_to_move, 0, cx);
|
||||||
self.center
|
self.center
|
||||||
.split(&pane_to_split, &new_pane, split_direction)
|
.split(&pane_to_split, &new_pane, split_direction)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1924,6 +1908,41 @@ impl Workspace {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_item(
|
||||||
|
&mut self,
|
||||||
|
source: ViewHandle<Pane>,
|
||||||
|
destination: ViewHandle<Pane>,
|
||||||
|
item_id_to_move: usize,
|
||||||
|
destination_index: usize,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
let item_to_move = source
|
||||||
|
.read(cx)
|
||||||
|
.items()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_, item_handle)| item_handle.id() == item_id_to_move);
|
||||||
|
|
||||||
|
if item_to_move.is_none() {
|
||||||
|
log::warn!("Tried to move item handle which was not in `from` pane. Maybe tab was closed during drop");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let (item_ix, item_handle) = item_to_move.unwrap();
|
||||||
|
let item_handle = item_handle.clone();
|
||||||
|
|
||||||
|
if source != destination {
|
||||||
|
// Close item from previous pane
|
||||||
|
source.update(cx, |source, cx| {
|
||||||
|
source.remove_item(item_ix, false, cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// This automatically removes duplicate items in the pane
|
||||||
|
destination.update(cx, |destination, cx| {
|
||||||
|
destination.add_item(item_handle, true, true, Some(destination_index), cx);
|
||||||
|
cx.focus_self();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn remove_pane(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) {
|
fn remove_pane(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) {
|
||||||
if self.center.remove(&pane).unwrap() {
|
if self.center.remove(&pane).unwrap() {
|
||||||
self.force_remove_pane(&pane, cx);
|
self.force_remove_pane(&pane, cx);
|
||||||
|
@ -2527,7 +2546,9 @@ impl Workspace {
|
||||||
if let Some(index) = pane.update(cx, |pane, _| pane.index_for_item(item.as_ref())) {
|
if let Some(index) = pane.update(cx, |pane, _| pane.index_for_item(item.as_ref())) {
|
||||||
pane.update(cx, |pane, cx| pane.activate_item(index, false, false, cx));
|
pane.update(cx, |pane, cx| pane.activate_item(index, false, false, cx));
|
||||||
} else {
|
} else {
|
||||||
Pane::add_item(self, &pane, item.boxed_clone(), false, false, None, cx);
|
pane.update(cx, |pane, cx| {
|
||||||
|
pane.add_item(item.boxed_clone(), false, false, None, cx)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if pane_was_focused {
|
if pane_was_focused {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue