Register the header and its option rows and wire their input.
26{
29 "Dropdown::place: no options");
30 return *this;
31 }
32
33 auto& ctx = surface.ctx();
34 const auto layer_ptr = surface.layer_ptr();
35
36 const Kinesis::AABB2D advanced = cursor.advance(row_h);
37 const Kinesis::AABB2D header_rect {
38 .min = { x_min, advanced.min.y },
39 .max = { x_max, advanced.max.y },
40 };
41
42 const auto labels = std::make_shared<std::vector<std::string>>(
m_labels);
44 const auto dims = std::make_shared<glm::uvec2>(
46
48 const uint32_t hid = header.first;
49 const auto& header_row = header.second;
50
51 auto selected_state = std::make_shared<MappedState<size_t>>();
53 auto open_state = std::make_shared<MappedState<bool>>();
54 open_state->write(false);
55
56 auto refresh_header = [header_row, labels, selected_state, open_state, dims]() {
57 header_row->set_text(
60 };
61
62 auto set_open = [layer_ptr, hid, open_state, refresh_header](bool next) {
63 open_state->write(next);
64 for (const uint32_t rel_id : layer_ptr->related_ids(hid))
65 layer_ptr->set_visible(rel_id, next);
66 if (next)
67 layer_ptr->bring_to_front(hid);
68 refresh_header();
69 };
70
72 selected_state->write(
index);
73 set_open(false);
76 };
77
78 const auto count =
static_cast<uint32_t
>(labels->size());
80 const float list_top = header_rect.min.y;
81
83 surface.render_config({ .additional_textures = { { "text", nullptr } } }));
84
85 std::optional<Scrollable> panel;
86 std::function<void(uint32_t, glm::vec2, double, double)> wheel;
87 if (
count > visible) {
90 std::move(panel_buf), surface,
91 { .min = { x_min, list_top - row_h * static_cast<float>(visible) }, .max = { x_max, list_top } },
94 layer_ptr->relate(hid, panel->viewport_id);
95 }
96
97 const auto rows = std::make_shared<std::vector<std::shared_ptr<Element>>>();
98
99 for (uint32_t i = 0; i <
count; ++i) {
100 const float top = list_top - row_h * static_cast<float>(i);
101 const Kinesis::AABB2D row_rect { .min = { x_min, top - row_h }, .max = { x_max, top } };
102
104 const uint32_t id = made.first;
105 const auto& row = made.second;
106 rows->push_back(row);
107
110
111 if (panel) {
112 ctx.on_scroll(id, wheel);
113 panel->track(
114 *layer_ptr, id, row_rect,
115 [row](Kinesis::AABB2D shifted) { row->retarget(shifted); },
116 row->buffer);
117 } else {
118 layer_ptr->relate(hid, id);
119 }
120 }
121
123 [open_state, set_open](uint32_t, glm::vec2) { set_open(!open_state->value); });
124
125 ctx.on_resize(hid,
126 [
window = surface.window(), x_min, x_max, row_h, dims, labels,
rows, refresh_header](uint32_t, uint32_t) {
128 refresh_header();
130 for (
size_t i = 0; i <
rows->size(); ++i)
132 });
133
134 set_open(false);
135
137 ElementRef { layer_ptr, hid }, selected_state, header_row->buffer.buffer());
138
140 selected = std::move(selected_state);
141 open = std::move(open_state);
144 return *this;
145}
#define MF_WARN(comp, ctx,...)
std::weak_ptr< Core::Window > window
@ API
API calls from external code.
@ Portal
High-level user-facing API layer.