diff --git a/CHANGELOG.md b/CHANGELOG.md index 69f2e231..dcfa17b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,14 @@ current (development) mistake. See #998. ### Dom +- Feature: Add `italic` decorator. For instance: + ```cpp + auto italic_text = text("Italic text") | italic; + ``` + ```cpp + auto italic_text = italic(text("Italic text")); + ``` + Proposed by @kenReneris in #1009. - Feature: Add `hscroll_indicator`. It display an horizontal indicator reflecting the current scroll position. Proposed by @ibrahimnasson in [issue 752](https://github.com/ArthurSonzogni/FTXUI/issues/752) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c121b1a..8816a582 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ add_library(dom src/ftxui/dom/hbox.cpp src/ftxui/dom/hyperlink.cpp src/ftxui/dom/inverted.cpp + src/ftxui/dom/italic.cpp src/ftxui/dom/linear_gradient.cpp src/ftxui/dom/node.cpp src/ftxui/dom/node_decorator.cpp diff --git a/README.md b/README.md index 62a59077..0c2ed177 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ Element can become flexible using the the `flex` decorator. An element can be decorated using the functions: - `bold` + - `italic` - `dim` - `inverted` - `underlined` diff --git a/cmake/ftxui_test.cmake b/cmake/ftxui_test.cmake index 7ff1b2d7..665b7444 100644 --- a/cmake/ftxui_test.cmake +++ b/cmake/ftxui_test.cmake @@ -39,6 +39,7 @@ add_executable(ftxui-tests src/ftxui/dom/gridbox_test.cpp src/ftxui/dom/hbox_test.cpp src/ftxui/dom/hyperlink_test.cpp + src/ftxui/dom/italic_test.cpp src/ftxui/dom/linear_gradient_test.cpp src/ftxui/dom/scroll_indicator_test.cpp src/ftxui/dom/selection_test.cpp diff --git a/doc/mainpage.md b/doc/mainpage.md index 59494b9c..27f6c18b 100644 --- a/doc/mainpage.md +++ b/doc/mainpage.md @@ -123,8 +123,8 @@ The project is comprised of 3 modules: This is the visual element of the program. It defines a `ftxui::Screen`, which is a grid of `ftxui::Pixel`. A Pixel represents a Unicode character and its -associated style (bold, colors, etc.). The screen can be printed as a string -using `ftxui::Screen::ToString()`. The following example highlights this +associated style (bold, italic, colors, etc.). The screen can be printed as a +string using `ftxui::Screen::ToString()`. The following example highlights this process: ```cpp @@ -476,10 +476,11 @@ See [demo](https://arthursonzogni.github.io/FTXUI/examples/?file=component/linea ## Style {#dom-style} In addition to colored text and colored backgrounds. Many terminals support text -effects such as: `bold`, `dim`, `underlined`, `inverted`, `blink`. +effects such as: `bold`, `italic`, `dim`, `underlined`, `inverted`, `blink`. ```cpp Element bold(Element); +Element italic(Element); Element dim(Element); Element inverted(Element); Element underlined(Element); diff --git a/examples/dom/CMakeLists.txt b/examples/dom/CMakeLists.txt index 59844ad0..d1361185 100644 --- a/examples/dom/CMakeLists.txt +++ b/examples/dom/CMakeLists.txt @@ -29,6 +29,7 @@ example(style_dim) example(style_gallery) example(style_hyperlink) example(style_inverted) +example(style_italic) example(style_strikethrough) example(style_underlined) example(style_underlined_double) diff --git a/examples/dom/style_gallery.cpp b/examples/dom/style_gallery.cpp index c8068939..2170d2e5 100644 --- a/examples/dom/style_gallery.cpp +++ b/examples/dom/style_gallery.cpp @@ -15,6 +15,7 @@ int main() { hbox({ text("normal") , text(" ") , text("bold") | bold , text(" ") , + text("italic") | italic , text(" ") , text("dim") | dim , text(" ") , text("inverted") | inverted , text(" ") , text("underlined") | underlined , text(" ") , diff --git a/examples/dom/style_italic.cpp b/examples/dom/style_italic.cpp new file mode 100644 index 00000000..3604179d --- /dev/null +++ b/examples/dom/style_italic.cpp @@ -0,0 +1,23 @@ +// Copyright 2025 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. +#include // for text, operator|, inverted, Fit, hbox, Element +#include // for Full, Screen +#include // for allocator + +#include "ftxui/dom/node.hpp" // for Render +#include "ftxui/screen/color.hpp" // for ftxui + +int main() { + using namespace ftxui; + auto document = hbox({ + text("This text is "), + text("italic") | italic, + text(". Do you like it?"), + }); + auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); + Render(screen, document); + screen.Print(); + + return 0; +} diff --git a/include/ftxui/dom/elements.hpp b/include/ftxui/dom/elements.hpp index fe778e32..4978ded6 100644 --- a/include/ftxui/dom/elements.hpp +++ b/include/ftxui/dom/elements.hpp @@ -95,6 +95,7 @@ Element canvas(std::function); // -- Decorator --- Element bold(Element); Element dim(Element); +Element italic(Element); Element inverted(Element); Element underlined(Element); Element underlinedDouble(Element); diff --git a/include/ftxui/screen/pixel.hpp b/include/ftxui/screen/pixel.hpp index cbc7cc23..b9b66a97 100644 --- a/include/ftxui/screen/pixel.hpp +++ b/include/ftxui/screen/pixel.hpp @@ -17,6 +17,7 @@ struct Pixel { : blink(false), bold(false), dim(false), + italic(false), inverted(false), underlined(false), underlined_double(false), @@ -27,6 +28,7 @@ struct Pixel { bool blink : 1; bool bold : 1; bool dim : 1; + bool italic : 1; bool inverted : 1; bool underlined : 1; bool underlined_double : 1; diff --git a/src/ftxui/dom/dbox.cpp b/src/ftxui/dom/dbox.cpp index 2c9994a2..2fd6fe11 100644 --- a/src/ftxui/dom/dbox.cpp +++ b/src/ftxui/dom/dbox.cpp @@ -75,6 +75,7 @@ class DBox : public Node { acc->bold = pixel.bold; acc->dim = pixel.dim; acc->inverted = pixel.inverted; + acc->italic = pixel.italic; acc->underlined = pixel.underlined; acc->underlined_double = pixel.underlined_double; acc->strikethrough = pixel.strikethrough; diff --git a/src/ftxui/dom/italic.cpp b/src/ftxui/dom/italic.cpp new file mode 100644 index 00000000..e1a1f6e5 --- /dev/null +++ b/src/ftxui/dom/italic.cpp @@ -0,0 +1,35 @@ +// Copyright 2025 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. +#include // for make_shared +#include // 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 italic(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).italic = true; + } + } + Node::Render(screen); + } + }; + + return std::make_shared(std::move(child)); +} + +} // namespace ftxui diff --git a/src/ftxui/dom/italic_test.cpp b/src/ftxui/dom/italic_test.cpp new file mode 100644 index 00000000..fdf124ee --- /dev/null +++ b/src/ftxui/dom/italic_test.cpp @@ -0,0 +1,22 @@ +// Copyright 2025 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. +#include // for allocator, string + +#include "ftxui/dom/elements.hpp" // for operator|, text, bold, Element +#include "ftxui/dom/node.hpp" // for Render +#include "ftxui/screen/screen.hpp" // for Screen, Pixel +#include "gtest/gtest.h" // for Test, AssertionResult, EXPECT_TRUE, Message, TEST, TestPartResult + +// NOLINTBEGIN +namespace ftxui { + +TEST(ItalicTest, Basic) { + auto element = text("text") | italic; + Screen screen(5, 1); + Render(screen, element); + EXPECT_TRUE(screen.PixelAt(0, 0).italic); +} + +} // namespace ftxui +// NOLINTEND diff --git a/src/ftxui/screen/screen.cpp b/src/ftxui/screen/screen.cpp index ac815399..ab087fcc 100644 --- a/src/ftxui/screen/screen.cpp +++ b/src/ftxui/screen/screen.cpp @@ -106,6 +106,12 @@ void UpdatePixelStyle(const Screen* screen, : "\x1B[27m"); // INVERTED_RESET } + // Italics + if (FTXUI_UNLIKELY(next.italic != prev.italic)) { + ss << (next.italic ? "\x1B[3m" // ITALIC_SET + : "\x1B[23m"); // ITALIC_RESET + } + // StrikeThrough if (FTXUI_UNLIKELY(next.strikethrough != prev.strikethrough)) { ss << (next.strikethrough ? "\x1B[9m" // CROSSED_OUT