Prioritize displaying right statusbar items overtop left items if needed

This commit is contained in:
Julia 2023-04-05 12:08:52 -04:00
parent 64428bac15
commit 77bb52f72c
2 changed files with 110 additions and 23 deletions

View File

@ -227,6 +227,7 @@ pub enum Lifecycle<T: Element> {
paint: T::PaintState,
},
}
pub struct ElementBox(ElementRc);
#[derive(Clone)]

View File

@ -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,7 +49,9 @@ impl View for StatusBar {
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
let theme = &cx.global::<Settings>().theme.workspace.status_bar;
Flex::row()
StatusBarElement {
left: Flex::row()
.with_children(self.left_items.iter().map(|i| {
ChildView::new(i.as_any(), cx)
.aligned()
@ -48,14 +59,18 @@ impl View for StatusBar {
.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)
.flex_float()
.boxed()
}))
.boxed(),
}
.contained()
.with_style(theme.container)
.constrained()
@ -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<usize>,
_: RectF,
_: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
_: &MeasurementContext,
) -> Option<RectF> {
None
}
fn debug(
&self,
bounds: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
_: &DebugContext,
) -> serde_json::Value {
json!({
"type": "StatusBarElement",
"bounds": bounds.to_json()
})
}
}