1+ use std:: ops:: ControlFlow ;
12use std:: time:: Duration ;
23
34use anathema_geometry:: { Pos , Size } ;
4- use anathema_store :: tree :: { AsNodePath , Node , TreeValues } ;
5+ use anathema_value_resolver :: { AttributeStorage , Scope } ;
56use anathema_widgets:: components:: events:: Event ;
6- use anathema_widgets:: layout:: { layout_widget, position_widget, Constraints , LayoutCtx , LayoutFilter , Viewport } ;
7- use anathema_widgets:: { AttributeStorage , Element , FloatingWidgets , WidgetKind , WidgetTree } ;
7+ use anathema_widgets:: error:: Result ;
8+ use anathema_widgets:: layout:: { Constraints , LayoutCtx , LayoutFilter , PositionFilter , Viewport } ;
9+ use anathema_widgets:: paint:: PaintFilter ;
10+ use anathema_widgets:: { GlyphMap , LayoutForEach , PaintChildren , PositionChildren , WidgetTreeView } ;
811
9- pub mod test ;
12+ pub mod testing ;
1013pub mod tui;
1114
1215pub trait Backend {
1316 fn size ( & self ) -> Size ;
1417
1518 fn next_event ( & mut self , timeout : Duration ) -> Option < Event > ;
1619
17- fn resize ( & mut self , new_size : Size ) ;
20+ fn resize ( & mut self , new_size : Size , glyph_map : & mut GlyphMap ) ;
1821
1922 /// Paint the widgets
2023 fn paint < ' bp > (
2124 & mut self ,
22- element : & mut Element < ' bp > ,
23- children : & [ Node ] ,
24- values : & mut TreeValues < WidgetKind < ' bp > > ,
25+ glyph_map : & mut GlyphMap ,
26+ widgets : PaintChildren < ' _ , ' bp > ,
2527 attribute_storage : & AttributeStorage < ' bp > ,
26- ignore_floats : bool ,
2728 ) ;
2829
2930 /// Called by the runtime at the end of the frame.
30- fn render ( & mut self ) ;
31+ fn render ( & mut self , glyph_map : & mut GlyphMap ) ;
3132
3233 /// Clear is called immediately after `render` is called.
3334 fn clear ( & mut self ) ;
@@ -41,94 +42,91 @@ pub trait Backend {
4142// a less silly name
4243pub struct WidgetCycle < ' rt , ' bp , T > {
4344 backend : & ' rt mut T ,
44- tree : & ' rt mut WidgetTree < ' bp > ,
45+ tree : WidgetTreeView < ' rt , ' bp > ,
4546 constraints : Constraints ,
46- attribute_storage : & ' rt AttributeStorage < ' bp > ,
47- floating_widgets : & ' rt FloatingWidgets ,
48- viewport : Viewport ,
4947}
5048
5149impl < ' rt , ' bp , T : Backend > WidgetCycle < ' rt , ' bp , T > {
52- pub fn new (
53- backend : & ' rt mut T ,
54- tree : & ' rt mut WidgetTree < ' bp > ,
55- constraints : Constraints ,
56- attribute_storage : & ' rt AttributeStorage < ' bp > ,
57- floating_widgets : & ' rt FloatingWidgets ,
58- viewport : Viewport ,
59- ) -> Self {
50+ pub fn new ( backend : & ' rt mut T , tree : WidgetTreeView < ' rt , ' bp > , constraints : Constraints ) -> Self {
6051 Self {
6152 backend,
6253 tree,
6354 constraints,
64- attribute_storage,
65- floating_widgets,
66- viewport,
6755 }
6856 }
6957
70- fn floating ( & mut self ) {
71- // Floating widgets
72- for widget_id in self . floating_widgets . iter ( ) {
73- // Find the parent widget and get the position
74- // If no parent element is found assume Pos::ZERO
75- let mut parent = self . tree . path_ref ( * widget_id) . parent ( ) ;
76- let ( pos, constraints) = loop {
77- match parent {
78- None => break ( Pos :: ZERO , self . constraints ) ,
79- Some ( p) => match self . tree . get_ref_by_path ( p) {
80- Some ( WidgetKind :: Element ( el) ) => {
81- let bounds = el. inner_bounds ( ) ;
82- break ( bounds. start , Constraints :: from ( bounds) ) ;
83- }
84- _ => parent = p. parent ( ) ,
85- } ,
86- }
87- } ;
88-
89- self . tree . with_nodes_and_values ( * widget_id, |widget, children, values| {
90- let WidgetKind :: Element ( el) = widget else { unreachable ! ( "this is always a floating widget" ) } ;
91- let mut layout_ctx = LayoutCtx :: new ( self . attribute_storage , & self . viewport ) ;
92-
93- layout_widget ( el, children, values, constraints, & mut layout_ctx, true ) ;
94-
95- // Position
96- position_widget ( pos, el, children, values, self . attribute_storage , true , self . viewport ) ;
97-
98- // Paint
99- self . backend . paint ( el, children, values, self . attribute_storage , true ) ;
100- } ) ;
58+ fn fixed ( & mut self , ctx : & mut LayoutCtx < ' _ , ' bp > , needs_layout : bool ) -> Result < ( ) > {
59+ // -----------------------------------------------------------------------------
60+ // - Layout -
61+ // -----------------------------------------------------------------------------
62+ if needs_layout {
63+ self . layout ( ctx, LayoutFilter ) ?;
10164 }
65+
66+ // -----------------------------------------------------------------------------
67+ // - Position -
68+ // -----------------------------------------------------------------------------
69+ self . position ( ctx. attribute_storage , * ctx. viewport , PositionFilter :: fixed ( ) ) ;
70+
71+ // -----------------------------------------------------------------------------
72+ // - Paint -
73+ // -----------------------------------------------------------------------------
74+ self . paint ( ctx, PaintFilter :: fixed ( ) ) ;
75+
76+ Ok ( ( ) )
77+ }
78+
79+ fn floating ( & mut self , ctx : & mut LayoutCtx < ' _ , ' bp > ) -> Result < ( ) > {
80+ // -----------------------------------------------------------------------------
81+ // - Position -
82+ // -----------------------------------------------------------------------------
83+ self . position ( ctx. attribute_storage , * ctx. viewport , PositionFilter :: floating ( ) ) ;
84+
85+ // -----------------------------------------------------------------------------
86+ // - Paint -
87+ // -----------------------------------------------------------------------------
88+ self . paint ( ctx, PaintFilter :: floating ( ) ) ;
89+
90+ Ok ( ( ) )
10291 }
10392
104- pub fn run ( & mut self ) {
105- let mut filter = LayoutFilter :: new ( true , self . attribute_storage ) ;
106- self . tree . for_each ( & mut filter) . first ( & mut |widget, children, values| {
107- // Layout
108- // TODO: once the text buffer can be read-only for the paint
109- // the context can be made outside of this closure.
110- //
111- // That doesn't have as much of an impact here
112- // as it will do when dealing with the floating widgets
113- let mut layout_ctx = LayoutCtx :: new ( self . attribute_storage , & self . viewport ) ;
114- layout_widget ( widget, children, values, self . constraints , & mut layout_ctx, true ) ;
115-
116- // Position
117- position_widget (
118- Pos :: ZERO ,
119- widget,
120- children,
121- values,
122- self . attribute_storage ,
123- true ,
124- self . viewport ,
125- ) ;
126-
127- // Paint
128- self . backend
129- . paint ( widget, children, values, self . attribute_storage , true ) ;
93+ pub fn run ( & mut self , ctx : & mut LayoutCtx < ' _ , ' bp > , needs_layout : bool ) -> Result < ( ) > {
94+ self . fixed ( ctx, needs_layout) ?;
95+ self . floating ( ctx) ?;
96+ Ok ( ( ) )
97+ }
98+
99+ fn layout ( & mut self , ctx : & mut LayoutCtx < ' _ , ' bp > , filter : LayoutFilter ) -> Result < ( ) > {
100+ #[ cfg( feature = "profile" ) ]
101+ puffin:: profile_function!( ) ;
102+ let tree = self . tree . view_mut ( ) ;
103+
104+ let scope = Scope :: root ( ) ;
105+ let mut for_each = LayoutForEach :: new ( tree, & scope, filter, None ) ;
106+ let constraints = self . constraints ;
107+ _ = for_each. each ( ctx, |ctx, widget, children| {
108+ _ = widget. layout ( children, constraints, ctx) ?;
109+ Ok ( ControlFlow :: Break ( ( ) ) )
110+ } ) ?;
111+ Ok ( ( ) )
112+ }
113+
114+ fn position ( & mut self , attributes : & AttributeStorage < ' bp > , viewport : Viewport , filter : PositionFilter ) {
115+ #[ cfg( feature = "profile" ) ]
116+ puffin:: profile_function!( ) ;
117+
118+ let mut for_each = PositionChildren :: new ( self . tree . view_mut ( ) , attributes, filter) ;
119+ _ = for_each. each ( |widget, children| {
120+ widget. position ( children, Pos :: ZERO , attributes, viewport) ;
121+ ControlFlow :: Break ( ( ) )
130122 } ) ;
123+ }
124+
125+ fn paint ( & mut self , ctx : & mut LayoutCtx < ' _ , ' bp > , filter : PaintFilter ) {
126+ #[ cfg( feature = "profile" ) ]
127+ puffin:: profile_function!( ) ;
131128
132- self . floating ( ) ;
129+ let for_each = PaintChildren :: new ( self . tree . view_mut ( ) , ctx. attribute_storage , filter) ;
130+ self . backend . paint ( ctx. glyph_map , for_each, ctx. attribute_storage ) ;
133131 }
134132}
0 commit comments