Replace hard-coded menu options with config

- Accept command, icon, option name, from config
This commit is contained in:
Candifloss 2026-01-12 12:59:02 +05:30
parent d0916291b4
commit 25eab25511
2 changed files with 58 additions and 45 deletions

View File

@ -1,5 +1,6 @@
use crate::config::ResolvedConfig; use crate::config::ResolvedConfig;
use slint::{Color, LogicalPosition, LogicalSize, SharedString}; use slint::{Color, LogicalPosition, LogicalSize, ModelRc, SharedString, VecModel};
use std::{collections::HashMap, process::Command};
slint::include_modules!(); slint::include_modules!();
@ -25,6 +26,31 @@ fn to_slint_button_style(s: crate::config::ButtonStyleResolved) -> ButtonStyle {
} }
} }
fn spawn_command(cmd: &str) {
let _ = Command::new("sh").arg("-c").arg(cmd).spawn();
}
fn build_options_model(
opts: &[crate::config::MenuOption],
) -> (ModelRc<MenuOption>, HashMap<String, String>) {
let mut command_map = HashMap::new();
let slint_opts: Vec<MenuOption> = opts
.iter()
.map(|o| {
command_map.insert(o.id.clone(), o.command.clone());
MenuOption {
op_id: o.id.clone().into(),
icon: o.icon.clone().into(),
text: o.text.clone().into(),
}
})
.collect();
(ModelRc::new(VecModel::from(slint_opts)), command_map)
}
pub fn run_power_menu(cfg: ResolvedConfig) -> Result<(), Box<dyn std::error::Error>> { pub fn run_power_menu(cfg: ResolvedConfig) -> Result<(), Box<dyn std::error::Error>> {
let ui = PowerMenu::new()?; let ui = PowerMenu::new()?;
@ -47,18 +73,24 @@ pub fn run_power_menu(cfg: ResolvedConfig) -> Result<(), Box<dyn std::error::Err
ui.set_menu_bg(cfg.menu_bg); ui.set_menu_bg(cfg.menu_bg);
ui.set_ico_lockscreen(SharedString::from(""));
ui.set_ico_logout(SharedString::from(""));
ui.set_ico_reboot(SharedString::from(""));
ui.set_ico_poweroff(SharedString::from(""));
ui.set_text_lockscreen(SharedString::from("Lock screen"));
ui.set_text_logout(SharedString::from("Log Out"));
ui.set_text_reboot(SharedString::from("Reboot"));
ui.set_text_poweroff(SharedString::from("Power Off"));
ui.set_button_style(button_style); ui.set_button_style(button_style);
let (options_model, command_map) = build_options_model(&cfg.options);
ui.set_options(options_model);
let command_map = std::sync::Arc::new(command_map);
ui.on_option_clicked({
let command_map = command_map.clone();
move |id: SharedString| {
if let Some(cmd) = command_map.get(id.as_str()) {
spawn_command(cmd);
}
}
});
ui.window().set_size(LogicalSize::new( ui.window().set_size(LogicalSize::new(
cfg.screen_width as f32, cfg.screen_width as f32,
cfg.screen_height as f32, cfg.screen_height as f32,

View File

@ -1,3 +1,9 @@
export struct MenuOption {
icon: string,
text: string,
op_id: string,
}
export struct ButtonStyle { export struct ButtonStyle {
btn_width: int, btn_width: int,
btn_height: int, btn_height: int,
@ -91,15 +97,8 @@ export component PowerMenu inherits Window {
in property <color> menu_bg; in property <color> menu_bg;
in property <string> ico_lockscreen; in property <[MenuOption]> options;
in property <string> ico_logout; callback option_clicked(string);
in property <string> ico_reboot;
in property <string> ico_poweroff;
in property <string> text_lockscreen;
in property <string> text_logout;
in property <string> text_reboot;
in property <string> text_poweroff;
no-frame: true; no-frame: true;
always-on-top: true; always-on-top: true;
@ -145,32 +144,14 @@ export component PowerMenu inherits Window {
padding: menu_padding_x *1px; padding: menu_padding_x *1px;
spacing: menu_spacing *1px; spacing: menu_spacing *1px;
// Lock screen for opt in options : PowerMenuButton {
PowerMenuButton { option_icon: opt.icon;
option_icon: ico_lockscreen; option_text: opt.text;
option_text: text_lockscreen;
button_style: root.button_style; button_style: root.button_style;
}
// Log out menu_btn_callback => {
PowerMenuButton { root.option_clicked(opt.op_id);
option_icon: ico_logout; }
option_text: text_logout;
button_style: root.button_style;
}
// Reboot
PowerMenuButton {
option_icon: ico_reboot;
option_text: text_reboot;
button_style: root.button_style;
}
// Power off
PowerMenuButton {
option_icon: ico_poweroff;
option_text: text_poweroff;
button_style: root.button_style;
} }
} }
} }