use crate::MenuIcon;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Theme {
Dark,
Light,
System,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Corner {
Round,
DoNotRound,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub theme: Theme,
pub size: MenuSize,
pub color: ThemeColor,
pub corner: Corner,
pub font: MenuFont,
pub icon: Option<IconSettings>,
}
impl Default for Config {
fn default() -> Self {
Self {
theme: Theme::Light,
size: MenuSize::default(),
color: ThemeColor::default(),
corner: Corner::Round,
font: MenuFont::default(),
icon: Some(IconSettings::default()),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MenuSize {
pub border_size: i32,
pub vertical_padding: i32,
pub horizontal_padding: i32,
pub item_vertical_padding: i32,
pub item_horizontal_padding: i32,
pub submenu_offset: i32,
pub separator_size: i32,
}
impl Default for MenuSize {
fn default() -> Self {
Self {
border_size: 0,
vertical_padding: 0,
horizontal_padding: 0,
item_vertical_padding: 8,
item_horizontal_padding: 20,
submenu_offset: -3,
separator_size: 1,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThemeColor {
pub dark: ColorScheme,
pub light: ColorScheme,
}
impl Default for ThemeColor {
fn default() -> Self {
Self {
dark: DEFAULT_DARK_COLOR_SCHEME,
light: DEFAULT_LIGHT_COLOR_SCHEME,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ColorScheme {
pub color: u32,
pub accelerator: u32,
pub border: u32,
pub separator: u32,
pub disabled: u32,
pub background_color: u32,
pub hover_background_color: u32,
}
pub const DEFAULT_DARK_COLOR_SCHEME: ColorScheme = ColorScheme {
color: 0xe7e0e0,
accelerator: 0xe7e0e08c,
border: 0x454545,
separator: 0x454545,
disabled: 0x565659,
background_color: 0x252526,
hover_background_color: 0x3b3a3a,
};
pub const DEFAULT_LIGHT_COLOR_SCHEME: ColorScheme = ColorScheme {
color: 0x494747,
accelerator: 0x4947478c,
border: 0xe9e2e2,
separator: 0xe9e2e2,
disabled: 0xc5c1c1,
background_color: 0xFFFFFF,
hover_background_color: 0xefefef,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MenuFont {
pub font_family: String,
pub dark_font_size: f32,
pub light_font_size: f32,
pub dark_font_weight: FontWeight,
pub light_font_weight: FontWeight,
}
impl Default for MenuFont {
fn default() -> Self {
Self {
font_family: String::from("Segoe UI"),
dark_font_size: 12.0,
light_font_size: 12.0,
dark_font_weight: FontWeight::Normal,
light_font_weight: FontWeight::Normal,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum FontWeight {
Thin,
Light,
Normal,
Medium,
Bold,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IconSettings {
pub check: Option<MenuIcon>,
pub arrow: Option<MenuIcon>,
pub reserve_icon_size: bool,
pub horizontal_margin: Option<i32>,
}
impl Default for IconSettings {
fn default() -> Self {
Self {
check: None,
arrow: None,
reserve_icon_size: true,
horizontal_margin: None,
}
}
}
#[derive(Debug)]
pub struct RGBA {
pub r: u32,
pub g: u32,
pub b: u32,
pub a: f32,
}
pub(crate) fn to_hex_string(color: u32) -> String {
if has_alpha(color) {
format!("#{:08x}", color)
} else {
format!("#{:06x}", color & 0xFFFFFF)
}
}
#[cfg(target_os = "linux")]
pub(crate) fn to_rgba_string(color: u32) -> String {
let rgba = rgba_from_hex(color);
format!("rgba({}, {}, {}, {:.2})", rgba.r, rgba.g, rgba.b, rgba.a)
}
pub fn rgba_from_hex(color: u32) -> RGBA {
if has_alpha(color) {
let r = (color >> 24) & 0xFF;
let g = (color >> 16) & 0xFF;
let b = (color >> 8) & 0xFF;
let a = (color & 0xFF) as f32 / 255.0;
RGBA {
r,
g,
b,
a,
}
} else {
let r = (color >> 16) & 0xFF;
let g = (color >> 8) & 0xFF;
let b = color & 0xFF;
RGBA {
r,
g,
b,
a: 1.0,
}
}
}
fn has_alpha(value: u32) -> bool {
value > 0xFFFFFF
}
pub fn hex_from_rgb(r: u32, g: u32, b: u32) -> u32 {
r << 16 | g << 8 | b
}
pub fn hex_from_rgba(r: u32, g: u32, b: u32, a: f32) -> u32 {
let alpha = (a * 255.0).round() as u32;
r << 24 | g << 16 | b << 8 | alpha
}