From 405061265b8bcff4b2f849385923d5329c072d28 Mon Sep 17 00:00:00 2001 From: Uncle Stretch Date: Tue, 26 Nov 2024 14:53:46 +0300 Subject: [PATCH] colors setting via config file Signed-off-by: Uncle Stretch --- config/config.json5 | 20 ++++ src/app.rs | 1 + src/components/explorer/block_ticker.rs | 17 ++- src/components/explorer/current_epoch.rs | 23 +++- src/components/explorer/current_era.rs | 17 ++- src/components/explorer/explorer_blocks.rs | 48 +++++--- src/components/explorer/extrinsics_chart.rs | 25 +++- src/components/explorer/finalized_block.rs | 23 +++- src/components/explorer/latest_block.rs | 23 +++- src/components/explorer/mod.rs | 11 +- src/components/menu.rs | 14 ++- src/config.rs | 4 + src/palette.rs | 125 ++++++++++---------- 13 files changed, 253 insertions(+), 98 deletions(-) diff --git a/config/config.json5 b/config/config.json5 index ef7ba9b..7a7a29f 100644 --- a/config/config.json5 +++ b/config/config.json5 @@ -1,4 +1,24 @@ { + "styles": { + "Menu": { + "normal_style": "", + "hover_style": "bold yellow italic on blue", + "normal_border_style": "blue", + "hover_border_style": "blue", + "normal_title_style": "blue", + "hover_title_style": "", + "tagged_style": "yellow italic", + }, + "Explorer": { + "normal_style": "", + "hover_style": "bold yellow italic on blue", + "normal_border_style": "blue", + "hover_border_style": "blue", + "normal_title_style": "blue", + "hover_title_style": "", + "tagged_style": "yellow bold", + } + }, "keybindings": { "Explorer": { "": "Quit", diff --git a/src/app.rs b/src/app.rs index a167f8e..7245baf 100644 --- a/src/app.rs +++ b/src/app.rs @@ -17,6 +17,7 @@ use crate::{ #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Mode { + Menu, Explorer, ExplorerActive, Empty, diff --git a/src/components/explorer/block_ticker.rs b/src/components/explorer/block_ticker.rs index 107911b..c38f588 100644 --- a/src/components/explorer/block_ticker.rs +++ b/src/components/explorer/block_ticker.rs @@ -9,6 +9,7 @@ use ratatui::{ use super::Component; use crate::{ + config::Config, widgets::{BigText, PixelSize}, action::Action, palette::StylePalette, @@ -46,6 +47,18 @@ impl BlockTicker { } impl Component for BlockTicker { + fn register_config_handler(&mut self, config: Config) -> Result<()> { + if let Some(style) = config.styles.get(&crate::app::Mode::Explorer) { + self.palette.with_normal_style(style.get("normal_style").copied()); + self.palette.with_hover_style(style.get("hover_style").copied()); + self.palette.with_normal_border_style(style.get("normal_border_style").copied()); + self.palette.with_hover_border_style(style.get("hover_border_style").copied()); + self.palette.with_normal_title_style(style.get("normal_title_style").copied()); + self.palette.with_hover_title_style(style.get("hover_title_style").copied()); + } + Ok(()) + } + fn update(&mut self, action: Action) -> Result> { match action { Action::BestBlockUpdated(block) => self.block_found(block)?, @@ -79,7 +92,7 @@ impl Component for BlockTicker { .border_style(border_style) .border_type(border_type) .title_alignment(Alignment::Right) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .padding(Padding::new(0, 0, height.saturating_sub(2) / 2, 0)) .title("Passed")) .alignment(Alignment::Center) @@ -99,7 +112,7 @@ impl Component for BlockTicker { .border_style(border_style) .border_type(border_type) .title_alignment(Alignment::Right) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .title("Passed")) .alignment(Alignment::Center) .wrap(Wrap { trim: true }); diff --git a/src/components/explorer/current_epoch.rs b/src/components/explorer/current_epoch.rs index a037111..27b5866 100644 --- a/src/components/explorer/current_epoch.rs +++ b/src/components/explorer/current_epoch.rs @@ -7,7 +7,12 @@ use ratatui::{ }; use super::Component; -use crate::{action::Action, palette::StylePalette, widgets::{PixelSize, BigText}}; +use crate::{ + config::Config, + action::Action, + palette::StylePalette, + widgets::{PixelSize, BigText}, +}; #[derive(Debug, Default)] pub struct CurrentEpoch { @@ -30,6 +35,18 @@ impl CurrentEpoch { } impl Component for CurrentEpoch { + fn register_config_handler(&mut self, config: Config) -> Result<()> { + if let Some(style) = config.styles.get(&crate::app::Mode::Explorer) { + self.palette.with_normal_style(style.get("normal_style").copied()); + self.palette.with_hover_style(style.get("hover_style").copied()); + self.palette.with_normal_border_style(style.get("normal_border_style").copied()); + self.palette.with_hover_border_style(style.get("hover_border_style").copied()); + self.palette.with_normal_title_style(style.get("normal_title_style").copied()); + self.palette.with_hover_title_style(style.get("hover_title_style").copied()); + } + Ok(()) + } + fn update(&mut self, action: Action) -> Result> { match action { Action::SetEpochProgress(number, progress) => @@ -70,7 +87,7 @@ impl Component for CurrentEpoch { .border_style(border_style) .border_type(border_type) .title_alignment(Alignment::Right) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .padding(Padding::new(0, 0, height.saturating_sub(3) / 2, 0)) .title("Epoch")) .alignment(Alignment::Center) @@ -89,7 +106,7 @@ impl Component for CurrentEpoch { .block(Block::bordered() .border_style(border_style) .border_type(border_type) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .title_top(Line::from("Epoch").right_aligned()) .title_top(Line::from(format!("{}{} {}{}", if big_time { hours } else { minutes }, diff --git a/src/components/explorer/current_era.rs b/src/components/explorer/current_era.rs index 8203d87..d217f78 100644 --- a/src/components/explorer/current_era.rs +++ b/src/components/explorer/current_era.rs @@ -8,6 +8,7 @@ use ratatui::{ use super::Component; use crate::{ + config::Config, action::Action, palette::StylePalette, types::EraInfo, @@ -35,6 +36,18 @@ impl CurrentEra { } impl Component for CurrentEra { + fn register_config_handler(&mut self, config: Config) -> Result<()> { + if let Some(style) = config.styles.get(&crate::app::Mode::Explorer) { + self.palette.with_normal_style(style.get("normal_style").copied()); + self.palette.with_hover_style(style.get("hover_style").copied()); + self.palette.with_normal_border_style(style.get("normal_border_style").copied()); + self.palette.with_hover_border_style(style.get("hover_border_style").copied()); + self.palette.with_normal_title_style(style.get("normal_title_style").copied()); + self.palette.with_hover_title_style(style.get("hover_title_style").copied()); + } + Ok(()) + } + fn update(&mut self, action: Action) -> Result> { match action { Action::SetActiveEra(era_info) => self.update_era(era_info)?, @@ -88,7 +101,7 @@ impl Component for CurrentEra { .border_style(border_style) .border_type(border_type) .title_alignment(Alignment::Right) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .padding(Padding::new(0, 0, (height.saturating_sub(3)) / 2, 0)) .title("Era")) .alignment(Alignment::Center) @@ -107,7 +120,7 @@ impl Component for CurrentEra { .block(Block::bordered() .border_style(border_style) .border_type(border_type) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .title_top(Line::from("Era").right_aligned()) .title_top(Line::from(format!("{}{} {}{}", if big_time { hours } else { minutes }, diff --git a/src/components/explorer/explorer_blocks.rs b/src/components/explorer/explorer_blocks.rs index 25996a4..7b896c4 100644 --- a/src/components/explorer/explorer_blocks.rs +++ b/src/components/explorer/explorer_blocks.rs @@ -5,7 +5,6 @@ use primitive_types::H256; use ratatui::{ layout::{Alignment, Rect}, prelude::*, - style::Style, text::Line, widgets::{Block, BorderType, Paragraph}, Frame @@ -16,7 +15,7 @@ use codec::Decode; use super::Component; use crate::{ types::CasperExtrinsicDetails, CasperAccountId, - action::Action, app::Mode, palette::StylePalette, + config::Config, action::Action, app::Mode, palette::StylePalette, }; struct BlockInfo { @@ -164,10 +163,6 @@ impl ExplorerBlocks { let total_length = rect.as_size().height as usize - 2; let mut items = Vec::new(); - let active_style = self.palette.create_text_style(true); - let latest_style = self.palette.create_text_style(false); - let finalized_style = Style::new().fg(self.palette.foreground_hover()); - let start_index = match self.used_block_number { Some(used_block) if total_length < self.blocks.len() => { self.blocks @@ -180,14 +175,16 @@ impl ExplorerBlocks { _ => 0, }; + let normal_style = self.palette.create_text_style(false); + let active_style = self.palette.create_text_style(true); + let finalized_style = self.palette.create_tagged_style(); + for (idx, current_block_info) in self.blocks.iter().skip(start_index).enumerate() { if idx == total_length { break; } let style = match self.used_block_number { Some(used_block) if current_block_info.block_number == used_block => active_style, - _ => { - if current_block_info.finalized { finalized_style } else { latest_style } - } + _ => if current_block_info.finalized { finalized_style } else { normal_style } }; items.push(self.prepare_block_line_info(¤t_block_info, width).style(style)); @@ -233,24 +230,22 @@ impl ExplorerBlocks { let mut total_length = rect.as_size().height - 2; let mut items = Vec::new(); - let normal_style = self.palette.create_text_style(false); - let active_style = self.palette.create_text_style(true); - if let Some(used_block_number) = self.used_block_number { let default_hash = H256::repeat_byte(69u8); let hash = self.block_headers .get(&used_block_number) .unwrap_or(&default_hash); + let normal_style = self.palette.create_text_style(false); + let active_style = self.palette.create_text_style(true); + if let Some(exts) = self.extrinsics.get(&hash) { for (index, ext) in exts.iter().enumerate() { if total_length == 0 { break; } let style = if let Some((_, used_ext_index)) = self.used_ext_index { if index == used_ext_index { active_style } else { normal_style } - } else { - normal_style - }; + } else { normal_style }; items.push(self.prepare_ext_line_info( index, @@ -405,7 +400,9 @@ impl ExplorerBlocks { border_style: Color, border_type: BorderType, ) -> Paragraph { - let title_style = self.palette.create_title_style(); + let title_style = self + .palette + .create_title_style(self.is_active && self.used_paragraph_index == 0); Paragraph::new(self.prepare_block_lines(place)) .block(Block::bordered() .border_style(border_style) @@ -422,7 +419,9 @@ impl ExplorerBlocks { border_style: Color, border_type: BorderType, ) -> Paragraph { - let title_style = self.palette.create_title_style(); + let title_style = self + .palette + .create_title_style(self.is_active && self.used_paragraph_index == 1); Paragraph::new(self.prepare_ext_lines(place)) .block(Block::bordered() .border_style(border_style) @@ -439,7 +438,7 @@ impl ExplorerBlocks { border_style: Color, border_type: BorderType, ) -> Paragraph { - let title_style = self.palette.create_title_style(); + let title_style = self.palette.create_title_style(false); Paragraph::new(self.prepare_event_lines(place)) .block(Block::bordered() .border_style(border_style) @@ -452,6 +451,19 @@ impl ExplorerBlocks { } impl Component for ExplorerBlocks { + fn register_config_handler(&mut self, config: Config) -> Result<()> { + if let Some(style) = config.styles.get(&crate::app::Mode::Explorer) { + self.palette.with_normal_style(style.get("normal_style").copied()); + self.palette.with_hover_style(style.get("hover_style").copied()); + self.palette.with_normal_border_style(style.get("normal_border_style").copied()); + self.palette.with_hover_border_style(style.get("hover_border_style").copied()); + self.palette.with_normal_title_style(style.get("normal_title_style").copied()); + self.palette.with_hover_title_style(style.get("hover_title_style").copied()); + self.palette.with_tagged_style(style.get("tagged_style").copied()); + } + Ok(()) + } + fn handle_key_event(&mut self, key: KeyEvent) -> Result> { match key.code { KeyCode::Char('k') | KeyCode::Up if self.is_active => self.move_up(), diff --git a/src/components/explorer/extrinsics_chart.rs b/src/components/explorer/extrinsics_chart.rs index 272a336..018e68f 100644 --- a/src/components/explorer/extrinsics_chart.rs +++ b/src/components/explorer/extrinsics_chart.rs @@ -4,15 +4,16 @@ use ratatui::{ layout::{Alignment, Rect}, text::Line, widgets::{Bar, BarChart, BarGroup, Block}, - Frame + Frame, }; use super::Component; -use crate::action::Action; +use crate::{palette::StylePalette, config::Config, action::Action}; #[derive(Debug, Default)] pub struct ExtrinsicsChart { extrinsics: VecDeque<(u32, usize)>, + palette: StylePalette, } impl ExtrinsicsChart { @@ -21,6 +22,7 @@ impl ExtrinsicsChart { const BAR_GAP: usize = 1; fn extrinsics_bar_chart(&self, width: u16) -> BarChart { + let (border_style, border_type) = self.palette.create_border_style(false); let length = (width as usize) / (Self::BAR_WIDTH + Self::BAR_GAP); let bars: Vec = self.extrinsics @@ -32,7 +34,12 @@ impl ExtrinsicsChart { BarChart::default() .data(BarGroup::default().bars(&bars)) - .block(Block::bordered().title_alignment(Alignment::Right).title("Tx. Heat Map")) + .block(Block::bordered() + .border_style(border_style) + .border_type(border_type) + .title_style(self.palette.create_title_style(false)) + .title_alignment(Alignment::Right) + .title("Tx. Heat Map")) .bar_width(8) .bar_gap(1) } @@ -64,6 +71,18 @@ impl ExtrinsicsChart { } impl Component for ExtrinsicsChart { + fn register_config_handler(&mut self, config: Config) -> Result<()> { + if let Some(style) = config.styles.get(&crate::app::Mode::Explorer) { + self.palette.with_normal_style(style.get("normal_style").copied()); + self.palette.with_hover_style(style.get("hover_style").copied()); + self.palette.with_normal_border_style(style.get("normal_border_style").copied()); + self.palette.with_hover_border_style(style.get("hover_border_style").copied()); + self.palette.with_normal_title_style(style.get("normal_title_style").copied()); + self.palette.with_hover_title_style(style.get("hover_title_style").copied()); + } + Ok(()) + } + fn update(&mut self, action: Action) -> Result> { match action { Action::ExtrinsicsLength(block, length) => self.update_extrinsics_length(block, length)?, diff --git a/src/components/explorer/finalized_block.rs b/src/components/explorer/finalized_block.rs index c0bce92..595e5b4 100644 --- a/src/components/explorer/finalized_block.rs +++ b/src/components/explorer/finalized_block.rs @@ -6,7 +6,12 @@ use ratatui::{ }; use super::Component; -use crate::{action::Action, palette::StylePalette, widgets::{PixelSize, BigText}}; +use crate::{ + config::Config, + action::Action, + palette::StylePalette, + widgets::{PixelSize, BigText}, +}; #[derive(Debug, Default)] pub struct FinalizedBlock { @@ -22,6 +27,18 @@ impl FinalizedBlock { } impl Component for FinalizedBlock { + fn register_config_handler(&mut self, config: Config) -> Result<()> { + if let Some(style) = config.styles.get(&crate::app::Mode::Explorer) { + self.palette.with_normal_style(style.get("normal_style").copied()); + self.palette.with_hover_style(style.get("hover_style").copied()); + self.palette.with_normal_border_style(style.get("normal_border_style").copied()); + self.palette.with_hover_border_style(style.get("hover_border_style").copied()); + self.palette.with_normal_title_style(style.get("normal_title_style").copied()); + self.palette.with_hover_title_style(style.get("hover_title_style").copied()); + } + Ok(()) + } + fn update(&mut self, action: Action) -> Result> { match action { Action::NewFinalizedBlock(number) => self.update_block_number(number)?, @@ -46,7 +63,7 @@ impl Component for FinalizedBlock { .border_style(border_style) .border_type(border_type) .title_alignment(Alignment::Right) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .padding(Padding::new(0, 0, height.saturating_sub(2) / 2, 0)) .title("Latest")) .alignment(Alignment::Center) @@ -66,7 +83,7 @@ impl Component for FinalizedBlock { .border_style(border_style) .border_type(border_type) .title_alignment(Alignment::Right) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .title("Latest")) .alignment(Alignment::Center) .wrap(Wrap { trim: true }); diff --git a/src/components/explorer/latest_block.rs b/src/components/explorer/latest_block.rs index e9e4cbe..bf9bbdc 100644 --- a/src/components/explorer/latest_block.rs +++ b/src/components/explorer/latest_block.rs @@ -6,7 +6,12 @@ use ratatui::{ }; use super::Component; -use crate::{action::Action, palette::StylePalette, widgets::{PixelSize, BigText}}; +use crate::{ + config::Config, + action::Action, + palette::StylePalette, + widgets::{PixelSize, BigText}, +}; #[derive(Debug, Default)] pub struct LatestBlock { @@ -22,6 +27,18 @@ impl LatestBlock { } impl Component for LatestBlock { + fn register_config_handler(&mut self, config: Config) -> Result<()> { + if let Some(style) = config.styles.get(&crate::app::Mode::Explorer) { + self.palette.with_normal_style(style.get("normal_style").copied()); + self.palette.with_hover_style(style.get("hover_style").copied()); + self.palette.with_normal_border_style(style.get("normal_border_style").copied()); + self.palette.with_hover_border_style(style.get("hover_border_style").copied()); + self.palette.with_normal_title_style(style.get("normal_title_style").copied()); + self.palette.with_hover_title_style(style.get("hover_title_style").copied()); + } + Ok(()) + } + fn update(&mut self, action: Action) -> Result> { match action { Action::NewBestBlock(number) => self.update_block_number(number)?, @@ -46,7 +63,7 @@ impl Component for LatestBlock { .border_style(border_style) .border_type(border_type) .title_alignment(Alignment::Right) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .padding(Padding::new(0, 0, height.saturating_sub(2) / 2, 0)) .title("Latest")) .alignment(Alignment::Center) @@ -66,7 +83,7 @@ impl Component for LatestBlock { .border_style(border_style) .border_type(border_type) .title_alignment(Alignment::Right) - .title_style(self.palette.create_title_style()) + .title_style(self.palette.create_title_style(false)) .title("Latest")) .alignment(Alignment::Center) .wrap(Wrap { trim: true }); diff --git a/src/components/explorer/mod.rs b/src/components/explorer/mod.rs index 1fab59e..517a868 100644 --- a/src/components/explorer/mod.rs +++ b/src/components/explorer/mod.rs @@ -6,7 +6,7 @@ use ratatui::{ }; use super::Component; -use crate::action::Action; +use crate::{config::Config, action::Action}; mod latest_block; mod finalized_block; @@ -45,6 +45,15 @@ impl Default for Explorer { } impl Component for Explorer { + fn register_config_handler(&mut self, config: Config) -> Result<()> { + if let Some(_) = config.styles.get(&crate::app::Mode::Explorer) { + for component in self.components.iter_mut() { + component.register_config_handler(config.clone())?; + } + } + Ok(()) + } + fn handle_key_event(&mut self, key: KeyEvent) -> Result> { for component in self.components.iter_mut() { component.handle_key_event(key)?; diff --git a/src/components/menu.rs b/src/components/menu.rs index a0a050f..d972588 100644 --- a/src/components/menu.rs +++ b/src/components/menu.rs @@ -5,7 +5,7 @@ use crossterm::event::{KeyEvent, KeyCode}; use super::Component; use super::palette::StylePalette; -use crate::{action::Action, app::Mode}; +use crate::{config::Config, action::Action, app::Mode}; pub struct Menu { command_tx: Option>, @@ -98,6 +98,18 @@ impl Component for Menu { Ok(()) } + fn register_config_handler(&mut self, config: Config) -> Result<()> { + if let Some(style) = config.styles.get(&crate::app::Mode::Menu) { + self.palette.with_normal_style(style.get("normal_style").copied()); + self.palette.with_hover_style(style.get("hover_style").copied()); + self.palette.with_normal_border_style(style.get("normal_border_style").copied()); + self.palette.with_hover_border_style(style.get("hover_border_style").copied()); + self.palette.with_normal_title_style(style.get("normal_title_style").copied()); + self.palette.with_hover_title_style(style.get("hover_title_style").copied()); + } + Ok(()) + } + fn handle_key_event(&mut self, key: KeyEvent) -> Result> { match key.code { KeyCode::Up | KeyCode::Char('k') if self.is_active => self.move_current_up()?, diff --git a/src/config.rs b/src/config.rs index 7543319..293eaaa 100644 --- a/src/config.rs +++ b/src/config.rs @@ -369,6 +369,7 @@ fn process_color_string(color_str: &str) -> (String, Modifier) { .replace("grey", "gray") .replace("bright", "") .replace("bold", "") + .replace("italic", "") .replace("underline", "") .replace("inverse", ""); @@ -382,6 +383,9 @@ fn process_color_string(color_str: &str) -> (String, Modifier) { if color_str.contains("inverse") { modifiers |= Modifier::REVERSED; } + if color_str.contains("italic") { + modifiers |= Modifier::ITALIC; + } (color, modifiers) } diff --git a/src/palette.rs b/src/palette.rs index a3498e0..dc1d58b 100644 --- a/src/palette.rs +++ b/src/palette.rs @@ -1,23 +1,21 @@ -use ratatui::style::{Style, Color, Modifier}; +use ratatui::style::{Style, Color}; use ratatui::widgets::block::BorderType; #[derive(Debug, Clone)] pub struct StylePalette { - background: Option, - foreground: Option, - modifiers: Vec, + normal_style: Option