Add key shortcut support, use key bindings to determine menu text

This commit is contained in:
Jeremy Soller 2023-10-30 10:19:52 -06:00
parent b2998f4317
commit 91e3d3e05a
No known key found for this signature in database
GPG key ID: DCFCA852D3906975
3 changed files with 116 additions and 19 deletions

69
src/config.rs Normal file
View file

@ -0,0 +1,69 @@
use cosmic::iced::keyboard::{KeyCode, Modifiers};
use std::{collections::HashMap, fmt};
use crate::{fl, Message};
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct KeyBind {
pub modifiers: Modifiers,
pub key_code: KeyCode,
}
impl KeyBind {
//TODO: load from config
pub fn load() -> HashMap<KeyBind, Message> {
let mut keybinds = HashMap::new();
macro_rules! bind {
($modifiers:ident, $key_code:ident, $message:ident) => {{
keybinds.insert(
KeyBind {
modifiers: Modifiers::$modifiers,
key_code: KeyCode::$key_code,
},
Message::$message,
);
}};
}
bind!(CTRL, N, New);
bind!(CTRL, O, OpenFileDialog);
bind!(CTRL, S, Save);
keybinds
}
}
impl fmt::Display for KeyBind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.modifiers.logo() {
write!(f, "Super + ")?;
}
if self.modifiers.control() {
write!(f, "Ctrl + ")?;
}
if self.modifiers.alt() {
write!(f, "Alt + ")?;
}
if self.modifiers.shift() {
write!(f, "Shift + ")?;
}
write!(f, "{:?}", self.key_code)
}
}
#[derive(Clone, Debug)]
pub struct Config {
pub wrap: bool,
pub keybinds: HashMap<KeyBind, Message>,
}
impl Config {
//TODO: load from cosmic-config
pub fn load() -> Self {
Self {
wrap: false,
keybinds: KeyBind::load(),
}
}
}

View file

@ -4,6 +4,7 @@ use cosmic::{
app::{message, Command, Core, Settings},
executor,
iced::{
event, keyboard, subscription,
widget::{row, text},
Alignment, Length, Limits,
},
@ -18,6 +19,9 @@ use std::{
sync::Mutex,
};
use config::{Config, KeyBind};
mod config;
mod localize;
use self::menu::menu_bar;
@ -50,18 +54,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
#[derive(Clone, Debug)]
pub struct Config {
wrap: bool,
}
impl Config {
//TODO: load from cosmic-config
pub fn new() -> Self {
Self { wrap: false }
}
}
pub struct App {
core: Core,
nav_model: segmented_button::SingleSelectModel,
@ -70,8 +62,9 @@ pub struct App {
}
#[allow(dead_code)]
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Message {
KeyBind(KeyBind),
New,
OpenFileDialog,
OpenFile(PathBuf),
@ -289,7 +282,7 @@ impl cosmic::Application for App {
core,
nav_model: nav_bar::Model::builder().build(),
tab_model: segmented_button::Model::builder().build(),
config: Config::new(),
config: Config::load(),
};
for arg in env::args().skip(1) {
@ -383,6 +376,13 @@ impl cosmic::Application for App {
fn update(&mut self, message: Message) -> Command<Message> {
match message {
Message::KeyBind(key_bind) => {
for (config_key_bind, config_message) in self.config.keybinds.iter() {
if config_key_bind == &key_bind {
return self.update(config_message.clone());
}
}
}
Message::New => {
self.open_tab(None);
return self.update_title();
@ -541,4 +541,17 @@ impl cosmic::Application for App {
//content.explain(cosmic::iced::Color::WHITE)
content
}
fn subscription(&self) -> subscription::Subscription<Message> {
subscription::events_with(|event, status| match event {
event::Event::Keyboard(keyboard::Event::KeyPressed {
modifiers,
key_code,
}) => Some(Message::KeyBind(KeyBind {
modifiers,
key_code,
})),
_ => None,
})
}
}

View file

@ -39,8 +39,23 @@ pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
let menu_folder =
|label| menu_button!(widget::text(label), horizontal_space(Length::Fill), ">");
let menu_item =
|label, message| MenuTree::new(menu_button!(widget::text(label)).on_press(message));
let menu_item = |label, message| {
let mut key = String::new();
for (config_key_bind, config_message) in config.keybinds.iter() {
if config_message == &message {
key = config_key_bind.to_string();
break;
}
}
MenuTree::new(
menu_button!(
widget::text(label),
horizontal_space(Length::Fill),
widget::text(key)
)
.on_press(message),
)
};
let menu_key = |label, key, message| {
MenuTree::new(
@ -53,16 +68,16 @@ pub fn menu_bar<'a>(config: &Config) -> Element<'a, Message> {
MenuTree::with_children(
menu_root(fl!("file")),
vec![
menu_key(fl!("new-file"), "Ctrl + N", Message::New),
menu_item(fl!("new-file"), Message::New),
menu_key(fl!("new-window"), "Ctrl + Shift + N", Message::Todo),
MenuTree::new(horizontal_rule(1)),
menu_key(fl!("open-file"), "Ctrl + O", Message::OpenFileDialog),
menu_item(fl!("open-file"), Message::OpenFileDialog),
MenuTree::with_children(
menu_folder(fl!("open-recent")),
vec![menu_item(fl!("todo"), Message::Todo)],
),
MenuTree::new(horizontal_rule(1)),
menu_key(fl!("save"), "Ctrl + S", Message::Save),
menu_item(fl!("save"), Message::Save),
menu_key(fl!("save-as"), "Ctrl + Shift + S", Message::Todo),
MenuTree::new(horizontal_rule(1)),
menu_item(fl!("revert-all-changes"), Message::Todo),