diff --git a/src/widgets/block.rs b/src/widgets/block.rs index e1686987..08df019c 100644 --- a/src/widgets/block.rs +++ b/src/widgets/block.rs @@ -135,13 +135,12 @@ impl<'a> Block<'a> { impl<'a> Widget for Block<'a> { fn render(self, area: Rect, buf: &mut Buffer) { - buf.set_style(area, self.style); - - if area.width < 2 || area.height < 2 { + if area.area() == 0 { return; } - + 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() { @@ -175,9 +174,9 @@ impl<'a> Widget for Block<'a> { } // Corners - if self.borders.contains(Borders::LEFT | Borders::TOP) { - buf.get_mut(area.left(), area.top()) - .set_symbol(symbols.top_left) + if self.borders.contains(Borders::RIGHT | Borders::BOTTOM) { + buf.get_mut(area.right() - 1, area.bottom() - 1) + .set_symbol(symbols.bottom_right) .set_style(self.border_style); } if self.borders.contains(Borders::RIGHT | Borders::TOP) { @@ -190,9 +189,9 @@ impl<'a> Widget for Block<'a> { .set_symbol(symbols.bottom_left) .set_style(self.border_style); } - if self.borders.contains(Borders::RIGHT | Borders::BOTTOM) { - buf.get_mut(area.right() - 1, area.bottom() - 1) - .set_symbol(symbols.bottom_right) + if self.borders.contains(Borders::LEFT | Borders::TOP) { + buf.get_mut(area.left(), area.top()) + .set_symbol(symbols.top_left) .set_style(self.border_style); } @@ -207,7 +206,7 @@ impl<'a> Widget for Block<'a> { } else { 0 }; - let width = area.width - lx - rx; + let width = area.width.saturating_sub(lx).saturating_sub(rx); buf.set_spans(area.left() + lx, area.top(), &title, width); } } diff --git a/tests/widgets_block.rs b/tests/widgets_block.rs index 2ce938b0..d3111081 100644 --- a/tests/widgets_block.rs +++ b/tests/widgets_block.rs @@ -45,3 +45,169 @@ fn widgets_block_renders() { } terminal.backend().assert_buffer(&expected); } + +#[test] +fn widgets_block_renders_on_small_areas() { + let test_case = |block, area: Rect, expected| { + let backend = TestBackend::new(area.width, area.height); + let mut terminal = Terminal::new(backend).unwrap(); + terminal + .draw(|f| { + f.render_widget(block, area); + }) + .unwrap(); + terminal.backend().assert_buffer(&expected); + }; + + let one_cell_test_cases = [ + (Borders::NONE, "T"), + (Borders::LEFT, "│"), + (Borders::TOP, "T"), + (Borders::RIGHT, "│"), + (Borders::BOTTOM, "T"), + (Borders::ALL, "┌"), + ]; + for (borders, symbol) in one_cell_test_cases.iter().cloned() { + test_case( + Block::default().title("Test").borders(borders), + Rect { + x: 0, + y: 0, + width: 0, + height: 0, + }, + Buffer::empty(Rect { + x: 0, + y: 0, + width: 0, + height: 0, + }), + ); + test_case( + Block::default().title("Test").borders(borders), + Rect { + x: 0, + y: 0, + width: 1, + height: 0, + }, + Buffer::empty(Rect { + x: 0, + y: 0, + width: 1, + height: 0, + }), + ); + test_case( + Block::default().title("Test").borders(borders), + Rect { + x: 0, + y: 0, + width: 0, + height: 1, + }, + Buffer::empty(Rect { + x: 0, + y: 0, + width: 0, + height: 1, + }), + ); + test_case( + Block::default().title("Test").borders(borders), + Rect { + x: 0, + y: 0, + width: 1, + height: 1, + }, + Buffer::with_lines(vec![symbol]), + ); + } + test_case( + Block::default().title("Test").borders(Borders::LEFT), + Rect { + x: 0, + y: 0, + width: 4, + height: 1, + }, + Buffer::with_lines(vec!["│Tes"]), + ); + test_case( + Block::default().title("Test").borders(Borders::RIGHT), + Rect { + x: 0, + y: 0, + width: 4, + height: 1, + }, + Buffer::with_lines(vec!["Tes│"]), + ); + test_case( + Block::default().title("Test").borders(Borders::RIGHT), + Rect { + x: 0, + y: 0, + width: 4, + height: 1, + }, + Buffer::with_lines(vec!["Tes│"]), + ); + test_case( + Block::default() + .title("Test") + .borders(Borders::LEFT | Borders::RIGHT), + Rect { + x: 0, + y: 0, + width: 4, + height: 1, + }, + Buffer::with_lines(vec!["│Te│"]), + ); + test_case( + Block::default().title("Test").borders(Borders::TOP), + Rect { + x: 0, + y: 0, + width: 4, + height: 1, + }, + Buffer::with_lines(vec!["Test"]), + ); + test_case( + Block::default().title("Test").borders(Borders::TOP), + Rect { + x: 0, + y: 0, + width: 5, + height: 1, + }, + Buffer::with_lines(vec!["Test─"]), + ); + test_case( + Block::default() + .title("Test") + .borders(Borders::LEFT | Borders::TOP), + Rect { + x: 0, + y: 0, + width: 5, + height: 1, + }, + Buffer::with_lines(vec!["┌Test"]), + ); + test_case( + Block::default() + .title("Test") + .borders(Borders::LEFT | Borders::TOP), + Rect { + x: 0, + y: 0, + width: 6, + height: 1, + }, + Buffer::with_lines(vec!["┌Test─"]), + ); +}