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 
16 namespace 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.
22 Component 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
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:208
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
Component Checkbox(CheckboxOption options)
Draw checkable element.
Definition: checkbox.cpp:112
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