mirror of
https://github.com/ratatui/ratatui.git
synced 2025-10-02 15:25:54 +00:00
Simpler layout and cleanup api
This commit is contained in:
parent
b411690fdd
commit
ea485b5439
@ -23,7 +23,7 @@ use log4rs::config::{Appender, Config, Root};
|
|||||||
use tui::Terminal;
|
use tui::Terminal;
|
||||||
use tui::widgets::{Widget, Block, List, Gauge, Sparkline, Text, border, Chart, Axis, Dataset,
|
use tui::widgets::{Widget, Block, List, Gauge, Sparkline, Text, border, Chart, Axis, Dataset,
|
||||||
BarChart};
|
BarChart};
|
||||||
use tui::layout::{Group, Direction, Alignment, Size};
|
use tui::layout::{Group, Direction, Size};
|
||||||
use tui::style::Color;
|
use tui::style::Color;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -234,44 +234,41 @@ fn draw(t: &mut Terminal, app: &App) {
|
|||||||
|
|
||||||
Group::default()
|
Group::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.alignment(Alignment::Left)
|
.sizes(&[Size::Fixed(7), Size::Min(7), Size::Fixed(7)])
|
||||||
.chunks(&[Size::Fixed(7), Size::Min(5), Size::Fixed(7)])
|
|
||||||
.render(t, &size, |t, chunks| {
|
.render(t, &size, |t, chunks| {
|
||||||
Block::default().borders(border::ALL).title("Graphs").render(&chunks[0], t);
|
Block::default().borders(border::ALL).title("Graphs").render(&chunks[0], t);
|
||||||
Group::default()
|
Group::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.alignment(Alignment::Left)
|
|
||||||
.margin(1)
|
.margin(1)
|
||||||
.chunks(&[Size::Fixed(2), Size::Fixed(3)])
|
.sizes(&[Size::Fixed(2), Size::Fixed(3)])
|
||||||
.render(t, &chunks[0], |t, chunks| {
|
.render(t, &chunks[0], |t, chunks| {
|
||||||
Gauge::default()
|
Gauge::default()
|
||||||
.block(Block::default().title("Gauge:"))
|
.block(Block::default().title("Gauge:"))
|
||||||
.bg(Color::Magenta)
|
.background_color(Color::Magenta)
|
||||||
.percent(app.progress)
|
.percent(app.progress)
|
||||||
.render(&chunks[0], t);
|
.render(&chunks[0], t);
|
||||||
Sparkline::default()
|
Sparkline::default()
|
||||||
.block(Block::default().title("Sparkline:"))
|
.block(Block::default().title("Sparkline:"))
|
||||||
.fg(Color::Green)
|
.color(Color::Green)
|
||||||
.data(&app.data)
|
.data(&app.data)
|
||||||
.render(&chunks[1], t);
|
.render(&chunks[1], t);
|
||||||
});
|
});
|
||||||
let sizes = if app.show_chart {
|
let sizes = if app.show_chart {
|
||||||
vec![Size::Max(40), Size::Min(20)]
|
vec![Size::Percent(50), Size::Percent(50)]
|
||||||
} else {
|
} else {
|
||||||
vec![Size::Max(40)]
|
vec![Size::Percent(100)]
|
||||||
};
|
};
|
||||||
Group::default()
|
Group::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.alignment(Alignment::Left)
|
.sizes(&sizes)
|
||||||
.chunks(&sizes)
|
|
||||||
.render(t, &chunks[1], |t, chunks| {
|
.render(t, &chunks[1], |t, chunks| {
|
||||||
Group::default()
|
Group::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.chunks(&[Size::Min(20), Size::Max(40)])
|
.sizes(&[Size::Percent(50), Size::Percent(50)])
|
||||||
.render(t, &chunks[0], |t, chunks| {
|
.render(t, &chunks[0], |t, chunks| {
|
||||||
Group::default()
|
Group::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.chunks(&[Size::Max(20), Size::Min(0)])
|
.sizes(&[Size::Percent(50), Size::Percent(50)])
|
||||||
.render(t, &chunks[0], |t, chunks| {
|
.render(t, &chunks[0], |t, chunks| {
|
||||||
List::default()
|
List::default()
|
||||||
.block(Block::default().borders(border::ALL).title("List"))
|
.block(Block::default().borders(border::ALL).title("List"))
|
||||||
|
109
src/layout.rs
109
src/layout.rs
@ -3,21 +3,12 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use cassowary::{Solver, Variable, Constraint};
|
use cassowary::{Solver, Variable, Constraint};
|
||||||
use cassowary::WeightedRelation::*;
|
use cassowary::WeightedRelation::*;
|
||||||
use cassowary::strength::{WEAK, REQUIRED};
|
use cassowary::strength::{REQUIRED, WEAK};
|
||||||
|
|
||||||
use terminal::Terminal;
|
use terminal::Terminal;
|
||||||
use util::hash;
|
use util::hash;
|
||||||
|
|
||||||
#[derive(Hash)]
|
#[derive(Hash, PartialEq)]
|
||||||
pub enum Alignment {
|
|
||||||
Top,
|
|
||||||
Left,
|
|
||||||
Center,
|
|
||||||
Bottom,
|
|
||||||
Right,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Hash)]
|
|
||||||
pub enum Direction {
|
pub enum Direction {
|
||||||
Horizontal,
|
Horizontal,
|
||||||
Vertical,
|
Vertical,
|
||||||
@ -104,6 +95,7 @@ impl Rect {
|
|||||||
#[derive(Debug, Clone, Hash)]
|
#[derive(Debug, Clone, Hash)]
|
||||||
pub enum Size {
|
pub enum Size {
|
||||||
Fixed(u16),
|
Fixed(u16),
|
||||||
|
Percent(u16),
|
||||||
Max(u16),
|
Max(u16),
|
||||||
Min(u16),
|
Min(u16),
|
||||||
}
|
}
|
||||||
@ -123,12 +115,7 @@ pub enum Size {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn split(area: &Rect,
|
pub fn split(area: &Rect, dir: &Direction, margin: u16, sizes: &[Size]) -> Vec<Rect> {
|
||||||
dir: &Direction,
|
|
||||||
align: &Alignment,
|
|
||||||
margin: u16,
|
|
||||||
sizes: &[Size])
|
|
||||||
-> Vec<Rect> {
|
|
||||||
let mut solver = Solver::new();
|
let mut solver = Solver::new();
|
||||||
let mut vars: HashMap<Variable, (usize, usize)> = HashMap::new();
|
let mut vars: HashMap<Variable, (usize, usize)> = HashMap::new();
|
||||||
let elements = sizes.iter().map(|_| Element::new()).collect::<Vec<Element>>();
|
let elements = sizes.iter().map(|_| Element::new()).collect::<Vec<Element>>();
|
||||||
@ -145,15 +132,15 @@ pub fn split(area: &Rect,
|
|||||||
constraints.push(match *dir {
|
constraints.push(match *dir {
|
||||||
Direction::Horizontal => first.x | EQ(REQUIRED) | dest_area.x as f64,
|
Direction::Horizontal => first.x | EQ(REQUIRED) | dest_area.x as f64,
|
||||||
Direction::Vertical => first.y | EQ(REQUIRED) | dest_area.y as f64,
|
Direction::Vertical => first.y | EQ(REQUIRED) | dest_area.y as f64,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
if let Some(last) = elements.last() {
|
if let Some(last) = elements.last() {
|
||||||
constraints.push(match *dir {
|
constraints.push(match *dir {
|
||||||
Direction::Horizontal => {
|
Direction::Horizontal => {
|
||||||
(last.x + last.width) | EQ(WEAK) | (dest_area.x + dest_area.width) as f64
|
(last.x + last.width) | EQ(REQUIRED) | (dest_area.x + dest_area.width) as f64
|
||||||
}
|
}
|
||||||
Direction::Vertical => {
|
Direction::Vertical => {
|
||||||
(last.y + last.height) | EQ(WEAK) | (dest_area.y + dest_area.height) as f64
|
(last.y + last.height) | EQ(REQUIRED) | (dest_area.y + dest_area.height) as f64
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -163,14 +150,16 @@ pub fn split(area: &Rect,
|
|||||||
constraints.push((pair[0].x + pair[0].width) | EQ(REQUIRED) | pair[1].x);
|
constraints.push((pair[0].x + pair[0].width) | EQ(REQUIRED) | pair[1].x);
|
||||||
}
|
}
|
||||||
for (i, size) in sizes.iter().enumerate() {
|
for (i, size) in sizes.iter().enumerate() {
|
||||||
let cs = [elements[i].y | EQ(REQUIRED) | dest_area.y as f64,
|
constraints.push(elements[i].y | EQ(REQUIRED) | dest_area.y as f64);
|
||||||
elements[i].height | EQ(REQUIRED) | dest_area.height as f64,
|
constraints.push(elements[i].height | EQ(REQUIRED) | dest_area.height as f64);
|
||||||
match *size {
|
constraints.push(match *size {
|
||||||
Size::Fixed(v) => elements[i].width | EQ(REQUIRED) | v as f64,
|
Size::Fixed(v) => elements[i].width | EQ(WEAK) | v as f64,
|
||||||
Size::Min(v) => elements[i].width | GE(REQUIRED) | v as f64,
|
Size::Percent(v) => {
|
||||||
Size::Max(v) => elements[i].width | LE(REQUIRED) | v as f64,
|
elements[i].width | EQ(WEAK) | ((v * dest_area.width) as f64 / 100.0)
|
||||||
}];
|
}
|
||||||
constraints.extend_from_slice(&cs);
|
Size::Min(v) => elements[i].width | GE(WEAK) | v as f64,
|
||||||
|
Size::Max(v) => elements[i].width | LE(WEAK) | v as f64,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Direction::Vertical => {
|
Direction::Vertical => {
|
||||||
@ -178,14 +167,16 @@ pub fn split(area: &Rect,
|
|||||||
constraints.push((pair[0].y + pair[0].height) | EQ(REQUIRED) | pair[1].y);
|
constraints.push((pair[0].y + pair[0].height) | EQ(REQUIRED) | pair[1].y);
|
||||||
}
|
}
|
||||||
for (i, size) in sizes.iter().enumerate() {
|
for (i, size) in sizes.iter().enumerate() {
|
||||||
let cs = [elements[i].x | EQ(REQUIRED) | dest_area.x as f64,
|
constraints.push(elements[i].x | EQ(REQUIRED) | dest_area.x as f64);
|
||||||
elements[i].width | EQ(REQUIRED) | dest_area.width as f64,
|
constraints.push(elements[i].width | EQ(REQUIRED) | dest_area.width as f64);
|
||||||
match *size {
|
constraints.push(match *size {
|
||||||
Size::Fixed(v) => elements[i].height | EQ(REQUIRED) | v as f64,
|
Size::Fixed(v) => elements[i].height | EQ(WEAK) | v as f64,
|
||||||
Size::Min(v) => elements[i].height | GE(REQUIRED) | v as f64,
|
Size::Percent(v) => {
|
||||||
Size::Max(v) => elements[i].height | LE(REQUIRED) | v as f64,
|
elements[i].height | EQ(WEAK) | ((v * dest_area.height) as f64 / 100.0)
|
||||||
}];
|
}
|
||||||
constraints.extend_from_slice(&cs);
|
Size::Min(v) => elements[i].height | GE(WEAK) | v as f64,
|
||||||
|
Size::Max(v) => elements[i].height | LE(WEAK) | v as f64,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,30 +184,32 @@ pub fn split(area: &Rect,
|
|||||||
// TODO: Find a better way to handle overflow error
|
// TODO: Find a better way to handle overflow error
|
||||||
for &(var, value) in solver.fetch_changes() {
|
for &(var, value) in solver.fetch_changes() {
|
||||||
let (index, attr) = vars[&var];
|
let (index, attr) = vars[&var];
|
||||||
|
let value = value as u16;
|
||||||
match attr {
|
match attr {
|
||||||
0 => {
|
0 => {
|
||||||
results[index].x = value as u16;
|
if value <= area.width {
|
||||||
|
results[index].x = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
1 => {
|
1 => {
|
||||||
results[index].y = value as u16;
|
if value <= area.height {
|
||||||
|
results[index].y = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
let mut v = value as u16;
|
if value <= area.width {
|
||||||
if v > area.width {
|
results[index].width = value;
|
||||||
v = 0;
|
|
||||||
}
|
}
|
||||||
results[index].width = v;
|
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
let mut v = value as u16;
|
if value <= area.height {
|
||||||
if v > area.height {
|
results[index].height = value;
|
||||||
v = 0;
|
|
||||||
}
|
}
|
||||||
results[index].height = v;
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
info!("{:?}, {:?}", results, dest_area);
|
||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,18 +234,16 @@ impl Element {
|
|||||||
#[derive(Hash)]
|
#[derive(Hash)]
|
||||||
pub struct Group {
|
pub struct Group {
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
alignment: Alignment,
|
|
||||||
margin: u16,
|
margin: u16,
|
||||||
chunks: Vec<Size>,
|
sizes: Vec<Size>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Group {
|
impl Default for Group {
|
||||||
fn default() -> Group {
|
fn default() -> Group {
|
||||||
Group {
|
Group {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
alignment: Alignment::Left,
|
|
||||||
margin: 0,
|
margin: 0,
|
||||||
chunks: Vec::new(),
|
sizes: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,18 +254,13 @@ impl Group {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alignment(&mut self, alignment: Alignment) -> &mut Group {
|
|
||||||
self.alignment = alignment;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn margin(&mut self, margin: u16) -> &mut Group {
|
pub fn margin(&mut self, margin: u16) -> &mut Group {
|
||||||
self.margin = margin;
|
self.margin = margin;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunks(&mut self, chunks: &[Size]) -> &mut Group {
|
pub fn sizes(&mut self, sizes: &[Size]) -> &mut Group {
|
||||||
self.chunks = Vec::from(chunks);
|
self.sizes = Vec::from(sizes);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn render<F>(&self, t: &mut Terminal, area: &Rect, mut f: F)
|
pub fn render<F>(&self, t: &mut Terminal, area: &Rect, mut f: F)
|
||||||
@ -283,14 +269,7 @@ impl Group {
|
|||||||
let hash = hash(self, area);
|
let hash = hash(self, area);
|
||||||
let (cache_update, chunks) = match t.get_layout(hash) {
|
let (cache_update, chunks) = match t.get_layout(hash) {
|
||||||
Some(chs) => (false, chs.to_vec()),
|
Some(chs) => (false, chs.to_vec()),
|
||||||
None => {
|
None => (true, split(area, &self.direction, self.margin, &self.sizes)),
|
||||||
(true,
|
|
||||||
split(area,
|
|
||||||
&self.direction,
|
|
||||||
&self.alignment,
|
|
||||||
self.margin,
|
|
||||||
&self.chunks))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
f(t, &chunks);
|
f(t, &chunks);
|
||||||
|
@ -160,8 +160,11 @@ impl<'a> Chart<'a> {
|
|||||||
|
|
||||||
fn layout(&self, inner: &Rect, outer: &Rect) -> ChartLayout {
|
fn layout(&self, inner: &Rect, outer: &Rect) -> ChartLayout {
|
||||||
let mut layout = ChartLayout::default();
|
let mut layout = ChartLayout::default();
|
||||||
|
if inner.height == 0 || inner.width == 0 {
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
let mut x = inner.x - outer.x;
|
let mut x = inner.x - outer.x;
|
||||||
let mut y = inner.height - 1 + (inner.y - outer.y);
|
let mut y = inner.height + (inner.y - outer.y) - 1;
|
||||||
|
|
||||||
if self.x_axis.labels.is_some() && y > 1 {
|
if self.x_axis.labels.is_some() && y > 1 {
|
||||||
layout.label_x = Some(y);
|
layout.label_x = Some(y);
|
||||||
@ -215,6 +218,9 @@ impl<'a> Widget<'a> for Chart<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let layout = self.layout(&chart_area, area);
|
let layout = self.layout(&chart_area, area);
|
||||||
|
if layout.graph_area.width == 0 || layout.graph_area.height == 0 {
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
let width = layout.graph_area.width;
|
let width = layout.graph_area.width;
|
||||||
let height = layout.graph_area.height;
|
let height = layout.graph_area.height;
|
||||||
let margin_x = layout.graph_area.x - area.x;
|
let margin_x = layout.graph_area.x - area.x;
|
||||||
|
@ -23,8 +23,8 @@ pub struct Gauge<'a> {
|
|||||||
block: Option<Block<'a>>,
|
block: Option<Block<'a>>,
|
||||||
percent: u16,
|
percent: u16,
|
||||||
percent_string: String,
|
percent_string: String,
|
||||||
fg: Color,
|
color: Color,
|
||||||
bg: Color,
|
background_color: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for Gauge<'a> {
|
impl<'a> Default for Gauge<'a> {
|
||||||
@ -33,8 +33,8 @@ impl<'a> Default for Gauge<'a> {
|
|||||||
block: None,
|
block: None,
|
||||||
percent: 0,
|
percent: 0,
|
||||||
percent_string: String::from("0%"),
|
percent_string: String::from("0%"),
|
||||||
bg: Color::Reset,
|
color: Color::Reset,
|
||||||
fg: Color::Reset,
|
background_color: Color::Reset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,13 +51,13 @@ impl<'a> Gauge<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bg(&mut self, bg: Color) -> &mut Gauge<'a> {
|
pub fn color(&mut self, color: Color) -> &mut Gauge<'a> {
|
||||||
self.bg = bg;
|
self.color = color;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fg(&mut self, fg: Color) -> &mut Gauge<'a> {
|
pub fn background_color(&mut self, color: Color) -> &mut Gauge<'a> {
|
||||||
self.fg = fg;
|
self.background_color = color;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,15 +76,23 @@ impl<'a> Widget<'a> for Gauge<'a> {
|
|||||||
// Gauge
|
// Gauge
|
||||||
let width = (gauge_area.width * self.percent) / 100;
|
let width = (gauge_area.width * self.percent) / 100;
|
||||||
for i in 0..width {
|
for i in 0..width {
|
||||||
buf.update_cell(margin_x + i, margin_y, " ", self.fg, self.bg);
|
buf.update_cell(margin_x + i,
|
||||||
|
margin_y,
|
||||||
|
" ",
|
||||||
|
self.color,
|
||||||
|
self.background_color);
|
||||||
}
|
}
|
||||||
// Label
|
// Label
|
||||||
let len = self.percent_string.len() as u16;
|
let len = self.percent_string.len() as u16;
|
||||||
let middle = gauge_area.width / 2 - len / 2;
|
let middle = gauge_area.width / 2 - len / 2;
|
||||||
buf.set_string(middle, margin_y, &self.percent_string, self.bg, self.fg);
|
buf.set_string(middle,
|
||||||
|
margin_y,
|
||||||
|
&self.percent_string,
|
||||||
|
self.background_color,
|
||||||
|
self.color);
|
||||||
let bound = max(middle, min(middle + len, width));
|
let bound = max(middle, min(middle + len, width));
|
||||||
for i in middle..bound {
|
for i in middle..bound {
|
||||||
buf.update_colors(margin_x + i, margin_y, self.fg, self.bg);
|
buf.update_colors(margin_x + i, margin_y, self.color, self.background_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf
|
buf
|
||||||
|
@ -12,8 +12,8 @@ pub struct List<'a> {
|
|||||||
selected: usize,
|
selected: usize,
|
||||||
selection_symbol: Option<&'a str>,
|
selection_symbol: Option<&'a str>,
|
||||||
selection_color: Color,
|
selection_color: Color,
|
||||||
text_color: Color,
|
color: Color,
|
||||||
bg: Color,
|
background_color: Color,
|
||||||
items: &'a [&'a str],
|
items: &'a [&'a str],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,8 +24,8 @@ impl<'a> Default for List<'a> {
|
|||||||
selected: 0,
|
selected: 0,
|
||||||
selection_symbol: None,
|
selection_symbol: None,
|
||||||
selection_color: Color::Reset,
|
selection_color: Color::Reset,
|
||||||
text_color: Color::Reset,
|
color: Color::Reset,
|
||||||
bg: Color::Reset,
|
background_color: Color::Reset,
|
||||||
items: &[],
|
items: &[],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,13 +42,13 @@ impl<'a> List<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_color(&'a mut self, text_color: Color) -> &mut List<'a> {
|
pub fn color(&'a mut self, color: Color) -> &mut List<'a> {
|
||||||
self.text_color = text_color;
|
self.color = color;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bg(&'a mut self, bg: Color) -> &mut List<'a> {
|
pub fn background_color(&'a mut self, color: Color) -> &mut List<'a> {
|
||||||
self.bg = bg;
|
self.background_color = color;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,16 +93,16 @@ impl<'a> Widget<'a> for List<'a> {
|
|||||||
let color = if index == self.selected {
|
let color = if index == self.selected {
|
||||||
self.selection_color
|
self.selection_color
|
||||||
} else {
|
} else {
|
||||||
self.text_color
|
self.color
|
||||||
};
|
};
|
||||||
buf.set_string(x, 1 + i as u16, item, color, self.bg);
|
buf.set_string(x, 1 + i as u16, item, color, self.background_color);
|
||||||
}
|
}
|
||||||
if let Some(s) = self.selection_symbol {
|
if let Some(s) = self.selection_symbol {
|
||||||
buf.set_string(1,
|
buf.set_string(1,
|
||||||
(1 + self.selected - offset) as u16,
|
(1 + self.selected - offset) as u16,
|
||||||
s,
|
s,
|
||||||
self.selection_color,
|
self.selection_color,
|
||||||
self.bg);
|
self.background_color);
|
||||||
}
|
}
|
||||||
buf
|
buf
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@ use symbols::bar;
|
|||||||
|
|
||||||
pub struct Sparkline<'a> {
|
pub struct Sparkline<'a> {
|
||||||
block: Option<Block<'a>>,
|
block: Option<Block<'a>>,
|
||||||
fg: Color,
|
color: Color,
|
||||||
bg: Color,
|
background_color: Color,
|
||||||
data: Vec<u64>,
|
data: &'a [u64],
|
||||||
max: Option<u64>,
|
max: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,9 +18,9 @@ impl<'a> Default for Sparkline<'a> {
|
|||||||
fn default() -> Sparkline<'a> {
|
fn default() -> Sparkline<'a> {
|
||||||
Sparkline {
|
Sparkline {
|
||||||
block: None,
|
block: None,
|
||||||
fg: Color::Reset,
|
color: Color::Reset,
|
||||||
bg: Color::Reset,
|
background_color: Color::Reset,
|
||||||
data: Vec::new(),
|
data: &[],
|
||||||
max: None,
|
max: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -32,19 +32,19 @@ impl<'a> Sparkline<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fg(&mut self, fg: Color) -> &mut Sparkline<'a> {
|
pub fn color(&mut self, color: Color) -> &mut Sparkline<'a> {
|
||||||
self.fg = fg;
|
self.color = color;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bg(&mut self, bg: Color) -> &mut Sparkline<'a> {
|
pub fn background_color(&mut self, color: Color) -> &mut Sparkline<'a> {
|
||||||
self.bg = bg;
|
self.background_color = color;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn data(&mut self, data: &[u64]) -> &mut Sparkline<'a> {
|
pub fn data(&mut self, data: &'a [u64]) -> &mut Sparkline<'a> {
|
||||||
self.data = data.to_vec();
|
self.data = data;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +88,11 @@ impl<'a> Widget<'a> for Sparkline<'a> {
|
|||||||
7 => bar::SEVEN_EIGHTHS,
|
7 => bar::SEVEN_EIGHTHS,
|
||||||
_ => bar::FULL,
|
_ => bar::FULL,
|
||||||
};
|
};
|
||||||
buf.update_cell(margin_x + i as u16, margin_y + j, symbol, self.fg, self.bg);
|
buf.update_cell(margin_x + i as u16,
|
||||||
|
margin_y + j,
|
||||||
|
symbol,
|
||||||
|
self.color,
|
||||||
|
self.background_color);
|
||||||
|
|
||||||
if *d > 8 {
|
if *d > 8 {
|
||||||
*d -= 8;
|
*d -= 8;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user