FTXUI  2.0.0
C++ functional terminal UI.
Loading...
Searching...
No Matches
toggle.cpp
Go to the documentation of this file.
1#include <algorithm> // for clamp, max
2#include <functional> // for function
3#include <memory> // for shared_ptr, allocator_traits<>::value_type
4#include <utility> // for move
5#include <vector> // for vector
6
7#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
8#include "ftxui/component/component.hpp" // for Make, Toggle
9#include "ftxui/component/component_base.hpp" // for Component, ComponentBase
10#include "ftxui/component/component_options.hpp" // for ToggleOption
11#include "ftxui/component/event.hpp" // for Event, Event::ArrowLeft, Event::ArrowRight, Event::Return, Event::Tab, Event::TabReverse
12#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Pressed
13#include "ftxui/dom/elements.hpp" // for operator|, Element, Elements, hbox, reflect, separator, text, focus, nothing, select
14#include "ftxui/screen/box.hpp" // for Box
15#include "ftxui/screen/util.hpp"
16#include "ftxui/util/ref.hpp" // for Ref, ConstStringListRef
17
18namespace ftxui {
19
20namespace {
21
22/// @brief An horizontal list of elements. The user can navigate through them.
23/// @ingroup component
24class ToggleBase : public ComponentBase {
25 public:
26 ToggleBase(ConstStringListRef entries,
27 int* selected,
28 Ref<ToggleOption> option)
29 : entries_(entries), selected_(selected), option_(std::move(option)) {}
30
31 private:
32 Element Render() override {
33 Clamp();
34 Elements children;
35 bool is_toggle_focused = Focused();
36 for (int i = 0; i < size(); ++i) {
37 // Separator.
38 if (i != 0)
39 children.push_back(separator());
40
41 bool is_focused = (focused_entry() == i) && is_toggle_focused;
42 bool is_selected = (*selected_ == i);
43
44 auto style = is_selected ? (is_focused ? option_->style_selected_focused
45 : option_->style_selected)
46 : (is_focused ? option_->style_focused
47 : option_->style_normal);
48 auto focus_management = !is_selected ? nothing
49 : is_toggle_focused ? focus
50 : select;
51 children.push_back(text(entries_[i]) | style | focus_management |
52 reflect(boxes_[i]));
53 }
54 return hbox(std::move(children));
55 }
56
57 bool OnEvent(Event event) override {
58 Clamp();
59 if (event.is_mouse())
60 return OnMouseEvent(event);
61
62 int old_selected = *selected_;
63 if (event == Event::ArrowLeft || event == Event::Character('h'))
64 (*selected_)--;
65 if (event == Event::ArrowRight || event == Event::Character('l'))
66 (*selected_)++;
67 if (event == Event::Tab && size())
68 *selected_ = (*selected_ + 1) % size();
69 if (event == Event::TabReverse && size())
70 *selected_ = (*selected_ + size() - 1) % size();
71
72 *selected_ = util::clamp(*selected_, 0, size() - 1);
73
74 if (old_selected != *selected_) {
75 focused_entry() = *selected_;
76 option_->on_change();
77 return true;
78 }
79
80 if (event == Event::Return) {
81 option_->on_enter();
82 return true;
83 }
84
85 return false;
86 }
87
88 bool OnMouseEvent(Event event) {
89 if (!CaptureMouse(event))
90 return false;
91 for (int i = 0; i < size(); ++i) {
92 if (!boxes_[i].Contain(event.mouse().x, event.mouse().y))
93 continue;
94
95 TakeFocus();
96 focused_entry() = i;
97 if (event.mouse().button == Mouse::Left &&
98 event.mouse().motion == Mouse::Pressed) {
99 TakeFocus();
100 if (*selected_ != i) {
101 *selected_ = i;
102 option_->on_change();
103 }
104 return true;
105 }
106 }
107 return false;
108 }
109
110 void Clamp() {
111 boxes_.resize(size());
112 *selected_ = util::clamp(*selected_, 0, size() - 1);
113 focused_entry() = util::clamp(focused_entry(), 0, size() - 1);
114 }
115
116 bool Focusable() const final { return size(); }
117 int& focused_entry() { return option_->focused_entry(); }
118 int size() const { return entries_.size(); }
119
120 ConstStringListRef entries_;
121 int* selected_ = 0;
122
123 std::vector<Box> boxes_;
124 Ref<ToggleOption> option_;
125};
126
127} // namespace
128
129/// @brief An horizontal list of elements. The user can navigate through them.
130/// @param entries The list of selectable entries to display.
131/// @param selected Reference the selected entry.
132/// @param option Additional optional parameters.
133/// @ingroup component
135 int* selected,
136 Ref<ToggleOption> option) {
137 return Make<ToggleBase>(entries, selected, std::move(option));
138}
139
140} // namespace ftxui
141
142// Copyright 2020 Arthur Sonzogni. All rights reserved.
143// Use of this source code is governed by the MIT license that can be found in
144// the LICENSE file.
An adapter. Reference a list of strings.
Definition ref.hpp:96
An adapter. Own or reference an mutable object.
Definition ref.hpp:27
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
Definition util.hpp:6
Element nothing(Element element)
A decoration doing absolutely nothing.
Definition util.cpp:26
Component Toggle(ConstStringListRef entries, int *selected, Ref< ToggleOption > option={})
An horizontal list of elements. The user can navigate through them.
Definition toggle.cpp:134
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:25
std::shared_ptr< Node > Element
Definition elements.hpp:18
Element focus(Element)
Definition frame.cpp:79
Element hbox(Elements)
A container displaying elements horizontally one by one.
Definition hbox.cpp:76
std::vector< Element > Elements
Definition elements.hpp:19
Element text(std::wstring text)
Display a piece of unicode text.
Definition text.cpp:106
Decorator reflect(Box &box)
Definition reflect.cpp:39
Element separator(void)
Draw a vertical or horizontal separation in between two other elements.
void Render(Screen &screen, const Element &node)
Display an element on a ftxui::Screen.
Definition node.cpp:40
Decorator size(Direction, Constraint, int value)
Apply a constraint on the size of an element.
Definition size.cpp:86
Element select(Element)
Definition frame.cpp:38
std::shared_ptr< ComponentBase > Component
static const Event TabReverse
Definition event.hpp:46
static const Event Tab
Definition event.hpp:45
static const Event Return
Definition event.hpp:43
static const Event ArrowLeft
Definition event.hpp:35
static const Event ArrowRight
Definition event.hpp:36