32 std::string label = (state.active ?
"> " :
" ") + state.label;
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());
94 selected_previous_ =
util::clamp(selected_previous_, 0, size() - 1);
95 selected_focus_ =
util::clamp(selected_focus_, 0, size() - 1);
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();
119 elements.reserve(size());
120 for (
int i = 0; i < size(); ++i) {
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]) |
149 std::reverse(elements.begin(), elements.end());
153 IsHorizontal() ?
hbox(std::move(elements)) :
vbox(std::move(elements));
156 return bar | reflect(box_);
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)) {
334 bool OnMouseWheel(Event event) {
335 if (!box_.Contain(event.mouse().x, event.mouse().y)) {
338 const int old_selected =
selected();
356 void UpdateAnimationTarget() {
358 UpdateUnderlineTarget();
361 void UpdateColorTarget() {
362 if (size() !=
int(animation_background_.size())) {
363 animation_background_.resize(size());
364 animation_foreground_.resize(size());
365 animator_background_.clear();
366 animator_foreground_.clear();
368 const int len = size();
369 animator_background_.reserve(len);
370 animator_foreground_.reserve(len);
371 for (
int i = 0; i < len; ++i) {
372 animation_background_[i] = 0.F;
373 animation_foreground_[i] = 0.F;
374 animator_background_.emplace_back(&animation_background_[i], 0.F,
375 std::chrono::milliseconds(0),
377 animator_foreground_.emplace_back(&animation_foreground_[i], 0.F,
378 std::chrono::milliseconds(0),
383 const bool is_menu_focused =
Focused();
384 for (
int i = 0; i < size(); ++i) {
385 const bool is_focused = (
focused_entry() == i) && is_menu_focused;
386 const bool is_selected = (
selected() == i);
387 float target = is_selected ? 1.F : is_focused ? 0.5F : 0.F;
388 if (animator_background_[i].to() != target) {
389 animator_background_[i] = animation::Animator(
390 &animation_background_[i], target,
393 animator_foreground_[i] = animation::Animator(
394 &animation_foreground_[i], target,
405 animation_foreground_[i],
412 animation_background_[i],
419 void UpdateUnderlineTarget() {
424 if (FirstTarget() == animator_first_.to() &&
425 SecondTarget() == animator_second_.to()) {
429 if (FirstTarget() >= animator_first_.to()) {
430 animator_first_ = animation::Animator(
431 &first_, FirstTarget(),
underline.follower_duration,
434 animator_second_ = animation::Animator(
435 &second_, SecondTarget(),
underline.leader_duration,
438 animator_first_ = animation::Animator(
439 &first_, FirstTarget(),
underline.leader_duration,
442 animator_second_ = animation::Animator(
443 &second_, SecondTarget(),
underline.follower_duration,
449 int size()
const {
return int(
entries.size()); }
450 float FirstTarget() {
451 if (boxes_.empty()) {
454 const int value = IsHorizontal() ? boxes_[
selected()].x_min - box_.x_min
455 : boxes_[
selected()].y_min - box_.y_min;
458 float SecondTarget() {
459 if (boxes_.empty()) {
462 const int value = IsHorizontal() ? boxes_[
selected()].x_max - box_.x_min
463 : boxes_[
selected()].y_max - box_.y_min;
468 int selected_previous_ =
selected();
472 std::vector<Box> boxes_;
478 animation::Animator animator_first_ = animation::Animator(&first_, 0.F);
479 animation::Animator animator_second_ = animation::Animator(&second_, 0.F);
480 std::vector<animation::Animator> animator_background_;
481 std::vector<animation::Animator> animator_foreground_;
482 std::vector<float> animation_background_;
483 std::vector<float> animation_foreground_;
548 return Menu(std::move(option));
587 option.
label = label;
624 const bool focused = Focused();
625 UpdateAnimationTarget();
635 (transform ? transform : DefaultOptionTransform)
639 return element | AnimatedColorStyle() | focus_management |
reflect(box_);
642 void UpdateAnimationTarget() {
643 const bool focused = Focused();
644 float target = focused ? 1.F : hovered_ ? 0.5F : 0.F;
645 if (target == animator_background_.to()) {
649 &animation_background_, target, animated_colors.background.duration,
650 animated_colors.background.function);
652 &animation_foreground_, target, animated_colors.foreground.duration,
653 animated_colors.foreground.function);
658 if (animated_colors.foreground.enabled) {
661 animated_colors.foreground.inactive,
662 animated_colors.foreground.active));
665 if (animated_colors.background.enabled) {
668 animated_colors.background.inactive,
669 animated_colors.background.active));
674 bool Focusable()
const override {
return true; }
675 bool OnEvent(
Event event)
override {
680 hovered_ = box_.Contain(event.
mouse().
x, event.
mouse().
y);
696 animator_background_.OnAnimation(params);
697 animator_foreground_.OnAnimation(params);
702 bool hovered_ =
false;
704 float animation_background_ = 0.F;
705 float animation_foreground_ = 0.F;
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...
virtual bool Focusable() const
Return true when the component contains focusable elements. The non focusable Components will be skip...
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...
virtual Element Render()
Draw the component. Build a ftxui::Element to be drawn on the ftxi::Screen representing this ftxui::C...
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.
Element nothing(Element element)
A decoration doing absolutely nothing.
Component Menu(MenuOption options)
A list of text. The focused element is selected.
std::shared_ptr< T > Make(Args &&... args)
std::shared_ptr< Node > Element
Component MenuEntry(MenuEntryOption options)
A specific menu entry. They can be put into a Container::Vertical to form a menu.
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.
Element hbox(Elements)
A container displaying elements horizontally one by one.
std::vector< Element > Elements
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.
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)
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
std::shared_ptr< ComponentBase > Component
Decorator color(Color)
Decorate using a foreground color.
Element vbox(Elements)
A container displaying elements vertically one by one.
arguments for |ButtonOptiontransform|, |CheckboxOptiontransform|, |Radioboxtransform|,...
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