25class RadioboxBase :
public ComponentBase,
public RadioboxOption {
27 explicit RadioboxBase(
const RadioboxOption& option)
28 : RadioboxOption(option) {}
34 const bool is_menu_focused = Focused();
35 elements.reserve(
size());
36 for (
int i = 0; i <
size(); ++i) {
37 const bool is_focused = (focused_entry() == i) && is_menu_focused;
38 const bool is_selected = (hovered_ == i);
39 auto state = EntryState{
40 std::string(entries[i]), selected() == i, is_selected, is_focused, i,
43 (transform ? transform : RadioboxOption::Simple().transform)(state);
53 bool OnEvent(Event event)
override {
55 if (!CaptureMouse(event)) {
59 if (event.is_mouse()) {
60 return OnMouseEvent(event);
64 const int old_hovered = hovered_;
65 if (event == Event::ArrowUp || event == Event::Character(
'k')) {
68 if (event == Event::ArrowDown || event == Event::Character(
'j')) {
71 if (event == Event::PageUp) {
72 (hovered_) -= box_.y_max - box_.y_min;
74 if (event == Event::PageDown) {
75 (hovered_) += box_.y_max - box_.y_min;
77 if (event == Event::Home) {
80 if (event == Event::End) {
81 (hovered_) =
size() - 1;
83 if (event == Event::Tab &&
size()) {
84 hovered_ = (hovered_ + 1) %
size();
86 if (event == Event::TabReverse &&
size()) {
87 hovered_ = (hovered_ +
size() - 1) %
size();
92 if (hovered_ != old_hovered) {
93 focused_entry() = hovered_;
94 App::PostEventOrExecute(on_change);
99 if (event == Event::Character(
' ') || event == Event::Return) {
100 selected() = hovered_;
101 App::PostEventOrExecute(on_change);
108 bool OnMouseEvent(Event event) {
109 if (event.mouse().button == Mouse::WheelDown ||
110 event.mouse().button == Mouse::WheelUp) {
111 return OnMouseWheel(event);
114 for (
int i = 0; i <
size(); ++i) {
115 if (!boxes_[i].Contain(event.mouse().x, event.mouse().y)) {
121 if (event.mouse().button == Mouse::Left &&
122 event.mouse().motion == Mouse::Pressed) {
123 if (selected() != i) {
125 App::PostEventOrExecute(on_change);
134 bool OnMouseWheel(Event event) {
135 if (!box_.Contain(event.mouse().x, event.mouse().y)) {
139 const int old_hovered = hovered_;
141 if (event.mouse().button == Mouse::WheelUp) {
144 if (event.mouse().button == Mouse::WheelDown) {
150 if (hovered_ != old_hovered) {
151 App::PostEventOrExecute(on_change);
158 boxes_.resize(
size());
164 bool Focusable() const final {
return entries.size(); }
165 int size()
const {
return int(entries.size()); }
167 int hovered_ = selected();
168 std::vector<Box> boxes_;
238 RadioboxOption option) {
239 option.entries = std::move(entries);
240 option.selected = selected;
Component Radiobox(ConstStringListRef entries, int *selected_, RadioboxOption options={})
一份元素清單,只能選取其中一個。
Decorator size(WidthOrHeight direction, Constraint constraint, int value)
對元素的大小套用限制。
Element focus(Element child)
將 child 設置為其同級元素中被聚焦的元素。
Element vbox(Elements children)
一個垂直一個接一個顯示元素的容器。
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
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