Skip to content

Commit 6838e71

Browse files
committed
Big push: rewrote how state are handled in templates
1 parent 393e6c6 commit 6838e71

File tree

181 files changed

+13160
-8779
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+13160
-8779
lines changed

Cargo.toml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "anathema"
3-
edition = "2021"
3+
edition = "2024"
44
version = "0.2.0"
55
license = "MIT"
66
description = "Create beautiful, easily customisable terminal applications"
@@ -22,13 +22,20 @@ anathema-store = { path = "./anathema-store" }
2222
anathema-templates = { path = "./anathema-templates" }
2323
anathema-widgets = { path = "./anathema-widgets" }
2424
anathema-geometry = { path = "./anathema-geometry" }
25+
anathema-strings = { path = "./anathema-strings" }
26+
anathema-value-resolver = { path = "./anathema-value-resolver" }
27+
28+
[features]
29+
default = []
30+
profile = ["anathema-runtime/profile", "anathema-widgets/profile", "anathema-backend/profile"]
31+
debuggy = ["anathema-widgets/debuggy"]
2532

2633
[lints]
2734
workspace = true
2835

2936
[workspace.package]
3037
version = "0.2.0"
31-
edition = "2021"
38+
edition = "2024"
3239

3340
[workspace.dependencies]
3441
bitflags = "2.4.1"
@@ -47,8 +54,10 @@ members = [
4754
"anathema-state",
4855
"anathema-state-derive",
4956
"anathema-store",
57+
"anathema-strings",
5058
"anathema-templates",
5159
"anathema-widgets",
60+
"anathema-value-resolver",
5261
]
5362

5463
[workspace.lints.rust]

anathema-backend/Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,18 @@ edition.workspace = true
77
anathema-geometry = { path = "../anathema-geometry" }
88
anathema-state = { path = "../anathema-state" }
99
anathema-store = { path = "../anathema-store" }
10-
anathema-widgets = { path = "../anathema-widgets" }
10+
anathema-strings = { path = "../anathema-strings" }
1111
anathema-templates = { path = "../anathema-templates" }
12+
anathema-value-resolver = { path = "../anathema-value-resolver" }
13+
anathema-widgets = { path = "../anathema-widgets" }
1214
crossterm = { workspace = true }
1315
unicode-width = { workspace = true }
1416
bitflags = { workspace = true }
17+
puffin = { version = "0.19.1", optional = true }
18+
19+
[features]
20+
default = []
21+
profile = ["puffin"]
1522

1623
[lints]
1724
workspace = true

anathema-backend/src/lib.rs

Lines changed: 87 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
use std::ops::ControlFlow;
12
use std::time::Duration;
23

34
use anathema_geometry::{Pos, Size};
4-
use anathema_store::tree::{AsNodePath, Node, TreeValues};
5+
use anathema_value_resolver::{AttributeStorage, Scope};
56
use 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, GlyphMap, 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;
1012
pub mod tui;
1113

1214
pub trait Backend {
@@ -20,11 +22,8 @@ pub trait Backend {
2022
fn paint<'bp>(
2123
&mut self,
2224
glyph_map: &mut GlyphMap,
23-
element: &mut Element<'bp>,
24-
children: &[Node],
25-
values: &mut TreeValues<WidgetKind<'bp>>,
25+
widgets: PaintChildren<'_, 'bp>,
2626
attribute_storage: &AttributeStorage<'bp>,
27-
ignore_floats: bool,
2827
);
2928

3029
/// Called by the runtime at the end of the frame.
@@ -42,93 +41,101 @@ pub trait Backend {
4241
// a less silly name
4342
pub struct WidgetCycle<'rt, 'bp, T> {
4443
backend: &'rt mut T,
45-
tree: &'rt mut WidgetTree<'bp>,
46-
glyph_map: &'rt mut GlyphMap,
44+
tree: WidgetTreeView<'rt, 'bp>,
4745
constraints: Constraints,
48-
attribute_storage: &'rt AttributeStorage<'bp>,
49-
floating_widgets: &'rt FloatingWidgets,
50-
viewport: Viewport,
5146
}
5247

5348
impl<'rt, 'bp, T: Backend> WidgetCycle<'rt, 'bp, T> {
54-
pub fn new(
55-
backend: &'rt mut T,
56-
tree: &'rt mut WidgetTree<'bp>,
57-
glyph_map: &'rt mut GlyphMap,
58-
constraints: Constraints,
59-
attribute_storage: &'rt AttributeStorage<'bp>,
60-
floating_widgets: &'rt FloatingWidgets,
61-
viewport: Viewport,
62-
) -> Self {
49+
pub fn new(backend: &'rt mut T, tree: WidgetTreeView<'rt, 'bp>, constraints: Constraints) -> Self {
6350
Self {
6451
backend,
6552
tree,
66-
glyph_map,
6753
constraints,
68-
attribute_storage,
69-
floating_widgets,
70-
viewport,
7154
}
7255
}
7356

74-
fn floating(&mut self) {
75-
// Floating widgets
76-
for widget_id in self.floating_widgets.iter() {
77-
// Find the parent widget and get the position
78-
// If no parent element is found assume Pos::ZERO
79-
let mut parent = self.tree.path_ref(*widget_id).parent();
80-
let (pos, constraints) = loop {
81-
match parent {
82-
None => break (Pos::ZERO, self.constraints),
83-
Some(p) => match self.tree.get_ref_by_path(p) {
84-
Some(WidgetKind::Element(el)) => {
85-
let bounds = el.inner_bounds();
86-
break (bounds.from, Constraints::from(bounds));
87-
}
88-
_ => parent = p.parent(),
89-
},
90-
}
91-
};
92-
93-
self.tree.with_nodes_and_values(*widget_id, |widget, children, values| {
94-
let WidgetKind::Element(el) = widget else { unreachable!("this is always a floating widget") };
95-
let mut layout_ctx = LayoutCtx::new(self.attribute_storage, &self.viewport, self.glyph_map);
96-
97-
layout_widget(el, children, values, constraints, &mut layout_ctx, true);
98-
99-
// Position
100-
position_widget(pos, el, children, values, self.attribute_storage, true, self.viewport);
101-
102-
// Paint
103-
self.backend
104-
.paint(self.glyph_map, el, children, values, self.attribute_storage, true);
105-
});
57+
fn floating(&mut self, ctx: &mut LayoutCtx<'_, 'bp>, needs_layout: bool) -> Result<()> {
58+
// -----------------------------------------------------------------------------
59+
// - Layout -
60+
// -----------------------------------------------------------------------------
61+
if needs_layout {
62+
let filter = LayoutFilter::floating();
63+
self.layout(ctx, filter)?;
10664
}
65+
66+
// -----------------------------------------------------------------------------
67+
// - Position -
68+
// -----------------------------------------------------------------------------
69+
self.position(ctx.attribute_storage, *ctx.viewport, PositionFilter::floating());
70+
71+
// -----------------------------------------------------------------------------
72+
// - Paint -
73+
// -----------------------------------------------------------------------------
74+
self.paint(ctx, PaintFilter::floating());
75+
76+
Ok(())
77+
}
78+
79+
fn fixed(&mut self, ctx: &mut LayoutCtx<'_, 'bp>, needs_layout: bool) -> Result<()> {
80+
// -----------------------------------------------------------------------------
81+
// - Layout -
82+
// -----------------------------------------------------------------------------
83+
if needs_layout {
84+
let filter = LayoutFilter::fixed();
85+
self.layout(ctx, filter)?;
86+
}
87+
88+
// -----------------------------------------------------------------------------
89+
// - Position -
90+
// -----------------------------------------------------------------------------
91+
self.position(ctx.attribute_storage, *ctx.viewport, PositionFilter::fixed());
92+
93+
// -----------------------------------------------------------------------------
94+
// - Paint -
95+
// -----------------------------------------------------------------------------
96+
self.paint(ctx, PaintFilter::fixed());
97+
98+
Ok(())
10799
}
108100

109-
pub fn run(&mut self) {
110-
let mut filter = LayoutFilter::new(true, self.attribute_storage);
111-
self.tree.for_each(&mut filter).first(&mut |widget, children, values| {
112-
// Layout
113-
let mut layout_ctx = LayoutCtx::new(self.attribute_storage, &self.viewport, self.glyph_map);
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(self.glyph_map, widget, children, values, self.attribute_storage, true);
101+
pub fn run(&mut self, ctx: &mut LayoutCtx<'_, 'bp>, needs_layout: bool) -> Result<()> {
102+
self.fixed(ctx, needs_layout)?;
103+
self.floating(ctx, needs_layout)?;
104+
105+
Ok(())
106+
}
107+
108+
fn layout(&mut self, ctx: &mut LayoutCtx<'_, 'bp>, filter: LayoutFilter) -> Result<()> {
109+
#[cfg(feature = "profile")]
110+
puffin::profile_function!();
111+
let tree = self.tree.view_mut();
112+
113+
let scope = Scope::root();
114+
let mut for_each = LayoutForEach::new(tree, &scope, filter, None);
115+
let constraints = self.constraints;
116+
_ = for_each.each(ctx, |ctx, widget, children| {
117+
let _ = widget.layout(children, constraints, ctx)?;
118+
Ok(ControlFlow::Break(()))
119+
})?;
120+
Ok(())
121+
}
122+
123+
fn position(&mut self, attributes: &AttributeStorage<'bp>, viewport: Viewport, filter: PositionFilter) {
124+
#[cfg(feature = "profile")]
125+
puffin::profile_function!();
126+
127+
let mut for_each = PositionChildren::new(self.tree.view_mut(), attributes, filter);
128+
_ = for_each.each(|widget, children| {
129+
widget.position(children, Pos::ZERO, attributes, viewport);
130+
ControlFlow::Break(())
130131
});
132+
}
133+
134+
fn paint(&mut self, ctx: &mut LayoutCtx<'_, 'bp>, filter: PaintFilter) {
135+
#[cfg(feature = "profile")]
136+
puffin::profile_function!();
131137

132-
self.floating();
138+
let for_each = PaintChildren::new(self.tree.view_mut(), ctx.attribute_storage, filter);
139+
self.backend.paint(ctx.glyph_map, for_each, ctx.attribute_storage);
133140
}
134141
}

anathema-backend/src/test/mod.rs

Lines changed: 0 additions & 122 deletions
This file was deleted.

0 commit comments

Comments
 (0)