Skip to content
This repository has been archived by the owner on Aug 6, 2023. It is now read-only.

Commit

Permalink
feat!(widgets/canvas): use spans for text of labels
Browse files Browse the repository at this point in the history
  • Loading branch information
fdehau committed Oct 17, 2021
1 parent 8c1f580 commit ca68bae
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 19 deletions.
9 changes: 7 additions & 2 deletions examples/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -103,7 +104,11 @@ fn main() -> Result<(), Box<dyn Error>> {
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]);
Expand Down
6 changes: 5 additions & 1 deletion examples/demo/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
33 changes: 17 additions & 16 deletions src/widgets/canvas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
layout::Rect,
style::{Color, Style},
symbols,
text::Spans,
widgets::{Block, Widget},
};
use std::fmt::Debug;
Expand All @@ -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)]
Expand Down Expand Up @@ -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<T>(&mut self, x: f64, y: f64, spans: T)
where
T: Into<Spans<'a>>,
{
self.labels.push(Label {
x,
y,
spans: spans.into(),
});
}

/// Push the last layer if necessary
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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];
Expand All @@ -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);
}
}
}
42 changes: 42 additions & 0 deletions tests/widgets_canvas.rs
Original file line number Diff line number Diff line change
@@ -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)
}

0 comments on commit ca68bae

Please sign in to comment.