feat(komorebi-bar): new widget to display current keyboard input method

This commit is contained in:
David
2025-02-06 21:17:01 +08:00
parent bbd232f649
commit 721d2ef408
4 changed files with 100 additions and 0 deletions

View File

@@ -45,6 +45,7 @@ version = "0.58"
features = [
"implement",
"Foundation_Numerics",
"Globalization",
"Win32_System_Com",
"Win32_UI_Shell_Common", # for IObjectArray
"Win32_Foundation",

93
komorebi-bar/src/keyboard.rs Executable file
View File

@@ -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<LabelPrefix>,
}
impl From<KeyboardConfig> 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()
{}
});
}
}
}
}

View File

@@ -3,6 +3,7 @@ mod battery;
mod config;
mod cpu;
mod date;
mod keyboard;
mod komorebi;
mod komorebi_layout;
mod media;

View File

@@ -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)