Add view menu for dialog, part of #541
This commit is contained in:
parent
705c780721
commit
a5dfffcd72
2 changed files with 134 additions and 14 deletions
|
|
@ -33,6 +33,7 @@ use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
collections::{HashMap, HashSet, VecDeque},
|
collections::{HashMap, HashSet, VecDeque},
|
||||||
env, fmt, fs,
|
env, fmt, fs,
|
||||||
|
num::NonZeroU16,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
time::{self, Instant},
|
time::{self, Instant},
|
||||||
|
|
@ -325,14 +326,25 @@ enum Message {
|
||||||
SearchInput(String),
|
SearchInput(String),
|
||||||
TabMessage(tab::Message),
|
TabMessage(tab::Message),
|
||||||
TabRescan(Vec<tab::Item>),
|
TabRescan(Vec<tab::Item>),
|
||||||
|
TabView(tab::View),
|
||||||
|
ToggleFoldersFirst,
|
||||||
|
ZoomDefault,
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
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::None => Message::None,
|
||||||
AppMessage::Preview(_entity_opt) => Message::Preview,
|
AppMessage::Preview(_entity_opt) => Message::Preview,
|
||||||
AppMessage::SearchActivate => Message::SearchActivate,
|
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::TabView(_entity_opt, view) => Message::TabView(view),
|
||||||
|
AppMessage::ToggleFoldersFirst => Message::ToggleFoldersFirst,
|
||||||
|
AppMessage::ZoomDefault(_entity_opt) => Message::ZoomDefault,
|
||||||
|
AppMessage::ZoomIn(_entity_opt) => Message::ZoomIn,
|
||||||
|
AppMessage::ZoomOut(_entity_opt) => Message::ZoomOut,
|
||||||
unsupported => {
|
unsupported => {
|
||||||
log::warn!("{unsupported:?} not supported in dialog mode");
|
log::warn!("{unsupported:?} not supported in dialog mode");
|
||||||
Message::None
|
Message::None
|
||||||
|
|
@ -933,8 +945,12 @@ impl Application for App {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let show_details = match self.context_page {
|
||||||
|
ContextPage::Preview(..) => self.core.window.show_context,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
elements.push(
|
elements.push(
|
||||||
menu::dialog_menu(&self.tab, &self.key_binds)
|
menu::dialog_menu(&self.tab, &self.key_binds, show_details)
|
||||||
.map(Message::from)
|
.map(Message::from)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -1462,6 +1478,54 @@ impl Application for App {
|
||||||
return widget::text_input::focus(self.filename_id.clone());
|
return widget::text_input::focus(self.filename_id.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::TabView(view) => {
|
||||||
|
self.tab.config.view = view;
|
||||||
|
}
|
||||||
|
Message::ToggleFoldersFirst => {
|
||||||
|
self.tab.config.folders_first = !self.tab.config.folders_first;
|
||||||
|
}
|
||||||
|
Message::ZoomDefault => match self.tab.config.view {
|
||||||
|
tab::View::List => self.tab.config.icon_sizes.list = 100.try_into().unwrap(),
|
||||||
|
tab::View::Grid => self.tab.config.icon_sizes.grid = 100.try_into().unwrap(),
|
||||||
|
},
|
||||||
|
Message::ZoomIn => {
|
||||||
|
let zoom_in = |size: &mut NonZeroU16, min: u16, max: u16| {
|
||||||
|
let mut step = min;
|
||||||
|
while step <= max {
|
||||||
|
if size.get() < step {
|
||||||
|
*size = step.try_into().unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
step += 25;
|
||||||
|
}
|
||||||
|
if size.get() > step {
|
||||||
|
*size = step.try_into().unwrap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match self.tab.config.view {
|
||||||
|
tab::View::List => zoom_in(&mut self.tab.config.icon_sizes.list, 50, 500),
|
||||||
|
tab::View::Grid => zoom_in(&mut self.tab.config.icon_sizes.grid, 50, 500),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::ZoomOut => {
|
||||||
|
let zoom_out = |size: &mut NonZeroU16, min: u16, max: u16| {
|
||||||
|
let mut step = max;
|
||||||
|
while step >= min {
|
||||||
|
if size.get() > step {
|
||||||
|
*size = step.try_into().unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
step -= 25;
|
||||||
|
}
|
||||||
|
if size.get() < step {
|
||||||
|
*size = step.try_into().unwrap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match self.tab.config.view {
|
||||||
|
tab::View::List => zoom_out(&mut self.tab.config.icon_sizes.list, 50, 500),
|
||||||
|
tab::View::Grid => zoom_out(&mut self.tab.config.icon_sizes.grid, 50, 500),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Command::none()
|
Command::none()
|
||||||
|
|
|
||||||
82
src/menu.rs
82
src/menu.rs
|
|
@ -35,6 +35,18 @@ macro_rules! menu_button {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn menu_button_optional(
|
||||||
|
label: String,
|
||||||
|
action: Action,
|
||||||
|
enabled: bool,
|
||||||
|
) -> menu::Item<Action, String> {
|
||||||
|
if enabled {
|
||||||
|
menu::Item::Button(label, action)
|
||||||
|
} else {
|
||||||
|
menu::Item::ButtonDisabled(label, action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn context_menu<'a>(
|
pub fn context_menu<'a>(
|
||||||
tab: &Tab,
|
tab: &Tab,
|
||||||
key_binds: &HashMap<KeyBind, Action>,
|
key_binds: &HashMap<KeyBind, Action>,
|
||||||
|
|
@ -291,6 +303,7 @@ pub fn context_menu<'a>(
|
||||||
pub fn dialog_menu<'a>(
|
pub fn dialog_menu<'a>(
|
||||||
tab: &Tab,
|
tab: &Tab,
|
||||||
key_binds: &HashMap<KeyBind, Action>,
|
key_binds: &HashMap<KeyBind, Action>,
|
||||||
|
show_details: bool,
|
||||||
) -> Element<'static, Message> {
|
) -> Element<'static, Message> {
|
||||||
let (sort_name, sort_direction, _) = tab.sort_options();
|
let (sort_name, sort_direction, _) = tab.sort_options();
|
||||||
let sort_item = |label, sort, dir| {
|
let sort_item = |label, sort, dir| {
|
||||||
|
|
@ -302,12 +315,25 @@ pub fn dialog_menu<'a>(
|
||||||
};
|
};
|
||||||
let in_trash = tab.location == Location::Trash;
|
let in_trash = tab.location == Location::Trash;
|
||||||
|
|
||||||
|
let mut selected_gallery = 0;
|
||||||
|
tab.items_opt().map(|items| {
|
||||||
|
for item in items.iter() {
|
||||||
|
if item.selected {
|
||||||
|
if item.can_gallery() {
|
||||||
|
selected_gallery += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
MenuBar::new(vec![
|
MenuBar::new(vec![
|
||||||
menu::Tree::with_children(
|
menu::Tree::with_children(
|
||||||
widget::button::icon(widget::icon::from_name(match tab.config.view {
|
widget::button::icon(widget::icon::from_name(match tab.config.view {
|
||||||
tab::View::Grid => "view-grid-symbolic",
|
tab::View::Grid => "view-grid-symbolic",
|
||||||
tab::View::List => "view-list-symbolic",
|
tab::View::List => "view-list-symbolic",
|
||||||
}))
|
}))
|
||||||
|
// This prevents the button from being shown as insensitive
|
||||||
|
.on_press(Message::None)
|
||||||
.padding(8),
|
.padding(8),
|
||||||
menu::items(
|
menu::items(
|
||||||
key_binds,
|
key_binds,
|
||||||
|
|
@ -331,6 +357,8 @@ pub fn dialog_menu<'a>(
|
||||||
} else {
|
} else {
|
||||||
"view-sort-descending-symbolic"
|
"view-sort-descending-symbolic"
|
||||||
}))
|
}))
|
||||||
|
// This prevents the button from being shown as insensitive
|
||||||
|
.on_press(Message::None)
|
||||||
.padding(8),
|
.padding(8),
|
||||||
menu::items(
|
menu::items(
|
||||||
key_binds,
|
key_binds,
|
||||||
|
|
@ -369,6 +397,38 @@ pub fn dialog_menu<'a>(
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
menu::Tree::with_children(
|
||||||
|
widget::button::icon(widget::icon::from_name("view-more-symbolic"))
|
||||||
|
// This prevents the button from being shown as insensitive
|
||||||
|
.on_press(Message::None)
|
||||||
|
.padding(8),
|
||||||
|
menu::items(
|
||||||
|
key_binds,
|
||||||
|
vec![
|
||||||
|
menu::Item::Button(fl!("zoom-in"), Action::ZoomIn),
|
||||||
|
menu::Item::Button(fl!("default-size"), Action::ZoomDefault),
|
||||||
|
menu::Item::Button(fl!("zoom-out"), Action::ZoomOut),
|
||||||
|
menu::Item::Divider,
|
||||||
|
menu::Item::CheckBox(
|
||||||
|
fl!("show-hidden-files"),
|
||||||
|
tab.config.show_hidden,
|
||||||
|
Action::ToggleShowHidden,
|
||||||
|
),
|
||||||
|
menu::Item::CheckBox(
|
||||||
|
fl!("list-directories-first"),
|
||||||
|
tab.config.folders_first,
|
||||||
|
Action::ToggleFoldersFirst,
|
||||||
|
),
|
||||||
|
menu::Item::CheckBox(fl!("show-details"), show_details, Action::Preview),
|
||||||
|
menu::Item::Divider,
|
||||||
|
menu_button_optional(
|
||||||
|
fl!("gallery-preview"),
|
||||||
|
Action::Gallery,
|
||||||
|
selected_gallery > 0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
])
|
])
|
||||||
.item_height(ItemHeight::Dynamic(40))
|
.item_height(ItemHeight::Dynamic(40))
|
||||||
.item_width(ItemWidth::Uniform(240))
|
.item_width(ItemWidth::Uniform(240))
|
||||||
|
|
@ -395,6 +455,7 @@ pub fn menu_bar<'a>(
|
||||||
|
|
||||||
let mut selected_dir = 0;
|
let mut selected_dir = 0;
|
||||||
let mut selected = 0;
|
let mut selected = 0;
|
||||||
|
let mut selected_gallery = 0;
|
||||||
tab_opt.and_then(|tab| tab.items_opt()).map(|items| {
|
tab_opt.and_then(|tab| tab.items_opt()).map(|items| {
|
||||||
for item in items.iter() {
|
for item in items.iter() {
|
||||||
if item.selected {
|
if item.selected {
|
||||||
|
|
@ -402,22 +463,13 @@ pub fn menu_bar<'a>(
|
||||||
if item.metadata.is_dir() {
|
if item.metadata.is_dir() {
|
||||||
selected_dir += 1;
|
selected_dir += 1;
|
||||||
}
|
}
|
||||||
|
if item.can_gallery() {
|
||||||
|
selected_gallery += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
fn menu_button_optional(
|
|
||||||
label: String,
|
|
||||||
action: Action,
|
|
||||||
enabled: bool,
|
|
||||||
) -> menu::Item<Action, String> {
|
|
||||||
if enabled {
|
|
||||||
menu::Item::Button(label, action)
|
|
||||||
} else {
|
|
||||||
menu::Item::ButtonDisabled(label, action)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuBar::new(vec![
|
MenuBar::new(vec![
|
||||||
menu::Tree::with_children(
|
menu::Tree::with_children(
|
||||||
menu::root(fl!("file")),
|
menu::root(fl!("file")),
|
||||||
|
|
@ -492,7 +544,11 @@ pub fn menu_bar<'a>(
|
||||||
),
|
),
|
||||||
menu::Item::CheckBox(fl!("show-details"), config.show_details, Action::Preview),
|
menu::Item::CheckBox(fl!("show-details"), config.show_details, Action::Preview),
|
||||||
menu::Item::Divider,
|
menu::Item::Divider,
|
||||||
menu_button_optional(fl!("gallery-preview"), Action::Gallery, selected > 0),
|
menu_button_optional(
|
||||||
|
fl!("gallery-preview"),
|
||||||
|
Action::Gallery,
|
||||||
|
selected_gallery > 0,
|
||||||
|
),
|
||||||
menu::Item::Divider,
|
menu::Item::Divider,
|
||||||
menu::Item::Button(fl!("menu-settings"), Action::Settings),
|
menu::Item::Button(fl!("menu-settings"), Action::Settings),
|
||||||
menu::Item::Divider,
|
menu::Item::Divider,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue