x11-overlay 0.1.0

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

#[derive(Debug, Clone)]
#[allow(dead_code)] // Library component not yet used in main app
pub struct RectangleComponent {
    pub bounds: Rect,
    pub fill_color: Color,
    pub stroke_color: Option<Color>,
    pub stroke_width: u32,
    pub visible: bool,
}

impl RectangleComponent {
    #[allow(dead_code)] // Library API not yet used in main app
    pub fn new(bounds: Rect, fill_color: Color) -> Self {
        Self {
            bounds,
            fill_color,
            stroke_color: None,
            stroke_width: 0,
            visible: true,
        }
    }

    #[allow(dead_code)] // Library API not yet used in main app
    pub fn with_stroke(mut self, color: Color, width: u32) -> Self {
        self.stroke_color = Some(color);
        self.stroke_width = width;
        self
    }

    #[allow(dead_code)] // Library API not yet used in main app
    pub fn set_visible(&mut self, visible: bool) {
        self.visible = visible;
    }
}

impl Component for RectangleComponent {
    fn render(&self, graphics: &mut GraphicsContext) -> Result<()> {
        if !self.visible {
            return Ok(());
        }

        graphics.fill_rectangle(self.bounds, self.fill_color)?;

        if let Some(stroke_color) = self.stroke_color {
            if self.stroke_width > 0 {
                graphics.stroke_rectangle(self.bounds, stroke_color, self.stroke_width)?;
            }
        }

        Ok(())
    }

    fn bounds(&self) -> crate::graphics::Rectangle {
        crate::graphics::Rectangle::new(
            self.bounds.x as i16,
            self.bounds.y as i16,
            self.bounds.width as u16,
            self.bounds.height as u16,
        )
    }

    fn update(&mut self, _delta_time: f64) -> bool {
        false
    }

    fn is_visible(&self) -> bool {
        self.visible
    }
}

#[derive(Debug, Clone)]
#[allow(dead_code)] // Library component not yet used in main app
pub struct CircleComponent {
    pub center_x: i32,
    pub center_y: i32,
    pub radius: u32,
    pub fill_color: Color,
    pub stroke_color: Option<Color>,
    pub stroke_width: u32,
    pub visible: bool,
}

impl CircleComponent {
    #[allow(dead_code)] // Library API not yet used in main app
    pub fn new(center_x: i32, center_y: i32, radius: u32, fill_color: Color) -> Self {
        Self {
            center_x,
            center_y,
            radius,
            fill_color,
            stroke_color: None,
            stroke_width: 0,
            visible: true,
        }
    }

    #[allow(dead_code)] // Library API not yet used in main app
    pub fn with_stroke(mut self, color: Color, width: u32) -> Self {
        self.stroke_color = Some(color);
        self.stroke_width = width;
        self
    }

    #[allow(dead_code)] // Library API not yet used in main app
    pub fn set_visible(&mut self, visible: bool) {
        self.visible = visible;
    }
}

impl Component for CircleComponent {
    fn render(&self, graphics: &mut GraphicsContext) -> Result<()> {
        if !self.visible {
            return Ok(());
        }

        graphics.fill_circle(self.center_x, self.center_y, self.radius, self.fill_color)?;

        if let Some(stroke_color) = self.stroke_color {
            if self.stroke_width > 0 {
                graphics.stroke_circle(
                    self.center_x,
                    self.center_y,
                    self.radius,
                    stroke_color,
                    self.stroke_width,
                )?;
            }
        }

        Ok(())
    }

    fn bounds(&self) -> crate::graphics::Rectangle {
        let diameter = (self.radius * 2) as u16;
        crate::graphics::Rectangle::new(
            (self.center_x - self.radius as i32) as i16,
            (self.center_y - self.radius as i32) as i16,
            diameter,
            diameter,
        )
    }

    fn update(&mut self, _delta_time: f64) -> bool {
        false
    }

    fn is_visible(&self) -> bool {
        self.visible
    }
}

#[derive(Debug, Clone)]
#[allow(dead_code)] // Library component not yet used in main app
pub struct LineComponent {
    pub start_x: i32,
    pub start_y: i32,
    pub end_x: i32,
    pub end_y: i32,
    pub color: Color,
    pub width: u32,
    pub visible: bool,
}

impl LineComponent {
    #[allow(dead_code)] // Library API not yet used in main app
    pub fn new(
        start_x: i32,
        start_y: i32,
        end_x: i32,
        end_y: i32,
        color: Color,
        width: u32,
    ) -> Self {
        Self {
            start_x,
            start_y,
            end_x,
            end_y,
            color,
            width,
            visible: true,
        }
    }

    #[allow(dead_code)] // Library API not yet used in main app
    pub fn set_visible(&mut self, visible: bool) {
        self.visible = visible;
    }
}

impl Component for LineComponent {
    fn render(&self, graphics: &mut GraphicsContext) -> Result<()> {
        if !self.visible {
            return Ok(());
        }

        graphics.draw_line(
            self.start_x,
            self.start_y,
            self.end_x,
            self.end_y,
            self.color,
            self.width,
        )
    }

    fn bounds(&self) -> crate::graphics::Rectangle {
        let min_x = self.start_x.min(self.end_x);
        let max_x = self.start_x.max(self.end_x);
        let min_y = self.start_y.min(self.end_y);
        let max_y = self.start_y.max(self.end_y);

        let width = (max_x - min_x).max(self.width as i32) as u16;
        let height = (max_y - min_y).max(self.width as i32) as u16;

        crate::graphics::Rectangle::new(min_x as i16, min_y as i16, width, height)
    }

    fn update(&mut self, _delta_time: f64) -> bool {
        false
    }

    fn is_visible(&self) -> bool {
        self.visible
    }
}