zed/crates/gpui/src/elements/align.rs

118 lines
2.8 KiB
Rust
Raw Normal View History

2021-03-10 04:00:51 +00:00
use crate::{
geometry::{rect::RectF, vector::Vector2F},
json, AnyElement, Element, LayoutContext, SceneBuilder, SizeConstraint, View, ViewContext,
2021-03-10 04:00:51 +00:00
};
use json::ToJson;
use serde_json::json;
2021-03-10 04:00:51 +00:00
2023-04-10 22:10:32 +00:00
pub struct Align<V: View> {
child: AnyElement<V>,
2021-03-10 04:00:51 +00:00
alignment: Vector2F,
}
2023-04-10 22:10:32 +00:00
impl<V: View> Align<V> {
pub fn new(child: AnyElement<V>) -> Self {
2021-03-10 04:00:51 +00:00
Self {
child,
alignment: Vector2F::zero(),
}
}
pub fn top(mut self) -> Self {
self.alignment.set_y(-1.0);
self
}
pub fn bottom(mut self) -> Self {
self.alignment.set_y(1.0);
self
}
pub fn left(mut self) -> Self {
self.alignment.set_x(-1.0);
self
}
pub fn right(mut self) -> Self {
self.alignment.set_x(1.0);
2021-03-10 04:00:51 +00:00
self
}
}
impl<V: View> Element<V> for Align<V> {
type LayoutState = ();
type PaintState = ();
2021-03-10 04:00:51 +00:00
fn layout(
&mut self,
mut constraint: SizeConstraint,
2023-04-12 00:21:56 +00:00
view: &mut V,
cx: &mut LayoutContext<V>,
) -> (Vector2F, Self::LayoutState) {
2021-03-10 04:00:51 +00:00
let mut size = constraint.max;
constraint.min = Vector2F::zero();
2023-04-12 00:21:56 +00:00
let child_size = self.child.layout(constraint, view, cx);
2021-03-10 04:00:51 +00:00
if size.x().is_infinite() {
size.set_x(child_size.x());
}
if size.y().is_infinite() {
size.set_y(child_size.y());
}
(size, ())
2021-03-10 04:00:51 +00:00
}
fn paint(
&mut self,
2023-04-10 22:10:32 +00:00
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
2023-04-12 00:21:56 +00:00
view: &mut V,
2023-04-10 22:10:32 +00:00
cx: &mut ViewContext<V>,
) -> Self::PaintState {
let my_center = bounds.size() / 2.;
let my_target = my_center + my_center * self.alignment;
let child_center = self.child.size() / 2.;
2021-03-10 04:00:51 +00:00
let child_target = child_center + child_center * self.alignment;
self.child.paint(
2023-04-10 22:10:32 +00:00
scene,
bounds.origin() - (child_target - my_target),
visible_bounds,
2023-04-12 00:21:56 +00:00
view,
cx,
);
2021-03-10 04:00:51 +00:00
}
fn rect_for_text_range(
&self,
range_utf16: std::ops::Range<usize>,
_: RectF,
_: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
2023-04-12 00:21:56 +00:00
view: &V,
2023-04-10 22:10:32 +00:00
cx: &ViewContext<V>,
) -> Option<RectF> {
2023-04-12 00:21:56 +00:00
self.child.rect_for_text_range(range_utf16, view, cx)
}
fn debug(
&self,
bounds: pathfinder_geometry::rect::RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
2023-04-12 00:21:56 +00:00
view: &V,
2023-04-10 22:10:32 +00:00
cx: &ViewContext<V>,
) -> json::Value {
json!({
"type": "Align",
"bounds": bounds.to_json(),
"alignment": self.alignment.to_json(),
2023-04-10 22:10:32 +00:00
"child": self.child.debug(view, cx),
})
}
2021-03-10 04:00:51 +00:00
}