FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
hoverable.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.
4#include <functional> // for function
5#include <utility> // for move
6
7#include "ftxui/component/app.hpp" // for Component, App
8#include "ftxui/component/component.hpp" // for ComponentDecorator, Hoverable, Make
9#include "ftxui/component/component_base.hpp" // for ComponentBase
10#include "ftxui/component/event.hpp" // for Event
11#include "ftxui/component/mouse.hpp" // for Mouse
12#include "ftxui/dom/elements.hpp" // for operator|, reflect, Element
13#include "ftxui/screen/box.hpp" // for Box
14
15namespace ftxui {
16
17namespace {} // namespace
18
19/// @brief Wrap a component. Gives the ability to know if it is hovered by the
20/// mouse.
21/// @param component The wrapped component.
22/// @param hover The value to reflect whether the component is hovered or not.
23/// @ingroup component
24///
25/// ### Example
26///
27/// ```cpp
28/// auto button = Button("exit", screen.ExitLoopClosure());
29/// bool hover = false;
30/// auto button_hover = Hoverable(button, &hover);
31/// ```
32// NOLINTNEXTLINE
33Component Hoverable(Component component, bool* hover) {
34 class Impl : public ComponentBase {
35 public:
36 Impl(Component component, bool* hover)
37 : component_(std::move(component)), hover_(hover) {
38 Add(component_);
39 }
40
41 private:
42 Element OnRender() override {
43 return ComponentBase::OnRender() | reflect(box_);
44 }
45
46 bool OnEvent(Event event) override {
47 if (event.is_mouse()) {
48 *hover_ = box_.Contain(event.mouse().x, event.mouse().y) &&
49 CaptureMouse(event);
50 }
51
52 return ComponentBase::OnEvent(event);
53 }
54
55 Component component_;
56 bool* hover_;
57 Box box_;
58 };
59
60 return Make<Impl>(component, hover);
61}
62
63/// @brief Wrap a component. Uses callbacks.
64/// @param component The wrapped component.
65/// @param on_enter Callback OnEnter
66/// @param on_leave Callback OnLeave
67/// @ingroup component
68///
69/// ### Example
70///
71/// ```cpp
72/// auto button = Button("exit", screen.ExitLoopClosure());
73/// bool hover = false;
74/// auto button_hover = Hoverable(button, &hover);
75/// ```
77 std::function<void()> on_enter,
78 std::function<void()> on_leave) {
79 class Impl : public ComponentBase {
80 public:
81 Impl(Component component,
82 std::function<void()> on_enter,
83 std::function<void()> on_leave)
84 : component_(std::move(component)),
85 on_enter_(std::move(on_enter)),
86 on_leave_(std::move(on_leave)) {
87 Add(component_);
88 }
89
90 private:
91 Element OnRender() override {
92 return ComponentBase::OnRender() | reflect(box_);
93 }
94
95 bool OnEvent(Event event) override {
96 if (event.is_mouse()) {
97 const bool hover = box_.Contain(event.mouse().x, event.mouse().y) &&
98 CaptureMouse(event);
99 if (hover != hover_) {
100 App::PostEventOrExecute(hover ? on_enter_ : on_leave_);
101 }
102 hover_ = hover;
103 }
104
105 return ComponentBase::OnEvent(event);
106 }
107
108 Component component_;
109 Box box_;
110 bool hover_ = false;
111 std::function<void()> on_enter_;
112 std::function<void()> on_leave_;
113 };
114
115 return Make<Impl>(std::move(component), std::move(on_enter),
116 std::move(on_leave));
117}
118
119/// @brief Wrap a component. Gives the ability to know if it is hovered by the
120/// mouse.
121/// @param hover The value to reflect whether the component is hovered or not.
122/// @ingroup component
123///
124/// ### Example
125///
126/// ```cpp
127/// bool hover = false;
128/// auto button = Button("exit", screen.ExitLoopClosure());
129/// button |= Hoverable(&hover);
130/// ```
132 return [hover](Component component) {
133 return Hoverable(std::move(component), hover);
134 };
135}
136
137/// @brief Wrap a component. Gives the ability to know if it is hovered by the
138/// mouse.
139/// @param on_enter is called when the mouse hover the component.
140/// @param on_leave is called when the mouse leave the component.
141/// @ingroup component
142///
143/// ### Example
144///
145/// ```cpp
146/// auto button = Button("exit", screen.ExitLoopClosure());
147/// int on_enter_cnt = 0;
148/// int on_leave_cnt = 0;
149/// button |= Hoverable(
150/// [&]{ on_enter_cnt++; },
151/// [&]{ on_leave_cnt++; }
152/// );
153/// ```
154// NOLINTNEXTLINE
155ComponentDecorator Hoverable(std::function<void()> on_enter,
156 // NOLINTNEXTLINE
157 std::function<void()> on_leave) {
158 return [on_enter, on_leave](Component component) {
159 return Hoverable(std::move(component), on_enter, on_leave);
160 };
161}
162
163/// @brief Wrap a component. Gives the ability to know if it is hovered by the
164/// mouse.
165/// @param component the wrapped component.
166/// @param on_change is called when the mouse enter or leave the component.
167/// @ingroup component
168///
169/// ### Example
170///
171/// ```cpp
172/// auto button = Button("exit", screen.ExitLoopClosure());
173/// bool hovered = false;
174/// auto button_hoverable = Hoverable(button,
175/// [&](bool hover) { hovered = hover;});
176/// ```
177// NOLINTNEXTLINE
178Component Hoverable(Component component, std::function<void(bool)> on_change) {
179 return Hoverable(
180 std::move(component), //
181 [on_change] { on_change(true); }, //
182 [on_change] { on_change(false); } //
183 );
184}
185
186/// @brief Wrap a component. Gives the ability to know if it is hovered by the
187/// mouse.
188/// @param on_change is called when the mouse enter or leave the component.
189/// @ingroup component
190///
191/// ### Example
192///
193/// ```cpp
194/// auto button = Button("exit", screen.ExitLoopClosure());
195/// bool hovered = false;
196/// button |= Hoverable([&](bool hover) { hovered = hover;});
197/// ```
198// NOLINTNEXTLINE
199ComponentDecorator Hoverable(std::function<void(bool)> on_change) {
200 return [on_change](Component component) {
201 return Hoverable(std::move(component), on_change);
202 };
203}
204
205} // namespace ftxui
Component Hoverable(Component component, bool *hover)
Wrap a component. Gives the ability to know if it is hovered by the mouse.
Definition hoverable.cpp:33
The FTXUI ftxui:: namespace.
Definition animation.hpp:11
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:28
std::shared_ptr< Node > Element
Definition elements.hpp:24
std::function< Component(Component)> ComponentDecorator
Definition component.hpp:33
std::shared_ptr< ComponentBase > Component
Definition app.hpp:23