灵符lingfu

ling-ui

↓ 0 downloads

Ling UI framework — retained-mode widgets and flex layout

lingfu install ling-ui
LicenseApache-2.0 OR MIT
AuthorsLing Lin, Sanny Lin
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / Files (18)

src/widget.rs
//! UI widget types.

/// Core trait for all UI elements.
pub trait Widget {
    fn id(&self) -> u64;
    fn render(&self, ctx: &mut RenderCtx);
    fn handle(&mut self, event: &crate::event::Event) -> bool;
}

/// Immediate-mode render context passed to widgets.
pub struct RenderCtx {
    pub width: f32,
    pub height: f32,
}

/// Root view container — holds a tree of boxed widgets.
pub struct View {
    pub children: Vec<Box<dyn Widget>>,
    #[allow(dead_code)] // reserved for stable per-widget ids (not yet read)
    next_id: u64,
}

impl View {
    pub fn new() -> Self {
        Self { children: vec![], next_id: 1 }
    }

    pub fn add(&mut self, w: impl Widget + 'static) {
        self.children.push(Box::new(w));
    }
}

impl Default for View {
    fn default() -> Self {
        Self::new()
    }
}

/// A simple text label.
pub struct Label {
    id: u64,
    pub text: String,
}

impl Label {
    pub fn new(id: u64, text: impl Into<String>) -> Self {
        Self { id, text: text.into() }
    }
}

impl Widget for Label {
    fn id(&self) -> u64 {
        self.id
    }

    fn render(&self, _ctx: &mut RenderCtx) {}

    fn handle(&mut self, _e: &crate::event::Event) -> bool {
        false
    }
}

/// A clickable button.
pub struct Button {
    id: u64,
    pub label: String,
    pub pressed: bool,
}

impl Button {
    pub fn new(id: u64, label: impl Into<String>) -> Self {
        Self { id, label: label.into(), pressed: false }
    }
}

impl Widget for Button {
    fn id(&self) -> u64 {
        self.id
    }

    fn render(&self, _ctx: &mut RenderCtx) {}

    fn handle(&mut self, e: &crate::event::Event) -> bool {
        if let crate::event::Event::Click { widget_id } = e {
            if *widget_id == self.id {
                self.pressed = true;
                return true;
            }
        }
        false
    }
}

← Back to index