use eframe::egui::{
Align, CornerRadius, Frame, Layout, Margin, Response, RichText, Stroke, Ui, vec2,
};
use super::{Palette, font_mono, size};
pub(crate) fn key_name(key: &str) -> String {
key.trim()
.to_ascii_lowercase()
.split('_')
.map(|part| match part {
"left" => "L".to_owned(),
"right" => "R".to_owned(),
"meta" | "super" | "win" => match std::env::consts::OS {
"windows" => "Win",
"macos" => "Cmd",
_ => "Super",
}
.to_owned(),
other => {
let mut word = other.to_owned();
if let Some(first) = word.get_mut(..1) {
first.make_ascii_uppercase();
}
word
}
})
.collect::<Vec<_>>()
.join(" ")
}
pub(crate) fn keycap(ui: &mut Ui, key: &str) -> Response {
let p = Palette::of(ui.ctx());
Frame::new()
.fill(p.hover)
.stroke(Stroke::new(1.0, p.border_strong))
.corner_radius(CornerRadius::same(size::R_KEYCAP))
.inner_margin(Margin::symmetric(7, 2))
.show(ui, |ui| {
ui.label(
RichText::new(key_name(key))
.font(font_mono(12.0))
.color(p.text),
);
})
.response
}
pub(crate) fn chord(ui: &mut Ui, chord: &str) {
let keys: Vec<_> = chord.split('+').collect();
let width: f32 = keys
.iter()
.map(|key| {
ui.painter()
.layout_no_wrap(key_name(key), font_mono(12.0), Palette::of(ui.ctx()).text)
.size()
.x
+ 18.0
})
.sum();
ui.allocate_ui_with_layout(
vec2(width.min(ui.available_width()), size::CONTROL_H),
Layout::left_to_right(Align::Center).with_main_wrap(true),
|ui| {
ui.spacing_mut().item_spacing.x = 4.0;
for key in keys {
keycap(ui, key);
}
},
);
}