31Element DefaultOptionTransform(
const EntryState& state) {
32 std::string label = (state.active ?
"> " :
" ") + state.label;
71class MenuBase :
public ComponentBase,
public MenuOption {
73 explicit MenuBase(MenuOption option) : MenuOption(std::move(option)) {}
75 bool IsHorizontal() {
return ftxui::IsHorizontal(direction); }
89 if (
selected() != selected_previous_) {
92 boxes_.resize(
size());
99 void OnAnimation(animation::Params& params)
override {
100 animator_first_.OnAnimation(params);
101 animator_second_.OnAnimation(params);
102 for (
auto& animator : animator_background_) {
103 animator.OnAnimation(params);
105 for (
auto& animator : animator_foreground_) {
106 animator.OnAnimation(params);
112 UpdateAnimationTarget();
115 const bool is_menu_focused =
Focused();
116 if (elements_prefix) {
119 elements.reserve(
size());
120 for (
int i = 0; i <
size(); ++i) {
121 if (i != 0 && elements_infix) {
124 const bool is_focused = (
focused_entry() == i) && is_menu_focused;
125 const bool is_selected = (
selected() == i);
127 const EntryState state = {
134 auto focus_management =
135 is_menu_focused && (selected_focus_ == i) ?
focus :
nothing;
139 : DefaultOptionTransform)
141 elements.push_back(element | AnimatedColorStyle(i) |
reflect(boxes_[i]) |
144 if (elements_postfix) {
148 if (IsInverted(direction)) {
149 std::reverse(elements.begin(), elements.end());
153 IsHorizontal() ?
hbox(std::move(elements)) :
vbox(std::move(elements));
159 if (IsHorizontal()) {
178 void SelectedTakeFocus() {
240 bool OnEvent(Event event)
override {
246 if (event.is_mouse()) {
247 return OnMouseEvent(event);
251 const int old_selected =
selected();
265 selected() -= box_.y_max - box_.y_min;
268 selected() += box_.y_max - box_.y_min;
301 bool OnMouseEvent(Event event) {
304 return OnMouseWheel(event);
314 for (
int i = 0; i <
size(); ++i) {
315 if (!boxes_[i].Contain(event.mouse().x, event.mouse().y)) {
321 if (event.mouse().IsPressed()) {
333 bool OnMouseWheel(Event event) {
334 if (!box_.Contain(event.mouse().x, event.mouse().y)) {
337 const int old_selected =
selected();
355 void UpdateAnimationTarget() {
357 UpdateUnderlineTarget();
360 void UpdateColorTarget() {
361 if (
size() !=
int(animation_background_.size())) {
362 animation_background_.resize(
size());
363 animation_foreground_.resize(
size());
364 animator_background_.clear();
365 animator_foreground_.clear();
367 const int len =
size();
368 animator_background_.reserve(len);
369 animator_foreground_.reserve(len);
370 for (
int i = 0; i < len; ++i) {
371 animation_background_[i] = 0.F;
372 animation_foreground_[i] = 0.F;
373 animator_background_.emplace_back(&animation_background_[i], 0.F,
374 std::chrono::milliseconds(0),
376 animator_foreground_.emplace_back(&animation_foreground_[i], 0.F,
377 std::chrono::milliseconds(0),
382 const bool is_menu_focused =
Focused();
383 for (
int i = 0; i <
size(); ++i) {
384 const bool is_focused = (
focused_entry() == i) && is_menu_focused;
385 const bool is_selected = (
selected() == i);
386 float target = is_selected ? 1.F : is_focused ? 0.5F : 0.F;
387 if (animator_background_[i].to() != target) {
388 animator_background_[i] = animation::Animator(
389 &animation_background_[i], target,
392 animator_foreground_[i] = animation::Animator(
393 &animation_foreground_[i], target,
404 animation_foreground_[i],
411 animation_background_[i],
418 void UpdateUnderlineTarget() {
423 if (FirstTarget() == animator_first_.to() &&
424 SecondTarget() == animator_second_.to()) {
428 if (FirstTarget() >= animator_first_.to()) {
429 animator_first_ = animation::Animator(
433 animator_second_ = animation::Animator(
437 animator_first_ = animation::Animator(
441 animator_second_ = animation::Animator(
447 bool Focusable() const final {
return entries.
size(); }
449 float FirstTarget() {
450 if (boxes_.empty()) {
453 const int value = IsHorizontal() ? boxes_[
selected()].x_min - box_.x_min
454 : boxes_[
selected()].y_min - box_.y_min;
457 float SecondTarget() {
458 if (boxes_.empty()) {
461 const int value = IsHorizontal() ? boxes_[
selected()].x_max - box_.x_min
462 : boxes_[
selected()].y_max - box_.y_min;
467 int selected_previous_ =
selected();
471 std::vector<Box> boxes_;
477 animation::Animator animator_first_ = animation::Animator(&first_, 0.F);
478 animation::Animator animator_second_ = animation::Animator(&second_, 0.F);
479 std::vector<animation::Animator> animator_background_;
480 std::vector<animation::Animator> animator_foreground_;
481 std::vector<float> animation_background_;
482 std::vector<float> animation_foreground_;
514 return Make<MenuBase>(std::move(option));
547 return Menu(std::move(option));
586 option.
label = label;
623 const bool focused = Focused();
624 UpdateAnimationTarget();
634 (transform ? transform : DefaultOptionTransform)
638 return element | AnimatedColorStyle() | focus_management |
reflect(box_);
641 void UpdateAnimationTarget() {
642 const bool focused = Focused();
643 float target = focused ? 1.F : hovered_ ? 0.5F : 0.F;
644 if (target == animator_background_.to()) {
648 &animation_background_, target, animated_colors.background.duration,
649 animated_colors.background.function);
651 &animation_foreground_, target, animated_colors.foreground.duration,
652 animated_colors.foreground.function);
657 if (animated_colors.foreground.enabled) {
660 animated_colors.foreground.inactive,
661 animated_colors.foreground.active));
664 if (animated_colors.background.enabled) {
667 animated_colors.background.inactive,
668 animated_colors.background.active));
673 bool Focusable()
const override {
return true; }
674 bool OnEvent(
Event event)
override {
679 hovered_ = box_.Contain(event.
mouse().
x, event.
mouse().
y);
694 animator_background_.OnAnimation(params);
695 animator_foreground_.OnAnimation(params);
700 bool hovered_ =
false;
702 float animation_background_ = 0.F;
703 float animation_foreground_ = 0.F;
710 return Make<Impl>(std::move(option));
static Color Interpolate(float t, const Color &a, const Color &b)
It implement rendering itself as ftxui::Element. It implement keyboard navigation by responding to ft...
bool Focused() const
Returns if the elements if focused by the user. True when the ComponentBase is focused by the user....
CapturedMouse CaptureMouse(const Event &event)
Take the CapturedMouse if available. There is only one component of them. It represents a component t...
void TakeFocus()
Configure all the ancestors to give focus to this component.
An adapter. Reference a list of strings.
An adapter. Own or reference a constant string. For convenience, this class convert multiple immutabl...
float Linear(float p)
Modeled after the line y = x.
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
Decorator bgcolor(Color)
Decorate using a background color.
Element xflex(Element)
Expand/Minimize if possible/needed on the X axis.
std::function< Element(Element)> Decorator
Element separatorVSelector(float up, float down, Color unselected_color, Color selected_color)
Draw an vertical bar, with the area in between up/downcolored differently.
AnimatedColorOption foreground
Element nothing(Element element)
A decoration doing absolutely nothing.
Decorator size(WidthOrHeight, Constraint, int value)
Apply a constraint on the size of an element.
std::shared_ptr< Node > Element
Component Menu(MenuOption options)
A list of text. The focused element is selected.
Component MenuEntry(MenuEntryOption options)
A specific menu entry. They can be put into a Container::Vertical to form a menu.
std::shared_ptr< ComponentBase > Component
Component Toggle(ConstStringListRef entries, int *selected)
An horizontal list of elements. The user can navigate through them.
Element bold(Element)
Use a bold font, for elements with more emphasis.
Element yflex(Element)
Expand/Minimize if possible/needed on the Y axis.
Element separatorHSelector(float left, float right, Color unselected_color, Color selected_color)
Draw an horizontal bar, with the area in between left/right colored differently.
AnimatedColorOption background
Element hbox(Elements)
A container displaying elements horizontally one by one.
std::function< Element(const EntryState &state)> transform
Element inverted(Element)
Add a filter that will invert the foreground and the background colors.
Element text(std::wstring text)
Display a piece of unicode text.
std::vector< Element > Elements
Element select(Element)
Set the child to be the one selected among its siblings.
Element focus(Element)
Set the child to be the one in focus globally.
Decorator reflect(Box &box)
AnimatedColorsOption animated_colors
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Decorator color(Color)
Decorate using a foreground color.
Element vbox(Elements)
A container displaying elements vertically one by one.
arguments for |ButtonOption::transform|, |CheckboxOption::transform|, |Radiobox::transform|,...
animation::easing::Function function
animation::Duration duration
Represent an event. It can be key press event, a terminal resize, or more ...
static const Event TabReverse
static const Event PageUp
static Event Character(std::string)
An event corresponding to a given typed character.
static const Event ArrowUp
static const Event ArrowDown
static const Event PageDown
static const Event Return
static const Event ArrowLeft
static const Event ArrowRight
bool IsPressed(Button btn=Left) const
animation::Duration follower_duration
animation::easing::Function leader_function
animation::Duration follower_delay
animation::Duration leader_duration
animation::easing::Function follower_function
animation::Duration leader_delay