diff --git a/Cargo.toml b/Cargo.toml index 6757252b..b02e0cfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ version = "0.58" features = [ "implement", "Foundation_Numerics", + "Globalization", "Win32_System_Com", "Win32_UI_Shell_Common", # for IObjectArray "Win32_Foundation", diff --git a/komorebi-bar/src/keyboard.rs b/komorebi-bar/src/keyboard.rs new file mode 100755 index 00000000..5364d14a --- /dev/null +++ b/komorebi-bar/src/keyboard.rs @@ -0,0 +1,93 @@ +use crate::config::LabelPrefix; +use crate::render::RenderConfig; +use crate::selected_frame::SelectableFrame; +use crate::widget::BarWidget; +use eframe::egui::text::LayoutJob; +use eframe::egui::Align; +use eframe::egui::Context; +use eframe::egui::Label; +use eframe::egui::TextFormat; +use eframe::egui::Ui; +use eframe::egui::WidgetText; +use schemars::JsonSchema; +use serde::Deserialize; +use serde::Serialize; +use windows::Globalization::Language; + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct KeyboardConfig { + /// Enable the Input widget + pub enable: bool, + /// Display label prefix + pub label_prefix: Option, +} + +impl From for Keyboard { + fn from(value: KeyboardConfig) -> Self { + Self { + enable: value.enable, + label_prefix: value.label_prefix.unwrap_or(LabelPrefix::IconAndText), + } + } +} + +pub struct Keyboard { + pub enable: bool, + pub label_prefix: LabelPrefix, +} + +impl Keyboard { + fn output(&mut self) -> String { + let lang = Language::CurrentInputMethodLanguageTag() + .map(|lang| lang.to_string()) + .unwrap_or_else(|_| "error".to_string()); + match self.label_prefix { + LabelPrefix::Text | LabelPrefix::IconAndText => format!("KB: {}", lang), + LabelPrefix::None | LabelPrefix::Icon => lang, + } + } +} + +impl BarWidget for Keyboard { + fn render(&mut self, ctx: &Context, ui: &mut Ui, config: &mut RenderConfig) { + if self.enable { + let output = self.output(); + if !output.is_empty() { + let mut layout_job = LayoutJob::simple( + match self.label_prefix { + LabelPrefix::Icon | LabelPrefix::IconAndText => { + egui_phosphor::regular::KEYBOARD.to_string() + } + LabelPrefix::None | LabelPrefix::Text => String::new(), + }, + config.icon_font_id.clone(), + ctx.style().visuals.selection.stroke.color, + 100.0, + ); + + layout_job.append( + &output, + 10.0, + TextFormat { + font_id: config.text_font_id.clone(), + color: ctx.style().visuals.text_color(), + valign: Align::Center, + ..Default::default() + }, + ); + + config.apply_on_widget(false, ui, |ui| { + if SelectableFrame::new(false) + .show(ui, |ui| { + ui.add( + Label::new(WidgetText::LayoutJob(layout_job.clone())) + .selectable(false), + ) + }) + .clicked() + {} + }); + } + } + } +} diff --git a/komorebi-bar/src/main.rs b/komorebi-bar/src/main.rs index 887710ec..b60bf449 100644 --- a/komorebi-bar/src/main.rs +++ b/komorebi-bar/src/main.rs @@ -3,6 +3,7 @@ mod battery; mod config; mod cpu; mod date; +mod keyboard; mod komorebi; mod komorebi_layout; mod media; diff --git a/komorebi-bar/src/widget.rs b/komorebi-bar/src/widget.rs index 2502f20a..aa205447 100644 --- a/komorebi-bar/src/widget.rs +++ b/komorebi-bar/src/widget.rs @@ -4,6 +4,8 @@ use crate::cpu::Cpu; use crate::cpu::CpuConfig; use crate::date::Date; use crate::date::DateConfig; +use crate::keyboard::Keyboard; +use crate::keyboard::KeyboardConfig; use crate::komorebi::Komorebi; use crate::komorebi::KomorebiConfig; use crate::media::Media; @@ -34,6 +36,7 @@ pub enum WidgetConfig { Battery(BatteryConfig), Cpu(CpuConfig), Date(DateConfig), + Keyboard(KeyboardConfig), Komorebi(KomorebiConfig), Media(MediaConfig), Memory(MemoryConfig), @@ -49,6 +52,7 @@ impl WidgetConfig { WidgetConfig::Battery(config) => Box::new(Battery::from(*config)), WidgetConfig::Cpu(config) => Box::new(Cpu::from(*config)), WidgetConfig::Date(config) => Box::new(Date::from(config.clone())), + WidgetConfig::Keyboard(config) => Box::new(Keyboard::from(*config)), WidgetConfig::Komorebi(config) => Box::new(Komorebi::from(config)), WidgetConfig::Media(config) => Box::new(Media::from(*config)), WidgetConfig::Memory(config) => Box::new(Memory::from(*config)), @@ -64,6 +68,7 @@ impl WidgetConfig { WidgetConfig::Battery(config) => config.enable, WidgetConfig::Cpu(config) => config.enable, WidgetConfig::Date(config) => config.enable, + WidgetConfig::Keyboard(config) => config.enable, WidgetConfig::Komorebi(config) => { config.workspaces.as_ref().is_some_and(|w| w.enable) || config.layout.as_ref().is_some_and(|w| w.enable)