mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-29 22:42:17 +03:00
Start laying the foundation for a per-pane navigation system
This commit is contained in:
parent
cd0d1d3340
commit
bbf634f439
@ -41,6 +41,7 @@ use std::{
|
|||||||
iter::{self, FromIterator},
|
iter::{self, FromIterator},
|
||||||
mem,
|
mem,
|
||||||
ops::{Deref, Range, RangeInclusive, Sub},
|
ops::{Deref, Range, RangeInclusive, Sub},
|
||||||
|
rc::Rc,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
@ -48,7 +49,7 @@ use sum_tree::Bias;
|
|||||||
use text::rope::TextDimension;
|
use text::rope::TextDimension;
|
||||||
use theme::{DiagnosticStyle, EditorStyle};
|
use theme::{DiagnosticStyle, EditorStyle};
|
||||||
use util::post_inc;
|
use util::post_inc;
|
||||||
use workspace::{PathOpener, Workspace};
|
use workspace::{Navigation, PathOpener, Workspace};
|
||||||
|
|
||||||
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
|
||||||
const MAX_LINE_LEN: usize = 1024;
|
const MAX_LINE_LEN: usize = 1024;
|
||||||
@ -377,6 +378,7 @@ pub struct Editor {
|
|||||||
mode: EditorMode,
|
mode: EditorMode,
|
||||||
placeholder_text: Option<Arc<str>>,
|
placeholder_text: Option<Arc<str>>,
|
||||||
highlighted_rows: Option<Range<u32>>,
|
highlighted_rows: Option<Range<u32>>,
|
||||||
|
navigation: Option<Rc<Navigation>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EditorSnapshot {
|
pub struct EditorSnapshot {
|
||||||
@ -457,6 +459,7 @@ impl Editor {
|
|||||||
let mut clone = Self::new(self.buffer.clone(), self.build_settings.clone(), cx);
|
let mut clone = Self::new(self.buffer.clone(), self.build_settings.clone(), cx);
|
||||||
clone.scroll_position = self.scroll_position;
|
clone.scroll_position = self.scroll_position;
|
||||||
clone.scroll_top_anchor = self.scroll_top_anchor.clone();
|
clone.scroll_top_anchor = self.scroll_top_anchor.clone();
|
||||||
|
clone.navigation = self.navigation.clone();
|
||||||
clone
|
clone
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,6 +509,7 @@ impl Editor {
|
|||||||
mode: EditorMode::Full,
|
mode: EditorMode::Full,
|
||||||
placeholder_text: None,
|
placeholder_text: None,
|
||||||
highlighted_rows: None,
|
highlighted_rows: None,
|
||||||
|
navigation: None,
|
||||||
};
|
};
|
||||||
let selection = Selection {
|
let selection = Selection {
|
||||||
id: post_inc(&mut this.next_selection_id),
|
id: post_inc(&mut this.next_selection_id),
|
||||||
|
@ -10,11 +10,12 @@ use postage::watch;
|
|||||||
use project::{File, ProjectPath, Worktree};
|
use project::{File, ProjectPath, Worktree};
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::rc::Rc;
|
||||||
use text::{Point, Selection};
|
use text::{Point, Selection};
|
||||||
use util::TryFutureExt;
|
use util::TryFutureExt;
|
||||||
use workspace::{
|
use workspace::{
|
||||||
ItemHandle, ItemView, ItemViewHandle, PathOpener, Settings, StatusItemView, WeakItemHandle,
|
ItemHandle, ItemView, ItemViewHandle, Navigation, PathOpener, Settings, StatusItemView,
|
||||||
Workspace,
|
WeakItemHandle, Workspace,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct BufferOpener;
|
pub struct BufferOpener;
|
||||||
@ -46,16 +47,19 @@ impl ItemHandle for BufferItemHandle {
|
|||||||
&self,
|
&self,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
workspace: &Workspace,
|
workspace: &Workspace,
|
||||||
|
navigation: Rc<Navigation>,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
) -> Box<dyn ItemViewHandle> {
|
) -> Box<dyn ItemViewHandle> {
|
||||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(self.0.clone(), cx));
|
let buffer = cx.add_model(|cx| MultiBuffer::singleton(self.0.clone(), cx));
|
||||||
let weak_buffer = buffer.downgrade();
|
let weak_buffer = buffer.downgrade();
|
||||||
Box::new(cx.add_view(window_id, |cx| {
|
Box::new(cx.add_view(window_id, |cx| {
|
||||||
Editor::for_buffer(
|
let mut editor = Editor::for_buffer(
|
||||||
buffer,
|
buffer,
|
||||||
crate::settings_builder(weak_buffer, workspace.settings()),
|
crate::settings_builder(weak_buffer, workspace.settings()),
|
||||||
cx,
|
cx,
|
||||||
)
|
);
|
||||||
|
editor.navigation = Some(navigation);
|
||||||
|
editor
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +133,12 @@ impl ItemView for Editor {
|
|||||||
Some(self.clone(cx))
|
Some(self.clone(cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn activated(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
|
if let Some(navigation) = self.navigation.as_ref() {
|
||||||
|
navigation.push::<(), _>(None, cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_dirty(&self, cx: &AppContext) -> bool {
|
fn is_dirty(&self, cx: &AppContext) -> bool {
|
||||||
self.buffer().read(cx).read(cx).is_dirty()
|
self.buffer().read(cx).read(cx).is_dirty()
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "workspace"
|
name = "workspace"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "src/workspace.rs"
|
path = "src/workspace.rs"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::{ItemViewHandle, SplitDirection};
|
use super::{ItemViewHandle, SplitDirection};
|
||||||
use crate::{ItemHandle, Settings, Workspace};
|
use crate::{ItemHandle, ItemView, Settings, WeakItemViewHandle, Workspace};
|
||||||
|
use collections::HashMap;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
action,
|
action,
|
||||||
elements::*,
|
elements::*,
|
||||||
@ -9,7 +10,8 @@ use gpui::{
|
|||||||
Entity, MutableAppContext, Quad, RenderContext, View, ViewContext,
|
Entity, MutableAppContext, Quad, RenderContext, View, ViewContext,
|
||||||
};
|
};
|
||||||
use postage::watch;
|
use postage::watch;
|
||||||
use std::cmp;
|
use project::ProjectPath;
|
||||||
|
use std::{any::Any, cell::RefCell, cmp, rc::Rc};
|
||||||
|
|
||||||
action!(Split, SplitDirection);
|
action!(Split, SplitDirection);
|
||||||
action!(ActivateItem, usize);
|
action!(ActivateItem, usize);
|
||||||
@ -17,6 +19,8 @@ action!(ActivatePrevItem);
|
|||||||
action!(ActivateNextItem);
|
action!(ActivateNextItem);
|
||||||
action!(CloseActiveItem);
|
action!(CloseActiveItem);
|
||||||
action!(CloseItem, usize);
|
action!(CloseItem, usize);
|
||||||
|
action!(GoBack);
|
||||||
|
action!(GoForward);
|
||||||
|
|
||||||
pub fn init(cx: &mut MutableAppContext) {
|
pub fn init(cx: &mut MutableAppContext) {
|
||||||
cx.add_action(|pane: &mut Pane, action: &ActivateItem, cx| {
|
cx.add_action(|pane: &mut Pane, action: &ActivateItem, cx| {
|
||||||
@ -37,6 +41,8 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||||||
cx.add_action(|pane: &mut Pane, action: &Split, cx| {
|
cx.add_action(|pane: &mut Pane, action: &Split, cx| {
|
||||||
pane.split(action.0, cx);
|
pane.split(action.0, cx);
|
||||||
});
|
});
|
||||||
|
cx.add_action(Pane::go_back);
|
||||||
|
cx.add_action(Pane::go_forward);
|
||||||
|
|
||||||
cx.add_bindings(vec![
|
cx.add_bindings(vec![
|
||||||
Binding::new("shift-cmd-{", ActivatePrevItem, Some("Pane")),
|
Binding::new("shift-cmd-{", ActivatePrevItem, Some("Pane")),
|
||||||
@ -46,6 +52,8 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||||||
Binding::new("cmd-k down", Split(SplitDirection::Down), Some("Pane")),
|
Binding::new("cmd-k down", Split(SplitDirection::Down), Some("Pane")),
|
||||||
Binding::new("cmd-k left", Split(SplitDirection::Left), Some("Pane")),
|
Binding::new("cmd-k left", Split(SplitDirection::Left), Some("Pane")),
|
||||||
Binding::new("cmd-k right", Split(SplitDirection::Right), Some("Pane")),
|
Binding::new("cmd-k right", Split(SplitDirection::Right), Some("Pane")),
|
||||||
|
Binding::new("ctrl-", GoBack, Some("Pane")),
|
||||||
|
Binding::new("ctrl-shift-_", GoForward, Some("Pane")),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +69,22 @@ pub struct Pane {
|
|||||||
item_views: Vec<(usize, Box<dyn ItemViewHandle>)>,
|
item_views: Vec<(usize, Box<dyn ItemViewHandle>)>,
|
||||||
active_item: usize,
|
active_item: usize,
|
||||||
settings: watch::Receiver<Settings>,
|
settings: watch::Receiver<Settings>,
|
||||||
|
navigation: Rc<Navigation>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Navigation(RefCell<NavigationHistory>);
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct NavigationHistory {
|
||||||
|
backward_stack: Vec<NavigationEntry>,
|
||||||
|
forward_stack: Vec<NavigationEntry>,
|
||||||
|
paths_by_item: HashMap<usize, ProjectPath>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NavigationEntry {
|
||||||
|
item_view: Box<dyn WeakItemViewHandle>,
|
||||||
|
data: Option<Box<dyn Any>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pane {
|
impl Pane {
|
||||||
@ -69,6 +93,7 @@ impl Pane {
|
|||||||
item_views: Vec::new(),
|
item_views: Vec::new(),
|
||||||
active_item: 0,
|
active_item: 0,
|
||||||
settings,
|
settings,
|
||||||
|
navigation: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +101,16 @@ impl Pane {
|
|||||||
cx.emit(Event::Activate);
|
cx.emit(Event::Activate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn go_back(&mut self, _: &GoBack, cx: &mut ViewContext<Self>) {
|
||||||
|
let mut navigation = self.navigation.0.borrow_mut();
|
||||||
|
if let Some(entry) = navigation.go_back() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn go_forward(&mut self, _: &GoForward, cx: &mut ViewContext<Self>) {
|
||||||
|
let mut navigation = self.navigation.0.borrow_mut();
|
||||||
|
if let Some(entry) = navigation.go_forward() {}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn open_item<T>(
|
pub fn open_item<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
item_handle: T,
|
item_handle: T,
|
||||||
@ -93,14 +128,15 @@ impl Pane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let item_view = item_handle.add_view(cx.window_id(), workspace, cx);
|
let item_view =
|
||||||
|
item_handle.add_view(cx.window_id(), workspace, self.navigation.clone(), cx);
|
||||||
self.add_item_view(item_view.boxed_clone(), cx);
|
self.add_item_view(item_view.boxed_clone(), cx);
|
||||||
item_view
|
item_view
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_item_view(
|
pub fn add_item_view(
|
||||||
&mut self,
|
&mut self,
|
||||||
item_view: Box<dyn ItemViewHandle>,
|
mut item_view: Box<dyn ItemViewHandle>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
item_view.added_to_pane(cx);
|
item_view.added_to_pane(cx);
|
||||||
@ -142,6 +178,7 @@ impl Pane {
|
|||||||
if index < self.item_views.len() {
|
if index < self.item_views.len() {
|
||||||
self.active_item = index;
|
self.active_item = index;
|
||||||
self.focus_active_item(cx);
|
self.focus_active_item(cx);
|
||||||
|
self.item_views[index].1.activated(cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,8 +209,21 @@ impl Pane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_item(&mut self, item_id: usize, cx: &mut ViewContext<Self>) {
|
pub fn close_item(&mut self, item_view_id: usize, cx: &mut ViewContext<Self>) {
|
||||||
self.item_views.retain(|(_, item)| item.id() != item_id);
|
self.item_views.retain(|(item_id, item)| {
|
||||||
|
if item.id() == item_view_id {
|
||||||
|
let mut navigation = self.navigation.0.borrow_mut();
|
||||||
|
if let Some(path) = item.project_path(cx) {
|
||||||
|
navigation.paths_by_item.insert(*item_id, path);
|
||||||
|
} else {
|
||||||
|
navigation.paths_by_item.remove(item_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
self.active_item = cmp::min(self.active_item, self.item_views.len().saturating_sub(1));
|
self.active_item = cmp::min(self.active_item, self.item_views.len().saturating_sub(1));
|
||||||
if self.item_views.is_empty() {
|
if self.item_views.is_empty() {
|
||||||
cx.emit(Event::Remove);
|
cx.emit(Event::Remove);
|
||||||
@ -369,3 +419,33 @@ impl View for Pane {
|
|||||||
self.focus_active_item(cx);
|
self.focus_active_item(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Navigation {
|
||||||
|
pub fn push<D: 'static + Any, T: ItemView>(&self, data: Option<D>, cx: &mut ViewContext<T>) {
|
||||||
|
let mut state = self.0.borrow_mut();
|
||||||
|
state.backward_stack.push(NavigationEntry {
|
||||||
|
item_view: Box::new(cx.weak_handle()),
|
||||||
|
data: data.map(|data| Box::new(data) as Box<dyn Any>),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NavigationHistory {
|
||||||
|
fn go_back(&mut self) -> Option<&NavigationEntry> {
|
||||||
|
if let Some(backward) = self.backward_stack.pop() {
|
||||||
|
self.forward_stack.push(backward);
|
||||||
|
self.forward_stack.last()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn go_forward(&mut self) -> Option<&NavigationEntry> {
|
||||||
|
if let Some(forward) = self.forward_stack.pop() {
|
||||||
|
self.backward_stack.push(forward);
|
||||||
|
self.backward_stack.last()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -36,6 +36,7 @@ use std::{
|
|||||||
future::Future,
|
future::Future,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
rc::Rc,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use theme::{Theme, ThemeRegistry};
|
use theme::{Theme, ThemeRegistry};
|
||||||
@ -135,6 +136,7 @@ pub trait Item: Entity + Sized {
|
|||||||
fn build_view(
|
fn build_view(
|
||||||
handle: ModelHandle<Self>,
|
handle: ModelHandle<Self>,
|
||||||
workspace: &Workspace,
|
workspace: &Workspace,
|
||||||
|
navigation: Rc<Navigation>,
|
||||||
cx: &mut ViewContext<Self::View>,
|
cx: &mut ViewContext<Self::View>,
|
||||||
) -> Self::View;
|
) -> Self::View;
|
||||||
|
|
||||||
@ -144,6 +146,8 @@ pub trait Item: Entity + Sized {
|
|||||||
pub trait ItemView: View {
|
pub trait ItemView: View {
|
||||||
type ItemHandle: ItemHandle;
|
type ItemHandle: ItemHandle;
|
||||||
|
|
||||||
|
fn added_to_pane(&mut self, _: Rc<Navigation>, _: &mut ViewContext<Self>) {}
|
||||||
|
fn activated(&mut self, _: &mut ViewContext<Self>) {}
|
||||||
fn item_handle(&self, cx: &AppContext) -> Self::ItemHandle;
|
fn item_handle(&self, cx: &AppContext) -> Self::ItemHandle;
|
||||||
fn title(&self, cx: &AppContext) -> String;
|
fn title(&self, cx: &AppContext) -> String;
|
||||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
|
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
|
||||||
@ -185,6 +189,7 @@ pub trait ItemHandle: Send + Sync {
|
|||||||
&self,
|
&self,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
workspace: &Workspace,
|
workspace: &Workspace,
|
||||||
|
navigation: Rc<Navigation>,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
) -> Box<dyn ItemViewHandle>;
|
) -> Box<dyn ItemViewHandle>;
|
||||||
fn boxed_clone(&self) -> Box<dyn ItemHandle>;
|
fn boxed_clone(&self) -> Box<dyn ItemHandle>;
|
||||||
@ -204,7 +209,8 @@ pub trait ItemViewHandle {
|
|||||||
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
|
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;
|
||||||
fn boxed_clone(&self) -> Box<dyn ItemViewHandle>;
|
fn boxed_clone(&self) -> Box<dyn ItemViewHandle>;
|
||||||
fn clone_on_split(&self, cx: &mut MutableAppContext) -> Option<Box<dyn ItemViewHandle>>;
|
fn clone_on_split(&self, cx: &mut MutableAppContext) -> Option<Box<dyn ItemViewHandle>>;
|
||||||
fn added_to_pane(&self, cx: &mut ViewContext<Pane>);
|
fn added_to_pane(&mut self, cx: &mut ViewContext<Pane>);
|
||||||
|
fn activated(&mut self, cx: &mut MutableAppContext);
|
||||||
fn id(&self) -> usize;
|
fn id(&self) -> usize;
|
||||||
fn to_any(&self) -> AnyViewHandle;
|
fn to_any(&self) -> AnyViewHandle;
|
||||||
fn is_dirty(&self, cx: &AppContext) -> bool;
|
fn is_dirty(&self, cx: &AppContext) -> bool;
|
||||||
@ -220,6 +226,10 @@ pub trait ItemViewHandle {
|
|||||||
) -> Task<anyhow::Result<()>>;
|
) -> Task<anyhow::Result<()>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait WeakItemViewHandle {
|
||||||
|
fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn ItemViewHandle>>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Item> ItemHandle for ModelHandle<T> {
|
impl<T: Item> ItemHandle for ModelHandle<T> {
|
||||||
fn id(&self) -> usize {
|
fn id(&self) -> usize {
|
||||||
self.id()
|
self.id()
|
||||||
@ -229,9 +239,12 @@ impl<T: Item> ItemHandle for ModelHandle<T> {
|
|||||||
&self,
|
&self,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
workspace: &Workspace,
|
workspace: &Workspace,
|
||||||
|
navigation: Rc<Navigation>,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
) -> Box<dyn ItemViewHandle> {
|
) -> Box<dyn ItemViewHandle> {
|
||||||
Box::new(cx.add_view(window_id, |cx| T::build_view(self.clone(), workspace, cx)))
|
Box::new(cx.add_view(window_id, |cx| {
|
||||||
|
T::build_view(self.clone(), workspace, navigation, cx)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boxed_clone(&self) -> Box<dyn ItemHandle> {
|
fn boxed_clone(&self) -> Box<dyn ItemHandle> {
|
||||||
@ -260,9 +273,10 @@ impl ItemHandle for Box<dyn ItemHandle> {
|
|||||||
&self,
|
&self,
|
||||||
window_id: usize,
|
window_id: usize,
|
||||||
workspace: &Workspace,
|
workspace: &Workspace,
|
||||||
|
navigation: Rc<Navigation>,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
) -> Box<dyn ItemViewHandle> {
|
) -> Box<dyn ItemViewHandle> {
|
||||||
ItemHandle::add_view(self.as_ref(), window_id, workspace, cx)
|
ItemHandle::add_view(self.as_ref(), window_id, workspace, navigation, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boxed_clone(&self) -> Box<dyn ItemHandle> {
|
fn boxed_clone(&self) -> Box<dyn ItemHandle> {
|
||||||
@ -330,7 +344,7 @@ impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
|
|||||||
.map(|handle| Box::new(handle) as Box<dyn ItemViewHandle>)
|
.map(|handle| Box::new(handle) as Box<dyn ItemViewHandle>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn added_to_pane(&self, cx: &mut ViewContext<Pane>) {
|
fn added_to_pane(&mut self, cx: &mut ViewContext<Pane>) {
|
||||||
cx.subscribe(self, |pane, item, event, cx| {
|
cx.subscribe(self, |pane, item, event, cx| {
|
||||||
if T::should_close_item_on_event(event) {
|
if T::should_close_item_on_event(event) {
|
||||||
pane.close_item(item.id(), cx);
|
pane.close_item(item.id(), cx);
|
||||||
@ -349,6 +363,10 @@ impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
|
|||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn activated(&mut self, cx: &mut MutableAppContext) {
|
||||||
|
self.update(cx, |this, cx| this.activated(cx));
|
||||||
|
}
|
||||||
|
|
||||||
fn save(&self, cx: &mut MutableAppContext) -> Result<Task<Result<()>>> {
|
fn save(&self, cx: &mut MutableAppContext) -> Result<Task<Result<()>>> {
|
||||||
self.update(cx, |item, cx| item.save(cx))
|
self.update(cx, |item, cx| item.save(cx))
|
||||||
}
|
}
|
||||||
@ -399,6 +417,13 @@ impl Clone for Box<dyn ItemHandle> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ItemView> WeakItemViewHandle for WeakViewHandle<T> {
|
||||||
|
fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn ItemViewHandle>> {
|
||||||
|
self.upgrade(cx)
|
||||||
|
.map(|v| Box::new(v) as Box<dyn ItemViewHandle>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WorkspaceParams {
|
pub struct WorkspaceParams {
|
||||||
pub project: ModelHandle<Project>,
|
pub project: ModelHandle<Project>,
|
||||||
|
Loading…
Reference in New Issue
Block a user