From 82fd83c485e342fd25c77f1a88e2dfe7f44a8d07 Mon Sep 17 00:00:00 2001 From: Jeff Hughes Date: Mon, 17 May 2021 07:19:45 -0400 Subject: [PATCH] Fix highlighting on active/inactive menus --- src/ui/menu.rs | 129 ++++++++++++++++++++++++++++++------------------ src/ui/mod.rs | 16 +++--- src/ui/panel.rs | 2 +- src/ui/popup.rs | 5 +- 4 files changed, 92 insertions(+), 60 deletions(-) diff --git a/src/ui/menu.rs b/src/ui/menu.rs index 48decfe..0e7a9e5 100644 --- a/src/ui/menu.rs +++ b/src/ui/menu.rs @@ -42,6 +42,7 @@ where T: Clone + Menuable pub start_row: u16, // beginning of first row of menu pub top_row: u16, // top row of text shown in window pub selected: u16, // which line of text is highlighted + pub active: bool, } impl Menu { @@ -54,6 +55,7 @@ impl Menu { start_row: 0, top_row: 0, selected: 0, + active: false, }; } @@ -62,6 +64,7 @@ impl Menu { pub fn redraw(&mut self) { self.panel.redraw(); self.update_items(); + self.highlight_selected(); } /// Prints the list of visible items to the terminal. @@ -87,11 +90,11 @@ impl Menu { if i == self.selected || !elem.is_played() { let mut style = style::ContentStyle::new(); - if i == self.selected { - style = style - .foreground(style::Color::White) - .background(style::Color::DarkYellow); - } + // if i == self.selected { + // style = style + // .foreground(style::Color::White) + // .background(style::Color::DarkYellow); + // } if !elem.is_played() { style = style.attribute(style::Attribute::Bold); } @@ -245,47 +248,43 @@ impl Menu { // apply_color_played(self, self.selected, ColorType::HighlightedActive); } - /// Sets font style and color of menu item. `index` is the position - /// of the menu item to be changed. `played` is an indicator of - /// whether that item has been played or not. `color` is a ColorType - /// representing the appropriate state of the item (e.g., Normal, - /// Highlighted). - pub fn set_attrs(&mut self, index: u16, played: bool, color: ColorType) { - // let attr = if played { - // pancurses::A_NORMAL - // } else { - // pancurses::A_BOLD - // }; - // self.panel - // .change_attr(index, -1, self.panel.get_cols() + 3, attr, color); - } - /// Highlights the currently selected item in the menu, based on /// whether the menu is currently active or not. - pub fn highlight_selected(&mut self, active_menu: bool) { - // let is_played = self - // .items - // .map_single_by_index(self.get_menu_idx(self.selected), |el| el.is_played()); - - // if let Some(played) = is_played { - // if active_menu { - // self.set_attrs(self.selected, played, ColorType::HighlightedActive); - // } else { - // self.set_attrs(self.selected, played, ColorType::Highlighted); - // } - // } + pub fn highlight_selected(&mut self) { + let el_details = self + .items + .map_single_by_index(self.get_menu_idx(self.selected), |el| { + (el.get_title(self.panel.get_cols() as usize), el.is_played()) + }); + + if let Some((title, is_played)) = el_details { + let mut style = style::ContentStyle::new(); + if self.active { + style = style + .foreground(style::Color::White) + .background(style::Color::DarkYellow); + } + style = if is_played { + style.attribute(style::Attribute::NormalIntensity) + } else { + style.attribute(style::Attribute::Bold) + }; + self.panel.write_line(self.selected, title, Some(style)); + } } /// Controls how the window changes when it is active (i.e., available /// for user input to modify state). pub fn activate(&mut self) { // if list is empty, will return None - if let Some(played) = self - .items - .map_single_by_index(self.get_menu_idx(self.selected), |el| el.is_played()) - { - self.set_attrs(self.selected, played, ColorType::HighlightedActive); - } + // if let Some(played) = self + // .items + // .map_single_by_index(self.get_menu_idx(self.selected), |el| el.is_played()) + // { + // self.set_attrs(self.selected, played, ColorType::HighlightedActive); + // } + self.active = true; + self.highlight_selected(); } /// Updates window size @@ -332,11 +331,28 @@ impl Menu { /// available for user input to modify state). pub fn deactivate(&mut self) { // if list is empty, will return None - if let Some(played) = self + // if let Some(played) = self + // .items + // .map_single_by_index(self.get_menu_idx(self.selected), |el| el.is_played()) + // { + // self.set_attrs(self.selected, played, ColorType::Highlighted); + // } + self.active = false; + let el_details = self .items - .map_single_by_index(self.get_menu_idx(self.selected), |el| el.is_played()) - { - self.set_attrs(self.selected, played, ColorType::Highlighted); + .map_single_by_index(self.get_menu_idx(self.selected), |el| { + (el.get_title(self.panel.get_cols() as usize), el.is_played()) + }); + if let Some((title, is_played)) = el_details { + let mut style = style::ContentStyle::new() + .foreground(style::Color::Black) + .background(style::Color::Grey); + style = if is_played { + style.attribute(style::Attribute::NormalIntensity) + } else { + style.attribute(style::Attribute::Bold) + }; + self.panel.write_line(self.selected, title, Some(style)); } } } @@ -346,11 +362,28 @@ impl Menu { /// available for user input to modify state). pub fn deactivate(&mut self) { // if list is empty, will return None - if let Some(played) = self + // if let Some(played) = self + // .items + // .map_single_by_index(self.get_menu_idx(self.selected), |el| el.is_played()) + // { + // self.set_attrs(self.selected, played, ColorType::Normal); + // } + self.active = false; + let el_details = self .items - .map_single_by_index(self.get_menu_idx(self.selected), |el| el.is_played()) - { - self.set_attrs(self.selected, played, ColorType::Normal); + .map_single_by_index(self.get_menu_idx(self.selected), |el| { + (el.get_title(self.panel.get_cols() as usize), el.is_played()) + }); + if let Some((title, is_played)) = el_details { + let mut style = style::ContentStyle::new() + .foreground(style::Color::Reset) + .background(style::Color::Reset); + style = if is_played { + style.attribute(style::Attribute::NormalIntensity) + } else { + style.attribute(style::Attribute::Bold) + }; + self.panel.write_line(self.selected, title, Some(style)); } } } @@ -363,7 +396,7 @@ impl Menu { let changed = self.change_item_selections(vec![self.get_menu_idx(self.selected)], None); if changed { self.update_items(); - self.highlight_selected(true); + self.highlight_selected(); } } @@ -377,7 +410,7 @@ impl Menu { self.change_item_selections((0..self.items.len()).collect(), Some(!all_selected)); if changed { self.update_items(); - self.highlight_selected(true); + self.highlight_selected(); } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index f0680aa..529eff3 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -210,9 +210,9 @@ impl<'a> Ui<'a> { /// This should be called immediately after creating the UI, in order /// to draw everything to the screen. pub fn init(&mut self) { - self.podcast_menu.activate(); self.podcast_menu.redraw(); self.episode_menu.redraw(); + self.podcast_menu.activate(); self.update_details_panel(); self.notif_win.redraw(); @@ -783,13 +783,13 @@ impl<'a> Ui<'a> { }; self.episode_menu.redraw(); - match self.active_menu { - ActiveMenu::PodcastMenu => self.podcast_menu.highlight_selected(true), - ActiveMenu::EpisodeMenu => { - self.podcast_menu.highlight_selected(false); - self.episode_menu.highlight_selected(true); - } - } + // match self.active_menu { + // ActiveMenu::PodcastMenu => self.podcast_menu.highlight_selected(true), + // ActiveMenu::EpisodeMenu => { + // self.podcast_menu.highlight_selected(false); + // self.episode_menu.highlight_selected(true); + // } + // } } /// When the program is ending, this performs tear-down functions so diff --git a/src/ui/panel.rs b/src/ui/panel.rs index 2b4366c..9fc59a6 100644 --- a/src/ui/panel.rs +++ b/src/ui/panel.rs @@ -3,7 +3,7 @@ use std::{convert::TryInto, io}; use chrono::{DateTime, Utc}; use crossterm::{cursor, queue, style}; -use super::ColorType; +// use super::ColorType; pub const VERTICAL: &str = "│"; diff --git a/src/ui/popup.rs b/src/ui/popup.rs index be280ba..54f5678 100644 --- a/src/ui/popup.rs +++ b/src/ui/popup.rs @@ -93,7 +93,7 @@ impl<'a> PopupWin<'a> { } ActivePopup::DownloadWin(_win) => { let mut download_win = self.make_download_win(); - download_win.highlight_selected(true); + download_win.activate(); self.popup = ActivePopup::DownloadWin(download_win); } ActivePopup::None => (), @@ -346,8 +346,7 @@ impl<'a> PopupWin<'a> { self.popup = ActivePopup::HelpWin(win); } else if self.download_win && !self.popup.is_download_win() { let mut win = self.make_download_win(); - win.update_items(); - win.highlight_selected(true); + win.activate(); self.popup = ActivePopup::DownloadWin(win); } else if self.welcome_win && !self.popup.is_welcome_win() { let win = self.make_welcome_win();