diff --git a/README.md b/README.md index f928a7a..af23136 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ layerrule = blur, worf ## Breaking changes to Wofi * Error messages differ * Configuration files are not 100% compatible, Worf is using toml files instead, for most part this only means strings have to be quoted +* Themes are not 100% compatible ## Not supported diff --git a/src/gui.rs b/src/gui.rs index 1266a94..b65e12a 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -10,14 +10,13 @@ use gtk4::prelude::{ ApplicationExt, ApplicationExtManual, BoxExt, ButtonExt, EditableExt, EntryExt, FileChooserExt, FlowBoxChildExt, GtkWindowExt, ListBoxRowExt, NativeExt, WidgetExt, }; -use gtk4::{ - Align, EventControllerKey, Expander, FlowBox, FlowBoxChild, Label, ListBox, ListBoxRow, - PolicyType, ScrolledWindow, SearchEntry, Widget, -}; +use gtk4::{Align, EventControllerKey, Expander, FlowBox, FlowBoxChild, Image, Label, ListBox, ListBoxRow, PolicyType, ScrolledWindow, SearchEntry, Widget}; use gtk4::{Application, ApplicationWindow, CssProvider, Orientation}; use gtk4_layer_shell::{KeyboardMode, LayerShell}; use log::{debug, error, info}; use std::process::exit; +use hyprland::ctl::output::create; +use hyprland::ctl::plugin::list; #[derive(Clone)] pub struct MenuItem { @@ -219,29 +218,24 @@ fn setup_key_event_handler( fn add_menu_item(inner_box: &FlowBox, entry_element: &MenuItem) { let parent: Widget = if !entry_element.sub_elements.is_empty() { let expander = Expander::new(None); + expander.set_widget_name("expander-box"); + expander.set_halign(Align::Fill); - // Inline label as expander label - let label = Label::new(Some(&entry_element.label)); - expander.set_label_widget(Some(&label)); + let menu_row = create_menu_row(entry_element); + expander.set_label_widget(Some(&menu_row)); let list_box = ListBox::new(); - // todo subelements do not fill full space yet. + list_box.set_widget_name("entry"); + // todo multi nesting is not supported yet. - - for x in entry_element.sub_elements.iter(){ - let row = ListBoxRow::new(); - row.set_widget_name("entry"); - - let label = Label::new(Some(&x.label)); - label.set_halign(Align::Start); - row.set_child(Some(&label)); - list_box.append(&row); + for sub_item in entry_element.sub_elements.iter(){ + list_box.append(&create_menu_row(sub_item)); } expander.set_child(Some(&list_box)); expander.upcast() } else { - Label::new(Some(&entry_element.label)).upcast() + create_menu_row(entry_element).upcast() }; parent.set_halign(Align::Start); @@ -253,6 +247,32 @@ fn add_menu_item(inner_box: &FlowBox, entry_element: &MenuItem) { inner_box.append(&child); } +fn create_menu_row(menu_item: &MenuItem) -> Widget { + let row = ListBoxRow::new(); + row.set_widget_name("entry"); + row.set_hexpand(true); + row.set_halign(Align::Start); + + let row_box = gtk4::Box::new(Orientation::Horizontal, 0); + row.set_child(Some(&row_box)); + + if let Some(image_path) = &menu_item.icon_path { + // todo check config too + let image = Image::from_icon_name(image_path); + image.set_pixel_size(24); + image.set_widget_name("img"); + row_box.append(&image); + } + + let label = Label::new(Some(&menu_item.label)); + + label.set_widget_name("unselected"); + row_box.append(&label); + + + row.upcast() +} + fn percent_or_absolute(value: &String, base_value: i32) -> Option { if value.contains("%") { let value = value.replace("%", ""); diff --git a/src/main.rs b/src/main.rs index 6ac9aff..745fbd6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -115,9 +115,12 @@ fn drun(mut config: Config) -> anyhow::Result<()> { debug!("Skipping desktop entry without name {file:?}") } + let icon = file.entry.icon.as_ref().map(|s| s.content.clone()); + debug!("file, name={name:?}, icon={icon:?}"); + let mut entry = MenuItem { label: name.unwrap(), - icon_path: None, + icon_path: icon.clone(), action: None, sub_elements: Vec::default(), }; @@ -128,9 +131,13 @@ fn drun(mut config: Config) -> anyhow::Result<()> { &action.name.variants, &action.name.default, ); + let action_icon = action.icon.as_ref().map(|s| s.content.clone()).or(icon.as_ref().map(|s| s.clone())); + + debug!("sub, action_name={action_name:?}, action_icon={action_icon:?}"); + let sub_entry = MenuItem { label: action_name.unwrap().trim().to_owned(), - icon_path: None, + icon_path: action_icon, action: None, sub_elements: Vec::default(), };