Repository: tarkah/tickrs (language: rust)

Issue:
Theme: background isn't applied everywhere
Just tried the background theming option for the first time

<details>
<summary> <code> ~/.config/tickrs/config.yml </code> </summary>

```yml
theme:
  background: '#403E41'
```

</details>

| | line | candle |
| - | - | - |
| summary of 1 | ![Screenshot_20210220_191115](https://user-images.githubusercontent.com/16881812/108604653-7edfcf80-73af-11eb-96e2-3b89909f1ca9.png) | ![Screenshot_20210220_190458](https://user-images.githubusercontent.com/16881812/108604488-95d1f200-73ae-11eb-8780-c1537af2730a.png) |
| summary of 3 | ![Screenshot_20210220_191301](https://user-images.githubusercontent.com/16881812/108604688-b77fa900-73af-11eb-84eb-44ade54af117.png) | ![Screenshot_20210220_190139](https://user-images.githubusercontent.com/16881812/108604438-41c70d80-73ae-11eb-8ace-bbe6e396cf4e.png)
| stock view | ![Screenshot_20210220_191435](https://user-images.githubusercontent.com/16881812/108604720-eac23800-73af-11eb-9dab-aa8a0037e4ab.png) | ![Screenshot_20210220_190300](https://user-images.githubusercontent.com/16881812/108604442-4db2cf80-73ae-11eb-8aa0-0bf815da468d.png) |


Discussion / hints:
Ahh, I never tested theming on the new candle chart. My bad! I should implement my own default style that always uses our Theme background color so I don't have to always remember to specify it.
Also, in summary mode (irrespective of line or candle views), the background isn't applied where there isn't a block showing an item. As shown above.

And the time frame tabs below in the summary view doesn't have a background too (unlike stock mode).
> 
> 
> Also, in summary mode (irrespective of line or candle views), the background isn't applied where there isn't a block showing an item. As shown above.
> 
> And the time frame tabs below in the summary view doesn't have a background too (unlike stock mode).

Yeah I know exactly what I did to break this from the initial theme release. I'll add a styling change that'll future proof me from making these errors again in the future.

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9e4a4fe..a1858a3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@ and `Removed`.
 
 ### Fixed
 
+- Fixed theme background not getting applied to all widgets ([#84])
 - Fixed last x label for candlestick charts from showing unix time 0 for 1W - 5Y
   timeframes ([#85])
 
@@ -123,4 +124,5 @@ and `Removed`.
 [#75]: https://github.com/tarkah/tickrs/pull/75
 [#76]: https://github.com/tarkah/tickrs/pull/76
 [#79]: https://github.com/tarkah/tickrs/pull/79
-[#85]: https://github.com/tarkah/tickrs/pull/85
\ No newline at end of file
+[#84]: https://github.com/tarkah/tickrs/pull/84
+[#85]: https://github.com/tarkah/tickrs/pull/85
diff --git a/src/draw.rs b/src/draw.rs
index 5ed42e0..c0e2a7f 100644
--- a/src/draw.rs
+++ b/src/draw.rs
@@ -1,12 +1,12 @@
 use tui::backend::Backend;
 use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
-use tui::style::Style;
 use tui::text::{Span, Spans, Text};
 use tui::widgets::{Block, Borders, Clear, Paragraph, Tabs, Wrap};
 use tui::{Frame, Terminal};
 
 use crate::app::{App, Mode, ScrollDirection};
 use crate::common::TimeFrame;
+use crate::theme::style;
 use crate::widget::{
     block, AddStockWidget, OptionsWidget, StockSummaryWidget, StockWidget, HELP_HEIGHT, HELP_WIDTH,
 };
@@ -26,10 +26,7 @@ pub fn draw<B: Backend>(terminal: &mut Terminal<B>, app: &mut App) {
     terminal
         .draw(|mut frame| {
             // Set background color
-            frame.render_widget(
-                Block::default().style(Style::default().bg(THEME.background())),
-                frame.size(),
-            );
+            frame.render_widget(Block::default().style(style()), frame.size());
 
             if app.debug.enabled && app.mode == Mode::AddStock {
                 // layout[0] - Main window
@@ -127,8 +124,8 @@ fn draw_main<B: Backend>(frame: &mut Frame<B>, app: &mut App, area: Rect) {
             frame.render_widget(
                 Tabs::new(tabs)
                     .select(app.current_tab)
-                    .style(Style::default().fg(THEME.text_secondary()))
-                    .highlight_style(Style::default().fg(THEME.text_primary())),
+                    .style(style().fg(THEME.text_secondary()))
+                    .highlight_style(style().fg(THEME.text_primary())),
                 header[0],
             );
         }
@@ -136,12 +133,8 @@ fn draw_main<B: Backend>(frame: &mut Frame<B>, app: &mut App, area: Rect) {
         // Draw help icon
         if !app.hide_help {
             frame.render_widget(
-                Paragraph::new(Text::styled("Help '?'", Style::default()))
-                    .style(
-                        Style::default()
-                            .fg(THEME.text_normal())
-                            .bg(THEME.background()),
-                    )
+                Paragraph::new(Text::styled("Help '?'", style()))
+                    .style(style().fg(THEME.text_normal()))
                     .alignment(Alignment::Center),
                 header[1],
             );
@@ -187,7 +180,7 @@ fn draw_main<B: Backend>(frame: &mut Frame<B>, app: &mut App, area: Rect) {
                 frame.render_widget(
                     Paragraph::new(Text::styled(
                         "Increase screen size to display options",
-                        Style::default(),
+                        style(),
                     )),
                     main_chunks[1],
                 );
@@ -272,12 +265,8 @@ fn draw_summary<B: Backend>(frame: &mut Frame<B>, app: &mut App, mut area: Rect)
     // Draw help icon
     if !app.hide_help {
         frame.render_widget(
-            Paragraph::new(Text::styled("Help '?'", Style::default()))
-                .style(
-                    Style::default()
-                        .fg(THEME.text_normal())
-                        .bg(THEME.background()),
-                )
+            Paragraph::new(Text::styled("Help '?'", style()))
+                .style(style().fg(THEME.text_normal()))
                 .alignment(Alignment::Center),
             header[1],
         );
@@ -301,16 +290,15 @@ fn draw_summary<B: Backend>(frame: &mut Frame<B>, app: &mut App, mut area: Rect)
     {
         layout[2] = add_padding(layout[2], 1, PaddingDirection::Left);
         frame.render_widget(Clear, layout[2]);
+        frame.render_widget(Block::default().style(style()), layout[2]);
 
         let offset = layout[2].height - 2;
         layout[2] = add_padding(layout[2], offset, PaddingDirection::Top);
 
         frame.render_widget(
-            Block::default().borders(Borders::TOP).border_style(
-                Style::default()
-                    .fg(THEME.border_secondary())
-                    .bg(THEME.background()),
-            ),
+            Block::default()
+                .borders(Borders::TOP)
+                .border_style(style().fg(THEME.border_secondary())),
             layout[2],
         );
 
@@ -330,8 +318,8 @@ fn draw_summary<B: Backend>(frame: &mut Frame<B>, app: &mut App, mut area: Rect)
 
         let tabs = Tabs::new(time_frames)
             .select(app.summary_time_frame.idx())
-            .style(Style::default().fg(THEME.text_secondary()))
-            .highlight_style(Style::default().fg(THEME.text_primary()));
+            .style(style().fg(THEME.text_secondary()))
+            .highlight_style(style().fg(THEME.text_primary()));
 
         frame.render_widget(tabs, bottom_layout[0]);
 
@@ -340,7 +328,7 @@ fn draw_summary<B: Backend>(frame: &mut Frame<B>, app: &mut App, mut area: Rect)
 
         let up_arrow = Span::styled(
             "ᐱ",
-            Style::default().fg(if more_up {
+            style().fg(if more_up {
                 THEME.text_normal()
             } else {
                 THEME.gray()
@@ -348,7 +336,7 @@ fn draw_summary<B: Backend>(frame: &mut Frame<B>, app: &mut App, mut area: Rect)
         );
         let down_arrow = Span::styled(
             "ᐯ",
-            Style::default().fg(if more_down {
+            style().fg(if more_down {
                 THEME.text_normal()
             } else {
                 THEME.gray()
@@ -369,7 +357,7 @@ fn draw_help<B: Backend>(frame: &mut Frame<B>, app: &mut App, area: Rect) {
         frame.render_widget(
             Paragraph::new(Text::styled(
                 "Increase screen size to display help",
-                Style::default(),
+                style(),
             )),
             layout,
         );
@@ -383,7 +371,7 @@ fn draw_help<B: Backend>(frame: &mut Frame<B>, app: &mut App, area: Rect) {
 fn draw_debug<B: Backend>(frame: &mut Frame<B>, app: &mut App, area: Rect) {
     app.debug.mode = app.mode;
 
-    let debug_text = Text::styled(format!("{:?}", app.debug), Style::default());
+    let debug_text = Text::styled(format!("{:?}", app.debug), style());
     let debug_paragraph = Paragraph::new(debug_text).wrap(Wrap { trim: true });
 
     frame.render_widget(debug_paragraph, area);
diff --git a/src/theme.rs b/src/theme.rs
index 74a55a2..c969579 100644
--- a/src/theme.rs
+++ b/src/theme.rs
@@ -1,7 +1,12 @@
 use serde::Deserialize;
-use tui::style::Color;
+use tui::style::{Color, Style};
 
 use self::de::deserialize_option_color_hex_string;
+use crate::THEME;
+
+pub fn style() -> Style {
+    Style::default().bg(THEME.background())
+}
 
 macro_rules! def_theme_struct_with_defaults {
     ($($name:ident => $color:expr),+) => {
diff --git a/src/widget/add_stock.rs b/src/widget/add_stock.rs
index 1f92fdc..911e890 100644
--- a/src/widget/add_stock.rs
+++ b/src/widget/add_stock.rs
@@ -1,10 +1,11 @@
 use tui::buffer::Buffer;
 use tui::layout::{Alignment, Rect};
-use tui::style::{Modifier, Style};
+use tui::style::Modifier;
 use tui::text::{Span, Spans};
 use tui::widgets::{Paragraph, StatefulWidget, Widget, Wrap};
 
 use super::block;
+use crate::theme::style;
 use crate::THEME;
 
 pub struct AddStockState {
@@ -50,20 +51,18 @@ impl StatefulWidget for AddStockWidget {
     fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
         let spans = if !state.has_user_input && state.error_msg.is_some() {
             Spans::from(vec![
-                Span::styled("> ", Style::default().fg(THEME.text_normal())),
+                Span::styled("> ", style().fg(THEME.text_normal())),
                 Span::styled(
                     state.error_msg.as_ref().unwrap(),
-                    Style::default()
-                        .add_modifier(Modifier::BOLD)
-                        .fg(THEME.loss()),
+                    style().add_modifier(Modifier::BOLD).fg(THEME.loss()),
                 ),
             ])
         } else {
             Spans::from(vec![
-                Span::styled("> ", Style::default().fg(THEME.text_normal())),
+                Span::styled("> ", style().fg(THEME.text_normal())),
                 Span::styled(
                     &state.search_string,
-                    Style::default()
+                    style()
                         .add_modifier(Modifier::BOLD)
                         .fg(THEME.text_secondary()),
                 ),
@@ -72,7 +71,7 @@ impl StatefulWidget for AddStockWidget {
 
         Paragraph::new(spans)
             .block(block::new(" Add Ticker "))
-            .style(Style::default())
+            .style(style())
             .alignment(Alignment::Left)
             .wrap(Wrap { trim: true })
             .render(area, buf);
diff --git a/src/widget/block.rs b/src/widget/block.rs
index c81b163..a2311b1 100644
--- a/src/widget/block.rs
+++ b/src/widget/block.rs
@@ -1,15 +1,12 @@
-use tui::style::Style;
 use tui::text::Span;
 use tui::widgets::{Block, Borders};
 
+use crate::theme::style;
 use crate::THEME;
 
 pub fn new(title: &str) -> Block {
     Block::default()
         .borders(Borders::ALL)
-        .border_style(Style::default().fg(THEME.border_primary()))
-        .title(Span::styled(
-            title,
-            Style::default().fg(THEME.text_normal()),
-        ))
+        .border_style(style().fg(THEME.border_primary()))
+        .title(Span::styled(title, style().fg(THEME.text_normal())))
 }
diff --git a/src/widget/chart/prices_candlestick.rs b/src/widget/chart/prices_candlestick.rs
index 50bb491..9a27b04 100644
--- a/src/widget/chart/prices_candlestick.rs
+++ b/src/widget/chart/prices_candlestick.rs
@@ -1,13 +1,13 @@
 use itertools::Itertools;
 use tui::buffer::Buffer;
 use tui::layout::{Constraint, Direction, Layout, Rect};
-use tui::style::Style;
 use tui::text::Span;
 use tui::widgets::canvas::{Canvas, Line, Rectangle};
 use tui::widgets::{Block, Borders, StatefulWidget, Widget};
 
 use crate::common::{Price, TimeFrame};
 use crate::draw::{add_padding, PaddingDirection};
+use crate::theme::style;
 use crate::widget::StockState;
 use crate::{HIDE_PREV_CLOSE, THEME};
 
@@ -38,7 +38,7 @@ impl<'a> StatefulWidget for PricesCandlestickChart<'a> {
         if !self.is_summary {
             Block::default()
                 .borders(Borders::TOP)
-                .border_style(Style::default().fg(THEME.border_secondary()))
+                .border_style(style().fg(THEME.border_secondary()))
                 .render(area, buf);
             area = add_padding(area, 1, PaddingDirection::Top);
         }
@@ -174,14 +174,16 @@ impl<'a> StatefulWidget for PricesCandlestickChart<'a> {
 
         if self.loaded {
             Canvas::default()
+                .background_color(THEME.background())
                 .block(
                     Block::default()
+                        .style(style())
                         .borders(if self.show_x_labels {
                             Borders::LEFT | Borders::BOTTOM
                         } else {
                             Borders::LEFT
                         })
-                        .border_style(Style::default().fg(THEME.border_axis())),
+                        .border_style(style().fg(THEME.border_axis())),
                 )
                 .x_bounds([0.0, num_candles as f64 * 4.0])
                 .y_bounds(state.y_bounds(min, max))
@@ -245,7 +247,7 @@ impl<'a> StatefulWidget for PricesCandlestickChart<'a> {
                 } else {
                     Borders::LEFT
                 })
-                .border_style(Style::default().fg(THEME.border_axis()))
+                .border_style(style().fg(THEME.border_axis()))
                 .render(layout[1], buf);
         }
     }
diff --git a/src/widget/chart/prices_line.rs b/src/widget/chart/prices_line.rs
index 2272404..c34fbeb 100644
--- a/src/widget/chart/prices_line.rs
+++ b/src/widget/chart/prices_line.rs
@@ -1,12 +1,12 @@
 use tui::buffer::Buffer;
 use tui::layout::Rect;
-use tui::style::Style;
 use tui::symbols::Marker;
 use tui::widgets::{Axis, Block, Borders, Chart, Dataset, GraphType, StatefulWidget, Widget};
 
 use crate::common::{
     cast_as_dataset, cast_historical_as_price, zeros_as_pre, Price, TimeFrame, TradingPeriod,
 };
+use crate::theme::style;
 use crate::widget::StockState;
 use crate::{HIDE_PREV_CLOSE, THEME};
 
@@ -140,19 +140,15 @@ impl<'a> StatefulWidget for PricesLineChart<'a> {
 
         let mut datasets = vec![Dataset::default()
             .marker(Marker::Braille)
-            .style(
-                Style::default()
-                    .fg(
-                        if trading_period != TradingPeriod::Regular && self.enable_pre_post {
-                            THEME.gray()
-                        } else if self.is_profit {
-                            THEME.profit()
-                        } else {
-                            THEME.loss()
-                        },
-                    )
-                    .bg(THEME.background()),
-            )
+            .style(style().fg(
+                if trading_period != TradingPeriod::Regular && self.enable_pre_post {
+                    THEME.gray()
+                } else if self.is_profit {
+                    THEME.profit()
+                } else {
+                    THEME.loss()
+                },
+            ))
             .graph_type(graph_type)
             .data(&reg_prices)];
 
@@ -160,17 +156,13 @@ impl<'a> StatefulWidget for PricesLineChart<'a> {
             datasets.push(
                 Dataset::default()
                     .marker(Marker::Braille)
-                    .style(
-                        Style::default()
-                            .fg(if trading_period != TradingPeriod::Post {
-                                THEME.gray()
-                            } else if self.is_profit {
-                                THEME.profit()
-                            } else {
-                                THEME.loss()
-                            })
-                            .bg(THEME.background()),
-                    )
+                    .style(style().fg(if trading_period != TradingPeriod::Post {
+                        THEME.gray()
+                    } else if self.is_profit {
+                        THEME.profit()
+                    } else {
+                        THEME.loss()
+                    }))
                     .graph_type(GraphType::Line)
                     .data(&data),
             );
@@ -181,17 +173,13 @@ impl<'a> StatefulWidget for PricesLineChart<'a> {
                 0,
                 Dataset::default()
                     .marker(Marker::Braille)
-                    .style(
-                        Style::default()
-                            .fg(if trading_period != TradingPeriod::Pre {
-                                THEME.gray()
-                            } else if self.is_profit {
-                                THEME.profit()
-                            } else {
-                                THEME.loss()
-                            })
-                            .bg(THEME.background()),
-                    )
+                    .style(style().fg(if trading_period != TradingPeriod::Pre {
+                        THEME.gray()
+                    } else if self.is_profit {
+                        THEME.profit()
+                    } else {
+                        THEME.loss()
+                    }))
                     .graph_type(GraphType::Line)
                     .data(&data),
             );
@@ -202,20 +190,19 @@ impl<'a> StatefulWidget for PricesLineChart<'a> {
                 0,
                 Dataset::default()
                     .marker(Marker::Braille)
-                    .style(Style::default().fg(THEME.gray()).bg(THEME.background()))
+                    .style(style().fg(THEME.gray()))
                     .graph_type(GraphType::Line)
                     .data(&data),
             );
         }
 
         let mut chart = Chart::new(datasets)
-            .style(Style::default().bg(THEME.background()))
+            .style(style())
             .x_axis({
                 let axis = Axis::default().bounds(state.x_bounds(start, end, &self.data));
 
                 if self.show_x_labels && self.loaded && !self.is_summary {
-                    axis.labels(x_labels)
-                        .style(Style::default().fg(THEME.border_axis()))
+                    axis.labels(x_labels).style(style().fg(THEME.border_axis()))
                 } else {
                     axis
                 }
@@ -224,15 +211,15 @@ impl<'a> StatefulWidget for PricesLineChart<'a> {
                 Axis::default()
                     .bounds(state.y_bounds(min, max))
                     .labels(state.y_labels(min, max))
-                    .style(Style::default().fg(THEME.border_axis())),
+                    .style(style().fg(THEME.border_axis())),
             );
 
         if !self.is_summary {
             chart = chart.block(
                 Block::default()
-                    .style(Style::default().fg(THEME.border_secondary()))
+                    .style(style().fg(THEME.border_secondary()))
                     .borders(Borders::TOP)
-                    .border_style(Style::default()),
+                    .border_style(style()),
             );
         }
 
diff --git a/src/widget/chart/volume_bar.rs b/src/widget/chart/volume_bar.rs
index 252f2d2..901b30c 100644
--- a/src/widget/chart/volume_bar.rs
+++ b/src/widget/chart/volume_bar.rs
@@ -1,11 +1,11 @@
 use itertools::Itertools;
 use tui::buffer::Buffer;
 use tui::layout::Rect;
-use tui::style::Style;
 use tui::symbols::bar;
 use tui::widgets::{BarChart, Block, Borders, StatefulWidget, Widget};
 
 use crate::common::{Price, TimeFrame};
+use crate::theme::style;
 use crate::widget::StockState;
 use crate::THEME;
 
@@ -58,7 +58,7 @@ impl<'a> StatefulWidget for VolumeBarChart<'a> {
 
             Block::default()
                 .borders(Borders::LEFT)
-                .border_style(Style::default().fg(THEME.border_axis()))
+                .border_style(style().fg(THEME.border_axis()))
                 .render(volume_chunks, buf);
 
             volume_chunks.x += 1;
@@ -66,7 +66,7 @@ impl<'a> StatefulWidget for VolumeBarChart<'a> {
             BarChart::default()
                 .bar_gap(0)
                 .bar_set(bar::NINE_LEVELS)
-                .style(Style::default().fg(THEME.gray()).bg(THEME.background()))
+                .style(style().fg(THEME.gray()))
                 .data(&volumes)
                 .render(volume_chunks, buf);
         }
diff --git a/src/widget/help.rs b/src/widget/help.rs
index c04f971..b37a02e 100644
--- a/src/widget/help.rs
+++ b/src/widget/help.rs
@@ -1,11 +1,11 @@
 use tui::buffer::Buffer;
 use tui::layout::{Constraint, Direction, Layout, Rect};
-use tui::style::Style;
 use tui::text::{Span, Spans};
 use tui::widgets::{Paragraph, Widget};
 
 use super::block;
 use crate::draw::{add_padding, PaddingDirection};
+use crate::theme::style;
 use crate::THEME;
 
 const LEFT_TEXT: &str = r#"
@@ -84,7 +84,7 @@ impl Widget for HelpWidget {
             .map(|line| {
                 Spans::from(Span::styled(
                     format!("{}\n", line),
-                    Style::default().fg(THEME.text_normal()),
+                    style().fg(THEME.text_normal()),
                 ))
             })
             .collect();
@@ -94,7 +94,7 @@ impl Widget for HelpWidget {
             .map(|line| {
                 Spans::from(Span::styled(
                     format!("{}\n", line),
-                    Style::default().fg(THEME.text_normal()),
+                    style().fg(THEME.text_normal()),
                 ))
             })
             .collect();
diff --git a/src/widget/options.rs b/src/widget/options.rs
index c3f3c99..7e0afa1 100644
--- a/src/widget/options.rs
+++ b/src/widget/options.rs
@@ -4,7 +4,7 @@ use std::hash::{Hash, Hasher};
 use chrono::NaiveDateTime;
 use tui::buffer::Buffer;
 use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
-use tui::style::{Modifier, Style};
+use tui::style::Modifier;
 use tui::text::{Span, Spans};
 use tui::widgets::{
     Block, Borders, Cell, List, ListItem, ListState, Paragraph, Row, StatefulWidget, Table,
@@ -15,6 +15,7 @@ use super::{block, CachableWidget, CacheState};
 use crate::api::model::{OptionsData, OptionsQuote};
 use crate::draw::{add_padding, PaddingDirection};
 use crate::service::{self, Service};
+use crate::theme::style;
 use crate::THEME;
 
 #[derive(Clone, Copy, PartialEq, Hash)]
@@ -269,7 +270,7 @@ impl CachableWidget<OptionsState> for OptionsWidget {
             let call_put_selector = vec![
                 Span::styled(
                     "Call",
-                    Style::default().fg(THEME.profit()).add_modifier(
+                    style().fg(THEME.profit()).add_modifier(
                         if state.selected_type == OptionType::Call {
                             Modifier::BOLD | Modifier::UNDERLINED
                         } else {
@@ -277,10 +278,10 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                         },
                     ),
                 ),
-                Span::styled(" | ", Style::default()),
+                Span::styled(" | ", style()),
                 Span::styled(
                     "Put",
-                    Style::default().fg(THEME.loss()).add_modifier(
+                    style().fg(THEME.loss()).add_modifier(
                         if state.selected_type == OptionType::Put {
                             Modifier::BOLD | Modifier::UNDERLINED
                         } else {
@@ -294,18 +295,14 @@ impl CachableWidget<OptionsState> for OptionsWidget {
             chunks[0] = add_padding(chunks[0], 1, PaddingDirection::Right);
 
             Block::default()
-                .style(Style::default().fg(THEME.border_secondary()))
+                .style(style().fg(THEME.border_secondary()))
                 .borders(Borders::BOTTOM)
                 .render(chunks[0], buf);
 
             chunks[0] = add_padding(chunks[0], 1, PaddingDirection::Bottom);
 
             Paragraph::new(Spans::from(call_put_selector))
-                .style(
-                    Style::default()
-                        .fg(THEME.text_normal())
-                        .bg(THEME.background()),
-                )
+                .style(style().fg(THEME.text_normal()))
                 .alignment(Alignment::Center)
                 .render(chunks[0], buf);
         }
@@ -322,7 +319,7 @@ impl CachableWidget<OptionsState> for OptionsWidget {
             selector_chunks[0] = add_padding(selector_chunks[0], 1, PaddingDirection::Left);
 
             Block::default()
-                .style(Style::default().fg(THEME.border_secondary()))
+                .style(style().fg(THEME.border_secondary()))
                 .borders(Borders::RIGHT)
                 .render(selector_chunks[0], buf);
             selector_chunks[0] = add_padding(selector_chunks[0], 2, PaddingDirection::Right);
@@ -332,26 +329,17 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                 .iter()
                 .map(|d| {
                     let date = NaiveDateTime::from_timestamp(*d, 0).date();
-                    ListItem::new(Span::styled(
-                        date.format("%b-%d-%y").to_string(),
-                        Style::default(),
-                    ))
+                    ListItem::new(Span::styled(date.format("%b-%d-%y").to_string(), style()))
                 })
                 .collect::<Vec<_>>();
 
             let list = List::new(dates)
-                .style(
-                    Style::default()
-                        .fg(THEME.text_normal())
-                        .bg(THEME.background()),
-                )
-                .highlight_style(Style::default().bg(
-                    if state.selection_mode == SelectionMode::Dates {
-                        THEME.highlight_focused()
-                    } else {
-                        THEME.highlight_unfocused()
-                    },
-                ));
+                .style(style().fg(THEME.text_normal()))
+                .highlight_style(style().bg(if state.selection_mode == SelectionMode::Dates {
+                    THEME.highlight_focused()
+                } else {
+                    THEME.highlight_unfocused()
+                }));
 
             let mut list_state = ListState::default();
             if let Some(idx) = state
@@ -362,11 +350,8 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                 list_state.select(Some(idx));
             }
 
-            Paragraph::new(Span::styled(
-                "Date",
-                Style::default().fg(THEME.text_secondary()),
-            ))
-            .render(selector_chunks[0], buf);
+            Paragraph::new(Span::styled("Date", style().fg(THEME.text_secondary())))
+                .render(selector_chunks[0], buf);
 
             selector_chunks[0] = add_padding(selector_chunks[0], 2, PaddingDirection::Top);
 
@@ -390,7 +375,7 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                         Cell::from(format!("{: <7.2}", d.last_price)),
                         Cell::from(format!("{: >7.2}%", d.percent_change)),
                     ])
-                    .style(Style::default().fg(if d.percent_change >= 0.0 {
+                    .style(style().fg(if d.percent_change >= 0.0 {
                         THEME.profit()
                     } else {
                         THEME.loss()
@@ -400,16 +385,12 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                 let table = Table::new(rows)
                     .header(
                         Row::new(vec!["Strike", "Price", "% Change"])
-                            .style(Style::default().fg(THEME.text_secondary()))
+                            .style(style().fg(THEME.text_secondary()))
                             .bottom_margin(1),
                     )
-                    .style(
-                        Style::default()
-                            .fg(THEME.text_normal())
-                            .bg(THEME.background()),
-                    )
+                    .style(style().fg(THEME.text_normal()))
                     .highlight_style(
-                        Style::default()
+                        style()
                             .bg(if state.selection_mode == SelectionMode::Options {
                                 THEME.highlight_focused()
                             } else {
@@ -441,7 +422,7 @@ impl CachableWidget<OptionsState> for OptionsWidget {
             chunks[1] = add_padding(chunks[1], 1, PaddingDirection::Right);
 
             Block::default()
-                .style(Style::default().fg(THEME.border_secondary()))
+                .style(style().fg(THEME.border_secondary()))
                 .borders(Borders::BOTTOM)
                 .render(chunks[1], buf);
 
@@ -488,12 +469,12 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                                 option.strike,
                                 currency
                             ),
-                            Style::default(),
+                            style(),
                         )),
                         Spans::default(),
                         Spans::from(Span::styled(
                             format!("price:{}{:.2}", " ".repeat(gap_last), option.last_price,),
-                            Style::default(),
+                            style(),
                         )),
                         Spans::default(),
                         Spans::from(Span::styled(
@@ -502,7 +483,7 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                                 " ".repeat(gap_ask),
                                 option.bid.unwrap_or_default(),
                             ),
-                            Style::default(),
+                            style(),
                         )),
                         Spans::default(),
                         Spans::from(Span::styled(
@@ -511,7 +492,7 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                                 " ".repeat(gap_bid),
                                 option.ask.unwrap_or_default(),
                             ),
-                            Style::default(),
+                            style(),
                         )),
                     ];
 
@@ -522,7 +503,7 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                                 " ".repeat(gap_volume),
                                 option.volume.unwrap_or_default(),
                             ),
-                            Style::default(),
+                            style(),
                         )),
                         Spans::default(),
                         Spans::from(Span::styled(
@@ -531,7 +512,7 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                                 " ".repeat(gap_open_int),
                                 option.open_interest.unwrap_or_default()
                             ),
-                            Style::default(),
+                            style(),
                         )),
                         Spans::default(),
                         Spans::from(Span::styled(
@@ -540,23 +521,15 @@ impl CachableWidget<OptionsState> for OptionsWidget {
                                 " ".repeat(gap_impl_vol),
                                 option.implied_volatility.unwrap_or_default() * 100.0
                             ),
-                            Style::default(),
+                            style(),
                         )),
                     ];
 
                     Paragraph::new(column_0)
-                        .style(
-                            Style::default()
-                                .fg(THEME.text_normal())
-                                .bg(THEME.background()),
-                        )
+                        .style(style().fg(THEME.text_normal()))
                         .render(columns[0], buf);
                     Paragraph::new(column_1)
-                        .style(
-                            Style::default()
-                                .fg(THEME.text_normal())
-                                .bg(THEME.background()),
-                        )
+                        .style(style().fg(THEME.text_normal()))
                         .render(columns[1], buf);
                 }
             }
diff --git a/src/widget/stock.rs b/src/widget/stock.rs
index 4dcac07..a2b8319 100644
--- a/src/widget/stock.rs
+++ b/src/widget/stock.rs
@@ -2,7 +2,7 @@ use std::hash::{Hash, Hasher};
 
 use tui::buffer::Buffer;
 use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
-use tui::style::{Modifier, Style};
+use tui::style::Modifier;
 use tui::text::{Span, Spans};
 use tui::widgets::{Block, Borders, Paragraph, StatefulWidget, Tabs, Widget, Wrap};
 
@@ -12,6 +12,7 @@ use crate::api::model::{ChartMeta, CompanyData};
 use crate::common::*;
 use crate::draw::{add_padding, PaddingDirection};
 use crate::service::{self, Service};
+use crate::theme::style;
 use crate::{
     CHART_TYPE, DEFAULT_TIMESTAMPS, ENABLE_PRE_POST, HIDE_PREV_CLOSE, HIDE_TOGGLE, SHOW_VOLUMES,
     SHOW_X_LABELS, THEME, TIME_FRAME, TRUNC_PRE,
@@ -424,7 +425,7 @@ impl StockState {
                 labels.push(chunk.get(0).map_or(Span::raw("".to_string()), |d| {
                     Span::styled(
                         self.time_frame.format_time(*d),
-                        Style::default().fg(THEME.text_normal()),
+                        style().fg(THEME.text_normal()),
                     )
                 }));
             }
@@ -435,7 +436,7 @@ impl StockState {
                     .map_or(Span::raw("".to_string()), |d| {
                         Span::styled(
                             self.time_frame.format_time(*d),
-                            Style::default().fg(THEME.text_normal()),
+                            style().fg(THEME.text_normal()),
                         )
                     }),
             );
@@ -451,18 +452,12 @@ impl StockState {
     pub fn y_labels(&self, min: f64, max: f64) -> Vec<Span> {
         if self.loaded() {
             vec![
-                Span::styled(
-                    format!("{:>8.2}", min),
-                    Style::default().fg(THEME.text_normal()),
-                ),
+                Span::styled(format!("{:>8.2}", min), style().fg(THEME.text_normal())),
                 Span::styled(
                     format!("{:>8.2}", (min + max) / 2.0),
-                    Style::default().fg(THEME.text_normal()),
-                ),
-                Span::styled(
-                    format!("{:>8.2}", max),
-                    Style::default().fg(THEME.text_normal()),
+                    style().fg(THEME.text_normal()),
                 ),
+                Span::styled(format!("{:>8.2}", max), style().fg(THEME.text_normal())),
             ]
         } else {
             vec![
@@ -606,14 +601,14 @@ impl CachableWidget<StockState> for StockWidget {
 
             let company_info = vec![
                 Spans::from(vec![
-                    Span::styled("c: ", Style::default()),
+                    Span::styled("c: ", style()),
                     Span::styled(
                         if loaded {
                             format!("{:.2} {}", state.current_price(), currency)
                         } else {
                             "".to_string()
                         },
-                        Style::default()
+                        style()
                             .add_modifier(Modifier::BOLD)
                             .fg(THEME.text_primary()),
                     ),
@@ -623,7 +618,7 @@ impl CachableWidget<StockState> for StockWidget {
                         } else {
                             "".to_string()
                         },
-                        Style::default()
+                        style()
                             .add_modifier(Modifier::BOLD)
                             .fg(if pct_change >= 0.0 {
                                 THEME.profit()
@@ -633,43 +628,39 @@ impl CachableWidget<StockState> for StockWidget {
                     ),
                 ]),
                 Spans::from(vec![
-                    Span::styled("h: ", Style::default()),
+                    Span::styled("h: ", style()),
                     Span::styled(
                         if loaded {
                             format!("{:.2}", high)
                         } else {
                             "".to_string()
                         },
-                        Style::default().fg(THEME.text_secondary()),
+                        style().fg(THEME.text_secondary()),
                     ),
                 ]),
                 Spans::from(vec![
-                    Span::styled("l: ", Style::default()),
+                    Span::styled("l: ", style()),
                     Span::styled(
                         if loaded {
                             format!("{:.2}", low)
                         } else {
                             "".to_string()
                         },
-                        Style::default().fg(THEME.text_secondary()),
+                        style().fg(THEME.text_secondary()),
                     ),
                 ]),
                 Spans::default(),
                 Spans::from(vec![
-                    Span::styled("v: ", Style::default()),
+                    Span::styled("v: ", style()),
                     Span::styled(
                         if loaded { vol } else { "".to_string() },
-                        Style::default().fg(THEME.text_secondary()),
+                        style().fg(THEME.text_secondary()),
                     ),
                 ]),
             ];
 
             Paragraph::new(company_info)
-                .style(
-                    Style::default()
-                        .fg(THEME.text_normal())
-                        .bg(THEME.background()),
-                )
+                .style(style().fg(THEME.text_normal()))
                 .alignment(Alignment::Left)
                 .wrap(Wrap { trim: true })
                 .render(info_chunks[0], buf);
@@ -690,8 +681,7 @@ impl CachableWidget<StockState> for StockWidget {
                     ])
                     .split(info_chunks[1]);
 
-                let mut left_info =
-                    vec![Spans::from(Span::styled("Summary  's'", Style::default()))];
+                let mut left_info = vec![Spans::from(Span::styled("Summary  's'", style()))];
                 let mut right_info = vec![];
 
                 if loaded {
@@ -704,12 +694,12 @@ impl CachableWidget<StockState> for StockWidget {
                                 "Line"
                             }
                         ),
-                        Style::default(),
+                        style(),
                     )));
 
                     left_info.push(Spans::from(Span::styled(
                         "Volumes  'v'",
-                        Style::default().bg(if show_volumes {
+                        style().bg(if show_volumes {
                             THEME.highlight_unfocused()
                         } else {
                             THEME.background()
@@ -718,7 +708,7 @@ impl CachableWidget<StockState> for StockWidget {
 
                     left_info.push(Spans::from(Span::styled(
                         "X Labels 'x'",
-                        Style::default().bg(if show_x_labels {
+                        style().bg(if show_x_labels {
                             THEME.highlight_unfocused()
                         } else {
                             THEME.background()
@@ -727,7 +717,7 @@ impl CachableWidget<StockState> for StockWidget {
 
                     right_info.push(Spans::from(Span::styled(
                         "Pre Post 'p'",
-                        Style::default().bg(if enable_pre_post {
+                        style().bg(if enable_pre_post {
                             THEME.highlight_unfocused()
                         } else {
                             THEME.background()
@@ -738,7 +728,7 @@ impl CachableWidget<StockState> for StockWidget {
                 if state.options_enabled() && loaded {
                     right_info.push(Spans::from(Span::styled(
                         "Options  'o'",
-                        Style::default().bg(if state.show_options {
+                        style().bg(if state.show_options {
                             THEME.highlight_unfocused()
                         } else {
                             THEME.background()
@@ -747,20 +737,12 @@ impl CachableWidget<StockState> for StockWidget {
                 }
 
                 Paragraph::new(left_info)
-                    .style(
-                        Style::default()
-                            .fg(THEME.text_normal())
-                            .bg(THEME.background()),
-                    )
+                    .style(style().fg(THEME.text_normal()))
                     .alignment(Alignment::Left)
                     .render(toggle_chunks[0], buf);
 
                 Paragraph::new(right_info)
-                    .style(
-                        Style::default()
-                            .fg(THEME.text_normal())
-                            .bg(THEME.background()),
-                    )
+                    .style(style().fg(THEME.text_normal()))
                     .alignment(Alignment::Left)
                     .render(toggle_chunks[2], buf);
             }
@@ -821,15 +803,13 @@ impl CachableWidget<StockState> for StockWidget {
 
             Tabs::new(tab_names)
                 .block(
-                    Block::default().borders(Borders::TOP).border_style(
-                        Style::default()
-                            .fg(THEME.border_secondary())
-                            .bg(THEME.background()),
-                    ),
+                    Block::default()
+                        .borders(Borders::TOP)
+                        .border_style(style().fg(THEME.border_secondary())),
                 )
                 .select(state.time_frame.idx())
-                .style(Style::default().fg(THEME.text_secondary()))
-                .highlight_style(Style::default().fg(THEME.text_primary()))
+                .style(style().fg(THEME.text_secondary()))
+                .highlight_style(style().fg(THEME.text_primary()))
                 .render(chunks[2], buf);
         }
     }
diff --git a/src/widget/stock_summary.rs b/src/widget/stock_summary.rs
index 841166c..655c184 100644
--- a/src/widget/stock_summary.rs
+++ b/src/widget/stock_summary.rs
@@ -1,6 +1,6 @@
 use tui::buffer::Buffer;
 use tui::layout::{Alignment, Constraint, Direction, Layout, Rect};
-use tui::style::{Modifier, Style};
+use tui::style::Modifier;
 use tui::text::{Span, Spans};
 use tui::widgets::{Block, Borders, Paragraph, StatefulWidget, Widget};
 
@@ -9,6 +9,7 @@ use super::stock::StockState;
 use super::{CachableWidget, CacheState};
 use crate::common::ChartType;
 use crate::draw::{add_padding, PaddingDirection};
+use crate::theme::style;
 use crate::{CHART_TYPE, ENABLE_PRE_POST, SHOW_VOLUMES, THEME};
 
 pub struct StockSummaryWidget {}
@@ -66,14 +67,10 @@ impl CachableWidget<StockState> for StockSummaryWidget {
                         format!("{:<4}", loading_indicator)
                     }
                 ),
-                Style::default().fg(THEME.text_normal()),
+                style().fg(THEME.text_normal()),
             ))
             .borders(Borders::TOP)
-            .border_style(
-                Style::default()
-                    .fg(THEME.border_secondary())
-                    .bg(THEME.background()),
-            )
+            .border_style(style().fg(THEME.border_secondary()))
             .render(area, buf);
         area = add_padding(area, 1, PaddingDirection::Top);
 
@@ -91,46 +88,46 @@ impl CachableWidget<StockState> for StockSummaryWidget {
 
             let prices = vec![
                 Spans::from(vec![
-                    Span::styled("c: ", Style::default().fg(THEME.text_normal())),
+                    Span::styled("c: ", style().fg(THEME.text_normal())),
                     Span::styled(
                         if loaded {
                             format!("{:.2} {}", state.current_price(), currency)
                         } else {
                             "".to_string()
                         },
-                        Style::default()
+                        style()
                             .add_modifier(Modifier::BOLD)
                             .fg(THEME.text_primary()),
                     ),
                 ]),
                 Spans::from(vec![
-                    Span::styled("h: ", Style::default().fg(THEME.text_normal())),
+                    Span::styled("h: ", style().fg(THEME.text_normal())),
                     Span::styled(
                         if loaded {
                             format!("{:.2}", high)
                         } else {
                             "".to_string()
                         },
-                        Style::default().fg(THEME.text_secondary()),
+                        style().fg(THEME.text_secondary()),
                     ),
                 ]),
                 Spans::from(vec![
-                    Span::styled("l: ", Style::default().fg(THEME.text_normal())),
+                    Span::styled("l: ", style().fg(THEME.text_normal())),
                     Span::styled(
                         if loaded {
                             format!("{:.2}", low)
                         } else {
                             "".to_string()
                         },
-                        Style::default().fg(THEME.text_secondary()),
+                        style().fg(THEME.text_secondary()),
                     ),
                 ]),
                 Spans::default(),
                 Spans::from(vec![
-                    Span::styled("v: ", Style::default().fg(THEME.text_normal())),
+                    Span::styled("v: ", style().fg(THEME.text_normal())),
                     Span::styled(
                         if loaded { vol } else { "".to_string() },
-                        Style::default().fg(THEME.text_secondary()),
+                        style().fg(THEME.text_secondary()),
                     ),
                 ]),
             ];
@@ -141,7 +138,7 @@ impl CachableWidget<StockState> for StockSummaryWidget {
                 } else {
                     "".to_string()
                 },
-                Style::default()
+                style()
                     .add_modifier(Modifier::BOLD)
                     .fg(if pct_change >= 0.0 {
                         THEME.profit()
@@ -151,12 +148,12 @@ impl CachableWidget<StockState> for StockSummaryWidget {
             )];
 
             Paragraph::new(prices)
-                .style(Style::default().bg(THEME.background()))
+                .style(style())
                 .alignment(Alignment::Left)
                 .render(layout[0], buf);
 
             Paragraph::new(Spans::from(pct))
-                .style(Style::default().bg(THEME.background()))
+                .style(style())
                 .alignment(Alignment::Right)
                 .render(layout[0], buf);
         }


Test patch: