Skip to main content

ling_ui/
widget.rs

1//! UI widget types.
2
3/// Core trait for all UI elements.
4pub trait Widget {
5    fn id(&self) -> u64;
6    fn render(&self, ctx: &mut RenderCtx);
7    fn handle(&mut self, event: &crate::event::Event) -> bool;
8}
9
10/// Immediate-mode render context passed to widgets.
11pub struct RenderCtx {
12    pub width:  f32,
13    pub height: f32,
14}
15
16/// Root view container — holds a tree of boxed widgets.
17pub struct View {
18    pub children: Vec<Box<dyn Widget>>,
19    next_id: u64,
20}
21
22impl View {
23    pub fn new() -> Self { Self { children: vec![], next_id: 1 } }
24    pub fn add(&mut self, w: impl Widget + 'static) { self.children.push(Box::new(w)); }
25}
26
27impl Default for View { fn default() -> Self { Self::new() } }
28
29/// A simple text label.
30pub struct Label { id: u64, pub text: String }
31
32impl Label {
33    pub fn new(id: u64, text: impl Into<String>) -> Self {
34        Self { id, text: text.into() }
35    }
36}
37
38impl Widget for Label {
39    fn id(&self) -> u64 { self.id }
40    fn render(&self, _ctx: &mut RenderCtx) {}
41    fn handle(&mut self, _e: &crate::event::Event) -> bool { false }
42}
43
44/// A clickable button.
45pub struct Button { id: u64, pub label: String, pub pressed: bool }
46
47impl Button {
48    pub fn new(id: u64, label: impl Into<String>) -> Self {
49        Self { id, label: label.into(), pressed: false }
50    }
51}
52
53impl Widget for Button {
54    fn id(&self) -> u64 { self.id }
55    fn render(&self, _ctx: &mut RenderCtx) {}
56    fn handle(&mut self, e: &crate::event::Event) -> bool {
57        if let crate::event::Event::Click { widget_id } = e {
58            if *widget_id == self.id { self.pressed = true; return true; }
59        }
60        false
61    }
62}