This commit is contained in:
Mikayla Maki 2023-07-12 12:46:56 -07:00
parent 9165320390
commit 488b41826b
No known key found for this signature in database
4 changed files with 140 additions and 35 deletions

View file

@ -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<V: View> {
axis: Axis,
handle_size: f32,
items: Vec<(AnyElement<V>, f32)>
}
impl<V: View> AdjustableFlex<V> {
fn new(axis: Axis) -> Self {
AdjustableFlex {
axis,
handle_size: 2.,
items: Vec::new(),
}
}
fn add_item()
}
impl<V: View> Element<V> for AdjustableFlex<V> {
type LayoutState = ();
type PaintState = ();
fn layout(
&mut self,
constraint: gpui::SizeConstraint,
view: &mut V,
cx: &mut gpui::LayoutContext<V>,
) -> (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<V>,
) -> Self::PaintState {
todo!()
}
fn rect_for_text_range(
&self,
range_utf16: std::ops::Range<usize>,
bounds: gpui::geometry::rect::RectF,
visible_bounds: gpui::geometry::rect::RectF,
layout: &Self::LayoutState,
paint: &Self::PaintState,
view: &V,
cx: &gpui::ViewContext<V>,
) -> Option<gpui::geometry::rect::RectF> {
todo!()
}
fn debug(
&self,
bounds: gpui::geometry::rect::RectF,
layout: &Self::LayoutState,
paint: &Self::PaintState,
view: &V,
cx: &gpui::ViewContext<V>,
) -> serde_json::Value {
todo!()
}
}

View file

@ -408,6 +408,9 @@ impl View for Dock {
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> { fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
if let Some(active_entry) = self.visible_entry() { if let Some(active_entry) = self.visible_entry() {
let style = self.style(cx); let style = self.style(cx);
ChildView::new(active_entry.panel.as_any(), cx) ChildView::new(active_entry.panel.as_any(), cx)

View file

@ -9,6 +9,7 @@ use gpui::{
platform::{CursorStyle, MouseButton}, platform::{CursorStyle, MouseButton},
AnyViewHandle, Axis, Border, ModelHandle, ViewContext, ViewHandle, AnyViewHandle, Axis, Border, ModelHandle, ViewContext, ViewHandle,
}; };
use itertools::Itertools;
use project::Project; use project::Project;
use serde::Deserialize; use serde::Deserialize;
use theme::Theme; use theme::Theme;
@ -385,40 +386,61 @@ impl PaneAxis {
app_state: &Arc<AppState>, app_state: &Arc<AppState>,
cx: &mut ViewContext<Workspace>, cx: &mut ViewContext<Workspace>,
) -> AnyElement<Workspace> { ) -> AnyElement<Workspace> {
let last_member_ix = self.members.len() - 1; let mut flex_container = Flex::new(self.axis);
Flex::new(self.axis)
.with_children(self.members.iter().enumerate().map(|(ix, member)| { let mut members = self.members.iter().enumerate().peekable();
let mut flex = 1.0; while let Some((ix, member)) = members.next() {
if member.contains(active_pane) { let last = members.peek().is_none();
flex = settings::get::<WorkspaceSettings>(cx).active_pane_magnification;
let mut flex = 1.0;
if member.contains(active_pane) {
flex = settings::get::<WorkspaceSettings>(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,
} }
let mut member = member.render( let side = match self.axis {
project, Axis::Horizontal => HandleSide::Right,
theme, Axis::Vertical => HandleSide::Bottom,
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();
}
FlexItem::new(member).flex(flex, true) member = member.contained().with_border(border)
})) .resizable(side, 1., |workspace, size, cx| {
.into_any() dbg!("resize", size);
})
.into_any();
}
flex_container = flex_container.with_child(
FlexItem::new(member)
.flex(flex, true)
.into_any()
);
}
flex_container.into_any()
} }
} }

View file

@ -1,13 +1,10 @@
pub mod dock; 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 item;
pub mod notifications; pub mod notifications;
pub mod pane; pub mod pane;
pub mod pane_group; pub mod pane_group;
mod persistence; mod persistence;
mod adjustable_flex;
pub mod searchable; pub mod searchable;
pub mod shared_screen; pub mod shared_screen;
mod status_bar; mod status_bar;