rosace_widgets/tree/
positioned.rs1use rosace_core::types::{Point, Rect, Size};
2use rosace_layout::Constraints;
3use super::{Widget, Children, LayoutCtx, PaintCtx, BoxedWidget};
4
5pub struct Positioned {
11 child: BoxedWidget,
12 top: Option<f32>, left: Option<f32>, right: Option<f32>, bottom: Option<f32>,
13 width: Option<f32>, height: Option<f32>,
14}
15
16impl Positioned {
17 pub fn new(child: impl Widget + 'static) -> Self {
18 Self { child: Box::new(child), top: None, left: None, right: None, bottom: None, width: None, height: None }
19 }
20 pub fn top(mut self, v: f32) -> Self { self.top = Some(v); self }
21 pub fn left(mut self, v: f32) -> Self { self.left = Some(v); self }
22 pub fn right(mut self, v: f32) -> Self { self.right = Some(v); self }
23 pub fn bottom(mut self, v: f32) -> Self { self.bottom = Some(v); self }
24 pub fn width(mut self, v: f32) -> Self { self.width = Some(v); self }
25 pub fn height(mut self, v: f32) -> Self { self.height = Some(v); self }
26}
27
28impl Widget for Positioned {
29 fn children(&self) -> Children<'_> { Children::One(&*self.child) }
30
31 fn layout(&self, ctx: &LayoutCtx) -> Size {
32 self.child.layout(ctx)
34 }
35
36 fn paint(&self, ctx: &mut PaintCtx) {
37 let s = ctx.rect; let measured = self.child.layout(&ctx.layout_ctx(Constraints::loose(s.size.width, s.size.height)));
40 let w = self.width.or_else(|| match (self.left, self.right) {
41 (Some(l), Some(r)) => Some((s.size.width - l - r).max(0.0)),
42 _ => None,
43 }).unwrap_or(measured.width);
44 let h = self.height.or_else(|| match (self.top, self.bottom) {
45 (Some(t), Some(b)) => Some((s.size.height - t - b).max(0.0)),
46 _ => None,
47 }).unwrap_or(measured.height);
48
49 let x = match (self.left, self.right) {
50 (Some(l), _) => s.origin.x + l,
51 (None, Some(r)) => s.origin.x + s.size.width - r - w,
52 (None, None) => s.origin.x,
53 };
54 let y = match (self.top, self.bottom) {
55 (Some(t), _) => s.origin.y + t,
56 (None, Some(b)) => s.origin.y + s.size.height - b - h,
57 (None, None) => s.origin.y,
58 };
59 let rect = Rect { origin: Point { x, y }, size: Size { width: w, height: h } };
60 self.child.paint(&mut ctx.child(rect));
61 }
62}