wip progress

This commit is contained in:
KCaverly 2023-10-31 10:49:51 -04:00
parent eb4ac2c276
commit 663e8aed8a
7 changed files with 472 additions and 438 deletions

View file

@ -1,6 +1,7 @@
use crate::{status_bar::StatusItemView, Axis, Workspace}; use crate::{status_bar::StatusItemView, Axis, Workspace};
use gpui2::{ use gpui2::{
Action, AnyView, EventEmitter, Render, Subscription, View, ViewContext, WeakView, WindowContext, Action, AnyView, Div, EventEmitter, Render, Subscription, View, ViewContext, WeakView,
WindowContext,
}; };
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -176,226 +177,226 @@ pub struct PanelButtons {
workspace: WeakView<Workspace>, workspace: WeakView<Workspace>,
} }
// impl Dock { impl Dock {
// pub fn new(position: DockPosition) -> Self { // pub fn new(position: DockPosition) -> Self {
// Self { // Self {
// position, // position,
// panel_entries: Default::default(), // panel_entries: Default::default(),
// active_panel_index: 0, // active_panel_index: 0,
// is_open: false, // is_open: false,
// } // }
// } // }
// pub fn position(&self) -> DockPosition { // pub fn position(&self) -> DockPosition {
// self.position // self.position
// } // }
// pub fn is_open(&self) -> bool { pub fn is_open(&self) -> bool {
// self.is_open self.is_open
// } }
// pub fn has_focus(&self, cx: &WindowContext) -> bool { // pub fn has_focus(&self, cx: &WindowContext) -> bool {
// self.visible_panel() // self.visible_panel()
// .map_or(false, |panel| panel.has_focus(cx)) // .map_or(false, |panel| panel.has_focus(cx))
// } // }
// pub fn panel<T: Panel>(&self) -> Option<View<T>> { // pub fn panel<T: Panel>(&self) -> Option<View<T>> {
// self.panel_entries // self.panel_entries
// .iter() // .iter()
// .find_map(|entry| entry.panel.as_any().clone().downcast()) // .find_map(|entry| entry.panel.as_any().clone().downcast())
// } // }
// pub fn panel_index_for_type<T: Panel>(&self) -> Option<usize> { // pub fn panel_index_for_type<T: Panel>(&self) -> Option<usize> {
// self.panel_entries // self.panel_entries
// .iter() // .iter()
// .position(|entry| entry.panel.as_any().is::<T>()) // .position(|entry| entry.panel.as_any().is::<T>())
// } // }
// pub fn panel_index_for_ui_name(&self, ui_name: &str, cx: &AppContext) -> Option<usize> { // pub fn panel_index_for_ui_name(&self, ui_name: &str, cx: &AppContext) -> Option<usize> {
// todo!() // todo!()
// // self.panel_entries.iter().position(|entry| { // // self.panel_entries.iter().position(|entry| {
// // let panel = entry.panel.as_any(); // // let panel = entry.panel.as_any();
// // cx.view_ui_name(panel.window(), panel.id()) == Some(ui_name) // // cx.view_ui_name(panel.window(), panel.id()) == Some(ui_name)
// // }) // // })
// } // }
// pub fn active_panel_index(&self) -> usize { // pub fn active_panel_index(&self) -> usize {
// self.active_panel_index // self.active_panel_index
// } // }
// pub(crate) fn set_open(&mut self, open: bool, cx: &mut ViewContext<Self>) { // pub(crate) fn set_open(&mut self, open: bool, cx: &mut ViewContext<Self>) {
// if open != self.is_open { // if open != self.is_open {
// self.is_open = open; // self.is_open = open;
// if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) { // if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
// active_panel.panel.set_active(open, cx); // active_panel.panel.set_active(open, cx);
// } // }
// cx.notify(); // cx.notify();
// } // }
// } // }
// pub fn set_panel_zoomed(&mut self, panel: &AnyView, zoomed: bool, cx: &mut ViewContext<Self>) { // pub fn set_panel_zoomed(&mut self, panel: &AnyView, zoomed: bool, cx: &mut ViewContext<Self>) {
// for entry in &mut self.panel_entries { // for entry in &mut self.panel_entries {
// if entry.panel.as_any() == panel { // if entry.panel.as_any() == panel {
// if zoomed != entry.panel.is_zoomed(cx) { // if zoomed != entry.panel.is_zoomed(cx) {
// entry.panel.set_zoomed(zoomed, cx); // entry.panel.set_zoomed(zoomed, cx);
// } // }
// } else if entry.panel.is_zoomed(cx) { // } else if entry.panel.is_zoomed(cx) {
// entry.panel.set_zoomed(false, cx); // entry.panel.set_zoomed(false, cx);
// } // }
// } // }
// cx.notify(); // cx.notify();
// } // }
// pub fn zoom_out(&mut self, cx: &mut ViewContext<Self>) { // pub fn zoom_out(&mut self, cx: &mut ViewContext<Self>) {
// for entry in &mut self.panel_entries { // for entry in &mut self.panel_entries {
// if entry.panel.is_zoomed(cx) { // if entry.panel.is_zoomed(cx) {
// entry.panel.set_zoomed(false, cx); // entry.panel.set_zoomed(false, cx);
// } // }
// } // }
// } // }
// pub(crate) fn add_panel<T: Panel>(&mut self, panel: View<T>, cx: &mut ViewContext<Self>) { // pub(crate) fn add_panel<T: Panel>(&mut self, panel: View<T>, cx: &mut ViewContext<Self>) {
// let subscriptions = [ // let subscriptions = [
// cx.observe(&panel, |_, _, cx| cx.notify()), // cx.observe(&panel, |_, _, cx| cx.notify()),
// cx.subscribe(&panel, |this, panel, event, cx| { // cx.subscribe(&panel, |this, panel, event, cx| {
// if T::should_activate_on_event(event) { // if T::should_activate_on_event(event) {
// if let Some(ix) = this // if let Some(ix) = this
// .panel_entries // .panel_entries
// .iter() // .iter()
// .position(|entry| entry.panel.id() == panel.id()) // .position(|entry| entry.panel.id() == panel.id())
// { // {
// this.set_open(true, cx); // this.set_open(true, cx);
// this.activate_panel(ix, cx); // this.activate_panel(ix, cx);
// cx.focus(&panel); // cx.focus(&panel);
// } // }
// } else if T::should_close_on_event(event) // } else if T::should_close_on_event(event)
// && this.visible_panel().map_or(false, |p| p.id() == panel.id()) // && this.visible_panel().map_or(false, |p| p.id() == panel.id())
// { // {
// this.set_open(false, cx); // this.set_open(false, cx);
// } // }
// }), // }),
// ]; // ];
// let dock_view_id = cx.view_id(); // let dock_view_id = cx.view_id();
// self.panel_entries.push(PanelEntry { // self.panel_entries.push(PanelEntry {
// panel: Arc::new(panel), // panel: Arc::new(panel),
// // todo!() // // todo!()
// // context_menu: cx.add_view(|cx| { // // context_menu: cx.add_view(|cx| {
// // let mut menu = ContextMenu::new(dock_view_id, cx); // // let mut menu = ContextMenu::new(dock_view_id, cx);
// // menu.set_position_mode(OverlayPositionMode::Local); // // menu.set_position_mode(OverlayPositionMode::Local);
// // menu // // menu
// // }), // // }),
// _subscriptions: subscriptions, // _subscriptions: subscriptions,
// }); // });
// cx.notify() // cx.notify()
// } // }
// pub fn remove_panel<T: Panel>(&mut self, panel: &View<T>, cx: &mut ViewContext<Self>) { // pub fn remove_panel<T: Panel>(&mut self, panel: &View<T>, cx: &mut ViewContext<Self>) {
// if let Some(panel_ix) = self // if let Some(panel_ix) = self
// .panel_entries // .panel_entries
// .iter() // .iter()
// .position(|entry| entry.panel.id() == panel.id()) // .position(|entry| entry.panel.id() == panel.id())
// { // {
// if panel_ix == self.active_panel_index { // if panel_ix == self.active_panel_index {
// self.active_panel_index = 0; // self.active_panel_index = 0;
// self.set_open(false, cx); // self.set_open(false, cx);
// } else if panel_ix < self.active_panel_index { // } else if panel_ix < self.active_panel_index {
// self.active_panel_index -= 1; // self.active_panel_index -= 1;
// } // }
// self.panel_entries.remove(panel_ix); // self.panel_entries.remove(panel_ix);
// cx.notify(); // cx.notify();
// } // }
// } // }
// pub fn panels_len(&self) -> usize { // pub fn panels_len(&self) -> usize {
// self.panel_entries.len() // self.panel_entries.len()
// } // }
// pub fn activate_panel(&mut self, panel_ix: usize, cx: &mut ViewContext<Self>) { // pub fn activate_panel(&mut self, panel_ix: usize, cx: &mut ViewContext<Self>) {
// if panel_ix != self.active_panel_index { // if panel_ix != self.active_panel_index {
// if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) { // if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
// active_panel.panel.set_active(false, cx); // active_panel.panel.set_active(false, cx);
// } // }
// self.active_panel_index = panel_ix; // self.active_panel_index = panel_ix;
// if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) { // if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
// active_panel.panel.set_active(true, cx); // active_panel.panel.set_active(true, cx);
// } // }
// cx.notify(); // cx.notify();
// } // }
// } // }
// pub fn visible_panel(&self) -> Option<&Arc<dyn PanelHandle>> { pub fn visible_panel(&self) -> Option<&Arc<dyn PanelHandle>> {
// let entry = self.visible_entry()?; let entry = self.visible_entry()?;
// Some(&entry.panel) Some(&entry.panel)
// } }
// pub fn active_panel(&self) -> Option<&Arc<dyn PanelHandle>> { // pub fn active_panel(&self) -> Option<&Arc<dyn PanelHandle>> {
// Some(&self.panel_entries.get(self.active_panel_index)?.panel) // Some(&self.panel_entries.get(self.active_panel_index)?.panel)
// } // }
// fn visible_entry(&self) -> Option<&PanelEntry> { fn visible_entry(&self) -> Option<&PanelEntry> {
// if self.is_open { if self.is_open {
// self.panel_entries.get(self.active_panel_index) self.panel_entries.get(self.active_panel_index)
// } else { } else {
// None None
// } }
// } }
// pub fn zoomed_panel(&self, cx: &WindowContext) -> Option<Arc<dyn PanelHandle>> { // pub fn zoomed_panel(&self, cx: &WindowContext) -> Option<Arc<dyn PanelHandle>> {
// let entry = self.visible_entry()?; // let entry = self.visible_entry()?;
// if entry.panel.is_zoomed(cx) { // if entry.panel.is_zoomed(cx) {
// Some(entry.panel.clone()) // Some(entry.panel.clone())
// } else { // } else {
// None // None
// } // }
// } // }
// pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option<f32> { // pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option<f32> {
// self.panel_entries // self.panel_entries
// .iter() // .iter()
// .find(|entry| entry.panel.id() == panel.id()) // .find(|entry| entry.panel.id() == panel.id())
// .map(|entry| entry.panel.size(cx)) // .map(|entry| entry.panel.size(cx))
// } // }
// pub fn active_panel_size(&self, cx: &WindowContext) -> Option<f32> { // pub fn active_panel_size(&self, cx: &WindowContext) -> Option<f32> {
// if self.is_open { // if self.is_open {
// self.panel_entries // self.panel_entries
// .get(self.active_panel_index) // .get(self.active_panel_index)
// .map(|entry| entry.panel.size(cx)) // .map(|entry| entry.panel.size(cx))
// } else { // } else {
// None // None
// } // }
// } // }
// pub fn resize_active_panel(&mut self, size: Option<f32>, cx: &mut ViewContext<Self>) { // pub fn resize_active_panel(&mut self, size: Option<f32>, cx: &mut ViewContext<Self>) {
// if let Some(entry) = self.panel_entries.get_mut(self.active_panel_index) { // if let Some(entry) = self.panel_entries.get_mut(self.active_panel_index) {
// entry.panel.set_size(size, cx); // entry.panel.set_size(size, cx);
// cx.notify(); // cx.notify();
// } // }
// } // }
// pub fn render_placeholder(&self, cx: &WindowContext) -> AnyElement<Workspace> { // pub fn render_placeholder(&self, cx: &WindowContext) -> AnyElement<Workspace> {
// todo!() // todo!()
// if let Some(active_entry) = self.visible_entry() { // if let Some(active_entry) = self.visible_entry() {
// Empty::new() // Empty::new()
// .into_any() // .into_any()
// .contained() // .contained()
// .with_style(self.style(cx)) // .with_style(self.style(cx))
// .resizable::<WorkspaceBounds>( // .resizable::<WorkspaceBounds>(
// self.position.to_resize_handle_side(), // self.position.to_resize_handle_side(),
// active_entry.panel.size(cx), // active_entry.panel.size(cx),
// |_, _, _| {}, // |_, _, _| {},
// ) // )
// .into_any() // .into_any()
// } else { // } else {
// Empty::new().into_any() // Empty::new().into_any()
// } // }
// } // }
// } }
// todo!() // todo!()
// impl View for Dock { // impl View for Dock {
@ -596,15 +597,23 @@ impl EventEmitter for PanelButtons {
// } // }
// } // }
// impl StatusItemView for PanelButtons { impl Render for PanelButtons {
// fn set_active_pane_item( type Element = Div<Self>;
// &mut self,
// active_pane_item: Option<&dyn crate::ItemHandle>, fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
// cx: &mut ViewContext<Self>, todo!()
// ) { }
// todo!() }
// }
// } impl StatusItemView for PanelButtons {
fn set_active_pane_item(
&mut self,
active_pane_item: Option<&dyn crate::ItemHandle>,
cx: &mut ViewContext<Self>,
) {
todo!()
}
}
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
pub mod test { pub mod test {

View file

@ -691,58 +691,58 @@ pub trait FollowableItemHandle: ItemHandle {
fn is_project_item(&self, cx: &AppContext) -> bool; fn is_project_item(&self, cx: &AppContext) -> bool;
} }
// impl<T: FollowableItem> FollowableItemHandle for View<T> { impl<T: FollowableItem> FollowableItemHandle for View<T> {
// fn remote_id(&self, client: &Arc<Client>, cx: &AppContext) -> Option<ViewId> { fn remote_id(&self, client: &Arc<Client>, cx: &AppContext) -> Option<ViewId> {
// self.read(cx).remote_id().or_else(|| { self.read(cx).remote_id().or_else(|| {
// client.peer_id().map(|creator| ViewId { client.peer_id().map(|creator| ViewId {
// creator, creator,
// id: self.id() as u64, id: self.id() as u64,
// }) })
// }) })
// } }
// fn set_leader_peer_id(&self, leader_peer_id: Option<PeerId>, cx: &mut WindowContext) { fn set_leader_peer_id(&self, leader_peer_id: Option<PeerId>, cx: &mut WindowContext) {
// self.update(cx, |this, cx| this.set_leader_peer_id(leader_peer_id, cx)) self.update(cx, |this, cx| this.set_leader_peer_id(leader_peer_id, cx))
// } }
// fn to_state_proto(&self, cx: &AppContext) -> Option<proto::view::Variant> { fn to_state_proto(&self, cx: &AppContext) -> Option<proto::view::Variant> {
// self.read(cx).to_state_proto(cx) self.read(cx).to_state_proto(cx)
// } }
// fn add_event_to_update_proto( fn add_event_to_update_proto(
// &self, &self,
// event: &dyn Any, event: &dyn Any,
// update: &mut Option<proto::update_view::Variant>, update: &mut Option<proto::update_view::Variant>,
// cx: &AppContext, cx: &AppContext,
// ) -> bool { ) -> bool {
// if let Some(event) = event.downcast_ref() { if let Some(event) = event.downcast_ref() {
// self.read(cx).add_event_to_update_proto(event, update, cx) self.read(cx).add_event_to_update_proto(event, update, cx)
// } else { } else {
// false false
// } }
// } }
// fn apply_update_proto( fn apply_update_proto(
// &self, &self,
// project: &Model<Project>, project: &Model<Project>,
// message: proto::update_view::Variant, message: proto::update_view::Variant,
// cx: &mut WindowContext, cx: &mut WindowContext,
// ) -> Task<Result<()>> { ) -> Task<Result<()>> {
// self.update(cx, |this, cx| this.apply_update_proto(project, message, cx)) self.update(cx, |this, cx| this.apply_update_proto(project, message, cx))
// } }
// fn should_unfollow_on_event(&self, event: &dyn Any, cx: &AppContext) -> bool { fn should_unfollow_on_event(&self, event: &dyn Any, cx: &AppContext) -> bool {
// if let Some(event) = event.downcast_ref() { if let Some(event) = event.downcast_ref() {
// T::should_unfollow_on_event(event, cx) T::should_unfollow_on_event(event, cx)
// } else { } else {
// false false
// } }
// } }
// fn is_project_item(&self, cx: &AppContext) -> bool { fn is_project_item(&self, cx: &AppContext) -> bool {
// self.read(cx).is_project_item(cx) self.read(cx).is_project_item(cx)
// } }
// } }
// #[cfg(any(test, feature = "test-support"))] // #[cfg(any(test, feature = "test-support"))]
// pub mod test { // pub mod test {

View file

@ -178,7 +178,7 @@ pub struct Pane {
// tab_context_menu: ViewHandle<ContextMenu>, // tab_context_menu: ViewHandle<ContextMenu>,
// workspace: WeakView<Workspace>, // workspace: WeakView<Workspace>,
project: Model<Project>, project: Model<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,
// render_tab_bar_buttons: Rc<dyn Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>>, // render_tab_bar_buttons: Rc<dyn Fn(&mut Pane, &mut ViewContext<Pane>) -> AnyElement<Pane>>,
@ -348,7 +348,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)),
// workspace, // workspace,
project, project,
// has_focus: false, has_focus: false,
// can_drop: Rc::new(|_, _| true), // can_drop: Rc::new(|_, _| true),
// can_split: true, // can_split: true,
// render_tab_bar_buttons: Rc::new(move |pane, cx| { // render_tab_bar_buttons: Rc::new(move |pane, cx| {
@ -415,9 +415,9 @@ impl Pane {
// &self.workspace // &self.workspace
// } // }
// pub fn has_focus(&self) -> bool { pub fn has_focus(&self) -> bool {
// self.has_focus self.has_focus
// } }
// pub fn active_item_index(&self) -> usize { // pub fn active_item_index(&self) -> usize {
// self.active_item_index // self.active_item_index
@ -614,9 +614,9 @@ impl Pane {
self.items.len() self.items.len()
} }
// pub fn items(&self) -> impl Iterator<Item = &Box<dyn ItemHandle>> + DoubleEndedIterator { pub fn items(&self) -> impl Iterator<Item = &Box<dyn ItemHandle>> + DoubleEndedIterator {
// self.items.iter() self.items.iter()
// } }
// pub fn items_of_type<T: View>(&self) -> impl '_ + Iterator<Item = ViewHandle<T>> { // pub fn items_of_type<T: View>(&self) -> impl '_ + Iterator<Item = ViewHandle<T>> {
// self.items // self.items

View file

@ -2,22 +2,24 @@ use crate::{AppState, FollowerState, Pane, Workspace};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use call2::ActiveCall; use call2::ActiveCall;
use collections::HashMap; use collections::HashMap;
use gpui2::{size, AnyElement, AnyView, Bounds, Handle, Model, Pixels, Point, View, ViewContext}; use gpui2::{point, size, AnyElement, AnyView, Bounds, Model, Pixels, Point, View, ViewContext};
use parking_lot::Mutex;
use project2::Project; use project2::Project;
use serde::Deserialize; use serde::Deserialize;
use std::{cell::RefCell, rc::Rc, sync::Arc}; use std::sync::Arc;
use theme2::Theme; use theme2::Theme;
const HANDLE_HITBOX_SIZE: f32 = 4.0; const HANDLE_HITBOX_SIZE: f32 = 4.0;
const HORIZONTAL_MIN_SIZE: f32 = 80.; const HORIZONTAL_MIN_SIZE: f32 = 80.;
const VERTICAL_MIN_SIZE: f32 = 100.; const VERTICAL_MIN_SIZE: f32 = 100.;
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Axis { pub enum Axis {
Vertical, Vertical,
Horizontal, Horizontal,
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, PartialEq)]
pub struct PaneGroup { pub struct PaneGroup {
pub(crate) root: Member, pub(crate) root: Member,
} }
@ -305,18 +307,24 @@ impl Member {
} }
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone)]
pub(crate) struct PaneAxis { pub(crate) struct PaneAxis {
pub axis: Axis, pub axis: Axis,
pub members: Vec<Member>, pub members: Vec<Member>,
pub flexes: Rc<RefCell<Vec<f32>>>, pub flexes: Arc<Mutex<Vec<f32>>>,
pub bounding_boxes: Rc<RefCell<Vec<Option<Bounds<Pixels>>>>>, pub bounding_boxes: Arc<Mutex<Vec<Option<Bounds<Pixels>>>>>,
}
impl PartialEq for PaneAxis {
fn eq(&self, other: &Self) -> bool {
todo!()
}
} }
impl PaneAxis { impl PaneAxis {
pub fn new(axis: Axis, members: Vec<Member>) -> Self { pub fn new(axis: Axis, members: Vec<Member>) -> Self {
let flexes = Rc::new(RefCell::new(vec![1.; members.len()])); let flexes = Arc::new(Mutex::new(vec![1.; members.len()]));
let bounding_boxes = Rc::new(RefCell::new(vec![None; members.len()])); let bounding_boxes = Arc::new(Mutex::new(vec![None; members.len()]));
Self { Self {
axis, axis,
members, members,
@ -329,8 +337,8 @@ impl PaneAxis {
let flexes = flexes.unwrap_or_else(|| vec![1.; members.len()]); let flexes = flexes.unwrap_or_else(|| vec![1.; members.len()]);
debug_assert!(members.len() == flexes.len()); debug_assert!(members.len() == flexes.len());
let flexes = Rc::new(RefCell::new(flexes)); let flexes = Arc::new(Mutex::new(flexes));
let bounding_boxes = Rc::new(RefCell::new(vec![None; members.len()])); let bounding_boxes = Arc::new(Mutex::new(vec![None; members.len()]));
Self { Self {
axis, axis,
members, members,
@ -360,7 +368,7 @@ impl PaneAxis {
} }
self.members.insert(idx, Member::Pane(new_pane.clone())); self.members.insert(idx, Member::Pane(new_pane.clone()));
*self.flexes.borrow_mut() = vec![1.; self.members.len()]; *self.flexes.lock() = vec![1.; self.members.len()];
} else { } else {
*member = *member =
Member::new_axis(old_pane.clone(), new_pane.clone(), direction); Member::new_axis(old_pane.clone(), new_pane.clone(), direction);
@ -400,12 +408,12 @@ impl PaneAxis {
if found_pane { if found_pane {
if let Some(idx) = remove_member { if let Some(idx) = remove_member {
self.members.remove(idx); self.members.remove(idx);
*self.flexes.borrow_mut() = vec![1.; self.members.len()]; *self.flexes.lock() = vec![1.; self.members.len()];
} }
if self.members.len() == 1 { if self.members.len() == 1 {
let result = self.members.pop(); let result = self.members.pop();
*self.flexes.borrow_mut() = vec![1.; self.members.len()]; *self.flexes.lock() = vec![1.; self.members.len()];
Ok(result) Ok(result)
} else { } else {
Ok(None) Ok(None)
@ -431,13 +439,13 @@ impl PaneAxis {
} }
fn bounding_box_for_pane(&self, pane: &View<Pane>) -> Option<Bounds<Pixels>> { fn bounding_box_for_pane(&self, pane: &View<Pane>) -> Option<Bounds<Pixels>> {
debug_assert!(self.members.len() == self.bounding_boxes.borrow().len()); debug_assert!(self.members.len() == self.bounding_boxes.lock().len());
for (idx, member) in self.members.iter().enumerate() { for (idx, member) in self.members.iter().enumerate() {
match member { match member {
Member::Pane(found) => { Member::Pane(found) => {
if pane == found { if pane == found {
return self.bounding_boxes.borrow()[idx]; return self.bounding_boxes.lock()[idx];
} }
} }
Member::Axis(axis) => { Member::Axis(axis) => {
@ -451,9 +459,9 @@ impl PaneAxis {
} }
fn pane_at_pixel_position(&self, coordinate: Point<Pixels>) -> Option<&View<Pane>> { fn pane_at_pixel_position(&self, coordinate: Point<Pixels>) -> Option<&View<Pane>> {
debug_assert!(self.members.len() == self.bounding_boxes.borrow().len()); debug_assert!(self.members.len() == self.bounding_boxes.lock().len());
let bounding_boxes = self.bounding_boxes.borrow(); let bounding_boxes = self.bounding_boxes.lock();
for (idx, member) in self.members.iter().enumerate() { for (idx, member) in self.members.iter().enumerate() {
if let Some(coordinates) = bounding_boxes[idx] { if let Some(coordinates) = bounding_boxes[idx] {
@ -480,7 +488,7 @@ impl PaneAxis {
app_state: &Arc<AppState>, app_state: &Arc<AppState>,
cx: &mut ViewContext<Workspace>, cx: &mut ViewContext<Workspace>,
) -> AnyElement<Workspace> { ) -> AnyElement<Workspace> {
debug_assert!(self.members.len() == self.flexes.borrow().len()); debug_assert!(self.members.len() == self.flexes.lock().len());
todo!() todo!()
// let mut pane_axis = PaneAxisElement::new( // let mut pane_axis = PaneAxisElement::new(
@ -546,32 +554,32 @@ impl SplitDirection {
[Self::Up, Self::Down, Self::Left, Self::Right] [Self::Up, Self::Down, Self::Left, Self::Right]
} }
pub fn edge(&self, rect: Bounds<Pixels>) -> f32 { pub fn edge(&self, rect: Bounds<Pixels>) -> Pixels {
match self { match self {
Self::Up => rect.min_y(), Self::Up => rect.origin.y,
Self::Down => rect.max_y(), Self::Down => rect.lower_left().y,
Self::Left => rect.min_x(), Self::Left => rect.lower_left().x,
Self::Right => rect.max_x(), Self::Right => rect.lower_right().x,
} }
} }
pub fn along_edge(&self, bounds: Bounds<Pixels>, length: Pixels) -> Bounds<Pixels> { pub fn along_edge(&self, bounds: Bounds<Pixels>, length: Pixels) -> Bounds<Pixels> {
match self { match self {
Self::Up => Bounds { Self::Up => Bounds {
origin: bounds.origin(), origin: bounds.origin,
size: size(bounds.width(), length), size: size(bounds.size.width, length),
}, },
Self::Down => Bounds { Self::Down => Bounds {
origin: size(bounds.min_x(), bounds.max_y() - length), origin: point(bounds.lower_left().x, bounds.lower_left().y - length),
size: size(bounds.width(), length), size: size(bounds.size.width, length),
}, },
Self::Left => Bounds { Self::Left => Bounds {
origin: bounds.origin(), origin: bounds.origin,
size: size(length, bounds.height()), size: size(length, bounds.size.height),
}, },
Self::Right => Bounds { Self::Right => Bounds {
origin: size(bounds.max_x() - length, bounds.min_y()), origin: point(bounds.lower_right().x - length, bounds.lower_left().y),
size: size(length, bounds.height()), size: size(length, bounds.size.height),
}, },
} }
} }

View file

@ -55,7 +55,7 @@ impl Column for WorkspaceLocation {
} }
} }
#[derive(Debug, PartialEq, Clone)] #[derive(PartialEq, Clone)]
pub struct SerializedWorkspace { pub struct SerializedWorkspace {
pub id: WorkspaceId, pub id: WorkspaceId,
pub location: WorkspaceLocation, pub location: WorkspaceLocation,
@ -127,7 +127,7 @@ impl Bind for DockData {
} }
} }
#[derive(Debug, PartialEq, Clone)] #[derive(PartialEq, Clone)]
pub enum SerializedPaneGroup { pub enum SerializedPaneGroup {
Group { Group {
axis: Axis, axis: Axis,

View file

@ -1,6 +1,6 @@
use std::{any::Any, sync::Arc}; use std::{any::Any, sync::Arc};
use gpui2::{AppContext, Subscription, Task, View, ViewContext, WindowContext}; use gpui2::{AnyView, AppContext, Subscription, Task, View, ViewContext, WindowContext};
use project2::search::SearchQuery; use project2::search::SearchQuery;
use crate::{ use crate::{
@ -95,7 +95,7 @@ pub trait SearchableItemHandle: ItemHandle {
fn subscribe_to_search_events( fn subscribe_to_search_events(
&self, &self,
cx: &mut WindowContext, cx: &mut WindowContext,
handler: Box<dyn Fn(SearchEvent, &mut WindowContext)>, handler: Box<dyn Fn(SearchEvent, &mut WindowContext) + Send>,
) -> Subscription; ) -> Subscription;
fn clear_matches(&self, cx: &mut WindowContext); fn clear_matches(&self, cx: &mut WindowContext);
fn update_matches(&self, matches: &Vec<Box<dyn Any + Send>>, cx: &mut WindowContext); fn update_matches(&self, matches: &Vec<Box<dyn Any + Send>>, cx: &mut WindowContext);
@ -130,7 +130,8 @@ pub trait SearchableItemHandle: ItemHandle {
impl<T: SearchableItem> SearchableItemHandle for View<T> { impl<T: SearchableItem> SearchableItemHandle for View<T> {
fn downgrade(&self) -> Box<dyn WeakSearchableItemHandle> { fn downgrade(&self) -> Box<dyn WeakSearchableItemHandle> {
Box::new(self.downgrade()) // Box::new(self.downgrade())
todo!()
} }
fn boxed_clone(&self) -> Box<dyn SearchableItemHandle> { fn boxed_clone(&self) -> Box<dyn SearchableItemHandle> {
@ -144,7 +145,7 @@ impl<T: SearchableItem> SearchableItemHandle for View<T> {
fn subscribe_to_search_events( fn subscribe_to_search_events(
&self, &self,
cx: &mut WindowContext, cx: &mut WindowContext,
handler: Box<dyn Fn(SearchEvent, &mut WindowContext)>, handler: Box<dyn Fn(SearchEvent, &mut WindowContext) + Send>,
) -> Subscription { ) -> Subscription {
cx.subscribe(self, move |handle, event, cx| { cx.subscribe(self, move |handle, event, cx| {
let search_event = handle.update(cx, |handle, cx| handle.to_search_event(event, cx)); let search_event = handle.update(cx, |handle, cx| handle.to_search_event(event, cx));
@ -198,7 +199,7 @@ impl<T: SearchableItem> SearchableItemHandle for View<T> {
cx: &mut WindowContext, cx: &mut WindowContext,
) -> Task<Vec<Box<dyn Any + Send>>> { ) -> Task<Vec<Box<dyn Any + Send>>> {
let matches = self.update(cx, |this, cx| this.find_matches(query, cx)); let matches = self.update(cx, |this, cx| this.find_matches(query, cx));
cx.foreground().spawn(async { cx.spawn_on_main(|cx| async {
let matches = matches.await; let matches = matches.await;
matches matches
.into_iter() .into_iter()
@ -231,23 +232,21 @@ fn downcast_matches<T: Any + Clone>(matches: &Vec<Box<dyn Any + Send>>) -> Vec<T
) )
} }
// todo!() impl From<Box<dyn SearchableItemHandle>> for AnyView {
// impl From<Box<dyn SearchableItemHandle>> for AnyViewHandle { fn from(this: Box<dyn SearchableItemHandle>) -> Self {
// fn from(this: Box<dyn SearchableItemHandle>) -> Self { this.to_any().clone()
// this.as_any().clone() }
// } }
// }
// todo!() impl From<&Box<dyn SearchableItemHandle>> for AnyView {
// impl From<&Box<dyn SearchableItemHandle>> for AnyViewHandle { fn from(this: &Box<dyn SearchableItemHandle>) -> Self {
// fn from(this: &Box<dyn SearchableItemHandle>) -> Self { this.to_any().clone()
// this.as_any().clone() }
// } }
// }
impl PartialEq for Box<dyn SearchableItemHandle> { impl PartialEq for Box<dyn SearchableItemHandle> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.id() == other.id() && self.window() == other.window() self.id() == other.id()
} }
} }
@ -256,24 +255,23 @@ impl Eq for Box<dyn SearchableItemHandle> {}
pub trait WeakSearchableItemHandle: WeakItemHandle { pub trait WeakSearchableItemHandle: WeakItemHandle {
fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>>; fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>>;
// todo!() // fn into_any(self) -> AnyWeakView;
// fn into_any(self) -> AnyWeakViewHandle;
} }
// todo!() // todo!()
// impl<T: SearchableItem> WeakSearchableItemHandle for WeakViewHandle<T> { // impl<T: SearchableItem> WeakSearchableItemHandle for WeakView<T> {
// fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>> { // fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>> {
// Some(Box::new(self.upgrade(cx)?)) // Some(Box::new(self.upgrade(cx)?))
// } // }
// fn into_any(self) -> AnyWeakViewHandle { // // fn into_any(self) -> AnyView {
// self.into_any() // // self.into_any()
// } // // }
// } // }
impl PartialEq for Box<dyn WeakSearchableItemHandle> { impl PartialEq for Box<dyn WeakSearchableItemHandle> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.id() == other.id() && self.window() == other.window() self.id() == other.id()
} }
} }
@ -281,6 +279,6 @@ impl Eq for Box<dyn WeakSearchableItemHandle> {}
impl std::hash::Hash for Box<dyn WeakSearchableItemHandle> { impl std::hash::Hash for Box<dyn WeakSearchableItemHandle> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) { fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
(self.id(), self.window().id()).hash(state) self.id().hash(state)
} }
} }

View file

@ -11,21 +11,25 @@ mod toolbar;
mod workspace_settings; mod workspace_settings;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use call2::ActiveCall;
use client2::{ use client2::{
proto::{self, PeerId}, proto::{self, PeerId},
Client, UserStore, Client, UserStore,
}; };
use collections::{HashMap, HashSet}; use collections::{HashMap, HashSet};
use dock::Dock;
use futures::{channel::oneshot, FutureExt}; use futures::{channel::oneshot, FutureExt};
use gpui2::{ use gpui2::{
AnyModel, AnyView, AppContext, AsyncAppContext, DisplayId, MainThread, Model, Task, View, AnyModel, AnyView, AppContext, AsyncAppContext, DisplayId, EventEmitter, MainThread, Model,
ViewContext, VisualContext, WeakModel, WeakView, WindowBounds, WindowHandle, WindowOptions, Subscription, Task, View, ViewContext, VisualContext, WeakModel, WeakView, WindowBounds,
WindowHandle, WindowOptions,
}; };
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem}; use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem};
use language2::LanguageRegistry; use language2::LanguageRegistry;
use node_runtime::NodeRuntime; use node_runtime::NodeRuntime;
pub use pane::*; pub use pane::*;
pub use pane_group::*; pub use pane_group::*;
use persistence::model::{ItemId, WorkspaceLocation};
use project2::{Project, ProjectEntryId, ProjectPath, Worktree}; use project2::{Project, ProjectEntryId, ProjectPath, Worktree};
use std::{ use std::{
any::TypeId, any::TypeId,
@ -37,7 +41,8 @@ pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
use util::ResultExt; use util::ResultExt;
use crate::persistence::model::{ use crate::persistence::model::{
DockStructure, SerializedItem, SerializedPane, SerializedPaneGroup, SerializedWorkspace, DockData, DockStructure, SerializedItem, SerializedPane, SerializedPaneGroup,
SerializedWorkspace,
}; };
// lazy_static! { // lazy_static! {
@ -386,14 +391,13 @@ type ItemDeserializers = HashMap<
) -> Task<Result<Box<dyn ItemHandle>>>, ) -> Task<Result<Box<dyn ItemHandle>>>,
>; >;
pub fn register_deserializable_item<I: Item>(cx: &mut AppContext) { pub fn register_deserializable_item<I: Item>(cx: &mut AppContext) {
cx.update_default_global(|deserializers: &mut ItemDeserializers, _cx| { cx.update_global(|deserializers: &mut ItemDeserializers, _cx| {
if let Some(serialized_item_kind) = I::serialized_item_kind() { if let Some(serialized_item_kind) = I::serialized_item_kind() {
deserializers.insert( deserializers.insert(
Arc::from(serialized_item_kind), Arc::from(serialized_item_kind),
|project, workspace, workspace_id, item_id, cx| { |project, workspace, workspace_id, item_id, cx| {
let task = I::deserialize(project, workspace, workspace_id, item_id, cx); let task = I::deserialize(project, workspace, workspace_id, item_id, cx);
cx.foreground() cx.spawn_on_main(|cx| async { Ok(Box::new(task.await?) as Box<_>) })
.spawn(async { Ok(Box::new(task.await?) as Box<_>) })
}, },
); );
} }
@ -426,6 +430,7 @@ struct Follower {
peer_id: PeerId, peer_id: PeerId,
} }
// todo!()
// impl AppState { // impl AppState {
// #[cfg(any(test, feature = "test-support"))] // #[cfg(any(test, feature = "test-support"))]
// pub fn test(cx: &mut AppContext) -> Arc<Self> { // pub fn test(cx: &mut AppContext) -> Arc<Self> {
@ -476,7 +481,7 @@ impl DelayedDebouncedEditAction {
fn fire_new<F>(&mut self, delay: Duration, cx: &mut ViewContext<Workspace>, func: F) fn fire_new<F>(&mut self, delay: Duration, cx: &mut ViewContext<Workspace>, func: F)
where where
F: 'static + FnOnce(&mut Workspace, &mut ViewContext<Workspace>) -> Task<Result<()>>, F: 'static + Send + FnOnce(&mut Workspace, &mut ViewContext<Workspace>) -> Task<Result<()>>,
{ {
if let Some(channel) = self.cancel_channel.take() { if let Some(channel) = self.cancel_channel.take() {
_ = channel.send(()); _ = channel.send(());
@ -517,7 +522,7 @@ pub struct Workspace {
// modal: Option<ActiveModal>, // modal: Option<ActiveModal>,
// zoomed: Option<AnyWeakViewHandle>, // zoomed: Option<AnyWeakViewHandle>,
// zoomed_position: Option<DockPosition>, // zoomed_position: Option<DockPosition>,
// center: PaneGroup, center: PaneGroup,
left_dock: View<Dock>, left_dock: View<Dock>,
bottom_dock: View<Dock>, bottom_dock: View<Dock>,
right_dock: View<Dock>, right_dock: View<Dock>,
@ -533,9 +538,9 @@ pub struct Workspace {
follower_states: HashMap<View<Pane>, FollowerState>, follower_states: HashMap<View<Pane>, FollowerState>,
last_leaders_by_pane: HashMap<WeakView<Pane>, PeerId>, last_leaders_by_pane: HashMap<WeakView<Pane>, PeerId>,
// window_edited: bool, // window_edited: bool,
// active_call: Option<(ModelHandle<ActiveCall>, Vec<Subscription>)>, active_call: Option<(Model<ActiveCall>, Vec<Subscription>)>,
// leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>, // leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
// database_id: WorkspaceId, database_id: WorkspaceId,
app_state: Arc<AppState>, app_state: Arc<AppState>,
// subscriptions: Vec<Subscription>, // subscriptions: Vec<Subscription>,
// _apply_leader_updates: Task<Result<()>>, // _apply_leader_updates: Task<Result<()>>,
@ -1925,19 +1930,21 @@ impl Workspace {
// } // }
fn add_pane(&mut self, cx: &mut ViewContext<Self>) -> View<Pane> { fn add_pane(&mut self, cx: &mut ViewContext<Self>) -> View<Pane> {
let pane = cx.build_view(|cx| { todo!()
Pane::new( // let pane = cx.build_view(|cx| {
self.weak_handle(), // Pane::new(
self.project.clone(), // self.weak_handle(),
self.pane_history_timestamp.clone(), // self.project.clone(),
cx, // self.pane_history_timestamp.clone(),
) // cx,
}); // )
cx.subscribe(&pane, Self::handle_pane_event).detach(); // });
self.panes.push(pane.clone()); // cx.subscribe(&pane, Self::handle_pane_event).detach();
cx.focus(&pane); // self.panes.push(pane.clone());
cx.emit(Event::PaneAdded(pane.clone())); // todo!()
pane // cx.focus(&pane);
// cx.emit(Event::PaneAdded(pane.clone()));
// pane
} }
// pub fn add_item_to_center( // pub fn add_item_to_center(
@ -2083,19 +2090,19 @@ impl Workspace {
) -> Task< ) -> Task<
Result<( Result<(
ProjectEntryId, ProjectEntryId,
impl 'static + FnOnce(&mut ViewContext<Pane>) -> Box<dyn ItemHandle>, impl 'static + Send + FnOnce(&mut ViewContext<Pane>) -> Box<dyn ItemHandle>,
)>, )>,
> { > {
let project = self.project().clone(); let project = self.project().clone();
let project_item = project.update(cx, |project, cx| project.open_path(path, cx)); let project_item = project.update(cx, |project, cx| project.open_path(path, cx));
cx.spawn(|_, mut cx| async move { cx.spawn(|_, cx| async move {
let (project_entry_id, project_item) = project_item.await?; let (project_entry_id, project_item) = project_item.await?;
let build_item = cx.update(|cx| { let build_item = cx.update(|cx| {
cx.default_global::<ProjectItemBuilders>() cx.default_global::<ProjectItemBuilders>()
.get(&project_item.model_type()) .get(&project_item.type_id())
.ok_or_else(|| anyhow!("no item builder for project item")) .ok_or_else(|| anyhow!("no item builder for project item"))
.cloned() .cloned()
})?; })??;
let build_item = let build_item =
move |cx: &mut ViewContext<Pane>| build_item(project, project_item, cx); move |cx: &mut ViewContext<Pane>| build_item(project, project_item, cx);
Ok((project_entry_id, build_item)) Ok((project_entry_id, build_item))
@ -3012,14 +3019,14 @@ impl Workspace {
&self, &self,
project_only: bool, project_only: bool,
update: proto::update_followers::Variant, update: proto::update_followers::Variant,
cx: &AppContext, cx: &mut AppContext,
) -> Option<()> { ) -> Option<()> {
let project_id = if project_only { let project_id = if project_only {
self.project.read(cx).remote_id() self.project.read(cx).remote_id()
} else { } else {
None None
}; };
self.app_state().workspace_store.read_with(cx, |store, cx| { self.app_state().workspace_store.update(cx, |store, cx| {
store.update_followers(project_id, update, cx) store.update_followers(project_id, update, cx)
}) })
} }
@ -3141,9 +3148,9 @@ impl Workspace {
// } // }
// } // }
// fn active_call(&self) -> Option<&ModelHandle<ActiveCall>> { fn active_call(&self) -> Option<&Model<ActiveCall>> {
// self.active_call.as_ref().map(|(call, _)| call) self.active_call.as_ref().map(|(call, _)| call)
// } }
// fn on_active_call_event( // fn on_active_call_event(
// &mut self, // &mut self,
@ -3164,21 +3171,21 @@ impl Workspace {
// self.database_id // self.database_id
// } // }
// fn location(&self, cx: &AppContext) -> Option<WorkspaceLocation> { fn location(&self, cx: &AppContext) -> Option<WorkspaceLocation> {
// let project = self.project().read(cx); let project = self.project().read(cx);
// if project.is_local() { if project.is_local() {
// Some( Some(
// project project
// .visible_worktrees(cx) .visible_worktrees(cx)
// .map(|worktree| worktree.read(cx).abs_path()) .map(|worktree| worktree.read(cx).abs_path())
// .collect::<Vec<_>>() .collect::<Vec<_>>()
// .into(), .into(),
// ) )
// } else { } else {
// None None
// } }
// } }
// fn remove_panes(&mut self, member: Member, cx: &mut ViewContext<Workspace>) { // fn remove_panes(&mut self, member: Member, cx: &mut ViewContext<Workspace>) {
// match member { // match member {
@ -3193,14 +3200,17 @@ impl Workspace {
// } // }
// } // }
// fn force_remove_pane(&mut self, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) { fn force_remove_pane(&mut self, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
// self.panes.retain(|p| p != pane); self.panes.retain(|p| p != pane);
// cx.focus(self.panes.last().unwrap()); if true {
// if self.last_active_center_pane == Some(pane.downgrade()) { todo!()
// self.last_active_center_pane = None; // cx.focus(self.panes.last().unwrap());
// } }
// cx.notify(); if self.last_active_center_pane == Some(pane.downgrade()) {
// } self.last_active_center_pane = None;
}
cx.notify();
}
// fn schedule_serialize(&mut self, cx: &mut ViewContext<Self>) { // fn schedule_serialize(&mut self, cx: &mut ViewContext<Self>) {
// self._schedule_serialize = Some(cx.spawn(|this, cx| async move { // self._schedule_serialize = Some(cx.spawn(|this, cx| async move {
@ -3248,7 +3258,7 @@ impl Workspace {
.iter() .iter()
.map(|member| build_serialized_pane_group(member, cx)) .map(|member| build_serialized_pane_group(member, cx))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
flexes: Some(flexes.borrow().clone()), flexes: Some(flexes.lock().clone()),
}, },
Member::Pane(pane_handle) => { Member::Pane(pane_handle) => {
SerializedPaneGroup::Pane(serialize_pane_handle(&pane_handle, cx)) SerializedPaneGroup::Pane(serialize_pane_handle(&pane_handle, cx))
@ -3260,10 +3270,11 @@ impl Workspace {
let left_dock = this.left_dock.read(cx); let left_dock = this.left_dock.read(cx);
let left_visible = left_dock.is_open(); let left_visible = left_dock.is_open();
let left_active_panel = left_dock.visible_panel().and_then(|panel| { let left_active_panel = left_dock.visible_panel().and_then(|panel| {
Some( todo!()
cx.view_ui_name(panel.as_any().window(), panel.id())? // Some(
.to_string(), // cx.view_ui_name(panel.as_any().window(), panel.id())?
) // .to_string(),
// )
}); });
let left_dock_zoom = left_dock let left_dock_zoom = left_dock
.visible_panel() .visible_panel()
@ -3273,10 +3284,11 @@ impl Workspace {
let right_dock = this.right_dock.read(cx); let right_dock = this.right_dock.read(cx);
let right_visible = right_dock.is_open(); let right_visible = right_dock.is_open();
let right_active_panel = right_dock.visible_panel().and_then(|panel| { let right_active_panel = right_dock.visible_panel().and_then(|panel| {
Some( todo!()
cx.view_ui_name(panel.as_any().window(), panel.id())? // Some(
.to_string(), // cx.view_ui_name(panel.as_any().window(), panel.id())?
) // .to_string(),
// )
}); });
let right_dock_zoom = right_dock let right_dock_zoom = right_dock
.visible_panel() .visible_panel()
@ -3286,10 +3298,11 @@ impl Workspace {
let bottom_dock = this.bottom_dock.read(cx); let bottom_dock = this.bottom_dock.read(cx);
let bottom_visible = bottom_dock.is_open(); let bottom_visible = bottom_dock.is_open();
let bottom_active_panel = bottom_dock.visible_panel().and_then(|panel| { let bottom_active_panel = bottom_dock.visible_panel().and_then(|panel| {
Some( todo!()
cx.view_ui_name(panel.as_any().window(), panel.id())? // Some(
.to_string(), // cx.view_ui_name(panel.as_any().window(), panel.id())?
) // .to_string(),
// )
}); });
let bottom_dock_zoom = bottom_dock let bottom_dock_zoom = bottom_dock
.visible_panel() .visible_panel()
@ -3332,8 +3345,7 @@ impl Workspace {
docks, docks,
}; };
cx.background() cx.spawn(|_, _| persistence::DB.save_workspace(serialized_workspace))
.spawn(persistence::DB.save_workspace(serialized_workspace))
.detach(); .detach();
} }
} }
@ -3719,6 +3731,11 @@ impl Workspace {
// .log_err(); // .log_err();
// } // }
impl EventEmitter for Workspace {
type Event = Event;
}
// todo!()
// impl Entity for Workspace { // impl Entity for Workspace {
// type Event = Event; // type Event = Event;
@ -3869,54 +3886,55 @@ impl Workspace {
// } // }
// } // }
// impl WorkspaceStore { impl WorkspaceStore {
// pub fn new(client: Arc<Client>, cx: &mut ModelContext<Self>) -> Self { // pub fn new(client: Arc<Client>, cx: &mut ModelContext<Self>) -> Self {
// Self { // Self {
// workspaces: Default::default(), // workspaces: Default::default(),
// followers: Default::default(), // followers: Default::default(),
// _subscriptions: vec![ // _subscriptions: vec![
// client.add_request_handler(cx.handle(), Self::handle_follow), // client.add_request_handler(cx.handle(), Self::handle_follow),
// client.add_message_handler(cx.handle(), Self::handle_unfollow), // client.add_message_handler(cx.handle(), Self::handle_unfollow),
// client.add_message_handler(cx.handle(), Self::handle_update_followers), // client.add_message_handler(cx.handle(), Self::handle_update_followers),
// ], // ],
// client, // client,
// } // }
// } // }
// pub fn update_followers( pub fn update_followers(
// &self, &self,
// project_id: Option<u64>, project_id: Option<u64>,
// update: proto::update_followers::Variant, update: proto::update_followers::Variant,
// cx: &AppContext, cx: &AppContext,
// ) -> Option<()> { ) -> Option<()> {
// if !cx.has_global::<ModelHandle<ActiveCall>>() { if !cx.has_global::<Model<ActiveCall>>() {
// return None; return None;
// } }
// let room_id = ActiveCall::global(cx).read(cx).room()?.read(cx).id(); let room_id = ActiveCall::global(cx).read(cx).room()?.read(cx).id();
// let follower_ids: Vec<_> = self let follower_ids: Vec<_> = self
// .followers .followers
// .iter() .iter()
// .filter_map(|follower| { .filter_map(|follower| {
// if follower.project_id == project_id || project_id.is_none() { if follower.project_id == project_id || project_id.is_none() {
// Some(follower.peer_id.into()) Some(follower.peer_id.into())
// } else { } else {
// None None
// } }
// }) })
// .collect(); .collect();
// if follower_ids.is_empty() { if follower_ids.is_empty() {
// return None; return None;
// } }
// self.client self.client
// .send(proto::UpdateFollowers { .send(proto::UpdateFollowers {
// room_id, room_id,
// project_id, project_id,
// follower_ids, follower_ids,
// variant: Some(update), variant: Some(update),
// }) })
// .log_err() .log_err()
// } }
}
// async fn handle_follow( // async fn handle_follow(
// this: ModelHandle<Self>, // this: ModelHandle<Self>,
@ -4303,13 +4321,14 @@ pub fn open_paths(
.await; .await;
if let Some(existing) = existing { if let Some(existing) = existing {
Ok(( // Ok((
existing.clone(), // existing.clone(),
cx.update_window_root(&existing, |workspace, cx| { // cx.update_window_root(&existing, |workspace, cx| {
workspace.open_paths(abs_paths, true, cx) // workspace.open_paths(abs_paths, true, cx)
})? // })?
.await, // .await,
)) // ))
todo!()
} else { } else {
todo!() todo!()
// Ok(cx // Ok(cx