FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
src/ftxui/component/dropdown.cpp
Go to the documentation of this file.
1// Copyright 2021 Arthur Sonzogni. 保留所有權利。
2// 本原始碼的使用受 MIT 授權條款約束,詳情請參閱 LICENSE 檔案。
4#include <functional> // for function
5#include <string> // for string
6
7#include <utility>
8#include "ftxui/component/component.hpp" // for Maybe, Checkbox, Make, Radiobox, Vertical, Dropdown
9#include "ftxui/component/component_base.hpp" // for Component, ComponentBase
10#include "ftxui/component/component_options.hpp" // for CheckboxOption, EntryState
11#include "ftxui/dom/elements.hpp" // for operator|, Element, border, filler, operator|=, separator, size, text, vbox, frame, vscroll_indicator, hbox, HEIGHT, LESS_THAN, bold, inverted
12#include "ftxui/screen/util.hpp" // for clamp
13#include "ftxui/util/ref.hpp" // for ConstStringListRef
14
15namespace ftxui {
16
17/// @brief 下拉式選單。
18/// @ingroup component
19/// @param entries 要顯示的項目清單。
20/// @param selected 選定項目的索引。
21Component Dropdown(ConstStringListRef entries, int* selected) {
22 DropdownOption option;
23 option.radiobox.entries = std::move(entries);
24 option.radiobox.selected = selected;
25 return Dropdown(option);
26}
27
28/// @brief 下拉式選單。
29/// @ingroup component
30/// @param option 下拉式選單的選項。
31// NOLINTNEXTLINE
33 class Impl : public ComponentBase, public DropdownOption {
34 public:
35 explicit Impl(DropdownOption option) : DropdownOption(std::move(option)) {
36 FillDefault();
37 checkbox_ = Checkbox(checkbox);
38 radiobox_ = Radiobox(radiobox);
39
40 Add(Container::Vertical({
41 checkbox_,
42 Maybe(radiobox_, checkbox.checked),
43 }));
44 }
45
46 Element OnRender() override {
47 selected_ =
48 util::clamp(radiobox.selected(), 0, int(radiobox.entries.size()) - 1);
49 selected_ = util::clamp(selected_(), 0, int(radiobox.entries.size()) - 1);
50
51 if (selected_() >= 0 && selected_() < int(radiobox.entries.size())) {
52 title_ = radiobox.entries[selected_()];
53 }
54
55 return transform(*open_, checkbox_->Render(), radiobox_->Render());
56 }
57
58 // 在選取時在核取方塊和單選方塊之間切換焦點。
59 bool OnEvent(ftxui::Event event) override {
60 const bool open_old = open_();
61 const int selected_old = selected_();
62 bool handled = ComponentBase::OnEvent(event);
63
64 // 下拉式選單開啟時,將焦點轉移到單選方塊。
65 if (!open_old && open_()) {
66 radiobox_->TakeFocus();
67 }
68
69 // 當使用者選擇一個項目時自動關閉下拉式選單,即使該項目與前一個相同。 if (open_old && open_()) {
70 const bool should_close =
71 (selected_() != selected_old) || //
72 (event == Event::Return) || //
73 (event == Event::Character(' ')) || //
74 (event == Event::Escape) || //
75 (event.is_mouse() && event.mouse().button == Mouse::Left &&
76 event.mouse().motion == Mouse::Pressed);
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,
111 Element radiobox_element) {
112 if (is_open) {
113 const int max_height = 12;
114 return vbox({
115 std::move(checkbox_element),
116 separator(),
117 std::move(radiobox_element) | vscroll_indicator | frame |
118 size(HEIGHT, LESS_THAN, max_height),
119 }) |
120 border;
121 }
122 return vbox({std::move(checkbox_element), filler()}) | border;
123 };
124 }
125 }
126
127 private:
128 Ref<bool> open_;
129 Ref<int> selected_;
130 Component checkbox_;
131 Component radiobox_;
132 std::string title_;
133 };
134
135 return Make<Impl>(option);
136}
137
138} // namespace ftxui
一個適配器。引用一個字串列表。
Definition ref.hpp:114
一個適配器。擁有或引用一個可變的物件。
Definition ref.hpp:46
auto radiobox
Definition gallery.cpp:73
struct Mouse mouse
Definition event.hpp:142
ConstStringListRef entries
Button button
Definition mouse.hpp:30
Motion motion
Definition mouse.hpp:33
它將自己實作為 ftxui::Element 進行渲染。它透過回應 ftxui::Event 來實現鍵盤導航。
Component Dropdown(ConstStringListRef entries, int *selected)
下拉式選單。
Dropdown 元件的選項。下拉式選單是開啟/關閉單選方塊的核取方塊。
代表一個事件。它可以是按鍵事件、終端機大小調整,或更多...
Definition event.hpp:27
Decorator size(WidthOrHeight, Constraint, int value)
限制元素的大小。
Element bold(Element)
使用粗體字型,用於需要更多強調的元素。
Definition bold.cpp:33
Element inverted(Element)
添加一個濾鏡,它將反轉前景和背景 顏色。
Definition inverted.cpp:34
Element text(std::wstring text)
顯示一段 Unicode 文字。
Definition text.cpp:160
Element separator()
在兩個元素之間繪製垂直或水平分隔線。
Element filler()
一個元素,它會按比例擴展以佔據容器中剩餘的空間。
Definition flex.cpp:97
Element vbox(Elements)
一個垂直一個接一個顯示元素的容器。
Definition vbox.cpp:95
FTXUI 的 ftxui:: 命名空間
Definition animation.hpp:10
std::shared_ptr< Node > Element
Definition elements.hpp:22
return Make< Impl >(option)
Element hbox(Elements)
一個逐一水平顯示元素的容器。
Definition hbox.cpp:94
@ LESS_THAN
Definition elements.hpp:159
std::shared_ptr< ComponentBase > Component
來自 |ButtonOption|、|CheckboxOption|、 |RadioboxOption|、|MenuEntryOption|、|MenuOption| 的轉換參數。