x11-overlay 0.1.0

A library for creating overlay interfaces on X11 systems using Cairo for rendering
Documentation
use crate::graphics::{GraphicsContext, Rectangle};
use anyhow::Result;

pub trait Component {
    fn render(&self, graphics: &mut GraphicsContext) -> Result<()>;
    fn bounds(&self) -> Rectangle;
    fn update(&mut self, delta_time: f64) -> bool; // Returns true if needs redraw

    /// Check if this component is visible (default: always visible)
    #[allow(dead_code)]
    fn is_visible(&self) -> bool {
        true
    }

    /// Check if this component should be removed (default: never remove)
    fn should_remove(&self) -> bool {
        false
    }

    /// Get component priority for rendering order (default: 0, higher = rendered later)
    #[allow(dead_code)]
    fn render_priority(&self) -> i32 {
        0
    }

    /// Calculate bounds without creating the component (for layout planning)
    /// Default implementation creates a temporary component - components should override this
    #[allow(dead_code)]
    fn calculate_bounds(&self) -> Rectangle {
        self.bounds()
    }
}

/// Extension trait for functional operations on collections of components
pub trait ComponentExt {
    #[allow(dead_code)]
    fn render_visible(&self, graphics: &mut GraphicsContext) -> Result<()>;
    fn update_all(&mut self, delta_time: f64) -> bool;
    fn remove_expired(&mut self) -> usize;
    #[allow(dead_code)]
    fn sort_by_priority(&mut self);
}

impl ComponentExt for Vec<Box<dyn Component>> {
    fn render_visible(&self, graphics: &mut GraphicsContext) -> Result<()> {
        self.iter()
            .filter(|component| component.is_visible())
            .try_for_each(|component| component.render(graphics))
    }

    fn update_all(&mut self, delta_time: f64) -> bool {
        self.iter_mut()
            .any(|component| component.update(delta_time))
    }

    fn remove_expired(&mut self) -> usize {
        let original_len = self.len();
        self.retain(|component| !component.should_remove());
        original_len - self.len()
    }

    fn sort_by_priority(&mut self) {
        self.sort_by_key(|component| component.render_priority());
    }
}