Feature: strikethrough and underlinedDouble decorator. (#561)

This resolves:
https://github.com/ArthurSonzogni/FTXUI/issues/560
This commit is contained in:
Arthur Sonzogni 2023-01-22 11:02:27 +01:00 committed by GitHub
parent 350dcac032
commit 6fe8310321
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 172 additions and 13 deletions

View File

@ -5,6 +5,9 @@ current (development)
--------------------- ---------------------
### DOM ### DOM
- Feature: more styles:
- `strikethrough`
- `underlinedDouble`
- Feature: Customize the cursor. Add the following decorators: - Feature: Customize the cursor. Add the following decorators:
- `focusCursorBlock` - `focusCursorBlock`
- `focusCursorBlockBlinking` - `focusCursorBlockBlinking`

View File

@ -79,9 +79,11 @@ add_library(dom
src/ftxui/dom/separator.cpp src/ftxui/dom/separator.cpp
src/ftxui/dom/size.cpp src/ftxui/dom/size.cpp
src/ftxui/dom/spinner.cpp src/ftxui/dom/spinner.cpp
src/ftxui/dom/strikethrough.cpp
src/ftxui/dom/table.cpp src/ftxui/dom/table.cpp
src/ftxui/dom/text.cpp src/ftxui/dom/text.cpp
src/ftxui/dom/underlined.cpp src/ftxui/dom/underlined.cpp
src/ftxui/dom/underlined_double.cpp
src/ftxui/dom/util.cpp src/ftxui/dom/util.cpp
src/ftxui/dom/vbox.cpp src/ftxui/dom/vbox.cpp
) )

View File

@ -122,7 +122,9 @@ An element can be decorated using the functions:
- `dim` - `dim`
- `inverted` - `inverted`
- `underlined` - `underlined`
- `underlinedDouble`
- `blink` - `blink`
- `strikethrough`
- `color` - `color`
- `bgcolor` - `bgcolor`

View File

@ -453,6 +453,8 @@ Element bold(Element);
Element dim(Element); Element dim(Element);
Element inverted(Element); Element inverted(Element);
Element underlined(Element); Element underlined(Element);
Element underlinedDouble(Element);
Element strikethrough(Element);
Element blink(Element); Element blink(Element);
Decorator color(Color); Decorator color(Color);
Decorator bgcolor(Color); Decorator bgcolor(Color);
@ -469,7 +471,7 @@ underlined(bold(text("This text is bold and underlined")))
Alternatively, use the pipe operator to chain it on your element: Alternatively, use the pipe operator to chain it on your element:
```cpp ```cpp
text("This text is bold")) | bold | underlined text("This text is bold") | bold | underlined
``` ```
## Layout {#dom-layout} ## Layout {#dom-layout}

View File

@ -26,7 +26,9 @@ example(style_color)
example(style_dim) example(style_dim)
example(style_gallery) example(style_gallery)
example(style_inverted) example(style_inverted)
example(style_strikethrough)
example(style_underlined) example(style_underlined)
example(style_underlined_double)
example(table) example(table)
example(vbox_hbox) example(vbox_hbox)
example(vflow) example(vflow)

View File

@ -15,7 +15,9 @@ int main(int argc, const char* argv[]) {
text("dim") | dim , text(" ") , text("dim") | dim , text(" ") ,
text("inverted") | inverted , text(" ") , text("inverted") | inverted , text(" ") ,
text("underlined") | underlined , text(" ") , text("underlined") | underlined , text(" ") ,
text("underlinedDouble") | underlinedDouble , text(" ") ,
text("blink") | blink , text(" ") , text("blink") | blink , text(" ") ,
text("strikethrough") | strikethrough , text(" ") ,
text("color") | color(Color::Blue) , text(" ") , text("color") | color(Color::Blue) , text(" ") ,
text("bgcolor") | bgcolor(Color::Blue) , text("bgcolor") | bgcolor(Color::Blue) ,
}); });

View File

@ -0,0 +1,25 @@
#include <ftxui/dom/elements.hpp> // for text, operator|, strikethrough, Fit, hbox, Element
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) {
using namespace ftxui;
auto document = //
hbox({
text("This text is "),
text("strikethrough") | strikethrough,
text(". Do you like it?"),
});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
return 0;
}
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.

View File

@ -0,0 +1,25 @@
#include <ftxui/dom/elements.hpp> // for text, operator|, underlinedDouble, Fit, hbox, Element
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <memory> // for allocator
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for ftxui
int main(int argc, const char* argv[]) {
using namespace ftxui;
auto document = //
hbox({
text("This text is "),
text("underlinedDouble") | underlinedDouble,
text(". Do you like it?"),
});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
screen.Print();
return 0;
}
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.

View File

@ -83,7 +83,9 @@ Element bold(Element);
Element dim(Element); Element dim(Element);
Element inverted(Element); Element inverted(Element);
Element underlined(Element); Element underlined(Element);
Element underlinedDouble(Element);
Element blink(Element); Element blink(Element);
Element strikethrough(Element);
Decorator color(Color); Decorator color(Color);
Decorator bgcolor(Color); Decorator bgcolor(Color);
Element color(Color, Element); Element color(Color, Element);

View File

@ -30,6 +30,8 @@ struct Pixel {
bool dim : 1; bool dim : 1;
bool inverted : 1; bool inverted : 1;
bool underlined : 1; bool underlined : 1;
bool underlined_double : 1;
bool strikethrough : 1;
bool automerge : 1; bool automerge : 1;
Pixel() Pixel()
@ -38,6 +40,8 @@ struct Pixel {
dim(false), dim(false),
inverted(false), inverted(false),
underlined(false), underlined(false),
underlined_double(false),
strikethrough(false),
automerge(false) {} automerge(false) {}
}; };

View File

@ -0,0 +1,36 @@
#include <memory> // for make_shared
#include <utility> // for move
#include "ftxui/dom/elements.hpp" // for Element, strikethrough
#include "ftxui/dom/node.hpp" // for Node
#include "ftxui/dom/node_decorator.hpp" // for NodeDecorator
#include "ftxui/screen/box.hpp" // for Box
#include "ftxui/screen/screen.hpp" // for Pixel, Screen
namespace ftxui {
/// @brief Apply a strikethrough to text.
/// @ingroup dom
Element strikethrough(Element child) {
class Impl : public NodeDecorator {
public:
using NodeDecorator::NodeDecorator;
void Render(Screen& screen) override {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
screen.PixelAt(x, y).strikethrough = true;
}
}
Node::Render(screen);
}
};
return std::make_shared<Impl>(std::move(child));
}
} // namespace ftxui
// Copyright 2023 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.

View File

@ -0,0 +1,36 @@
#include <memory> // for make_shared
#include <utility> // for move
#include "ftxui/dom/elements.hpp" // for Element, underlinedDouble
#include "ftxui/dom/node.hpp" // for Node
#include "ftxui/dom/node_decorator.hpp" // for NodeDecorator
#include "ftxui/screen/box.hpp" // for Box
#include "ftxui/screen/screen.hpp" // for Pixel, Screen
namespace ftxui {
/// @brief Apply a underlinedDouble to text.
/// @ingroup dom
Element underlinedDouble(Element child) {
class Impl : public NodeDecorator {
public:
using NodeDecorator::NodeDecorator;
void Render(Screen& screen) override {
for (int y = box_.y_min; y <= box_.y_max; ++y) {
for (int x = box_.x_min; x <= box_.x_max; ++x) {
screen.PixelAt(x, y).underlined_double = true;
}
}
Node::Render(screen);
}
};
return std::make_shared<Impl>(std::move(child));
}
} // namespace ftxui
// Copyright 2023 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.

View File

@ -66,6 +66,16 @@ void UpdatePixelStyle(std::stringstream& ss,
previous.dim = false; previous.dim = false;
} }
if ((!next.underlined && previous.underlined) ||
(!next.underlined_double && previous.underlined_double)) {
// We might have wrongfully reset underlined or underlinedbold because they
// share the same resetter. Take it into account so that the side effect
// will cause it to be set again below.
ss << "\x1B[24m"; // UNDERLINED_RESET
previous.underlined = false;
previous.underlined_double = false;
}
if (next.bold && !previous.bold) { if (next.bold && !previous.bold) {
ss << "\x1B[1m"; // BOLD_SET ss << "\x1B[1m"; // BOLD_SET
} }
@ -78,10 +88,6 @@ void UpdatePixelStyle(std::stringstream& ss,
ss << "\x1B[4m"; // UNDERLINED_SET ss << "\x1B[4m"; // UNDERLINED_SET
} }
if (!next.underlined && previous.underlined) {
ss << "\x1B[24m"; // UNDERLINED_RESET
}
if (next.blink && !previous.blink) { if (next.blink && !previous.blink) {
ss << "\x1B[5m"; // BLINK_SET ss << "\x1B[5m"; // BLINK_SET
} }
@ -98,6 +104,18 @@ void UpdatePixelStyle(std::stringstream& ss,
ss << "\x1B[27m"; // INVERTED_RESET ss << "\x1B[27m"; // INVERTED_RESET
} }
if (next.strikethrough && !previous.strikethrough) {
ss << "\x1B[9m"; // CROSSED_OUT
}
if (!next.strikethrough && previous.strikethrough) {
ss << "\x1B[29m"; // CROSSED_OUT_RESET
}
if (next.underlined_double && !previous.underlined_double) {
ss << "\x1B[21m"; // DOUBLE_UNDERLINED_SET
}
if (next.foreground_color != previous.foreground_color || if (next.foreground_color != previous.foreground_color ||
next.background_color != previous.background_color) { next.background_color != previous.background_color) {
ss << "\x1B[" + next.foreground_color.Print(false) + "m"; ss << "\x1B[" + next.foreground_color.Print(false) + "m";