29 Element DefaultOptionTransform(
const EntryState& state) {
30 std::string label = (state.active ?
"> " :
" ") + state.label;
69 class MenuBase :
public ComponentBase,
public MenuOption {
71 explicit MenuBase(
const MenuOption& option) : MenuOption(option) {}
73 bool IsHorizontal() {
return ftxui::IsHorizontal(direction); }
87 if (
selected() != selected_previous_) {
90 boxes_.resize(
size());
97 void OnAnimation(animation::Params& params)
override {
98 animator_first_.OnAnimation(params);
99 animator_second_.OnAnimation(params);
100 for (
auto& animator : animator_background_) {
101 animator.OnAnimation(params);
103 for (
auto& animator : animator_foreground_) {
104 animator.OnAnimation(params);
110 UpdateAnimationTarget();
113 const bool is_menu_focused =
Focused();
114 if (elements_prefix) {
117 elements.reserve(
size());
118 for (
int i = 0; i <
size(); ++i) {
119 if (i != 0 && elements_infix) {
122 const bool is_focused = (
focused_entry() == i) && is_menu_focused;
123 const bool is_selected = (
selected() == i);
125 const EntryState state = {
126 entries[i],
false, is_selected, is_focused, i,
129 auto focus_management = (selected_focus_ != i) ?
nothing
130 : is_menu_focused ?
focus
135 : DefaultOptionTransform)
137 elements.push_back(element | AnimatedColorStyle(i) |
reflect(boxes_[i]) |
140 if (elements_postfix) {
144 if (IsInverted(direction)) {
145 std::reverse(elements.begin(), elements.end());
149 IsHorizontal() ?
hbox(std::move(elements)) :
vbox(std::move(elements));
155 if (IsHorizontal()) {
174 void SelectedTakeFocus() {
236 bool OnEvent(Event event)
override {
242 if (event.is_mouse()) {
243 return OnMouseEvent(event);
247 const int old_selected =
selected();
261 selected() -= box_.y_max - box_.y_min;
264 selected() += box_.y_max - box_.y_min;
297 bool OnMouseEvent(Event event) {
300 return OnMouseWheel(event);
310 for (
int i = 0; i <
size(); ++i) {
311 if (!boxes_[i].Contain(event.mouse().x, event.mouse().y)) {
331 bool OnMouseWheel(Event event) {
332 if (!box_.Contain(event.mouse().x, event.mouse().y)) {
335 const int old_selected =
selected();
353 void UpdateAnimationTarget() {
355 UpdateUnderlineTarget();
358 void UpdateColorTarget() {
359 if (
size() !=
int(animation_background_.size())) {
360 animation_background_.resize(
size());
361 animation_foreground_.resize(
size());
362 animator_background_.clear();
363 animator_foreground_.clear();
365 const int len =
size();
366 animator_background_.reserve(len);
367 animator_foreground_.reserve(len);
368 for (
int i = 0; i < len; ++i) {
369 animation_background_[i] = 0.F;
370 animation_foreground_[i] = 0.F;
371 animator_background_.emplace_back(&animation_background_[i], 0.F,
372 std::chrono::milliseconds(0),
374 animator_foreground_.emplace_back(&animation_foreground_[i], 0.F,
375 std::chrono::milliseconds(0),
380 const bool is_menu_focused =
Focused();
381 for (
int i = 0; i <
size(); ++i) {
382 const bool is_focused = (
focused_entry() == i) && is_menu_focused;
383 const bool is_selected = (
selected() == i);
384 float target = is_selected ? 1.F : is_focused ? 0.5F : 0.F;
385 if (animator_background_[i].to() != target) {
386 animator_background_[i] = animation::Animator(
387 &animation_background_[i], target,
390 animator_foreground_[i] = animation::Animator(
391 &animation_foreground_[i], target,
402 animation_foreground_[i],
409 animation_background_[i],
416 void UpdateUnderlineTarget() {
421 if (FirstTarget() == animator_first_.to() &&
422 SecondTarget() == animator_second_.to()) {
426 if (FirstTarget() >= animator_first_.to()) {
427 animator_first_ = animation::Animator(
431 animator_second_ = animation::Animator(
435 animator_first_ = animation::Animator(
439 animator_second_ = animation::Animator(
445 bool Focusable() const final {
return entries.
size(); }
447 float FirstTarget() {
448 if (boxes_.empty()) {
451 const int value = IsHorizontal() ? boxes_[
selected()].x_min - box_.x_min
452 : boxes_[
selected()].y_min - box_.y_min;
455 float SecondTarget() {
456 if (boxes_.empty()) {
459 const int value = IsHorizontal() ? boxes_[
selected()].x_max - box_.x_min
460 : boxes_[
selected()].y_max - box_.y_min;
465 int selected_previous_ =
selected();
469 std::vector<Box> boxes_;
475 animation::Animator animator_first_ = animation::Animator(&first_, 0.F);
476 animation::Animator animator_second_ = animation::Animator(&second_, 0.F);
477 std::vector<animation::Animator> animator_background_;
478 std::vector<animation::Animator> animator_foreground_;
479 std::vector<float> animation_background_;
480 std::vector<float> animation_foreground_;
513 return Make<MenuBase>(std::move(option));
544 option.
entries = std::move(entries);
585 option.
label = std::move(label);
622 const bool focused = Focused();
623 UpdateAnimationTarget();
626 label(),
false, hovered_, focused, Index(),
630 (transform ? transform : DefaultOptionTransform)
634 return element | AnimatedColorStyle() | focus_management |
reflect(box_);
637 void UpdateAnimationTarget() {
638 const bool focused = Focused();
639 float target = focused ? 1.F : hovered_ ? 0.5F : 0.F;
640 if (target == animator_background_.to()) {
644 &animation_background_, target, animated_colors.background.duration,
645 animated_colors.background.function);
647 &animation_foreground_, target, animated_colors.foreground.duration,
648 animated_colors.foreground.function);
653 if (animated_colors.foreground.enabled) {
656 animated_colors.foreground.inactive,
657 animated_colors.foreground.active));
660 if (animated_colors.background.enabled) {
663 animated_colors.background.inactive,
664 animated_colors.background.active));
669 bool Focusable()
const override {
return true; }
670 bool OnEvent(
Event event)
override {
675 hovered_ = box_.Contain(event.
mouse().
x, event.
mouse().
y);
691 animator_background_.OnAnimation(params);
692 animator_foreground_.OnAnimation(params);
697 bool hovered_ =
false;
699 float animation_background_ = 0.F;
700 float animation_foreground_ = 0.F;
707 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
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