FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
src/ftxui/component/radiobox.cpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. Todos los derechos reservados.
2// El uso de este código fuente se rige por la licencia MIT que se puede encontrar en
3// el archivo LICENSE.
4#include <functional> // for function
5#include <utility> // for move
6#include <vector> // for vector
7
8#include "ftxui/component/component.hpp" // for Make, Radiobox
9#include "ftxui/component/component_base.hpp" // for ComponentBase
10#include "ftxui/component/component_options.hpp" // for RadioboxOption, EntryState
11#include "ftxui/component/event.hpp" // for Event, Event::ArrowDown, Event::ArrowUp, Event::End, Event::Home, Event::PageDown, Event::PageUp, Event::Return, Event::Tab, Event::TabReverse
12#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::WheelDown, Mouse::WheelUp, Mouse::Left, Mouse::Released
13#include "ftxui/component/screen_interactive.hpp" // for Component
14#include "ftxui/dom/elements.hpp" // for operator|, reflect, Element, vbox, Elements, focus, nothing, select
15#include "ftxui/screen/box.hpp" // for Box
16#include "ftxui/screen/util.hpp" // for clamp
17#include "ftxui/util/ref.hpp" // for Ref, ConstStringListRef
18
19namespace ftxui {
20
21namespace {
22/// @brief Una lista de elementos seleccionables. Solo uno puede ser seleccionado a
23/// la vez.
24/// @ingroup component
25class RadioboxBase : public ComponentBase, public RadioboxOption {
26 public:
27 explicit RadioboxBase(const RadioboxOption& option)
28 : RadioboxOption(option) {}
29
30 private:
31 Element OnRender() override {
32 Clamp();
33 Elements elements;
34 const bool is_menu_focused = Focused();
35 elements.reserve(size());
36 for (int i = 0; i < size(); ++i) {
37 const bool is_focused = (focused_entry() == i) && is_menu_focused;
38 const bool is_selected = (hovered_ == i);
39 auto state = EntryState{
40 entries[i], selected() == i, is_selected, is_focused, i,
41 };
42 auto element =
43 (transform ? transform : RadioboxOption::Simple().transform)(state);
44 if (is_selected) {
45 element |= focus;
46 }
47 elements.push_back(element | reflect(boxes_[i]));
48 }
49 return vbox(std::move(elements)) | reflect(box_);
50 }
51
52 // NOLINTNEXTLINE(readability-function-cognitive-complexity)
53 bool OnEvent(Event event) override {
54 Clamp();
55 if (!CaptureMouse(event)) {
56 return false;
57 }
58
59 if (event.is_mouse()) {
60 return OnMouseEvent(event);
61 }
62
63 if (Focused()) {
64 const int old_hovered = hovered_;
65 if (event == Event::ArrowUp || event == Event::Character('k')) {
66 (hovered_)--;
67 }
68 if (event == Event::ArrowDown || event == Event::Character('j')) {
69 (hovered_)++;
70 }
71 if (event == Event::PageUp) {
72 (hovered_) -= box_.y_max - box_.y_min;
73 }
74 if (event == Event::PageDown) {
75 (hovered_) += box_.y_max - box_.y_min;
76 }
77 if (event == Event::Home) {
78 (hovered_) = 0;
79 }
80 if (event == Event::End) {
81 (hovered_) = size() - 1;
82 }
83 if (event == Event::Tab && size()) {
84 hovered_ = (hovered_ + 1) % size();
85 }
86 if (event == Event::TabReverse && size()) {
87 hovered_ = (hovered_ + size() - 1) % size();
88 }
89
90 hovered_ = util::clamp(hovered_, 0, size() - 1);
91
92 if (hovered_ != old_hovered) {
93 focused_entry() = hovered_;
94 on_change();
95 return true;
96 }
97 }
98
99 if (event == Event::Character(' ') || event == Event::Return) {
100 selected() = hovered_;
101 on_change();
102 return true;
103 }
104
105 return false;
106 }
107
108 bool OnMouseEvent(Event event) {
109 if (event.mouse().button == Mouse::WheelDown ||
110 event.mouse().button == Mouse::WheelUp) {
111 return OnMouseWheel(event);
112 }
113
114 for (int i = 0; i < size(); ++i) {
115 if (!boxes_[i].Contain(event.mouse().x, event.mouse().y)) {
116 continue;
117 }
118
119 TakeFocus();
120 focused_entry() = i;
121 if (event.mouse().button == Mouse::Left &&
122 event.mouse().motion == Mouse::Pressed) {
123 if (selected() != i) {
124 selected() = i;
125 on_change();
126 }
127
128 return true;
129 }
130 }
131 return false;
132 }
133
134 bool OnMouseWheel(Event event) {
135 if (!box_.Contain(event.mouse().x, event.mouse().y)) {
136 return false;
137 }
138
139 const int old_hovered = hovered_;
140
141 if (event.mouse().button == Mouse::WheelUp) {
142 (hovered_)--;
143 }
144 if (event.mouse().button == Mouse::WheelDown) {
145 (hovered_)++;
146 }
147
148 hovered_ = util::clamp(hovered_, 0, size() - 1);
149
150 if (hovered_ != old_hovered) {
151 on_change();
152 }
153
154 return true;
155 }
156
157 void Clamp() {
158 boxes_.resize(size());
159 selected() = util::clamp(selected(), 0, size() - 1);
160 focused_entry() = util::clamp(focused_entry(), 0, size() - 1);
161 hovered_ = util::clamp(hovered_, 0, size() - 1);
162 }
163
164 bool Focusable() const final { return entries.size(); }
165 int size() const { return int(entries.size()); }
166
167 int hovered_ = selected();
168 std::vector<Box> boxes_;
169 Box box_;
170};
171
172} // namespace
173
174/// @brief Una lista de elementos, donde solo uno puede ser seleccionado.
175/// @param option Los parámetros
176/// @ingroup component
177/// @see RadioboxBase
178///
179/// ### Ejemplo
180///
181/// ```cpp
182/// auto screen = ScreenInteractive::TerminalOutput();
183/// std::vector<std::string> entries = {
184/// "entry 1",
185/// "entry 2",
186/// "entry 3",
187/// };
188/// int selected = 0;
189/// auto menu = Radiobox({
190/// .entries = entries,
191/// .selected = &selected,
192/// });
193/// screen.Loop(menu);
194/// ```
195///
196/// ### Salida
197///
198/// ```bash
199/// ◉ entry 1
200/// ○ entry 2
201/// ○ entry 3
202/// ```
203/// NOLINTNEXTLINE
205 return Make<RadioboxBase>(std::move(option));
206}
207
208/// @brief Una lista de elementos, donde solo uno puede ser seleccionado.
209/// @param entries La lista de entradas en la lista.
210/// @param selected El índice del elemento actualmente seleccionado.
211/// @param option Parámetros opcionales adicionales.
212/// @ingroup component
213/// @see RadioboxBase
214///
215/// ### Ejemplo
216///
217/// ```cpp
218/// auto screen = ScreenInteractive::TerminalOutput();
219/// std::vector<std::string> entries = {
220/// "entry 1",
221/// "entry 2",
222/// "entry 3",
223/// };
224/// int selected = 0;
225/// auto menu = Radiobox(&entries, &selected);
226/// screen.Loop(menu);
227/// ```
228///
229/// ### Salida
230///
231/// ```bash
232/// ◉ entry 1
233/// ○ entry 2
234/// ○ entry 3
235/// ```
237 int* selected,
238 RadioboxOption option) {
239 option.entries = std::move(entries);
240 option.selected = selected;
241 return Make<RadioboxBase>(std::move(option));
242}
243
244} // namespace ftxui
Un adaptador. Referencia una lista de cadenas.
Definition ref.hpp:116
static const Event TabReverse
Definition event.hpp:56
static const Event PageUp
Definition event.hpp:62
ConstStringListRef entries
static const Event ArrowUp
Definition event.hpp:42
static const Event Tab
Definition event.hpp:55
static const Event ArrowDown
Definition event.hpp:43
static const Event End
Definition event.hpp:61
static const Event Home
Definition event.hpp:60
static const Event PageDown
Definition event.hpp:63
static const Event Return
Definition event.hpp:53
static RadioboxOption Simple()
Opción para Radiobox estándar.
std::function< Element(const EntryState &)> transform
Component Radiobox(RadioboxOption options)
Una lista de elementos, donde solo uno puede ser seleccionado.
Opción para el componente Radiobox.
Decorator size(WidthOrHeight, Constraint, int value)
Aplica una restricción al tamaño de un elemento.
Element focus(Element)
Establece que child sea el elemento enfocado entre sus hermanos.
Definition frame.cpp:101
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
Definition util.hpp:11
El espacio de nombres ftxui:: de FTXUI.
Definition animation.hpp:10
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:27
std::shared_ptr< Node > Element
Definition elements.hpp:22
std::vector< Element > Elements
Definition elements.hpp:23
Element vbox(Elements)
Decorator reflect(Box &box)
Definition reflect.cpp:43
std::shared_ptr< ComponentBase > Component