Add handlers for arrow keys

This commit is contained in:
Jeremy Soller 2024-02-28 16:16:59 -07:00
parent dc8433ce59
commit 6e14a0baea
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
3 changed files with 91 additions and 3 deletions

View file

@ -47,6 +47,10 @@ pub enum Action {
EditLocation,
HistoryNext,
HistoryPrevious,
ItemDown,
ItemLeft,
ItemRight,
ItemUp,
LocationUp,
MoveToTrash,
NewFile,
@ -79,6 +83,10 @@ impl Action {
Action::EditLocation => Message::EditLocation(entity_opt),
Action::HistoryNext => Message::TabMessage(entity_opt, tab::Message::GoNext),
Action::HistoryPrevious => Message::TabMessage(entity_opt, tab::Message::GoPrevious),
Action::ItemDown => Message::TabMessage(entity_opt, tab::Message::ItemDown),
Action::ItemLeft => Message::TabMessage(entity_opt, tab::Message::ItemLeft),
Action::ItemRight => Message::TabMessage(entity_opt, tab::Message::ItemRight),
Action::ItemUp => Message::TabMessage(entity_opt, tab::Message::ItemUp),
Action::LocationUp => Message::TabMessage(entity_opt, tab::Message::LocationUp),
Action::MoveToTrash => Message::MoveToTrash(entity_opt),
Action::NewFile => Message::NewItem(entity_opt, false),
@ -658,10 +666,26 @@ impl Application for App {
// Usually, the Escape key (for example) closes menus and panes one by one instead
// of closing everything on one press
// TODO: Close MenuBar too
match self.tab_model.data_mut::<Tab>(entity) {
Some(tab) if tab.context_menu.is_some() => tab.context_menu = None,
_ => self.core.window.show_context = false,
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
if tab.context_menu.is_some() {
tab.context_menu = None;
return Command::none();
}
if let Some(ref mut items) = tab.items_opt {
let mut had_selection = false;
for item in items.iter_mut() {
if item.selected {
item.selected = false;
had_selection = true;
}
}
if had_selection {
return Command::none();
}
}
}
self.core.window.show_context = false;
Command::none()
}

View file

@ -65,6 +65,16 @@ pub fn key_binds() -> HashMap<KeyBind, Action> {
bind!([Ctrl], Key::Character("l".into()), EditLocation);
bind!([Alt], Key::Named(Named::ArrowRight), HistoryNext);
bind!([Alt], Key::Named(Named::ArrowLeft), HistoryPrevious);
// Catch arrow keys
bind!([], Key::Named(Named::ArrowDown), ItemDown);
bind!([], Key::Named(Named::ArrowLeft), ItemLeft);
bind!([], Key::Named(Named::ArrowRight), ItemRight);
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::ArrowLeft), ItemLeft);
bind!([Shift], Key::Named(Named::ArrowRight), ItemRight);
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);

View file

@ -373,6 +373,10 @@ pub enum Message {
EditLocation(Option<Location>),
GoNext,
GoPrevious,
ItemDown,
ItemLeft,
ItemRight,
ItemUp,
Location(Location),
LocationUp,
Open,
@ -705,6 +709,56 @@ impl Tab {
}
}
}
Message::ItemDown | Message::ItemLeft => {
//TODO: handle grid correctly
//TODO: do not wrap
if let Some(ref mut items) = self.items_opt {
let mut last_selected_opt = None;
for (i, item) in items.iter_mut().enumerate() {
if item.selected {
if !modifiers.contains(Modifiers::SHIFT) {
item.selected = false;
}
last_selected_opt = Some(i);
}
}
for (i, item) in items.iter_mut().enumerate() {
if !self.config.show_hidden && item.hidden {
continue;
}
if last_selected_opt.map_or(true, |last_selected| i > last_selected) {
item.selected = true;
break;
}
}
}
}
Message::ItemUp | Message::ItemRight => {
//TODO: handle grid correctly
//TODO: do not wrap
if let Some(ref mut items) = self.items_opt {
let mut last_selected_opt = None;
for (i, item) in items.iter_mut().enumerate().rev() {
if item.selected {
if !modifiers.contains(Modifiers::SHIFT) {
item.selected = false;
}
last_selected_opt = Some(i);
}
}
for (i, item) in items.iter_mut().enumerate().rev() {
if !self.config.show_hidden && item.hidden {
continue;
}
if last_selected_opt.map_or(true, |last_selected| i < last_selected) {
item.selected = true;
break;
}
}
}
}
Message::Location(location) => {
cd = Some(location);
}