mirror of
https://github.com/ratatui/ratatui.git
synced 2025-09-28 05:21:23 +00:00
feat: preserve block titles when merging borders (#1977)
Resolves #1939
This commit is contained in:
parent
821611f76f
commit
017af11b2b
@ -300,15 +300,20 @@ impl MergeStrategy {
|
||||
/// [Box Drawing Unicode block]: https://en.wikipedia.org/wiki/Box_Drawing
|
||||
/// [`Cell::merge_symbol`]: crate::buffer::Cell::merge_symbol
|
||||
pub fn merge<'a>(self, prev: &'a str, next: &'a str) -> &'a str {
|
||||
let (Ok(prev_symbol), Ok(next_symbol)) =
|
||||
(BorderSymbol::from_str(prev), BorderSymbol::from_str(next))
|
||||
else {
|
||||
// Replace should always just return the last symbol.
|
||||
if self == Self::Replace {
|
||||
return next;
|
||||
};
|
||||
if let Ok(merged) = prev_symbol.merge(next_symbol, self).try_into() {
|
||||
return merged;
|
||||
}
|
||||
next
|
||||
|
||||
match (BorderSymbol::from_str(prev), BorderSymbol::from_str(next)) {
|
||||
(Ok(prev_symbol), Ok(next_symbol)) => prev_symbol
|
||||
.merge(next_symbol, self)
|
||||
.try_into()
|
||||
.unwrap_or(next),
|
||||
// Non-border symbols take precedence in strategies other than Replace.
|
||||
(Err(_), Ok(_)) => prev,
|
||||
(_, Err(_)) => next,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,7 +528,6 @@ macro_rules! define_symbols {
|
||||
}
|
||||
|
||||
define_symbols!(
|
||||
" " => (Nothing, Nothing, Nothing, Nothing),
|
||||
"─" => (Plain, Nothing, Plain, Nothing),
|
||||
"━" => (Thick, Nothing, Thick, Nothing),
|
||||
"│" => (Nothing, Plain, Nothing, Plain),
|
||||
@ -666,7 +670,7 @@ mod tests {
|
||||
"╄", "╅", "╆", "╇", "╈", "╉", "╊", "╋", "╌", "╍", "╎", "╏", "═", "║", "╒", "╓", "╔",
|
||||
"╕", "╖", "╗", "╘", "╙", "╚", "╛", "╜", "╝", "╞", "╟", "╠", "╡", "╢", "╣", "╤", "╥",
|
||||
"╦", "╧", "╨", "╩", "╪", "╫", "╬", "╭", "╮", "╯", "╰", "╴", "╵", "╶", "╷", "╸", "╹",
|
||||
"╺", "╻", "╼", "╽", "╾", "╿", " ",
|
||||
"╺", "╻", "╼", "╽", "╾", "╿", " ", "a", "b",
|
||||
];
|
||||
|
||||
for a in symbols {
|
||||
@ -695,8 +699,8 @@ mod tests {
|
||||
assert_eq!(strategy.merge("┵", "┝"), "┿");
|
||||
assert_eq!(strategy.merge("│", "━"), "┿");
|
||||
assert_eq!(strategy.merge("┵", "╞"), "╞");
|
||||
assert_eq!(strategy.merge(" ", "╠"), "╠");
|
||||
assert_eq!(strategy.merge("╠", " "), "╠");
|
||||
assert_eq!(strategy.merge(" ", "╠"), " ");
|
||||
assert_eq!(strategy.merge("╠", " "), " ");
|
||||
assert_eq!(strategy.merge("╎", "╧"), "╧");
|
||||
assert_eq!(strategy.merge("╛", "╒"), "╪");
|
||||
assert_eq!(strategy.merge("│", "═"), "╪");
|
||||
@ -704,6 +708,9 @@ mod tests {
|
||||
assert_eq!(strategy.merge("╡", "╞"), "╪");
|
||||
assert_eq!(strategy.merge("┌", "╭"), "╭");
|
||||
assert_eq!(strategy.merge("┘", "╭"), "╭");
|
||||
assert_eq!(strategy.merge("┌", "a"), "a");
|
||||
assert_eq!(strategy.merge("a", "╭"), "a");
|
||||
assert_eq!(strategy.merge("a", "b"), "b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -711,7 +718,7 @@ mod tests {
|
||||
let strategy = MergeStrategy::Fuzzy;
|
||||
assert_eq!(strategy.merge("┄", "╴"), "─");
|
||||
assert_eq!(strategy.merge("│", "┆"), "┆");
|
||||
assert_eq!(strategy.merge(" ", "┉"), "┉");
|
||||
assert_eq!(strategy.merge(" ", "┉"), " ");
|
||||
assert_eq!(strategy.merge("┋", "┋"), "┋");
|
||||
assert_eq!(strategy.merge("╷", "╶"), "┌");
|
||||
assert_eq!(strategy.merge("╭", "┌"), "┌");
|
||||
@ -725,8 +732,8 @@ mod tests {
|
||||
assert_eq!(strategy.merge("┘", "┌"), "┼");
|
||||
assert_eq!(strategy.merge("┘", "╭"), "┼");
|
||||
assert_eq!(strategy.merge("╎", "┉"), "┿");
|
||||
assert_eq!(strategy.merge(" ", "╠"), "╠");
|
||||
assert_eq!(strategy.merge("╠", " "), "╠");
|
||||
assert_eq!(strategy.merge(" ", "╠"), " ");
|
||||
assert_eq!(strategy.merge("╠", " "), " ");
|
||||
assert_eq!(strategy.merge("┵", "╞"), "╪");
|
||||
assert_eq!(strategy.merge("╛", "╒"), "╪");
|
||||
assert_eq!(strategy.merge("│", "═"), "╪");
|
||||
@ -734,5 +741,8 @@ mod tests {
|
||||
assert_eq!(strategy.merge("╡", "╞"), "╪");
|
||||
assert_eq!(strategy.merge("╎", "╧"), "╪");
|
||||
assert_eq!(strategy.merge("┌", "╭"), "╭");
|
||||
assert_eq!(strategy.merge("┌", "a"), "a");
|
||||
assert_eq!(strategy.merge("a", "╭"), "a");
|
||||
assert_eq!(strategy.merge("a", "b"), "b");
|
||||
}
|
||||
}
|
||||
|
@ -1969,6 +1969,82 @@ mod tests {
|
||||
pretty_assertions::assert_eq!(Buffer::with_lines(expected.lines()), buffer);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case::replace(MergeStrategy::Replace, Buffer::with_lines([
|
||||
"┏block top━━┓",
|
||||
"┃ ┃",
|
||||
"┗━━━━━━━━━━━┛",
|
||||
"│ │",
|
||||
"└───────────┘",
|
||||
])
|
||||
)]
|
||||
#[case::replace(MergeStrategy::Exact, Buffer::with_lines([
|
||||
"┏block top━━┓",
|
||||
"┃ ┃",
|
||||
"┡block btm━━┩",
|
||||
"│ │",
|
||||
"└───────────┘",
|
||||
])
|
||||
)]
|
||||
#[case::replace(MergeStrategy::Fuzzy, Buffer::with_lines([
|
||||
"┏block top━━┓",
|
||||
"┃ ┃",
|
||||
"┡block btm━━┩",
|
||||
"│ │",
|
||||
"└───────────┘",
|
||||
])
|
||||
)]
|
||||
fn merged_titles_bottom_first(#[case] strategy: MergeStrategy, #[case] expected: Buffer) {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 13, 5));
|
||||
Block::bordered()
|
||||
.title("block btm")
|
||||
.render(Rect::new(0, 2, 13, 3), &mut buffer);
|
||||
Block::bordered()
|
||||
.title("block top")
|
||||
.border_type(BorderType::Thick)
|
||||
.merge_borders(strategy)
|
||||
.render(Rect::new(0, 0, 13, 3), &mut buffer);
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case::replace(MergeStrategy::Replace, Buffer::with_lines([
|
||||
"┏block top━━┓",
|
||||
"┃ ┃",
|
||||
"┌block btm──┐",
|
||||
"│ │",
|
||||
"└───────────┘",
|
||||
])
|
||||
)]
|
||||
#[case::replace(MergeStrategy::Exact, Buffer::with_lines([
|
||||
"┏block top━━┓",
|
||||
"┃ ┃",
|
||||
"┞block btm──┦",
|
||||
"│ │",
|
||||
"└───────────┘",
|
||||
])
|
||||
)]
|
||||
#[case::replace(MergeStrategy::Fuzzy, Buffer::with_lines([
|
||||
"┏block top━━┓",
|
||||
"┃ ┃",
|
||||
"┞block btm──┦",
|
||||
"│ │",
|
||||
"└───────────┘",
|
||||
])
|
||||
)]
|
||||
fn merged_titles_top_first(#[case] strategy: MergeStrategy, #[case] expected: Buffer) {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 13, 5));
|
||||
Block::bordered()
|
||||
.title("block top")
|
||||
.border_type(BorderType::Thick)
|
||||
.render(Rect::new(0, 0, 13, 3), &mut buffer);
|
||||
Block::bordered()
|
||||
.title("block btm")
|
||||
.merge_borders(strategy)
|
||||
.render(Rect::new(0, 2, 13, 3), &mut buffer);
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn left_titles() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 1));
|
||||
|
Loading…
x
Reference in New Issue
Block a user