Skip to main content

Node

Struct Node 

Source
pub struct Node {
    pub x: u16,
    pub y: u16,
    pub width: u16,
    pub height: u16,
}
Expand description

Position and size of a UI element.

Fields§

§x: u16§y: u16§width: u16§height: u16

Implementations§

Source§

impl Node

Source

pub fn new(x: u16, y: u16, width: u16, height: u16) -> Self

Examples found in repository?
examples/ui.rs (line 27)
24fn setup(world: &mut World) {
25    // Root container fills the terminal
26    let root = world.spawn((
27        Node::new(0, 0, 0, 0),
28        Container,
29        Anchor::fill(),
30    ));
31
32    // Title
33    world.spawn((
34        Node::new(0, 0, 0, 0),
35        Text::new("Decay UI Demo"),
36        UiStyle { fg: Some((100, 160, 255)), bold: true, ..UiStyle::new() },
37        Anchor { min: (0.0, 0.0), max: (0.6, 0.0), offset: (4, 1, 0, 2) },
38        Parent(root),
39    ));
40
41    // Subtitle
42    world.spawn((
43        Node::new(0, 0, 0, 0),
44        Text::new("A TUI framework built on an ECS core"),
45        UiStyle::dim(),
46        Anchor { min: (0.0, 0.0), max: (0.6, 0.0), offset: (4, 2, 0, 3) },
47        Parent(root),
48    ));
49
50    // Separator
51    world.spawn((
52        Node::new(0, 0, 0, 0),
53        Separator::new(),
54        Anchor { min: (0.0, 0.0), max: (0.6, 0.0), offset: (4, 4, 0, 5) },
55        Parent(root),
56    ));
57
58    // Status label
59    let status = world.spawn((
60        Node::new(0, 0, 0, 0),
61        Text::new("Select a button and press Enter..."),
62        Anchor { min: (0.0, 0.0), max: (0.7, 0.0), offset: (4, 6, 0, 7) },
63        Parent(root),
64    ));
65    world.insert_resource(StatusLabel(status));
66
67    // Click counter
68    let counter = world.spawn((
69        Node::new(0, 0, 0, 0),
70        Text::new("Clicks: 0"),
71        UiStyle::dim(),
72        Anchor { min: (0.0, 0.0), max: (0.7, 0.0), offset: (4, 7, 0, 8) },
73        Parent(root),
74    ));
75    world.insert_resource(CounterLabel(counter));
76    world.insert_resource(ClickCount(0));
77
78    // Buttons
79    world.spawn((
80        Node::new(0, 0, 0, 0),
81        Text::new("Say Hello"), Button, Interaction::None,
82        Anchor { min: (0.0, 0.0), max: (0.45, 0.0), offset: (4, 10, 0, 13) },
83        Parent(root),
84    ));
85
86    world.spawn((
87        Node::new(0, 0, 0, 0),
88        Text::new("Say Goodbye"), Button, Interaction::None,
89        Anchor { min: (0.0, 0.0), max: (0.45, 0.0), offset: (4, 14, 0, 17) },
90        Parent(root),
91    ));
92
93    world.spawn((
94        Node::new(0, 0, 0, 0),
95        Text::new("Reset Counter"), Button, Interaction::None,
96        Anchor { min: (0.0, 0.0), max: (0.45, 0.0), offset: (4, 18, 0, 21) },
97        Parent(root),
98    ));
99
100    // Instructions
101    world.spawn((
102        Node::new(0, 0, 0, 0),
103        Text::new("\u{2191}\u{2193}/Tab  Navigate    Enter/Space  Click    q  Quit"),
104        UiStyle::dim(),
105        Anchor { min: (0.0, 0.0), max: (0.8, 0.0), offset: (4, 22, 0, 23) },
106        Parent(root),
107    ));
108}
More examples
Hide additional examples
examples/fancyui.rs (line 29)
24fn setup(world: &mut World) {
25    world.insert_resource(FrameCount(0));
26
27    // Root container fills the terminal
28    let root = world.spawn((
29        Node::new(0, 0, 0, 0),
30        Container,
31        Anchor::fill(),
32    ));
33
34    // ═══ Header Panel ═══
35    let header = world.spawn((
36        Node::new(0, 0, 0, 0),
37        Panel::titled("\u{2726} Decay Fancy UI").border(BorderStyle::Double).shadow(),
38        UiStyle::fg(90, 130, 220),
39        Anchor { min: (0.0, 0.0), max: (1.0, 0.0), offset: (2, 1, -2, 4) },
40        Parent(root),
41    ));
42
43    // Subtitle inside panel
44    world.spawn((
45        Node::new(0, 0, 0, 0),
46        Text::new("zero-dependency TUI framework"),
47        UiStyle { fg: Some((130, 130, 145)), italic: true, ..UiStyle::new() },
48        TextAlign::Center,
49        Anchor { min: (0.0, 0.0), max: (1.0, 1.0), offset: (2, 1, -2, -1) },
50        Parent(header),
51    ));
52
53    // ─── System Monitor ───
54    world.spawn((
55        Node::new(0, 0, 0, 0),
56        Separator::labeled("System Monitor"),
57        Anchor { min: (0.0, 0.0), max: (1.0, 0.0), offset: (2, 4, -2, 5) },
58        Parent(root),
59    ));
60
61    // Progress bar labels
62    world.spawn((
63        Node::new(0, 0, 0, 0), Text::new("CPU"), UiStyle::dim(),
64        Anchor { min: (0.0, 0.0), max: (0.0, 0.0), offset: (3, 5, 11, 6) },
65        Parent(root),
66    ));
67    world.spawn((
68        Node::new(0, 0, 0, 0), Text::new("Memory"), UiStyle::dim(),
69        Anchor { min: (0.0, 0.0), max: (0.0, 0.0), offset: (3, 6, 11, 7) },
70        Parent(root),
71    ));
72    world.spawn((
73        Node::new(0, 0, 0, 0), Text::new("Disk"), UiStyle::dim(),
74        Anchor { min: (0.0, 0.0), max: (0.0, 0.0), offset: (3, 7, 11, 8) },
75        Parent(root),
76    ));
77    world.spawn((
78        Node::new(0, 0, 0, 0), Text::new("Network"), UiStyle::dim(),
79        Anchor { min: (0.0, 0.0), max: (0.0, 0.0), offset: (3, 8, 11, 9) },
80        Parent(root),
81    ));
82
83    // Progress bars (proportional width)
84    let cpu = world.spawn((
85        Node::new(0, 0, 0, 0),
86        ProgressBar::new(0.64).with_gradient((255, 100, 80)).with_label(),
87        Anchor { min: (0.15, 0.0), max: (0.55, 0.0), offset: (0, 5, 0, 6) },
88        Parent(root),
89    ));
90    let mem = world.spawn((
91        Node::new(0, 0, 0, 0),
92        ProgressBar::new(0.78)
93            .with_gradient((100, 180, 255))
94            .with_label()
95            .with_colors((60, 160, 240), (40, 40, 50)),
96        Anchor { min: (0.15, 0.0), max: (0.55, 0.0), offset: (0, 6, 0, 7) },
97        Parent(root),
98    ));
99    let disk = world.spawn((
100        Node::new(0, 0, 0, 0),
101        ProgressBar::new(0.21).with_label(),
102        Anchor { min: (0.15, 0.0), max: (0.55, 0.0), offset: (0, 7, 0, 8) },
103        Parent(root),
104    ));
105    let net = world.spawn((
106        Node::new(0, 0, 0, 0),
107        ProgressBar::classic(0.45)
108            .with_colors((200, 180, 60), (50, 50, 60))
109            .with_label(),
110        Anchor { min: (0.15, 0.0), max: (0.55, 0.0), offset: (0, 8, 0, 9) },
111        Parent(root),
112    ));
113    world.insert_resource(Bars { cpu, mem, disk, net });
114
115    // ─── Controls ───
116    world.spawn((
117        Node::new(0, 0, 0, 0),
118        Separator::labeled("Controls"),
119        Anchor { min: (0.0, 0.0), max: (1.0, 0.0), offset: (2, 10, -2, 11) },
120        Parent(root),
121    ));
122
123    // Buttons (2x2 grid, proportional width)
124    world.spawn((
125        Node::new(0, 0, 0, 0),
126        Text::new("Dashboard"), Button, Interaction::None,
127        Anchor { min: (0.0, 0.0), max: (0.48, 0.0), offset: (3, 11, 0, 14) },
128        Parent(root),
129    ));
130    world.spawn((
131        Node::new(0, 0, 0, 0),
132        Text::new("Reports"), Button, Interaction::None,
133        Anchor { min: (0.5, 0.0), max: (1.0, 0.0), offset: (0, 11, -2, 14) },
134        Parent(root),
135    ));
136    world.spawn((
137        Node::new(0, 0, 0, 0),
138        Text::new("Settings"), Button, Interaction::None,
139        Anchor { min: (0.0, 0.0), max: (0.48, 0.0), offset: (3, 14, 0, 17) },
140        Parent(root),
141    ));
142    world.spawn((
143        Node::new(0, 0, 0, 0),
144        Text::new("Exit"), Button, Interaction::None,
145        Anchor { min: (0.5, 0.0), max: (1.0, 0.0), offset: (0, 14, -2, 17) },
146        Parent(root),
147    ));
148
149    // ─── Activity ───
150    world.spawn((
151        Node::new(0, 0, 0, 0),
152        Separator::labeled("Activity"),
153        Anchor { min: (0.0, 0.0), max: (1.0, 0.0), offset: (2, 17, -2, 18) },
154        Parent(root),
155    ));
156
157    // Spinner
158    world.spawn((
159        Node::new(0, 0, 0, 0),
160        Spinner::new(SpinnerStyle::Dots).with_label("Processing data..."),
161        UiStyle::fg(100, 200, 255),
162        Anchor { min: (0.0, 0.0), max: (0.5, 0.0), offset: (3, 18, 0, 19) },
163        Parent(root),
164    ));
165
166    // Animated typewriter text
167    world.spawn((
168        Node::new(0, 0, 0, 0),
169        AnimatedText::new("The quick brown fox jumps over the lazy dog", 15.0),
170        UiStyle::fg(180, 180, 195),
171        Anchor { min: (0.0, 0.0), max: (0.8, 0.0), offset: (3, 19, 0, 20) },
172        Parent(root),
173    ));
174
175    // Status
176    let status = world.spawn((
177        Node::new(0, 0, 0, 0),
178        Text::new("Select a button and press Enter..."),
179        UiStyle::dim(),
180        Anchor { min: (0.0, 0.0), max: (0.8, 0.0), offset: (3, 21, 0, 22) },
181        Parent(root),
182    ));
183    world.insert_resource(StatusLabel(status));
184
185    // Footer
186    world.spawn((
187        Node::new(0, 0, 0, 0),
188        Text::new("\u{2191}\u{2193}/Tab Navigate   Enter/Space Click   q Quit"),
189        UiStyle::dim(),
190        Anchor { min: (0.0, 0.0), max: (0.8, 0.0), offset: (3, 22, 0, 23) },
191        Parent(root),
192    ));
193}

Trait Implementations§

Auto Trait Implementations§

§

impl Freeze for Node

§

impl RefUnwindSafe for Node

§

impl Send for Node

§

impl Sync for Node

§

impl Unpin for Node

§

impl UnsafeUnpin for Node

§

impl UnwindSafe for Node

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.