use image::Rgba;
use termwiz::cell::Cell;
use crate::{
image_renderer::{
ImageRendererError,
canvas::{Canvas, Corners},
render_size::Size,
utils::{darken_color, lighten_color},
},
theme::Theme,
window_decoration::{
Fonts, WindowMetrics,
common::{default_build_command_line, default_font},
},
};
use super::WindowDecoration;
#[derive(Debug)]
pub struct Classic;
const GREEN: Rgba<u8> = Rgba([52, 199, 89, 255]);
const YELLOW: Rgba<u8> = Rgba([255, 189, 45, 255]);
const RED: Rgba<u8> = Rgba([255, 95, 87, 255]);
impl WindowDecoration for Classic {
fn build_command_line(&self, command: &str) -> Vec<Cell> {
default_build_command_line(command)
}
fn compute_metrics(&self, char_size: Size) -> WindowMetrics {
let char_height = char_size.height;
let padding = char_height;
let border_width = 1;
let title_bar_height = char_height;
WindowMetrics {
padding,
border_width,
title_bar_height,
}
}
fn font(&self) -> Result<Fonts, ImageRendererError> {
default_font()
}
fn draw_window(
&self,
canvas: &mut Canvas,
metrics: &WindowMetrics,
theme: &Theme,
) -> Result<(), ImageRendererError> {
draw_window_decorations(canvas, metrics, theme)
}
}
fn draw_window_decorations(
canvas: &mut Canvas,
metrics: &WindowMetrics,
theme: &Theme,
) -> Result<(), ImageRendererError> {
let bg_color = theme.background_color;
let title_bar_color = darken_color(bg_color, 0.2); let border_color = lighten_color(bg_color, 0.2);
canvas.fill_rounded(
border_color,
metrics.title_bar_height as f32 / 4.0,
&Corners::ALL,
);
canvas.fill_rounded_rect(
i32::try_from(metrics.border_width)?,
i32::try_from(metrics.border_width)?,
canvas.width() - 2 * metrics.border_width,
canvas.height() - 2 * metrics.border_width,
bg_color,
metrics.title_bar_height as f32 / 4.0,
&Corners::ALL,
);
canvas.fill_rounded_rect(
i32::try_from(metrics.border_width)?,
i32::try_from(metrics.border_width)?,
canvas.width() - 2 * metrics.border_width,
metrics.title_bar_height,
title_bar_color,
metrics.title_bar_height as f32 / 4.0,
&(Corners::TOP_LEFT | Corners::TOP_RIGHT),
);
draw_window_buttons(canvas, metrics)
}
fn draw_window_buttons(
canvas: &mut Canvas,
metrics: &WindowMetrics,
) -> Result<(), ImageRendererError> {
let btn_y = i32::try_from(metrics.border_width + (metrics.title_bar_height / 2))?;
let radius = i32::try_from(metrics.title_bar_height / 4)?;
let spacing = radius * 3;
let right = i32::try_from(canvas.width() - metrics.border_width)?;
canvas.fill_circle(right - spacing, btn_y, radius, RED);
canvas.fill_circle(right - 2 * spacing, btn_y, radius, YELLOW);
canvas.fill_circle(right - 3 * spacing, btn_y, radius, GREEN);
Ok(())
}