FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
canvas_animated.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 LICENSED file.
4#include <cmath> // for sin, cos
5#include <ftxui/dom/elements.hpp> // for canvas, Element, separator, hbox, operator|, border
6#include <ftxui/screen/screen.hpp> // for Cell
7#include <memory> // for allocator, shared_ptr, __shared_ptr_access
8#include <string> // for string, basic_string
9#include <utility> // for move
10#include <vector> // for vector, __alloc_traits<>::value_type
11
12#include "ftxui/component/app.hpp" // for App
13#include "ftxui/component/component.hpp" // for Renderer, CatchEvent, Horizontal, Menu, Tab
14#include "ftxui/component/component_base.hpp" // for ComponentBase
15#include "ftxui/component/event.hpp" // for Event
16#include "ftxui/component/mouse.hpp" // for Mouse
17#include "ftxui/dom/canvas.hpp" // for Canvas
18#include "ftxui/screen/color.hpp" // for Color, Color::Red, Color::Blue, Color::Green, ftxui
19
20int main() {
21 using namespace ftxui;
22
23 int mouse_x = 0;
24 int mouse_y = 0;
25
26 // A triangle following the mouse, using braille characters.
27 auto renderer_line_braille = Renderer([&] {
28 auto c = Canvas(100, 100);
29 c.DrawText(0, 0, "Several lines (braille)");
30 c.DrawPointLine(mouse_x, mouse_y, 80, 10, Color::Red);
31 c.DrawPointLine(80, 10, 80, 40, Color::Blue);
32 c.DrawPointLine(80, 40, mouse_x, mouse_y, Color::Green);
33 return canvas(std::move(c));
34 });
35
36 // A triangle following the mouse, using block characters.
37 auto renderer_line_block = Renderer([&] {
38 auto c = Canvas(100, 100);
39 c.DrawText(0, 0, "Several lines (block)");
40 c.DrawBlockLine(mouse_x, mouse_y, 80, 10, Color::Red);
41 c.DrawBlockLine(80, 10, 80, 40, Color::Blue);
42 c.DrawBlockLine(80, 40, mouse_x, mouse_y, Color::Green);
43 return canvas(std::move(c));
44 });
45
46 // A circle following the mouse, using braille characters.
47 auto renderer_circle_braille = Renderer([&] {
48 auto c = Canvas(100, 100);
49 c.DrawText(0, 0, "A circle (braille)");
50 c.DrawPointCircle(mouse_x, mouse_y, 30);
51 return canvas(std::move(c));
52 });
53
54 // A circle following the mouse, using block characters.
55 auto renderer_circle_block = Renderer([&] {
56 auto c = Canvas(100, 100);
57 c.DrawText(0, 0, "A circle (block)");
58 c.DrawBlockCircle(mouse_x, mouse_y, 30);
59 return canvas(std::move(c));
60 });
61
62 // A filled circle following the mouse, using braille characters.
63 auto renderer_circle_filled_braille = Renderer([&] {
64 auto c = Canvas(100, 100);
65 c.DrawText(0, 0, "A circle filled (braille)");
66 c.DrawPointCircleFilled(mouse_x, mouse_y, 30);
67 return canvas(std::move(c));
68 });
69
70 // A filled circle following the mouse, using block characters.
71 auto renderer_circle_filled_block = Renderer([&] {
72 auto c = Canvas(100, 100);
73 c.DrawText(0, 0, "A circle filled (block)");
74 c.DrawBlockCircleFilled(mouse_x, mouse_y, 30);
75 return canvas(std::move(c));
76 });
77
78 // An ellipse following the mouse, using braille characters.
79 auto renderer_ellipse_braille = Renderer([&] {
80 auto c = Canvas(100, 100);
81 c.DrawText(0, 0, "An ellipse (braille)");
82 c.DrawPointEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
83 return canvas(std::move(c));
84 });
85
86 // An ellipse following the mouse, using block characters.
87 auto renderer_ellipse_block = Renderer([&] {
88 auto c = Canvas(100, 100);
89 c.DrawText(0, 0, "An ellipse (block)");
90 c.DrawBlockEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
91 return canvas(std::move(c));
92 });
93
94 // An ellipse following the mouse filled, using braille characters.
95 auto renderer_ellipse_filled_braille = Renderer([&] {
96 auto c = Canvas(100, 100);
97 c.DrawText(0, 0, "A filled ellipse (braille)");
98 c.DrawPointEllipseFilled(mouse_x / 2, mouse_y / 2, mouse_x / 2,
99 mouse_y / 2);
100 return canvas(std::move(c));
101 });
102
103 // An ellipse following the mouse filled, using block characters.
104 auto renderer_ellipse_filled_block = Renderer([&] {
105 auto c = Canvas(100, 100);
106 c.DrawText(0, 0, "A filled ellipse (block)");
107 c.DrawBlockEllipseFilled(mouse_x / 2, mouse_y / 2, mouse_x / 2,
108 mouse_y / 2);
109 c.DrawBlockEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
110 return canvas(std::move(c));
111 });
112
113 // A text following the mouse
114 auto renderer_text = Renderer([&] {
115 auto c = Canvas(100, 100);
116 c.DrawText(0, 0, "A piece of text");
117 c.DrawText(mouse_x, mouse_y, "This is a piece of text with effects",
118 [](Cell& p) {
119 p.foreground_color = Color::Red;
120 p.underlined = true;
121 p.bold = true;
122 });
123 return canvas(std::move(c));
124 });
125
126 auto renderer_plot_1 = Renderer([&] {
127 auto c = Canvas(100, 100);
128 c.DrawText(0, 0, "A graph");
129
130 std::vector<int> ys(100);
131 for (int x = 0; x < 100; x++) {
132 float dx = float(x - mouse_x);
133 float dy = 50.f;
134 ys[x] = int(dy + 20 * cos(dx * 0.14) + 10 * sin(dx * 0.42));
135 }
136 for (int x = 1; x < 99; x++) {
137 c.DrawPointLine(x, ys[x], x + 1, ys[x + 1]);
138 }
139
140 return canvas(std::move(c));
141 });
142
143 auto renderer_plot_2 = Renderer([&] {
144 auto c = Canvas(100, 100);
145 c.DrawText(0, 0, "A symmetrical graph filled");
146 std::vector<int> ys(100);
147 for (int x = 0; x < 100; x++) {
148 ys[x] = int(30 + //
149 10 * cos(x * 0.2 - mouse_x * 0.05) + //
150 5 * sin(x * 0.4) + //
151 5 * sin(x * 0.3 - mouse_y * 0.05)); //
152 }
153 for (int x = 0; x < 100; x++) {
154 c.DrawPointLine(x, 50 + ys[x], x, 50 - ys[x], Color::Red);
155 }
156
157 return canvas(std::move(c));
158 });
159
160 auto renderer_plot_3 = Renderer([&] {
161 auto c = Canvas(100, 100);
162 c.DrawText(0, 0, "A 2D gaussian plot");
163 int size = 15;
164
165 // mouse_x = 5mx + 3*my
166 // mouse_y = 0mx + -5my + 90
167 float my = (mouse_y - 90) / -5.f;
168 float mx = (mouse_x - 3 * my) / 5.f;
169 std::vector<std::vector<float>> ys(size, std::vector<float>(size));
170 for (int y = 0; y < size; y++) {
171 for (int x = 0; x < size; x++) {
172 float dx = x - mx;
173 float dy = y - my;
174 ys[y][x] = -1.5f + 3.0f * std::exp(-0.2f * (dx * dx + dy * dy));
175 }
176 }
177 for (int y = 0; y < size; y++) {
178 for (int x = 0; x < size; x++) {
179 if (x != 0) {
180 c.DrawPointLine(
181 static_cast<int>(5 * (x - 1) + 3 * (y - 0)),
182 static_cast<int>(90 - 5 * (y - 0) - 5 * ys[y][x - 1]),
183 static_cast<int>(5 * (x - 0) + 3 * (y - 0)),
184 static_cast<int>(90 - 5 * (y - 0) - 5 * ys[y][x]));
185 }
186 if (y != 0) {
187 c.DrawPointLine(
188 static_cast<int>(5 * (x - 0) + 3 * (y - 1)),
189 static_cast<int>(90 - 5 * (y - 1) - 5 * ys[y - 1][x]),
190 static_cast<int>(5 * (x - 0) + 3 * (y - 0)),
191 static_cast<int>(90 - 5 * (y - 0) - 5 * ys[y][x]));
192 }
193 }
194 }
195
196 return canvas(std::move(c));
197 });
198
199 int selected_tab = 12;
200 auto tab = Container::Tab(
201 {
202 renderer_line_braille,
203 renderer_line_block,
204 renderer_circle_braille,
205 renderer_circle_block,
206 renderer_circle_filled_braille,
207 renderer_circle_filled_block,
208 renderer_ellipse_braille,
209 renderer_ellipse_block,
210 renderer_ellipse_filled_braille,
211 renderer_ellipse_filled_block,
212
213 renderer_plot_1,
214 renderer_plot_2,
215 renderer_plot_3,
216
217 renderer_text,
218 },
219 &selected_tab);
220
221 // This capture the last mouse position.
222 auto tab_with_mouse = CatchEvent(tab, [&](Event e) {
223 if (e.is_mouse()) {
224 mouse_x = (e.mouse().x - 1) * 2;
225 mouse_y = (e.mouse().y - 1) * 4;
226 }
227 return false;
228 });
229
230 std::vector<std::string> tab_titles = {
231 "line (braille)",
232 "line (block)",
233 "circle (braille)",
234 "circle (block)",
235 "circle filled (braille)",
236 "circle filled (block)",
237 "ellipse (braille)",
238 "ellipse (block)",
239 "ellipse filled (braille)",
240 "ellipse filled (block)",
241 "plot_1 simple",
242 "plot_2 filled",
243 "plot_3 3D",
244 "text",
245 };
246 auto tab_toggle = Menu(&tab_titles, &selected_tab);
247
248 auto component = Container::Horizontal({
249 tab_with_mouse,
250 tab_toggle,
251 });
252
253 // Add some separator to decorate the whole component:
254 auto component_renderer = Renderer(component, [&] {
255 return hbox({
256 tab_with_mouse->Render(),
257 separator(),
258 tab_toggle->Render(),
259 }) |
260 border;
261 });
262
263 auto screen = App::FitComponent();
264 screen.Loop(component_renderer);
265
266 return 0;
267}
int main()
bool is_mouse() const
Definition event.hpp:121
struct Mouse mouse
Definition event.hpp:171
Represent an event. It can be key press event, a terminal resize, or more ...
Definition event.hpp:32
Canvas is a drawable buffer associated with drawing operations.
Definition canvas.hpp:38
Color foreground_color
Definition cell.hpp:52
bool bold
Definition cell.hpp:32
bool underlined
Definition cell.hpp:36
A Unicode character and its associated style.
Definition cell.hpp:18
The FTXUI ftxui:: namespace.
Definition animation.hpp:10