colors setting via config file

Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
Uncle Stretch 2024-11-26 14:53:46 +03:00
parent 73db8ca32a
commit 405061265b
Signed by: str3tch
GPG Key ID: 84F3190747EE79AA
13 changed files with 253 additions and 98 deletions

View File

@ -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": { "keybindings": {
"Explorer": { "Explorer": {
"<q>": "Quit", "<q>": "Quit",

View File

@ -17,6 +17,7 @@ use crate::{
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Mode { pub enum Mode {
Menu,
Explorer, Explorer,
ExplorerActive, ExplorerActive,
Empty, Empty,

View File

@ -9,6 +9,7 @@ use ratatui::{
use super::Component; use super::Component;
use crate::{ use crate::{
config::Config,
widgets::{BigText, PixelSize}, widgets::{BigText, PixelSize},
action::Action, action::Action,
palette::StylePalette, palette::StylePalette,
@ -46,6 +47,18 @@ impl BlockTicker {
} }
impl Component for 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<Option<Action>> { fn update(&mut self, action: Action) -> Result<Option<Action>> {
match action { match action {
Action::BestBlockUpdated(block) => self.block_found(block)?, Action::BestBlockUpdated(block) => self.block_found(block)?,
@ -79,7 +92,7 @@ impl Component for BlockTicker {
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .border_type(border_type)
.title_alignment(Alignment::Right) .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)) .padding(Padding::new(0, 0, height.saturating_sub(2) / 2, 0))
.title("Passed")) .title("Passed"))
.alignment(Alignment::Center) .alignment(Alignment::Center)
@ -99,7 +112,7 @@ impl Component for BlockTicker {
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .border_type(border_type)
.title_alignment(Alignment::Right) .title_alignment(Alignment::Right)
.title_style(self.palette.create_title_style()) .title_style(self.palette.create_title_style(false))
.title("Passed")) .title("Passed"))
.alignment(Alignment::Center) .alignment(Alignment::Center)
.wrap(Wrap { trim: true }); .wrap(Wrap { trim: true });

View File

@ -7,7 +7,12 @@ use ratatui::{
}; };
use super::Component; 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)] #[derive(Debug, Default)]
pub struct CurrentEpoch { pub struct CurrentEpoch {
@ -30,6 +35,18 @@ impl CurrentEpoch {
} }
impl Component for 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<Option<Action>> { fn update(&mut self, action: Action) -> Result<Option<Action>> {
match action { match action {
Action::SetEpochProgress(number, progress) => Action::SetEpochProgress(number, progress) =>
@ -70,7 +87,7 @@ impl Component for CurrentEpoch {
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .border_type(border_type)
.title_alignment(Alignment::Right) .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)) .padding(Padding::new(0, 0, height.saturating_sub(3) / 2, 0))
.title("Epoch")) .title("Epoch"))
.alignment(Alignment::Center) .alignment(Alignment::Center)
@ -89,7 +106,7 @@ impl Component for CurrentEpoch {
.block(Block::bordered() .block(Block::bordered()
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .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("Epoch").right_aligned())
.title_top(Line::from(format!("{}{} {}{}", .title_top(Line::from(format!("{}{} {}{}",
if big_time { hours } else { minutes }, if big_time { hours } else { minutes },

View File

@ -8,6 +8,7 @@ use ratatui::{
use super::Component; use super::Component;
use crate::{ use crate::{
config::Config,
action::Action, action::Action,
palette::StylePalette, palette::StylePalette,
types::EraInfo, types::EraInfo,
@ -35,6 +36,18 @@ impl CurrentEra {
} }
impl Component for 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<Option<Action>> { fn update(&mut self, action: Action) -> Result<Option<Action>> {
match action { match action {
Action::SetActiveEra(era_info) => self.update_era(era_info)?, Action::SetActiveEra(era_info) => self.update_era(era_info)?,
@ -88,7 +101,7 @@ impl Component for CurrentEra {
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .border_type(border_type)
.title_alignment(Alignment::Right) .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)) .padding(Padding::new(0, 0, (height.saturating_sub(3)) / 2, 0))
.title("Era")) .title("Era"))
.alignment(Alignment::Center) .alignment(Alignment::Center)
@ -107,7 +120,7 @@ impl Component for CurrentEra {
.block(Block::bordered() .block(Block::bordered()
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .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("Era").right_aligned())
.title_top(Line::from(format!("{}{} {}{}", .title_top(Line::from(format!("{}{} {}{}",
if big_time { hours } else { minutes }, if big_time { hours } else { minutes },

View File

@ -5,7 +5,6 @@ use primitive_types::H256;
use ratatui::{ use ratatui::{
layout::{Alignment, Rect}, layout::{Alignment, Rect},
prelude::*, prelude::*,
style::Style,
text::Line, text::Line,
widgets::{Block, BorderType, Paragraph}, widgets::{Block, BorderType, Paragraph},
Frame Frame
@ -16,7 +15,7 @@ use codec::Decode;
use super::Component; use super::Component;
use crate::{ use crate::{
types::CasperExtrinsicDetails, CasperAccountId, types::CasperExtrinsicDetails, CasperAccountId,
action::Action, app::Mode, palette::StylePalette, config::Config, action::Action, app::Mode, palette::StylePalette,
}; };
struct BlockInfo { struct BlockInfo {
@ -164,10 +163,6 @@ impl ExplorerBlocks {
let total_length = rect.as_size().height as usize - 2; let total_length = rect.as_size().height as usize - 2;
let mut items = Vec::new(); 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 { let start_index = match self.used_block_number {
Some(used_block) if total_length < self.blocks.len() => { Some(used_block) if total_length < self.blocks.len() => {
self.blocks self.blocks
@ -180,14 +175,16 @@ impl ExplorerBlocks {
_ => 0, _ => 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() { for (idx, current_block_info) in self.blocks.iter().skip(start_index).enumerate() {
if idx == total_length { break; } if idx == total_length { break; }
let style = match self.used_block_number { let style = match self.used_block_number {
Some(used_block) if current_block_info.block_number == used_block => active_style, Some(used_block) if current_block_info.block_number == used_block => active_style,
_ => { _ => if current_block_info.finalized { finalized_style } else { normal_style }
if current_block_info.finalized { finalized_style } else { latest_style }
}
}; };
items.push(self.prepare_block_line_info(&current_block_info, width).style(style)); items.push(self.prepare_block_line_info(&current_block_info, width).style(style));
@ -233,24 +230,22 @@ impl ExplorerBlocks {
let mut total_length = rect.as_size().height - 2; let mut total_length = rect.as_size().height - 2;
let mut items = Vec::new(); 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 { if let Some(used_block_number) = self.used_block_number {
let default_hash = H256::repeat_byte(69u8); let default_hash = H256::repeat_byte(69u8);
let hash = self.block_headers let hash = self.block_headers
.get(&used_block_number) .get(&used_block_number)
.unwrap_or(&default_hash); .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) { if let Some(exts) = self.extrinsics.get(&hash) {
for (index, ext) in exts.iter().enumerate() { for (index, ext) in exts.iter().enumerate() {
if total_length == 0 { break; } if total_length == 0 { break; }
let style = if let Some((_, used_ext_index)) = self.used_ext_index { let style = if let Some((_, used_ext_index)) = self.used_ext_index {
if index == used_ext_index { active_style } else { normal_style } if index == used_ext_index { active_style } else { normal_style }
} else { } else { normal_style };
normal_style
};
items.push(self.prepare_ext_line_info( items.push(self.prepare_ext_line_info(
index, index,
@ -405,7 +400,9 @@ impl ExplorerBlocks {
border_style: Color, border_style: Color,
border_type: BorderType, border_type: BorderType,
) -> Paragraph { ) -> 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)) Paragraph::new(self.prepare_block_lines(place))
.block(Block::bordered() .block(Block::bordered()
.border_style(border_style) .border_style(border_style)
@ -422,7 +419,9 @@ impl ExplorerBlocks {
border_style: Color, border_style: Color,
border_type: BorderType, border_type: BorderType,
) -> Paragraph { ) -> 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)) Paragraph::new(self.prepare_ext_lines(place))
.block(Block::bordered() .block(Block::bordered()
.border_style(border_style) .border_style(border_style)
@ -439,7 +438,7 @@ impl ExplorerBlocks {
border_style: Color, border_style: Color,
border_type: BorderType, border_type: BorderType,
) -> Paragraph { ) -> 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)) Paragraph::new(self.prepare_event_lines(place))
.block(Block::bordered() .block(Block::bordered()
.border_style(border_style) .border_style(border_style)
@ -452,6 +451,19 @@ impl ExplorerBlocks {
} }
impl Component for 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<Option<Action>> { fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
match key.code { match key.code {
KeyCode::Char('k') | KeyCode::Up if self.is_active => self.move_up(), KeyCode::Char('k') | KeyCode::Up if self.is_active => self.move_up(),

View File

@ -4,15 +4,16 @@ use ratatui::{
layout::{Alignment, Rect}, layout::{Alignment, Rect},
text::Line, text::Line,
widgets::{Bar, BarChart, BarGroup, Block}, widgets::{Bar, BarChart, BarGroup, Block},
Frame Frame,
}; };
use super::Component; use super::Component;
use crate::action::Action; use crate::{palette::StylePalette, config::Config, action::Action};
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct ExtrinsicsChart { pub struct ExtrinsicsChart {
extrinsics: VecDeque<(u32, usize)>, extrinsics: VecDeque<(u32, usize)>,
palette: StylePalette,
} }
impl ExtrinsicsChart { impl ExtrinsicsChart {
@ -21,6 +22,7 @@ impl ExtrinsicsChart {
const BAR_GAP: usize = 1; const BAR_GAP: usize = 1;
fn extrinsics_bar_chart(&self, width: u16) -> BarChart { 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 length = (width as usize) / (Self::BAR_WIDTH + Self::BAR_GAP);
let bars: Vec<Bar> = self.extrinsics let bars: Vec<Bar> = self.extrinsics
@ -32,7 +34,12 @@ impl ExtrinsicsChart {
BarChart::default() BarChart::default()
.data(BarGroup::default().bars(&bars)) .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_width(8)
.bar_gap(1) .bar_gap(1)
} }
@ -64,6 +71,18 @@ impl ExtrinsicsChart {
} }
impl Component for 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<Option<Action>> { fn update(&mut self, action: Action) -> Result<Option<Action>> {
match action { match action {
Action::ExtrinsicsLength(block, length) => self.update_extrinsics_length(block, length)?, Action::ExtrinsicsLength(block, length) => self.update_extrinsics_length(block, length)?,

View File

@ -6,7 +6,12 @@ use ratatui::{
}; };
use super::Component; 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)] #[derive(Debug, Default)]
pub struct FinalizedBlock { pub struct FinalizedBlock {
@ -22,6 +27,18 @@ impl FinalizedBlock {
} }
impl Component for 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<Option<Action>> { fn update(&mut self, action: Action) -> Result<Option<Action>> {
match action { match action {
Action::NewFinalizedBlock(number) => self.update_block_number(number)?, Action::NewFinalizedBlock(number) => self.update_block_number(number)?,
@ -46,7 +63,7 @@ impl Component for FinalizedBlock {
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .border_type(border_type)
.title_alignment(Alignment::Right) .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)) .padding(Padding::new(0, 0, height.saturating_sub(2) / 2, 0))
.title("Latest")) .title("Latest"))
.alignment(Alignment::Center) .alignment(Alignment::Center)
@ -66,7 +83,7 @@ impl Component for FinalizedBlock {
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .border_type(border_type)
.title_alignment(Alignment::Right) .title_alignment(Alignment::Right)
.title_style(self.palette.create_title_style()) .title_style(self.palette.create_title_style(false))
.title("Latest")) .title("Latest"))
.alignment(Alignment::Center) .alignment(Alignment::Center)
.wrap(Wrap { trim: true }); .wrap(Wrap { trim: true });

View File

@ -6,7 +6,12 @@ use ratatui::{
}; };
use super::Component; 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)] #[derive(Debug, Default)]
pub struct LatestBlock { pub struct LatestBlock {
@ -22,6 +27,18 @@ impl LatestBlock {
} }
impl Component for 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<Option<Action>> { fn update(&mut self, action: Action) -> Result<Option<Action>> {
match action { match action {
Action::NewBestBlock(number) => self.update_block_number(number)?, Action::NewBestBlock(number) => self.update_block_number(number)?,
@ -46,7 +63,7 @@ impl Component for LatestBlock {
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .border_type(border_type)
.title_alignment(Alignment::Right) .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)) .padding(Padding::new(0, 0, height.saturating_sub(2) / 2, 0))
.title("Latest")) .title("Latest"))
.alignment(Alignment::Center) .alignment(Alignment::Center)
@ -66,7 +83,7 @@ impl Component for LatestBlock {
.border_style(border_style) .border_style(border_style)
.border_type(border_type) .border_type(border_type)
.title_alignment(Alignment::Right) .title_alignment(Alignment::Right)
.title_style(self.palette.create_title_style()) .title_style(self.palette.create_title_style(false))
.title("Latest")) .title("Latest"))
.alignment(Alignment::Center) .alignment(Alignment::Center)
.wrap(Wrap { trim: true }); .wrap(Wrap { trim: true });

View File

@ -6,7 +6,7 @@ use ratatui::{
}; };
use super::Component; use super::Component;
use crate::action::Action; use crate::{config::Config, action::Action};
mod latest_block; mod latest_block;
mod finalized_block; mod finalized_block;
@ -45,6 +45,15 @@ impl Default for Explorer {
} }
impl Component 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<Option<Action>> { fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
for component in self.components.iter_mut() { for component in self.components.iter_mut() {
component.handle_key_event(key)?; component.handle_key_event(key)?;

View File

@ -5,7 +5,7 @@ use crossterm::event::{KeyEvent, KeyCode};
use super::Component; use super::Component;
use super::palette::StylePalette; use super::palette::StylePalette;
use crate::{action::Action, app::Mode}; use crate::{config::Config, action::Action, app::Mode};
pub struct Menu { pub struct Menu {
command_tx: Option<UnboundedSender<Action>>, command_tx: Option<UnboundedSender<Action>>,
@ -98,6 +98,18 @@ impl Component for Menu {
Ok(()) 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<Option<Action>> { fn handle_key_event(&mut self, key: KeyEvent) -> Result<Option<Action>> {
match key.code { match key.code {
KeyCode::Up | KeyCode::Char('k') if self.is_active => self.move_current_up()?, KeyCode::Up | KeyCode::Char('k') if self.is_active => self.move_current_up()?,

View File

@ -369,6 +369,7 @@ fn process_color_string(color_str: &str) -> (String, Modifier) {
.replace("grey", "gray") .replace("grey", "gray")
.replace("bright", "") .replace("bright", "")
.replace("bold", "") .replace("bold", "")
.replace("italic", "")
.replace("underline", "") .replace("underline", "")
.replace("inverse", ""); .replace("inverse", "");
@ -382,6 +383,9 @@ fn process_color_string(color_str: &str) -> (String, Modifier) {
if color_str.contains("inverse") { if color_str.contains("inverse") {
modifiers |= Modifier::REVERSED; modifiers |= Modifier::REVERSED;
} }
if color_str.contains("italic") {
modifiers |= Modifier::ITALIC;
}
(color, modifiers) (color, modifiers)
} }

View File

@ -1,23 +1,21 @@
use ratatui::style::{Style, Color, Modifier}; use ratatui::style::{Style, Color};
use ratatui::widgets::block::BorderType; use ratatui::widgets::block::BorderType;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StylePalette { pub struct StylePalette {
background: Option<Color>, normal_style: Option<Style>,
foreground: Option<Color>, hover_style: Option<Style>,
modifiers: Vec<Modifier>,
background_hover: Option<Color>, normal_border_style: Option<Style>,
foreground_hover: Option<Color>, hover_border_style: Option<Style>,
modifiers_hover: Vec<Modifier>,
border_color: Option<Color>, normal_title_style: Option<Style>,
title_color: Option<Color>, hover_title_style: Option<Style>,
border_type: BorderType,
border_color_hover: Option<Color>, tagged_style: Option<Style>,
//title_color_hover: Option<Color>,
border_type_hover: BorderType, normal_border_type: BorderType,
hover_border_type: BorderType,
} }
impl Default for StylePalette { impl Default for StylePalette {
@ -27,77 +25,80 @@ impl Default for StylePalette {
} }
impl StylePalette { impl StylePalette {
// TODO: make read from the config by default
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
background: None, normal_style: None,
foreground: None, hover_style: None,
modifiers: Vec::new(), normal_border_style: None,
hover_border_style: None,
normal_title_style: None,
hover_title_style: None,
tagged_style: None,
background_hover: Some(Color::Blue), normal_border_type: BorderType::Plain,
foreground_hover: Some(Color::Yellow), hover_border_type: BorderType::Double,
modifiers_hover: vec![
Modifier::ITALIC,
Modifier::BOLD,
],
border_color: Some(Color::Blue),
title_color: Some(Color::Blue),
border_type: BorderType::Plain,
border_color_hover: Some(Color::Blue),
//title_color_hover: Some(Color::Blue),
border_type_hover: BorderType::Double,
} }
} }
pub fn foreground_hover(&self) -> Color { pub fn with_normal_style(&mut self, normal_style: Option<Style>) {
self.foreground_hover.unwrap_or_default() self.normal_style = normal_style;
}
pub fn with_hover_style(&mut self, hover_style: Option<Style>) {
self.hover_style = hover_style;
}
pub fn with_normal_border_style(&mut self, normal_border_style: Option<Style>) {
self.normal_border_style = normal_border_style;
}
pub fn with_hover_border_style(&mut self, hover_border_style: Option<Style>) {
self.hover_border_style = hover_border_style;
}
pub fn with_normal_title_style(&mut self, normal_title_style: Option<Style>) {
self.normal_title_style = normal_title_style;
}
pub fn with_hover_title_style(&mut self, hover_title_style: Option<Style>) {
self.hover_title_style = hover_title_style;
}
pub fn with_tagged_style(&mut self, tagged_style: Option<Style>) {
self.tagged_style = tagged_style;
}
pub fn create_tagged_style(&self) -> Style {
self.tagged_style.unwrap_or_default()
} }
pub fn create_text_style(&mut self, active: bool) -> Style { pub fn create_text_style(&mut self, active: bool) -> Style {
if active { if active {
self.create_text_style_hover() self.hover_style.unwrap_or_default()
} else { } else {
self.create_text_style_normal() self.normal_style.unwrap_or_default()
} }
} }
pub fn create_border_style(&self, active: bool) -> (Color, BorderType) { pub fn create_border_style(&self, active: bool) -> (Color, BorderType) {
if active { if active {
( (
self.border_color_hover.unwrap_or_default(), self.hover_border_style.map(|style| style.fg).flatten().unwrap_or_default(),
self.border_type_hover, self.hover_border_type,
) )
} else { } else {
( (
self.border_color.unwrap_or_default(), self.normal_border_style.map(|style| style.fg).flatten().unwrap_or_default(),
self.border_type, self.normal_border_type,
) )
} }
} }
pub fn create_title_style(&mut self) -> Style { pub fn create_title_style(&self, active: bool) -> Style {
Style::default().fg(self.title_color.unwrap_or_default()) if active {
} self.normal_title_style.unwrap_or_default()
} else {
fn create_text_style_normal(&self) -> Style { self.hover_title_style.unwrap_or_default()
let mut style = Style::default()
.fg(self.foreground.unwrap_or_default())
.bg(self.background.unwrap_or_default());
for modifier in self.modifiers.iter() {
style = style.add_modifier(*modifier);
} }
style
}
fn create_text_style_hover(&self) -> Style {
let mut style = Style::default()
.fg(self.foreground_hover.unwrap_or_default())
.bg(self.background_hover.unwrap_or_default());
for modifier in self.modifiers_hover.iter() {
style = style.add_modifier(*modifier);
}
style
} }
} }