From b851f3dd66a05ddc2d76da603e15b680a18c9bfb Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 11 Sep 2024 14:22:40 -0600 Subject: [PATCH] dialog: implement view and sort menu as designed --- src/dialog.rs | 16 +++++++++-- src/menu.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/dialog.rs b/src/dialog.rs index 8ae5df3b..0528c0f6 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -43,6 +43,7 @@ use crate::{ config::{Config, Favorite, TabConfig}, fl, home_dir, localize::LANGUAGE_SORTER, + menu, mounter::{mounters, MounterItem, MounterItems, MounterKey, Mounters}, tab::{self, ItemMetadata, Location, Tab}, }; @@ -293,6 +294,7 @@ struct Flags { /// Messages that are used specifically by our [`App`]. #[derive(Clone, Debug)] enum Message { + None, Cancel, Choice(usize, usize), Config(Config), @@ -682,9 +684,16 @@ impl Application for App { */ elements.push( - widget::segmented_control::horizontal(&self.view_model) - .on_activate(Message::ViewSelect) - .width(Length::Shrink) + menu::dialog_menu(&self.tab, &self.key_binds) + .map(|message| match message { + AppMessage::TabMessage(_entity_opt, tab_message) => { + Message::TabMessage(tab_message) + } + unsupported => { + log::warn!("{unsupported:?} not supported in dialog mode"); + Message::None + } + }) .into(), ); @@ -773,6 +782,7 @@ impl Application for App { /// Handle application events here. fn update(&mut self, message: Message) -> Command { match message { + Message::None => {} Message::Cancel => { if self.replace_dialog { self.replace_dialog = false; diff --git a/src/menu.rs b/src/menu.rs index 6389f97b..acf69035 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -4,7 +4,7 @@ use cosmic::{ iced::{Alignment, Background, Border, Length}, theme, widget::{ - button, column, container, divider, horizontal_space, + self, button, column, container, divider, horizontal_space, menu::{self, key_bind::KeyBind, ItemHeight, ItemWidth, MenuBar}, text, Row, }, @@ -240,6 +240,82 @@ pub fn context_menu<'a>( .into() } +pub fn dialog_menu<'a>( + tab: &Tab, + key_binds: &HashMap, +) -> Element<'static, Message> { + let sort_item = |label, sort, dir| { + menu::Item::CheckBox( + label, + tab.config.sort_name == sort && tab.config.sort_direction == dir, + Action::SetSort(sort, dir), + ) + }; + + MenuBar::new(vec![ + menu::Tree::with_children( + widget::button::icon(widget::icon::from_name(match tab.config.view { + tab::View::Grid => "view-grid-symbolic", + tab::View::List => "view-list-symbolic", + })), + menu::items( + key_binds, + vec![ + menu::Item::CheckBox( + fl!("grid-view"), + matches!(tab.config.view, tab::View::Grid), + Action::TabViewGrid, + ), + menu::Item::CheckBox( + fl!("list-view"), + matches!(tab.config.view, tab::View::List), + Action::TabViewList, + ), + ], + ), + ), + menu::Tree::with_children( + widget::button::icon(widget::icon::from_name(if tab.config.sort_direction { + "view-sort-ascending-symbolic" + } else { + "view-sort-descending-symbolic" + })), + menu::items( + key_binds, + vec![ + sort_item(fl!("sort-a-z"), tab::HeadingOptions::Name, true), + sort_item(fl!("sort-z-a"), tab::HeadingOptions::Name, false), + sort_item( + fl!("sort-newest-first"), + tab::HeadingOptions::Modified, + false, + ), + sort_item( + fl!("sort-oldest-first"), + tab::HeadingOptions::Modified, + true, + ), + sort_item( + fl!("sort-smallest-to-largest"), + tab::HeadingOptions::Size, + true, + ), + sort_item( + fl!("sort-largest-to-smallest"), + tab::HeadingOptions::Size, + false, + ), + //TODO: sort by type + ], + ), + ), + ]) + .item_height(ItemHeight::Dynamic(40)) + .item_width(ItemWidth::Uniform(240)) + .spacing(theme::active().cosmic().spacing.space_xxxs.into()) + .into() +} + pub fn menu_bar<'a>( tab_opt: Option<&Tab>, key_binds: &HashMap,