mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-07 20:39:04 +03:00
Tabs n splits (#3340)
Adds back: - [x] Tab clicking - [x] Splits ~ - [x] Workspace deserialization Also adds a new `FocusableView` API to GPUI Release Notes: - N/A
This commit is contained in:
commit
c8f83e2d4d
@ -204,6 +204,9 @@ core-graphics = { git = "https://github.com/servo/core-foundation-rs", rev = "07
|
||||
[profile.dev]
|
||||
split-debuginfo = "unpacked"
|
||||
|
||||
[profile.dev.package.taffy]
|
||||
opt-level = 3
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
lto = "thin"
|
||||
|
@ -220,7 +220,6 @@ impl TestServer {
|
||||
languages: Arc::new(language_registry),
|
||||
fs: fs.clone(),
|
||||
build_window_options: |_, _, _| Default::default(),
|
||||
initialize_workspace: |_, _, _, _| gpui::Task::ready(Ok(())),
|
||||
node_runtime: FakeNodeRuntime::new(),
|
||||
});
|
||||
|
||||
|
@ -153,17 +153,20 @@ actions!(
|
||||
// channel_id: ChannelId,
|
||||
// }
|
||||
|
||||
// const COLLABORATION_PANEL_KEY: &'static str = "CollaborationPanel";
|
||||
const COLLABORATION_PANEL_KEY: &'static str = "CollaborationPanel";
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use gpui::{
|
||||
actions, div, AppContext, AsyncWindowContext, Div, EventEmitter, FocusHandle, Focusable,
|
||||
InteractiveComponent, ParentComponent, Render, Task, View, ViewContext, VisualContext,
|
||||
WeakView,
|
||||
actions, div, serde_json, AppContext, AsyncWindowContext, Div, EventEmitter, FocusHandle,
|
||||
Focusable, FocusableView, InteractiveComponent, ParentComponent, Render, View, ViewContext,
|
||||
VisualContext, WeakView,
|
||||
};
|
||||
use project::Fs;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use settings::Settings;
|
||||
use util::ResultExt;
|
||||
use workspace::{
|
||||
dock::{DockPosition, Panel, PanelEvent},
|
||||
Workspace,
|
||||
@ -317,11 +320,11 @@ pub struct CollabPanel {
|
||||
// Channel(ChannelId),
|
||||
// }
|
||||
|
||||
// #[derive(Serialize, Deserialize)]
|
||||
// struct SerializedCollabPanel {
|
||||
// width: Option<f32>,
|
||||
// collapsed_channels: Option<Vec<ChannelId>>,
|
||||
// }
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct SerializedCollabPanel {
|
||||
width: Option<f32>,
|
||||
collapsed_channels: Option<Vec<u64>>,
|
||||
}
|
||||
|
||||
// #[derive(Debug)]
|
||||
// pub enum Event {
|
||||
@ -660,43 +663,34 @@ impl CollabPanel {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn load(
|
||||
pub async fn load(
|
||||
workspace: WeakView<Workspace>,
|
||||
cx: AsyncWindowContext,
|
||||
) -> Task<anyhow::Result<View<Self>>> {
|
||||
cx.spawn(|mut cx| async move {
|
||||
// todo!()
|
||||
// let serialized_panel = if let Some(panel) = cx
|
||||
// .background()
|
||||
// .spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
|
||||
// .await
|
||||
// .log_err()
|
||||
// .flatten()
|
||||
// {
|
||||
// match serde_json::from_str::<SerializedCollabPanel>(&panel) {
|
||||
// Ok(panel) => Some(panel),
|
||||
// Err(err) => {
|
||||
// log::error!("Failed to deserialize collaboration panel: {}", err);
|
||||
// None
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// None
|
||||
// };
|
||||
mut cx: AsyncWindowContext,
|
||||
) -> anyhow::Result<View<Self>> {
|
||||
let serialized_panel = cx
|
||||
.background_executor()
|
||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
|
||||
.await
|
||||
.map_err(|_| anyhow::anyhow!("Failed to read collaboration panel from key value store"))
|
||||
.log_err()
|
||||
.flatten()
|
||||
.map(|panel| serde_json::from_str::<SerializedCollabPanel>(&panel))
|
||||
.transpose()
|
||||
.log_err()
|
||||
.flatten();
|
||||
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
let panel = CollabPanel::new(workspace, cx);
|
||||
// if let Some(serialized_panel) = serialized_panel {
|
||||
// panel.update(cx, |panel, cx| {
|
||||
// panel.width = serialized_panel.width;
|
||||
// panel.collapsed_channels = serialized_panel
|
||||
// .collapsed_channels
|
||||
// .unwrap_or_else(|| Vec::new());
|
||||
// cx.notify();
|
||||
// });
|
||||
// }
|
||||
panel
|
||||
})
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
let panel = CollabPanel::new(workspace, cx);
|
||||
if let Some(serialized_panel) = serialized_panel {
|
||||
panel.update(cx, |panel, cx| {
|
||||
panel.width = serialized_panel.width;
|
||||
// panel.collapsed_channels = serialized_panel
|
||||
// .collapsed_channels
|
||||
// .unwrap_or_else(|| Vec::new());
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
panel
|
||||
})
|
||||
}
|
||||
|
||||
@ -3454,11 +3448,13 @@ impl Panel for CollabPanel {
|
||||
self.focus_handle.contains_focused(cx)
|
||||
}
|
||||
|
||||
fn persistent_name(&self) -> &'static str {
|
||||
"Collaboration Panel"
|
||||
fn persistent_name() -> &'static str {
|
||||
"CollabPanel"
|
||||
}
|
||||
}
|
||||
|
||||
fn focus_handle(&self, _cx: &ui::prelude::WindowContext) -> gpui::FocusHandle {
|
||||
impl FocusableView for CollabPanel {
|
||||
fn focus_handle(&self, _cx: &AppContext) -> gpui::FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
@ -41,8 +41,8 @@ use git::diff_hunk_to_display;
|
||||
use gpui::{
|
||||
action, actions, div, point, prelude::*, px, relative, rems, size, uniform_list, AnyElement,
|
||||
AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Component, Context,
|
||||
EventEmitter, FocusHandle, FontFeatures, FontStyle, FontWeight, HighlightStyle, Hsla,
|
||||
InputHandler, KeyContext, Model, MouseButton, ParentComponent, Pixels, Render, Styled,
|
||||
EventEmitter, FocusHandle, FocusableView, FontFeatures, FontStyle, FontWeight, HighlightStyle,
|
||||
Hsla, InputHandler, KeyContext, Model, MouseButton, ParentComponent, Pixels, Render, Styled,
|
||||
Subscription, Task, TextStyle, UniformListScrollHandle, View, ViewContext, VisualContext,
|
||||
WeakView, WindowContext,
|
||||
};
|
||||
@ -9367,6 +9367,12 @@ pub struct EditorReleased(pub WeakView<Editor>);
|
||||
//
|
||||
impl EventEmitter<Event> for Editor {}
|
||||
|
||||
impl FocusableView for Editor {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for Editor {
|
||||
type Element = EditorElement;
|
||||
|
||||
|
@ -527,10 +527,6 @@ fn deserialize_anchor(buffer: &MultiBufferSnapshot, anchor: proto::EditorAnchor)
|
||||
}
|
||||
|
||||
impl Item for Editor {
|
||||
fn focus_handle(&self) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
|
||||
fn navigate(&mut self, data: Box<dyn std::any::Any>, cx: &mut ViewContext<Self>) -> bool {
|
||||
todo!();
|
||||
// if let Ok(data) = data.downcast::<NavigationData>() {
|
||||
|
@ -68,7 +68,7 @@ pub trait Action: std::fmt::Debug + 'static {
|
||||
// Types become actions by satisfying a list of trait bounds.
|
||||
impl<A> Action for A
|
||||
where
|
||||
A: for<'a> Deserialize<'a> + PartialEq + Clone + Default + std::fmt::Debug + 'static,
|
||||
A: for<'a> Deserialize<'a> + PartialEq + Default + Clone + std::fmt::Debug + 'static,
|
||||
{
|
||||
fn qualified_name() -> SharedString {
|
||||
let name = type_name::<A>();
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
AnyView, AnyWindowHandle, AppCell, AppContext, BackgroundExecutor, Context, ForegroundExecutor,
|
||||
Model, ModelContext, Render, Result, Task, View, ViewContext, VisualContext, WindowContext,
|
||||
WindowHandle,
|
||||
AnyView, AnyWindowHandle, AppCell, AppContext, BackgroundExecutor, Context, FocusableView,
|
||||
ForegroundExecutor, Model, ModelContext, Render, Result, Task, View, ViewContext,
|
||||
VisualContext, WindowContext, WindowHandle,
|
||||
};
|
||||
use anyhow::{anyhow, Context as _};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
@ -307,4 +307,13 @@ impl VisualContext for AsyncWindowContext {
|
||||
self.window
|
||||
.update(self, |_, cx| cx.replace_root_view(build_view))
|
||||
}
|
||||
|
||||
fn focus_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
|
||||
where
|
||||
V: FocusableView,
|
||||
{
|
||||
self.window.update(self, |_, cx| {
|
||||
view.read(cx).focus_handle(cx).clone().focus(cx);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ impl EntityMap {
|
||||
}
|
||||
|
||||
/// Move an entity to the stack.
|
||||
#[track_caller]
|
||||
pub fn lease<'a, T>(&mut self, model: &'a Model<T>) -> Lease<'a, T> {
|
||||
self.assert_valid_context(model);
|
||||
let entity = Some(
|
||||
|
@ -562,6 +562,14 @@ impl<'a> VisualContext for VisualTestContext<'a> {
|
||||
.update(self.cx, |_, cx| cx.replace_root_view(build_view))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn focus_view<V: crate::FocusableView>(&mut self, view: &View<V>) -> Self::Result<()> {
|
||||
self.window
|
||||
.update(self.cx, |_, cx| {
|
||||
view.read(cx).focus_handle(cx).clone().focus(cx)
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl AnyWindowHandle {
|
||||
|
@ -135,6 +135,10 @@ pub trait VisualContext: Context {
|
||||
) -> Self::Result<View<V>>
|
||||
where
|
||||
V: Render;
|
||||
|
||||
fn focus_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
|
||||
where
|
||||
V: FocusableView;
|
||||
}
|
||||
|
||||
pub trait Entity<T>: Sealed {
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
private::Sealed, AnyBox, AnyElement, AnyModel, AnyWeakModel, AppContext, AvailableSpace,
|
||||
BorrowWindow, Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, LayoutId,
|
||||
Model, Pixels, Point, Size, ViewContext, VisualContext, WeakModel, WindowContext,
|
||||
BorrowWindow, Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, FocusHandle,
|
||||
FocusableView, LayoutId, Model, Pixels, Point, Size, ViewContext, VisualContext, WeakModel,
|
||||
WindowContext,
|
||||
};
|
||||
use anyhow::{Context, Result};
|
||||
use std::{
|
||||
@ -73,6 +74,13 @@ impl<V: 'static> View<V> {
|
||||
component: Some(component),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn focus_handle(&self, cx: &AppContext) -> FocusHandle
|
||||
where
|
||||
V: FocusableView,
|
||||
{
|
||||
self.read(cx).focus_handle(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Clone for View<V> {
|
||||
|
@ -185,6 +185,10 @@ impl Drop for FocusHandle {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FocusableView: Render {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
|
||||
}
|
||||
|
||||
// Holds the state for a specific window.
|
||||
pub struct Window {
|
||||
pub(crate) handle: AnyWindowHandle,
|
||||
@ -1546,6 +1550,12 @@ impl VisualContext for WindowContext<'_> {
|
||||
self.window.root_view = Some(view.clone().into());
|
||||
view
|
||||
}
|
||||
|
||||
fn focus_view<V: crate::FocusableView>(&mut self, view: &View<V>) -> Self::Result<()> {
|
||||
self.update_view(view, |view, cx| {
|
||||
view.focus_handle(cx).clone().focus(cx);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::ops::Deref for WindowContext<'a> {
|
||||
@ -2219,9 +2229,7 @@ impl<'a, V: 'static> ViewContext<'a, V> {
|
||||
.set_input_handler(Box::new(input_handler));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> ViewContext<'_, V> {
|
||||
pub fn emit<Evt>(&mut self, event: Evt)
|
||||
where
|
||||
Evt: 'static,
|
||||
@ -2234,6 +2242,13 @@ impl<V> ViewContext<'_, V> {
|
||||
event: Box::new(event),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn focus_self(&mut self)
|
||||
where
|
||||
V: FocusableView,
|
||||
{
|
||||
self.defer(|view, cx| view.focus_handle(cx).focus(cx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Context for ViewContext<'_, V> {
|
||||
@ -2309,6 +2324,10 @@ impl<V: 'static> VisualContext for ViewContext<'_, V> {
|
||||
{
|
||||
self.window_cx.replace_root_view(build_view)
|
||||
}
|
||||
|
||||
fn focus_view<W: FocusableView>(&mut self, view: &View<W>) -> Self::Result<()> {
|
||||
self.window_cx.focus_view(view)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V> std::ops::Deref for ViewContext<'a, V> {
|
||||
|
@ -9,10 +9,10 @@ use file_associations::FileAssociations;
|
||||
use anyhow::{anyhow, Result};
|
||||
use gpui::{
|
||||
actions, div, px, uniform_list, Action, AppContext, AssetSource, AsyncWindowContext,
|
||||
ClipboardItem, Component, Div, EventEmitter, FocusHandle, Focusable, InteractiveComponent,
|
||||
Model, MouseButton, ParentComponent, Pixels, Point, PromptLevel, Render, Stateful,
|
||||
StatefulInteractiveComponent, Styled, Task, UniformListScrollHandle, View, ViewContext,
|
||||
VisualContext as _, WeakView, WindowContext,
|
||||
ClipboardItem, Component, Div, EventEmitter, FocusHandle, Focusable, FocusableView,
|
||||
InteractiveComponent, Model, MouseButton, ParentComponent, Pixels, Point, PromptLevel, Render,
|
||||
Stateful, StatefulInteractiveComponent, Styled, Task, UniformListScrollHandle, View,
|
||||
ViewContext, VisualContext as _, WeakView, WindowContext,
|
||||
};
|
||||
use menu::{Confirm, SelectNext, SelectPrev};
|
||||
use project::{
|
||||
@ -32,7 +32,7 @@ use std::{
|
||||
use theme::ActiveTheme as _;
|
||||
use ui::{h_stack, v_stack, IconElement, Label};
|
||||
use unicase::UniCase;
|
||||
use util::{maybe, TryFutureExt};
|
||||
use util::{maybe, ResultExt, TryFutureExt};
|
||||
use workspace::{
|
||||
dock::{DockPosition, PanelEvent},
|
||||
Workspace,
|
||||
@ -310,32 +310,31 @@ impl ProjectPanel {
|
||||
project_panel
|
||||
}
|
||||
|
||||
pub fn load(
|
||||
pub async fn load(
|
||||
workspace: WeakView<Workspace>,
|
||||
cx: AsyncWindowContext,
|
||||
) -> Task<Result<View<Self>>> {
|
||||
cx.spawn(|mut cx| async move {
|
||||
// let serialized_panel = if let Some(panel) = cx
|
||||
// .background_executor()
|
||||
// .spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
|
||||
// .await
|
||||
// .log_err()
|
||||
// .flatten()
|
||||
// {
|
||||
// Some(serde_json::from_str::<SerializedProjectPanel>(&panel)?)
|
||||
// } else {
|
||||
// None
|
||||
// };
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
let panel = ProjectPanel::new(workspace, cx);
|
||||
// if let Some(serialized_panel) = serialized_panel {
|
||||
// panel.update(cx, |panel, cx| {
|
||||
// panel.width = serialized_panel.width;
|
||||
// cx.notify();
|
||||
// });
|
||||
// }
|
||||
panel
|
||||
})
|
||||
mut cx: AsyncWindowContext,
|
||||
) -> Result<View<Self>> {
|
||||
let serialized_panel = cx
|
||||
.background_executor()
|
||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
|
||||
.await
|
||||
.map_err(|e| anyhow!("Failed to load project panel: {}", e))
|
||||
.log_err()
|
||||
.flatten()
|
||||
.map(|panel| serde_json::from_str::<SerializedProjectPanel>(&panel))
|
||||
.transpose()
|
||||
.log_err()
|
||||
.flatten();
|
||||
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
let panel = ProjectPanel::new(workspace, cx);
|
||||
if let Some(serialized_panel) = serialized_panel {
|
||||
panel.update(cx, |panel, cx| {
|
||||
panel.width = serialized_panel.width;
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
panel
|
||||
})
|
||||
}
|
||||
|
||||
@ -1531,25 +1530,19 @@ impl workspace::dock::Panel for ProjectPanel {
|
||||
Box::new(ToggleFocus)
|
||||
}
|
||||
|
||||
// fn should_change_position_on_event(event: &Self::Event) -> bool {
|
||||
// matches!(event, Event::DockPositionChanged)
|
||||
// }
|
||||
|
||||
fn has_focus(&self, _: &WindowContext) -> bool {
|
||||
self.has_focus
|
||||
}
|
||||
|
||||
fn persistent_name(&self) -> &'static str {
|
||||
fn persistent_name() -> &'static str {
|
||||
"Project Panel"
|
||||
}
|
||||
}
|
||||
|
||||
fn focus_handle(&self, _cx: &WindowContext) -> FocusHandle {
|
||||
impl FocusableView for ProjectPanel {
|
||||
fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
|
||||
// fn is_focus_event(event: &Self::Event) -> bool {
|
||||
// matches!(event, Event::Focus)
|
||||
// }
|
||||
}
|
||||
|
||||
impl ClipboardEntry {
|
||||
|
@ -9,7 +9,7 @@ use schemars::{
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
use util::asset_str;
|
||||
use util::{asset_str, ResultExt};
|
||||
|
||||
#[derive(Debug, Deserialize, Default, Clone, JsonSchema)]
|
||||
#[serde(transparent)]
|
||||
@ -86,9 +86,7 @@ impl KeymapFile {
|
||||
"invalid binding value for keystroke {keystroke}, context {context:?}"
|
||||
)
|
||||
})
|
||||
// todo!()
|
||||
.ok()
|
||||
// .log_err()
|
||||
.log_err()
|
||||
.map(|action| KeyBinding::load(&keystroke, action, context.as_deref()))
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{status_bar::StatusItemView, Axis, Workspace};
|
||||
use gpui::{
|
||||
div, px, Action, AnyView, AppContext, Component, Div, Entity, EntityId, EventEmitter,
|
||||
FocusHandle, ParentComponent, Render, Styled, Subscription, View, ViewContext, WeakView,
|
||||
WindowContext,
|
||||
FocusHandle, FocusableView, ParentComponent, Render, Styled, Subscription, View, ViewContext,
|
||||
WeakView, WindowContext,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -18,8 +18,8 @@ pub enum PanelEvent {
|
||||
Focus,
|
||||
}
|
||||
|
||||
pub trait Panel: Render + EventEmitter<PanelEvent> {
|
||||
fn persistent_name(&self) -> &'static str;
|
||||
pub trait Panel: FocusableView + EventEmitter<PanelEvent> {
|
||||
fn persistent_name() -> &'static str;
|
||||
fn position(&self, cx: &WindowContext) -> DockPosition;
|
||||
fn position_is_valid(&self, position: DockPosition) -> bool;
|
||||
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
|
||||
@ -36,12 +36,11 @@ pub trait Panel: Render + EventEmitter<PanelEvent> {
|
||||
fn set_zoomed(&mut self, _zoomed: bool, _cx: &mut ViewContext<Self>) {}
|
||||
fn set_active(&mut self, _active: bool, _cx: &mut ViewContext<Self>) {}
|
||||
fn has_focus(&self, cx: &WindowContext) -> bool;
|
||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
|
||||
}
|
||||
|
||||
pub trait PanelHandle: Send + Sync {
|
||||
fn id(&self) -> EntityId;
|
||||
fn persistent_name(&self, cx: &WindowContext) -> &'static str;
|
||||
fn persistent_name(&self) -> &'static str;
|
||||
fn position(&self, cx: &WindowContext) -> DockPosition;
|
||||
fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool;
|
||||
fn set_position(&self, position: DockPosition, cx: &mut WindowContext);
|
||||
@ -54,7 +53,7 @@ pub trait PanelHandle: Send + Sync {
|
||||
fn toggle_action(&self, cx: &WindowContext) -> Box<dyn Action>;
|
||||
fn icon_label(&self, cx: &WindowContext) -> Option<String>;
|
||||
fn has_focus(&self, cx: &WindowContext) -> bool;
|
||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
|
||||
fn to_any(&self) -> AnyView;
|
||||
}
|
||||
|
||||
@ -66,8 +65,8 @@ where
|
||||
self.entity_id()
|
||||
}
|
||||
|
||||
fn persistent_name(&self, cx: &WindowContext) -> &'static str {
|
||||
self.read(cx).persistent_name()
|
||||
fn persistent_name(&self) -> &'static str {
|
||||
T::persistent_name()
|
||||
}
|
||||
|
||||
fn position(&self, cx: &WindowContext) -> DockPosition {
|
||||
@ -122,7 +121,7 @@ where
|
||||
self.clone().into()
|
||||
}
|
||||
|
||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
||||
self.read(cx).focus_handle(cx).clone()
|
||||
}
|
||||
}
|
||||
@ -140,6 +139,14 @@ pub struct Dock {
|
||||
active_panel_index: usize,
|
||||
}
|
||||
|
||||
impl FocusableView for Dock {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
||||
self.panel_entries[self.active_panel_index]
|
||||
.panel
|
||||
.focus_handle(cx)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum DockPosition {
|
||||
@ -221,12 +228,14 @@ impl Dock {
|
||||
.position(|entry| entry.panel.to_any().downcast::<T>().is_ok())
|
||||
}
|
||||
|
||||
pub fn panel_index_for_ui_name(&self, _ui_name: &str, _cx: &AppContext) -> Option<usize> {
|
||||
todo!()
|
||||
// self.panel_entries.iter().position(|entry| {
|
||||
// let panel = entry.panel.as_any();
|
||||
// cx.view_ui_name(panel.window(), panel.id()) == Some(ui_name)
|
||||
// })
|
||||
pub fn panel_index_for_persistent_name(
|
||||
&self,
|
||||
ui_name: &str,
|
||||
_cx: &AppContext,
|
||||
) -> Option<usize> {
|
||||
self.panel_entries
|
||||
.iter()
|
||||
.position(|entry| entry.panel.persistent_name() == ui_name)
|
||||
}
|
||||
|
||||
pub fn active_panel_index(&self) -> usize {
|
||||
@ -654,11 +663,11 @@ impl Render for PanelButtons {
|
||||
.enumerate()
|
||||
.filter_map(|(i, panel)| {
|
||||
let icon = panel.panel.icon(cx)?;
|
||||
let name = panel.panel.persistent_name(cx);
|
||||
let name = panel.panel.persistent_name();
|
||||
let action = panel.panel.toggle_action(cx);
|
||||
let action2 = action.boxed_clone();
|
||||
|
||||
let mut button = IconButton::new(panel.panel.persistent_name(cx), icon)
|
||||
let mut button = IconButton::new(panel.panel.persistent_name(), icon)
|
||||
.when(i == active_index, |el| el.state(InteractionState::Active))
|
||||
.on_click(move |this, cx| cx.dispatch_action(action.boxed_clone()))
|
||||
.tooltip(move |_, cx| Tooltip::for_action(name, &*action2, cx));
|
||||
@ -717,7 +726,7 @@ pub mod test {
|
||||
}
|
||||
|
||||
impl Panel for TestPanel {
|
||||
fn persistent_name(&self) -> &'static str {
|
||||
fn persistent_name() -> &'static str {
|
||||
"TestPanel"
|
||||
}
|
||||
|
||||
@ -765,8 +774,10 @@ pub mod test {
|
||||
fn has_focus(&self, _cx: &WindowContext) -> bool {
|
||||
self.has_focus
|
||||
}
|
||||
}
|
||||
|
||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
|
||||
impl FocusableView for TestPanel {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,9 @@ use client2::{
|
||||
Client,
|
||||
};
|
||||
use gpui::{
|
||||
AnyElement, AnyView, AppContext, Entity, EntityId, EventEmitter, FocusHandle, HighlightStyle,
|
||||
Model, Pixels, Point, Render, SharedString, Task, View, ViewContext, WeakView, WindowContext,
|
||||
AnyElement, AnyView, AppContext, Entity, EntityId, EventEmitter, FocusHandle, FocusableView,
|
||||
HighlightStyle, Model, Pixels, Point, SharedString, Task, View, ViewContext, WeakView,
|
||||
WindowContext,
|
||||
};
|
||||
use project2::{Project, ProjectEntryId, ProjectPath};
|
||||
use schemars::JsonSchema;
|
||||
@ -91,8 +92,7 @@ pub struct BreadcrumbText {
|
||||
pub highlights: Option<Vec<(Range<usize>, HighlightStyle)>>,
|
||||
}
|
||||
|
||||
pub trait Item: Render + EventEmitter<ItemEvent> {
|
||||
fn focus_handle(&self) -> FocusHandle;
|
||||
pub trait Item: FocusableView + EventEmitter<ItemEvent> {
|
||||
fn deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
||||
fn workspace_deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
||||
fn navigate(&mut self, _: Box<dyn Any>, _: &mut ViewContext<Self>) -> bool {
|
||||
@ -286,7 +286,7 @@ impl dyn ItemHandle {
|
||||
|
||||
impl<T: Item> ItemHandle for View<T> {
|
||||
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
|
||||
self.read(cx).focus_handle()
|
||||
self.focus_handle(cx)
|
||||
}
|
||||
|
||||
fn subscribe_to_item_events(
|
||||
|
@ -8,8 +8,8 @@ use anyhow::Result;
|
||||
use collections::{HashMap, HashSet, VecDeque};
|
||||
use gpui::{
|
||||
actions, prelude::*, register_action, AppContext, AsyncWindowContext, Component, Div, EntityId,
|
||||
EventEmitter, FocusHandle, Focusable, Model, PromptLevel, Render, Task, View, ViewContext,
|
||||
VisualContext, WeakView, WindowContext,
|
||||
EventEmitter, FocusHandle, Focusable, FocusableView, Model, PromptLevel, Render, Task, View,
|
||||
ViewContext, VisualContext, WeakView, WindowContext,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use project2::{Project, ProjectEntryId, ProjectPath};
|
||||
@ -125,10 +125,6 @@ pub fn init(cx: &mut AppContext) {
|
||||
// cx.add_async_action(Pane::close_items_to_the_left);
|
||||
// cx.add_async_action(Pane::close_items_to_the_right);
|
||||
// cx.add_async_action(Pane::close_all_items);
|
||||
// cx.add_action(|pane: &mut Pane, _: &SplitLeft, cx| pane.split(SplitDirection::Left, cx));
|
||||
// cx.add_action(|pane: &mut Pane, _: &SplitUp, cx| pane.split(SplitDirection::Up, cx));
|
||||
// cx.add_action(|pane: &mut Pane, _: &SplitRight, cx| pane.split(SplitDirection::Right, cx));
|
||||
// cx.add_action(|pane: &mut Pane, _: &SplitDown, cx| pane.split(SplitDirection::Down, cx));
|
||||
}
|
||||
|
||||
pub enum Event {
|
||||
@ -1195,9 +1191,9 @@ impl Pane {
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn split(&mut self, direction: SplitDirection, cx: &mut ViewContext<Self>) {
|
||||
// cx.emit(Event::Split(direction));
|
||||
// }
|
||||
pub fn split(&mut self, direction: SplitDirection, cx: &mut ViewContext<Self>) {
|
||||
cx.emit(Event::Split(direction));
|
||||
}
|
||||
|
||||
// fn deploy_split_menu(&mut self, cx: &mut ViewContext<Self>) {
|
||||
// self.tab_bar_context_menu.handle.update(cx, |menu, cx| {
|
||||
@ -1398,6 +1394,7 @@ impl Pane {
|
||||
.when_some(item.tab_tooltip_text(cx), |div, text| {
|
||||
div.tooltip(move |_, cx| cx.build_view(|cx| Tooltip::new(text.clone())).into())
|
||||
})
|
||||
.on_click(move |v: &mut Self, e, cx| v.activate_item(ix, true, true, cx))
|
||||
// .on_drag(move |pane, cx| pane.render_tab(ix, item.boxed_clone(), detail, cx))
|
||||
// .drag_over::<DraggedTab>(|d| d.bg(cx.theme().colors().element_drop_target))
|
||||
// .on_drop(|_view, state: View<DraggedTab>, cx| {
|
||||
@ -1430,32 +1427,22 @@ impl Pane {
|
||||
.items_center()
|
||||
.gap_1()
|
||||
.text_color(text_color)
|
||||
.children(if item.has_conflict(cx) {
|
||||
Some(
|
||||
IconElement::new(Icon::ExclamationTriangle)
|
||||
.size(ui::IconSize::Small)
|
||||
.color(TextColor::Warning),
|
||||
)
|
||||
} else if item.is_dirty(cx) {
|
||||
Some(
|
||||
IconElement::new(Icon::ExclamationTriangle)
|
||||
.size(ui::IconSize::Small)
|
||||
.color(TextColor::Info),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.children(if !close_right {
|
||||
Some(close_icon())
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.children(
|
||||
item.has_conflict(cx)
|
||||
.then(|| {
|
||||
IconElement::new(Icon::ExclamationTriangle)
|
||||
.size(ui::IconSize::Small)
|
||||
.color(TextColor::Warning)
|
||||
})
|
||||
.or(item.is_dirty(cx).then(|| {
|
||||
IconElement::new(Icon::ExclamationTriangle)
|
||||
.size(ui::IconSize::Small)
|
||||
.color(TextColor::Info)
|
||||
})),
|
||||
)
|
||||
.children((!close_right).then(|| close_icon()))
|
||||
.child(label)
|
||||
.children(if close_right {
|
||||
Some(close_icon())
|
||||
} else {
|
||||
None
|
||||
}),
|
||||
.children(close_right.then(|| close_icon())),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1912,9 +1899,11 @@ impl Pane {
|
||||
}
|
||||
}
|
||||
|
||||
// impl Entity for Pane {
|
||||
// type Event = Event;
|
||||
// }
|
||||
impl FocusableView for Pane {
|
||||
fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for Pane {
|
||||
type Element = Focusable<Self, Div<Self>>;
|
||||
@ -1923,6 +1912,10 @@ impl Render for Pane {
|
||||
v_stack()
|
||||
.key_context("Pane")
|
||||
.track_focus(&self.focus_handle)
|
||||
.on_action(|pane: &mut Pane, _: &SplitLeft, cx| pane.split(SplitDirection::Left, cx))
|
||||
.on_action(|pane: &mut Pane, _: &SplitUp, cx| pane.split(SplitDirection::Up, cx))
|
||||
.on_action(|pane: &mut Pane, _: &SplitRight, cx| pane.split(SplitDirection::Right, cx))
|
||||
.on_action(|pane: &mut Pane, _: &SplitDown, cx| pane.split(SplitDirection::Down, cx))
|
||||
.size_full()
|
||||
.on_action(|pane: &mut Self, action, cx| {
|
||||
pane.close_active_item(action, cx)
|
||||
|
@ -148,6 +148,10 @@ impl PaneGroup {
|
||||
self.root.collect_panes(&mut panes);
|
||||
panes
|
||||
}
|
||||
|
||||
pub(crate) fn first_pane(&self) -> View<Pane> {
|
||||
self.root.first_pane()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
@ -181,6 +185,13 @@ impl Member {
|
||||
}
|
||||
}
|
||||
|
||||
fn first_pane(&self) -> View<Pane> {
|
||||
match self {
|
||||
Member::Axis(axis) => axis.members[0].first_pane(),
|
||||
Member::Pane(pane) => pane.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(
|
||||
&self,
|
||||
project: &Model<Project>,
|
||||
@ -551,7 +562,32 @@ impl PaneAxis {
|
||||
) -> AnyElement<Workspace> {
|
||||
debug_assert!(self.members.len() == self.flexes.lock().len());
|
||||
|
||||
todo!()
|
||||
div()
|
||||
.flex()
|
||||
.flex_auto()
|
||||
.map(|s| match self.axis {
|
||||
Axis::Vertical => s.flex_col(),
|
||||
Axis::Horizontal => s.flex_row(),
|
||||
})
|
||||
.children(self.members.iter().enumerate().map(|(ix, member)| {
|
||||
match member {
|
||||
Member::Axis(axis) => axis
|
||||
.render(
|
||||
project,
|
||||
basis,
|
||||
follower_states,
|
||||
active_call,
|
||||
active_pane,
|
||||
zoomed,
|
||||
app_state,
|
||||
cx,
|
||||
)
|
||||
.render(),
|
||||
Member::Pane(pane) => pane.clone().render(),
|
||||
}
|
||||
}))
|
||||
.render()
|
||||
|
||||
// let mut pane_axis = PaneAxisElement::new(
|
||||
// self.axis,
|
||||
// basis,
|
||||
|
@ -68,41 +68,6 @@ impl StatusBar {
|
||||
}
|
||||
}
|
||||
|
||||
// todo!()
|
||||
// impl View for StatusBar {
|
||||
// fn ui_name() -> &'static str {
|
||||
// "StatusBar"
|
||||
// }
|
||||
|
||||
// fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||
// let theme = &theme::current(cx).workspace.status_bar;
|
||||
|
||||
// StatusBarElement {
|
||||
// left: Flex::row()
|
||||
// .with_children(self.left_items.iter().map(|i| {
|
||||
// ChildView::new(i.as_any(), cx)
|
||||
// .aligned()
|
||||
// .contained()
|
||||
// .with_margin_right(theme.item_spacing)
|
||||
// }))
|
||||
// .into_any(),
|
||||
// right: Flex::row()
|
||||
// .with_children(self.right_items.iter().rev().map(|i| {
|
||||
// ChildView::new(i.as_any(), cx)
|
||||
// .aligned()
|
||||
// .contained()
|
||||
// .with_margin_left(theme.item_spacing)
|
||||
// }))
|
||||
// .into_any(),
|
||||
// }
|
||||
// .contained()
|
||||
// .with_style(theme.container)
|
||||
// .constrained()
|
||||
// .with_height(theme.height)
|
||||
// .into_any()
|
||||
// }
|
||||
// }
|
||||
|
||||
impl StatusBar {
|
||||
pub fn new(active_pane: &View<Pane>, cx: &mut ViewContext<Self>) -> Self {
|
||||
let mut this = Self {
|
||||
@ -222,80 +187,3 @@ impl From<&dyn StatusItemViewHandle> for AnyView {
|
||||
val.to_any().clone()
|
||||
}
|
||||
}
|
||||
|
||||
// todo!()
|
||||
// struct StatusBarElement {
|
||||
// left: AnyElement<StatusBar>,
|
||||
// right: AnyElement<StatusBar>,
|
||||
// }
|
||||
|
||||
// todo!()
|
||||
// impl Element<StatusBar> for StatusBarElement {
|
||||
// type LayoutState = ();
|
||||
// type PaintState = ();
|
||||
|
||||
// fn layout(
|
||||
// &mut self,
|
||||
// mut constraint: SizeConstraint,
|
||||
// view: &mut StatusBar,
|
||||
// cx: &mut ViewContext<StatusBar>,
|
||||
// ) -> (Vector2F, Self::LayoutState) {
|
||||
// let max_width = constraint.max.x();
|
||||
// constraint.min = vec2f(0., constraint.min.y());
|
||||
|
||||
// let right_size = self.right.layout(constraint, view, cx);
|
||||
// let constraint = SizeConstraint::new(
|
||||
// vec2f(0., constraint.min.y()),
|
||||
// vec2f(max_width - right_size.x(), constraint.max.y()),
|
||||
// );
|
||||
|
||||
// self.left.layout(constraint, view, cx);
|
||||
|
||||
// (vec2f(max_width, right_size.y()), ())
|
||||
// }
|
||||
|
||||
// fn paint(
|
||||
// &mut self,
|
||||
// bounds: RectF,
|
||||
// visible_bounds: RectF,
|
||||
// _: &mut Self::LayoutState,
|
||||
// view: &mut StatusBar,
|
||||
// cx: &mut ViewContext<StatusBar>,
|
||||
// ) -> Self::PaintState {
|
||||
// let origin_y = bounds.upper_right().y();
|
||||
// let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
|
||||
|
||||
// let left_origin = vec2f(bounds.lower_left().x(), origin_y);
|
||||
// self.left.paint(left_origin, visible_bounds, view, cx);
|
||||
|
||||
// let right_origin = vec2f(bounds.upper_right().x() - self.right.size().x(), origin_y);
|
||||
// self.right.paint(right_origin, visible_bounds, view, cx);
|
||||
// }
|
||||
|
||||
// fn rect_for_text_range(
|
||||
// &self,
|
||||
// _: Range<usize>,
|
||||
// _: RectF,
|
||||
// _: RectF,
|
||||
// _: &Self::LayoutState,
|
||||
// _: &Self::PaintState,
|
||||
// _: &StatusBar,
|
||||
// _: &ViewContext<StatusBar>,
|
||||
// ) -> Option<RectF> {
|
||||
// None
|
||||
// }
|
||||
|
||||
// fn debug(
|
||||
// &self,
|
||||
// bounds: RectF,
|
||||
// _: &Self::LayoutState,
|
||||
// _: &Self::PaintState,
|
||||
// _: &StatusBar,
|
||||
// _: &ViewContext<StatusBar>,
|
||||
// ) -> serde_json::Value {
|
||||
// json!({
|
||||
// "type": "StatusBarElement",
|
||||
// "bounds": bounds.to_json()
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
@ -37,9 +37,10 @@ use futures::{
|
||||
};
|
||||
use gpui::{
|
||||
actions, div, point, prelude::*, size, Action, AnyModel, AnyView, AnyWeakView, AppContext,
|
||||
AsyncAppContext, AsyncWindowContext, Bounds, Div, Entity, EntityId, EventEmitter, GlobalPixels,
|
||||
KeyContext, Model, ModelContext, ParentComponent, Point, Render, Size, Styled, Subscription,
|
||||
Task, View, ViewContext, WeakView, WindowBounds, WindowContext, WindowHandle, WindowOptions,
|
||||
AsyncAppContext, AsyncWindowContext, Bounds, Div, Entity, EntityId, EventEmitter, FocusHandle,
|
||||
FocusableView, GlobalPixels, KeyContext, Model, ModelContext, ParentComponent, Point, Render,
|
||||
Size, Styled, Subscription, Task, View, ViewContext, WeakView, WindowBounds, WindowContext,
|
||||
WindowHandle, WindowOptions,
|
||||
};
|
||||
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem};
|
||||
use itertools::Itertools;
|
||||
@ -319,12 +320,6 @@ pub struct AppState {
|
||||
pub fs: Arc<dyn fs2::Fs>,
|
||||
pub build_window_options:
|
||||
fn(Option<WindowBounds>, Option<Uuid>, &mut AppContext) -> WindowOptions,
|
||||
pub initialize_workspace: fn(
|
||||
WeakView<Workspace>,
|
||||
bool,
|
||||
Arc<AppState>,
|
||||
AsyncWindowContext,
|
||||
) -> Task<anyhow::Result<()>>,
|
||||
pub node_runtime: Arc<dyn NodeRuntime>,
|
||||
}
|
||||
|
||||
@ -370,7 +365,6 @@ impl AppState {
|
||||
user_store,
|
||||
workspace_store,
|
||||
node_runtime: FakeNodeRuntime::new(),
|
||||
initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
||||
build_window_options: |_, _, _| Default::default(),
|
||||
})
|
||||
}
|
||||
@ -682,7 +676,7 @@ impl Workspace {
|
||||
fn new_local(
|
||||
abs_paths: Vec<PathBuf>,
|
||||
app_state: Arc<AppState>,
|
||||
_requesting_window: Option<WindowHandle<Workspace>>,
|
||||
requesting_window: Option<WindowHandle<Workspace>>,
|
||||
cx: &mut AppContext,
|
||||
) -> Task<
|
||||
anyhow::Result<(
|
||||
@ -700,7 +694,8 @@ impl Workspace {
|
||||
);
|
||||
|
||||
cx.spawn(|mut cx| async move {
|
||||
let serialized_workspace: Option<SerializedWorkspace> = None; //persistence::DB.workspace_for_roots(&abs_paths.as_slice());
|
||||
let serialized_workspace: Option<SerializedWorkspace> =
|
||||
persistence::DB.workspace_for_roots(&abs_paths.as_slice());
|
||||
|
||||
let paths_to_open = Arc::new(abs_paths);
|
||||
|
||||
@ -729,15 +724,14 @@ impl Workspace {
|
||||
DB.next_id().await.unwrap_or(0)
|
||||
};
|
||||
|
||||
// todo!()
|
||||
let window = /*if let Some(window) = requesting_window {
|
||||
let window = if let Some(window) = requesting_window {
|
||||
cx.update_window(window.into(), |old_workspace, cx| {
|
||||
cx.replace_root_view(|cx| {
|
||||
Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx)
|
||||
});
|
||||
});
|
||||
})?;
|
||||
window
|
||||
} else */ {
|
||||
} else {
|
||||
let window_bounds_override = window_bounds_env_override(&cx);
|
||||
let (bounds, display) = if let Some(bounds) = window_bounds_override {
|
||||
(Some(bounds), None)
|
||||
@ -751,12 +745,13 @@ impl Workspace {
|
||||
// Stored bounds are relative to the containing display.
|
||||
// So convert back to global coordinates if that screen still exists
|
||||
if let WindowBounds::Fixed(mut window_bounds) = bounds {
|
||||
let screen =
|
||||
cx.update(|cx|
|
||||
cx.displays()
|
||||
.into_iter()
|
||||
.find(|display| display.uuid().ok() == Some(serialized_display))
|
||||
).ok()??;
|
||||
let screen = cx
|
||||
.update(|cx| {
|
||||
cx.displays().into_iter().find(|display| {
|
||||
display.uuid().ok() == Some(serialized_display)
|
||||
})
|
||||
})
|
||||
.ok()??;
|
||||
let screen_bounds = screen.bounds();
|
||||
window_bounds.origin.x += screen_bounds.origin.x;
|
||||
window_bounds.origin.y += screen_bounds.origin.y;
|
||||
@ -785,17 +780,17 @@ impl Workspace {
|
||||
};
|
||||
|
||||
// todo!() Ask how to do this
|
||||
let weak_view = window.update(&mut cx, |_, cx| cx.view().downgrade())?;
|
||||
let async_cx = window.update(&mut cx, |_, cx| cx.to_async())?;
|
||||
// let weak_view = window.update(&mut cx, |_, cx| cx.view().downgrade())?;
|
||||
// let async_cx = window.update(&mut cx, |_, cx| cx.to_async())?;
|
||||
|
||||
(app_state.initialize_workspace)(
|
||||
weak_view,
|
||||
serialized_workspace.is_some(),
|
||||
app_state.clone(),
|
||||
async_cx,
|
||||
)
|
||||
.await
|
||||
.log_err();
|
||||
// (app_state.initialize_workspace)(
|
||||
// weak_view,
|
||||
// serialized_workspace.is_some(),
|
||||
// app_state.clone(),
|
||||
// async_cx,
|
||||
// )
|
||||
// .await
|
||||
// .log_err();
|
||||
|
||||
window
|
||||
.update(&mut cx, |_, cx| cx.activate_window())
|
||||
@ -804,12 +799,7 @@ impl Workspace {
|
||||
notify_if_database_failed(window, &mut cx);
|
||||
let opened_items = window
|
||||
.update(&mut cx, |_workspace, cx| {
|
||||
open_items(
|
||||
serialized_workspace,
|
||||
project_paths,
|
||||
app_state,
|
||||
cx,
|
||||
)
|
||||
open_items(serialized_workspace, project_paths, app_state, cx)
|
||||
})?
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
@ -2970,13 +2960,15 @@ impl Workspace {
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
// fn schedule_serialize(&mut self, cx: &mut ViewContext<Self>) {
|
||||
// self._schedule_serialize = Some(cx.spawn(|this, cx| async move {
|
||||
// cx.background().timer(Duration::from_millis(100)).await;
|
||||
// this.read_with(&cx, |this, cx| this.serialize_workspace(cx))
|
||||
// .ok();
|
||||
// }));
|
||||
// }
|
||||
fn schedule_serialize(&mut self, cx: &mut ViewContext<Self>) {
|
||||
self._schedule_serialize = Some(cx.spawn(|this, mut cx| async move {
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_millis(100))
|
||||
.await;
|
||||
this.update(&mut cx, |this, cx| this.serialize_workspace(cx))
|
||||
.log_err();
|
||||
}));
|
||||
}
|
||||
|
||||
fn serialize_workspace(&self, cx: &mut ViewContext<Self>) {
|
||||
fn serialize_pane_handle(pane_handle: &View<Pane>, cx: &WindowContext) -> SerializedPane {
|
||||
@ -3032,7 +3024,7 @@ impl Workspace {
|
||||
let left_visible = left_dock.is_open();
|
||||
let left_active_panel = left_dock
|
||||
.visible_panel()
|
||||
.and_then(|panel| Some(panel.persistent_name(cx).to_string()));
|
||||
.and_then(|panel| Some(panel.persistent_name().to_string()));
|
||||
let left_dock_zoom = left_dock
|
||||
.visible_panel()
|
||||
.map(|panel| panel.is_zoomed(cx))
|
||||
@ -3042,7 +3034,7 @@ impl Workspace {
|
||||
let right_visible = right_dock.is_open();
|
||||
let right_active_panel = right_dock
|
||||
.visible_panel()
|
||||
.and_then(|panel| Some(panel.persistent_name(cx).to_string()));
|
||||
.and_then(|panel| Some(panel.persistent_name().to_string()));
|
||||
let right_dock_zoom = right_dock
|
||||
.visible_panel()
|
||||
.map(|panel| panel.is_zoomed(cx))
|
||||
@ -3052,7 +3044,7 @@ impl Workspace {
|
||||
let bottom_visible = bottom_dock.is_open();
|
||||
let bottom_active_panel = bottom_dock
|
||||
.visible_panel()
|
||||
.and_then(|panel| Some(panel.persistent_name(cx).to_string()));
|
||||
.and_then(|panel| Some(panel.persistent_name().to_string()));
|
||||
let bottom_dock_zoom = bottom_dock
|
||||
.visible_panel()
|
||||
.map(|panel| panel.is_zoomed(cx))
|
||||
@ -3158,45 +3150,34 @@ impl Workspace {
|
||||
|
||||
// Swap workspace center group
|
||||
workspace.center = PaneGroup::with_root(center_group);
|
||||
|
||||
// Change the focus to the workspace first so that we retrigger focus in on the pane.
|
||||
// todo!()
|
||||
// cx.focus_self();
|
||||
// if let Some(active_pane) = active_pane {
|
||||
// cx.focus(&active_pane);
|
||||
// } else {
|
||||
// cx.focus(workspace.panes.last().unwrap());
|
||||
// }
|
||||
} else {
|
||||
// todo!()
|
||||
// let old_center_handle = old_center_pane.and_then(|weak| weak.upgrade());
|
||||
// if let Some(old_center_handle) = old_center_handle {
|
||||
// cx.focus(&old_center_handle)
|
||||
// } else {
|
||||
// cx.focus_self()
|
||||
// }
|
||||
workspace.last_active_center_pane = active_pane.as_ref().map(|p| p.downgrade());
|
||||
if let Some(active_pane) = active_pane {
|
||||
workspace.active_pane = active_pane;
|
||||
cx.focus_self();
|
||||
} else {
|
||||
workspace.active_pane = workspace.center.first_pane().clone();
|
||||
}
|
||||
}
|
||||
|
||||
let docks = serialized_workspace.docks;
|
||||
workspace.left_dock.update(cx, |dock, cx| {
|
||||
dock.set_open(docks.left.visible, cx);
|
||||
if let Some(active_panel) = docks.left.active_panel {
|
||||
if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) {
|
||||
if let Some(ix) = dock.panel_index_for_persistent_name(&active_panel, cx) {
|
||||
dock.activate_panel(ix, cx);
|
||||
}
|
||||
}
|
||||
dock.active_panel()
|
||||
.map(|panel| panel.set_zoomed(docks.left.zoom, cx));
|
||||
if docks.left.visible && docks.left.zoom {
|
||||
// todo!()
|
||||
// cx.focus_self()
|
||||
cx.focus_self()
|
||||
}
|
||||
});
|
||||
// TODO: I think the bug is that setting zoom or active undoes the bottom zoom or something
|
||||
workspace.right_dock.update(cx, |dock, cx| {
|
||||
dock.set_open(docks.right.visible, cx);
|
||||
if let Some(active_panel) = docks.right.active_panel {
|
||||
if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) {
|
||||
if let Some(ix) = dock.panel_index_for_persistent_name(&active_panel, cx) {
|
||||
dock.activate_panel(ix, cx);
|
||||
}
|
||||
}
|
||||
@ -3204,14 +3185,13 @@ impl Workspace {
|
||||
.map(|panel| panel.set_zoomed(docks.right.zoom, cx));
|
||||
|
||||
if docks.right.visible && docks.right.zoom {
|
||||
// todo!()
|
||||
// cx.focus_self()
|
||||
cx.focus_self()
|
||||
}
|
||||
});
|
||||
workspace.bottom_dock.update(cx, |dock, cx| {
|
||||
dock.set_open(docks.bottom.visible, cx);
|
||||
if let Some(active_panel) = docks.bottom.active_panel {
|
||||
if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) {
|
||||
if let Some(ix) = dock.panel_index_for_persistent_name(&active_panel, cx) {
|
||||
dock.activate_panel(ix, cx);
|
||||
}
|
||||
}
|
||||
@ -3220,8 +3200,7 @@ impl Workspace {
|
||||
.map(|panel| panel.set_zoomed(docks.bottom.zoom, cx));
|
||||
|
||||
if docks.bottom.visible && docks.bottom.zoom {
|
||||
// todo!()
|
||||
// cx.focus_self()
|
||||
cx.focus_self()
|
||||
}
|
||||
});
|
||||
|
||||
@ -3283,7 +3262,6 @@ impl Workspace {
|
||||
// },
|
||||
// );
|
||||
.on_action(|this, e: &ToggleLeftDock, cx| {
|
||||
println!("TOGGLING DOCK");
|
||||
this.toggle_dock(DockPosition::Left, cx);
|
||||
})
|
||||
// cx.add_action(|workspace: &mut Workspace, _: &ToggleRightDock, cx| {
|
||||
@ -3347,7 +3325,6 @@ impl Workspace {
|
||||
user_store,
|
||||
fs: project.read(cx).fs().clone(),
|
||||
build_window_options: |_, _, _| Default::default(),
|
||||
initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
||||
node_runtime: FakeNodeRuntime::new(),
|
||||
});
|
||||
let workspace = Self::new(0, project, app_state, cx);
|
||||
@ -3626,6 +3603,12 @@ fn notify_if_database_failed(workspace: WindowHandle<Workspace>, cx: &mut AsyncA
|
||||
|
||||
impl EventEmitter<Event> for Workspace {}
|
||||
|
||||
impl FocusableView for Workspace {
|
||||
fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
|
||||
self.active_pane.focus_handle(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for Workspace {
|
||||
type Element = Div<Self>;
|
||||
|
||||
|
@ -50,8 +50,8 @@ use util::{
|
||||
use uuid::Uuid;
|
||||
use workspace::{AppState, WorkspaceStore};
|
||||
use zed2::{
|
||||
build_window_options, ensure_only_instance, handle_cli_connection, init_zed_actions,
|
||||
initialize_workspace, languages, Assets, IsOnlyInstance, OpenListener, OpenRequest,
|
||||
build_window_options, ensure_only_instance, handle_cli_connection, initialize_workspace,
|
||||
languages, Assets, IsOnlyInstance, OpenListener, OpenRequest,
|
||||
};
|
||||
|
||||
mod open_listener;
|
||||
@ -176,7 +176,6 @@ fn main() {
|
||||
user_store,
|
||||
fs,
|
||||
build_window_options,
|
||||
initialize_workspace,
|
||||
// background_actions: todo!("ask Mikayla"),
|
||||
workspace_store,
|
||||
node_runtime,
|
||||
@ -213,7 +212,7 @@ fn main() {
|
||||
// zed::init(&app_state, cx);
|
||||
|
||||
// cx.set_menus(menus::menus());
|
||||
init_zed_actions(app_state.clone(), cx);
|
||||
initialize_workspace(app_state.clone(), cx);
|
||||
|
||||
if stdout_is_a_pty() {
|
||||
cx.activate(true);
|
||||
|
@ -10,13 +10,13 @@ pub use assets::*;
|
||||
use collections::VecDeque;
|
||||
use editor::{Editor, MultiBuffer};
|
||||
use gpui::{
|
||||
actions, point, px, AppContext, AsyncWindowContext, Context, PromptLevel, Task,
|
||||
TitlebarOptions, ViewContext, VisualContext, WeakView, WindowBounds, WindowKind, WindowOptions,
|
||||
actions, point, px, AppContext, Context, PromptLevel, TitlebarOptions, ViewContext,
|
||||
VisualContext, WindowBounds, WindowKind, WindowOptions,
|
||||
};
|
||||
pub use only_instance::*;
|
||||
pub use open_listener::*;
|
||||
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use anyhow::{anyhow, Context as _};
|
||||
use project_panel::ProjectPanel;
|
||||
use settings::{initial_local_settings_content, Settings};
|
||||
use std::{borrow::Cow, ops::Deref, sync::Arc};
|
||||
@ -86,8 +86,147 @@ pub fn build_window_options(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_zed_actions(app_state: Arc<AppState>, cx: &mut AppContext) {
|
||||
cx.observe_new_views(move |workspace: &mut Workspace, _cx| {
|
||||
pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
|
||||
cx.observe_new_views(move |workspace: &mut Workspace, cx| {
|
||||
let workspace_handle = cx.view().clone();
|
||||
cx.subscribe(&workspace_handle, {
|
||||
move |workspace, _, event, cx| {
|
||||
if let workspace::Event::PaneAdded(pane) = event {
|
||||
pane.update(cx, |pane, cx| {
|
||||
pane.toolbar().update(cx, |toolbar, cx| {
|
||||
// todo!()
|
||||
// let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(workspace));
|
||||
// toolbar.add_item(breadcrumbs, cx);
|
||||
// let buffer_search_bar = cx.add_view(BufferSearchBar::new);
|
||||
// toolbar.add_item(buffer_search_bar.clone(), cx);
|
||||
// let quick_action_bar = cx.add_view(|_| {
|
||||
// QuickActionBar::new(buffer_search_bar, workspace)
|
||||
// });
|
||||
// toolbar.add_item(quick_action_bar, cx);
|
||||
// let diagnostic_editor_controls =
|
||||
// cx.add_view(|_| diagnostics2::ToolbarControls::new());
|
||||
// toolbar.add_item(diagnostic_editor_controls, cx);
|
||||
// let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
|
||||
// toolbar.add_item(project_search_bar, cx);
|
||||
// let submit_feedback_button =
|
||||
// cx.add_view(|_| SubmitFeedbackButton::new());
|
||||
// toolbar.add_item(submit_feedback_button, cx);
|
||||
// let feedback_info_text = cx.add_view(|_| FeedbackInfoText::new());
|
||||
// toolbar.add_item(feedback_info_text, cx);
|
||||
// let lsp_log_item =
|
||||
// cx.add_view(|_| language_tools::LspLogToolbarItemView::new());
|
||||
// toolbar.add_item(lsp_log_item, cx);
|
||||
// let syntax_tree_item = cx
|
||||
// .add_view(|_| language_tools::SyntaxTreeToolbarItemView::new());
|
||||
// toolbar.add_item(syntax_tree_item, cx);
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
// cx.emit(workspace2::Event::PaneAdded(
|
||||
// workspace.active_pane().clone(),
|
||||
// ));
|
||||
|
||||
// let collab_titlebar_item =
|
||||
// cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx));
|
||||
// workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
|
||||
|
||||
// let copilot =
|
||||
// cx.add_view(|cx| copilot_button::CopilotButton::new(app_state.fs.clone(), cx));
|
||||
// let diagnostic_summary =
|
||||
// cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
|
||||
// let activity_indicator = activity_indicator::ActivityIndicator::new(
|
||||
// workspace,
|
||||
// app_state.languages.clone(),
|
||||
// cx,
|
||||
// );
|
||||
// let active_buffer_language =
|
||||
// cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
|
||||
// let vim_mode_indicator = cx.add_view(|cx| vim::ModeIndicator::new(cx));
|
||||
// let feedback_button = cx.add_view(|_| {
|
||||
// feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace)
|
||||
// });
|
||||
// let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
|
||||
workspace.status_bar().update(cx, |status_bar, cx| {
|
||||
// status_bar.add_left_item(diagnostic_summary, cx);
|
||||
// status_bar.add_left_item(activity_indicator, cx);
|
||||
|
||||
// status_bar.add_right_item(feedback_button, cx);
|
||||
// status_bar.add_right_item(copilot, cx);
|
||||
// status_bar.add_right_item(active_buffer_language, cx);
|
||||
// status_bar.add_right_item(vim_mode_indicator, cx);
|
||||
// status_bar.add_right_item(cursor_position, cx);
|
||||
});
|
||||
|
||||
// auto_update::notify_of_any_new_update(cx.weak_handle(), cx);
|
||||
|
||||
// vim::observe_keystrokes(cx);
|
||||
|
||||
// cx.on_window_should_close(|workspace, cx| {
|
||||
// if let Some(task) = workspace.close(&Default::default(), cx) {
|
||||
// task.detach_and_log_err(cx);
|
||||
// }
|
||||
// false
|
||||
// });
|
||||
|
||||
cx.spawn(|workspace_handle, mut cx| async move {
|
||||
let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
|
||||
// let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
|
||||
// let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone());
|
||||
let channels_panel =
|
||||
collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
|
||||
// let chat_panel =
|
||||
// collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
|
||||
// let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
|
||||
// workspace_handle.clone(),
|
||||
// cx.clone(),
|
||||
// );
|
||||
let (
|
||||
project_panel,
|
||||
// terminal_panel,
|
||||
// assistant_panel,
|
||||
channels_panel,
|
||||
// chat_panel,
|
||||
// notification_panel,
|
||||
) = futures::try_join!(
|
||||
project_panel,
|
||||
// terminal_panel,
|
||||
// assistant_panel,
|
||||
channels_panel,
|
||||
// chat_panel,
|
||||
// notification_panel,
|
||||
)?;
|
||||
|
||||
workspace_handle.update(&mut cx, |workspace, cx| {
|
||||
let project_panel_position = project_panel.position(cx);
|
||||
workspace.add_panel(project_panel, cx);
|
||||
// workspace.add_panel(terminal_panel, cx);
|
||||
// workspace.add_panel(assistant_panel, cx);
|
||||
workspace.add_panel(channels_panel, cx);
|
||||
// workspace.add_panel(chat_panel, cx);
|
||||
// workspace.add_panel(notification_panel, cx);
|
||||
|
||||
// if !was_deserialized
|
||||
// && workspace
|
||||
// .project()
|
||||
// .read(cx)
|
||||
// .visible_worktrees(cx)
|
||||
// .any(|tree| {
|
||||
// tree.read(cx)
|
||||
// .root_entry()
|
||||
// .map_or(false, |entry| entry.is_dir())
|
||||
// })
|
||||
// {
|
||||
// workspace.toggle_dock(project_panel_position, cx);
|
||||
// }
|
||||
// cx.focus_self();
|
||||
})
|
||||
})
|
||||
.detach();
|
||||
|
||||
workspace
|
||||
.register_action(about)
|
||||
.register_action(|_, _: &Hide, cx| {
|
||||
@ -291,150 +430,6 @@ pub fn init_zed_actions(app_state: Arc<AppState>, cx: &mut AppContext) {
|
||||
.detach();
|
||||
}
|
||||
|
||||
pub fn initialize_workspace(
|
||||
workspace_handle: WeakView<Workspace>,
|
||||
was_deserialized: bool,
|
||||
app_state: Arc<AppState>,
|
||||
cx: AsyncWindowContext,
|
||||
) -> Task<Result<()>> {
|
||||
cx.spawn(|mut cx| async move {
|
||||
workspace_handle.update(&mut cx, |workspace, cx| {
|
||||
let workspace_handle = cx.view().clone();
|
||||
cx.subscribe(&workspace_handle, {
|
||||
move |workspace, _, event, cx| {
|
||||
if let workspace::Event::PaneAdded(pane) = event {
|
||||
pane.update(cx, |pane, cx| {
|
||||
pane.toolbar().update(cx, |toolbar, cx| {
|
||||
// todo!()
|
||||
// let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(workspace));
|
||||
// toolbar.add_item(breadcrumbs, cx);
|
||||
// let buffer_search_bar = cx.add_view(BufferSearchBar::new);
|
||||
// toolbar.add_item(buffer_search_bar.clone(), cx);
|
||||
// let quick_action_bar = cx.add_view(|_| {
|
||||
// QuickActionBar::new(buffer_search_bar, workspace)
|
||||
// });
|
||||
// toolbar.add_item(quick_action_bar, cx);
|
||||
// let diagnostic_editor_controls =
|
||||
// cx.add_view(|_| diagnostics2::ToolbarControls::new());
|
||||
// toolbar.add_item(diagnostic_editor_controls, cx);
|
||||
// let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
|
||||
// toolbar.add_item(project_search_bar, cx);
|
||||
// let submit_feedback_button =
|
||||
// cx.add_view(|_| SubmitFeedbackButton::new());
|
||||
// toolbar.add_item(submit_feedback_button, cx);
|
||||
// let feedback_info_text = cx.add_view(|_| FeedbackInfoText::new());
|
||||
// toolbar.add_item(feedback_info_text, cx);
|
||||
// let lsp_log_item =
|
||||
// cx.add_view(|_| language_tools::LspLogToolbarItemView::new());
|
||||
// toolbar.add_item(lsp_log_item, cx);
|
||||
// let syntax_tree_item = cx
|
||||
// .add_view(|_| language_tools::SyntaxTreeToolbarItemView::new());
|
||||
// toolbar.add_item(syntax_tree_item, cx);
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
// cx.emit(workspace2::Event::PaneAdded(
|
||||
// workspace.active_pane().clone(),
|
||||
// ));
|
||||
|
||||
// let copilot =
|
||||
// cx.add_view(|cx| copilot_button::CopilotButton::new(app_state.fs.clone(), cx));
|
||||
// let diagnostic_summary =
|
||||
// cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
|
||||
// let activity_indicator = activity_indicator::ActivityIndicator::new(
|
||||
// workspace,
|
||||
// app_state.languages.clone(),
|
||||
// cx,
|
||||
// );
|
||||
// let active_buffer_language =
|
||||
// cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
|
||||
// let vim_mode_indicator = cx.add_view(|cx| vim::ModeIndicator::new(cx));
|
||||
// let feedback_button = cx.add_view(|_| {
|
||||
// feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace)
|
||||
// });
|
||||
// let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
|
||||
workspace.status_bar().update(cx, |status_bar, cx| {
|
||||
// status_bar.add_left_item(diagnostic_summary, cx);
|
||||
// status_bar.add_left_item(activity_indicator, cx);
|
||||
|
||||
// status_bar.add_right_item(feedback_button, cx);
|
||||
// status_bar.add_right_item(copilot, cx);
|
||||
// status_bar.add_right_item(active_buffer_language, cx);
|
||||
// status_bar.add_right_item(vim_mode_indicator, cx);
|
||||
// status_bar.add_right_item(cursor_position, cx);
|
||||
});
|
||||
|
||||
// auto_update::notify_of_any_new_update(cx.weak_handle(), cx);
|
||||
|
||||
// vim::observe_keystrokes(cx);
|
||||
|
||||
// cx.on_window_should_close(|workspace, cx| {
|
||||
// if let Some(task) = workspace.close(&Default::default(), cx) {
|
||||
// task.detach_and_log_err(cx);
|
||||
// }
|
||||
// false
|
||||
// });
|
||||
})?;
|
||||
|
||||
let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
|
||||
// let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
|
||||
// let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone());
|
||||
let channels_panel =
|
||||
collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
|
||||
// let chat_panel =
|
||||
// collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
|
||||
// let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
|
||||
// workspace_handle.clone(),
|
||||
// cx.clone(),
|
||||
// );
|
||||
let (
|
||||
project_panel,
|
||||
// terminal_panel,
|
||||
// assistant_panel,
|
||||
channels_panel,
|
||||
// chat_panel,
|
||||
// notification_panel,
|
||||
) = futures::try_join!(
|
||||
project_panel,
|
||||
// terminal_panel,
|
||||
// assistant_panel,
|
||||
channels_panel,
|
||||
// chat_panel,
|
||||
// notification_panel,/
|
||||
)?;
|
||||
|
||||
workspace_handle.update(&mut cx, |workspace, cx| {
|
||||
let project_panel_position = project_panel.position(cx);
|
||||
workspace.add_panel(project_panel, cx);
|
||||
// workspace.add_panel(terminal_panel, cx);
|
||||
// workspace.add_panel(assistant_panel, cx);
|
||||
workspace.add_panel(channels_panel, cx);
|
||||
// workspace.add_panel(chat_panel, cx);
|
||||
// workspace.add_panel(notification_panel, cx);
|
||||
|
||||
// if !was_deserialized
|
||||
// && workspace
|
||||
// .project()
|
||||
// .read(cx)
|
||||
// .visible_worktrees(cx)
|
||||
// .any(|tree| {
|
||||
// tree.read(cx)
|
||||
// .root_entry()
|
||||
// .map_or(false, |entry| entry.is_dir())
|
||||
// })
|
||||
// {
|
||||
workspace.toggle_dock(project_panel_position, cx);
|
||||
// }
|
||||
// cx.focus_self();
|
||||
})?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
|
||||
let app_name = cx.global::<ReleaseChannel>().display_name();
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
|
Loading…
Reference in New Issue
Block a user