17class ContainerBase :
public ComponentBase {
19 ContainerBase(
Components children,
int* selector)
20 : selector_(selector ? selector : &selected_) {
22 Add(std::move(child));
27 bool OnEvent(Event event)
override {
28 if (event.is_mouse()) {
29 return OnMouseEvent(event);
36 if (ActiveChild() && ActiveChild()->OnEvent(event)) {
40 return EventHandler(event);
52 for (
size_t i = 0; i <
children_.size(); ++i) {
54 *selector_ =
static_cast<int>(i);
62 virtual bool EventHandler(Event ) {
return false; }
64 virtual bool OnMouseEvent(Event event) {
69 int* selector_ =
nullptr;
71 void MoveSelector(
int dir) {
72 for (
int i = *selector_ + dir; i >= 0 && i < int(
children_.size());
81 void MoveSelectorWrap(
int dir) {
85 for (
size_t offset = 1; offset <
children_.size(); ++offset) {
96class VerticalContainer :
public ContainerBase {
98 using ContainerBase::ContainerBase;
104 elements.push_back(it->Render());
106 if (elements.empty()) {
112 bool EventHandler(Event event)
override {
113 const int old_selected = *selector_;
121 for (
int i = 0; i < box_.
y_max - box_.
y_min; ++i) {
126 for (
int i = 0; i < box_.
y_max - box_.
y_min; ++i) {
131 for (
size_t i = 0; i <
children_.size(); ++i) {
136 for (
size_t i = 0; i <
children_.size(); ++i) {
141 MoveSelectorWrap(+1);
144 MoveSelectorWrap(-1);
147 *selector_ = std::max(0, std::min(
int(
children_.size()) - 1, *selector_));
148 return old_selected != *selector_;
151 bool OnMouseEvent(Event event)
override {
152 if (ContainerBase::OnMouseEvent(event)) {
161 if (!box_.
Contain(event.mouse().x, event.mouse().y)) {
165 const int old_selected = *selector_;
172 *selector_ = std::max(0, std::min(
int(
children_.size()) - 1, *selector_));
174 return old_selected != *selector_;
180class HorizontalContainer :
public ContainerBase {
182 using ContainerBase::ContainerBase;
188 elements.push_back(it->Render());
190 if (elements.empty()) {
191 return text(
"Empty container");
193 return hbox(std::move(elements));
196 bool EventHandler(Event event)
override {
197 const int old_selected = *selector_;
205 MoveSelectorWrap(+1);
208 MoveSelectorWrap(-1);
211 *selector_ = std::max(0, std::min(
int(
children_.size()) - 1, *selector_));
212 return old_selected != *selector_;
216class TabContainer :
public ContainerBase {
218 using ContainerBase::ContainerBase;
221 const Component active_child = ActiveChild();
223 return active_child->Render();
225 return text(
"Empty container");
228 bool Focusable()
const override {
235 bool OnMouseEvent(Event event)
override {
236 return ActiveChild() && ActiveChild()->OnEvent(event);
240class StackedContainer :
public ContainerBase {
242 explicit StackedContainer(
Components children)
243 : ContainerBase(std::move(children), nullptr) {}
249 elements.push_back(child->Render());
252 std::reverse(elements.begin(), elements.end());
253 return dbox(std::move(elements));
256 bool Focusable() const final {
258 if (child->Focusable()) {
281 [child](
const Component& c) { return c.get() == child; });
285 std::rotate(
children_.begin(), it, it + 1);
288 bool OnEvent(Event event)
final {
290 if (child->OnEvent(event)) {
316 return Vertical(std::move(children),
nullptr);
337 return std::make_shared<VerticalContainer>(std::move(children), selector);
357 return Horizontal(std::move(children),
nullptr);
378 return std::make_shared<HorizontalContainer>(std::move(children), selector);
399 return std::make_shared<TabContainer>(std::move(children), selector);
424 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:: 命名空間
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