18class ContainerBase :
public ComponentBase {
20 ContainerBase(
Components children,
int* selector)
21 : selector_(selector ? selector : &selected_) {
23 Add(std::move(child));
28 bool OnEvent(Event event)
override {
29 if (event.is_mouse()) {
30 return OnMouseEvent(event);
37 if (ActiveChild() && ActiveChild()->OnEvent(event)) {
41 return EventHandler(event);
53 for (
size_t i = 0; i <
children_.size(); ++i) {
55 *selector_ =
static_cast<int>(i);
63 virtual bool EventHandler(Event ) {
return false; }
65 virtual bool OnMouseEvent(Event event) {
70 int* selector_ =
nullptr;
72 void MoveSelector(
int dir) {
73 for (
int i = *selector_ + dir; i >= 0 && i < int(
children_.size());
82 void MoveSelectorWrap(
int dir) {
86 for (
size_t offset = 1; offset <
children_.size(); ++offset) {
97class VerticalContainer :
public ContainerBase {
99 using ContainerBase::ContainerBase;
105 elements.push_back(it->Render());
107 if (elements.empty()) {
113 bool EventHandler(Event event)
override {
114 const int old_selected = *selector_;
122 for (
int i = 0; i < box_.
y_max - box_.
y_min; ++i) {
127 for (
int i = 0; i < box_.
y_max - box_.
y_min; ++i) {
132 for (
size_t i = 0; i <
children_.size(); ++i) {
137 for (
size_t i = 0; i <
children_.size(); ++i) {
142 MoveSelectorWrap(+1);
145 MoveSelectorWrap(-1);
148 *selector_ = std::max(0, std::min(
int(
children_.size()) - 1, *selector_));
149 return old_selected != *selector_;
152 bool OnMouseEvent(Event event)
override {
153 if (ContainerBase::OnMouseEvent(event)) {
162 if (!box_.
Contain(event.mouse().x, event.mouse().y)) {
166 const int old_selected = *selector_;
173 *selector_ = std::max(0, std::min(
int(
children_.size()) - 1, *selector_));
175 return old_selected != *selector_;
181class HorizontalContainer :
public ContainerBase {
183 using ContainerBase::ContainerBase;
189 elements.push_back(it->Render());
191 if (elements.empty()) {
192 return text(
"Empty container");
194 return hbox(std::move(elements));
197 bool EventHandler(Event event)
override {
198 const int old_selected = *selector_;
206 MoveSelectorWrap(+1);
209 MoveSelectorWrap(-1);
212 *selector_ = std::max(0, std::min(
int(
children_.size()) - 1, *selector_));
213 return old_selected != *selector_;
217class TabContainer :
public ContainerBase {
219 using ContainerBase::ContainerBase;
222 const Component active_child = ActiveChild();
224 return active_child->Render();
226 return text(
"Empty container");
229 bool Focusable()
const override {
236 bool OnMouseEvent(Event event)
override {
237 return ActiveChild() && ActiveChild()->OnEvent(event);
241class StackedContainer :
public ContainerBase {
243 explicit StackedContainer(
Components children)
244 : ContainerBase(std::move(children), nullptr) {}
250 elements.push_back(child->Render());
253 std::reverse(elements.begin(), elements.end());
254 return dbox(std::move(elements));
257 bool Focusable() const final {
259 if (child->Focusable()) {
282 [child](
const Component& c) { return c.get() == child; });
286 std::rotate(
children_.begin(), it, it + 1);
289 bool OnEvent(Event event)
final {
291 if (child->OnEvent(event)) {
317 return Vertical(std::move(children),
nullptr);
338 return std::make_shared<VerticalContainer>(std::move(children), selector);
358 return Horizontal(std::move(children),
nullptr);
379 return std::make_shared<HorizontalContainer>(std::move(children), selector);
400 return std::make_shared<TabContainer>(std::move(children), selector);
425 return std::make_shared<StackedContainer>(std::move(children));
static const Event TabReverse
virtual bool Focusable() const
当组件包含可聚焦元素时返回 true。 使用键盘导航时,不可聚焦的组件将被跳过。
bool Focused() const
返回元素是否被用户聚焦。 当 ComponentBase 被用户聚焦时返回 true。当一个元素及其所有祖先都是其父级的 ActiveChild() 并且它是 Focusable() 时,该元素被聚焦。
static const Event PageUp
void Add(Component children)
添加一个子项。 @param child 要附加的子项。
static const Event ArrowUp
static const Event ArrowDown
virtual bool OnEvent(Event)
响应事件时调用。
static const Event PageDown
static const Event ArrowLeft
static const Event ArrowRight
Component Horizontal(Components children)
一个组件列表,水平逐个绘制,并使用左/右箭头键或“h”/“l”键水平导航。
Component Vertical(Components children)
一个组件列表,垂直逐个绘制,并使用上/下箭头键或“j”/“k”键垂直导航。
Component Stacked(Components children)
一个组件列表,它们相互堆叠。 事件传播到第一个组件,如果未处理,则传播到第二个,依此类推。 组件以给定顺序的相反顺序绘制。 当一个组件获得焦点时,它会被置于最前面,而不改变其他元素的相对顺序。
Component Tab(Components children, int *selector)
一个组件列表,一次只绘制并与其交互一个。|selector| 提供所选组件的索引。这对于实现选项卡很有用。
Element text(std::wstring text)
显示一段Unicode文本。
Element dbox(Elements)
将多个元素堆叠在一起。
Element vbox(Elements)
垂直一个接一个显示元素的容器。
bool Contain(int x, int y) const
FTXUI ftxui::Container:: 命名空间
#include "ftxui/component/component_base.hpp" // 用于 ComponentBase
std::shared_ptr< Node > Element
std::vector< Component > Components
Element hbox(Elements)
一个按水平顺序逐一显示元素的容器。
std::vector< Element > Elements
Decorator reflect(Box &box)
std::shared_ptr< ComponentBase > Component