power-menu-app/ui/power-menu.slint
candifloss 25eab25511 Replace hard-coded menu options with config
- Accept command, icon, option name, from config
2026-01-12 12:59:02 +05:30

159 lines
4.3 KiB
Plaintext

export struct MenuOption {
icon: string,
text: string,
op_id: string,
}
export struct ButtonStyle {
btn_width: int,
btn_height: int,
btn_border_radius: int,
btn_bg_normal: color,
btn_bg_hover: color,
btn_bg_clicked: color,
option_icon_height: int,
icon_font_size: int,
icon_font: string,
icon_font_color: color,
option_text_height: int,
option_text_font_size: int,
option_text_font: string,
option_text_color: color,
}
component PowerMenuButton {
in property <string> option_icon: "";
in property <string> option_text: "Menu Option";
in property <ButtonStyle> button_style;
callback menu_btn_callback();
Rectangle {
width: button_style.btn_width *1px;
height: button_style.btn_height *1px;
border-radius: button_style.btn_border_radius *1px;
drop-shadow-color: #232323;
drop-shadow-blur: 10px;
drop-shadow-offset-x: 0;
drop-shadow-offset-y: 0;
background: touch_area.pressed ? button_style.btn_bg_clicked
: touch_area.has-hover ? button_style.btn_bg_hover
: button_style.btn_bg_normal;
VerticalLayout {
padding: 0;
spacing: 0;
Text {
text: option_icon;
font-size: button_style.icon_font_size *1px;
width: button_style.btn_width *1px;
height: button_style.option_icon_height *1px;
vertical-alignment: center;
horizontal-alignment: center;
font-family: button_style.icon_font;
color: button_style.icon_font_color;
}
Text {
text: option_text;
font-size: button_style.option_text_font_size *1px;
width: button_style.btn_width *1px;
height: button_style.option_text_height *1px;
vertical-alignment: center;
horizontal-alignment: center;
font-family: button_style.option_text_font;
color: button_style.option_text_color;
}
}
touch_area := TouchArea {
clicked => { menu_btn_callback(); }
}
}
}
export component PowerMenu inherits Window {
callback request_close();
in property <int> screen_width;
in property <int> screen_height;
in property <color> screen_bg;
in property <ButtonStyle> button_style;
in property <int> menu_padding_x;
in property <int> menu_padding_y;
in property <int> menu_spacing;
in property <int> menu_border_radius;
in property <int> menu_width;
in property <int> menu_height;
in property <int> menu_pos_x;
in property <int> menu_pos_y;
in property <color> menu_bg;
in property <[MenuOption]> options;
callback option_clicked(string);
no-frame: true;
always-on-top: true;
background: transparent;
width: screen_width *1px;
height: screen_height *1px;
// Power menu screen
Rectangle {
width: 100%;
height: 100%;
x: 0;
y:0;
background: screen_bg;
// Close upon clicking outside the menu
TouchArea {
x: 0;
y: 0;
width: 100%;
height: 100%;
clicked => {
request_close();
}
}
// Menu pop-up
Rectangle {
background: menu_bg;
border-radius: menu_border_radius *1px;
width: menu_width *1px;
height: menu_height * 1px;
x: menu_pos_x *1px;
y: menu_pos_y *1px;
TouchArea {
// Empty. Prevent close-on-click inside the menu.
}
// Buttons
HorizontalLayout {
padding: menu_padding_x *1px;
spacing: menu_spacing *1px;
for opt in options : PowerMenuButton {
option_icon: opt.icon;
option_text: opt.text;
button_style: root.button_style;
menu_btn_callback => {
root.option_clicked(opt.op_id);
}
}
}
}
}
}