From f3cae9f1f99184ebe64344acc52755550d7c90d6 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 21 Jan 2026 11:50:52 +0100 Subject: [PATCH] lib: Allow switching themes --- README.md | 3 ++- examples/hello.rs | 3 ++- examples/readme.rs | 3 ++- examples/selection.rs | 3 ++- src/ui.rs | 5 +++++ src/ui/theme.rs | 4 +++- src/ui/widget.rs | 9 ++++++--- 7 files changed, 22 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b9ceb657..80f86e97 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,7 @@ use radicle_tui as tui; use tui::event::Key; use tui::store; use tui::task::EmptyProcessors; +use tui::ui::theme::Theme; use tui::ui::widget::{Borders, Window}; use tui::ui::{Context, Show}; use tui::{Channel, Exit}; @@ -173,7 +174,7 @@ impl store::Update for App { impl Show for App { fn show(&self, ctx: &Context, frame: &mut Frame) -> Result<()> { - Window::default().show(ctx, |ui| { + Window::default().show(ctx, Theme::default(), |ui| { ui.text_view( frame, self.hello.clone(), diff --git a/examples/hello.rs b/examples/hello.rs index 58b1ae95..73009b45 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -9,6 +9,7 @@ use radicle_tui as tui; use tui::event::Key; use tui::store; use tui::task::EmptyProcessors; +use tui::ui::theme::Theme; use tui::ui::widget::{Borders, Window}; use tui::ui::{Context, Show}; use tui::{Channel, Exit}; @@ -50,7 +51,7 @@ impl store::Update for App { impl Show for App { fn show(&self, ctx: &Context, frame: &mut Frame) -> Result<()> { - Window::default().show(ctx, |ui| { + Window::default().show(ctx, Theme::default(), |ui| { ui.text_view( frame, self.alien.clone(), diff --git a/examples/readme.rs b/examples/readme.rs index 33f09876..bfd0bb41 100644 --- a/examples/readme.rs +++ b/examples/readme.rs @@ -8,6 +8,7 @@ use radicle_tui as tui; use tui::event::Key; use tui::store; use tui::task::EmptyProcessors; +use tui::ui::theme::Theme; use tui::ui::widget::{Borders, Window}; use tui::ui::{Context, Show}; use tui::{Channel, Exit}; @@ -34,7 +35,7 @@ impl store::Update for App { impl Show for App { fn show(&self, ctx: &Context, frame: &mut Frame) -> Result<()> { - Window::default().show(ctx, |ui| { + Window::default().show(ctx, Theme::default(), |ui| { ui.text_view( frame, self.hello.clone(), diff --git a/examples/selection.rs b/examples/selection.rs index 7f87161d..7ff2bd8b 100644 --- a/examples/selection.rs +++ b/examples/selection.rs @@ -14,6 +14,7 @@ use tui::event::Key; use tui::store::Update; use tui::task::EmptyProcessors; use tui::ui::layout::Spacing; +use tui::ui::theme::Theme; use tui::ui::widget::{Borders, Column, TableState, Window}; use tui::ui::{Context, Show, ToRow}; use tui::Channel; @@ -75,7 +76,7 @@ impl Update for App { impl Show for App { fn show(&self, ctx: &Context, frame: &mut Frame) -> Result<()> { - Window::default().show(ctx, |ui| { + Window::default().show(ctx, Theme::default(), |ui| { ui.layout( Layout::vertical([ Constraint::Length(1), diff --git a/src/ui.rs b/src/ui.rs index dfc4f968..f9371a51 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -397,6 +397,11 @@ impl Ui { self } + pub fn with_theme(mut self, theme: Theme) -> Self { + self.theme = theme; + self + } + pub fn theme(&self) -> &Theme { &self.theme } diff --git a/src/ui/theme.rs b/src/ui/theme.rs index da710bc8..b6a57757 100644 --- a/src/ui/theme.rs +++ b/src/ui/theme.rs @@ -1,6 +1,8 @@ +use serde::{Deserialize, Serialize}; + use ratatui::style::{Color, Style, Stylize}; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Theme { pub border_style: Style, pub focus_border_style: Style, diff --git a/src/ui/widget.rs b/src/ui/widget.rs index 941066b2..cdb72d48 100644 --- a/src/ui/widget.rs +++ b/src/ui/widget.rs @@ -15,7 +15,7 @@ use ratatui::{layout::Constraint, widgets::Paragraph}; use crate::event::Key; use crate::ui::ext::{FooterBlock, FooterBlockType, HeaderBlock}; use crate::ui::layout::Spacing; -use crate::ui::theme::style; +use crate::ui::theme::{style, Theme}; use crate::ui::ToRow; use crate::ui::{layout, span, ToTree}; @@ -131,17 +131,19 @@ impl Window { pub fn show( self, ctx: &Context, + theme: Theme, add_contents: impl FnOnce(&mut Ui) -> R, ) -> Option>> where M: Clone, { - self.show_dyn(ctx, Box::new(add_contents)) + self.show_dyn(ctx, theme, Box::new(add_contents)) } fn show_dyn( self, ctx: &Context, + theme: Theme, add_contents: Box>, ) -> Option>> where @@ -152,7 +154,8 @@ impl Window { .with_area(ctx.frame_size()) .with_ctx(ctx.clone()) .with_layout(Layout::horizontal([Constraint::Min(1)]).into()) - .with_area_focus(Some(0)); + .with_area_focus(Some(0)) + .with_theme(theme); let inner = add_contents(&mut ui);