FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
src/ftxui/component/button.cpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved. (ja: 無断複写・転載を禁じます。)
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file. (ja: このソースコードの使用は、LICENSEファイルにあるMITライセンスによって管理されています。)
4
5#include <functional> // for function
6#include <utility> // for move
7
8#include "ftxui/component/animation.hpp" // for Animator, Params (ptr only)
9#include "ftxui/component/component.hpp" // for Make, Button
10#include "ftxui/component/component_base.hpp" // for ComponentBase
11#include "ftxui/component/component_options.hpp" // for ButtonOption, AnimatedColorOption, AnimatedColorsOption, EntryState
12#include "ftxui/component/event.hpp" // for Event, Event::Return
13#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Pressed
14#include "ftxui/component/screen_interactive.hpp" // for Component
15#include "ftxui/dom/elements.hpp" // for operator|, Decorator, Element, operator|=, bgcolor, color, reflect, text, bold, border, inverted, nothing
16#include "ftxui/screen/box.hpp" // for Box
17#include "ftxui/screen/color.hpp" // for Color
18#include "ftxui/util/ref.hpp" // for Ref, ConstStringRef
19
20namespace ftxui {
21
22namespace {
23
24Element DefaultTransform(EntryState params) { // NOLINT
25 auto element = text(params.label) | border;
26 if (params.active) {
27 element |= bold;
28 }
29 if (params.focused) {
30 element |= inverted;
31 }
32 return element;
33}
34
35class ButtonBase : public ComponentBase, public ButtonOption {
36 public:
37 explicit ButtonBase(ButtonOption option) : ButtonOption(std::move(option)) {}
38
39 // Component implementation:
40 Element OnRender() override {
41 const bool active = Active();
42 const bool focused = Focused();
43 const bool focused_or_hover = focused || mouse_hover_;
44
45 float target = focused_or_hover ? 1.f : 0.f; // NOLINT
46 if (target != animator_background_.to()) {
47 SetAnimationTarget(target);
48 }
49
50 const EntryState state{
51 *label, false, active, focused_or_hover, Index(),
52 };
53
54 auto element = (transform ? transform : DefaultTransform) //
55 (state);
56 element |= AnimatedColorStyle();
57 element |= focus;
58 element |= reflect(box_);
59 return element;
60 }
61
62 Decorator AnimatedColorStyle() {
63 Decorator style = nothing;
64 if (animated_colors.background.enabled) {
65 style = style |
66 bgcolor(Color::Interpolate(animation_foreground_, //
67 animated_colors.background.inactive,
68 animated_colors.background.active));
69 }
70 if (animated_colors.foreground.enabled) {
71 style =
72 style | color(Color::Interpolate(animation_foreground_, //
73 animated_colors.foreground.inactive,
74 animated_colors.foreground.active));
75 }
76 return style;
77 }
78
79 void SetAnimationTarget(float target) {
80 if (animated_colors.foreground.enabled) {
81 animator_foreground_ = animation::Animator(
82 &animation_foreground_, target, animated_colors.foreground.duration,
83 animated_colors.foreground.function);
84 }
85 if (animated_colors.background.enabled) {
86 animator_background_ = animation::Animator(
87 &animation_background_, target, animated_colors.background.duration,
88 animated_colors.background.function);
89 }
90 }
91
92 void OnAnimation(animation::Params& p) override {
93 animator_background_.OnAnimation(p);
94 animator_foreground_.OnAnimation(p);
95 }
96
97 void OnClick() {
98 animation_background_ = 0.5F; // NOLINT
99 animation_foreground_ = 0.5F; // NOLINT
100 SetAnimationTarget(1.F); // NOLINT
101
102 // TODO(arthursonzogni): Consider posting the task to the main loop, instead
103 // of invoking it immediately. (ja: タスクをすぐに呼び出すのではなく、メインループにポストすることを検討してください。)
104 on_click(); // May delete this.
105 }
106
107 bool OnEvent(Event event) override {
108 if (event.is_mouse()) {
109 return OnMouseEvent(event);
110 }
111
112 if (event == Event::Return) {
113 OnClick(); // May delete this.
114 return true;
115 }
116 return false;
117 }
118
119 bool OnMouseEvent(Event event) {
120 mouse_hover_ =
121 box_.Contain(event.mouse().x, event.mouse().y) && CaptureMouse(event);
122
123 if (!mouse_hover_) {
124 return false;
125 }
126
127 if (event.mouse().button == Mouse::Left &&
128 event.mouse().motion == Mouse::Pressed) {
129 TakeFocus();
130 OnClick(); // May delete this.
131 return true;
132 }
133
134 return false;
135 }
136
137 bool Focusable() const final { return true; }
138
139 private:
140 bool mouse_hover_ = false;
141 Box box_;
142 float animation_background_ = 0;
143 float animation_foreground_ = 0;
144 animation::Animator animator_background_ =
145 animation::Animator(&animation_background_);
146 animation::Animator animator_foreground_ =
147 animation::Animator(&animation_foreground_);
148};
149
150} // namespace
151
152/// @brief Draw a button. Execute a function when clicked. (ja: ボタンを描画します。クリックされたときに機能を実行します。)
153/// @param option Additional optional parameters. (ja: その他のオプションパラメーター。)
154/// @ingroup component
155/// @see ButtonBase
156///
157/// ### Example (ja: 例)
158///
159/// ```cpp
160/// auto screen = ScreenInteractive::FitComponent();
161/// Component button = Button({
162/// .label = "Click to quit",
163/// .on_click = screen.ExitLoopClosure(),
164/// });
165/// screen.Loop(button)
166/// ```
167///
168/// ### Output (ja: 出力)
169///
170/// ```bash
171/// ┌─────────────┐
172/// │Click to quit│
173/// └─────────────┘
174/// ```
176 return Make<ButtonBase>(std::move(option));
177}
178
179/// @brief Draw a button. Execute a function when clicked. (ja: ボタンを描画します。クリックされたときに機能を実行します。)
180/// @param label The label of the button. (ja: ボタンのラベル。)
181/// @param on_click The action to execute when clicked. (ja: クリックされたときに実行するアクション。)
182/// @param option Additional optional parameters. (ja: その他のオプションパラメーター。)
183/// @ingroup component
184/// @see ButtonBase
185///
186/// ### Example (ja: 例)
187///
188/// ```cpp
189/// auto screen = ScreenInteractive::FitComponent();
190/// std::string label = "Click to quit";
191/// Component button = Button(&label, screen.ExitLoopClosure());
192/// screen.Loop(button)
193/// ```
194///
195/// ### Output (ja: 出力)
196///
197/// ```bash
198/// ┌─────────────┐
199/// │Click to quit│
200/// └─────────────┘
201/// ```
202// NOLINTNEXTLINE
204 std::function<void()> on_click,
205 ButtonOption option) {
206 option.label = std::move(label);
207 option.on_click = std::move(on_click);
208 return Make<ButtonBase>(std::move(option));
209}
210
211} // namespace ftxui
アダプター。定数文字列を所有または参照します。便宜上、このクラスは複数の不変文字列を共有表現に変換します。
Definition ref.hpp:91
std::function< void()> on_click
static const Event Return
Definition event.hpp:52
Component Button(ButtonOption options)
Draw a button. Execute a function when clicked. (ja: ボタンを描画します。クリックされたときに機能を実行します。)
AnimatedButtonコンポーネントのオプション。
Decorator bgcolor(Color)
背景色を使用して装飾します。
Element nothing(Element element)
何も行わないデコレーションです。
Definition dom/util.cpp:28
Element bold(Element)
より強調したい要素に、太字フォントを使用します。
Definition bold.cpp:33
Element inverted(Element)
前景色と背景色を反転させるフィルターを追加します。
Definition inverted.cpp:32
Element text(std::wstring text)
ユニコードテキストを表示します。
Definition text.cpp:160
Element focus(Element)
子要素を兄弟要素の中でフォーカスされたものとして設定します。
Definition frame.cpp:101
Decorator color(Color)
前景色を使用して装飾します。
static Color Interpolate(float t, const Color &a, const Color &b)
FTXUI ftxui:: 名前空間
Definition animation.hpp:9
std::function< Element(Element)> Decorator
Definition elements.hpp:23
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:26
std::shared_ptr< Node > Element
Definition elements.hpp:21
Element border(Element)
Decorator reflect(Box &box)
Definition reflect.cpp:42
std::shared_ptr< ComponentBase > Component