Loading...
Searching...
No Matches
hoverable.cpp
Go to the documentation of this file.
// Copyright 2022 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include <functional> // for function
#include <utility> // for move
#include "ftxui/component/component.hpp" // for ComponentDecorator, Hoverable, Make
#include "ftxui/component/component_base.hpp" // for ComponentBase
#include "ftxui/component/event.hpp" // for Event
#include "ftxui/component/mouse.hpp" // for Mouse
#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/dom/elements.hpp" // for operator|, reflect, Element
#include "ftxui/screen/box.hpp" // for Box
namespace ftxui {
namespace {
void Post(std::function<void()> f) {
if (auto* screen = ScreenInteractive::Active()) {
screen->Post(std::move(f));
return;
}
f();
}
} // namespace
/// @brief Wrap a component. Gives the ability to know if it is hovered by the
/// mouse.
/// @param component The wrapped component.
/// @param hover The value to reflect whether the component is hovered or not.
/// @ingroup component
///
/// ### Example
///
/// ```cpp
/// auto button = Button("exit", screen.ExitLoopClosure());
/// bool hover = false;
/// auto button_hover = Hoverable(button, &hover);
/// ```
// NOLINTNEXTLINE
Component Hoverable(Component component, bool* hover) {
class Impl : public ComponentBase {
public:
Impl(Component component, bool* hover)
: component_(std::move(component)), hover_(hover) {
Add(component_);
}
private:
Element OnRender() override {
return ComponentBase::OnRender() | reflect(box_);
}
bool OnEvent(Event event) override {
if (event.is_mouse()) {
*hover_ = box_.Contain(event.mouse().x, event.mouse().y) &&
CaptureMouse(event);
}
return ComponentBase::OnEvent(event);
}
Component component_;
bool* hover_;
Box box_;
};
return Make<Impl>(component, hover);
}
/// @brief Wrap a component. Uses callbacks.
/// @param component The wrapped component.
/// @param on_enter Callback OnEnter
/// @param on_leave Callback OnLeave
/// @ingroup component
///
/// ### Example
///
/// ```cpp
/// auto button = Button("exit", screen.ExitLoopClosure());
/// bool hover = false;
/// auto button_hover = Hoverable(button, &hover);
/// ```
Component Hoverable(Component component,
std::function<void()> on_enter,
std::function<void()> on_leave) {
class Impl : public ComponentBase {
public:
Impl(Component component,
std::function<void()> on_enter,
std::function<void()> on_leave)
: component_(std::move(component)),
on_enter_(std::move(on_enter)),
on_leave_(std::move(on_leave)) {
Add(component_);
}
private:
Element OnRender() override {
return ComponentBase::OnRender() | reflect(box_);
}
bool OnEvent(Event event) override {
if (event.is_mouse()) {
const bool hover = box_.Contain(event.mouse().x, event.mouse().y) &&
CaptureMouse(event);
if (hover != hover_) {
Post(hover ? on_enter_ : on_leave_);
}
hover_ = hover;
}
return ComponentBase::OnEvent(event);
}
Component component_;
Box box_;
bool hover_ = false;
std::function<void()> on_enter_;
std::function<void()> on_leave_;
};
return Make<Impl>(std::move(component), std::move(on_enter),
std::move(on_leave));
}
/// @brief Wrap a component. Gives the ability to know if it is hovered by the
/// mouse.
/// @param hover The value to reflect whether the component is hovered or not.
/// @ingroup component
///
/// ### Example
///
/// ```cpp
/// bool hover = false;
/// auto button = Button("exit", screen.ExitLoopClosure());
/// button |= Hoverable(&hover);
/// ```
ComponentDecorator Hoverable(bool* hover) {
return [hover](Component component) {
return Hoverable(std::move(component), hover);
};
}
/// @brief Wrap a component. Gives the ability to know if it is hovered by the
/// mouse.
/// @param on_enter is called when the mouse hover the component.
/// @param on_leave is called when the mouse leave the component.
/// @ingroup component
///
/// ### Example
///
/// ```cpp
/// auto button = Button("exit", screen.ExitLoopClosure());
/// int on_enter_cnt = 0;
/// int on_leave_cnt = 0;
/// button |= Hoverable(
/// [&]{ on_enter_cnt++; },
/// [&]{ on_leave_cnt++; }
// );
/// ```
// NOLINTNEXTLINE
ComponentDecorator Hoverable(std::function<void()> on_enter,
// NOLINTNEXTLINE
std::function<void()> on_leave) {
return [on_enter, on_leave](Component component) {
return Hoverable(std::move(component), on_enter, on_leave);
};
}
/// @brief Wrap a component. Gives the ability to know if it is hovered by the
/// mouse.
/// @param component the wrapped component.
/// @param on_change is called when the mouse enter or leave the component.
/// @ingroup component
///
/// ### Example
///
/// ```cpp
/// auto button = Button("exit", screen.ExitLoopClosure());
/// bool hovered = false;
/// auto button_hoverable = Hoverable(button,
// [&](bool hover) { hovered = hover;});
/// ```
// NOLINTNEXTLINE
Component Hoverable(Component component, std::function<void(bool)> on_change) {
return Hoverable(
std::move(component), //
[on_change] { on_change(true); }, //
[on_change] { on_change(false); } //
);
}
/// @brief Wrap a component. Gives the ability to know if it is hovered by the
/// mouse.
/// @param on_change is called when the mouse enter or leave the component.
/// @ingroup component
///
/// ### Example
///
/// ```cpp
/// auto button = Button("exit", screen.ExitLoopClosure());
/// bool hovered = false;
/// button |= Hoverable([&](bool hover) { hovered = hover;});
/// ```
// NOLINTNEXTLINE
ComponentDecorator Hoverable(std::function<void(bool)> on_change) {
return [on_change](Component component) {
return Hoverable(std::move(component), on_change);
};
}
} // namespace ftxui
box.hpp
ftxui::ComponentBase
It implement rendering itself as ftxui::Element. It implement keyboard navigation by responding to ft...
Definition component_base.hpp:30
ftxui::ComponentBase::OnRender
virtual Element OnRender()
Draw the component. Build a ftxui::Element to be drawn on the ftxi::Screen representing this ftxui::C...
Definition component.cpp:147
ftxui::ComponentBase::OnEvent
virtual bool OnEvent(Event)
Called in response to an event.
Definition component.cpp:161
ftxui::ScreenInteractive::Active
static ScreenInteractive * Active()
Return the currently active screen, or null if none.
Definition screen_interactive.cpp:594
component.hpp
component_base.hpp
elements.hpp
event.hpp
mouse.hpp
ftxui
Definition animation.hpp:10
ftxui::Make
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:26
ftxui::Element
std::shared_ptr< Node > Element
Definition elements.hpp:22
ftxui::Hoverable
Component Hoverable(Component component, bool *hover)
Wrap a component. Gives the ability to know if it is hovered by the mouse.
Definition hoverable.cpp:43
ftxui::reflect
Decorator reflect(Box &box)
Definition reflect.cpp:43
ftxui::ComponentDecorator
std::function< Component(Component)> ComponentDecorator
Definition component.hpp:31
ftxui::Component
std::shared_ptr< ComponentBase > Component
Definition component_base.hpp:24
screen_interactive.hpp
ftxui::Box
Definition box.hpp:9
ftxui::Event
Represent an event. It can be key press event, a terminal resize, or more ...
Definition event.hpp:27
ftxui::Event::is_mouse
bool is_mouse() const
Definition event.hpp:107
ftxui::Event::mouse
struct Mouse & mouse()
Definition event.hpp:108
ftxui::Mouse::y
int y
Definition mouse.hpp:42
ftxui::Mouse::x
int x
Definition mouse.hpp:41