FTXUI  5.0.0
C++ functional terminal UI.
Loading...
Searching...
No Matches
dropdown.cpp
Go to the documentation of this file.
1// Copyright 2021 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.
5#include <functional> // for function
6#include <string> // for string
7
8#include <utility>
9#include "ftxui/component/component.hpp" // for Maybe, Checkbox, Make, Radiobox, Vertical, Dropdown
10#include "ftxui/component/component_base.hpp" // for Component, ComponentBase
11#include "ftxui/component/component_options.hpp" // for CheckboxOption, EntryState
12#include "ftxui/dom/elements.hpp" // for operator|, Element, border, filler, operator|=, separator, size, text, vbox, frame, vscroll_indicator, hbox, HEIGHT, LESS_THAN, bold, inverted
13#include "ftxui/screen/util.hpp" // for clamp
14#include "ftxui/util/ref.hpp" // for ConstStringListRef
15
16namespace ftxui {
17
18/// @brief A dropdown menu.
19/// @ingroup component
20/// @param entries The list of entries to display.
21/// @param selected The index of the selected entry.
22Component Dropdown(ConstStringListRef entries, int* selected) {
24 option.radiobox.entries = std::move(entries);
25 option.radiobox.selected = selected;
26 return Dropdown(option);
27}
28
29/// @brief A dropdown menu.
30/// @ingroup component
31/// @param option The options for the dropdown.
32// NOLINTNEXTLINE
34 class Impl : public ComponentBase, public DropdownOption {
35 public:
36 explicit Impl(DropdownOption option) : DropdownOption(std::move(option)) {
38 checkbox_ = Checkbox(checkbox);
39 radiobox_ = Radiobox(radiobox);
40
43 Maybe(radiobox_, checkbox.checked),
44 }));
45 }
46
47 Element Render() override {
48 radiobox.selected =
49 util::clamp(radiobox.selected(), 0, int(radiobox.entries.size()) - 1);
50 selected_ = util::clamp(selected_(), 0, int(radiobox.entries.size()) - 1);
51
52 if (selected_() >= 0) {
53 title_ = radiobox.entries[selected_()];
54 }
55
56 return transform(*open_, checkbox_->Render(), radiobox_->Render());
57 }
58
59 // Switch focus in between the checkbox and the radiobox when selecting it.
60 bool OnEvent(ftxui::Event event) override {
61 const bool open_old = open_();
62 const int selected_old = selected_();
64
65 // Transfer focus to the radiobox when the dropdown is opened.
66 if (!open_old && open_()) {
67 radiobox_->TakeFocus();
68 }
69
70 // Auto-close the dropdown when the user selects an item, even if the item
71 // it the same as the previous one.
72 if (open_old && open_()) {
73 const bool should_close = (selected_() != selected_old) || //
74 (event == Event::Return) || //
75 (event == Event::Character(' ')) || //
76 (event == Event::Escape); //
77
78 if (should_close) {
79 checkbox_->TakeFocus();
80 open_ = false;
81 handled = true;
82 }
83 }
84
85 return handled;
86 }
87
88 void FillDefault() {
89 open_ = checkbox.checked;
90 selected_ = radiobox.selected;
91 checkbox.checked = &*open_;
92 radiobox.selected = &*selected_;
93 checkbox.label = &title_;
94
95 if (!checkbox.transform) {
96 checkbox.transform = [](const EntryState& s) {
97 auto prefix = text(s.state ? "↓ " : "→ "); // NOLINT
98 auto t = text(s.label);
99 if (s.active) {
100 t |= bold;
101 }
102 if (s.focused) {
103 t |= inverted;
104 }
105 return hbox({prefix, t});
106 };
107 }
108
109 if (!transform) {
110 transform = [](bool is_open, Element checkbox_element,
112 if (is_open) {
113 const int max_height = 12;
114 return vbox({
115 std::move(checkbox_element),
116 separator(),
119 }) |
120 border;
121 }
122 return vbox({std::move(checkbox_element), filler()}) | border;
123 };
124 }
125 }
126
127 private:
129 Ref<int> selected_;
132 std::string title_;
133 };
134
135 return Make<Impl>(option);
136}
137
138} // namespace ftxui
It implement rendering itself as ftxui::Element. It implement keyboard navigation by responding to ft...
virtual bool OnEvent(Event)
Called in response to an event.
An adapter. Reference a list of strings.
Definition ref.hpp:116
An adapter. Own or reference an mutable object.
Definition ref.hpp:46
Component Vertical(Components children)
A list of components, drawn one by one vertically and navigated vertically using up/down arrow key or...
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
Definition util.hpp:11
Element vscroll_indicator(Element)
Display a vertical scrollbar to the right. colors.
Decorator size(WidthOrHeight, Constraint, int value)
Apply a constraint on the size of an element.
Definition size.cpp:89
Component Maybe(Component, const bool *show)
Decorate a component |child|. It is shown only when |show| is true.
Definition maybe.cpp:74
std::shared_ptr< Node > Element
Definition elements.hpp:22
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:26
std::shared_ptr< ComponentBase > Component
Element bold(Element)
Use a bold font, for elements with more emphasis.
Definition bold.cpp:33
Component Radiobox(RadioboxOption options)
A list of element, where only one can be selected.
Definition radiobox.cpp:205
Element hbox(Elements)
A container displaying elements horizontally one by one.
Definition hbox.cpp:96
Element inverted(Element)
Add a filter that will invert the foreground and the background colors.
Definition inverted.cpp:34
Element text(std::wstring text)
Display a piece of unicode text.
Definition text.cpp:159
Component Dropdown(ConstStringListRef entries, int *selected)
A dropdown menu.
Definition dropdown.cpp:22
Element separator()
Draw a vertical or horizontal separation in between two other elements.
Element filler()
An element that will take expand proportionally to the space left in a container.
Definition flex.cpp:98
Element frame(Element)
Allow an element to be displayed inside a 'virtual' area. It size can be larger than its container....
Definition frame.cpp:166
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Definition node.cpp:72
@ LESS_THAN
Definition elements.hpp:153
Component Checkbox(CheckboxOption options)
Draw checkable element.
Definition checkbox.cpp:108
Element border(Element)
Draw a border around the element.
Definition border.cpp:228
Element vbox(Elements)
A container displaying elements vertically one by one.
Definition vbox.cpp:97
Option for the Dropdown component.A dropdown menu is a checkbox opening/closing a radiobox.
arguments for |ButtonOption::transform|, |CheckboxOption::transform|, |Radiobox::transform|,...
Represent an event. It can be key press event, a terminal resize, or more ...
Definition event.hpp:27
static const Event Escape
Definition event.hpp:52
static const Event Return
Definition event.hpp:51
ConstStringListRef entries