MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ pick() [1/2]

MAYAFLUX_API void MayaFlux::Portal::Forma::pick ( std::string  title,
std::vector< std::string >  labels,
PickCallback  callback 
)

Open a window of clickable rows, one per label, and report the choice.

Requires Portal::Forma to be initialized and the engine running. The callback fires exactly once, on the event thread, so it must not block. Selecting a row hides the window and delivers its index. Closing the window delivers nullopt. Lists longer than ten rows scroll with the mouse wheel. An empty list delivers nullopt immediately.

Parameters
titleWindow title.
labelsRow captions, in display order.
callbackInvoked once with the chosen index or nullopt.

Definition at line 46 of file Picker.cpp.

50{
51 if (labels.empty()) {
52 MF_WARN(Journal::Component::Portal, Journal::Context::API,
53 "Forma::pick: empty list");
54 if (callback) {
55 callback(std::nullopt);
56 }
57 return;
58 }
59
60 uint32_t row_px = k_min_row_px;
61 if (auto atlas = Text::TypeFaceFoundry::instance().get_default_glyph_atlas()) {
62 row_px = std::max(row_px, static_cast<uint32_t>(atlas->pixel_size()) + k_row_padding_px);
63 }
64
65 const auto rows = static_cast<uint32_t>(labels.size());
66 const uint32_t visible = std::min(rows, k_max_visible_rows);
67 const bool scrolling = rows > visible;
68 const uint32_t window_h = row_px * visible + (scrolling ? row_px / 2 : 0);
69
70 auto& atelier = internal::atelier();
71
72 auto window = atelier.create_window(Core::WindowCreateInfo {
73 .title = std::move(title),
74 .width = k_width_px,
75 .height = window_h,
76 .resizable = false,
77 });
78
79 auto state = std::make_shared<PickerState>();
80 state->callback = std::move(callback);
81 state->window = window;
82
83 Surface surface = atelier.create_surface(SurfaceConfig {
84 .window = window,
85 .name = window->get_create_info().title,
86 .on_close = [state] { state->finish(std::nullopt); },
87 });
88
89 const auto text_batch = atelier.create_buffer(
90 surface.render_config({ .additional_textures = { { "text", nullptr } } }));
91
92 std::optional<Scrollable> panel;
93 std::function<void(uint32_t, glm::vec2, double, double)> wheel;
94 if (scrolling) {
95 auto panel_buf = FormaTarget::slice_of(text_batch, Graphics::PrimitiveTopology::TRIANGLE_STRIP);
96 panel = make_scrollable(std::move(panel_buf), surface, surface.full(), glm::vec3(internal::row_idle_color()));
97 wheel = panel->wheel_handler(surface);
98 }
99
100 const auto row_dims = std::make_shared<glm::uvec2>(k_width_px, row_px);
101
102 const float row_h = 2.F * static_cast<float>(row_px) / static_cast<float>(window_h);
103 const float gap = 2.F / static_cast<float>(window_h);
104
105 for (uint32_t i = 0; i < rows; ++i) {
106 const float top = 1.F - row_h * static_cast<float>(i);
107 const Kinesis::AABB2D bounds {
108 .min = { -1.F, top - row_h + gap },
109 .max = { 1.F, top - gap },
110 };
111
112 auto made = internal::add_text_row(surface, labels.at(i), bounds, *row_dims, text_batch);
113 const uint32_t id = made.first;
114 const auto& row = made.second;
115
116 internal::hover_text_row(surface, id, row, labels.at(i), row_dims);
117 surface.ctx().on_press(id, IO::MouseButtons::Left, [state, i](uint32_t, glm::vec2) {
118 state->finish(i);
119 });
120
121 if (panel) {
122 surface.ctx().on_scroll(id, wheel);
123 panel->track(
124 surface.layer(), id, bounds,
125 [row](Kinesis::AABB2D shifted) { row->retarget(shifted); },
126 row->buffer);
127 }
128 }
129}
#define MF_WARN(comp, ctx,...)
uint32_t rows
PickCallback callback
Definition Picker.cpp:22
std::weak_ptr< Core::Window > window
Definition Picker.cpp:23
Surface create_surface(SurfaceConfig config)
Build a Surface from a SurfaceConfig, creating Layer and Context when config.layer/config....
Definition Atelier.cpp:160
std::shared_ptr< Core::Window > create_window(const Core::WindowCreateInfo &info)
Create a window through the stored WindowManager and show it.
Definition Atelier.cpp:104
std::shared_ptr< Buffers::FormaBuffer > create_buffer(Graphics::RenderConfig render)
The single buffer construction path.
Definition Atelier.cpp:117
Atelier & atelier()
Accessor for the process-wide Atelier.
Definition Atelier.hpp:304
Scrollable make_scrollable(FormaTarget buf, Surface &surface, Kinesis::AABB2D viewport, glm::vec3 background_color, float wheel_speed)
Construct a scrollable viewport.

References MayaFlux::Journal::API, MayaFlux::Portal::Forma::internal::atelier(), callback, MayaFlux::Portal::Forma::internal::Atelier::create_buffer(), MayaFlux::Portal::Forma::internal::Atelier::create_surface(), MayaFlux::Portal::Forma::internal::Atelier::create_window(), MayaFlux::Portal::Text::TypeFaceFoundry::instance(), MF_WARN, MayaFlux::Journal::Portal, MayaFlux::Portal::Forma::Surface::render_config(), rows, MayaFlux::Core::WindowCreateInfo::title, window, and MayaFlux::Portal::Forma::SurfaceConfig::window.

Referenced by MayaFlux::choose_camera(), and pick().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: