FTXUI  4.1.1
C++ functional terminal UI.
Loading...
Searching...
No Matches
button.cpp
Go to the documentation of this file.
1#include <functional> // for function
2#include <memory> // for shared_ptr
3#include <utility> // for move
4
5#include "ftxui/component/animation.hpp" // for Animator, Params (ptr only)
6#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
7#include "ftxui/component/component.hpp" // for Make, Button
8#include "ftxui/component/component_base.hpp" // for ComponentBase
9#include "ftxui/component/component_options.hpp" // for ButtonOption, AnimatedColorOption, AnimatedColorsOption, EntryState
10#include "ftxui/component/event.hpp" // for Event, Event::Return
11#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Pressed
12#include "ftxui/component/screen_interactive.hpp" // for Component
13#include "ftxui/dom/elements.hpp" // for operator|, Decorator, Element, operator|=, bgcolor, color, reflect, text, bold, border, inverted, nothing
14#include "ftxui/screen/box.hpp" // for Box
15#include "ftxui/screen/color.hpp" // for Color
16#include "ftxui/util/ref.hpp" // for Ref, ConstStringRef
17
18namespace ftxui {
19
20namespace {
21
22Element DefaultTransform(EntryState params) { // NOLINT
23 auto element = text(params.label) | border;
24 if (params.active) {
25 element |= bold;
26 }
27 if (params.focused) {
28 element |= inverted;
29 }
30 return element;
31}
32
33} // namespace
34
35/// @brief Draw a button. Execute a function when clicked.
36/// @param label The label of the button.
37/// @param on_click The action to execute when clicked.
38/// @param option Additional optional parameters.
39/// @ingroup component
40/// @see ButtonBase
41///
42/// ### Example
43///
44/// ```cpp
45/// auto screen = ScreenInteractive::FitComponent();
46/// std::string label = "Click to quit";
47/// Component button = Button(&label, screen.ExitLoopClosure());
48/// screen.Loop(button)
49/// ```
50///
51/// ### Output
52///
53/// ```bash
54/// ┌─────────────┐
55/// │Click to quit│
56/// └─────────────┘
57/// ```
58// NOLINTNEXTLINE(readability-function-cognitive-complexity)
60 std::function<void()> on_click,
61 Ref<ButtonOption> option) {
62 class Impl : public ComponentBase {
63 public:
64 Impl(ConstStringRef label,
65 std::function<void()> on_click,
66 Ref<ButtonOption> option)
67 : label_(std::move(label)),
68 on_click_(std::move(on_click)),
69 option_(std::move(option)) {}
70
71 // Component implementation:
72 Element Render() override {
73 const bool active = Active();
74 const bool focused = Focused();
75 const bool focused_or_hover = focused || mouse_hover_;
76
77 float target = focused_or_hover ? 1.F : 0.F; // NOLINT
78 if (target != animator_background_.to()) {
79 SetAnimationTarget(target);
80 }
81
82 auto focus_management = focused ? focus : active ? select : nothing;
83 const EntryState state = {
84 *label_,
85 false,
86 active,
87 focused_or_hover,
88 };
89
90 auto element =
91 (option_->transform ? option_->transform : DefaultTransform) //
92 (state);
93 return element | AnimatedColorStyle() | focus_management | reflect(box_);
94 }
95
96 Decorator AnimatedColorStyle() {
97 Decorator style = nothing;
98 if (option_->animated_colors.background.enabled) {
99 style = style | bgcolor(Color::Interpolate(
100 animation_foreground_, //
101 option_->animated_colors.background.inactive,
102 option_->animated_colors.background.active));
103 }
104 if (option_->animated_colors.foreground.enabled) {
105 style = style | color(Color::Interpolate(
106 animation_foreground_, //
107 option_->animated_colors.foreground.inactive,
108 option_->animated_colors.foreground.active));
109 }
110 return style;
111 }
112
113 void SetAnimationTarget(float target) {
114 if (option_->animated_colors.foreground.enabled) {
115 animator_foreground_ =
116 animation::Animator(&animation_foreground_, target,
117 option_->animated_colors.foreground.duration,
118 option_->animated_colors.foreground.function);
119 }
120 if (option_->animated_colors.background.enabled) {
121 animator_background_ =
122 animation::Animator(&animation_background_, target,
123 option_->animated_colors.background.duration,
124 option_->animated_colors.background.function);
125 }
126 }
127
128 void OnAnimation(animation::Params& p) override {
129 animator_background_.OnAnimation(p);
130 animator_foreground_.OnAnimation(p);
131 }
132
133 void OnClick() {
134 on_click_();
135 animation_background_ = 0.5F; // NOLINT
136 animation_foreground_ = 0.5F; // NOLINT
137 SetAnimationTarget(1.F); // NOLINT
138 }
139
140 bool OnEvent(Event event) override {
141 if (event.is_mouse()) {
142 return OnMouseEvent(event);
143 }
144
145 if (event == Event::Return) {
146 OnClick();
147 return true;
148 }
149 return false;
150 }
151
152 bool OnMouseEvent(Event event) {
153 mouse_hover_ =
154 box_.Contain(event.mouse().x, event.mouse().y) && CaptureMouse(event);
155
156 if (!mouse_hover_) {
157 return false;
158 }
159
160 if (event.mouse().button == Mouse::Left &&
161 event.mouse().motion == Mouse::Pressed) {
162 TakeFocus();
163 OnClick();
164 return true;
165 }
166
167 return false;
168 }
169
170 bool Focusable() const final { return true; }
171
172 private:
173 ConstStringRef label_;
174 std::function<void()> on_click_;
175 bool mouse_hover_ = false;
176 Box box_;
177 Ref<ButtonOption> option_;
178 float animation_background_ = 0;
179 float animation_foreground_ = 0;
180 animation::Animator animator_background_ =
181 animation::Animator(&animation_background_);
182 animation::Animator animator_foreground_ =
183 animation::Animator(&animation_foreground_);
184 };
185
186 return Make<Impl>(std::move(label), std::move(on_click), std::move(option));
187}
188
189} // namespace ftxui
190
191// Copyright 2020 Arthur Sonzogni. All rights reserved.
192// Use of this source code is governed by the MIT license that can be found in
193// the LICENSE file.
It implement rendering itself as ftxui::Element. It implement keyboard navigation by responding to ft...
An adapter. Own or reference a constant string. For convenience, this class convert multiple immutabl...
Definition ref.hpp:60
An adapter. Own or reference an mutable object.
Definition ref.hpp:27
Decorator bgcolor(Color)
Decorate using a background color.
Definition color.cpp:100
std::function< Element(Element)> Decorator
Definition elements.hpp:21
Element nothing(Element element)
A decoration doing absolutely nothing.
Definition util.cpp:27
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:25
std::shared_ptr< Node > Element
Definition elements.hpp:19
Element bold(Element)
Use a bold font, for elements with more emphasis.
Definition bold.cpp:28
Element focus(Element)
Definition frame.cpp:83
Element inverted(Element)
Add a filter that will invert the foreground and the background colors.
Definition inverted.cpp:29
Component Button(ConstStringRef label, std::function< void()> on_click, Ref< ButtonOption >=ButtonOption::Simple())
Draw a button. Execute a function when clicked.
Definition button.cpp:59
Element text(std::wstring text)
Display a piece of unicode text.
Definition text.cpp:111
Decorator reflect(Box &box)
Definition reflect.cpp:39
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Definition node.cpp:44
Element border(Element)
Draw a border around the element.
Definition border.cpp:222
Element select(Element)
Definition frame.cpp:38
std::shared_ptr< ComponentBase > Component
Decorator color(Color)
Decorate using a foreground color.
Definition color.cpp:86
arguments for |ButtonOption::transform|, |CheckboxOption::transform|, |Radiobox::transform|,...
Represent an event. It can be key press event, a terminal resize, or more ...
Definition event.hpp:26
bool is_mouse() const
Definition event.hpp:68
struct Mouse & mouse()
Definition event.hpp:69
Button button
Definition mouse.hpp:24
Motion motion
Definition mouse.hpp:27