FTXUI  5.0.0
C++ functional terminal UI.
renderer.cpp
Go to the documentation of this file.
1// Copyright 2021 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#include <functional> // for function
5#include <memory> // for __shared_ptr_access, shared_ptr
6#include <utility> // for move
7
8#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
9#include "ftxui/component/component.hpp" // for Make, Renderer
10#include "ftxui/component/component_base.hpp" // for Component, ComponentBase
11#include "ftxui/component/event.hpp" // for Event
12#include "ftxui/component/mouse.hpp" // for Mouse
13#include "ftxui/dom/elements.hpp" // for Element, operator|, reflect
14#include "ftxui/screen/box.hpp" // for Box
15
16namespace ftxui {
17
18/// @brief Return a component, using |render| to render its interface.
19/// @param render The function drawing the interface.
20/// @ingroup component
21///
22/// ### Example
23///
24/// ```cpp
25/// auto screen = ScreenInteractive::TerminalOutput();
26/// auto renderer = Renderer([] {
27/// return text("My interface");
28/// });
29/// screen.Loop(renderer);
30/// ```
31Component Renderer(std::function<Element()> render) {
32 class Impl : public ComponentBase {
33 public:
34 explicit Impl(std::function<Element()> render)
35 : render_(std::move(render)) {}
36 Element Render() override { return render_(); }
37 std::function<Element()> render_;
38 };
39
40 return Make<Impl>(std::move(render));
41}
42
43/// @brief Return a new Component, similar to |child|, but using |render| as the
44/// Component::Render() event.
45/// @param child The component to forward events to.
46/// @param render The function drawing the interface.
47/// @ingroup component
48///
49/// ### Example
50///
51/// ```cpp
52/// auto screen = ScreenInteractive::TerminalOutput();
53/// std::string label = "Click to quit";
54/// auto button = Button(&label, screen.ExitLoopClosure());
55/// auto renderer = Renderer(button, [&] {
56/// return hbox({
57/// text("A button:"),
58/// button->Render(),
59/// });
60/// });
61/// screen.Loop(renderer);
62/// ```
63Component Renderer(Component child, std::function<Element()> render) {
64 Component renderer = Renderer(std::move(render));
65 renderer->Add(std::move(child));
66 return renderer;
67}
68
69/// @brief Return a focusable component, using |render| to render its interface.
70/// @param render The function drawing the interface, taking a boolean telling
71/// whether the component is focused or not.
72/// @ingroup component
73///
74/// ### Example
75///
76/// ```cpp
77/// auto screen = ScreenInteractive::TerminalOutput();
78/// auto renderer = Renderer([] (bool focused) {
79/// if (focused)
80/// return text("My interface") | inverted;
81/// else
82/// return text("My interface");
83/// });
84/// screen.Loop(renderer);
85/// ```
86Component Renderer(std::function<Element(bool)> render) {
87 class Impl : public ComponentBase {
88 public:
89 explicit Impl(std::function<Element(bool)> render)
90 : render_(std::move(render)) {}
91
92 private:
93 Element Render() override { return render_(Focused()) | reflect(box_); }
94 bool Focusable() const override { return true; }
95 bool OnEvent(Event event) override {
96 if (event.is_mouse() && box_.Contain(event.mouse().x, event.mouse().y)) {
97 if (!CaptureMouse(event)) {
98 return false;
99 }
100
101 TakeFocus();
102 }
103
104 return false;
105 }
106 Box box_;
107
108 std::function<Element(bool)> render_;
109 };
110 return Make<Impl>(std::move(render));
111}
112
113/// @brief Decorate a component, by decorating what it renders.
114/// @param decorator the function modifying the element it renders.
115/// @ingroup component
116///
117/// ### Example
118///
119/// ```cpp
120/// auto screen = ScreenInteractive::TerminalOutput();
121/// auto renderer =
122// Renderer([] { return text("Hello");)
123/// | Renderer(bold)
124/// | Renderer(inverted);
125/// screen.Loop(renderer);
126/// ```
128 return [decorator](Component component) { // NOLINT
129 return Renderer(component, [component, decorator] {
130 return component->Render() | decorator;
131 });
132 };
133}
134
135} // namespace ftxui
It implement rendering itself as ftxui::Element. It implement keyboard navigation by responding to ft...
std::shared_ptr< Node > Element
Definition: elements.hpp:23
std::function< Element(Element)> ElementDecorator
Definition: component.hpp:34
std::shared_ptr< ComponentBase > Component
Component Renderer(Component child, std::function< Element()>)
Return a new Component, similar to |child|, but using |render| as the Component::Render() event.
Definition: renderer.cpp:63
Decorator reflect(Box &box)
Definition: reflect.cpp:44
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Definition: node.cpp:47
std::function< Component(Component)> ComponentDecorator
Definition: component.hpp:33
Represent an event. It can be key press event, a terminal resize, or more ...
Definition: event.hpp:29
bool is_mouse() const
Definition: event.hpp:78
struct Mouse & mouse()
Definition: event.hpp:79