mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-25 22:20:31 +00:00
fix(widgets/block): allow Block to render on small areas
This commit is contained in:
parent
8543523f18
commit
8a27036a54
2 changed files with 176 additions and 11 deletions
|
@ -135,13 +135,12 @@ impl<'a> Block<'a> {
|
||||||
|
|
||||||
impl<'a> Widget for Block<'a> {
|
impl<'a> Widget for Block<'a> {
|
||||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||||
buf.set_style(area, self.style);
|
if area.area() == 0 {
|
||||||
|
|
||||||
if area.width < 2 || area.height < 2 {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
buf.set_style(area, self.style);
|
||||||
let symbols = BorderType::line_symbols(self.border_type);
|
let symbols = BorderType::line_symbols(self.border_type);
|
||||||
|
|
||||||
// Sides
|
// Sides
|
||||||
if self.borders.intersects(Borders::LEFT) {
|
if self.borders.intersects(Borders::LEFT) {
|
||||||
for y in area.top()..area.bottom() {
|
for y in area.top()..area.bottom() {
|
||||||
|
@ -175,9 +174,9 @@ impl<'a> Widget for Block<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Corners
|
// Corners
|
||||||
if self.borders.contains(Borders::LEFT | Borders::TOP) {
|
if self.borders.contains(Borders::RIGHT | Borders::BOTTOM) {
|
||||||
buf.get_mut(area.left(), area.top())
|
buf.get_mut(area.right() - 1, area.bottom() - 1)
|
||||||
.set_symbol(symbols.top_left)
|
.set_symbol(symbols.bottom_right)
|
||||||
.set_style(self.border_style);
|
.set_style(self.border_style);
|
||||||
}
|
}
|
||||||
if self.borders.contains(Borders::RIGHT | Borders::TOP) {
|
if self.borders.contains(Borders::RIGHT | Borders::TOP) {
|
||||||
|
@ -190,9 +189,9 @@ impl<'a> Widget for Block<'a> {
|
||||||
.set_symbol(symbols.bottom_left)
|
.set_symbol(symbols.bottom_left)
|
||||||
.set_style(self.border_style);
|
.set_style(self.border_style);
|
||||||
}
|
}
|
||||||
if self.borders.contains(Borders::RIGHT | Borders::BOTTOM) {
|
if self.borders.contains(Borders::LEFT | Borders::TOP) {
|
||||||
buf.get_mut(area.right() - 1, area.bottom() - 1)
|
buf.get_mut(area.left(), area.top())
|
||||||
.set_symbol(symbols.bottom_right)
|
.set_symbol(symbols.top_left)
|
||||||
.set_style(self.border_style);
|
.set_style(self.border_style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +206,7 @@ impl<'a> Widget for Block<'a> {
|
||||||
} else {
|
} else {
|
||||||
0
|
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);
|
buf.set_spans(area.left() + lx, area.top(), &title, width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,3 +45,169 @@ fn widgets_block_renders() {
|
||||||
}
|
}
|
||||||
terminal.backend().assert_buffer(&expected);
|
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─"]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue