FTXUI  5.0.0
C++ functional terminal UI.
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.
4#include <cstddef> // for size_t
5#include <functional> // for function
6#include <memory> // for __shared_ptr_access, allocator, shared_ptr
7#include <string> // for string
8
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) {
23 class Impl : public ComponentBase {
24 public:
25 Impl(ConstStringListRef entries, int* selected)
26 : entries_(entries), selected_(selected) {
27 CheckboxOption option;
28 option.transform = [](const EntryState& s) {
29 auto prefix = text(s.state ? "↓ " : "→ "); // NOLINT
30 auto t = text(s.label);
31 if (s.active) {
32 t |= bold;
33 }
34 if (s.focused) {
35 t |= inverted;
36 }
37 return hbox({prefix, t});
38 };
39 checkbox_ = Checkbox(&title_, &show_, option);
40 radiobox_ = Radiobox(entries_, selected_);
41
43 checkbox_,
44 Maybe(radiobox_, &show_),
45 }));
46 }
47
48 Element Render() override {
49 *selected_ = util::clamp(*selected_, 0, int(entries_.size()) - 1);
50 title_ = entries_[static_cast<size_t>(*selected_)];
51 if (show_) {
52 const int max_height = 12;
53 return vbox({
54 checkbox_->Render(),
55 separator(),
56 radiobox_->Render() | vscroll_indicator | frame |
57 size(HEIGHT, LESS_THAN, max_height),
58 }) |
59 border;
60 }
61
62 return vbox({
63 checkbox_->Render() | border,
64 filler(),
65 });
66 }
67
68 // Switch focus in between the checkbox and the radiobox when selecting it.
69 bool OnEvent(ftxui::Event event) override {
70 const bool show_old = show_;
71 const int selected_old = *selected_;
72 const bool handled = ComponentBase::OnEvent(event);
73
74 if (!show_old && show_) {
75 radiobox_->TakeFocus();
76 }
77
78 if (selected_old != *selected_) {
79 checkbox_->TakeFocus();
80 show_ = false;
81 }
82
83 return handled;
84 }
85
86 private:
87 ConstStringListRef entries_;
88 bool show_ = false;
89 int* selected_;
90 std::string title_;
91 Component checkbox_;
92 Component radiobox_;
93 };
94
95 return Make<Impl>(entries, selected);
96}
97
98} // 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.
Definition: component.cpp:106
An adapter. Reference a list of strings.
Definition: ref.hpp:98
Component Vertical(Components children)
A list of components, drawn one by one vertically and navigated vertically using up/down arrow key or...
Definition: container.cpp:317
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
Definition: util.hpp:12
@ HEIGHT
Definition: elements.hpp:148
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:90
Component Maybe(Component, const bool *show)
Decorate a component |child|. It is shown only when |show| is true.
Definition: maybe.cpp:75
Component Checkbox(CheckboxOption options)
std::shared_ptr< Node > Element
Definition: elements.hpp:23
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:207
Element hbox(Elements)
A container displaying elements horizontally one by one.
Definition: hbox.cpp:83
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:120
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.
Definition: separator.cpp:132
Element filler()
An element that will take expand proportionnally 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:167
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Definition: node.cpp:47
@ LESS_THAN
Definition: elements.hpp:149
Element border(Element)
Draw a border around the element.
Definition: border.cpp:227
Element vbox(Elements)
A container displaying elements vertically one by one.
Definition: vbox.cpp:83
arguments for |ButtonOption::transform|, |CheckboxOption::transform|, |Radiobox::transform|,...
Option for the Checkbox component.
std::function< Element(const EntryState &)> transform
Represent an event. It can be key press event, a terminal resize, or more ...
Definition: event.hpp:29