MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Collapsible.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "LayoutCursor.hpp"
5
6namespace MayaFlux::Core {
7class Window;
8}
9
10namespace MayaFlux::Buffers {
11class FormaBuffer;
12}
13
15
16class Layer;
17class Context;
18class Surface;
19
20/**
21 * @struct Collapsible
22 * @brief A collapsible header strip.
23 *
24 * Before place() is called, the struct carries only configuration.
25 * After place(), header_id, open, buf, and cursor_out are populated.
26 * This mirrors the Element pattern: configure with setters, register
27 * with a single explicit call.
28 *
29 * @code
30 * auto col = Collapsible{}
31 * .initially_open(false)
32 * .closed_color({ 0.2F, 0.2F, 0.2F })
33 * .label("Oscillator")
34 * .place(window, layer, ctx, cursor, x_min, x_max, row_h);
35 *
36 * col.attach(layer, body_id);
37 * @endcode
38 */
40 // =========================================================================
41 // Results - populated by place()
42 // =========================================================================
43
44 /// @brief Element id of the header strip. Valid after place().
45 uint32_t header_id {};
46
47 /// @brief Open/closed state. Valid after place(). Write to toggle.
48 std::shared_ptr<MappedState<bool>> open;
49
50 /// @brief FormaBuffer backing the header geometry. Valid after place().
52
53 /// @brief Cursor positioned below the header, ready for body elements. Valid after place().
55
56 /// @brief NDC region occupied by the header strip. Valid after place().
58
59 /// @brief Header strip region, satisfying Kinesis::HasBounds.
60 [[nodiscard]] Kinesis::AABB2D bounds() const noexcept { return header_bounds; }
61
62 // =========================================================================
63 // Configuration - set before place()
64 // =========================================================================
65
66 /// @brief Starting toggle state. Default: true (open).
67 bool m_initially_open { true };
68
69 /// @brief Background color when closed. Default: glm::vec3(0.25F).
70 glm::vec3 m_color_closed { 0.25F };
71
72 /// @brief Background color when open. Default: glm::vec3(0.35F).
73 glm::vec3 m_color_open { 0.35F };
74
75 /// @brief Text label drawn over the header. Empty = color only.
76 std::string m_label_text;
77
78 /// @brief Label text color. Default opaque white.
79 glm::vec4 m_label_color { 1.F, 1.F, 1.F, 1.F };
80
81 // =========================================================================
82 // Configuration setters
83 // =========================================================================
84
86 {
88 return *this;
89 }
90
92 {
94 return *this;
95 }
96
97 Collapsible& open_color(glm::vec3 c)
98 {
99 m_color_open = c;
100 return *this;
101 }
102
103 /**
104 * @brief Draw a text label over the header, background included.
105 *
106 * When set, place() draws @p text with the current open/closed color
107 * as Portal::Text::PressParams::background, and every toggle draws it
108 * again with the new color - background and label are one slice, so
109 * they can never drift out of sync the way two independent draws could.
110 * When empty
111 * (default), the header stays a plain color-only quad with no text
112 * machinery at all.
113 *
114 * @p buf passed to place() still needs the "text" additional_textures
115 * slot when a label is set, same as Element::with_text.
116 */
117 Collapsible& label(std::string text)
118 {
119 m_label_text = std::move(text);
120 return *this;
121 }
122
123 /// @brief Label text color. Only meaningful when label() is non-empty.
125 {
126 m_label_color = c;
127 return *this;
128 }
129
130 // =========================================================================
131 // Placement
132 // =========================================================================
133
134 /**
135 * @brief Register the header element and wire the toggle callback.
136 *
137 * Advances @p cursor by @p row_h. Populates header_id, open, buf,
138 * and cursor_out on this struct.
139 *
140 * @param buf Pre-created FormaBuffer sized for this header.
141 * @param surface Surface to register the header on.
142 * @param cursor Layout cursor. Advanced by row_h on return.
143 * @param x_min Left edge in NDC.
144 * @param x_max Right edge in NDC.
145 * @param row_h Header strip height in NDC units.
146 * @return *this, with results populated.
147 */
148 MAYAFLUX_API Collapsible& place(
150 Surface& surface,
151 LayoutCursor& cursor,
152 float x_min, float x_max, float row_h);
153
154 /**
155 * @brief Register the header element using the cursor's column extents.
156 *
157 * Equivalent to the explicit-extent overload with x_min and x_max taken
158 * from @p cursor. Use with a column-scoped LayoutCursor so the header
159 * spans exactly the column the cursor advances within.
160 *
161 * @param buf Pre-created FormaBuffer sized for this header.
162 * @param surface Surface to register the header on.
163 * @param cursor Layout cursor. Supplies column extents and is advanced
164 * by @p row_h on return.
165 * @param row_h Header strip height in NDC units.
166 * @return *this, with results populated.
167 */
168 MAYAFLUX_API Collapsible& place(
170 Surface& surface,
171 LayoutCursor& cursor,
172 float row_h);
173
174 // =========================================================================
175 // Post-placement helpers
176 // =========================================================================
177
178 /**
179 * @brief Relate a body element to this collapsible and sync its visibility
180 * to the current open state.
181 *
182 * This is the only bookkeeping Collapsible does for an attached body -
183 * everything else lives in Layer::m_relations, keyed by header_id. That
184 * means Portal::Forma::destroy(surface, header_id) tears down every
185 * attached body for free, with no Collapsible-specific teardown code.
186 *
187 * @param layer Layer the body element lives on.
188 * @param body_id Element id returned from layer.add(...).
189 */
190 MAYAFLUX_API void attach(Layer& layer, uint32_t body_id) const;
191};
192
193// =============================================================================
194// Free function escape hatch
195// =============================================================================
196
197/**
198 * @brief Construct a collapsible header strip.
199 *
200 * Thin wrapper delegating to Collapsible::place(). Preserved as an escape
201 * hatch; existing callsites require no changes. The @p bridge parameter is
202 * accepted but ignored - Forma::bridge() is called internally.
203 */
204[[nodiscard]] MAYAFLUX_API Collapsible make_collapsible(
205 FormaTarget buf,
206 Surface& surface,
207 LayoutCursor& cursor,
208 float x_min,
209 float x_max,
210 float row_h,
211 bool initially_open = true,
212 glm::vec3 color_closed = glm::vec3(0.25F),
213 glm::vec3 color_open = glm::vec3(0.35F),
214 std::string label = {});
215
216} // namespace MayaFlux::Portal::Forma
uint32_t label
Definition Contours.cpp:16
Where an element's geometry and texture are written.
Definition Target.hpp:22
Flat registry of Elements on a surface.
Definition Layer.hpp:24
Reactive Y-position accumulator for vertical primitive stacking.
Named owner of a (Window, Layer, Context) triple: the Forma canvas.
Definition Surface.hpp:121
Context
Execution contexts for log messages.
Collapsible make_collapsible(FormaTarget buf, Surface &surface, LayoutCursor &cursor, float x_min, float x_max, float row_h, bool initially_open, glm::vec3 color_closed, glm::vec3 color_open, std::string label)
Construct a collapsible header strip.
Axis-aligned bounding rectangle in a 2D coordinate space.
Definition Bounds.hpp:63
glm::vec4 m_label_color
Label text color. Default opaque white.
Kinesis::AABB2D header_bounds
NDC region occupied by the header strip. Valid after place().
std::shared_ptr< MappedState< bool > > open
Open/closed state. Valid after place(). Write to toggle.
MAYAFLUX_API Collapsible & place(FormaTarget buf, Surface &surface, LayoutCursor &cursor, float x_min, float x_max, float row_h)
Register the header element and wire the toggle callback.
uint32_t header_id
Element id of the header strip. Valid after place().
Collapsible & closed_color(glm::vec3 c)
std::string m_label_text
Text label drawn over the header. Empty = color only.
glm::vec3 m_color_closed
Background color when closed. Default: glm::vec3(0.25F).
Collapsible & open_color(glm::vec3 c)
FormaTarget buf
FormaBuffer backing the header geometry. Valid after place().
Collapsible & label(std::string text)
Draw a text label over the header, background included.
Collapsible & label_color(glm::vec4 c)
Label text color. Only meaningful when label() is non-empty.
Collapsible & initially_open(bool v)
glm::vec3 m_color_open
Background color when open. Default: glm::vec3(0.35F).
MAYAFLUX_API void attach(Layer &layer, uint32_t body_id) const
Relate a body element to this collapsible and sync its visibility to the current open state.
bool m_initially_open
Starting toggle state. Default: true (open).
Kinesis::AABB2D bounds() const noexcept
Header strip region, satisfying Kinesis::HasBounds.
LayoutCursor cursor_out
Cursor positioned below the header, ready for body elements. Valid after place().
A collapsible header strip.