Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-tui/src/widgets/block.rs')
| -rw-r--r-- | helix-tui/src/widgets/block.rs | 180 |
1 files changed, 98 insertions, 82 deletions
diff --git a/helix-tui/src/widgets/block.rs b/helix-tui/src/widgets/block.rs index ee7aa757..f1576bc1 100644 --- a/helix-tui/src/widgets/block.rs +++ b/helix-tui/src/widgets/block.rs @@ -1,15 +1,13 @@ use crate::{ - buffer::Buffer, + buffer::{Buffer, SurfaceExt}, symbols::line, - text::Spans, + text::{Span, Spans}, widgets::{Borders, Widget}, }; use helix_view::graphics::{Rect, Style}; -/// Border render type. Defaults to [`BorderType::Plain`]. -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum BorderType { - #[default] Plain, Rounded, Double, @@ -42,7 +40,7 @@ impl BorderType { /// .border_type(BorderType::Rounded) /// .style(Style::default().bg(Color::Black)); /// ``` -#[derive(Debug, Default, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq)] pub struct Block<'a> { /// Optional title place on the upper left of the block title: Option<Spans<'a>>, @@ -57,23 +55,19 @@ pub struct Block<'a> { style: Style, } -impl<'a> Block<'a> { - pub const fn new() -> Self { - Self { +impl<'a> Default for Block<'a> { + fn default() -> Block<'a> { + Block { title: None, - borders: Borders::empty(), - border_style: Style::new(), + borders: Borders::NONE, + border_style: Default::default(), border_type: BorderType::Plain, - style: Style::new(), + style: Default::default(), } } +} - pub const fn bordered() -> Self { - let mut block = Self::new(); - block.borders = Borders::ALL; - block - } - +impl<'a> Block<'a> { pub fn title<T>(mut self, title: T) -> Block<'a> where T: Into<Spans<'a>>, @@ -82,22 +76,34 @@ impl<'a> Block<'a> { self } - pub const fn border_style(mut self, style: Style) -> Block<'a> { + #[deprecated( + since = "0.10.0", + note = "You should use styling capabilities of `text::Spans` given as argument of the `title` method to apply styling to the title." + )] + pub fn title_style(mut self, style: Style) -> Block<'a> { + if let Some(t) = self.title { + let title = String::from(t); + self.title = Some(Spans::from(Span::styled(title, style))); + } + self + } + + pub fn border_style(mut self, style: Style) -> Block<'a> { self.border_style = style; self } - pub const fn style(mut self, style: Style) -> Block<'a> { + pub fn style(mut self, style: Style) -> Block<'a> { self.style = style; self } - pub const fn borders(mut self, flag: Borders) -> Block<'a> { + pub fn borders(mut self, flag: Borders) -> Block<'a> { self.borders = flag; self } - pub const fn border_type(mut self, border_type: BorderType) -> Block<'a> { + pub fn border_type(mut self, border_type: BorderType) -> Block<'a> { self.border_type = border_type; self } @@ -123,71 +129,79 @@ impl<'a> Block<'a> { } } -impl Widget for Block<'_> { +impl<'a> Widget for Block<'a> { fn render(self, area: Rect, buf: &mut Buffer) { if area.area() == 0 { return; } - buf.set_style(area, self.style); + // buf.set_style(area, self.style); let symbols = BorderType::line_symbols(self.border_type); - // Sides - if self.borders.intersects(Borders::LEFT) { - for y in area.top()..area.bottom() { - buf[(area.left(), y)] - .set_symbol(symbols.vertical) - .set_style(self.border_style); - } - } - if self.borders.intersects(Borders::TOP) { - for x in area.left()..area.right() { - buf[(x, area.top())] - .set_symbol(symbols.horizontal) - .set_style(self.border_style); - } - } - if self.borders.intersects(Borders::RIGHT) { - let x = area.right() - 1; - for y in area.top()..area.bottom() { - buf[(x, y)] - .set_symbol(symbols.vertical) - .set_style(self.border_style); - } - } - if self.borders.intersects(Borders::BOTTOM) { - let y = area.bottom() - 1; - for x in area.left()..area.right() { - buf[(x, y)] - .set_symbol(symbols.horizontal) - .set_style(self.border_style); - } - } + // // Sides + // if self.borders.intersects(Borders::LEFT) { + // for y in area.top()..area.bottom() { + // buf[(area.left(), y)] + // .set_symbol(symbols.vertical) + // .set_style(self.border_style); + // } + // } + // if self.borders.intersects(Borders::TOP) { + // for x in area.left()..area.right() { + // buf[(x, area.top())] + // .set_symbol(symbols.horizontal) + // .set_style(self.border_style); + // } + // } + // if self.borders.intersects(Borders::RIGHT) { + // let x = area.right() - 1; + // for y in area.top()..area.bottom() { + // buf[(x, y)] + // .set_symbol(symbols.vertical) + // .set_style(self.border_style); + // } + // } + // if self.borders.intersects(Borders::BOTTOM) { + // let y = area.bottom() - 1; + // for x in area.left()..area.right() { + // buf[(x, y)] + // .set_symbol(symbols.horizontal) + // .set_style(self.border_style); + // } + // } - // Corners - if self.borders.contains(Borders::RIGHT | Borders::BOTTOM) { - buf[(area.right() - 1, area.bottom() - 1)] - .set_symbol(symbols.bottom_right) - .set_style(self.border_style); - } - if self.borders.contains(Borders::RIGHT | Borders::TOP) { - buf[(area.right() - 1, area.top())] - .set_symbol(symbols.top_right) - .set_style(self.border_style); - } - if self.borders.contains(Borders::LEFT | Borders::BOTTOM) { - buf[(area.left(), area.bottom() - 1)] - .set_symbol(symbols.bottom_left) - .set_style(self.border_style); - } - if self.borders.contains(Borders::LEFT | Borders::TOP) { - buf[(area.left(), area.top())] - .set_symbol(symbols.top_left) - .set_style(self.border_style); - } + // // Corners + // if self.borders.contains(Borders::RIGHT | Borders::BOTTOM) { + // buf[(area.right() - 1, area.bottom() - 1)] + // .set_symbol(symbols.bottom_right) + // .set_style(self.border_style); + // } + // if self.borders.contains(Borders::RIGHT | Borders::TOP) { + // buf[(area.right() - 1, area.top())] + // .set_symbol(symbols.top_right) + // .set_style(self.border_style); + // } + // if self.borders.contains(Borders::LEFT | Borders::BOTTOM) { + // buf[(area.left(), area.bottom() - 1)] + // .set_symbol(symbols.bottom_left) + // .set_style(self.border_style); + // } + // if self.borders.contains(Borders::LEFT | Borders::TOP) { + // buf[(area.left(), area.top())] + // .set_symbol(symbols.top_left) + // .set_style(self.border_style); + // } if let Some(title) = self.title { - let lx = u16::from(self.borders.intersects(Borders::LEFT)); - let rx = u16::from(self.borders.intersects(Borders::RIGHT)); + let lx = if self.borders.intersects(Borders::LEFT) { + 1 + } else { + 0 + }; + let rx = if self.borders.intersects(Borders::RIGHT) { + 1 + } else { + 0 + }; let width = area.width.saturating_sub(lx).saturating_sub(rx); buf.set_spans(area.left() + lx, area.top(), &title, width); } @@ -417,7 +431,9 @@ mod tests { // All borders assert_eq!( - Block::bordered().inner(Rect::default()), + Block::default() + .borders(Borders::ALL) + .inner(Rect::default()), Rect { x: 0, y: 0, @@ -427,7 +443,7 @@ mod tests { "all borders, width=0, height=0" ); assert_eq!( - Block::bordered().inner(Rect { + Block::default().borders(Borders::ALL).inner(Rect { x: 0, y: 0, width: 1, @@ -442,7 +458,7 @@ mod tests { "all borders, width=1, height=1" ); assert_eq!( - Block::bordered().inner(Rect { + Block::default().borders(Borders::ALL).inner(Rect { x: 0, y: 0, width: 2, @@ -457,7 +473,7 @@ mod tests { "all borders, width=2, height=2" ); assert_eq!( - Block::bordered().inner(Rect { + Block::default().borders(Borders::ALL).inner(Rect { x: 0, y: 0, width: 3, |