Add open message, improve context menus
This commit is contained in:
parent
09be33e391
commit
dc8433ce59
5 changed files with 89 additions and 29 deletions
10
src/app.rs
10
src/app.rs
|
|
@ -51,6 +51,7 @@ pub enum Action {
|
|||
MoveToTrash,
|
||||
NewFile,
|
||||
NewFolder,
|
||||
Open,
|
||||
Operations,
|
||||
Paste,
|
||||
Properties,
|
||||
|
|
@ -76,12 +77,13 @@ impl Action {
|
|||
Action::Copy => Message::Copy(entity_opt),
|
||||
Action::Cut => Message::Cut(entity_opt),
|
||||
Action::EditLocation => Message::EditLocation(entity_opt),
|
||||
Action::HistoryNext => Message::TabMessage(None, tab::Message::GoNext),
|
||||
Action::HistoryPrevious => Message::TabMessage(None, tab::Message::GoPrevious),
|
||||
Action::LocationUp => Message::TabMessage(None, tab::Message::LocationUp),
|
||||
Action::HistoryNext => Message::TabMessage(entity_opt, tab::Message::GoNext),
|
||||
Action::HistoryPrevious => Message::TabMessage(entity_opt, tab::Message::GoPrevious),
|
||||
Action::LocationUp => Message::TabMessage(entity_opt, tab::Message::LocationUp),
|
||||
Action::MoveToTrash => Message::MoveToTrash(entity_opt),
|
||||
Action::NewFile => Message::NewItem(entity_opt, false),
|
||||
Action::NewFolder => Message::NewItem(entity_opt, true),
|
||||
Action::Open => Message::TabMessage(entity_opt, tab::Message::Open),
|
||||
Action::Operations => Message::ToggleContextPage(ContextPage::Operations),
|
||||
Action::Paste => Message::Paste(entity_opt),
|
||||
Action::Properties => Message::ToggleContextPage(ContextPage::Properties),
|
||||
|
|
@ -1316,7 +1318,7 @@ impl Application for App {
|
|||
match self.tab_model.data::<Tab>(entity) {
|
||||
Some(tab) => {
|
||||
let tab_view = tab
|
||||
.view(self.core())
|
||||
.view(self.core(), &self.key_binds)
|
||||
.map(move |message| Message::TabMessage(Some(entity), message));
|
||||
tab_column = tab_column.push(tab_view);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,13 @@ use cosmic::{
|
|||
Application, ApplicationExt, Element,
|
||||
};
|
||||
use notify::Watcher;
|
||||
use std::{any::TypeId, collections::HashSet, env, fs, path::PathBuf, time};
|
||||
use std::{
|
||||
any::TypeId,
|
||||
collections::{HashMap, HashSet},
|
||||
env, fs,
|
||||
path::PathBuf,
|
||||
time,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
config::TabConfig,
|
||||
|
|
@ -610,8 +616,9 @@ impl Application for App {
|
|||
|
||||
let mut tab_column = widget::column::with_capacity(2);
|
||||
tab_column = tab_column.push(
|
||||
//TODO: key binds for dialog
|
||||
self.tab
|
||||
.view(self.core())
|
||||
.view(self.core(), &HashMap::new())
|
||||
.map(move |message| Message::TabMessage(message)),
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ pub fn key_binds() -> HashMap<KeyBind, Action> {
|
|||
bind!([Alt], Key::Named(Named::ArrowUp), LocationUp);
|
||||
bind!([], Key::Named(Named::Delete), MoveToTrash);
|
||||
bind!([Ctrl, Shift], Key::Character("N".into()), NewFolder);
|
||||
bind!([], Key::Named(Named::Enter), Open);
|
||||
bind!([Ctrl], Key::Character("v".into()), Paste);
|
||||
bind!([], Key::Named(Named::F2), Rename);
|
||||
bind!([Ctrl], Key::Character("a".into()), SelectAll);
|
||||
|
|
|
|||
66
src/menu.rs
66
src/menu.rs
|
|
@ -34,10 +34,27 @@ macro_rules! menu_button {
|
|||
);
|
||||
}
|
||||
|
||||
pub fn context_menu<'a>(tab: &Tab) -> Element<'a, tab::Message> {
|
||||
//TODO: show key bindings in context menu?
|
||||
let menu_action = |label, action| {
|
||||
menu_button!(widget::text(label)).on_press(tab::Message::ContextAction(action))
|
||||
pub fn context_menu<'a>(
|
||||
tab: &Tab,
|
||||
key_binds: &HashMap<KeyBind, Action>,
|
||||
) -> Element<'a, tab::Message> {
|
||||
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);
|
||||
menu_button!(
|
||||
widget::text(label),
|
||||
widget::horizontal_space(Length::Fill),
|
||||
widget::text(key)
|
||||
)
|
||||
.on_press(tab::Message::ContextAction(action))
|
||||
};
|
||||
|
||||
let selected = tab
|
||||
|
|
@ -48,32 +65,41 @@ pub fn context_menu<'a>(tab: &Tab) -> Element<'a, tab::Message> {
|
|||
let mut children: Vec<Element<_>> = Vec::new();
|
||||
match tab.location {
|
||||
Location::Path(_) => {
|
||||
children.push(menu_action(fl!("new-file"), Action::NewFile).into());
|
||||
children.push(menu_action(fl!("new-folder"), Action::NewFolder).into());
|
||||
children.push(horizontal_rule(1).into());
|
||||
if selected > 0 {
|
||||
children.push(menu_action(fl!("rename"), Action::Rename).into());
|
||||
children.push(menu_action(fl!("cut"), Action::Cut).into());
|
||||
children.push(menu_action(fl!("copy"), Action::Copy).into());
|
||||
children.push(menu_action(fl!("paste"), Action::Paste).into());
|
||||
}
|
||||
children.push(menu_action(fl!("select-all"), Action::SelectAll).into());
|
||||
if selected > 0 {
|
||||
children.push(menu_item(fl!("open"), Action::Open).into());
|
||||
//TODO: Open with
|
||||
children.push(horizontal_rule(1).into());
|
||||
children.push(menu_action(fl!("move-to-trash"), Action::MoveToTrash).into());
|
||||
children.push(menu_item(fl!("rename"), Action::Rename).into());
|
||||
children.push(menu_item(fl!("cut"), Action::Cut).into());
|
||||
children.push(menu_item(fl!("copy"), Action::Copy).into());
|
||||
//TODO: Print?
|
||||
children.push(horizontal_rule(1).into());
|
||||
//TODO: change to Show details
|
||||
children.push(menu_item(fl!("properties"), Action::Properties).into());
|
||||
//TODO: Add to sidebar
|
||||
children.push(horizontal_rule(1).into());
|
||||
children.push(menu_item(fl!("move-to-trash"), Action::MoveToTrash).into());
|
||||
} else {
|
||||
//TODO: need better designs for menu with no selection
|
||||
//TODO: have things like properties but they apply to the folder?
|
||||
children.push(menu_item(fl!("new-file"), Action::NewFile).into());
|
||||
children.push(menu_item(fl!("new-folder"), Action::NewFolder).into());
|
||||
children.push(horizontal_rule(1).into());
|
||||
children.push(menu_item(fl!("select-all"), Action::SelectAll).into());
|
||||
children.push(menu_item(fl!("paste"), Action::Paste).into());
|
||||
}
|
||||
}
|
||||
Location::Trash => {
|
||||
children.push(menu_action(fl!("select-all"), Action::SelectAll).into());
|
||||
children.push(menu_item(fl!("select-all"), Action::SelectAll).into());
|
||||
if selected > 0 {
|
||||
children.push(horizontal_rule(1).into());
|
||||
children.push(menu_item(fl!("properties"), Action::Properties).into());
|
||||
children.push(horizontal_rule(1).into());
|
||||
children
|
||||
.push(menu_action(fl!("restore-from-trash"), Action::RestoreFromTrash).into());
|
||||
.push(menu_item(fl!("restore-from-trash"), Action::RestoreFromTrash).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
children.push(horizontal_rule(1).into());
|
||||
children.push(menu_action(fl!("properties"), Action::Properties).into());
|
||||
|
||||
widget::container(widget::column::with_children(children))
|
||||
.padding(1)
|
||||
|
|
@ -134,7 +160,7 @@ pub fn menu_bar<'a>(key_binds: &HashMap<KeyBind, Action>) -> Element<'a, Message
|
|||
menu_item(fl!("new-window"), Action::WindowNew),
|
||||
menu_item(fl!("new-file"), Action::NewFile),
|
||||
menu_item(fl!("new-folder"), Action::NewFolder),
|
||||
//TODO: open
|
||||
menu_item(fl!("open"), Action::Open),
|
||||
MenuTree::new(horizontal_rule(1)),
|
||||
menu_item(fl!("rename"), Action::Rename),
|
||||
//TOOD: add to sidebar, then divider
|
||||
|
|
|
|||
30
src/tab.rs
30
src/tab.rs
|
|
@ -32,7 +32,9 @@ use crate::{
|
|||
app::Action,
|
||||
config::{IconSizes, TabConfig},
|
||||
dialog::DialogKind,
|
||||
fl, menu,
|
||||
fl,
|
||||
key_bind::KeyBind,
|
||||
menu,
|
||||
mime_icon::mime_icon,
|
||||
mouse_area,
|
||||
};
|
||||
|
|
@ -373,6 +375,7 @@ pub enum Message {
|
|||
GoPrevious,
|
||||
Location(Location),
|
||||
LocationUp,
|
||||
Open,
|
||||
RightClick(usize),
|
||||
Scroll(Viewport),
|
||||
Thumbnail(PathBuf, Result<image::RgbaImage, ()>),
|
||||
|
|
@ -714,6 +717,27 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
}
|
||||
Message::Open => {
|
||||
if let Some(ref mut items) = self.items_opt {
|
||||
for item in items.iter() {
|
||||
if item.selected {
|
||||
match self.location {
|
||||
Location::Path(_) => {
|
||||
if item.path.is_dir() {
|
||||
//TODO: allow opening multiple tabs?
|
||||
cd = Some(Location::Path(item.path.clone()));
|
||||
} else {
|
||||
commands.push(Command::OpenFile(item.path.clone()));
|
||||
}
|
||||
}
|
||||
Location::Trash => {
|
||||
//TODO: open properties?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::RightClick(click_i) => {
|
||||
if let Some(ref mut items) = self.items_opt {
|
||||
if !items.get(click_i).map_or(false, |x| x.selected) {
|
||||
|
|
@ -1214,7 +1238,7 @@ impl Tab {
|
|||
.into()
|
||||
}
|
||||
|
||||
pub fn view(&self, core: &Core) -> Element<Message> {
|
||||
pub fn view(&self, core: &Core, key_binds: &HashMap<KeyBind, Action>) -> Element<Message> {
|
||||
let location_view = self.location_view(core);
|
||||
let item_view = match self.view {
|
||||
View::Grid => self.grid_view(core),
|
||||
|
|
@ -1237,7 +1261,7 @@ impl Tab {
|
|||
let mut popover = widget::popover(mouse_area);
|
||||
if let Some(point) = self.context_menu {
|
||||
popover = popover
|
||||
.popup(menu::context_menu(&self))
|
||||
.popup(menu::context_menu(&self, &key_binds))
|
||||
.position(widget::popover::Position::Point(point));
|
||||
}
|
||||
widget::container(widget::column::with_children(vec![
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue