Adjust key bindings based on mode, part of #547
This commit is contained in:
parent
a1e79c97e6
commit
8615157ec8
4 changed files with 58 additions and 48 deletions
25
src/app.rs
25
src/app.rs
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
src/tab.rs
13
src/tab.rs
|
|
@ -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},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue