rosace_widgets/tree/
rect_reader.rs1use rosace_core::types::Rect;
2use rosace_state::Atom;
3use super::{Widget, PaintCtx, BoxedWidget};
4
5pub struct RectReader {
14 atom: Atom<Option<Rect>>,
15 child: BoxedWidget,
16}
17
18impl RectReader {
19 pub fn new(atom: Atom<Option<Rect>>, child: impl Widget + 'static) -> Self {
20 Self { atom, child: Box::new(child) }
21 }
22}
23
24impl Widget for RectReader {
25 fn children(&self) -> super::Children<'_> {
26 super::Children::One(&*self.child)
27 }
28
29 fn paint(&self, ctx: &mut PaintCtx) {
30 let r = ctx.rect;
31 self.child.paint(&mut ctx.child(r));
32 self.atom.set(Some(r));
33 }
34 }
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40 use rosace_core::types::{Point, Rect, Size};
41
42 use rosace_render::{FontCache, PictureRecorder};
43 use rosace_state::use_atom;
44 use rosace_theme::built_in;
45 use std::rc::Rc;
46 use std::cell::RefCell;
47 use crate::tree::{RenderTree, Text};
48
49 fn make_paint_ctx<'a>(
50 recorder: &'a mut PictureRecorder,
51 font: &'a FontCache,
52 ) -> PaintCtx<'a> {
53 let theme = built_in::dark_theme();
54 let mut ctx = PaintCtx::root(
55 recorder,
56 Rect {
57 origin: Point { x: 10.0, y: 20.0 },
58 size: Size { width: 100.0, height: 50.0 },
59 },
60 font,
61 theme,
62 Rc::new(RefCell::new(RenderTree::new())),
63 );
64 ctx.clip_rect = None;
65 ctx
66 }
67
68 #[test]
69 fn fires_atom_with_paint_rect() {
70 let atom: Atom<Option<Rect>> = use_atom(None);
71 let font = FontCache::system_ui()
72 .or_else(FontCache::system_mono)
73 .expect("no system font");
74 let widget = RectReader::new(atom.clone(), Text::new("hi"));
75 let mut recorder = PictureRecorder::new();
76 let mut ctx = make_paint_ctx(&mut recorder, &font);
77 widget.paint(&mut ctx);
78 let rect = atom.get().expect("atom should be Some after paint");
79 assert_eq!(rect.origin.x, 10.0);
80 assert_eq!(rect.origin.y, 20.0);
81 assert_eq!(rect.size.width, 100.0);
82 assert_eq!(rect.size.height, 50.0);
83 }
84}