diff --git a/crates/workspace/src/adjustable_flex.rs b/crates/workspace/src/adjustable_flex.rs new file mode 100644 index 0000000000000000000000000000000000000000..4ea1b719f1e08a6893448c0c08a57a421f53e818 --- /dev/null +++ b/crates/workspace/src/adjustable_flex.rs @@ -0,0 +1,83 @@ +use gpui::{Element, View, Axis, AnyElement}; + +// Model for the center group: AdjustableGroup of AdjustableGroups +// Implementation notes +// - These have two representations: Exact pixel widths and ratios of elements compared to whole space +// - We have a constraint of minimum sizes for things. +// - If The space is smaller than allowed, things run off the edge +// - When doing Drag resize, we update the pixel width representation, causing a recalc of the ratios +// - If dragging past minimum, take space from next item, until out of space +// - When doing a reflow (e.g. layout) we read off the ratios and calculate pixels from that +// - When adding / removing items in an Adjustable flex, reset to default ratios (1:1) +// - By default, every item takes up as much space as possible +// + + +struct AdjustableFlex { + axis: Axis, + handle_size: f32, + items: Vec<(AnyElement, f32)> +} + +impl AdjustableFlex { + fn new(axis: Axis) -> Self { + AdjustableFlex { + axis, + handle_size: 2., + items: Vec::new(), + } + } + + fn add_item() +} + +impl Element for AdjustableFlex { + type LayoutState = (); + + type PaintState = (); + + fn layout( + &mut self, + constraint: gpui::SizeConstraint, + view: &mut V, + cx: &mut gpui::LayoutContext, + ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) { + todo!() + } + + fn paint( + &mut self, + scene: &mut gpui::SceneBuilder, + bounds: gpui::geometry::rect::RectF, + visible_bounds: gpui::geometry::rect::RectF, + layout: &mut Self::LayoutState, + view: &mut V, + cx: &mut gpui::ViewContext, + ) -> Self::PaintState { + todo!() + } + + fn rect_for_text_range( + &self, + range_utf16: std::ops::Range, + bounds: gpui::geometry::rect::RectF, + visible_bounds: gpui::geometry::rect::RectF, + layout: &Self::LayoutState, + paint: &Self::PaintState, + view: &V, + cx: &gpui::ViewContext, + ) -> Option { + todo!() + } + + fn debug( + &self, + bounds: gpui::geometry::rect::RectF, + layout: &Self::LayoutState, + paint: &Self::PaintState, + view: &V, + cx: &gpui::ViewContext, + ) -> serde_json::Value { + todo!() + } +} diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index ebaf399e22b3ecfa51b217327f5912a34dc7b542..259e343248508790b673133f9f46c983c7532a2f 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -408,6 +408,9 @@ impl View for Dock { } fn render(&mut self, cx: &mut ViewContext) -> AnyElement { + + + if let Some(active_entry) = self.visible_entry() { let style = self.style(cx); ChildView::new(active_entry.panel.as_any(), cx) diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 5e5a5a98baaf07482c8b3854b08a3301fd75baa7..8160a770a3759bddeefd1bf8a6a124bcd652bdcd 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -9,6 +9,7 @@ use gpui::{ platform::{CursorStyle, MouseButton}, AnyViewHandle, Axis, Border, ModelHandle, ViewContext, ViewHandle, }; +use itertools::Itertools; use project::Project; use serde::Deserialize; use theme::Theme; @@ -385,40 +386,61 @@ impl PaneAxis { app_state: &Arc, cx: &mut ViewContext, ) -> AnyElement { - let last_member_ix = self.members.len() - 1; - Flex::new(self.axis) - .with_children(self.members.iter().enumerate().map(|(ix, member)| { - let mut flex = 1.0; - if member.contains(active_pane) { - flex = settings::get::(cx).active_pane_magnification; - } + let mut flex_container = Flex::new(self.axis); - let mut member = member.render( - project, - theme, - follower_state, - active_call, - active_pane, - zoomed, - app_state, - cx, - ); - if ix < last_member_ix { - let mut border = theme.workspace.pane_divider; - border.left = false; - border.right = false; - border.top = false; - border.bottom = false; - match self.axis { - Axis::Vertical => border.bottom = true, - Axis::Horizontal => border.right = true, - } - member = member.contained().with_border(border).into_any(); + let mut members = self.members.iter().enumerate().peekable(); + while let Some((ix, member)) = members.next() { + let last = members.peek().is_none(); + + let mut flex = 1.0; + if member.contains(active_pane) { + flex = settings::get::(cx).active_pane_magnification; + } + + let mut member = member.render( + project, + theme, + follower_state, + active_call, + active_pane, + zoomed, + app_state, + cx, + ); + if !last { + let mut border = theme.workspace.pane_divider; + border.left = false; + border.right = false; + border.top = false; + border.bottom = false; + + match self.axis { + Axis::Vertical => border.bottom = true, + Axis::Horizontal => border.right = true, } - FlexItem::new(member).flex(flex, true) - })) - .into_any() + let side = match self.axis { + Axis::Horizontal => HandleSide::Right, + Axis::Vertical => HandleSide::Bottom, + }; + + member = member.contained().with_border(border) + .resizable(side, 1., |workspace, size, cx| { + dbg!("resize", size); + }) + .into_any(); + + + } + + flex_container = flex_container.with_child( + FlexItem::new(member) + .flex(flex, true) + .into_any() + ); + } + + flex_container.into_any() } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 01d80d141c9b38fff5e7129bd5cfcabe27b42bd7..cafcd191a3c476cb1f532b2ffbb07e8bb1292616 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1,13 +1,10 @@ pub mod dock; -/// NOTE: Focus only 'takes' after an update has flushed_effects. -/// -/// This may cause issues when you're trying to write tests that use workspace focus to add items at -/// specific locations. pub mod item; pub mod notifications; pub mod pane; pub mod pane_group; mod persistence; +mod adjustable_flex; pub mod searchable; pub mod shared_screen; mod status_bar;