Add more documentation.

This commit is contained in:
ArthurSonzogni 2020-08-16 02:24:50 +02:00 committed by Arthur Sonzogni
parent f2dc080a35
commit 114ab4ae2a
33 changed files with 310 additions and 144 deletions

View File

@ -162,7 +162,7 @@ FULL_PATH_NAMES = YES
# will be relative from the directory where doxygen is started. # will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES. # This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH = STRIP_FROM_PATH = ../..
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which # path mentioned in the documentation of a class, which tells the reader which
@ -2319,7 +2319,7 @@ TEMPLATE_RELATIONS = NO
# The default value is: YES. # The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES. # This tag requires that the tag HAVE_DOT is set to YES.
INCLUDE_GRAPH = YES INCLUDE_GRAPH = NO
# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
# set to YES then doxygen will generate a graph for each documented file showing # set to YES then doxygen will generate a graph for each documented file showing

View File

@ -96,17 +96,18 @@
<namespace> <namespace>
<briefdescription visible="yes"/> <briefdescription visible="yes"/>
<memberdecl> <memberdecl>
<functions title=""/>
<enums title=""/>
<typedefs title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<nestednamespaces visible="yes" title=""/> <nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/> <constantgroups visible="yes" title=""/>
<interfaces visible="yes" title=""/> <interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/> <exceptions visible="yes" title=""/>
<typedefs title=""/>
<sequences title=""/> <sequences title=""/>
<dictionaries title=""/> <dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/> <variables title=""/>
<membergroups visible="yes"/> <membergroups visible="yes"/>
</memberdecl> </memberdecl>

View File

@ -1,35 +0,0 @@
# Examples
@example ./examples/util/print_key_press.cpp
@example ./examples/dom/dbox.cpp
@example ./examples/dom/separator.cpp
@example ./examples/dom/style_color.cpp
@example ./examples/dom/paragraph.cpp
@example ./examples/dom/style_blink.cpp
@example ./examples/dom/style_dim.cpp
@example ./examples/dom/style_inverted.cpp
@example ./examples/dom/graph.cpp
@example ./examples/dom/package_manager.cpp
@example ./examples/dom/window.cpp
@example ./examples/dom/html_like.cpp
@example ./examples/dom/border.cpp
@example ./examples/dom/style_underlined.cpp
@example ./examples/dom/gauge.cpp
@example ./examples/dom/style_bold.cpp
@example ./examples/dom/spinner.cpp
@example ./examples/dom/style_gallery.cpp
@example ./examples/dom/vbox_hbox.cpp
@example ./examples/dom/size.cpp
@example ./examples/dom/hflow.cpp
@example ./examples/component/tab_vertical.cpp
@example ./examples/component/gallery.cpp
@example ./examples/component/checkbox.cpp
@example ./examples/component/checkbox_in_frame.cpp
@example ./examples/component/menu2.cpp
@example ./examples/component/tab_horizontal.cpp
@example ./examples/component/input.cpp
@example ./examples/component/homescreen.cpp
@example ./examples/component/radiobox.cpp
@example ./examples/component/menu.cpp
@example ./examples/component/menu_style.cpp
@example ./examples/component/radiobox_in_frame.cpp
@example ./examples/component/toggle.cpp

View File

@ -341,26 +341,40 @@ its keyboard. They handle keyboard navigation, including component focus.
## Input ## Input
The component: \ref ftxui::Input
@htmlonly @htmlonly
<script id="asciicast-223719" src="https://asciinema.org/a/223719.js" async></script> <script id="asciicast-223719" src="https://asciinema.org/a/223719.js" async></script>
@endhtmlonly @endhtmlonly
## Menu ## Menu
The component: \ref ftxui::Menu
@htmlonly @htmlonly
<script id="asciicast-223720" src="https://asciinema.org/a/223720.js" async></script> <script id="asciicast-223720" src="https://asciinema.org/a/223720.js" async></script>
@endhtmlonly @endhtmlonly
## Toggle. ## Toggle.
The component: \ref ftxui::Toggle
@htmlonly @htmlonly
<script id="asciicast-223722" src="https://asciinema.org/a/223722.js" async></script> <script id="asciicast-223722" src="https://asciinema.org/a/223722.js" async></script>
@endhtmlonly @endhtmlonly
## CheckBox ## CheckBox
The component: \ref ftxui::CheckBox
@htmlonly @htmlonly
<script id="asciicast-223724" src="https://asciinema.org/a/223724.js" async></script> <script id="asciicast-223724" src="https://asciinema.org/a/223724.js" async></script>
@endhtmlonly @endhtmlonly
## RadioBox ## RadioBox
The component: \ref ftxui::RadioBox
@htmlonly @htmlonly
<script id="asciicast-223725" src="https://asciinema.org/a/223725.js" async></script> <script id="asciicast-223725" src="https://asciinema.org/a/223725.js" async></script>
@endhtmlonly @endhtmlonly

View File

@ -7,27 +7,29 @@
namespace ftxui { namespace ftxui {
/// @brief A Checkbox. It can be checked or unchecked.Display an element on a ftxui::Screen.
/// @ingroup dom
class CheckBox : public Component { class CheckBox : public Component {
public: public:
// Constructor. // Constructor.
CheckBox() = default; CheckBox() = default;
~CheckBox() override = default; ~CheckBox() override = default;
bool state = false; bool state = false; // The current state. true=checked, false:unchecked.
std::wstring label = L"label"; std::wstring label = L"label"; // The CheckBox label.
#if defined(_WIN32) #if defined(_WIN32)
std::wstring checked = L"[X] "; std::wstring checked = L"[X] "; /// Prefix for a "checked" state.
std::wstring unchecked = L"[ ] "; std::wstring unchecked = L"[ ] "; /// Prefix for an "unchecked" state.
#else #else
std::wstring checked = L""; std::wstring checked = L""; /// Prefix for a "checked" state.
std::wstring unchecked = L""; std::wstring unchecked = L""; /// Prefix for a "unchecked" state.
#endif #endif
Decorator focused_style = inverted; Decorator focused_style = inverted; /// Decorator used when focused.
Decorator unfocused_style = nothing; Decorator unfocused_style = nothing; /// Decorator used when unfocused.
// State update callback. /// Called when the user change the state of the CheckBox.
std::function<void()> on_change = []() {}; std::function<void()> on_change = []() {};
// Component implementation. // Component implementation.

View File

@ -9,6 +9,9 @@ namespace ftxui {
class Delegate; class Delegate;
class Focus; class Focus;
/// @brief It implement rendering itself as ftxui::Element. It implement
/// keyboard navigation by responding to ftxui::Event.
/// @ingroup component
class Component { class Component {
public: public:
// Constructor/Destructor. // Constructor/Destructor.
@ -16,7 +19,7 @@ class Component {
virtual ~Component(); virtual ~Component();
// Component hierarchy. // Component hierarchy.
Component* Parent() { return parent_; } Component* Parent();
void Add(Component* children); void Add(Component* children);
// Renders the component. // Renders the component.

View File

@ -5,10 +5,7 @@
namespace ftxui { namespace ftxui {
// A component where focus and events are automatically handled for you. /// @brief A component where focus and events are automatically handled for you.
// List of container:
//
// Please use HorizontalContainer or VerticalContainer.
class Container : public Component { class Container : public Component {
public: public:
static Container Vertical(); static Container Vertical();

View File

@ -9,6 +9,9 @@
namespace ftxui { namespace ftxui {
/// @brief Represent an event. It can be key press event, a terminal resize, or
/// more ...
//
// Documentation: // Documentation:
// https://invisible-island.net/xterm/ctlseqs/ctlseqs.html // https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
// //

View File

@ -7,6 +7,8 @@
namespace ftxui { namespace ftxui {
/// @brief An input box. The user can type text into it.
/// @ingroup component.
class Input : public Component { class Input : public Component {
public: public:
// Constructor. // Constructor.

View File

@ -8,6 +8,8 @@
namespace ftxui { namespace ftxui {
/// @brief A list of items. The user can navigate through them.
/// @ingroup component
class Menu : public Component { class Menu : public Component {
public: public:
// Constructor. // Constructor.

View File

@ -7,6 +7,9 @@
namespace ftxui { namespace ftxui {
/// @brief A list of selectable element. One and only one can be selected at
/// the same time.
/// @ingroup component
class RadioBox : public Component { class RadioBox : public Component {
public: public:
// Constructor. // Constructor.

View File

@ -8,6 +8,8 @@
namespace ftxui { namespace ftxui {
/// @brief An horizontal list of elements. The user can navigate through them.
/// @ingroup component
class Toggle : public Component { class Toggle : public Component {
public: public:
// Constructor. // Constructor.

View File

@ -61,13 +61,13 @@ Element flex(Element); // Expand/Minimize if possible/needed.
Element flex_grow(Element); // Expand element if possible. Element flex_grow(Element); // Expand element if possible.
Element flex_shrink(Element); // Minimize element if needed. Element flex_shrink(Element); // Minimize element if needed.
Element xflex(Element); // Expand/Minimize if possible/needed. Element xflex(Element); // Expand/Minimize if possible/needed on X axis.
Element xflex_grow(Element); // Expand element if possible. Element xflex_grow(Element); // Expand element if possible on X axis.
Element xflex_shrink(Element); // Minimize element if needed. Element xflex_shrink(Element); // Minimize element if needed on X axis.
Element yflex(Element); // Expand/Minimize if possible/needed. Element yflex(Element); // Expand/Minimize if possible/needed on Y axis.
Element yflex_grow(Element); // Expand element if possible. Element yflex_grow(Element); // Expand element if possible on Y axis.
Element yflex_shrink(Element); // Minimize element if needed. Element yflex_shrink(Element); // Minimize element if needed on Y axis.
Element notflex(Element); // Reset the flex attribute. Element notflex(Element); // Reset the flex attribute.
Element filler(); // A blank expandable element. Element filler(); // A blank expandable element.

View File

@ -3,6 +3,7 @@
namespace ftxui { namespace ftxui {
/// Assign a value to a variable, reset its old value when going out of scope.
template <typename T> template <typename T>
class AutoReset { class AutoReset {
public: public:

View File

@ -5,28 +5,44 @@
#include <algorithm> #include <algorithm>
namespace ftxui { namespace ftxui {
void Component::Detach() {
if (!parent_)
return;
auto it = std::find(std::begin(parent_->children_),
std::end(parent_->children_), this);
parent_->children_.erase(it);
}
void Component::Attach(Component* parent) {
Detach();
parent_ = parent;
parent_->children_.push_back(this);
}
void Component::Add(Component* child) {
child->Attach(this);
}
Component::~Component() { Component::~Component() {
Detach(); Detach();
} }
/// @brief Return the parent Component, or nul if any.
/// @see Attach
/// @see Detach
/// @see Parent
/// @ingroup component
Component* Component::Parent() {
return parent_;
}
/// @brief Add a children.
/// @@param child The child to be attached.
/// @ingroup component
void Component::Add(Component* child) {
child->Attach(this);
}
/// @brief Draw the component.
/// Build a ftxui::Element to be drawn on the ftxi::Screen representing this
/// ftxui::Component.
/// @ingroup component
Element Component::Render() {
if (children_.size() == 1)
return children_.front()->Render();
return text(L"Not implemented component");
}
/// @brief Called in response to an event.
/// @param event The event.
/// @return True when the event has been handled.
/// The default implementation called OnEvent on every child until one return
/// true. If none returns true, return false.
/// @ingroup component
bool Component::OnEvent(Event event) { bool Component::OnEvent(Event event) {
for (Component* child : children_) { for (Component* child : children_) {
if (child->OnEvent(event)) if (child->OnEvent(event))
@ -35,17 +51,16 @@ bool Component::OnEvent(Event event) {
return false; return false;
} }
/// @brief Return the currently Active child.
/// @return the currently Active child.
/// @ingroup component
Component* Component::ActiveChild() { Component* Component::ActiveChild() {
return children_.empty() ? nullptr : children_.front(); return children_.empty() ? nullptr : children_.front();
} }
Element Component::Render() { /// @brief Returns if the elements if focused by the user.
if (children_.size() == 1) /// True when the Component is focused by the user. An element is Focused when
return children_.front()->Render(); /// it is with all its ancestors the ActiveChild() of their parents.
return text(L"Not implemented component");
}
bool Component::Focused() { bool Component::Focused() {
Component* current = this; Component* current = this;
for (;;) { for (;;) {
@ -58,6 +73,31 @@ bool Component::Focused() {
} }
} }
/// @brief Detach this children from its parent.
/// @see Attach
/// @see Detach
/// @see Parent
/// @ingroup component
void Component::Detach() {
if (!parent_)
return;
auto it = std::find(std::begin(parent_->children_),
std::end(parent_->children_), this);
parent_->children_.erase(it);
}
/// @brief Attach this element to its parent.
/// @see Attach
/// @see Detach
/// @see Parent
/// @ingroup component
void Component::Attach(Component* parent) {
Detach();
parent_ = parent;
parent_->children_.push_back(this);
}
} // namespace ftxui } // namespace ftxui
// Copyright 2020 Arthur Sonzogni. All rights reserved. // Copyright 2020 Arthur Sonzogni. All rights reserved.

View File

@ -18,7 +18,7 @@ class Blink : public NodeDecorator {
} }
}; };
/// @brief The text drawn alternate in between visible and hidden. /// @brief The text drawn alternates in between visible and hidden.
/// @ingroup dom /// @ingroup dom
Element blink(Element child) { Element blink(Element child) {
return std::make_shared<Blink>(unpack(std::move(child))); return std::make_shared<Blink>(unpack(std::move(child)));

View File

@ -129,7 +129,7 @@ Element border(Element child) {
/// @param title The title of the window. /// @param title The title of the window.
/// @param content The element to be wrapped. /// @param content The element to be wrapped.
/// @ingroup dom /// @ingroup dom
/// @seealso border /// @see border
/// ///
/// ### Example /// ### Example
/// ///
@ -152,7 +152,7 @@ Element window(Element title, Element content) {
/// @brief Same as border but with a constant Pixel around the element. /// @brief Same as border but with a constant Pixel around the element.
/// @ingroup dom /// @ingroup dom
/// @seealso border /// @see border
Decorator borderWith(Pixel pixel) { Decorator borderWith(Pixel pixel) {
return [pixel](Element child) { return [pixel](Element child) {
return std::make_shared<Border>(unpack(std::move(child)), pixel); return std::make_shared<Border>(unpack(std::move(child)), pixel);

View File

@ -39,8 +39,8 @@ class FgColor : public NodeDecorator {
}; };
/// @brief Set the foreground color of an element. /// @brief Set the foreground color of an element.
/// @param The color of the output element. /// @param color The color of the output element.
/// @param The input element. /// @param child The input element.
/// @return The output element colored. /// @return The output element colored.
/// @ingroup dom /// @ingroup dom
/// ///
@ -54,8 +54,8 @@ Element color(Color color, Element child) {
} }
/// @brief Set the background color of an element. /// @brief Set the background color of an element.
/// @param The color of the output element. /// @param color The color of the output element.
/// @param The input element. /// @param child The input element.
/// @return The output element colored. /// @return The output element colored.
/// @ingroup dom /// @ingroup dom
/// ///
@ -83,7 +83,7 @@ Decorator color(Color c) {
} }
/// @brief Decorate using a background color. /// @brief Decorate using a background color.
/// @param The background color to be applied. /// @param color The background color to be applied.
/// @return The Decorator applying the color. /// @return The Decorator applying the color.
/// @ingroup dom /// @ingroup dom
/// ///
@ -92,8 +92,8 @@ Decorator color(Color c) {
/// ```cpp /// ```cpp
/// Element document = text(L"red") | bgcolor(Color::Red); /// Element document = text(L"red") | bgcolor(Color::Red);
/// ``` /// ```
Decorator bgcolor(Color c) { Decorator bgcolor(Color color) {
return [c](Element child) { return bgcolor(c, std::move(child)); }; return [color](Element child) { return bgcolor(color, std::move(child)); };
} }
} // namespace ftxui } // namespace ftxui

View File

@ -40,7 +40,7 @@ class DBox : public Node {
}; };
/// @brief Stack several element on top of each other. /// @brief Stack several element on top of each other.
/// @param The input element. /// @param children The input element.
/// @return The right aligned element. /// @return The right aligned element.
/// @ingroup dom /// @ingroup dom
Element dbox(Elements children) { Element dbox(Elements children) {

View File

@ -92,6 +92,7 @@ Element filler() {
/// @brief Make a child element to expand proportionnally to the space left in a /// @brief Make a child element to expand proportionnally to the space left in a
/// container. /// container.
/// @ingroup dom
/// ///
/// #### Examples: /// #### Examples:
/// ///
@ -114,38 +115,56 @@ Element flex(Element child) {
return std::make_shared<Flex>(function_flex, std::move(child)); return std::make_shared<Flex>(function_flex, std::move(child));
} }
/// @brief Expand/Minimize if possible/needed on the X axis.
/// @ingroup dom
Element xflex(Element child) { Element xflex(Element child) {
return std::make_shared<Flex>(function_xflex, std::move(child)); return std::make_shared<Flex>(function_xflex, std::move(child));
} }
/// @brief Expand/Minimize if possible/needed on the Y axis.
/// @ingroup dom
Element yflex(Element child) { Element yflex(Element child) {
return std::make_shared<Flex>(function_yflex, std::move(child)); return std::make_shared<Flex>(function_yflex, std::move(child));
} }
/// @brief Expand if possible.
/// @ingroup dom
Element flex_grow(Element child) { Element flex_grow(Element child) {
return std::make_shared<Flex>(function_flex_grow, std::move(child)); return std::make_shared<Flex>(function_flex_grow, std::move(child));
} }
/// @brief Expand if possible on the X axis.
/// @ingroup dom
Element xflex_grow(Element child) { Element xflex_grow(Element child) {
return std::make_shared<Flex>(function_xflex_grow, std::move(child)); return std::make_shared<Flex>(function_xflex_grow, std::move(child));
} }
/// @brief Expand if possible on the Y axis.
/// @ingroup dom
Element yflex_grow(Element child) { Element yflex_grow(Element child) {
return std::make_shared<Flex>(function_yflex_grow, std::move(child)); return std::make_shared<Flex>(function_yflex_grow, std::move(child));
} }
/// @brief Minimize if needed.
/// @ingroup dom
Element flex_shrink(Element child) { Element flex_shrink(Element child) {
return std::make_shared<Flex>(function_flex_shrink, std::move(child)); return std::make_shared<Flex>(function_flex_shrink, std::move(child));
} }
/// @brief Minimize if needed on the X axis.
/// @ingroup dom
Element xflex_shrink(Element child) { Element xflex_shrink(Element child) {
return std::make_shared<Flex>(function_xflex_shrink, std::move(child)); return std::make_shared<Flex>(function_xflex_shrink, std::move(child));
} }
/// @brief Minimize if needed on the Y axis.
/// @ingroup dom
Element yflex_shrink(Element child) { Element yflex_shrink(Element child) {
return std::make_shared<Flex>(function_yflex_shrink, std::move(child)); return std::make_shared<Flex>(function_yflex_shrink, std::move(child));
} }
/// @brief Make the element not flexible.
/// @ingroup dom
Element notflex(Element child) { Element notflex(Element child) {
return std::make_shared<Flex>(function_not_flex, std::move(child)); return std::make_shared<Flex>(function_not_flex, std::move(child));
} }

View File

@ -109,7 +109,7 @@ class Frame : public Node {
/// @brief Allow an element to be displayed inside a 'virtual' area. It size can /// @brief Allow an element to be displayed inside a 'virtual' area. It size can
/// be larger than its container. In this case only a smaller portion is /// be larger than its container. In this case only a smaller portion is
/// displayed. The view is scrollable to make the focused element visible. /// displayed. The view is scrollable to make the focused element visible.
/// @seealso focus /// @see focus
Element frame(Element child) { Element frame(Element child) {
return std::make_shared<Frame>(unpack(std::move(child)), true, true); return std::make_shared<Frame>(unpack(std::move(child)), true, true);
} }

View File

@ -20,6 +20,9 @@ class Inverted : public NodeDecorator {
} }
}; };
/// @brief Add a filter that will invert the foreground and the background
/// colors.
/// @ingroup dom
Element inverted(Element child) { Element inverted(Element child) {
return std::make_shared<Inverted>(unpack(std::move(child))); return std::make_shared<Inverted>(unpack(std::move(child)));
} }

View File

@ -8,24 +8,34 @@ Node::Node() {}
Node::Node(Elements children) : children(std::move(children)) {} Node::Node(Elements children) : children(std::move(children)) {}
Node::~Node() {} Node::~Node() {}
/// @brief Compute how much space an elements needs.
/// @ingroup dom
void Node::ComputeRequirement() { void Node::ComputeRequirement() {
for (auto& child : children) for (auto& child : children)
child->ComputeRequirement(); child->ComputeRequirement();
} }
/// @brief Assign a position and a dimension to an element for drawing.
/// @ingroup dom
void Node::SetBox(Box box) { void Node::SetBox(Box box) {
box_ = box; box_ = box;
} }
/// @brief Display an element on a ftxui::Screen.
/// @ingroup dom
void Node::Render(Screen& screen) { void Node::Render(Screen& screen) {
for (auto& child : children) for (auto& child : children)
child->Render(screen); child->Render(screen);
} }
/// @brief Display an element on a ftxui::Screen.
/// @ingroup dom
void Render(Screen& screen, const Element& element) { void Render(Screen& screen, const Element& element) {
Render(screen, element.get()); Render(screen, element.get());
} }
/// @brief Display an element on a ftxui::Screen.
/// @ingroup dom
void Render(Screen& screen, Node* node) { void Render(Screen& screen, Node* node) {
// Step 1: Find what dimension this elements wants to be. // Step 1: Find what dimension this elements wants to be.
node->ComputeRequirement(); node->ComputeRequirement();

View File

@ -4,6 +4,11 @@
namespace ftxui { namespace ftxui {
/// @brief Return a vector of ftxui::text for every word of the string. This is
/// useful combined with ftxui::hflow.
/// @param the_text The string to be splitted.
/// @ingroup dom
/// @see hflow.
Elements paragraph(std::wstring the_text) { Elements paragraph(std::wstring the_text) {
Elements output; Elements output;
std::wstringstream ss(the_text); std::wstringstream ss(the_text);

View File

@ -73,6 +73,12 @@ class Size : public Node {
int value_; int value_;
}; };
/// @brief Apply a constraint on the size of an element.
/// @param direction Whether the WIDTH of the HEIGHT of the element must be
/// constrained.
/// @param constrain The type of constaint.
/// @param value the value.
/// @ingroup dom
Decorator size(Direction direction, Constraint constraint, int value) { Decorator size(Direction direction, Constraint constraint, int value) {
return [=](Element e) { return [=](Element e) {
return std::make_shared<Size>(std::move(e), direction, constraint, value); return std::make_shared<Size>(std::move(e), direction, constraint, value);

View File

@ -241,17 +241,23 @@ static const std::vector<std::vector<std::vector<std::wstring>>> elements = {
L" LOLLOL ", L" LOLLOL ",
}}}; }}};
Element spinner(int c, size_t index) { /// @brief Useful to represent the effect of time and/or events. This display an
if (c == 0) { /// ASCII art "video".
index %= 40; /// @param charset_index The type of "video".
if (index > 20) /// @param image_index The "frame" of the video. You need to increase this for
index = 40 - index; ///every "step".
return gauge(index * 0.05); /// @ingroup dom
Element spinner(int charset_index, size_t image_index) {
if (charset_index == 0) {
image_index %= 40;
if (image_index > 20)
image_index = 40 - image_index;
return gauge(image_index * 0.05);
} }
c %= elements.size(); charset_index %= elements.size();
index %= elements[c].size(); image_index %= elements[charset_index].size();
std::vector<Element> lines; std::vector<Element> lines;
for (const auto& it : elements[c][index]) for (const auto& it : elements[charset_index][image_index])
lines.push_back(text(it)); lines.push_back(text(it));
return vbox(std::move(lines)); return vbox(std::move(lines));
} }

View File

@ -64,10 +64,51 @@ class VText : public Node {
int width_ = 1; int width_ = 1;
}; };
/// @brief Display a pieve of unicode text.
/// @ingroup dom
/// @see ftxui::to_wstring
///
/// ### Example
///
/// ```cpp
/// Element document = text(L"Hello world!");
/// ```
///
/// ### Output
///
/// ```bash
/// Hello world!
/// ```
Element text(std::wstring text) { Element text(std::wstring text) {
return std::make_shared<Text>(text); return std::make_shared<Text>(text);
} }
/// @brief Display a pieve of unicode text vertically.
/// @ingroup dom
/// @see ftxui::to_wstring
///
/// ### Example
///
/// ```cpp
/// Element document = vtext(L"Hello world!");
/// ```
///
/// ### Output
///
/// ```bash
/// H
/// e
/// l
/// l
/// o
///
/// w
/// o
/// r
/// l
/// d
/// !
/// ```
Element vtext(std::wstring text) { Element vtext(std::wstring text) {
return std::make_shared<VText>(text); return std::make_shared<VText>(text);
} }

View File

@ -20,6 +20,8 @@ class Underlined : public NodeDecorator {
} }
}; };
/// @brief Make the underlined element to be underlined.
/// @ingroup dom
Element underlined(Element child) { Element underlined(Element child) {
return std::make_shared<Underlined>(unpack(std::move(child))); return std::make_shared<Underlined>(unpack(std::move(child)));
} }

View File

@ -2,29 +2,57 @@
namespace ftxui { namespace ftxui {
Element nothing(Element element) { namespace {
return element;
}
Decorator compose(Decorator a, Decorator b) { Decorator compose(Decorator a, Decorator b) {
return [a = std::move(a), b = std::move(b)](Element element) { return [a = std::move(a), b = std::move(b)](Element element) {
return b(a(std::move(element))); return b(a(std::move(element)));
}; };
} }
} // namespace
/// @brief A decoration doing absolutely nothing.
/// @ingroup dom
Element nothing(Element element) {
return element;
}
/// @brief Compose two decorator into one.
/// @ingroup dom
///
/// ### Example
///
/// ```cpp
/// auto decorator = bold | blink;
/// ```
Decorator operator|(Decorator a, Decorator b) { Decorator operator|(Decorator a, Decorator b) {
return compose(a, b); return compose(a, b);
} }
Elements operator|(Elements es, Decorator d) { /// @brief From a set of element, apply a decorator to every elements.
/// @return the set of decorated element.
/// @ingroup dom
Elements operator|(Elements elements, Decorator decorator) {
Elements output; Elements output;
for (auto& it : es) for (auto& it : elements)
output.push_back(std::move(it) | d); output.push_back(std::move(it) | decorator);
return output; return output;
} }
Element operator|(Element e, Decorator d) { /// @brief From an element, apply a decorator.
return d(std::move(e)); /// @return the decorated element.
/// @ingroup dom
///
/// ### Example
///
/// Both of these are equivalent:
/// ```cpp
/// bold(text(L"Hello"));
/// ```
/// ```cpp
/// text(L"Hello") | bold;
/// ```
Element operator|(Element element, Decorator decorator) {
return decorator(std::move(element));
} }
} // namespace ftxui } // namespace ftxui

View File

@ -128,6 +128,7 @@ class VBox : public Node {
/// @brief A container displaying elements vertically one by one. /// @brief A container displaying elements vertically one by one.
/// @param children The elements in the container /// @param children The elements in the container
/// @return The container. /// @return The container.
/// @ingroup dom
/// ///
/// #### Example /// #### Example
/// ///

View File

@ -3,6 +3,8 @@
#include <algorithm> #include <algorithm>
namespace ftxui { namespace ftxui {
/// @return the biggest Box contained in both |a| and |b|.
/// @ingroup screen
// static // static
Box Box::Intersection(Box a, Box b) { Box Box::Intersection(Box a, Box b) {
return Box{ return Box{

View File

@ -67,14 +67,46 @@ void WindowsEmulateVT100Terminal() {
} }
#endif #endif
void UpdatePixelStyle(std::wstringstream& ss, Pixel& previous, Pixel& next) {
if (next.bold != previous.bold)
ss << (next.bold ? BOLD_SET : BOLD_RESET);
if (next.dim != previous.dim)
ss << (next.dim ? DIM_SET : DIM_RESET);
if (next.underlined != previous.underlined)
ss << (next.underlined ? UNDERLINED_SET : UNDERLINED_RESET);
if (next.blink != previous.blink)
ss << (next.blink ? BLINK_SET : BLINK_RESET);
if (next.inverted != previous.inverted)
ss << (next.inverted ? INVERTED_SET : INVERTED_RESET);
if (next.foreground_color != previous.foreground_color ||
next.background_color != previous.background_color) {
ss << L"\x1B[" +
to_wstring(std::to_string((uint8_t)next.foreground_color)) + L"m";
ss << L"\x1B[" +
to_wstring(std::to_string(10 + (uint8_t)next.background_color)) +
L"m";
}
previous = next;
}
} // namespace } // namespace
/// A fixed dimension. /// A fixed dimension.
/// @see Fit
/// @see Full
Dimension Dimension::Fixed(int v) { Dimension Dimension::Fixed(int v) {
return Dimension{v, v}; return Dimension{v, v};
} }
/// The minimal dimension that will fit the given element. /// The minimal dimension that will fit the given element.
/// @see Fixed
/// @see Full
Dimension Dimension::Fit(Element& e) { Dimension Dimension::Fit(Element& e) {
e->ComputeRequirement(); e->ComputeRequirement();
Terminal::Dimensions size = Terminal::Size(); Terminal::Dimensions size = Terminal::Size();
@ -83,6 +115,8 @@ Dimension Dimension::Fit(Element& e) {
} }
/// Use the terminal dimensions. /// Use the terminal dimensions.
/// @see Fixed
/// @see Fit
Dimension Dimension::Full() { Dimension Dimension::Full() {
Terminal::Dimensions size = Terminal::Size(); Terminal::Dimensions size = Terminal::Size();
return Dimension{size.dimx, size.dimy}; return Dimension{size.dimx, size.dimy};
@ -117,34 +151,6 @@ Screen::Screen(int dimx, int dimy)
#endif #endif
} }
void UpdatePixelStyle(std::wstringstream& ss, Pixel& previous, Pixel& next) {
if (next.bold != previous.bold)
ss << (next.bold ? BOLD_SET : BOLD_RESET);
if (next.dim != previous.dim)
ss << (next.dim ? DIM_SET : DIM_RESET);
if (next.underlined != previous.underlined)
ss << (next.underlined ? UNDERLINED_SET : UNDERLINED_RESET);
if (next.blink != previous.blink)
ss << (next.blink ? BLINK_SET : BLINK_RESET);
if (next.inverted != previous.inverted)
ss << (next.inverted ? INVERTED_SET : INVERTED_RESET);
if (next.foreground_color != previous.foreground_color ||
next.background_color != previous.background_color) {
ss << L"\x1B[" +
to_wstring(std::to_string((uint8_t)next.foreground_color)) + L"m";
ss << L"\x1B[" +
to_wstring(std::to_string(10 + (uint8_t)next.background_color)) +
L"m";
}
previous = next;
}
/// Produce a std::string that can be used to print the Screen on the terminal. /// Produce a std::string that can be used to print the Screen on the terminal.
std::string Screen::ToString() { std::string Screen::ToString() {
std::wstringstream ss; std::wstringstream ss;

View File

@ -9,11 +9,13 @@ namespace ftxui {
#pragma warning(disable : 4996) // codecvt_utf8_utf16 is deprecated #pragma warning(disable : 4996) // codecvt_utf8_utf16 is deprecated
#endif #endif
/// Convert a UTF8 std::string into a std::wstring.
std::string to_string(const std::wstring& s) { std::string to_string(const std::wstring& s) {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.to_bytes(s); return converter.to_bytes(s);
} }
/// Convert a std::wstring into a UTF8 std::string.
std::wstring to_wstring(const std::string& s) { std::wstring to_wstring(const std::string& s) {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.from_bytes(s); return converter.from_bytes(s);