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 Pixel
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/component.hpp" // for Renderer, CatchEvent, Horizontal, Menu, Tab
13#include "ftxui/component/component_base.hpp" // for ComponentBase
14#include "ftxui/component/event.hpp" // for Event
15#include "ftxui/component/mouse.hpp" // for Mouse
16#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive
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 [](Pixel& 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 return canvas(std::move(c));
140 });
141
142 auto renderer_plot_2 = Renderer([&] {
143 auto c = Canvas(100, 100);
144 c.DrawText(0, 0, "A symmetrical graph filled");
145 std::vector<int> ys(100);
146 for (int x = 0; x < 100; x++) {
147 ys[x] = int(30 + //
148 10 * cos(x * 0.2 - mouse_x * 0.05) + //
149 5 * sin(x * 0.4) + //
150 5 * sin(x * 0.3 - mouse_y * 0.05)); //
151 }
152 for (int x = 0; x < 100; x++) {
153 c.DrawPointLine(x, 50 + ys[x], x, 50 - ys[x], Color::Red);
154 }
155
156 return canvas(std::move(c));
157 });
158
159 auto renderer_plot_3 = Renderer([&] {
160 auto c = Canvas(100, 100);
161 c.DrawText(0, 0, "A 2D gaussian plot");
162 int size = 15;
163
164 // mouse_x = 5mx + 3*my
165 // mouse_y = 0mx + -5my + 90
166 float my = (mouse_y - 90) / -5.f;
167 float mx = (mouse_x - 3 * my) / 5.f;
168 std::vector<std::vector<float>> ys(size, std::vector<float>(size));
169 for (int y = 0; y < size; y++) {
170 for (int x = 0; x < size; x++) {
171 float dx = x - mx;
172 float dy = y - my;
173 ys[y][x] = -1.5 + 3.0 * std::exp(-0.2f * (dx * dx + dy * dy));
174 }
175 }
176 for (int y = 0; y < size; y++) {
177 for (int x = 0; x < size; x++) {
178 if (x != 0) {
179 c.DrawPointLine(
180 5 * (x - 1) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x - 1],
181 5 * (x - 0) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x]);
182 }
183 if (y != 0) {
184 c.DrawPointLine(
185 5 * (x - 0) + 3 * (y - 1), 90 - 5 * (y - 1) - 5 * ys[y - 1][x],
186 5 * (x - 0) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x]);
187 }
188 }
189 }
190
191 return canvas(std::move(c));
192 });
193
194 int selected_tab = 12;
195 auto tab = Container::Tab(
196 {
197 renderer_line_braille,
198 renderer_line_block,
199 renderer_circle_braille,
200 renderer_circle_block,
201 renderer_circle_filled_braille,
202 renderer_circle_filled_block,
203 renderer_ellipse_braille,
204 renderer_ellipse_block,
205 renderer_ellipse_filled_braille,
206 renderer_ellipse_filled_block,
207
208 renderer_plot_1,
209 renderer_plot_2,
210 renderer_plot_3,
211
212 renderer_text,
213 },
214 &selected_tab);
215
216 // This capture the last mouse position.
217 auto tab_with_mouse = CatchEvent(tab, [&](Event e) {
218 if (e.is_mouse()) {
219 mouse_x = (e.mouse().x - 1) * 2;
220 mouse_y = (e.mouse().y - 1) * 4;
221 }
222 return false;
223 });
224
225 std::vector<std::string> tab_titles = {
226 "line (braille)",
227 "line (block)",
228 "circle (braille)",
229 "circle (block)",
230 "circle filled (braille)",
231 "circle filled (block)",
232 "ellipse (braille)",
233 "ellipse (block)",
234 "ellipse filled (braille)",
235 "ellipse filled (block)",
236 "plot_1 simple",
237 "plot_2 filled",
238 "plot_3 3D",
239 "text",
240 };
241 auto tab_toggle = Menu(&tab_titles, &selected_tab);
242
243 auto component = Container::Horizontal({
244 tab_with_mouse,
245 tab_toggle,
246 });
247
248 // Add some separator to decorate the whole component:
249 auto component_renderer = Renderer(component, [&] {
250 return hbox({
251 tab_with_mouse->Render(),
252 separator(),
253 tab_toggle->Render(),
254 }) |
255 border;
256 });
257
258 auto screen = ScreenInteractive::FitComponent();
259 screen.Loop(component_renderer);
260
261 return 0;
262}
int main()
bool is_mouse() const
Definition event.hpp:109
struct Mouse mouse
Definition event.hpp:144
Represent an event. It can be key press event, a terminal resize, or more ...
Definition event.hpp:29
Canvas is a drawable buffer associated with drawing operations.
Definition canvas.hpp:38
Color foreground_color
Definition pixel.hpp:49
bool bold
Definition pixel.hpp:29
bool underlined
Definition pixel.hpp:33
A Unicode character and its associated style.
Definition pixel.hpp:15
The FTXUI ftxui:: namespace.
Definition animation.hpp:10