diff --git a/data/popup.ui b/data/popup.ui index 214fbea6..94b15e1e 100644 --- a/data/popup.ui +++ b/data/popup.ui @@ -1,7 +1,16 @@ - - + + + Emoji + layout + emoji + + + Terminal + layout + terminal +
Keyboard Settings diff --git a/src/popover.rs b/src/popover.rs index 9a1b6902..e2b8aebf 100644 --- a/src/popover.rs +++ b/src/popover.rs @@ -20,10 +20,9 @@ use gio::SimpleActionExt; use glib::translate::FromGlibPtrNone; use glib::variant::ToVariant; #[cfg(not(feature = "gtk_v0_5"))] -use gtk::BuilderExtManual; +use gtk::prelude::*; use gtk::PopoverExt; use gtk::WidgetExt; -use std::io::Write; use ::logging::Warn; mod c { @@ -111,46 +110,6 @@ mod variants { } } -fn make_menu_builder(inputs: Vec<(&str, OwnedTranslation)>) -> gtk::Builder { - let mut xml: Vec = Vec::new(); - writeln!( - xml, - " - - -
" - ).unwrap(); - for (input_name, translation) in inputs { - writeln!( - xml, - " - - {} - layout - {} - ", - translation.0, - input_name, - ).unwrap(); - } - writeln!( - xml, - " -
-
- - Keyboard Settings - settings - -
-
-
" - ).unwrap(); - gtk::Builder::new_from_string( - &String::from_utf8(xml).expect("Bad menu definition") - ) -} - fn get_settings(schema_name: &str) -> Option { let mut error_handler = logging::Print{}; gio::SettingsSchemaSource::get_default() @@ -350,12 +309,12 @@ pub fn show( .chain(overlay_layouts) .collect(); - let translated_names = translate_layout_names(&all_layouts); - - // sorted collection of human and machine names + let translated_names = translate_layout_names(&system_layouts); + + // sorted collection of language layouts let mut human_names: Vec<(OwnedTranslation, LayoutId)> = translated_names .into_iter() - .zip(all_layouts.clone().into_iter()) + .zip(system_layouts.clone().into_iter()) .collect(); human_names.sort_unstable_by(|(tr_a, layout_a), (tr_b, layout_b)| { @@ -367,32 +326,14 @@ pub fn show( } }); - // GVariant doesn't natively support `enum`s, - // so the `choices` vector will serve as a lookup table. - let choices_with_translations: Vec<(String, (OwnedTranslation, LayoutId))> - = human_names.into_iter() - .enumerate() - .map(|(i, human_entry)| {( - format!("{}_{}", i, human_entry.1.get_name()), - human_entry, - )}).collect(); + let builder = gtk::Builder::new_from_resource("/sm/puri/squeekboard/popup.ui"); + let model: gio::Menu = builder.get_object("app-menu").unwrap(); - - let builder = make_menu_builder( - choices_with_translations.iter() - .map(|(id, (translation, _))| (id.as_str(), (*translation).clone())) - .collect() - ); - - let choices: Vec<(String, LayoutId)> - = choices_with_translations.into_iter() - .map(|(id, (_tr, layout))| (id, layout)) - .collect(); - - // Much more debuggable to populate the model & menu - // from a string representation - // than add items imperatively - let model: gio::MenuModel = builder.get_object("app-menu").unwrap(); + for (tr, l) in human_names.iter().rev() { + let detailed_action = format!("layout::{}", l.get_name()); + let item = gio::MenuItem::new(Some(&tr.0), Some(detailed_action.as_str())); + model.prepend_item (&item); + } let menu = gtk::Popover::new_from_model(Some(&window), &model); menu.set_pointing_to(>k::Rectangle { @@ -403,32 +344,36 @@ pub fn show( }); menu.set_constrain_to(gtk::PopoverConstraint::None); + let action_group = gio::SimpleActionGroup::new(); + if let Some(current_layout) = get_current_layout(manager, &system_layouts) { - let current_name_variant = choices.iter() + let current_layout_name = all_layouts.iter() .find( - |(_id, layout)| layout == ¤t_layout + |l| l.get_name() == current_layout.get_name() ).unwrap() - .0.to_variant(); + .get_name(); + log_print!(logging::Level::Debug, "Current Layout {}", current_layout_name); let layout_action = gio::SimpleAction::new_stateful( "layout", - Some(current_name_variant.type_()), - ¤t_name_variant, + Some(current_layout_name.to_variant().type_()), + ¤t_layout_name.to_variant() ); let menu_inner = menu.clone(); layout_action.connect_change_state(move |_action, state| { match state { Some(v) => { + log_print!(logging::Level::Debug, "Selected layout {}", v); v.get::() .or_print( logging::Problem::Bug, &format!("Variant is not string: {:?}", v) ) .map(|state| { - let (_id, layout) = choices.iter() + let layout = all_layouts.iter() .find( - |choices| state == choices.0 + |choices| state == choices.get_name() ).unwrap(); set_visible_layout( manager, @@ -443,20 +388,18 @@ pub fn show( }; menu_inner.popdown(); }); - - let settings_action = gio::SimpleAction::new("settings", None); - settings_action.connect_activate(move |_, _| { - let s = CString::new("region").unwrap(); - unsafe { c::popover_open_settings_panel(s.as_ptr()) }; - }); - - let action_group = gio::SimpleActionGroup::new(); action_group.add_action(&layout_action); - action_group.add_action(&settings_action); - - menu.insert_action_group("popup", Some(&action_group)); }; + let settings_action = gio::SimpleAction::new("settings", None); + settings_action.connect_activate(move |_, _| { + let s = CString::new("region").unwrap(); + unsafe { c::popover_open_settings_panel(s.as_ptr()) }; + }); + action_group.add_action(&settings_action); + + menu.insert_action_group("popup", Some(&action_group)); + menu.bind_model(Some(&model), Some("popup")); menu.popup(); }