feat(symbols): add dashed borders (#1573)
Adds several new border sets: - ratatui::symbols::border::LIGHT_DOUBLE_DASHED - ratatui::symbols::border::HEAVY_DOUBLE_DASHED - ratatui::symbols::border::LIGHT_TRIPLE_DASHED - ratatui::symbols::border::HEAVY_TRIPLE_DASHED - ratatui::symbols::border::LIGHT_QUADRUPLE_DASHED - ratatui::symbols::border::HEAVY_QUADRUPLE_DASHED And corresponding variants to the ratatui::widgets::BorderType enum Fixes: https://github.com/ratatui/ratatui/issues/1355 Signed-off-by: Théo Tchilinguirian <theo.tchlx@gmail.com>
This commit is contained in:
committed by
GitHub
parent
57c2326574
commit
985cd05573
@@ -18,6 +18,20 @@ impl Default for Set {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to convert a line set to a border set
|
||||
const fn from_line_set(line_set: line::Set) -> Set {
|
||||
Set {
|
||||
top_left: line_set.top_left,
|
||||
top_right: line_set.top_right,
|
||||
bottom_left: line_set.bottom_left,
|
||||
bottom_right: line_set.bottom_right,
|
||||
vertical_left: line_set.vertical,
|
||||
vertical_right: line_set.vertical,
|
||||
horizontal_top: line_set.horizontal,
|
||||
horizontal_bottom: line_set.horizontal,
|
||||
}
|
||||
}
|
||||
|
||||
/// Border Set with a single line width
|
||||
///
|
||||
/// ```text
|
||||
@@ -94,6 +108,66 @@ pub const THICK: Set = Set {
|
||||
horizontal_bottom: line::THICK.horizontal,
|
||||
};
|
||||
|
||||
/// Border Set with light double-dashed border lines
|
||||
///
|
||||
/// ```text
|
||||
/// ┌╌╌╌╌╌┐
|
||||
/// ╎xxxxx╎
|
||||
/// ╎xxxxx╎
|
||||
/// └╌╌╌╌╌┘
|
||||
/// ```
|
||||
pub const LIGHT_DOUBLE_DASHED: Set = from_line_set(line::LIGHT_DOUBLE_DASHED);
|
||||
|
||||
/// Border Set with thick double-dashed border lines
|
||||
///
|
||||
/// ```text
|
||||
/// ┏╍╍╍╍╍┓
|
||||
/// ╏xxxxx╏
|
||||
/// ╏xxxxx╏
|
||||
/// ┗╍╍╍╍╍┛
|
||||
/// ```
|
||||
pub const HEAVY_DOUBLE_DASHED: Set = from_line_set(line::HEAVY_DOUBLE_DASHED);
|
||||
|
||||
/// Border Set with light triple-dashed border lines
|
||||
///
|
||||
/// ```text
|
||||
/// ┌┄┄┄┄┄┐
|
||||
/// ┆xxxxx┆
|
||||
/// ┆xxxxx┆
|
||||
/// └┄┄┄┄┄┘
|
||||
/// ```
|
||||
pub const LIGHT_TRIPLE_DASHED: Set = from_line_set(line::LIGHT_TRIPLE_DASHED);
|
||||
|
||||
/// Border Set with thick triple-dashed border lines
|
||||
///
|
||||
/// ```text
|
||||
/// ┏┅┅┅┅┅┓
|
||||
/// ┇xxxxx┇
|
||||
/// ┇xxxxx┇
|
||||
/// ┗┅┅┅┅┅┛
|
||||
/// ```
|
||||
pub const HEAVY_TRIPLE_DASHED: Set = from_line_set(line::HEAVY_TRIPLE_DASHED);
|
||||
|
||||
/// Border Set with light quadruple-dashed border lines
|
||||
///
|
||||
/// ```text
|
||||
/// ┌┈┈┈┈┈┐
|
||||
/// ┊xxxxx┊
|
||||
/// ┊xxxxx┊
|
||||
/// └┈┈┈┈┈┘
|
||||
/// ```
|
||||
pub const LIGHT_QUADRUPLE_DASHED: Set = from_line_set(line::LIGHT_QUADRUPLE_DASHED);
|
||||
|
||||
/// Border Set with thick quadruple-dashed border lines
|
||||
///
|
||||
/// ```text
|
||||
/// ┏┉┉┉┉┉┓
|
||||
/// ┋xxxxx┋
|
||||
/// ┋xxxxx┋
|
||||
/// ┗┉┉┉┉┉┛
|
||||
/// ```
|
||||
pub const HEAVY_QUADRUPLE_DASHED: Set = from_line_set(line::HEAVY_QUADRUPLE_DASHED);
|
||||
|
||||
pub const QUADRANT_TOP_LEFT: &str = "▘";
|
||||
pub const QUADRANT_TOP_RIGHT: &str = "▝";
|
||||
pub const QUADRANT_BOTTOM_LEFT: &str = "▖";
|
||||
@@ -327,6 +401,39 @@ mod tests {
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn border_set_from_line_set() {
|
||||
let custom_line_set = line::Set {
|
||||
top_left: "a",
|
||||
top_right: "b",
|
||||
bottom_left: "c",
|
||||
bottom_right: "d",
|
||||
vertical: "e",
|
||||
horizontal: "f",
|
||||
vertical_left: "g",
|
||||
vertical_right: "h",
|
||||
horizontal_down: "i",
|
||||
horizontal_up: "j",
|
||||
cross: "k",
|
||||
};
|
||||
|
||||
let border_set = from_line_set(custom_line_set);
|
||||
|
||||
assert_eq!(
|
||||
border_set,
|
||||
Set {
|
||||
top_left: "a",
|
||||
top_right: "b",
|
||||
bottom_left: "c",
|
||||
bottom_right: "d",
|
||||
vertical_left: "e",
|
||||
vertical_right: "e",
|
||||
horizontal_bottom: "f",
|
||||
horizontal_top: "f",
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plain() {
|
||||
assert_eq!(
|
||||
@@ -387,6 +494,96 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn light_double_dashed() {
|
||||
assert_eq!(
|
||||
render(LIGHT_DOUBLE_DASHED),
|
||||
indoc!(
|
||||
"░░░░░░
|
||||
░┌╌╌┐░
|
||||
░╎░░╎░
|
||||
░╎░░╎░
|
||||
░└╌╌┘░
|
||||
░░░░░░"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn heavy_double_dashed() {
|
||||
assert_eq!(
|
||||
render(HEAVY_DOUBLE_DASHED),
|
||||
indoc!(
|
||||
"░░░░░░
|
||||
░┏╍╍┓░
|
||||
░╏░░╏░
|
||||
░╏░░╏░
|
||||
░┗╍╍┛░
|
||||
░░░░░░"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn light_triple_dashed() {
|
||||
assert_eq!(
|
||||
render(LIGHT_TRIPLE_DASHED),
|
||||
indoc!(
|
||||
"░░░░░░
|
||||
░┌┄┄┐░
|
||||
░┆░░┆░
|
||||
░┆░░┆░
|
||||
░└┄┄┘░
|
||||
░░░░░░"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn heavy_triple_dashed() {
|
||||
assert_eq!(
|
||||
render(HEAVY_TRIPLE_DASHED),
|
||||
indoc!(
|
||||
"░░░░░░
|
||||
░┏┅┅┓░
|
||||
░┇░░┇░
|
||||
░┇░░┇░
|
||||
░┗┅┅┛░
|
||||
░░░░░░"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn light_quadruple_dashed() {
|
||||
assert_eq!(
|
||||
render(LIGHT_QUADRUPLE_DASHED),
|
||||
indoc!(
|
||||
"░░░░░░
|
||||
░┌┈┈┐░
|
||||
░┊░░┊░
|
||||
░┊░░┊░
|
||||
░└┈┈┘░
|
||||
░░░░░░"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn heavy_quadruple_dashed() {
|
||||
assert_eq!(
|
||||
render(HEAVY_QUADRUPLE_DASHED),
|
||||
indoc!(
|
||||
"░░░░░░
|
||||
░┏┉┉┓░
|
||||
░┋░░┋░
|
||||
░┋░░┋░
|
||||
░┗┉┉┛░
|
||||
░░░░░░"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quadrant_outside() {
|
||||
assert_eq!(
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
pub const VERTICAL: &str = "│";
|
||||
pub const DOUBLE_VERTICAL: &str = "║";
|
||||
pub const THICK_VERTICAL: &str = "┃";
|
||||
pub const LIGHT_DOUBLE_DASH_VERTICAL: &str = "╎";
|
||||
pub const HEAVY_DOUBLE_DASH_VERTICAL: &str = "╏";
|
||||
pub const LIGHT_TRIPLE_DASH_VERTICAL: &str = "┆";
|
||||
pub const HEAVY_TRIPLE_DASH_VERTICAL: &str = "┇";
|
||||
pub const LIGHT_QUADRUPLE_DASH_VERTICAL: &str = "┊";
|
||||
pub const HEAVY_QUADRUPLE_DASH_VERTICAL: &str = "┋";
|
||||
|
||||
pub const HORIZONTAL: &str = "─";
|
||||
pub const DOUBLE_HORIZONTAL: &str = "═";
|
||||
pub const THICK_HORIZONTAL: &str = "━";
|
||||
pub const LIGHT_DOUBLE_DASH_HORIZONTAL: &str = "╌";
|
||||
pub const HEAVY_DOUBLE_DASH_HORIZONTAL: &str = "╍";
|
||||
pub const LIGHT_TRIPLE_DASH_HORIZONTAL: &str = "┄";
|
||||
pub const HEAVY_TRIPLE_DASH_HORIZONTAL: &str = "┅";
|
||||
pub const LIGHT_QUADRUPLE_DASH_HORIZONTAL: &str = "┈";
|
||||
pub const HEAVY_QUADRUPLE_DASH_HORIZONTAL: &str = "┉";
|
||||
|
||||
pub const TOP_RIGHT: &str = "┐";
|
||||
pub const ROUNDED_TOP_RIGHT: &str = "╮";
|
||||
@@ -117,6 +129,42 @@ pub const THICK: Set = Set {
|
||||
cross: THICK_CROSS,
|
||||
};
|
||||
|
||||
pub const LIGHT_DOUBLE_DASHED: Set = Set {
|
||||
vertical: LIGHT_DOUBLE_DASH_VERTICAL,
|
||||
horizontal: LIGHT_DOUBLE_DASH_HORIZONTAL,
|
||||
..NORMAL
|
||||
};
|
||||
|
||||
pub const HEAVY_DOUBLE_DASHED: Set = Set {
|
||||
vertical: HEAVY_DOUBLE_DASH_VERTICAL,
|
||||
horizontal: HEAVY_DOUBLE_DASH_HORIZONTAL,
|
||||
..THICK
|
||||
};
|
||||
|
||||
pub const LIGHT_TRIPLE_DASHED: Set = Set {
|
||||
vertical: LIGHT_TRIPLE_DASH_VERTICAL,
|
||||
horizontal: LIGHT_TRIPLE_DASH_HORIZONTAL,
|
||||
..NORMAL
|
||||
};
|
||||
|
||||
pub const HEAVY_TRIPLE_DASHED: Set = Set {
|
||||
vertical: HEAVY_TRIPLE_DASH_VERTICAL,
|
||||
horizontal: HEAVY_TRIPLE_DASH_HORIZONTAL,
|
||||
..THICK
|
||||
};
|
||||
|
||||
pub const LIGHT_QUADRUPLE_DASHED: Set = Set {
|
||||
vertical: LIGHT_QUADRUPLE_DASH_VERTICAL,
|
||||
horizontal: LIGHT_QUADRUPLE_DASH_HORIZONTAL,
|
||||
..NORMAL
|
||||
};
|
||||
|
||||
pub const HEAVY_QUADRUPLE_DASHED: Set = Set {
|
||||
vertical: HEAVY_QUADRUPLE_DASH_VERTICAL,
|
||||
horizontal: HEAVY_QUADRUPLE_DASH_HORIZONTAL,
|
||||
..THICK
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use indoc::{formatdoc, indoc};
|
||||
|
||||
@@ -1389,6 +1389,30 @@ mod tests {
|
||||
assert_eq!(format!("{}", BorderType::Rounded), "Rounded");
|
||||
assert_eq!(format!("{}", BorderType::Double), "Double");
|
||||
assert_eq!(format!("{}", BorderType::Thick), "Thick");
|
||||
assert_eq!(
|
||||
format!("{}", BorderType::LightDoubleDashed),
|
||||
"LightDoubleDashed"
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", BorderType::HeavyDoubleDashed),
|
||||
"HeavyDoubleDashed"
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", BorderType::LightTripleDashed),
|
||||
"LightTripleDashed"
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", BorderType::HeavyTripleDashed),
|
||||
"HeavyTripleDashed"
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", BorderType::LightQuadrupleDashed),
|
||||
"LightQuadrupleDashed"
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", BorderType::HeavyQuadrupleDashed),
|
||||
"HeavyQuadrupleDashed"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1397,6 +1421,30 @@ mod tests {
|
||||
assert_eq!("Rounded".parse(), Ok(BorderType::Rounded));
|
||||
assert_eq!("Double".parse(), Ok(BorderType::Double));
|
||||
assert_eq!("Thick".parse(), Ok(BorderType::Thick));
|
||||
assert_eq!(
|
||||
"LightDoubleDashed".parse(),
|
||||
Ok(BorderType::LightDoubleDashed)
|
||||
);
|
||||
assert_eq!(
|
||||
"HeavyDoubleDashed".parse(),
|
||||
Ok(BorderType::HeavyDoubleDashed)
|
||||
);
|
||||
assert_eq!(
|
||||
"LightTripleDashed".parse(),
|
||||
Ok(BorderType::LightTripleDashed)
|
||||
);
|
||||
assert_eq!(
|
||||
"HeavyTripleDashed".parse(),
|
||||
Ok(BorderType::HeavyTripleDashed)
|
||||
);
|
||||
assert_eq!(
|
||||
"LightQuadrupleDashed".parse(),
|
||||
Ok(BorderType::LightQuadrupleDashed)
|
||||
);
|
||||
assert_eq!(
|
||||
"HeavyQuadrupleDashed".parse(),
|
||||
Ok(BorderType::HeavyQuadrupleDashed)
|
||||
);
|
||||
assert_eq!("".parse::<BorderType>(), Err(ParseError::VariantNotFound));
|
||||
}
|
||||
|
||||
@@ -1490,6 +1538,96 @@ mod tests {
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_light_double_dashed_border() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3));
|
||||
Block::bordered()
|
||||
.border_type(BorderType::LightDoubleDashed)
|
||||
.render(buffer.area, &mut buffer);
|
||||
#[rustfmt::skip]
|
||||
let expected = Buffer::with_lines([
|
||||
"┌╌╌╌╌╌╌╌╌┐",
|
||||
"╎ ╎",
|
||||
"└╌╌╌╌╌╌╌╌┘",
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_heavy_double_dashed_border() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3));
|
||||
Block::bordered()
|
||||
.border_type(BorderType::HeavyDoubleDashed)
|
||||
.render(buffer.area, &mut buffer);
|
||||
#[rustfmt::skip]
|
||||
let expected = Buffer::with_lines([
|
||||
"┏╍╍╍╍╍╍╍╍┓",
|
||||
"╏ ╏",
|
||||
"┗╍╍╍╍╍╍╍╍┛",
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_light_triple_dashed_border() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3));
|
||||
Block::bordered()
|
||||
.border_type(BorderType::LightTripleDashed)
|
||||
.render(buffer.area, &mut buffer);
|
||||
#[rustfmt::skip]
|
||||
let expected = Buffer::with_lines([
|
||||
"┌┄┄┄┄┄┄┄┄┐",
|
||||
"┆ ┆",
|
||||
"└┄┄┄┄┄┄┄┄┘",
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_heavy_triple_dashed_border() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3));
|
||||
Block::bordered()
|
||||
.border_type(BorderType::HeavyTripleDashed)
|
||||
.render(buffer.area, &mut buffer);
|
||||
#[rustfmt::skip]
|
||||
let expected = Buffer::with_lines([
|
||||
"┏┅┅┅┅┅┅┅┅┓",
|
||||
"┇ ┇",
|
||||
"┗┅┅┅┅┅┅┅┅┛",
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_light_quadruple_dashed_border() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3));
|
||||
Block::bordered()
|
||||
.border_type(BorderType::LightQuadrupleDashed)
|
||||
.render(buffer.area, &mut buffer);
|
||||
#[rustfmt::skip]
|
||||
let expected = Buffer::with_lines([
|
||||
"┌┈┈┈┈┈┈┈┈┐",
|
||||
"┊ ┊",
|
||||
"└┈┈┈┈┈┈┈┈┘",
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_heavy_quadruple_dashed_border() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3));
|
||||
Block::bordered()
|
||||
.border_type(BorderType::HeavyQuadrupleDashed)
|
||||
.render(buffer.area, &mut buffer);
|
||||
#[rustfmt::skip]
|
||||
let expected = Buffer::with_lines([
|
||||
"┏┉┉┉┉┉┉┉┉┓",
|
||||
"┋ ┋",
|
||||
"┗┉┉┉┉┉┉┉┉┛",
|
||||
]);
|
||||
assert_eq!(buffer, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_custom_border_set() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3));
|
||||
|
||||
@@ -74,6 +74,54 @@ pub enum BorderType {
|
||||
/// ┗━━━━━━━┛
|
||||
/// ```
|
||||
Thick,
|
||||
/// A light double-dashed border.
|
||||
///
|
||||
/// ```plain
|
||||
/// ┌╌╌╌╌╌╌╌┐
|
||||
/// ╎ ╎
|
||||
/// └╌╌╌╌╌╌╌┘
|
||||
/// ```
|
||||
LightDoubleDashed,
|
||||
/// A heavy double-dashed border.
|
||||
///
|
||||
/// ```plain
|
||||
/// ┏╍╍╍╍╍╍╍┓
|
||||
/// ╏ ╏
|
||||
/// ┗╍╍╍╍╍╍╍┛
|
||||
/// ```
|
||||
HeavyDoubleDashed,
|
||||
/// A light triple-dashed border.
|
||||
///
|
||||
/// ```plain
|
||||
/// ┌┄┄┄┄┄┄┄┐
|
||||
/// ┆ ┆
|
||||
/// └┄┄┄┄┄┄┄┘
|
||||
/// ```
|
||||
LightTripleDashed,
|
||||
/// A heavy triple-dashed border.
|
||||
///
|
||||
/// ```plain
|
||||
/// ┏┅┅┅┅┅┅┅┓
|
||||
/// ┇ ┇
|
||||
/// ┗┅┅┅┅┅┅┅┛
|
||||
/// ```
|
||||
HeavyTripleDashed,
|
||||
/// A light quadruple-dashed border.
|
||||
///
|
||||
/// ```plain
|
||||
/// ┌┈┈┈┈┈┈┈┐
|
||||
/// ┊ ┊
|
||||
/// └┈┈┈┈┈┈┈┘
|
||||
/// ```
|
||||
LightQuadrupleDashed,
|
||||
/// A heavy quadruple-dashed border.
|
||||
///
|
||||
/// ```plain
|
||||
/// ┏┉┉┉┉┉┉┉┓
|
||||
/// ┋ ┋
|
||||
/// ┗┉┉┉┉┉┉┉┛
|
||||
/// ```
|
||||
HeavyQuadrupleDashed,
|
||||
/// A border with a single line on the inside of a half block.
|
||||
///
|
||||
/// # Example
|
||||
@@ -105,6 +153,12 @@ impl BorderType {
|
||||
Self::Rounded => border::ROUNDED,
|
||||
Self::Double => border::DOUBLE,
|
||||
Self::Thick => border::THICK,
|
||||
Self::LightDoubleDashed => border::LIGHT_DOUBLE_DASHED,
|
||||
Self::HeavyDoubleDashed => border::HEAVY_DOUBLE_DASHED,
|
||||
Self::LightTripleDashed => border::LIGHT_TRIPLE_DASHED,
|
||||
Self::HeavyTripleDashed => border::HEAVY_TRIPLE_DASHED,
|
||||
Self::LightQuadrupleDashed => border::LIGHT_QUADRUPLE_DASHED,
|
||||
Self::HeavyQuadrupleDashed => border::HEAVY_QUADRUPLE_DASHED,
|
||||
Self::QuadrantInside => border::QUADRANT_INSIDE,
|
||||
Self::QuadrantOutside => border::QUADRANT_OUTSIDE,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user