use crate::graphics::{Color, FontDesc, Rectangle};
use crate::ui::{
Alignment, Component, LayoutBuilder, LayoutContainer, NotificationComponent,
ProgressBarComponent, Spacing, StatusPanel, TextComponent,
};
use anyhow::Result;
mod animation;
mod graphics;
mod overlay;
mod ui;
mod x11;
fn main() -> Result<()> {
println!("Starting x11-overlay with component demo...");
let mut overlay = overlay::Overlay::new()?;
let screen_width = overlay.screen_width();
let screen_height = overlay.screen_height();
create_component_demo(&mut overlay, screen_width, screen_height)?;
overlay.run()?;
Ok(())
}
fn create_component_demo(
overlay: &mut overlay::Overlay,
screen_width: u16,
screen_height: u16,
) -> Result<()> {
println!("Creating layout-based component demo...");
let layout_containers = create_layout_demo(screen_width, screen_height)?;
for container in layout_containers {
overlay.add_component(Box::new(container));
}
println!("Created layout demo with multiple layout containers:");
[
"Left sidebar with vertical layout",
"Main content area with grid layout",
"Top header with horizontal layout",
"Bottom status bar with horizontal layout",
]
.iter()
.enumerate()
.for_each(|(i, desc)| println!("- {}: {}", i + 1, desc));
Ok(())
}
fn create_layout_demo(screen_width: u16, screen_height: u16) -> Result<Vec<LayoutContainer>> {
let mut containers = Vec::new();
let header_bounds = Rectangle::new(0, 0, screen_width, 80);
let mut header_layout = LayoutBuilder::horizontal(header_bounds)
.with_padding(Spacing::uniform(10))
.with_gap(20)
.with_alignment(Alignment::Start);
let header_text = TextComponent::new("X11 Overlay - Layout Demo", 0, 0, 400, 60)
.with_font(FontDesc::new("DejaVu Sans", 18.0))
.with_color(Color::rgba(1.0, 1.0, 1.0, 0.9));
header_layout.add_component(Box::new(header_text));
header_layout.layout()?; containers.push(header_layout);
let sidebar_bounds = Rectangle::new(0, 80, 200, screen_height.saturating_sub(80));
let mut sidebar_layout = LayoutBuilder::vertical(sidebar_bounds)
.with_padding(Spacing::uniform(10))
.with_gap(10)
.with_alignment(Alignment::Start);
let status_panel = create_status_panel_component()?;
sidebar_layout.add_component(status_panel);
let info_text = create_info_text_component()?;
sidebar_layout.add_component(info_text);
sidebar_layout.layout()?;
containers.push(sidebar_layout);
let main_bounds = Rectangle::new(
200,
80,
screen_width.saturating_sub(200),
screen_height.saturating_sub(160),
);
let mut main_layout = LayoutBuilder::grid(main_bounds, 2)
.with_padding(Spacing::uniform(15))
.with_gap(15)
.with_alignment(Alignment::Center);
let welcome_text = create_welcome_text_component()?;
main_layout.add_component(welcome_text);
let progress_bars = create_progress_bars_components()?;
for bar in progress_bars {
main_layout.add_component(bar);
}
main_layout.layout()?;
containers.push(main_layout);
let status_bounds =
Rectangle::new(0, screen_height.saturating_sub(80) as i16, screen_width, 80);
let mut status_layout = LayoutBuilder::horizontal(status_bounds)
.with_padding(Spacing::uniform(10))
.with_gap(20)
.with_alignment(Alignment::End);
let notification = create_notification_component()?;
status_layout.add_component(notification);
status_layout.layout()?;
containers.push(status_layout);
Ok(containers)
}
fn create_status_panel_component() -> Result<Box<dyn Component>> {
let mut status_panel = StatusPanel::new("System Status", 0, 0, 180, 120)
.with_background_color(Color::rgba(0.059, 0.071, 0.090, 0.95));
[
"CPU: 45% (4.2GHz)",
"Memory: 2.1GB / 8GB",
"Disk: 78% (SSD)",
"Network: Up 1.2MB/s Down 850KB/s",
"Battery: 87%",
]
.iter()
.for_each(|line| status_panel.add_line(line));
Ok(Box::new(status_panel))
}
fn create_welcome_text_component() -> Result<Box<dyn Component>> {
let welcome_text = TextComponent::new("Welcome to X11 Overlay!", 0, 0, 300, 80)
.with_font(FontDesc::new("DejaVu Sans", 20.0))
.with_color(Color::rgba(0.376, 0.647, 0.984, 1.0)) .centered();
Ok(Box::new(welcome_text))
}
fn create_progress_bars_components() -> Result<Vec<Box<dyn Component>>> {
let progress_configs = [
(
"Download Progress",
0.75,
Color::rgba(0.200, 0.831, 0.522, 1.0),
), (
"Upload Progress",
0.45,
Color::rgba(0.235, 0.561, 0.969, 1.0),
), ("Sync Progress", 0.85, Color::rgba(0.663, 0.408, 0.992, 1.0)), ];
let progress_bars: Vec<Box<dyn Component>> = progress_configs
.iter()
.map(|(label, progress, color)| {
let mut bar = ProgressBarComponent::new(label, 0, 0, 180)
.with_colors(Color::rgba(0.118, 0.145, 0.180, 0.8), *color); bar.set_progress(*progress);
Box::new(bar) as Box<dyn Component>
})
.collect();
Ok(progress_bars)
}
fn create_notification_component() -> Result<Box<dyn Component>> {
let notification = NotificationComponent::new("System update available!", 0, 0, 250, 10.0)
.with_background_color(Color::rgba(0.957, 0.620, 0.039, 0.95));
Ok(Box::new(notification))
}
fn create_info_text_component() -> Result<Box<dyn Component>> {
let info_text = TextComponent::new(
"Layout System:\n- Automatic positioning\n- Flexible alignment\n- Grid/Flow layouts",
0,
0,
180,
80,
)
.with_font(FontDesc::new("DejaVu Sans", 11.0))
.with_color(Color::rgba(0.925, 0.286, 0.631, 0.9));
Ok(Box::new(info_text))
}