18class FocusNode :
public Node {
20 explicit FocusNode(
Elements children) : Node(std::move(children)) {}
22 void ComputeRequirement()
override {
23 Node::ComputeRequirement();
24 requirement_ = children_[0]->requirement();
25 requirement_.focused.enabled =
true;
26 requirement_.focused.node =
this;
27 requirement_.focused.box.x_min = 0;
28 requirement_.focused.box.y_min = 0;
29 requirement_.focused.box.x_max = requirement_.min_x - 1;
30 requirement_.focused.box.y_max = requirement_.min_y - 1;
33 void SetBox(Box box)
override {
35 children_[0]->SetBox(box);
39class Frame :
public Node {
41 Frame(
Elements children,
bool x_frame,
bool y_frame)
42 : Node(std::move(children)), x_frame_(x_frame), y_frame_(y_frame) {}
44 void SetBox(Box box)
override {
46 auto& focused_box = requirement_.focused.box;
47 Box children_box = box;
50 const int external_dimx = box.x_max - box.x_min;
51 const int internal_dimx = std::max(requirement_.min_x, external_dimx);
52 const int focused_dimx = focused_box.x_max - focused_box.x_min;
53 int dx = focused_box.x_min - external_dimx / 2 + focused_dimx / 2;
54 dx = std::max(0, std::min(internal_dimx - external_dimx - 1, dx));
55 children_box.x_min = box.x_min - dx;
56 children_box.x_max = box.x_min + internal_dimx - dx;
60 const int external_dimy = box.y_max - box.y_min;
61 const int internal_dimy = std::max(requirement_.min_y, external_dimy);
62 const int focused_dimy = focused_box.y_max - focused_box.y_min;
63 int dy = focused_box.y_min - external_dimy / 2 + focused_dimy / 2;
64 dy = std::max(0, std::min(internal_dimy - external_dimy - 1, dy));
65 children_box.y_min = box.y_min - dy;
66 children_box.y_max = box.y_min + internal_dimy - dy;
69 children_[0]->SetBox(children_box);
72 void Render(Screen& screen)
override {
73 const AutoReset<Box> stencil(&screen.stencil,
74 Box::Intersection(box_, screen.stencil));
75 children_[0]->Render(screen);
83class FocusCursorNode :
public FocusNode {
85 FocusCursorNode(
Elements children, Screen::Cursor::Shape shape)
86 : FocusNode(std::move(children)), shape_(shape) {}
89 void ComputeRequirement()
override {
90 FocusNode::ComputeRequirement();
91 requirement_.focused.cursor_shape = shape_;
93 Screen::Cursor::Shape shape_;
102 return std::make_shared<FocusNode>(unpack(std::move(child)));
109 return focus(std::move(e));
117 return std::make_shared<Frame>(unpack(std::move(child)),
true,
true);
125 return std::make_shared<Frame>(unpack(std::move(child)),
true,
false);
133 return std::make_shared<Frame>(unpack(std::move(child)),
false,
true);
146 return std::make_shared<FocusCursorNode>(unpack(std::move(child)),
147 Screen::Cursor::Block);
160 return std::make_shared<FocusCursorNode>(unpack(std::move(child)),
161 Screen::Cursor::BlockBlinking);
174 return std::make_shared<FocusCursorNode>(unpack(std::move(child)),
175 Screen::Cursor::Bar);
188 return std::make_shared<FocusCursorNode>(unpack(std::move(child)),
189 Screen::Cursor::BarBlinking);
202 return std::make_shared<FocusCursorNode>(unpack(std::move(child)),
203 Screen::Cursor::Underline);
216 return std::make_shared<FocusCursorNode>(unpack(std::move(child)),
217 Screen::Cursor::UnderlineBlinking);
Element focusCursorBarBlinking(Element child)
與 focus 相同,但將游標形狀設置為閃爍條狀。
Element focusCursorUnderlineBlinking(Element child)
與 focus 相同,但將游標形狀設置為閃爍底線。
Element focusCursorBar(Element child)
與 focus 相同,但將游標形狀設置為靜止條狀。
Element focusCursorBlock(Element child)
與 focus 相同,但將游標形狀設置為靜止條狀。
Element focusCursorUnderline(Element child)
與 focus 相同,但將游標形狀設置為靜止底線。
Element focus(Element child)
將 child 設置為其同級元素中被聚焦的元素。
Element focusCursorBlockBlinking(Element child)
與 focus 相同,但將游標形狀設置為閃爍方塊。
std::shared_ptr< Node > Element
Element xframe(Element child)
與 frame 相同,但僅限於 x 軸。
std::vector< Element > Elements
Element yframe(Element child)
與 frame 相同,但僅限於 y 軸。
void Render(Screen &screen, Node *node, Selection &selection)
Element frame(Element child)
允許元素顯示在「虛擬」區域內。其大小可以大於其容器。在這種情況下,只會顯示較小的一部分。視圖可滾動以使聚焦元素可見。
Element select(Element e)
將 child 設為其兄弟元素中被聚焦的那一個。