FTXUI  5.0.0
C++ functional terminal UI.
component_options.cpp
Go to the documentation of this file.
1// Copyright 2022 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.
5
6#include <ftxui/dom/linear_gradient.hpp> // for LinearGradient
7#include <ftxui/screen/color.hpp> // for Color, Color::White, Color::Black, Color::GrayDark, Color::Blue, Color::GrayLight, Color::Red
8#include <memory> // for shared_ptr
9#include <utility> // for move
10
11#include "ftxui/component/animation.hpp" // for Function, Duration
12#include "ftxui/dom/elements.hpp" // for operator|=, Element, text, bgcolor, inverted, bold, dim, operator|, color, borderEmpty, hbox, automerge, border, borderLight
13
14namespace ftxui {
15
16/// @brief A color option that can be animated.
17/// @params _inactive The color when the component is inactive.
18/// @params _active The color when the component is active.
19/// @params _duration The duration of the animation.
20/// @params _function The easing function of the animation.
21/// @ingroup component
23 Color _active,
24 animation::Duration _duration,
26 enabled = true;
27 inactive = _inactive;
28 active = _active;
29 duration = _duration;
30 function = std::move(_function);
31}
32
33/// @brief Set how the underline should animate.
34/// @param d The duration of the animation.
35/// @param f The easing function of the animation.
36/// @ingroup component
40 SetAnimationFunction(std::move(f));
41}
42
43/// @brief Set how the underline should animate.
44/// @param d The duration of the animation.
45/// @ingroup component
49}
50
51/// @brief Set how the underline should animate.
52/// @param f The easing function of the animation.
53/// @ingroup component
56 follower_function = std::move(f);
57}
58
59/// @brief Set how the underline should animate.
60/// This is useful to desynchronize the animation of the leader and the
61/// follower.
62/// @param f_leader The duration of the animation for the leader.
63/// @param f_follower The duration of the animation for the follower.
64/// @ingroup component
67 animation::easing::Function f_follower) {
68 leader_function = std::move(f_leader);
69 follower_function = std::move(f_follower);
70}
71
72/// @brief Standard options for an horizontal menu.
73/// This can be useful to implement a tab bar.
74/// @ingroup component
75// static
77 MenuOption option;
79 option.entries_option.transform = [](const EntryState& state) {
80 Element e = text(state.label);
81 if (state.focused) {
82 e |= inverted;
83 }
84 if (state.active) {
85 e |= bold;
86 }
87 if (!state.focused && !state.active) {
88 e |= dim;
89 }
90 return e;
91 };
92 option.elements_infix = [] { return text(" "); };
93
94 return option;
95}
96
97/// @brief Standard options for an animated horizontal menu.
98/// This can be useful to implement a tab bar.
99/// @ingroup component
100// static
102 auto option = Horizontal();
103 option.underline.enabled = true;
104 return option;
105}
106
107/// @brief Standard options for a vertical menu.
108/// This can be useful to implement a list of selectable items.
109/// @ingroup component
110// static
112 MenuOption option;
113 option.entries_option.transform = [](const EntryState& state) {
114 Element e = text((state.active ? "> " : " ") + state.label); // NOLINT
115 if (state.focused) {
116 e |= inverted;
117 }
118 if (state.active) {
119 e |= bold;
120 }
121 if (!state.focused && !state.active) {
122 e |= dim;
123 }
124 return e;
125 };
126 return option;
127}
128
129/// @brief Standard options for an animated vertical menu.
130/// This can be useful to implement a list of selectable items.
131/// @ingroup component
132// static
134 auto option = MenuOption::Vertical();
135 option.entries_option.transform = [](const EntryState& state) {
136 Element e = text(state.label);
137 if (state.focused) {
138 e |= inverted;
139 }
140 if (state.active) {
141 e |= bold;
142 }
143 if (!state.focused && !state.active) {
144 e |= dim;
145 }
146 return e;
147 };
148 option.underline.enabled = true;
149 return option;
150}
151
152/// @brief Standard options for a horitontal menu with some separator.
153/// This can be useful to implement a tab bar.
154/// @ingroup component
155// static
157 auto option = MenuOption::Horizontal();
158 option.elements_infix = [] { return text("│") | automerge; };
159 return option;
160}
161
162/// @brief Create a ButtonOption, highlighted using [] characters.
163/// @ingroup component
164// static
166 ButtonOption option;
167 option.transform = [](const EntryState& s) {
168 const std::string t = s.focused ? "[" + s.label + "]" //
169 : " " + s.label + " ";
170 return text(t);
171 };
172 return option;
173}
174
175/// @brief Create a ButtonOption, inverted when focused.
176/// @ingroup component
177// static
179 ButtonOption option;
180 option.transform = [](const EntryState& s) {
181 auto element = text(s.label) | borderLight;
182 if (s.focused) {
183 element |= inverted;
184 }
185 return element;
186 };
187 return option;
188}
189
190/// @brief Create a ButtonOption. The button is shown using a border, inverted
191/// when focused. This is the current default.
192/// @ingroup component
194 ButtonOption option;
195 option.transform = [](const EntryState& s) {
196 auto element = text(s.label) | border;
197 if (s.active) {
198 element |= bold;
199 }
200 if (s.focused) {
201 element |= inverted;
202 }
203 return element;
204 };
205 return option;
206}
207
208/// @brief Create a ButtonOption, using animated colors.
209/// @ingroup component
210// static
214}
215
216/// @brief Create a ButtonOption, using animated colors.
217/// @ingroup component
218// static
221 Color::Interpolate(0.85F, color, Color::Black), // NOLINT
222 Color::Interpolate(0.10F, color, Color::White), // NOLINT
223 Color::Interpolate(0.10F, color, Color::Black), // NOLINT
224 Color::Interpolate(0.85F, color, Color::White)); // NOLINT
225}
226
227/// @brief Create a ButtonOption, using animated colors.
228/// @ingroup component
229// static
231 // NOLINTBEGIN
233 /*bakground=*/background,
234 /*foreground=*/foreground,
235 /*background_active=*/foreground,
236 /*foreground_active=*/background);
237 // NOLINTEND
238}
239
240/// @brief Create a ButtonOption, using animated colors.
241/// @ingroup component
242// static
244 Color foreground,
245 Color background_active,
246 Color foreground_active) {
247 ButtonOption option;
248 option.transform = [](const EntryState& s) {
249 auto element = text(s.label) | borderEmpty;
250 if (s.focused) {
251 element |= bold;
252 }
253 return element;
254 };
255 option.animated_colors.foreground.Set(foreground, foreground_active);
256 option.animated_colors.background.Set(background, background_active);
257 return option;
258}
259
260/// @brief Option for standard Checkbox.
261/// @ingroup component
262// static
264 auto option = CheckboxOption();
265 option.transform = [](const EntryState& s) {
266#if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
267 // Microsoft terminal do not use fonts able to render properly the default
268 // radiobox glyph.
269 auto prefix = text(s.state ? "[X] " : "[ ] "); // NOLINT
270#else
271 auto prefix = text(s.state ? "▣ " : "☐ "); // NOLINT
272#endif
273 auto t = text(s.label);
274 if (s.active) {
275 t |= bold;
276 }
277 if (s.focused) {
278 t |= inverted;
279 }
280 return hbox({prefix, t});
281 };
282 return option;
283}
284
285/// @brief Option for standard Radiobox
286/// @ingroup component
287// static
289 auto option = RadioboxOption();
290 option.transform = [](const EntryState& s) {
291#if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
292 // Microsoft terminal do not use fonts able to render properly the default
293 // radiobox glyph.
294 auto prefix = text(s.state ? "(*) " : "( ) "); // NOLINT
295#else
296 auto prefix = text(s.state ? "◉ " : "○ "); // NOLINT
297#endif
298 auto t = text(s.label);
299 if (s.active) {
300 t |= bold;
301 }
302 if (s.focused) {
303 t |= inverted;
304 }
305 return hbox({prefix, t});
306 };
307 return option;
308}
309
310/// @brief Standard options for the input component.
311/// @ingroup component
312// static
314 InputOption option;
315 option.transform = [](InputState state) {
316 state.element |= color(Color::White);
317
318 if (state.is_placeholder) {
319 state.element |= dim;
320 }
321
322 if (state.focused) {
323 state.element |= inverted;
324 } else if (state.hovered) {
325 state.element |= bgcolor(Color::GrayDark);
326 }
327
328 return state.element;
329 };
330 return option;
331}
332
333/// @brief Standard options for a more beautiful input component.
334/// @ingroup component
335// static
337 InputOption option;
338 option.transform = [](InputState state) {
339 state.element |= borderEmpty;
340 state.element |= color(Color::White);
341
342 if (state.is_placeholder) {
343 state.element |= dim;
344 }
345
346 if (state.focused) {
347 state.element |= bgcolor(Color::Black);
348 }
349
350 if (state.hovered) {
351 state.element |= bgcolor(Color::GrayDark);
352 }
353
354 return state.element;
355 };
356 return option;
357}
358
359} // namespace ftxui
A class representing terminal colors.
Definition: color.hpp:21
static Color Interpolate(float t, const Color &a, const Color &b)
Definition: color.cpp:217
std::function< float(float)> Function
Definition: animation.hpp:39
std::chrono::duration< float > Duration
Definition: animation.hpp:24
Decorator bgcolor(Color)
Decorate using a background color.
Definition: color.cpp:124
AnimatedColorOption foreground
std::shared_ptr< Node > Element
Definition: elements.hpp:23
Element bold(Element)
Use a bold font, for elements with more emphasis.
Definition: bold.cpp:33
AnimatedColorOption background
Element hbox(Elements)
A container displaying elements horizontally one by one.
Definition: hbox.cpp:83
std::function< Element(const EntryState &state)> transform
Element inverted(Element)
Add a filter that will invert the foreground and the background colors.
Definition: inverted.cpp:34
Element text(std::wstring text)
Display a piece of unicode text.
Definition: text.cpp:120
Element borderLight(Element)
Draw a dashed border around the element.
Definition: border.cpp:335
Element dim(Element)
Use a light font, for elements with less emphasis.
Definition: dim.cpp:33
Element automerge(Element child)
Enable character to be automatically merged with others nearby.
Definition: automerge.cpp:17
Element border(Element)
Draw a border around the element.
Definition: border.cpp:227
Element borderEmpty(Element)
Draw an empty border around the element.
Definition: border.cpp:475
Decorator color(Color)
Decorate using a foreground color.
Definition: color.cpp:110
arguments for |ButtonOption::transform|, |CheckboxOption::transform|, |Radiobox::transform|,...
Used to define style for the Input component.
animation::easing::Function function
animation::Duration duration
void Set(Color inactive, Color active, animation::Duration duration=std::chrono::milliseconds(250), animation::easing::Function function=animation::easing::QuadraticInOut)
A color option that can be animated. @params _inactive The color when the component is inactive....
Option for the AnimatedButton component.
static ButtonOption Animated()
Create a ButtonOption, using animated colors.
static ButtonOption Border()
Create a ButtonOption. The button is shown using a border, inverted when focused. This is the current...
static ButtonOption Simple()
Create a ButtonOption, inverted when focused.
static ButtonOption Ascii()
Create a ButtonOption, highlighted using [] characters.
AnimatedColorsOption animated_colors
std::function< Element(const EntryState &)> transform
Option for the Checkbox component.
static CheckboxOption Simple()
Option for standard Checkbox.
Option for the Input component.
static InputOption Default()
Create the default input style:
static InputOption Spacious()
A white on black style with high margins:
std::function< Element(InputState)> transform
Option for the Menu component.
static MenuOption Toggle()
Standard options for a horitontal menu with some separator. This can be useful to implement a tab bar...
MenuEntryOption entries_option
static MenuOption Horizontal()
Standard options for an horizontal menu. This can be useful to implement a tab bar.
static MenuOption VerticalAnimated()
Standard options for an animated vertical menu. This can be useful to implement a list of selectable ...
static MenuOption Vertical()
Standard options for a vertical menu. This can be useful to implement a list of selectable items.
std::function< Element()> elements_infix
static MenuOption HorizontalAnimated()
Standard options for an animated horizontal menu. This can be useful to implement a tab bar.
Option for the Radiobox component.
static RadioboxOption Simple()
Option for standard Radiobox.
animation::Duration follower_duration
animation::easing::Function leader_function
void SetAnimationFunction(animation::easing::Function f)
Set how the underline should animate.
animation::Duration leader_duration
void SetAnimation(animation::Duration d, animation::easing::Function f)
Set how the underline should animate.
void SetAnimationDuration(animation::Duration d)
Set how the underline should animate.
animation::easing::Function follower_function