Detailed changes
@@ -1,6 +1,7 @@
use crate::{status_bar::StatusItemView, Axis, Workspace};
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 serde::{Deserialize, Serialize};
@@ -176,226 +177,226 @@ pub struct PanelButtons {
workspace: WeakView<Workspace>,
}
-// impl Dock {
-// pub fn new(position: DockPosition) -> Self {
-// Self {
-// position,
-// panel_entries: Default::default(),
-// active_panel_index: 0,
-// is_open: false,
-// }
-// }
+impl Dock {
+ // pub fn new(position: DockPosition) -> Self {
+ // Self {
+ // position,
+ // panel_entries: Default::default(),
+ // active_panel_index: 0,
+ // is_open: false,
+ // }
+ // }
-// pub fn position(&self) -> DockPosition {
-// self.position
-// }
+ // pub fn position(&self) -> DockPosition {
+ // self.position
+ // }
-// pub fn is_open(&self) -> bool {
-// self.is_open
-// }
+ pub fn is_open(&self) -> bool {
+ self.is_open
+ }
-// pub fn has_focus(&self, cx: &WindowContext) -> bool {
-// self.visible_panel()
-// .map_or(false, |panel| panel.has_focus(cx))
-// }
+ // pub fn has_focus(&self, cx: &WindowContext) -> bool {
+ // self.visible_panel()
+ // .map_or(false, |panel| panel.has_focus(cx))
+ // }
-// pub fn panel<T: Panel>(&self) -> Option<View<T>> {
-// self.panel_entries
-// .iter()
-// .find_map(|entry| entry.panel.as_any().clone().downcast())
-// }
+ // pub fn panel<T: Panel>(&self) -> Option<View<T>> {
+ // self.panel_entries
+ // .iter()
+ // .find_map(|entry| entry.panel.as_any().clone().downcast())
+ // }
-// pub fn panel_index_for_type<T: Panel>(&self) -> Option<usize> {
-// self.panel_entries
-// .iter()
-// .position(|entry| entry.panel.as_any().is::<T>())
-// }
+ // pub fn panel_index_for_type<T: Panel>(&self) -> Option<usize> {
+ // self.panel_entries
+ // .iter()
+ // .position(|entry| entry.panel.as_any().is::<T>())
+ // }
-// 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_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 active_panel_index(&self) -> usize {
-// self.active_panel_index
-// }
+ // pub fn active_panel_index(&self) -> usize {
+ // self.active_panel_index
+ // }
-// pub(crate) fn set_open(&mut self, open: bool, cx: &mut ViewContext<Self>) {
-// if open != self.is_open {
-// self.is_open = open;
-// if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
-// active_panel.panel.set_active(open, cx);
-// }
+ // pub(crate) fn set_open(&mut self, open: bool, cx: &mut ViewContext<Self>) {
+ // if open != self.is_open {
+ // self.is_open = open;
+ // if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
+ // 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>) {
-// for entry in &mut self.panel_entries {
-// if entry.panel.as_any() == panel {
-// if zoomed != entry.panel.is_zoomed(cx) {
-// entry.panel.set_zoomed(zoomed, cx);
-// }
-// } else if entry.panel.is_zoomed(cx) {
-// entry.panel.set_zoomed(false, cx);
-// }
-// }
+ // pub fn set_panel_zoomed(&mut self, panel: &AnyView, zoomed: bool, cx: &mut ViewContext<Self>) {
+ // for entry in &mut self.panel_entries {
+ // if entry.panel.as_any() == panel {
+ // if zoomed != entry.panel.is_zoomed(cx) {
+ // entry.panel.set_zoomed(zoomed, cx);
+ // }
+ // } else if entry.panel.is_zoomed(cx) {
+ // entry.panel.set_zoomed(false, cx);
+ // }
+ // }
+
+ // cx.notify();
+ // }
-// cx.notify();
-// }
+ // pub fn zoom_out(&mut self, cx: &mut ViewContext<Self>) {
+ // for entry in &mut self.panel_entries {
+ // if entry.panel.is_zoomed(cx) {
+ // entry.panel.set_zoomed(false, cx);
+ // }
+ // }
+ // }
-// pub fn zoom_out(&mut self, cx: &mut ViewContext<Self>) {
-// for entry in &mut self.panel_entries {
-// if entry.panel.is_zoomed(cx) {
-// entry.panel.set_zoomed(false, cx);
-// }
-// }
-// }
+ // pub(crate) fn add_panel<T: Panel>(&mut self, panel: View<T>, cx: &mut ViewContext<Self>) {
+ // let subscriptions = [
+ // cx.observe(&panel, |_, _, cx| cx.notify()),
+ // cx.subscribe(&panel, |this, panel, event, cx| {
+ // if T::should_activate_on_event(event) {
+ // if let Some(ix) = this
+ // .panel_entries
+ // .iter()
+ // .position(|entry| entry.panel.id() == panel.id())
+ // {
+ // this.set_open(true, cx);
+ // this.activate_panel(ix, cx);
+ // cx.focus(&panel);
+ // }
+ // } else if T::should_close_on_event(event)
+ // && this.visible_panel().map_or(false, |p| p.id() == panel.id())
+ // {
+ // this.set_open(false, cx);
+ // }
+ // }),
+ // ];
+
+ // let dock_view_id = cx.view_id();
+ // self.panel_entries.push(PanelEntry {
+ // panel: Arc::new(panel),
+ // // todo!()
+ // // context_menu: cx.add_view(|cx| {
+ // // let mut menu = ContextMenu::new(dock_view_id, cx);
+ // // menu.set_position_mode(OverlayPositionMode::Local);
+ // // menu
+ // // }),
+ // _subscriptions: subscriptions,
+ // });
+ // cx.notify()
+ // }
-// pub(crate) fn add_panel<T: Panel>(&mut self, panel: View<T>, cx: &mut ViewContext<Self>) {
-// let subscriptions = [
-// cx.observe(&panel, |_, _, cx| cx.notify()),
-// cx.subscribe(&panel, |this, panel, event, cx| {
-// if T::should_activate_on_event(event) {
-// if let Some(ix) = this
-// .panel_entries
-// .iter()
-// .position(|entry| entry.panel.id() == panel.id())
-// {
-// this.set_open(true, cx);
-// this.activate_panel(ix, cx);
-// cx.focus(&panel);
-// }
-// } else if T::should_close_on_event(event)
-// && this.visible_panel().map_or(false, |p| p.id() == panel.id())
-// {
-// this.set_open(false, cx);
-// }
-// }),
-// ];
-
-// let dock_view_id = cx.view_id();
-// self.panel_entries.push(PanelEntry {
-// panel: Arc::new(panel),
-// // todo!()
-// // context_menu: cx.add_view(|cx| {
-// // let mut menu = ContextMenu::new(dock_view_id, cx);
-// // menu.set_position_mode(OverlayPositionMode::Local);
-// // menu
-// // }),
-// _subscriptions: subscriptions,
-// });
-// cx.notify()
-// }
+ // pub fn remove_panel<T: Panel>(&mut self, panel: &View<T>, cx: &mut ViewContext<Self>) {
+ // if let Some(panel_ix) = self
+ // .panel_entries
+ // .iter()
+ // .position(|entry| entry.panel.id() == panel.id())
+ // {
+ // if panel_ix == self.active_panel_index {
+ // self.active_panel_index = 0;
+ // self.set_open(false, cx);
+ // } else if panel_ix < self.active_panel_index {
+ // self.active_panel_index -= 1;
+ // }
+ // self.panel_entries.remove(panel_ix);
+ // cx.notify();
+ // }
+ // }
-// pub fn remove_panel<T: Panel>(&mut self, panel: &View<T>, cx: &mut ViewContext<Self>) {
-// if let Some(panel_ix) = self
-// .panel_entries
-// .iter()
-// .position(|entry| entry.panel.id() == panel.id())
-// {
-// if panel_ix == self.active_panel_index {
-// self.active_panel_index = 0;
-// self.set_open(false, cx);
-// } else if panel_ix < self.active_panel_index {
-// self.active_panel_index -= 1;
-// }
-// self.panel_entries.remove(panel_ix);
-// cx.notify();
-// }
-// }
+ // pub fn panels_len(&self) -> usize {
+ // self.panel_entries.len()
+ // }
-// pub fn panels_len(&self) -> usize {
-// self.panel_entries.len()
-// }
+ // pub fn activate_panel(&mut self, panel_ix: usize, cx: &mut ViewContext<Self>) {
+ // if panel_ix != self.active_panel_index {
+ // if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
+ // active_panel.panel.set_active(false, cx);
+ // }
-// pub fn activate_panel(&mut self, panel_ix: usize, cx: &mut ViewContext<Self>) {
-// if panel_ix != self.active_panel_index {
-// if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
-// active_panel.panel.set_active(false, cx);
-// }
+ // self.active_panel_index = panel_ix;
+ // if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
+ // active_panel.panel.set_active(true, cx);
+ // }
-// self.active_panel_index = panel_ix;
-// if let Some(active_panel) = self.panel_entries.get(self.active_panel_index) {
-// active_panel.panel.set_active(true, cx);
-// }
-
-// cx.notify();
-// }
-// }
+ // cx.notify();
+ // }
+ // }
-// pub fn visible_panel(&self) -> Option<&Arc<dyn PanelHandle>> {
-// let entry = self.visible_entry()?;
-// Some(&entry.panel)
-// }
+ pub fn visible_panel(&self) -> Option<&Arc<dyn PanelHandle>> {
+ let entry = self.visible_entry()?;
+ Some(&entry.panel)
+ }
-// pub fn active_panel(&self) -> Option<&Arc<dyn PanelHandle>> {
-// Some(&self.panel_entries.get(self.active_panel_index)?.panel)
-// }
+ // pub fn active_panel(&self) -> Option<&Arc<dyn PanelHandle>> {
+ // Some(&self.panel_entries.get(self.active_panel_index)?.panel)
+ // }
-// fn visible_entry(&self) -> Option<&PanelEntry> {
-// if self.is_open {
-// self.panel_entries.get(self.active_panel_index)
-// } else {
-// None
-// }
-// }
+ fn visible_entry(&self) -> Option<&PanelEntry> {
+ if self.is_open {
+ self.panel_entries.get(self.active_panel_index)
+ } else {
+ None
+ }
+ }
-// pub fn zoomed_panel(&self, cx: &WindowContext) -> Option<Arc<dyn PanelHandle>> {
-// let entry = self.visible_entry()?;
-// if entry.panel.is_zoomed(cx) {
-// Some(entry.panel.clone())
-// } else {
-// None
-// }
-// }
+ // pub fn zoomed_panel(&self, cx: &WindowContext) -> Option<Arc<dyn PanelHandle>> {
+ // let entry = self.visible_entry()?;
+ // if entry.panel.is_zoomed(cx) {
+ // Some(entry.panel.clone())
+ // } else {
+ // None
+ // }
+ // }
-// pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option<f32> {
-// self.panel_entries
-// .iter()
-// .find(|entry| entry.panel.id() == panel.id())
-// .map(|entry| entry.panel.size(cx))
-// }
+ // pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option<f32> {
+ // self.panel_entries
+ // .iter()
+ // .find(|entry| entry.panel.id() == panel.id())
+ // .map(|entry| entry.panel.size(cx))
+ // }
-// pub fn active_panel_size(&self, cx: &WindowContext) -> Option<f32> {
-// if self.is_open {
-// self.panel_entries
-// .get(self.active_panel_index)
-// .map(|entry| entry.panel.size(cx))
-// } else {
-// None
-// }
-// }
+ // pub fn active_panel_size(&self, cx: &WindowContext) -> Option<f32> {
+ // if self.is_open {
+ // self.panel_entries
+ // .get(self.active_panel_index)
+ // .map(|entry| entry.panel.size(cx))
+ // } else {
+ // None
+ // }
+ // }
-// 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) {
-// entry.panel.set_size(size, cx);
-// cx.notify();
-// }
-// }
+ // 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) {
+ // entry.panel.set_size(size, cx);
+ // cx.notify();
+ // }
+ // }
-// pub fn render_placeholder(&self, cx: &WindowContext) -> AnyElement<Workspace> {
-// todo!()
-// if let Some(active_entry) = self.visible_entry() {
-// Empty::new()
-// .into_any()
-// .contained()
-// .with_style(self.style(cx))
-// .resizable::<WorkspaceBounds>(
-// self.position.to_resize_handle_side(),
-// active_entry.panel.size(cx),
-// |_, _, _| {},
-// )
-// .into_any()
-// } else {
-// Empty::new().into_any()
-// }
-// }
-// }
+ // pub fn render_placeholder(&self, cx: &WindowContext) -> AnyElement<Workspace> {
+ // todo!()
+ // if let Some(active_entry) = self.visible_entry() {
+ // Empty::new()
+ // .into_any()
+ // .contained()
+ // .with_style(self.style(cx))
+ // .resizable::<WorkspaceBounds>(
+ // self.position.to_resize_handle_side(),
+ // active_entry.panel.size(cx),
+ // |_, _, _| {},
+ // )
+ // .into_any()
+ // } else {
+ // Empty::new().into_any()
+ // }
+ // }
+}
// todo!()
// impl View for Dock {
@@ -596,15 +597,23 @@ impl EventEmitter for PanelButtons {
// }
// }
-// impl StatusItemView for PanelButtons {
-// fn set_active_pane_item(
-// &mut self,
-// active_pane_item: Option<&dyn crate::ItemHandle>,
-// cx: &mut ViewContext<Self>,
-// ) {
-// todo!()
-// }
-// }
+impl Render for PanelButtons {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+ 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"))]
pub mod test {
@@ -691,58 +691,58 @@ pub trait FollowableItemHandle: ItemHandle {
fn is_project_item(&self, cx: &AppContext) -> bool;
}
-// impl<T: FollowableItem> FollowableItemHandle for View<T> {
-// fn remote_id(&self, client: &Arc<Client>, cx: &AppContext) -> Option<ViewId> {
-// self.read(cx).remote_id().or_else(|| {
-// client.peer_id().map(|creator| ViewId {
-// creator,
-// id: self.id() as u64,
-// })
-// })
-// }
+impl<T: FollowableItem> FollowableItemHandle for View<T> {
+ fn remote_id(&self, client: &Arc<Client>, cx: &AppContext) -> Option<ViewId> {
+ self.read(cx).remote_id().or_else(|| {
+ client.peer_id().map(|creator| ViewId {
+ creator,
+ id: self.id() as u64,
+ })
+ })
+ }
-// 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))
-// }
+ 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))
+ }
-// fn to_state_proto(&self, cx: &AppContext) -> Option<proto::view::Variant> {
-// self.read(cx).to_state_proto(cx)
-// }
+ fn to_state_proto(&self, cx: &AppContext) -> Option<proto::view::Variant> {
+ self.read(cx).to_state_proto(cx)
+ }
-// fn add_event_to_update_proto(
-// &self,
-// event: &dyn Any,
-// update: &mut Option<proto::update_view::Variant>,
-// cx: &AppContext,
-// ) -> bool {
-// if let Some(event) = event.downcast_ref() {
-// self.read(cx).add_event_to_update_proto(event, update, cx)
-// } else {
-// false
-// }
-// }
+ fn add_event_to_update_proto(
+ &self,
+ event: &dyn Any,
+ update: &mut Option<proto::update_view::Variant>,
+ cx: &AppContext,
+ ) -> bool {
+ if let Some(event) = event.downcast_ref() {
+ self.read(cx).add_event_to_update_proto(event, update, cx)
+ } else {
+ false
+ }
+ }
-// fn apply_update_proto(
-// &self,
-// project: &Model<Project>,
-// message: proto::update_view::Variant,
-// cx: &mut WindowContext,
-// ) -> Task<Result<()>> {
-// self.update(cx, |this, cx| this.apply_update_proto(project, message, cx))
-// }
+ fn apply_update_proto(
+ &self,
+ project: &Model<Project>,
+ message: proto::update_view::Variant,
+ cx: &mut WindowContext,
+ ) -> Task<Result<()>> {
+ self.update(cx, |this, cx| this.apply_update_proto(project, message, cx))
+ }
-// fn should_unfollow_on_event(&self, event: &dyn Any, cx: &AppContext) -> bool {
-// if let Some(event) = event.downcast_ref() {
-// T::should_unfollow_on_event(event, cx)
-// } else {
-// false
-// }
-// }
+ fn should_unfollow_on_event(&self, event: &dyn Any, cx: &AppContext) -> bool {
+ if let Some(event) = event.downcast_ref() {
+ T::should_unfollow_on_event(event, cx)
+ } else {
+ false
+ }
+ }
-// fn is_project_item(&self, cx: &AppContext) -> bool {
-// self.read(cx).is_project_item(cx)
-// }
-// }
+ fn is_project_item(&self, cx: &AppContext) -> bool {
+ self.read(cx).is_project_item(cx)
+ }
+}
// #[cfg(any(test, feature = "test-support"))]
// pub mod test {
@@ -178,7 +178,7 @@ pub struct Pane {
// tab_context_menu: ViewHandle<ContextMenu>,
// workspace: WeakView<Workspace>,
project: Model<Project>,
- // has_focus: bool,
+ has_focus: bool,
// can_drop: Rc<dyn Fn(&DragAndDrop<Workspace>, &WindowContext) -> bool>,
// can_split: bool,
// 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)),
// workspace,
project,
- // has_focus: false,
+ has_focus: false,
// can_drop: Rc::new(|_, _| true),
// can_split: true,
// render_tab_bar_buttons: Rc::new(move |pane, cx| {
@@ -415,9 +415,9 @@ impl Pane {
// &self.workspace
// }
- // pub fn has_focus(&self) -> bool {
- // self.has_focus
- // }
+ pub fn has_focus(&self) -> bool {
+ self.has_focus
+ }
// pub fn active_item_index(&self) -> usize {
// self.active_item_index
@@ -614,9 +614,9 @@ impl Pane {
self.items.len()
}
- // pub fn items(&self) -> impl Iterator<Item = &Box<dyn ItemHandle>> + DoubleEndedIterator {
- // self.items.iter()
- // }
+ pub fn items(&self) -> impl Iterator<Item = &Box<dyn ItemHandle>> + DoubleEndedIterator {
+ self.items.iter()
+ }
// pub fn items_of_type<T: View>(&self) -> impl '_ + Iterator<Item = ViewHandle<T>> {
// self.items
@@ -2,22 +2,24 @@ use crate::{AppState, FollowerState, Pane, Workspace};
use anyhow::{anyhow, Result};
use call2::ActiveCall;
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 serde::Deserialize;
-use std::{cell::RefCell, rc::Rc, sync::Arc};
+use std::sync::Arc;
use theme2::Theme;
const HANDLE_HITBOX_SIZE: f32 = 4.0;
const HORIZONTAL_MIN_SIZE: f32 = 80.;
const VERTICAL_MIN_SIZE: f32 = 100.;
+#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Axis {
Vertical,
Horizontal,
}
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, PartialEq)]
pub struct PaneGroup {
pub(crate) root: Member,
}
@@ -305,18 +307,24 @@ impl Member {
}
}
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone)]
pub(crate) struct PaneAxis {
pub axis: Axis,
pub members: Vec<Member>,
- pub flexes: Rc<RefCell<Vec<f32>>>,
- pub bounding_boxes: Rc<RefCell<Vec<Option<Bounds<Pixels>>>>>,
+ pub flexes: Arc<Mutex<Vec<f32>>>,
+ pub bounding_boxes: Arc<Mutex<Vec<Option<Bounds<Pixels>>>>>,
+}
+
+impl PartialEq for PaneAxis {
+ fn eq(&self, other: &Self) -> bool {
+ todo!()
+ }
}
impl PaneAxis {
pub fn new(axis: Axis, members: Vec<Member>) -> Self {
- let flexes = Rc::new(RefCell::new(vec![1.; members.len()]));
- let bounding_boxes = Rc::new(RefCell::new(vec![None; members.len()]));
+ let flexes = Arc::new(Mutex::new(vec![1.; members.len()]));
+ let bounding_boxes = Arc::new(Mutex::new(vec![None; members.len()]));
Self {
axis,
members,
@@ -329,8 +337,8 @@ impl PaneAxis {
let flexes = flexes.unwrap_or_else(|| vec![1.; members.len()]);
debug_assert!(members.len() == flexes.len());
- let flexes = Rc::new(RefCell::new(flexes));
- let bounding_boxes = Rc::new(RefCell::new(vec![None; members.len()]));
+ let flexes = Arc::new(Mutex::new(flexes));
+ let bounding_boxes = Arc::new(Mutex::new(vec![None; members.len()]));
Self {
axis,
members,
@@ -360,7 +368,7 @@ impl PaneAxis {
}
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 {
*member =
Member::new_axis(old_pane.clone(), new_pane.clone(), direction);
@@ -400,12 +408,12 @@ impl PaneAxis {
if found_pane {
if let Some(idx) = remove_member {
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 {
let result = self.members.pop();
- *self.flexes.borrow_mut() = vec![1.; self.members.len()];
+ *self.flexes.lock() = vec![1.; self.members.len()];
Ok(result)
} else {
Ok(None)
@@ -431,13 +439,13 @@ impl PaneAxis {
}
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() {
match member {
Member::Pane(found) => {
if pane == found {
- return self.bounding_boxes.borrow()[idx];
+ return self.bounding_boxes.lock()[idx];
}
}
Member::Axis(axis) => {
@@ -451,9 +459,9 @@ impl PaneAxis {
}
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() {
if let Some(coordinates) = bounding_boxes[idx] {
@@ -480,7 +488,7 @@ impl PaneAxis {
app_state: &Arc<AppState>,
cx: &mut ViewContext<Workspace>,
) -> AnyElement<Workspace> {
- debug_assert!(self.members.len() == self.flexes.borrow().len());
+ debug_assert!(self.members.len() == self.flexes.lock().len());
todo!()
// let mut pane_axis = PaneAxisElement::new(
@@ -546,32 +554,32 @@ impl SplitDirection {
[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 {
- Self::Up => rect.min_y(),
- Self::Down => rect.max_y(),
- Self::Left => rect.min_x(),
- Self::Right => rect.max_x(),
+ Self::Up => rect.origin.y,
+ Self::Down => rect.lower_left().y,
+ Self::Left => rect.lower_left().x,
+ Self::Right => rect.lower_right().x,
}
}
pub fn along_edge(&self, bounds: Bounds<Pixels>, length: Pixels) -> Bounds<Pixels> {
match self {
Self::Up => Bounds {
- origin: bounds.origin(),
- size: size(bounds.width(), length),
+ origin: bounds.origin,
+ size: size(bounds.size.width, length),
},
Self::Down => Bounds {
- origin: size(bounds.min_x(), bounds.max_y() - length),
- size: size(bounds.width(), length),
+ origin: point(bounds.lower_left().x, bounds.lower_left().y - length),
+ size: size(bounds.size.width, length),
},
Self::Left => Bounds {
- origin: bounds.origin(),
- size: size(length, bounds.height()),
+ origin: bounds.origin,
+ size: size(length, bounds.size.height),
},
Self::Right => Bounds {
- origin: size(bounds.max_x() - length, bounds.min_y()),
- size: size(length, bounds.height()),
+ origin: point(bounds.lower_right().x - length, bounds.lower_left().y),
+ size: size(length, bounds.size.height),
},
}
}
@@ -55,7 +55,7 @@ impl Column for WorkspaceLocation {
}
}
-#[derive(Debug, PartialEq, Clone)]
+#[derive(PartialEq, Clone)]
pub struct SerializedWorkspace {
pub id: WorkspaceId,
pub location: WorkspaceLocation,
@@ -127,7 +127,7 @@ impl Bind for DockData {
}
}
-#[derive(Debug, PartialEq, Clone)]
+#[derive(PartialEq, Clone)]
pub enum SerializedPaneGroup {
Group {
axis: Axis,
@@ -1,6 +1,6 @@
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 crate::{
@@ -95,7 +95,7 @@ pub trait SearchableItemHandle: ItemHandle {
fn subscribe_to_search_events(
&self,
cx: &mut WindowContext,
- handler: Box<dyn Fn(SearchEvent, &mut WindowContext)>,
+ handler: Box<dyn Fn(SearchEvent, &mut WindowContext) + Send>,
) -> Subscription;
fn clear_matches(&self, 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> {
fn downgrade(&self) -> Box<dyn WeakSearchableItemHandle> {
- Box::new(self.downgrade())
+ // Box::new(self.downgrade())
+ todo!()
}
fn boxed_clone(&self) -> Box<dyn SearchableItemHandle> {
@@ -144,7 +145,7 @@ impl<T: SearchableItem> SearchableItemHandle for View<T> {
fn subscribe_to_search_events(
&self,
cx: &mut WindowContext,
- handler: Box<dyn Fn(SearchEvent, &mut WindowContext)>,
+ handler: Box<dyn Fn(SearchEvent, &mut WindowContext) + Send>,
) -> Subscription {
cx.subscribe(self, move |handle, 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,
) -> Task<Vec<Box<dyn Any + Send>>> {
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;
matches
.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 AnyViewHandle {
-// fn from(this: Box<dyn SearchableItemHandle>) -> Self {
-// this.as_any().clone()
-// }
-// }
+impl From<Box<dyn SearchableItemHandle>> for AnyView {
+ fn from(this: Box<dyn SearchableItemHandle>) -> Self {
+ this.to_any().clone()
+ }
+}
-// todo!()
-// impl From<&Box<dyn SearchableItemHandle>> for AnyViewHandle {
-// fn from(this: &Box<dyn SearchableItemHandle>) -> Self {
-// this.as_any().clone()
-// }
-// }
+impl From<&Box<dyn SearchableItemHandle>> for AnyView {
+ fn from(this: &Box<dyn SearchableItemHandle>) -> Self {
+ this.to_any().clone()
+ }
+}
impl PartialEq for Box<dyn SearchableItemHandle> {
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 {
fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>>;
- // todo!()
- // fn into_any(self) -> AnyWeakViewHandle;
+ // fn into_any(self) -> AnyWeakView;
}
// todo!()
-// impl<T: SearchableItem> WeakSearchableItemHandle for WeakViewHandle<T> {
+// impl<T: SearchableItem> WeakSearchableItemHandle for WeakView<T> {
// fn upgrade(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>> {
// Some(Box::new(self.upgrade(cx)?))
// }
-// fn into_any(self) -> AnyWeakViewHandle {
-// self.into_any()
-// }
+// // fn into_any(self) -> AnyView {
+// // self.into_any()
+// // }
// }
impl PartialEq for Box<dyn WeakSearchableItemHandle> {
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> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
- (self.id(), self.window().id()).hash(state)
+ self.id().hash(state)
}
}
@@ -11,21 +11,25 @@ mod toolbar;
mod workspace_settings;
use anyhow::{anyhow, Result};
+use call2::ActiveCall;
use client2::{
proto::{self, PeerId},
Client, UserStore,
};
use collections::{HashMap, HashSet};
+use dock::Dock;
use futures::{channel::oneshot, FutureExt};
use gpui2::{
- AnyModel, AnyView, AppContext, AsyncAppContext, DisplayId, MainThread, Model, Task, View,
- ViewContext, VisualContext, WeakModel, WeakView, WindowBounds, WindowHandle, WindowOptions,
+ AnyModel, AnyView, AppContext, AsyncAppContext, DisplayId, EventEmitter, MainThread, Model,
+ Subscription, Task, View, ViewContext, VisualContext, WeakModel, WeakView, WindowBounds,
+ WindowHandle, WindowOptions,
};
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem};
use language2::LanguageRegistry;
use node_runtime::NodeRuntime;
pub use pane::*;
pub use pane_group::*;
+use persistence::model::{ItemId, WorkspaceLocation};
use project2::{Project, ProjectEntryId, ProjectPath, Worktree};
use std::{
any::TypeId,
@@ -37,7 +41,8 @@ pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
use util::ResultExt;
use crate::persistence::model::{
- DockStructure, SerializedItem, SerializedPane, SerializedPaneGroup, SerializedWorkspace,
+ DockData, DockStructure, SerializedItem, SerializedPane, SerializedPaneGroup,
+ SerializedWorkspace,
};
// lazy_static! {
@@ -386,14 +391,13 @@ type ItemDeserializers = HashMap<
) -> Task<Result<Box<dyn ItemHandle>>>,
>;
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() {
deserializers.insert(
Arc::from(serialized_item_kind),
|project, workspace, workspace_id, item_id, cx| {
let task = I::deserialize(project, workspace, workspace_id, item_id, cx);
- cx.foreground()
- .spawn(async { Ok(Box::new(task.await?) as Box<_>) })
+ cx.spawn_on_main(|cx| async { Ok(Box::new(task.await?) as Box<_>) })
},
);
}
@@ -426,6 +430,7 @@ struct Follower {
peer_id: PeerId,
}
+// todo!()
// impl AppState {
// #[cfg(any(test, feature = "test-support"))]
// 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)
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() {
_ = channel.send(());
@@ -517,7 +522,7 @@ pub struct Workspace {
// modal: Option<ActiveModal>,
// zoomed: Option<AnyWeakViewHandle>,
// zoomed_position: Option<DockPosition>,
- // center: PaneGroup,
+ center: PaneGroup,
left_dock: View<Dock>,
bottom_dock: View<Dock>,
right_dock: View<Dock>,
@@ -533,9 +538,9 @@ pub struct Workspace {
follower_states: HashMap<View<Pane>, FollowerState>,
last_leaders_by_pane: HashMap<WeakView<Pane>, PeerId>,
// 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)>,
- // database_id: WorkspaceId,
+ database_id: WorkspaceId,
app_state: Arc<AppState>,
// subscriptions: Vec<Subscription>,
// _apply_leader_updates: Task<Result<()>>,
@@ -1925,19 +1930,21 @@ impl Workspace {
// }
fn add_pane(&mut self, cx: &mut ViewContext<Self>) -> View<Pane> {
- let pane = cx.build_view(|cx| {
- Pane::new(
- self.weak_handle(),
- self.project.clone(),
- self.pane_history_timestamp.clone(),
- cx,
- )
- });
- cx.subscribe(&pane, Self::handle_pane_event).detach();
- self.panes.push(pane.clone());
- cx.focus(&pane);
- cx.emit(Event::PaneAdded(pane.clone()));
- pane
+ todo!()
+ // let pane = cx.build_view(|cx| {
+ // Pane::new(
+ // self.weak_handle(),
+ // self.project.clone(),
+ // self.pane_history_timestamp.clone(),
+ // cx,
+ // )
+ // });
+ // cx.subscribe(&pane, Self::handle_pane_event).detach();
+ // self.panes.push(pane.clone());
+ // todo!()
+ // cx.focus(&pane);
+ // cx.emit(Event::PaneAdded(pane.clone()));
+ // pane
}
// pub fn add_item_to_center(
@@ -2083,19 +2090,19 @@ impl Workspace {
) -> Task<
Result<(
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_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 build_item = cx.update(|cx| {
cx.default_global::<ProjectItemBuilders>()
- .get(&project_item.model_type())
+ .get(&project_item.type_id())
.ok_or_else(|| anyhow!("no item builder for project item"))
.cloned()
- })?;
+ })??;
let build_item =
move |cx: &mut ViewContext<Pane>| build_item(project, project_item, cx);
Ok((project_entry_id, build_item))
@@ -3012,14 +3019,14 @@ impl Workspace {
&self,
project_only: bool,
update: proto::update_followers::Variant,
- cx: &AppContext,
+ cx: &mut AppContext,
) -> Option<()> {
let project_id = if project_only {
self.project.read(cx).remote_id()
} else {
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)
})
}
@@ -3141,9 +3148,9 @@ impl Workspace {
// }
// }
- // fn active_call(&self) -> Option<&ModelHandle<ActiveCall>> {
- // self.active_call.as_ref().map(|(call, _)| call)
- // }
+ fn active_call(&self) -> Option<&Model<ActiveCall>> {
+ self.active_call.as_ref().map(|(call, _)| call)
+ }
// fn on_active_call_event(
// &mut self,
@@ -3164,21 +3171,21 @@ impl Workspace {
// self.database_id
// }
- // fn location(&self, cx: &AppContext) -> Option<WorkspaceLocation> {
- // let project = self.project().read(cx);
+ fn location(&self, cx: &AppContext) -> Option<WorkspaceLocation> {
+ let project = self.project().read(cx);
- // if project.is_local() {
- // Some(
- // project
- // .visible_worktrees(cx)
- // .map(|worktree| worktree.read(cx).abs_path())
- // .collect::<Vec<_>>()
- // .into(),
- // )
- // } else {
- // None
- // }
- // }
+ if project.is_local() {
+ Some(
+ project
+ .visible_worktrees(cx)
+ .map(|worktree| worktree.read(cx).abs_path())
+ .collect::<Vec<_>>()
+ .into(),
+ )
+ } else {
+ None
+ }
+ }
// fn remove_panes(&mut self, member: Member, cx: &mut ViewContext<Workspace>) {
// match member {
@@ -3193,14 +3200,17 @@ impl Workspace {
// }
// }
- // fn force_remove_pane(&mut self, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
- // self.panes.retain(|p| p != pane);
- // cx.focus(self.panes.last().unwrap());
- // if self.last_active_center_pane == Some(pane.downgrade()) {
- // self.last_active_center_pane = None;
- // }
- // cx.notify();
- // }
+ fn force_remove_pane(&mut self, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
+ self.panes.retain(|p| p != pane);
+ if true {
+ todo!()
+ // cx.focus(self.panes.last().unwrap());
+ }
+ 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>) {
// self._schedule_serialize = Some(cx.spawn(|this, cx| async move {
@@ -3248,7 +3258,7 @@ impl Workspace {
.iter()
.map(|member| build_serialized_pane_group(member, cx))
.collect::<Vec<_>>(),
- flexes: Some(flexes.borrow().clone()),
+ flexes: Some(flexes.lock().clone()),
},
Member::Pane(pane_handle) => {
SerializedPaneGroup::Pane(serialize_pane_handle(&pane_handle, cx))
@@ -3260,10 +3270,11 @@ impl Workspace {
let left_dock = this.left_dock.read(cx);
let left_visible = left_dock.is_open();
let left_active_panel = left_dock.visible_panel().and_then(|panel| {
- Some(
- cx.view_ui_name(panel.as_any().window(), panel.id())?
- .to_string(),
- )
+ todo!()
+ // Some(
+ // cx.view_ui_name(panel.as_any().window(), panel.id())?
+ // .to_string(),
+ // )
});
let left_dock_zoom = left_dock
.visible_panel()
@@ -3273,10 +3284,11 @@ impl Workspace {
let right_dock = this.right_dock.read(cx);
let right_visible = right_dock.is_open();
let right_active_panel = right_dock.visible_panel().and_then(|panel| {
- Some(
- cx.view_ui_name(panel.as_any().window(), panel.id())?
- .to_string(),
- )
+ todo!()
+ // Some(
+ // cx.view_ui_name(panel.as_any().window(), panel.id())?
+ // .to_string(),
+ // )
});
let right_dock_zoom = right_dock
.visible_panel()
@@ -3286,10 +3298,11 @@ impl Workspace {
let bottom_dock = this.bottom_dock.read(cx);
let bottom_visible = bottom_dock.is_open();
let bottom_active_panel = bottom_dock.visible_panel().and_then(|panel| {
- Some(
- cx.view_ui_name(panel.as_any().window(), panel.id())?
- .to_string(),
- )
+ todo!()
+ // Some(
+ // cx.view_ui_name(panel.as_any().window(), panel.id())?
+ // .to_string(),
+ // )
});
let bottom_dock_zoom = bottom_dock
.visible_panel()
@@ -3332,8 +3345,7 @@ impl Workspace {
docks,
};
- cx.background()
- .spawn(persistence::DB.save_workspace(serialized_workspace))
+ cx.spawn(|_, _| persistence::DB.save_workspace(serialized_workspace))
.detach();
}
}
@@ -3719,6 +3731,11 @@ impl Workspace {
// .log_err();
// }
+impl EventEmitter for Workspace {
+ type Event = Event;
+}
+
+// todo!()
// impl Entity for Workspace {
// type Event = Event;
@@ -3869,54 +3886,55 @@ impl Workspace {
// }
// }
-// impl WorkspaceStore {
-// pub fn new(client: Arc<Client>, cx: &mut ModelContext<Self>) -> Self {
-// Self {
-// workspaces: Default::default(),
-// followers: Default::default(),
-// _subscriptions: vec![
-// 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_update_followers),
-// ],
-// client,
-// }
-// }
+impl WorkspaceStore {
+ // pub fn new(client: Arc<Client>, cx: &mut ModelContext<Self>) -> Self {
+ // Self {
+ // workspaces: Default::default(),
+ // followers: Default::default(),
+ // _subscriptions: vec![
+ // 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_update_followers),
+ // ],
+ // client,
+ // }
+ // }
-// pub fn update_followers(
-// &self,
-// project_id: Option<u64>,
-// update: proto::update_followers::Variant,
-// cx: &AppContext,
-// ) -> Option<()> {
-// if !cx.has_global::<ModelHandle<ActiveCall>>() {
-// return None;
-// }
+ pub fn update_followers(
+ &self,
+ project_id: Option<u64>,
+ update: proto::update_followers::Variant,
+ cx: &AppContext,
+ ) -> Option<()> {
+ if !cx.has_global::<Model<ActiveCall>>() {
+ return None;
+ }
-// let room_id = ActiveCall::global(cx).read(cx).room()?.read(cx).id();
-// let follower_ids: Vec<_> = self
-// .followers
-// .iter()
-// .filter_map(|follower| {
-// if follower.project_id == project_id || project_id.is_none() {
-// Some(follower.peer_id.into())
-// } else {
-// None
-// }
-// })
-// .collect();
-// if follower_ids.is_empty() {
-// return None;
-// }
-// self.client
-// .send(proto::UpdateFollowers {
-// room_id,
-// project_id,
-// follower_ids,
-// variant: Some(update),
-// })
-// .log_err()
-// }
+ let room_id = ActiveCall::global(cx).read(cx).room()?.read(cx).id();
+ let follower_ids: Vec<_> = self
+ .followers
+ .iter()
+ .filter_map(|follower| {
+ if follower.project_id == project_id || project_id.is_none() {
+ Some(follower.peer_id.into())
+ } else {
+ None
+ }
+ })
+ .collect();
+ if follower_ids.is_empty() {
+ return None;
+ }
+ self.client
+ .send(proto::UpdateFollowers {
+ room_id,
+ project_id,
+ follower_ids,
+ variant: Some(update),
+ })
+ .log_err()
+ }
+}
// async fn handle_follow(
// this: ModelHandle<Self>,
@@ -4303,13 +4321,14 @@ pub fn open_paths(
.await;
if let Some(existing) = existing {
- Ok((
- existing.clone(),
- cx.update_window_root(&existing, |workspace, cx| {
- workspace.open_paths(abs_paths, true, cx)
- })?
- .await,
- ))
+ // Ok((
+ // existing.clone(),
+ // cx.update_window_root(&existing, |workspace, cx| {
+ // workspace.open_paths(abs_paths, true, cx)
+ // })?
+ // .await,
+ // ))
+ todo!()
} else {
todo!()
// Ok(cx