26class RadioboxBase :
public ComponentBase,
public RadioboxOption {
28 explicit RadioboxBase(
const RadioboxOption& option)
29 : RadioboxOption(option) {}
35 const bool is_menu_focused = Focused();
36 elements.reserve(
size());
37 for (
int i = 0; i <
size(); ++i) {
38 const bool is_focused = (focused_entry() == i) && is_menu_focused;
39 const bool is_selected = (hovered_ == i);
40 auto state = EntryState{
41 std::string(entries[i]), selected() == i, is_selected, is_focused, i,
44 (transform ? transform : RadioboxOption::Simple().transform)(state);
54 bool OnEvent(Event event)
override {
56 if (!CaptureMouse(event)) {
60 if (event.is_mouse()) {
61 return OnMouseEvent(event);
65 const int old_hovered = hovered_;
66 if (event == Event::ArrowUp || event == Event::Character(
'k')) {
69 if (event == Event::ArrowDown || event == Event::Character(
'j')) {
72 if (event == Event::PageUp) {
73 (hovered_) -= box_.y_max - box_.y_min;
75 if (event == Event::PageDown) {
76 (hovered_) += box_.y_max - box_.y_min;
78 if (event == Event::Home) {
81 if (event == Event::End) {
82 (hovered_) =
size() - 1;
84 if (event == Event::Tab &&
size()) {
85 hovered_ = (hovered_ + 1) %
size();
87 if (event == Event::TabReverse &&
size()) {
88 hovered_ = (hovered_ +
size() - 1) %
size();
93 if (hovered_ != old_hovered) {
94 focused_entry() = hovered_;
95 App::PostEventOrExecute(on_change);
100 if (event == Event::Character(
' ') || event == Event::Return) {
101 selected() = hovered_;
102 App::PostEventOrExecute(on_change);
109 bool OnMouseEvent(Event event) {
110 if (event.mouse().button == Mouse::WheelDown ||
111 event.mouse().button == Mouse::WheelUp) {
112 return OnMouseWheel(event);
115 for (
int i = 0; i <
size(); ++i) {
116 if (!boxes_[i].Contain(event.mouse().x, event.mouse().y)) {
122 if (event.mouse().button == Mouse::Left &&
123 event.mouse().motion == Mouse::Pressed) {
124 if (selected() != i) {
126 App::PostEventOrExecute(on_change);
135 bool OnMouseWheel(Event event) {
136 if (!box_.Contain(event.mouse().x, event.mouse().y)) {
140 const int old_hovered = hovered_;
142 if (event.mouse().button == Mouse::WheelUp) {
145 if (event.mouse().button == Mouse::WheelDown) {
151 if (hovered_ != old_hovered) {
152 App::PostEventOrExecute(on_change);
159 boxes_.resize(
size());
165 bool Focusable() const final {
return entries.size(); }
166 int size()
const {
return int(entries.size()); }
168 int hovered_ = selected();
169 std::vector<Box> boxes_;
239 RadioboxOption option) {
240 option.entries = std::move(entries);
241 option.selected = selected;
Component Radiobox(ConstStringListRef entries, int *selected_, RadioboxOption options={})
A list of element, where only one can be selected.
Decorator size(WidthOrHeight direction, Constraint constraint, int value)
Apply a constraint on the size of an element.
Element focus(Element child)
Set the child to be the one focused among its siblings.
Element vbox(Elements children)
A container displaying elements vertically one by one.
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
The FTXUI ftxui:: namespace.
std::shared_ptr< T > Make(Args &&... args)
std::shared_ptr< Node > Element
std::vector< Element > Elements
Decorator reflect(Box &box)
std::shared_ptr< ComponentBase > Component