Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,38 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
style="max-width: 640px"/>
</div>

### Color theme

Colors can be remapped using `color_theme` on `EmbeddedBackendConfig`.
By default the ANSI palette is used.

```rust,ignore
use mousefood::{ColorTheme, EmbeddedBackend, EmbeddedBackendConfig};
use mousefood::embedded_graphics::pixelcolor::Rgb888;

let theme = ColorTheme {
background: Rgb888::new(5, 5, 5),
foreground: Rgb888::new(240, 240, 240),
yellow: Rgb888::new(255, 200, 0),
..ColorTheme::ansi()
};

let config = EmbeddedBackendConfig {
color_theme: theme,
..Default::default()
};
let backend = EmbeddedBackend::new(&mut display, config);
```

#### Built-in themes

Mousefood includes popular color themes that can be used directly.

Available themes:

- `ColorTheme::ansi()` - Standard ANSI colors (default)
- `ColorTheme::tokionight()` - Tokyo Night dark theme with blue/purple tones

### Simulator

Mousefood can be run in a simulator using
Expand Down
38 changes: 31 additions & 7 deletions mousefood/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ where
/// Determines how the view is horizontally aligned when the display width
/// is not an exact multiple of the font width.
pub horizontal_alignment: TerminalAlignment,

/// Color theme that maps Ratatui colors to display pixels.
pub color_theme: ColorTheme,
}

impl<D, C> Default for EmbeddedBackendConfig<D, C>
Expand All @@ -61,6 +64,7 @@ where
font_italic: None,
vertical_alignment: TerminalAlignment::Start,
horizontal_alignment: TerminalAlignment::Start,
color_theme: ColorTheme::default(),
}
}
}
Expand Down Expand Up @@ -111,12 +115,13 @@ where

columns_rows: layout::Size,
pixels: layout::Size,
color_theme: ColorTheme,
}

impl<'display, D, C> EmbeddedBackend<'display, D, C>
where
D: DrawTarget<Color = C> + Dimensions + 'static,
C: PixelColor + Into<Rgb888> + From<Rgb888> + From<TermColor> + 'static,
C: PixelColor + Into<Rgb888> + From<Rgb888> + for<'a> From<TermColor<'a>> + 'static,
{
fn init(
display: &'display mut D,
Expand All @@ -126,6 +131,7 @@ where
font_italic: Option<MonoFont<'static>>,
vertical_alignment: TerminalAlignment,
horizontal_alignment: TerminalAlignment,
color_theme: ColorTheme,
) -> EmbeddedBackend<'display, D, C> {
let pixels = layout::Size {
width: display.bounding_box().size.width as u16,
Expand All @@ -150,7 +156,7 @@ where

Self {
#[cfg(feature = "framebuffer")]
buffer: crate::framebuffer::HeapBuffer::new(display.bounding_box()),
buffer: crate::framebuffer::HeapBuffer::new(display.bounding_box(), color_theme),
display,
display_type: PhantomData,
flush_callback: Box::new(flush_callback),
Expand All @@ -163,6 +169,7 @@ where
width: pixels.width / font_regular.character_size.width as u16,
},
pixels,
color_theme,
}
}

Expand All @@ -179,6 +186,7 @@ where
config.font_italic,
config.vertical_alignment,
config.horizontal_alignment,
config.color_theme,
)
}

Expand All @@ -198,7 +206,7 @@ type Result<T, E = crate::error::Error> = core::result::Result<T, E>;
impl<D, C> Backend for EmbeddedBackend<'_, D, C>
where
D: DrawTarget<Color = C> + 'static,
C: PixelColor + Into<Rgb888> + From<Rgb888> + From<TermColor> + 'static,
C: PixelColor + Into<Rgb888> + From<Rgb888> + for<'a> From<TermColor<'a>> + 'static,
{
type Error = crate::error::Error;

Expand All @@ -214,8 +222,12 @@ where

let mut style_builder = MonoTextStyleBuilder::new()
.font(&self.font_regular)
.text_color(TermColor(cell.fg, TermColorType::Foreground).into())
.background_color(TermColor(cell.bg, TermColorType::Background).into());
.text_color(
TermColor::new(cell.fg, TermColorType::Foreground, &self.color_theme).into(),
)
.background_color(
TermColor::new(cell.bg, TermColorType::Background, &self.color_theme).into(),
);

for modifier in cell.modifier.iter() {
style_builder = match modifier {
Expand All @@ -240,7 +252,12 @@ where

if cell.underline_color != style::Color::Reset {
style_builder = style_builder.underline_with_color(
TermColor(cell.underline_color, TermColorType::Foreground).into(),
TermColor::new(
cell.underline_color,
TermColorType::Foreground,
&self.color_theme,
)
.into(),
);
}

Expand Down Expand Up @@ -287,7 +304,14 @@ where
#[cfg(feature = "framebuffer")]
fn clear(&mut self) -> Result<()> {
self.buffer
.clear(TermColor(style::Color::Reset, TermColorType::Background).into())
.clear(
TermColor::new(
style::Color::Reset,
TermColorType::Background,
&self.color_theme,
)
.into(),
)
.map_err(|_| crate::error::Error::DrawError)
}

Expand Down
Loading
Loading