Adjust key bindings based on mode, part of #547

This commit is contained in:
Jeremy Soller 2024-10-03 13:01:59 -06:00
parent a1e79c97e6
commit 8615157ec8
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
4 changed files with 58 additions and 48 deletions

View file

@ -147,7 +147,7 @@ impl Action {
Action::Copy => Message::Copy(entity_opt), Action::Copy => Message::Copy(entity_opt),
Action::Cut => Message::Cut(entity_opt), Action::Cut => Message::Cut(entity_opt),
Action::EditHistory => Message::ToggleContextPage(ContextPage::EditHistory), Action::EditHistory => Message::ToggleContextPage(ContextPage::EditHistory),
Action::EditLocation => Message::EditLocation(entity_opt), Action::EditLocation => Message::TabMessage(entity_opt, tab::Message::EditLocationToggle),
Action::ExtractHere => Message::ExtractHere(entity_opt), Action::ExtractHere => Message::ExtractHere(entity_opt),
Action::Gallery => Message::TabMessage(entity_opt, tab::Message::GalleryToggle), Action::Gallery => Message::TabMessage(entity_opt, tab::Message::GalleryToggle),
Action::HistoryNext => Message::TabMessage(entity_opt, tab::Message::GoNext), Action::HistoryNext => Message::TabMessage(entity_opt, tab::Message::GoNext),
@ -257,7 +257,6 @@ pub enum Message {
DialogPush(DialogPage), DialogPush(DialogPage),
DialogUpdate(DialogPage), DialogUpdate(DialogPage),
DialogUpdateComplete(DialogPage), DialogUpdateComplete(DialogPage),
EditLocation(Option<Entity>),
ExtractHere(Option<Entity>), ExtractHere(Option<Entity>),
Key(Modifiers, Key), Key(Modifiers, Key),
LaunchUrl(String), LaunchUrl(String),
@ -1080,6 +1079,11 @@ impl Application for App {
let app_themes = vec![fl!("match-desktop"), fl!("dark"), fl!("light")]; let app_themes = vec![fl!("match-desktop"), fl!("dark"), fl!("light")];
let key_binds = key_binds(&match flags.mode {
Mode::App => tab::Mode::App,
Mode::Desktop => tab::Mode::Desktop,
});
let mut app = App { let mut app = App {
core, core,
nav_bar_context_id: segmented_button::Entity::null(), nav_bar_context_id: segmented_button::Entity::null(),
@ -1092,7 +1096,7 @@ impl Application for App {
context_page: ContextPage::Preview(None, PreviewKind::Selected), context_page: ContextPage::Preview(None, PreviewKind::Selected),
dialog_pages: VecDeque::new(), dialog_pages: VecDeque::new(),
dialog_text_input: widget::Id::unique(), dialog_text_input: widget::Id::unique(),
key_binds: key_binds(), key_binds,
modifiers: Modifiers::empty(), modifiers: Modifiers::empty(),
mounters: mounters(), mounters: mounters(),
mounter_items: HashMap::new(), mounter_items: HashMap::new(),
@ -1484,21 +1488,6 @@ impl Application for App {
self.update(Message::DialogComplete), self.update(Message::DialogComplete),
]); ]);
} }
Message::EditLocation(entity_opt) => {
let entity = entity_opt.unwrap_or_else(|| self.tab_model.active());
if let Some(location) = self.tab_model.data::<Tab>(entity).and_then(|tab| {
if tab.edit_location.is_none() {
Some(tab.location.clone())
} else {
None
}
}) {
return self.update(Message::TabMessage(
Some(entity),
tab::Message::EditLocation(Some(location)),
));
}
}
Message::ExtractHere(entity_opt) => { Message::ExtractHere(entity_opt) => {
let paths = self.selected_paths(entity_opt); let paths = self.selected_paths(entity_opt);
if let Some(current_path) = paths.get(0) { if let Some(current_path) = paths.get(0) {

View file

@ -330,6 +330,7 @@ enum Message {
impl From<AppMessage> for Message { impl From<AppMessage> for Message {
fn from(app_message: AppMessage) -> Message { fn from(app_message: AppMessage) -> Message {
match app_message { match app_message {
AppMessage::SearchActivate => Message::SearchActivate,
AppMessage::TabMessage(_entity_opt, tab_message) => Message::TabMessage(tab_message), AppMessage::TabMessage(_entity_opt, tab_message) => Message::TabMessage(tab_message),
AppMessage::ToggleShowDetails => Message::ToggleShowDetails, AppMessage::ToggleShowDetails => Message::ToggleShowDetails,
unsupported => { unsupported => {
@ -708,6 +709,8 @@ impl Application for App {
tab.sort_name = tab::HeadingOptions::Modified; tab.sort_name = tab::HeadingOptions::Modified;
tab.sort_direction = false; tab.sort_direction = false;
let key_binds = key_binds(&tab.mode);
let mut app = App { let mut app = App {
core, core,
flags, flags,
@ -729,7 +732,7 @@ impl Application for App {
search_id: widget::Id::unique(), search_id: widget::Id::unique(),
search_input: String::new(), search_input: String::new(),
tab, tab,
key_binds: key_binds(), key_binds,
watcher_opt: None, watcher_opt: None,
}; };

View file

@ -5,10 +5,10 @@ use cosmic::{
}; };
use std::collections::HashMap; use std::collections::HashMap;
use crate::app::Action; use crate::{app::Action, tab};
//TODO: load from config //TODO: load from config
pub fn key_binds() -> HashMap<KeyBind, Action> { pub fn key_binds(mode: &tab::Mode) -> HashMap<KeyBind, Action> {
let mut key_binds = HashMap::new(); let mut key_binds = HashMap::new();
macro_rules! bind { macro_rules! bind {
@ -23,47 +23,58 @@ pub fn key_binds() -> HashMap<KeyBind, Action> {
}}; }};
} }
bind!([Ctrl], Key::Character("d".into()), AddToSidebar); // Common keys
bind!([Ctrl], Key::Character("c".into()), Copy);
bind!([Ctrl], Key::Character("x".into()), Cut);
bind!([Ctrl], Key::Character("l".into()), EditLocation);
bind!([], Key::Named(Named::Space), Gallery); bind!([], Key::Named(Named::Space), Gallery);
bind!([Alt], Key::Named(Named::ArrowRight), HistoryNext);
bind!([Alt], Key::Named(Named::ArrowLeft), HistoryPrevious);
bind!([], Key::Named(Named::Backspace), HistoryPrevious);
// Catch arrow keys
bind!([], Key::Named(Named::ArrowDown), ItemDown); bind!([], Key::Named(Named::ArrowDown), ItemDown);
bind!([], Key::Named(Named::ArrowLeft), ItemLeft); bind!([], Key::Named(Named::ArrowLeft), ItemLeft);
bind!([], Key::Named(Named::ArrowRight), ItemRight); bind!([], Key::Named(Named::ArrowRight), ItemRight);
bind!([], Key::Named(Named::ArrowUp), ItemUp); bind!([], Key::Named(Named::ArrowUp), ItemUp);
// We also need to catch these when shift is held
bind!([Shift], Key::Named(Named::ArrowDown), ItemDown); bind!([Shift], Key::Named(Named::ArrowDown), ItemDown);
bind!([Shift], Key::Named(Named::ArrowLeft), ItemLeft); bind!([Shift], Key::Named(Named::ArrowLeft), ItemLeft);
bind!([Shift], Key::Named(Named::ArrowRight), ItemRight); bind!([Shift], Key::Named(Named::ArrowRight), ItemRight);
bind!([Shift], Key::Named(Named::ArrowUp), ItemUp); bind!([Shift], Key::Named(Named::ArrowUp), ItemUp);
bind!([Alt], Key::Named(Named::ArrowUp), LocationUp);
bind!([], Key::Named(Named::Delete), MoveToTrash);
bind!([Ctrl, Shift], Key::Character("n".into()), NewFolder); bind!([Ctrl, Shift], Key::Character("n".into()), NewFolder);
bind!([], Key::Named(Named::Enter), Open); bind!([], Key::Named(Named::Enter), Open);
bind!([Ctrl], Key::Named(Named::Enter), OpenInNewTab);
bind!([Shift], Key::Named(Named::Enter), OpenInNewWindow);
bind!([Ctrl], Key::Character("v".into()), Paste);
bind!([Ctrl], Key::Named(Named::Space), Preview); bind!([Ctrl], Key::Named(Named::Space), Preview);
bind!([], Key::Named(Named::F2), Rename);
bind!([Ctrl], Key::Character("f".into()), SearchActivate);
bind!([Ctrl], Key::Character("a".into()), SelectAll);
bind!([Ctrl], Key::Character(",".into()), Settings);
bind!([Ctrl], Key::Character("w".into()), TabClose);
bind!([Ctrl], Key::Character("t".into()), TabNew);
bind!([Ctrl], Key::Named(Named::Tab), TabNext);
bind!([Ctrl, Shift], Key::Named(Named::Tab), TabPrev);
bind!([Ctrl], Key::Character("h".into()), ToggleShowHidden); bind!([Ctrl], Key::Character("h".into()), ToggleShowHidden);
bind!([Ctrl], Key::Character("q".into()), WindowClose); bind!([Ctrl], Key::Character("a".into()), SelectAll);
bind!([Ctrl], Key::Character("n".into()), WindowNew);
bind!([Ctrl], Key::Character("=".into()), ZoomIn); bind!([Ctrl], Key::Character("=".into()), ZoomIn);
bind!([Ctrl], Key::Character("+".into()), ZoomIn); bind!([Ctrl], Key::Character("+".into()), ZoomIn);
bind!([Ctrl], Key::Character("0".into()), ZoomDefault); bind!([Ctrl], Key::Character("0".into()), ZoomDefault);
bind!([Ctrl], Key::Character("-".into()), ZoomOut); bind!([Ctrl], Key::Character("-".into()), ZoomOut);
// App-only keys
if matches!(mode, tab::Mode::App) {
bind!([Ctrl], Key::Character("d".into()), AddToSidebar);
bind!([Ctrl], Key::Named(Named::Enter), OpenInNewTab);
bind!([Ctrl], Key::Character(",".into()), Settings);
bind!([Ctrl], Key::Character("w".into()), TabClose);
bind!([Ctrl], Key::Character("t".into()), TabNew);
bind!([Ctrl], Key::Named(Named::Tab), TabNext);
bind!([Ctrl, Shift], Key::Named(Named::Tab), TabPrev);
bind!([Ctrl], Key::Character("q".into()), WindowClose);
bind!([Ctrl], Key::Character("n".into()), WindowNew);
}
// App and desktop only keys
if matches!(mode, tab::Mode::App | tab::Mode::Desktop) {
bind!([Ctrl], Key::Character("c".into()), Copy);
bind!([Ctrl], Key::Character("x".into()), Cut);
bind!([], Key::Named(Named::Delete), MoveToTrash);
bind!([Shift], Key::Named(Named::Enter), OpenInNewWindow);
bind!([Ctrl], Key::Character("v".into()), Paste);
bind!([], Key::Named(Named::F2), Rename);
}
// App and dialog only keys
if matches!(mode, tab::Mode::App | tab::Mode::Dialog(_)) {
bind!([Ctrl], Key::Character("l".into()), EditLocation);
bind!([Alt], Key::Named(Named::ArrowRight), HistoryNext);
bind!([Alt], Key::Named(Named::ArrowLeft), HistoryPrevious);
bind!([], Key::Named(Named::Backspace), HistoryPrevious);
bind!([Alt], Key::Named(Named::ArrowUp), LocationUp);
bind!([Ctrl], Key::Character("f".into()), SearchActivate);
}
key_binds key_binds
} }

View file

@ -841,6 +841,7 @@ pub enum Message {
LocationMenuAction(LocationMenuAction), LocationMenuAction(LocationMenuAction),
Drag(Option<Rectangle>), Drag(Option<Rectangle>),
EditLocation(Option<Location>), EditLocation(Option<Location>),
EditLocationToggle,
OpenInNewTab(PathBuf), OpenInNewTab(PathBuf),
EmptyTrash, EmptyTrash,
Gallery(bool), Gallery(bool),
@ -2017,6 +2018,13 @@ impl Tab {
} }
self.edit_location = edit_location; self.edit_location = edit_location;
} }
Message::EditLocationToggle => {
if self.edit_location.is_none() {
self.edit_location = Some(self.location.clone());
} else {
self.edit_location = None;
}
}
Message::OpenInNewTab(path) => { Message::OpenInNewTab(path) => {
commands.push(Command::OpenInNewTab(path)); commands.push(Command::OpenInNewTab(path));
} }
@ -4041,9 +4049,8 @@ mod tests {
use super::{respond_to_scroll_direction, scan_path, Location, Message, Tab}; use super::{respond_to_scroll_direction, scan_path, Location, Message, Tab};
use crate::{ use crate::{
app::test_utils::{ app::test_utils::{
assert_eq_tab_path, empty_fs, eq_path_item, filter_dirs, assert_eq_tab_path, empty_fs, eq_path_item, filter_dirs, read_dir_sorted, simple_fs,
read_dir_sorted, simple_fs, tab_click_new, NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, tab_click_new, NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED,
NUM_NESTED,
}, },
config::{IconSizes, TabConfig}, config::{IconSizes, TabConfig},
}; };