15 std::string header_label(std::string_view
label,
bool open)
17 return std::string(open ?
"^ " :
"v ") +
std::string(
label);
25 float x_min,
float x_max,
float row_h)
29 "Dropdown::place: no options");
33 auto& ctx = surface.
ctx();
34 const auto layer_ptr = surface.
layer_ptr();
38 .
min = { x_min, advanced.
min.y },
39 .max = { x_max, advanced.
max.y },
42 const auto labels = std::make_shared<std::vector<std::string>>(
m_labels);
44 const auto dims = std::make_shared<glm::uvec2>(
48 const uint32_t hid = header.first;
49 const auto& header_row = header.second;
51 auto selected_state = std::make_shared<MappedState<size_t>>();
53 auto open_state = std::make_shared<MappedState<bool>>();
54 open_state->write(
false);
56 auto refresh_header = [header_row, labels, selected_state, open_state, dims]() {
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);
67 layer_ptr->bring_to_front(hid);
72 selected_state->write(
index);
78 const auto count =
static_cast<uint32_t
>(labels->size());
80 const float list_top = header_rect.min.y;
83 surface.
render_config({ .additional_textures = { {
"text", nullptr } } }));
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);
97 const auto rows = std::make_shared<std::vector<std::shared_ptr<Element>>>();
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 } };
104 const uint32_t
id = made.first;
105 const auto& row = made.second;
106 rows->push_back(row);
112 ctx.on_scroll(
id, wheel);
114 *layer_ptr,
id, row_rect,
115 [row](Kinesis::AABB2D shifted) { row->retarget(shifted); },
118 layer_ptr->relate(hid,
id);
123 [open_state, set_open](uint32_t, glm::vec2) { set_open(!open_state->value); });
126 [
window = surface.window(), x_min, x_max, row_h, dims, labels,
rows, refresh_header](uint32_t, uint32_t) {
130 for (
size_t i = 0; i <
rows->size(); ++i)
137 ElementRef { layer_ptr, hid }, selected_state, header_row->buffer.buffer());
140 selected = std::move(selected_state);
141 open = std::move(open_state);
142 header_bounds = header_rect;
152 return place(surface, cursor, cursor.
x_min(), cursor.
x_max(), row_h);
#define MF_WARN(comp, ctx,...)
std::weak_ptr< Core::Window > window
@ API
API calls from external code.
@ Portal
High-level user-facing API layer.
void open(std::span< const float > mask, std::span< float > tmp, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Morphological opening writing into dst.
Axis-aligned bounding rectangle in a 2D coordinate space.