FTXUI 6.1.9
C++ functional terminal UI.
载入中...
搜索中...
未找到
hoverable.cpp
浏览该文件的文档.
1// 版权所有 2022 Arthur Sonzogni. 保留所有权利。
2// 本源代码的使用受 MIT 许可的约束,该许可可在
3// LICENSE 文件中找到。
4#include <functional> // for function
5#include <utility> // for move
6
7#include "ftxui/component/component.hpp" // for ComponentDecorator, Hoverable, Make
8#include "ftxui/component/component_base.hpp" // for ComponentBase
9#include "ftxui/component/event.hpp" // for Event
10#include "ftxui/component/mouse.hpp" // for Mouse
11#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
12#include "ftxui/dom/elements.hpp" // for operator|, reflect, Element
13#include "ftxui/screen/box.hpp" // for Box
14
15namespace ftxui {
16
17namespace {
18
19void Post(std::function<void()> f) {
20 if (auto* screen = ScreenInteractive::Active()) {
21 screen->Post(std::move(f));
22 return;
23 }
24 f();
25}
26
27} // namespace
28
29/// @ingroup component
30///
31/// ### 示例
32///
33/// ```cpp
34/// auto button = Button("exit", screen.ExitLoopClosure());
35/// bool hover = false;
36/// auto button_hover = Hoverable(button, &hover);
37/// ```
38// NOLINTNEXTLINE
39Component Hoverable(Component component, bool* hover) {
40 class Impl : public ComponentBase {
41 public:
42 Impl(Component component, bool* hover)
43 : component_(std::move(component)), hover_(hover) {
44 Add(component_);
45 }
46
47 private:
48 Element OnRender() override {
49 return ComponentBase::OnRender() | reflect(box_);
50 }
51
52 bool OnEvent(Event event) override {
53 if (event.is_mouse()) {
54 *hover_ = box_.Contain(event.mouse().x, event.mouse().y) &&
55 CaptureMouse(event);
56 }
57
58 return ComponentBase::OnEvent(event);
59 }
60
61 Component component_;
62 bool* hover_;
63 Box box_;
64 };
65
66 return Make<Impl>(component, hover);
67}
68
69/// @brief 包装一个组件。使用回调。
70/// @param component 被包装的组件。
71/// @param on_enter 鼠标进入时的回调函数
72/// @param on_leave 鼠标离开时的回调函数
73/// @ingroup component
74///
75/// ### 示例
76///
77/// ```cpp
78/// auto button = Button("exit", screen.ExitLoopClosure());
79/// bool hover = false;
80/// auto button_hover = Hoverable(button, &hover);
81/// ```
83 std::function<void()> on_enter,
84 std::function<void()> on_leave) {
85 class Impl : public ComponentBase {
86 public:
87 Impl(Component component,
88 std::function<void()> on_enter,
89 std::function<void()> on_leave)
90 : component_(std::move(component)),
91 on_enter_(std::move(on_enter)),
92 on_leave_(std::move(on_leave)) {
93 Add(component_);
94 }
95
96 private:
97 Element OnRender() override {
98 return ComponentBase::OnRender() | reflect(box_);
99 }
100
101 bool OnEvent(Event event) override {
102 if (event.is_mouse()) {
103 const bool hover = box_.Contain(event.mouse().x, event.mouse().y) &&
104 CaptureMouse(event);
105 if (hover != hover_) {
106 Post(hover ? on_enter_ : on_leave_);
107 }
108 hover_ = hover;
109 }
110
111 return ComponentBase::OnEvent(event);
112 }
113
114 Component component_;
115 Box box_;
116 bool hover_ = false;
117 std::function<void()> on_enter_;
118 std::function<void()> on_leave_;
119 };
120
121 return Make<Impl>(std::move(component), std::move(on_enter),
122 std::move(on_leave));
123}
124
125/// @brief 包装一个组件。使其能够知道鼠标是否悬停在其上。
126/// @param hover 反映组件是否被悬停的值。
127/// @ingroup component
128///
129/// ### 示例
130///
131/// ```cpp
132/// bool hover = false;
133/// auto button = Button("exit", screen.ExitLoopClosure());
134/// button |= Hoverable(&hover);
135/// ```
137 return [hover](Component component) {
138 return Hoverable(std::move(component), hover);
139 };
140}
141
142/// @brief 包装一个组件。使其能够知道鼠标是否悬停在其上。
143/// @param on_enter 当鼠标悬停在组件上时调用。
144/// @param on_leave 当鼠标离开组件时调用。
145/// @ingroup component
146///
147/// ### 示例
148///
149/// ```cpp
150/// auto button = Button("exit", screen.ExitLoopClosure());
151/// int on_enter_cnt = 0;
152/// int on_leave_cnt = 0;
153/// button |= Hoverable(
154/// [&]{ on_enter_cnt++; },
155/// [&]{ on_leave_cnt++; }
156/// );
157/// ```
158// NOLINTNEXTLINE
159ComponentDecorator Hoverable(std::function<void()> on_enter,
160 // NOLINTNEXTLINE
161 std::function<void()> on_leave) {
162 return [on_enter, on_leave](Component component) {
163 return Hoverable(std::move(component), on_enter, on_leave);
164 };
165}
166
167/// @brief 包装一个组件。使其能够知道鼠标是否悬停在其上。
168/// @param component 被包装的组件。
169/// @param on_change 当鼠标进入或离开组件时调用。
170/// @ingroup component
171///
172/// ### 示例
173///
174/// ```cpp
175/// auto button = Button("exit", screen.ExitLoopClosure());
176/// bool hovered = false;
177/// auto button_hoverable = Hoverable(button,
178/// [&](bool hover) { hovered = hover;});
179/// ```
180// NOLINTNEXTLINE
181Component Hoverable(Component component, std::function<void(bool)> on_change) {
182 return Hoverable(
183 std::move(component), //
184 [on_change] { on_change(true); }, //
185 [on_change] { on_change(false); } //
186 );
187}
188
189/// @brief 包装一个组件。使其能够知道鼠标是否悬停在其上。
190/// @ingroup component
191///
192/// ### 示例
193///
194/// ```cpp
195/// auto button = Button("exit", screen.ExitLoopClosure());
196/// bool hovered = false;
197/// button |= Hoverable([&](bool hover) { hovered = hover;});
198/// ```
199// NOLINTNEXTLINE
200ComponentDecorator Hoverable(std::function<void(bool)> on_change) {
201 return [on_change](Component component) {
202 return Hoverable(std::move(component), on_change);
203 };
204}
205
206} // namespace ftxui
bool is_mouse() const
struct Mouse mouse
static ScreenInteractive * Active()
返回当前活动屏幕,如果没有则返回空。
它将自身实现为 ftxui::Element。它通过响应 ftxui::Event 来实现键盘导航。
Component Hoverable(Component component, bool *hover)
代表一个事件。它可以是按键事件、终端大小调整等等...
Box是一个表示2D空间中矩形区域的结构体。
定义 box.hpp:15
#include "ftxui/component/component_base.hpp" // 用于 ComponentBase
std::shared_ptr< T > Make(Args &&... args)
std::shared_ptr< Node > Element
std::function< Component(Component)> ComponentDecorator
std::shared_ptr< ComponentBase > Component