From ca68bae4edc7558d02e0d4aa794febfe3888dfdc Mon Sep 17 00:00:00 2001 From: Florian Dehau Date: Sun, 17 Oct 2021 18:44:00 +0200 Subject: [PATCH] feat!(widgets/canvas): use spans for text of labels --- examples/canvas.rs | 9 +++++++-- examples/demo/ui.rs | 6 +++++- src/widgets/canvas/mod.rs | 33 +++++++++++++++--------------- tests/widgets_canvas.rs | 42 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 tests/widgets_canvas.rs diff --git a/examples/canvas.rs b/examples/canvas.rs index 6f5ef59..f3cb380 100644 --- a/examples/canvas.rs +++ b/examples/canvas.rs @@ -7,7 +7,8 @@ use termion::{event::Key, input::MouseTerminal, raw::IntoRawMode, screen::Altern use tui::{ backend::TermionBackend, layout::{Constraint, Direction, Layout, Rect}, - style::Color, + style::{Color, Style}, + text::Span, widgets::{ canvas::{Canvas, Map, MapResolution, Rectangle}, Block, Borders, @@ -103,7 +104,11 @@ fn main() -> Result<(), Box> { color: Color::White, resolution: MapResolution::High, }); - ctx.print(app.x, -app.y, "You are here", Color::Yellow); + ctx.print( + app.x, + -app.y, + Span::styled("You are here", Style::default().fg(Color::Yellow)), + ); }) .x_bounds([-180.0, 180.0]) .y_bounds([-90.0, 90.0]); diff --git a/examples/demo/ui.rs b/examples/demo/ui.rs index e5664c0..96d4642 100644 --- a/examples/demo/ui.rs +++ b/examples/demo/ui.rs @@ -363,7 +363,11 @@ where } else { Color::Red }; - ctx.print(server.coords.1, server.coords.0, "X", color); + ctx.print( + server.coords.1, + server.coords.0, + Span::styled("X", Style::default().fg(color)), + ); } }) .marker(if app.enhanced_graphics { diff --git a/src/widgets/canvas/mod.rs b/src/widgets/canvas/mod.rs index 48e2240..be23ee6 100644 --- a/src/widgets/canvas/mod.rs +++ b/src/widgets/canvas/mod.rs @@ -14,6 +14,7 @@ use crate::{ layout::Rect, style::{Color, Style}, symbols, + text::Spans, widgets::{Block, Widget}, }; use std::fmt::Debug; @@ -26,10 +27,9 @@ pub trait Shape { /// Label to draw some text on the canvas #[derive(Debug, Clone)] pub struct Label<'a> { - pub x: f64, - pub y: f64, - pub text: &'a str, - pub color: Color, + x: f64, + y: f64, + spans: Spans<'a>, } #[derive(Debug, Clone)] @@ -293,8 +293,15 @@ impl<'a> Context<'a> { } /// Print a string on the canvas at the given position - pub fn print(&mut self, x: f64, y: f64, text: &'a str, color: Color) { - self.labels.push(Label { x, y, text, color }); + pub fn print(&mut self, x: f64, y: f64, spans: T) + where + T: Into>, + { + self.labels.push(Label { + x, + y, + spans: spans.into(), + }); } /// Push the last layer if necessary @@ -433,6 +440,8 @@ where None => area, }; + buf.set_style(canvas_area, Style::default().bg(self.background_color)); + let width = canvas_area.width as usize; let painter = match self.painter { @@ -464,14 +473,12 @@ where let (x, y) = (i % width, i / width); buf.get_mut(x as u16 + canvas_area.left(), y as u16 + canvas_area.top()) .set_char(ch) - .set_fg(color) - .set_bg(self.background_color); + .set_fg(color); } } } // Finally draw the labels - let style = Style::default().bg(self.background_color); let left = self.x_bounds[0]; let right = self.x_bounds[1]; let top = self.y_bounds[1]; @@ -490,13 +497,7 @@ where { let x = ((label.x - left) * resolution.0 / width) as u16 + canvas_area.left(); let y = ((top - label.y) * resolution.1 / height) as u16 + canvas_area.top(); - buf.set_stringn( - x, - y, - label.text, - (canvas_area.right() - x) as usize, - style.fg(label.color), - ); + buf.set_spans(x, y, &label.spans, canvas_area.right() - x); } } } diff --git a/tests/widgets_canvas.rs b/tests/widgets_canvas.rs new file mode 100644 index 0000000..f85f0d4 --- /dev/null +++ b/tests/widgets_canvas.rs @@ -0,0 +1,42 @@ +use tui::{ + backend::TestBackend, + buffer::Buffer, + style::{Color, Style}, + text::Span, + widgets::canvas::Canvas, + Terminal, +}; + +#[test] +fn widgets_canvas_draw_labels() { + let backend = TestBackend::new(5, 5); + let mut terminal = Terminal::new(backend).unwrap(); + terminal + .draw(|f| { + let label = String::from("test"); + let canvas = Canvas::default() + .background_color(Color::Yellow) + .x_bounds([0.0, 5.0]) + .y_bounds([0.0, 5.0]) + .paint(|ctx| { + ctx.print( + 0.0, + 0.0, + Span::styled(label.clone(), Style::default().fg(Color::Blue)), + ); + }); + f.render_widget(canvas, f.size()); + }) + .unwrap(); + + let mut expected = Buffer::with_lines(vec![" ", " ", " ", " ", "test "]); + for row in 0..5 { + for col in 0..5 { + expected.get_mut(col, row).set_bg(Color::Yellow); + } + } + for col in 0..4 { + expected.get_mut(col, 4).set_fg(Color::Blue); + } + terminal.backend().assert_buffer(&expected) +}