FTXUI 6.1.9
C++ functional terminal UI.
载入中...
搜索中...
未找到
canvas_animated.cpp
浏览该文件的文档.
1// 版权所有 2021 Arthur Sonzogni。保留所有权利。
2// 此源代码的使用受 MIT 许可证的约束,该许可证可在以下位置找到
3// LICENSED 文件。
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 // 一个跟随鼠标的三角形,使用盲文符号。
27 auto renderer_line_braille = Renderer([&] {
28 auto c = Canvas(100, 100);
29 c.DrawText(0, 0, "多条线(盲文)");
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 // 一个跟随鼠标的三角形,使用块状符号。
37 auto renderer_line_block = Renderer([&] {
38 auto c = Canvas(100, 100);
39 c.DrawText(0, 0, "多条线(块状)");
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 // 一个跟随鼠标的圆形,使用盲文符号。
47 auto renderer_circle_braille = Renderer([&] {
48 auto c = Canvas(100, 100);
49 c.DrawText(0, 0, "一个圆形(盲文)");
50 c.DrawPointCircle(mouse_x, mouse_y, 30);
51 return canvas(std::move(c));
52 });
53
54 // 一个跟随鼠标的圆形,使用块状符号。
55 auto renderer_circle_block = Renderer([&] {
56 auto c = Canvas(100, 100);
57 c.DrawText(0, 0, "一个圆形(块状)");
58 c.DrawBlockCircle(mouse_x, mouse_y, 30);
59 return canvas(std::move(c));
60 });
61
62 // 一个跟随鼠标的填充圆形,使用盲文符号。
63 auto renderer_circle_filled_braille = Renderer([&] {
64 auto c = Canvas(100, 100);
65 c.DrawText(0, 0, "一个填充圆形(盲文)");
66 c.DrawPointCircleFilled(mouse_x, mouse_y, 30);
67 return canvas(std::move(c));
68 });
69
70 // 一个跟随鼠标的填充圆形,使用块状符号。
71 auto renderer_circle_filled_block = Renderer([&] {
72 auto c = Canvas(100, 100);
73 c.DrawText(0, 0, "一个填充圆形(块状)");
74 c.DrawBlockCircleFilled(mouse_x, mouse_y, 30);
75 return canvas(std::move(c));
76 });
77
78 // 一个跟随鼠标的椭圆形,使用盲文符号。
79 auto renderer_ellipse_braille = Renderer([&] {
80 auto c = Canvas(100, 100);
81 c.DrawText(0, 0, "一个椭圆形(盲文)");
82 c.DrawPointEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
83 return canvas(std::move(c));
84 });
85
86 // 一个跟随鼠标的椭圆形,使用块状符号。
87 auto renderer_ellipse_block = Renderer([&] {
88 auto c = Canvas(100, 100);
89 c.DrawText(0, 0, "一个椭圆形(块状)");
90 c.DrawBlockEllipse(mouse_x / 2, mouse_y / 2, mouse_x / 2, mouse_y / 2);
91 return canvas(std::move(c));
92 });
93
94 // 一个跟随鼠标的填充椭圆形,使用盲文符号。
95 auto renderer_ellipse_filled_braille = Renderer([&] {
96 auto c = Canvas(100, 100);
97 c.DrawText(0, 0, "一个填充椭圆形(盲文)");
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 // 一个跟随鼠标的填充椭圆形,使用块状符号。
104 auto renderer_ellipse_filled_block = Renderer([&] {
105 auto c = Canvas(100, 100);
106 c.DrawText(0, 0, "一个填充椭圆形(块状)");
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 // 跟随鼠标的文本
114 auto renderer_text = Renderer([&] {
115 auto c = Canvas(100, 100);
116 c.DrawText(0, 0, "一段文本");
117 c.DrawText(mouse_x, mouse_y, "这是一段带有效果的文本",
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, "一个图表");
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, "一个对称填充图表");
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, "一个二维高斯图");
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.5 + 3.0 * 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 5 * (x - 1) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x - 1],
182 5 * (x - 0) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x]);
183 }
184 if (y != 0) {
185 c.DrawPointLine(
186 5 * (x - 0) + 3 * (y - 1), 90 - 5 * (y - 1) - 5 * ys[y - 1][x],
187 5 * (x - 0) + 3 * (y - 0), 90 - 5 * (y - 0) - 5 * ys[y][x]);
188 }
189 }
190 }
191
192 return canvas(std::move(c));
193 });
194
195 int selected_tab = 12;
196 auto tab = Container::Tab(
197 {
198 renderer_line_braille,
199 renderer_line_block,
200 renderer_circle_braille,
201 renderer_circle_block,
202 renderer_circle_filled_braille,
203 renderer_circle_filled_block,
204 renderer_ellipse_braille,
205 renderer_ellipse_block,
206 renderer_ellipse_filled_braille,
207 renderer_ellipse_filled_block,
208
209 renderer_plot_1,
210 renderer_plot_2,
211 renderer_plot_3,
212
213 renderer_text,
214 },
215 &selected_tab);
216
217 // 这捕获了鼠标的最后位置。
218 auto tab_with_mouse = CatchEvent(tab, [&](Event e) {
219 if (e.is_mouse()) {
220 mouse_x = (e.mouse().x - 1) * 2;
221 mouse_y = (e.mouse().y - 1) * 4;
222 }
223 return false;
224 });
225
226 std::vector<std::string> tab_titles = {
227 "线(盲文)",
228 "线(块状)",
229 "圆形(盲文)",
230 "圆形(块状)",
231 "填充圆形(盲文)",
232 "填充圆形(块状)",
233 "椭圆形(盲文)",
234 "椭圆形(块状)",
235 "填充椭圆形(盲文)",
236 "填充椭圆形(块状)",
237
238 "图表1 简单",
239 "图表2 填充",
240 "图表3 3D",
241
242 "文本",
243 };
244 auto tab_toggle = Menu(&tab_titles, &selected_tab);
245
246 auto component = Container::Horizontal({
247 tab_with_mouse,
248 tab_toggle,
249 });
250
251 // 添加一些分隔符来装饰整个组件:
252 auto component_renderer = Renderer(component, [&] {
253 return hbox({
254 tab_with_mouse->Render(),
255 separator(),
256 tab_toggle->Render(),
257 }) |
258 border;
259 });
260
261 auto screen = ScreenInteractive::FitComponent();
262 screen.Loop(component_renderer);
263
264 return 0;
265}
bool is_mouse() const
struct Mouse mouse
代表一个事件。它可以是按键事件、终端大小调整等等...
Canvas 是一个与绘图操作相关的可绘制缓冲区。
Color foreground_color
一个 Unicode 字符及其相关样式。
#include "ftxui/component/component_base.hpp" // 用于 ComponentBase