From 7bdca3ee68ae6521b009b630f9cdb33041e6c258 Mon Sep 17 00:00:00 2001 From: Arthur Sonzogni Date: Wed, 15 Mar 2023 22:50:27 +0100 Subject: [PATCH] Feature: Add the dashed style. (#594) --- CHANGELOG.md | 3 ++ examples/dom/border_style.cpp | 1 + examples/dom/separator_style.cpp | 6 ++++ include/ftxui/dom/elements.hpp | 11 +++++- src/ftxui/dom/border.cpp | 54 +++++++++++++++++++++++++---- src/ftxui/dom/separator.cpp | 58 ++++++++++++++++++++++++++++---- src/ftxui/dom/separator_test.cpp | 14 ++++++++ src/ftxui/dom/table.cpp | 13 +++---- src/ftxui/screen/screen.cpp | 2 ++ 9 files changed, 143 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cdab8fb..73aa26f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ current (development) - Feature: Support `ResizableSplit` with customizable separator. - Breaking: MenuDirection enum is renamed Direction +### Dom +- Feature: Add the dashed style for border and separator. + ### - Breaking: Direction enum is renamed WidthOrHeight - Breaking: GaugeDirection enum is renamed Direction diff --git a/examples/dom/border_style.cpp b/examples/dom/border_style.cpp index f98d04e..995ee95 100644 --- a/examples/dom/border_style.cpp +++ b/examples/dom/border_style.cpp @@ -11,6 +11,7 @@ int main(int argc, const char* argv[]) { auto document = vbox({ text("borderLight") | borderLight, + text("borderDashed") | borderDashed, text("borderHeavy") | borderHeavy, text("borderDouble") | borderDouble, text("borderRounded") | borderRounded, diff --git a/examples/dom/separator_style.cpp b/examples/dom/separator_style.cpp index f0bf6e2..2d72777 100644 --- a/examples/dom/separator_style.cpp +++ b/examples/dom/separator_style.cpp @@ -16,6 +16,12 @@ int main(int argc, const char* argv[]) { hbox(text("left"), separatorLight(), text("right")), }) | borderLight, + vbox({ + text("separatorDashed"), + separatorDashed(), + hbox(text("left"), separatorDashed(), text("right")), + }) | borderDashed, + vbox({ text("separatorHeavy"), separatorHeavy(), diff --git a/include/ftxui/dom/elements.hpp b/include/ftxui/dom/elements.hpp index e8ac059..7714041 100644 --- a/include/ftxui/dom/elements.hpp +++ b/include/ftxui/dom/elements.hpp @@ -21,7 +21,14 @@ using Elements = std::vector; using Decorator = std::function; using GraphFunction = std::function(int, int)>; -enum BorderStyle { LIGHT, HEAVY, DOUBLE, ROUNDED, EMPTY }; +enum BorderStyle { + LIGHT, + DASHED, + HEAVY, + DOUBLE, + ROUNDED, + EMPTY, +}; // Pipe elements into decorator togethers. // For instance the next lines are equivalents: @@ -37,6 +44,7 @@ Element text(std::string text); Element vtext(std::string text); Element separator(); Element separatorLight(); +Element separatorDashed(); Element separatorHeavy(); Element separatorDouble(); Element separatorEmpty(); @@ -59,6 +67,7 @@ Element gaugeDown(float progress); Element gaugeDirection(float progress, Direction direction); Element border(Element); Element borderLight(Element); +Element borderDashed(Element); Element borderHeavy(Element); Element borderDouble(Element); Element borderRounded(Element); diff --git a/src/ftxui/dom/border.cpp b/src/ftxui/dom/border.cpp index f39eb52..9397e39 100644 --- a/src/ftxui/dom/border.cpp +++ b/src/ftxui/dom/border.cpp @@ -14,14 +14,15 @@ namespace ftxui { using Charset = std::array; // NOLINT -using Charsets = std::array; // NOLINT +using Charsets = std::array; // NOLINT // NOLINTNEXTLINE static Charsets simple_border_charset = { - Charset{"┌", "┐", "└", "┘", "─", "│"}, - Charset{"┏", "┓", "┗", "┛", "━", "┃"}, - Charset{"╔", "╗", "╚", "╝", "═", "║"}, - Charset{"╭", "╮", "╰", "╯", "─", "│"}, - Charset{" ", " ", " ", " ", " ", " "}, + Charset{"┌", "┐", "└", "┘", "─", "│"}, // LIGHT + Charset{"┏", "┓", "┗", "┛", "╍", "╏"}, // DASHED + Charset{"┏", "┓", "┗", "┛", "━", "┃"}, // HEAVY + Charset{"╔", "╗", "╚", "╝", "═", "║"}, // DOUBLE + Charset{"╭", "╮", "╰", "╯", "─", "│"}, // ROUNDED + Charset{" ", " ", " ", " ", " ", " "}, // EMPTY }; // For reference, here is the charset for normal border: @@ -173,6 +174,7 @@ class BorderPixel : public Node { /// @ingroup dom /// @see border /// @see borderLight +/// @see borderDashed /// @see borderDouble /// @see borderHeavy /// @see borderEmpty @@ -223,6 +225,42 @@ Decorator borderStyled(BorderStyle style) { /// @ingroup dom /// @see border /// @see borderLight +/// @see borderDashed +/// @see borderDouble +/// @see borderHeavy +/// @see borderRounded +/// @see borderEmpty +/// @see borderStyled +/// @see borderWith +/// +/// Add a border around an element +/// +/// ### Example +/// +/// ```cpp +/// // Use 'borderDash' as a function... +/// Element document = borderDash(text("The element")); +/// +/// // ...Or as a 'pipe'. +/// Element document = text("The element") | borderDAsh; +/// ``` +/// +/// ### Output +/// +/// ```bash +/// ┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ +/// ╏The element ╏ +/// ┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ +/// ``` +Element borderDashed(Element child) { + return std::make_shared(unpack(std::move(child)), DASHED); +} + +/// @brief Draw a dashed border around the element. +/// @ingroup dom +/// @see border +/// @see borderLight +/// @see borderDashed /// @see borderDouble /// @see borderHeavy /// @see borderRounded @@ -257,6 +295,7 @@ Element borderLight(Element child) { /// @ingroup dom /// @see border /// @see borderLight +/// @see borderDashed /// @see borderDouble /// @see borderHeavy /// @see borderRounded @@ -291,6 +330,7 @@ Element borderHeavy(Element child) { /// @ingroup dom /// @see border /// @see borderLight +/// @see borderDashed /// @see borderDouble /// @see borderHeavy /// @see borderRounded @@ -325,6 +365,7 @@ Element borderDouble(Element child) { /// @ingroup dom /// @see border /// @see borderLight +/// @see borderDashed /// @see borderDouble /// @see borderHeavy /// @see borderRounded @@ -359,6 +400,7 @@ Element borderRounded(Element child) { /// @ingroup dom /// @see border /// @see borderLight +/// @see borderDashed /// @see borderDouble /// @see borderHeavy /// @see borderRounded diff --git a/src/ftxui/dom/separator.cpp b/src/ftxui/dom/separator.cpp index 9130d64..aeb00d0 100644 --- a/src/ftxui/dom/separator.cpp +++ b/src/ftxui/dom/separator.cpp @@ -14,14 +14,15 @@ namespace ftxui { namespace { using Charset = std::array; // NOLINT -using Charsets = std::array; // NOLINT +using Charsets = std::array; // NOLINT // NOLINTNEXTLINE const Charsets charsets = { - Charset{"│", "─"}, // - Charset{"┃", "━"}, // - Charset{"║", "═"}, // - Charset{"│", "─"}, // - Charset{" ", " "}, // + Charset{"│", "─"}, // LIGHT + Charset{"╏", "╍"}, // DASHED + Charset{"┃", "━"}, // HEAVY + Charset{"║", "═"}, // DOUBLE + Charset{"│", "─"}, // ROUNDED + Charset{" ", " "}, // EMPTY }; } // namespace @@ -98,6 +99,7 @@ class SeparatorWithPixel : public SeparatorAuto { /// @ingroup dom /// @see separator /// @see separatorLight +/// @see separatorDashed /// @see separatorDouble /// @see separatorHeavy /// @see separatorEmpty @@ -135,6 +137,7 @@ Element separator() { /// @ingroup dom /// @see separator /// @see separatorLight +/// @see separatorDashed /// @see separatorDouble /// @see separatorHeavy /// @see separatorEmpty @@ -171,6 +174,7 @@ Element separatorStyled(BorderStyle style) { /// @ingroup dom /// @see separator /// @see separatorLight +/// @see separatorDashed /// @see separatorDouble /// @see separatorHeavy /// @see separatorEmpty @@ -202,11 +206,49 @@ Element separatorLight() { return std::make_shared(LIGHT); } +/// @brief Draw a vertical or horizontal separation in between two other +/// elements, using the DASHED style. +/// @ingroup dom +/// @see separator +/// @see separatorLight +/// @see separatorDashed +/// @see separatorDouble +/// @see separatorHeavy +/// @see separatorEmpty +/// @see separatorRounded +/// @see separatorStyled +/// @see separatorCharacter +/// +/// Add a visual separation in between two elements. +/// +/// ### Example +/// +/// ```cpp +/// // Use 'border' as a function... +/// Element document = vbox({ +/// text("up"), +/// separatorLight(), +/// text("down"), +/// }); +/// ``` +/// +/// ### Output +/// +/// ```bash +/// up +/// ╍╍╍╍ +/// down +/// ``` +Element separatorDashed() { + return std::make_shared(DASHED); +} + /// @brief Draw a vertical or horizontal separation in between two other /// elements, using the HEAVY style. /// @ingroup dom /// @see separator /// @see separatorLight +/// @see separatorDashed /// @see separatorDouble /// @see separatorHeavy /// @see separatorEmpty @@ -243,6 +285,7 @@ Element separatorHeavy() { /// @ingroup dom /// @see separator /// @see separatorLight +/// @see separatorDashed /// @see separatorDouble /// @see separatorHeavy /// @see separatorEmpty @@ -279,6 +322,7 @@ Element separatorDouble() { /// @ingroup dom /// @see separator /// @see separatorLight +/// @see separatorDashed /// @see separatorDouble /// @see separatorHeavy /// @see separatorEmpty @@ -316,6 +360,7 @@ Element separatorEmpty() { /// @ingroup dom /// @see separator /// @see separatorLight +/// @see separatorDashed /// @see separatorDouble /// @see separatorHeavy /// @see separatorEmpty @@ -351,6 +396,7 @@ Element separatorCharacter(std::string value) { /// @ingroup dom /// @see separator /// @see separatorLight +/// @see separatorDashed /// @see separatorHeavy /// @see separatorDouble /// @see separatorStyled diff --git a/src/ftxui/dom/separator_test.cpp b/src/ftxui/dom/separator_test.cpp index ffb4c14..1dbef62 100644 --- a/src/ftxui/dom/separator_test.cpp +++ b/src/ftxui/dom/separator_test.cpp @@ -35,6 +35,20 @@ TEST(SeparatorTest, Light) { "down"); } +TEST(SeparatorTest, Dashed) { + auto element = vbox({ + text("top"), + separatorDashed(), + text("down"), + }); + Screen screen(4, 3); + Render(screen, element); + EXPECT_EQ(screen.ToString(), + "top \r\n" + "╍╍╍╍\r\n" + "down"); +} + TEST(SeparatorTest, Double) { auto element = vbox({ text("top"), diff --git a/src/ftxui/dom/table.cpp b/src/ftxui/dom/table.cpp index 081011f..bdaf5fc 100644 --- a/src/ftxui/dom/table.cpp +++ b/src/ftxui/dom/table.cpp @@ -14,12 +14,13 @@ bool IsCell(int x, int y) { } // NOLINTNEXTLINE -static std::string charset[5][6] = { - {"┌", "┐", "└", "┘", "─", "│"}, // - {"┏", "┓", "┗", "┛", "━", "┃"}, // - {"╔", "╗", "╚", "╝", "═", "║"}, // - {"╭", "╮", "╰", "╯", "─", "│"}, // - {" ", " ", " ", " ", " ", " "}, // +static std::string charset[6][6] = { + {"┌", "┐", "└", "┘", "─", "│"}, // LIGHT + {"┏", "┓", "┗", "┛", "╍", "╏"}, // DASHED + {"┏", "┓", "┗", "┛", "━", "┃"}, // HEAVY + {"╔", "╗", "╚", "╝", "═", "║"}, // DOUBLE + {"╭", "╮", "╰", "╯", "─", "│"}, // ROUNDED + {" ", " ", " ", " ", " ", " "}, // EMPTY }; int Wrap(int input, int modulo) { diff --git a/src/ftxui/screen/screen.cpp b/src/ftxui/screen/screen.cpp index a358966..04cc758 100644 --- a/src/ftxui/screen/screen.cpp +++ b/src/ftxui/screen/screen.cpp @@ -154,9 +154,11 @@ struct TileEncoding { const std::map tile_encoding = { // NOLINT {"─", {1, 0, 1, 0, 0}}, {"━", {2, 0, 2, 0, 0}}, + {"╍", {2, 0, 2, 0, 0}}, {"│", {0, 1, 0, 1, 0}}, {"┃", {0, 2, 0, 2, 0}}, + {"╏", {0, 2, 0, 2, 0}}, {"┌", {0, 0, 1, 1, 0}}, {"┍", {0, 0, 2, 1, 0}},