use minui::{Color, ColorPair, Event, Result, TerminalWindow, Window, define_colors};
define_colors! {
pub const SUNSET_ORANGE = (Color::rgb(255, 165, 0), Color::Black);
pub const SUNSET_RED = (Color::rgb(255, 69, 0), Color::Black);
pub const SUNSET_PURPLE = (Color::rgb(148, 0, 211), Color::Black);
pub const OCEAN_DEEP = (Color::rgb(0, 105, 148), Color::Black);
pub const OCEAN_MEDIUM = (Color::rgb(0, 191, 255), Color::Black);
pub const OCEAN_LIGHT = (Color::rgb(173, 216, 230), Color::Black);
pub const FOREST_DARK = (Color::rgb(34, 139, 34), Color::Black);
pub const FOREST_BRIGHT = (Color::rgb(124, 252, 0), Color::Black);
pub const NEON_PINK = (Color::rgb(255, 20, 147), Color::Black);
pub const NEON_CYAN = (Color::rgb(0, 255, 255), Color::Black);
pub const NEON_GREEN = (Color::rgb(57, 255, 20), Color::Black);
}
fn main() -> Result<()> {
let mut window = TerminalWindow::new()?;
window.set_auto_flush(false);
window.clear_screen()?;
let (width, height) = window.get_size();
window.write_str(0, 0, "RGB Color & Gradient Demo (press 'q' to quit)")?;
draw_rainbow_gradient(&mut window, 2, width)?;
draw_color_themes(&mut window, 6)?;
draw_vertical_gradient(&mut window, 12, width, height)?;
draw_color_blocks(&mut window, height)?;
window.flush()?;
loop {
if let Ok(event) = window.get_input() {
if let Event::Character('q') = event {
break;
}
}
}
Ok(())
}
fn draw_rainbow_gradient(window: &mut TerminalWindow, start_y: u16, width: u16) -> Result<()> {
window.write_str(start_y, 0, "Rainbow Gradient:")?;
let gradient_y = start_y + 1;
let gradient_width = (width - 2).min(60);
for x in 0..gradient_width {
let hue = (x as f32 / gradient_width as f32) * 360.0;
let (r, g, b) = hsl_to_rgb(hue, 1.0, 0.5);
let color = ColorPair::new(Color::rgb(r, g, b), Color::Black);
window.write_str_colored(gradient_y, x + 1, "█", color)?;
}
Ok(())
}
fn draw_color_themes(window: &mut TerminalWindow, start_y: u16) -> Result<()> {
window.write_str(start_y, 0, "Color Themes:")?;
window.write_str(start_y + 1, 0, "Sunset: ")?;
window.write_str_colored(start_y + 1, 8, "█████", SUNSET_ORANGE)?;
window.write_str_colored(start_y + 1, 13, "█████", SUNSET_RED)?;
window.write_str_colored(start_y + 1, 18, "█████", SUNSET_PURPLE)?;
window.write_str(start_y + 2, 0, "Ocean: ")?;
window.write_str_colored(start_y + 2, 8, "█████", OCEAN_DEEP)?;
window.write_str_colored(start_y + 2, 13, "█████", OCEAN_MEDIUM)?;
window.write_str_colored(start_y + 2, 18, "█████", OCEAN_LIGHT)?;
window.write_str(start_y + 3, 0, "Forest: ")?;
window.write_str_colored(start_y + 3, 8, "█████", FOREST_DARK)?;
window.write_str_colored(start_y + 3, 13, "█████", FOREST_BRIGHT)?;
window.write_str(start_y + 4, 0, "Neon: ")?;
window.write_str_colored(start_y + 4, 8, "█████", NEON_PINK)?;
window.write_str_colored(start_y + 4, 13, "█████", NEON_CYAN)?;
window.write_str_colored(start_y + 4, 18, "█████", NEON_GREEN)?;
Ok(())
}
fn draw_vertical_gradient(
window: &mut TerminalWindow,
start_y: u16,
width: u16,
height: u16,
) -> Result<()> {
if start_y + 10 > height {
return Ok(()); }
window.write_str(start_y, 0, "Vertical Blue-to-Red Gradient:")?;
let gradient_height = (height - start_y - 2).min(8);
let gradient_width = (width - 2).min(30);
for y in 0..gradient_height {
let ratio = y as f32 / gradient_height as f32;
let r = (ratio * 255.0) as u8;
let g = 0;
let b = ((1.0 - ratio) * 255.0) as u8;
let color = ColorPair::new(Color::rgb(r, g, b), Color::Black);
for x in 0..gradient_width {
window.write_str_colored(start_y + 1 + y, x + 1, "█", color)?;
}
}
Ok(())
}
fn draw_color_blocks(window: &mut TerminalWindow, height: u16) -> Result<()> {
let start_y = height.saturating_sub(6);
window.write_str(start_y, 0, "RGB Color Examples:")?;
let colors = [
(Color::rgb(255, 0, 0), "Pure Red (255,0,0)"),
(Color::rgb(0, 255, 0), "Pure Green (0,255,0)"),
(Color::rgb(0, 0, 255), "Pure Blue (0,0,255)"),
(Color::rgb(255, 255, 0), "Yellow (255,255,0)"),
(Color::rgb(255, 0, 255), "Magenta (255,0,255)"),
(Color::rgb(0, 255, 255), "Cyan (0,255,255)"),
];
for (i, (color, label)) in colors.iter().enumerate() {
let y = start_y + 1 + (i as u16 / 3);
let x = (i % 3) * 25;
let color_pair = ColorPair::new(*color, Color::Black);
window.write_str_colored(y, x as u16, "███", color_pair)?;
window.write_str(y, x as u16 + 4, label)?;
}
Ok(())
}
fn hsl_to_rgb(h: f32, s: f32, l: f32) -> (u8, u8, u8) {
let h = h / 60.0;
let c = (1.0 - (2.0 * l - 1.0).abs()) * s;
let x = c * (1.0 - (h % 2.0 - 1.0).abs());
let m = l - c / 2.0;
let (r_prime, g_prime, b_prime) = if h < 1.0 {
(c, x, 0.0)
} else if h < 2.0 {
(x, c, 0.0)
} else if h < 3.0 {
(0.0, c, x)
} else if h < 4.0 {
(0.0, x, c)
} else if h < 5.0 {
(x, 0.0, c)
} else {
(c, 0.0, x)
};
let r = ((r_prime + m) * 255.0) as u8;
let g = ((g_prime + m) * 255.0) as u8;
let b = ((b_prime + m) * 255.0) as u8;
(r, g, b)
}