16class ContainerBase :
public ComponentBase {
18 ContainerBase(
Components children,
int* selector)
19 : selector_(selector ? selector : &selected_) {
21 Add(std::move(child));
26 bool OnEvent(Event event)
override {
27 if (event.is_mouse()) {
28 return OnMouseEvent(event);
35 if (ActiveChild() && ActiveChild()->OnEvent(event)) {
39 return EventHandler(event);
50 void SetActiveChild(ComponentBase* child)
override {
51 for (
size_t i = 0; i <
children_.size(); ++i) {
61 virtual bool EventHandler(Event ) {
return false; }
63 virtual bool OnMouseEvent(Event event) {
68 int* selector_ =
nullptr;
70 void MoveSelector(
int dir) {
71 for (
int i = *selector_ + dir; i >= 0 && i < (int)
children_.size();
80 void MoveSelectorWrap(
int dir) {
84 for (
size_t offset = 1; offset <
children_.size(); ++offset) {
85 size_t i = ((size_t(*selector_ + offset * dir +
children_.size())) %
95class VerticalContainer :
public ContainerBase {
97 using ContainerBase::ContainerBase;
102 elements.push_back(it->Render());
104 if (elements.empty()) {
110 bool EventHandler(Event event)
override {
111 int old_selected = *selector_;
119 for (
int i = 0; i < box_.
y_max - box_.
y_min; ++i) {
124 for (
int i = 0; i < box_.
y_max - box_.
y_min; ++i) {
129 for (
size_t i = 0; i <
children_.size(); ++i) {
134 for (
size_t i = 0; i <
children_.size(); ++i) {
139 MoveSelectorWrap(+1);
142 MoveSelectorWrap(-1);
145 *selector_ = std::max(0, std::min(
int(
children_.size()) - 1, *selector_));
146 return old_selected != *selector_;
149 bool OnMouseEvent(Event event)
override {
150 if (ContainerBase::OnMouseEvent(event)) {
159 if (!box_.
Contain(event.mouse().x, event.mouse().y)) {
169 *selector_ = std::max(0, std::min(
int(
children_.size()) - 1, *selector_));
177class HorizontalContainer :
public ContainerBase {
179 using ContainerBase::ContainerBase;
184 elements.push_back(it->Render());
186 if (elements.empty()) {
187 return text(
"Empty container");
189 return hbox(std::move(elements));
192 bool EventHandler(Event event)
override {
193 int old_selected = *selector_;
201 MoveSelectorWrap(+1);
204 MoveSelectorWrap(-1);
207 *selector_ = std::max(0, std::min(
int(
children_.size()) - 1, *selector_));
208 return old_selected != *selector_;
212class TabContainer :
public ContainerBase {
214 using ContainerBase::ContainerBase;
219 return active_child->Render();
221 return text(
"Empty container");
224 bool Focusable()
const override {
231 bool OnMouseEvent(Event event)
override {
232 return ActiveChild()->OnEvent(event);
255 return Vertical(std::move(children),
nullptr);
277 return std::make_shared<VerticalContainer>(std::move(children), selector);
298 return Horizontal(std::move(children),
nullptr);
320 return std::make_shared<HorizontalContainer>(std::move(children), selector);
343 return std::make_shared<TabContainer>(std::move(children), selector);
virtual bool Focusable() const
Return true when the component contains focusable elements. The non focusable Components will be skip...
bool Focused() const
Returns if the elements if focused by the user. True when the ComponentBase is focused by the user....
void Add(Component children)
Add a child. @param child The child to be attached.
virtual bool OnEvent(Event)
Called in response to an event.
Component Horizontal(Components children)
A list of components, drawn one by one horizontally and navigated horizontally using left/right arrow...
Component Vertical(Components children)
A list of components, drawn one by one vertically and navigated vertically using up/down arrow key or...
Component Tab(Components children, int *selector)
A list of components, where only one is drawn and interacted with at a time. The |selector| gives the...
std::shared_ptr< Node > Element
std::vector< Component > Components
Element hbox(Elements)
A container displaying elements horizontally one by one.
std::vector< Element > Elements
Element text(std::wstring text)
Display a piece of unicode text.
Decorator reflect(Box &box)
std::shared_ptr< ComponentBase > Component
Element vbox(Elements)
A container displaying elements vertically one by one.
bool Contain(int x, int y) const
static const Event TabReverse
static const Event PageUp
static const Event ArrowUp
static const Event ArrowDown
static const Event PageDown
static const Event ArrowLeft
static const Event ArrowRight