diff --git a/src/app.rs b/src/app.rs index ee8052e..6d86430 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,8 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only +use cosmic::widget::menu::action::MenuAction; +use cosmic::widget::menu::key_bind::KeyBind; use cosmic::{ app::{message, Command, Core}, cosmic_config, cosmic_theme, executor, @@ -32,7 +34,7 @@ use std::{ use crate::{ config::{AppTheme, Config, IconSizes, TabConfig, CONFIG_VERSION}, fl, home_dir, - key_bind::{key_binds, KeyBind}, + key_bind::key_binds, menu, mime_app, operation::Operation, spawn_detached::spawn_detached, @@ -83,8 +85,10 @@ pub enum Action { WindowNew, } -impl Action { - pub fn message(self, entity_opt: Option) -> Message { +impl MenuAction for Action { + type Message = Message; + + fn message(&self, entity_opt: Option) -> Message { match self { Action::About => Message::ToggleContextPage(ContextPage::About), Action::Copy => Message::Copy(entity_opt), @@ -121,7 +125,7 @@ impl Action { Message::TabMessage(entity_opt, tab::Message::View(tab::View::List)) } Action::ToggleShowHidden => Message::TabMessage(None, tab::Message::ToggleShowHidden), - Action::ToggleSort(sort) => Message::TabMessage(None, tab::Message::ToggleSort(sort)), + Action::ToggleSort(sort) => Message::TabMessage(None, tab::Message::ToggleSort(*sort)), Action::WindowClose => Message::WindowClose, Action::WindowNew => Message::WindowNew, } diff --git a/src/key_bind.rs b/src/key_bind.rs index 9bc6db6..5653613 100644 --- a/src/key_bind.rs +++ b/src/key_bind.rs @@ -1,48 +1,9 @@ -use cosmic::{ - iced::keyboard::{Key, Modifiers}, - iced_core::keyboard::key::Named, -}; -use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, fmt}; +use cosmic::widget::menu::key_bind::KeyBind; +use cosmic::{iced::keyboard::Key, iced_core::keyboard::key::Named}; +use std::collections::HashMap; use crate::app::Action; - -#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] -pub enum Modifier { - Super, - Ctrl, - Alt, - Shift, -} - -#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] -pub struct KeyBind { - pub modifiers: Vec, - pub key: Key, -} - -impl KeyBind { - pub fn matches(&self, modifiers: Modifiers, key: &Key) -> bool { - key == &self.key - && modifiers.logo() == self.modifiers.contains(&Modifier::Super) - && modifiers.control() == self.modifiers.contains(&Modifier::Ctrl) - && modifiers.alt() == self.modifiers.contains(&Modifier::Alt) - && modifiers.shift() == self.modifiers.contains(&Modifier::Shift) - } -} - -impl fmt::Display for KeyBind { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for modifier in self.modifiers.iter() { - write!(f, "{:?} + ", modifier)?; - } - match &self.key { - Key::Character(c) => write!(f, "{}", c.to_uppercase()), - Key::Named(named) => write!(f, "{:?}", named), - other => write!(f, "{:?}", other), - } - } -} +use cosmic::widget::menu::key_bind::Modifier; //TODO: load from config pub fn key_binds() -> HashMap { diff --git a/src/menu.rs b/src/menu.rs index e0a4e79..51a511c 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only +use cosmic::widget::menu::key_bind::KeyBind; +use cosmic::widget::menu::menu_tree::{menu_items, menu_root, MenuItem}; use cosmic::{ //TODO: export iced::widget::horizontal_rule in cosmic::widget iced::{widget::horizontal_rule, Alignment, Background, Border, Length}, @@ -16,7 +18,6 @@ use crate::{ app::{Action, Message}, config::TabConfig, fl, - key_bind::KeyBind, tab::{self, HeadingOptions, Location, Tab}, }; @@ -171,75 +172,56 @@ pub fn context_menu<'a>( } pub fn menu_bar<'a>(key_binds: &HashMap) -> Element<'a, Message> { - //TODO: port to libcosmic - let menu_root = |label| { - widget::button(widget::text(label)) - .padding([4, 12]) - .style(theme::Button::MenuRoot) - }; - - let find_key = |action: &Action| -> String { - for (key_bind, key_action) in key_binds.iter() { - if action == key_action { - return key_bind.to_string(); - } - } - String::new() - }; - - let menu_item = |label, action| { - let key = find_key(&action); - MenuTree::new( - menu_button!( - widget::text(label), - widget::horizontal_space(Length::Fill), - widget::text(key) - ) - .on_press(action.message(None)), - ) - }; - MenuBar::new(vec![ MenuTree::with_children( menu_root(fl!("file")), - vec![ - menu_item(fl!("new-tab"), Action::TabNew), - menu_item(fl!("new-window"), Action::WindowNew), - menu_item(fl!("new-file"), Action::NewFile), - menu_item(fl!("new-folder"), Action::NewFolder), - menu_item(fl!("open"), Action::Open), - MenuTree::new(horizontal_rule(1)), - menu_item(fl!("rename"), Action::Rename), - //TOOD: add to sidebar, then divider - MenuTree::new(horizontal_rule(1)), - menu_item(fl!("move-to-trash"), Action::MoveToTrash), - MenuTree::new(horizontal_rule(1)), - menu_item(fl!("close-tab"), Action::TabClose), - menu_item(fl!("quit"), Action::WindowClose), - ], + menu_items( + key_binds, + vec![ + MenuItem::Button(fl!("new-tab"), Action::TabNew), + MenuItem::Button(fl!("new-window"), Action::WindowNew), + MenuItem::Button(fl!("new-file"), Action::NewFile), + MenuItem::Button(fl!("new-folder"), Action::NewFolder), + MenuItem::Button(fl!("open"), Action::Open), + MenuItem::Divider, + MenuItem::Button(fl!("rename"), Action::Rename), + //TOOD: add to sidebar, then divider + MenuItem::Divider, + MenuItem::Button(fl!("move-to-trash"), Action::MoveToTrash), + MenuItem::Divider, + MenuItem::Button(fl!("close-tab"), Action::TabClose), + MenuItem::Button(fl!("quit"), Action::WindowClose), + ], + ), ), MenuTree::with_children( menu_root(fl!("edit")), - vec![ - menu_item(fl!("cut"), Action::Cut), - menu_item(fl!("copy"), Action::Copy), - menu_item(fl!("paste"), Action::Paste), - menu_item(fl!("select-all"), Action::SelectAll), - MenuTree::new(horizontal_rule(1)), - //TODO: edit history - menu_item(fl!("operations"), Action::Operations), - ], + menu_items( + key_binds, + vec![ + MenuItem::Button(fl!("cut"), Action::Cut), + MenuItem::Button(fl!("copy"), Action::Copy), + MenuItem::Button(fl!("paste"), Action::Paste), + MenuItem::Button(fl!("select-all"), Action::SelectAll), + MenuItem::Divider, + //TODO: edit history + MenuItem::Button(fl!("operations"), Action::Operations), + ], + ), ), MenuTree::with_children( menu_root(fl!("view")), - vec![ - menu_item(fl!("grid-view"), Action::TabViewGrid), - menu_item(fl!("list-view"), Action::TabViewList), - MenuTree::new(horizontal_rule(1)), - menu_item(fl!("menu-settings"), Action::Settings), - MenuTree::new(horizontal_rule(1)), - menu_item(fl!("menu-about"), Action::About), - ], + menu_items( + key_binds, + vec![ + MenuItem::Button(fl!("grid-view"), Action::TabViewGrid), + MenuItem::Button(fl!("list-view"), Action::TabViewList), + MenuItem::Divider, + MenuItem::Button(fl!("menu-settings"), Action::Settings), + MenuItem::Divider, + MenuItem::Button(fl!("menu-about"), Action::About), + ], + ), ), ]) .item_height(ItemHeight::Dynamic(40)) diff --git a/src/tab.rs b/src/tab.rs index 06e1358..81f910f 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1,3 +1,4 @@ +use cosmic::widget::menu::key_bind::KeyBind; use cosmic::{ cosmic_theme, iced::{ @@ -37,9 +38,7 @@ use crate::{ app::{self, Action}, config::{IconSizes, TabConfig}, dialog::DialogKind, - fl, - key_bind::KeyBind, - menu, + fl, menu, mime_app::{mime_apps, MimeApp}, mime_icon::{mime_for_path, mime_icon}, mouse_area,