diff options
author | Canop <cano.petrole@gmail.com> | 2022-10-01 19:53:46 +0200 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2022-10-01 19:53:46 +0200 |
commit | c372aef844ae59e5cb65f0815c2868f19d58aa64 (patch) | |
tree | 29e01cbe1530bf73684899a1b2c200c85dedb430 /src/app | |
parent | 79ed47d94cc011b2bc3dc597226768c4aed0f0c7 (diff) |
Status message on toggling tree options
Diffstat (limited to 'src/app')
-rw-r--r-- | src/app/app.rs | 32 | ||||
-rw-r--r-- | src/app/cmd_result.rs | 16 | ||||
-rw-r--r-- | src/app/panel.rs | 3 | ||||
-rw-r--r-- | src/app/panel_state.rs | 218 |
4 files changed, 225 insertions, 44 deletions
diff --git a/src/app/app.rs b/src/app/app.rs index f9034f9..1533aba 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -266,7 +266,9 @@ impl App { screen: self.screen, // it can't change in this function con, }; - match self.mut_panel().apply_command(w, &cmd, app_state, &app_cmd_context)? { + let cmd_result = self.mut_panel().apply_command(w, &cmd, app_state, &app_cmd_context)?; + debug!("cmd_result: {:?}", &cmd_result); + match cmd_result { ApplyOnPanel { id } => { if let Some(idx) = self.panel_id_to_idx(id) { if let DisplayError(txt) = self.panels[idx].apply_command( @@ -461,10 +463,14 @@ impl App { error = Some(s); } } - NewState(state) => { + NewState { state, message } => { self.mut_panel().clear_input(); self.mut_panel().push_state(state); - self.mut_panel().refresh_input_status(app_state, &app_cmd_context); + if let Some(md) = message { + self.mut_panel().set_message(md); + } else { + self.mut_panel().refresh_input_status(app_state, &app_cmd_context); + } } PopState => { if is_input_invocation { @@ -621,15 +627,17 @@ impl App { self.update_preview(con, false); // the selection may have changed if let Some(error) = &error { self.mut_panel().set_error(error.to_string()); - } else { - let app_cmd_context = AppCmdContext { - panel_skin: &skin.focused, - preview_panel: self.preview_panel, - stage_panel: self.stage_panel, - screen: self.screen, - con, - }; - self.mut_panel().refresh_input_status(app_state, &app_cmd_context); + //} else { + // // the refresh here removes the toggle status message. Not + // // sure there's a case it's useful + // let app_cmd_context = AppCmdContext { + // panel_skin: &skin.focused, + // preview_panel: self.preview_panel, + // stage_panel: self.stage_panel, + // screen: self.screen, + // con, + // }; + // self.mut_panel().refresh_input_status(app_state, &app_cmd_context); } self.display_panels(w, skin, app_state, con)?; if error.is_some() { diff --git a/src/app/cmd_result.rs b/src/app/cmd_result.rs index 465feff..ff7b462 100644 --- a/src/app/cmd_result.rs +++ b/src/app/cmd_result.rs @@ -48,7 +48,10 @@ pub enum CmdResult { purpose: PanelPurpose, direction: HDir, }, - NewState(Box<dyn PanelState>), + NewState { + state: Box<dyn PanelState>, + message: Option<&'static str>, // explaining why there's a new state + }, PopStateAndReapply, // the state asks the command be executed on a previous state PopState, Quit, @@ -63,24 +66,31 @@ impl CmdResult { } pub fn from_optional_state( os: Result<BrowserState, TreeBuildError>, + message: Option<&'static str>, in_new_panel: bool, ) -> CmdResult { match os { Ok(os) => { if in_new_panel { - CmdResult::NewPanel { + CmdResult::NewPanel { // TODO keep the message ? state: Box::new(os), purpose: PanelPurpose::None, direction: HDir::Right, } } else { - CmdResult::NewState(Box::new(os)) + CmdResult::NewState { + state: Box::new(os), + message, + } } } Err(TreeBuildError::Interrupted) => CmdResult::Keep, Err(e) => CmdResult::error(e.to_string()), } } + pub fn new_state(state: Box<dyn PanelState>) -> Self { + Self::NewState { state, message: None } + } pub fn error<S: Into<String>>(message: S) -> Self { Self::DisplayError(message.into()) } diff --git a/src/app/panel.rs b/src/app/panel.rs index 9a2757d..9577adf 100644 --- a/src/app/panel.rs +++ b/src/app/panel.rs @@ -57,6 +57,9 @@ impl Panel { pub fn set_error(&mut self, text: String) { self.status = Status::from_error(text); } + pub fn set_message<S: Into<String>>(&mut self, md: S) { + self.status = Status::from_message(md.into()); + } /// apply a command on the current state, with no /// effect on screen diff --git a/src/app/panel_state.rs b/src/app/panel_state.rs index f84f697..0d79d63 100644 --- a/src/app/panel_state.rs +++ b/src/app/panel_state.rs @@ -153,7 +153,7 @@ pub trait PanelState { direction: HDir::Right, } } else { - CmdResult::NewState(Box::new(state)) + CmdResult::new_state(Box::new(state)) } } Err(e) => CmdResult::DisplayError(format!("{}", e)), @@ -170,7 +170,7 @@ pub trait PanelState { direction: HDir::Right, } } else { - CmdResult::NewState(Box::new( + CmdResult::new_state(Box::new( HelpState::new(self.tree_options(), screen, con) )) } @@ -195,9 +195,11 @@ pub trait PanelState { if o.sort == Sort::Count { o.sort = Sort::None; o.show_counts = false; + "*not sorting anymore*" } else { o.sort = Sort::Count; o.show_counts = true; + "*now sorting by file count*" } }, bang, @@ -209,9 +211,11 @@ pub trait PanelState { if o.sort == Sort::Date { o.sort = Sort::None; o.show_dates = false; + "*not sorting anymore*" } else { o.sort = Sort::Date; o.show_dates = true; + "*now sorting by last modified date*" } }, bang, @@ -223,10 +227,12 @@ pub trait PanelState { if o.sort == Sort::Size { o.sort = Sort::None; o.show_sizes = false; + "*not sorting anymore*" } else { o.sort = Sort::Size; o.show_sizes = true; o.show_root_fs = true; + "*now sorting files and directories by total size*" } }, bang, @@ -235,11 +241,20 @@ pub trait PanelState { Internal::sort_by_type => self.with_new_options( screen, &|o| { - o.sort = match o.sort { - Sort::TypeDirsFirst => Sort::TypeDirsLast, - Sort::TypeDirsLast => Sort::None, - _ => Sort::TypeDirsFirst, - }; + match o.sort { + Sort::TypeDirsFirst => { + o.sort = Sort::TypeDirsLast; + "*sorting by type, directories last*" + } + Sort::TypeDirsLast => { + o.sort = Sort::None; + "*not sorting anymore*" + } + _ => { + o.sort = Sort::TypeDirsFirst; + "*sorting by type, directories first*" + } + } }, bang, con, @@ -247,10 +262,13 @@ pub trait PanelState { Internal::sort_by_type_dirs_first => self.with_new_options( screen, &|o| { - o.sort = match o.sort { - Sort::TypeDirsFirst => Sort::None, - _ => Sort::TypeDirsFirst, - }; + if o.sort == Sort::TypeDirsFirst { + o.sort = Sort::None; + "*not sorting anymore*" + } else { + o.sort = Sort::TypeDirsFirst; + "*now sorting by type, directories first*" + } }, bang, con, @@ -258,53 +276,178 @@ pub trait PanelState { Internal::sort_by_type_dirs_last => self.with_new_options( screen, &|o| { - o.sort = match o.sort { - Sort::TypeDirsLast => Sort::None, - _ => Sort::TypeDirsLast, - }; + if o.sort == Sort::TypeDirsLast { + o.sort = Sort::None; + "*not sorting anymore*" + } else { + o.sort = Sort::TypeDirsLast; + "*now sorting by type, directories last*" + } + }, + bang, + con, + ), + Internal::no_sort => self.with_new_options( + screen, + &|o| { + if o.sort == Sort::None { + "*still not searching*" + } else { + o.sort = Sort::None; + "*not sorting anymore*" + } }, bang, con, ), - Internal::no_sort => self.with_new_options(screen, &|o| o.sort = Sort::None, bang, con), Internal::toggle_counts => { - self.with_new_options(screen, &|o| o.show_counts ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.show_counts ^= true; + if o.show_counts { + "*displaying file counts*" + } else { + "*hiding file counts*" + } + }, + bang, + con, + ) } Internal::toggle_dates => { - self.with_new_options(screen, &|o| o.show_dates ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.show_dates ^= true; + if o.show_dates { + "*displaying last modified dates*" + } else { + "*hiding last modified dates*" + } + }, + bang, + con, + ) } Internal::toggle_device_id => { - self.with_new_options(screen, &|o| o.show_device_id ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.show_device_id ^= true; + if o.show_device_id { + "*displaying device id*" + } else { + "*hiding device id*" + } + }, + bang, + con, + ) } Internal::toggle_files => { - self.with_new_options(screen, &|o: &mut TreeOptions| o.only_folders ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.only_folders ^= true; + if o.only_folders { + "*displaying only directories*" + } else { + "*displaying both files and directories*" + } + }, + bang, + con, + ) } Internal::toggle_hidden => { - self.with_new_options(screen, &|o| o.show_hidden ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.show_hidden ^= true; + if o.show_hidden { + "h:**y** - *Hidden files displayed*" + } else { + "h:**n** - *Hidden files not displayed*" + } + }, + bang, + con, + ) } Internal::toggle_root_fs => { - self.with_new_options(screen, &|o| o.show_root_fs ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.show_root_fs ^= true; + if o.show_root_fs { + "*displaying filesystem info for the tree's root directory*" + } else { + "*removing filesystem info*" + } + }, + bang, + con, + ) } Internal::toggle_git_ignore => { - self.with_new_options(screen, &|o| o.respect_git_ignore ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.respect_git_ignore ^= true; + if o.respect_git_ignore { + "gi:**y** - *applying gitignore rules*" + } else { + "gi:**n** - *not applying gitignore rules*" + } + }, + bang, + con, + ) } Internal::toggle_git_file_info => { - self.with_new_options(screen, &|o| o.show_git_file_info ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.show_git_file_info ^= true; + if o.show_git_file_info { + "*displaying git info next to files*" + } else { + "*removing git file info*" + } + }, + bang, + con, + ) } Internal::toggle_git_status => { self.with_new_options( screen, &|o| { if o.filter_by_git_status { o.filter_by_git_status = false; + "*not filtering according to git status anymore*" } else { o.filter_by_git_status = true; o.show_hidden = true; + "*only displaying new or modified files*" } }, bang, con ) } Internal::toggle_perm => { - self.with_new_options(screen, &|o| o.show_permissions ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.show_permissions ^= true; + if o.show_permissions { + "*displaying file permissions*" + } else { + "*removing file permissions*" + } + }, + bang, + con, + ) } Internal::toggle_sizes => self.with_new_options( screen, @@ -312,16 +455,30 @@ pub trait PanelState { if o.show_sizes { o.show_sizes = false; o.show_root_fs = false; + "*removing sizes of files and directories*" } else { o.show_sizes = true; o.show_root_fs = true; + "*now diplaying sizes of files and directories*" } }, bang, con, ), Internal::toggle_trim_root => { - self.with_new_options(screen, &|o| o.trim_root ^= true, bang, con) + self.with_new_options( + screen, + &|o| { + o.trim_root ^= true; + if o.trim_root { + "*now trimming root from excess files*" + } else { + "*not trimming root files anymore*" + } + }, + bang, + con, + ) } Internal::close_preview => { if let Some(id) = cc.app.preview_panel { @@ -709,12 +866,15 @@ pub trait PanelState { fn tree_options(&self) -> TreeOptions; - /// build a cmdResult in response to a command being a change of - /// tree options. This may or not be a new state + /// Build a cmdResult in response to a command being a change of + /// tree options. This may or not be a new state. + /// + /// The provided `change_options` function returns a status message + /// explaining the change fn with_new_options( &mut self, screen: Screen, - change_options: &dyn Fn(&mut TreeOptions), + change_options: &dyn Fn(&mut TreeOptions) -> &'static str, in_new_panel: bool, con: &AppContext, ) -> CmdResult; |