From 77bb52f72c3089edd689cba801559ec7a92c4f6d Mon Sep 17 00:00:00 2001 From: Julia Date: Wed, 5 Apr 2023 12:08:52 -0400 Subject: [PATCH] Prioritize displaying right statusbar items overtop left items if needed --- crates/gpui/src/elements.rs | 1 + crates/workspace/src/status_bar.rs | 132 ++++++++++++++++++++++++----- 2 files changed, 110 insertions(+), 23 deletions(-) diff --git a/crates/gpui/src/elements.rs b/crates/gpui/src/elements.rs index bf3e17e1f1..3e3370a507 100644 --- a/crates/gpui/src/elements.rs +++ b/crates/gpui/src/elements.rs @@ -227,6 +227,7 @@ pub enum Lifecycle { paint: T::PaintState, }, } + pub struct ElementBox(ElementRc); #[derive(Clone)] diff --git a/crates/workspace/src/status_bar.rs b/crates/workspace/src/status_bar.rs index 04801d934c..a9c8547fd5 100644 --- a/crates/workspace/src/status_bar.rs +++ b/crates/workspace/src/status_bar.rs @@ -1,7 +1,16 @@ +use std::ops::Range; + use crate::{ItemHandle, Pane}; use gpui::{ - elements::*, AnyViewHandle, ElementBox, Entity, MutableAppContext, RenderContext, Subscription, - View, ViewContext, ViewHandle, + elements::*, + geometry::{ + rect::RectF, + vector::{vec2f, Vector2F}, + }, + json::{json, ToJson}, + AnyViewHandle, DebugContext, ElementBox, Entity, LayoutContext, MeasurementContext, + MutableAppContext, PaintContext, RenderContext, SizeConstraint, Subscription, View, + ViewContext, ViewHandle, }; use settings::Settings; @@ -40,27 +49,33 @@ impl View for StatusBar { fn render(&mut self, cx: &mut RenderContext) -> ElementBox { let theme = &cx.global::().theme.workspace.status_bar; - Flex::row() - .with_children(self.left_items.iter().map(|i| { - ChildView::new(i.as_any(), cx) - .aligned() - .contained() - .with_margin_right(theme.item_spacing) - .boxed() - })) - .with_children(self.right_items.iter().rev().map(|i| { - ChildView::new(i.as_any(), cx) - .aligned() - .contained() - .with_margin_left(theme.item_spacing) - .flex_float() - .boxed() - })) - .contained() - .with_style(theme.container) - .constrained() - .with_height(theme.height) - .boxed() + + StatusBarElement { + left: Flex::row() + .with_children(self.left_items.iter().map(|i| { + ChildView::new(i.as_any(), cx) + .aligned() + .contained() + .with_margin_right(theme.item_spacing) + .boxed() + })) + .boxed(), + + right: Flex::row() + .with_children(self.right_items.iter().rev().map(|i| { + ChildView::new(i.as_any(), cx) + .aligned() + .contained() + .with_margin_left(theme.item_spacing) + .boxed() + })) + .boxed(), + } + .contained() + .with_style(theme.container) + .constrained() + .with_height(theme.height) + .boxed() } } @@ -131,3 +146,74 @@ impl From<&dyn StatusItemViewHandle> for AnyViewHandle { val.as_any().clone() } } + +struct StatusBarElement { + left: ElementBox, + right: ElementBox, +} + +impl Element for StatusBarElement { + type LayoutState = (); + type PaintState = (); + + fn layout( + &mut self, + mut constraint: SizeConstraint, + cx: &mut LayoutContext, + ) -> (Vector2F, Self::LayoutState) { + let max_width = constraint.max.x(); + constraint.min = vec2f(0., constraint.min.y()); + + let right_size = self.right.layout(constraint, cx); + let constraint = SizeConstraint::new( + vec2f(0., constraint.min.y()), + vec2f(max_width - right_size.x(), constraint.max.y()), + ); + + self.left.layout(constraint, cx); + + (vec2f(max_width, right_size.y()), ()) + } + + fn paint( + &mut self, + bounds: RectF, + visible_bounds: RectF, + _: &mut Self::LayoutState, + cx: &mut PaintContext, + ) -> Self::PaintState { + let origin_y = bounds.upper_right().y(); + let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); + + let left_origin = vec2f(bounds.lower_left().x(), origin_y); + self.left.paint(left_origin, visible_bounds, cx); + + let right_origin = vec2f(bounds.upper_right().x() - self.right.size().x(), origin_y); + self.right.paint(right_origin, visible_bounds, cx); + } + + fn rect_for_text_range( + &self, + _: Range, + _: RectF, + _: RectF, + _: &Self::LayoutState, + _: &Self::PaintState, + _: &MeasurementContext, + ) -> Option { + None + } + + fn debug( + &self, + bounds: RectF, + _: &Self::LayoutState, + _: &Self::PaintState, + _: &DebugContext, + ) -> serde_json::Value { + json!({ + "type": "StatusBarElement", + "bounds": bounds.to_json() + }) + } +}