feat: window borders

This commit is contained in:
2024-05-22 04:55:45 +02:00
parent 19314e00ea
commit 157d892498
5 changed files with 63 additions and 21 deletions

View File

@@ -3,7 +3,7 @@
A practical application runner written in Rust. Inspired by [dmenu](https://tools.suckless.org/dmenu/)
### Features
- theming (colors, font family, font size, line spacing)
- theming (colors, font family, font size, line spacing, window border)
- custom row count
- prompt message
- open menu on a specific display

View File

@@ -1,8 +1,8 @@
use clap::Parser;
use crate::config::{
BACKGROUND_COLOR, BACKGROUND_COLOR_ACTIVE, FONT_COLOR, FONT_COLOR_ACTIVE, FONT_POINT_SIZE,
LINE_SPACING, MAX_ITEM_DISPLAY_COUNT,
BACKGROUND_COLOR, BACKGROUND_COLOR_ACTIVE, BORDER_COLOR, BORDER_SIZE, FONT_COLOR,
FONT_COLOR_ACTIVE, FONT_POINT_SIZE, LINE_SPACING, MAX_ITEM_DISPLAY_COUNT,
};
#[derive(Parser, Debug)]
@@ -20,6 +20,12 @@ pub struct Arguments {
#[arg(long, help = "The font color of the active item", default_value_t = String::from(FONT_COLOR_ACTIVE))]
pub font_color_active: String,
#[arg(long, help = "The window border color", default_value_t = String::from(BORDER_COLOR))]
pub border_color: String,
#[arg(long, help = "The window border size in pixels", default_value_t = BORDER_SIZE)]
pub border_size: u8,
#[arg(long, help = "The default background color", default_value_t = String::from(BACKGROUND_COLOR))]
pub background_color: String,

View File

@@ -9,9 +9,14 @@ pub const FONT_COLOR_ACTIVE: &str = "#1e1e2e";
pub const BACKGROUND_COLOR: &str = "#1e1e2e";
pub const BACKGROUND_COLOR_ACTIVE: &str = "#89b4fa";
pub const BORDER_SIZE: u8 = 1;
pub const BORDER_COLOR: &str = "#585b70";
pub struct RunnerMenuSettings {
pub font_color: String,
pub font_color_active: String,
pub border_color: String,
pub border_size: u8,
pub background_color: String,
pub background_color_active: String,
pub rows: u16,

View File

@@ -27,6 +27,8 @@ fn main() -> Result<(), Box<dyn Error>> {
font: args.font,
font_color: args.font_color,
font_color_active: args.font_color_active,
border_color: args.border_color,
border_size: args.border_size,
background_color: args.background_color,
background_color_active: args.background_color_active,
rows: args.rows,

View File

@@ -5,7 +5,7 @@ use sdl2::{
event::Event,
keyboard::{Keycode, Mod},
rect::Rect,
render::Canvas,
render::{Canvas, WindowCanvas},
ttf,
video::Window,
Sdl,
@@ -36,7 +36,7 @@ impl Runner {
let font_path: String;
let (window_width, window_height): (u32, u32);
window_width = 480;
window_width = 480 + (settings.border_size * 2) as u32;
{
font_path = get_font_path(match settings.font {
@@ -52,7 +52,8 @@ impl Runner {
window_height = (PADDING
+ ((font.height() as u16 + settings.line_spacing) * (1 + settings.rows))
- settings.line_spacing.div_euclid(2)
+ PADDING)
+ PADDING
+ (settings.border_size * 2) as u16)
.into();
}
@@ -125,6 +126,8 @@ impl Runner {
let font_color = color_from_hex(&self.settings.font_color).unwrap();
let font_color_active = color_from_hex(&self.settings.font_color_active).unwrap();
let border_color = color_from_hex(&self.settings.border_color).unwrap();
let font = self
.ttf
.load_font(&self.font_path, self.settings.font_size)
@@ -137,6 +140,8 @@ impl Runner {
'run: loop {
self.canvas.set_draw_color(background_color);
self.canvas.clear();
self.canvas.set_draw_color(border_color);
draw_borders(self.settings.border_size, self.window_size, &mut self.canvas);
for event in event_pump.poll_iter() {
match event {
@@ -222,8 +227,10 @@ impl Runner {
}
}
let mut cursor_offset_x = PADDING;
let input_position_y: u16 = (PADDING + self.settings.line_spacing.div_ceil(4)).into();
let mut cursor_offset_x = PADDING + self.settings.border_size as u16;
let input_position_y: u16 = (PADDING + self.settings.border_size as u16 - 1
+ self.settings.line_spacing.div_ceil(4))
.into();
if !self.input.is_empty() || !self.prompt.is_empty() {
let surface = font
@@ -232,7 +239,7 @@ impl Runner {
.expect("Error rendering text");
let rect = Rect::new(
PADDING.into(),
(PADDING + self.settings.border_size as u16).into(),
input_position_y.into(),
surface.width(),
surface.height(),
@@ -247,6 +254,7 @@ impl Runner {
let _ = self.canvas.copy(&texture, None, Some(rect));
}
if self.canvas.window().has_input_focus() {
let cursor_rect = Rect::new(
cursor_offset_x.into(),
input_position_y.into(),
@@ -256,6 +264,7 @@ impl Runner {
self.canvas.set_draw_color(background_color_active);
let _ = self.canvas.fill_rect(cursor_rect);
}
// try to keep the selection centered
let executables_len: u16 = filtered_executables.len() as u16;
@@ -270,7 +279,8 @@ impl Runner {
let mut display_count: u16 = 0;
for i in start..end {
let offset = PADDING * 2
let offset = self.settings.border_size as u16
+ PADDING * 2
+ (font.height() as u16 + self.settings.line_spacing) * (display_count + 1);
let surface = font
@@ -283,16 +293,16 @@ impl Runner {
.expect("Error rendering text");
let rect = Rect::new(
PADDING.into(),
(self.settings.border_size as u16 + PADDING).into(),
offset.into(),
surface.width(),
surface.height(),
);
let background_rect = Rect::new(
0,
self.settings.border_size.into(),
(offset - half_line_spacing).into(),
self.window_size.0,
self.window_size.0 - (self.settings.border_size as u32) * 2,
(surface.height() + self.settings.line_spacing as u32).into(),
);
@@ -340,3 +350,22 @@ fn filter_executables(
filtered_executables.sort_by(|a, b| b.starts_with(input).cmp(&a.starts_with(input)));
}
fn draw_borders(border_size: u8, window_size: (u32, u32), canvas: &mut WindowCanvas) {
if border_size > 0 {
let _ = canvas.fill_rect(Rect::new(0, 0, window_size.0, border_size.into()));
let _ = canvas.fill_rect(Rect::new(
(window_size.0 - border_size as u32) as i32,
0,
border_size.into(),
window_size.1,
));
let _ = canvas.fill_rect(Rect::new(
0,
(window_size.1 - border_size as u32) as i32,
window_size.0,
border_size.into(),
));
let _ = canvas.fill_rect(Rect::new(0, 0, border_size.into(), window_size.1));
}
}