MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Collapsible.cpp
Go to the documentation of this file.
1#include "Collapsible.hpp"
2
4
6
8
9namespace {
10
11 [[nodiscard]] GeometryFn<bool> collapsible_header_geom(
12 float y_top,
13 float x_min,
14 float x_max,
15 float row_h,
16 glm::vec3 color_closed,
17 glm::vec3 color_open,
18 bool has_label)
19 {
20 return [y_top, x_min, x_max, row_h, color_closed, color_open, has_label](
21 bool open, std::vector<uint8_t>& out, Element& el) {
22 const float bot = y_top - row_h;
23 const glm::vec3 col = open ? color_open : color_closed;
24
25 const size_t stride = Kakshya::VertexLayout::for_meshes().stride_bytes;
26 const size_t vertex_count = has_label ? 12 : 6;
27
28 out.assign(vertex_count * stride, 0);
29
30 const glm::vec3 bl { x_min, bot, 0.F };
31 const glm::vec3 br { x_max, bot, 0.F };
32 const glm::vec3 tl { x_min, y_top, 0.F };
33 const glm::vec3 tr { x_max, y_top, 0.F };
34 constexpr glm::vec3 white { 1.F, 1.F, 1.F };
35
36 auto write = [&](size_t idx, glm::vec3 pos, glm::vec3 c, float w, glm::vec2 uv) {
37 auto* v = out.data() + idx * stride;
38 std::memcpy(v, &pos, 12);
39 std::memcpy(v + 12, &c, 12);
40 std::memcpy(v + 24, &w, 4);
41 std::memcpy(v + 28, &uv, 8);
42 };
43
44 write(0, bl, col, 0.F, {});
45 write(1, br, col, 0.F, {});
46 write(2, tl, col, 0.F, {});
47 write(3, br, col, 0.F, {});
48 write(4, tr, col, 0.F, {});
49 write(5, tl, col, 0.F, {});
50
51 if (has_label) {
52 write(6, bl, white, 1.F, { 0.F, 1.F });
53 write(7, br, white, 1.F, { 1.F, 1.F });
54 write(8, tl, white, 1.F, { 0.F, 0.F });
55 write(9, br, white, 1.F, { 1.F, 1.F });
56 write(10, tr, white, 1.F, { 1.F, 0.F });
57 write(11, tl, white, 1.F, { 0.F, 0.F });
58 }
59
60 el.bounds_hint = Kinesis::AABB2D {
61 .min = { x_min, bot },
62 .max = { x_max, y_top },
63 };
64 };
65 }
66
67} // namespace
68
69// =============================================================================
70// Collapsible
71// =============================================================================
72
74 std::shared_ptr<Buffers::FormaBuffer> in_buf,
75 Surface& surface,
76 LayoutCursor& cursor,
77 float x_min, float x_max, float row_h)
78{
79 buf = std::move(in_buf);
80
81 const float y_top = cursor.y();
82 cursor.advance(row_h);
83
84 auto open_state = std::make_shared<MappedState<bool>>();
85 open_state->write(m_initially_open);
86
87 Mapped<bool> mapped;
88 mapped.state = open_state;
89 mapped.geometry_fn = collapsible_header_geom(
90 y_top, x_min, x_max, row_h, m_color_closed, m_color_open, m_label != nullptr);
91 mapped.element.buffer = buf;
93 .min = { x_min, cursor.y() },
94 .max = { x_max, y_top },
95 };
96
97 const uint32_t hid = surface.layer().add(mapped.element);
98 mapped.element.id = hid;
99 open_state->id = hid;
100 mapped.sync();
101
102 surface.ctx().on_press(hid, IO::MouseButtons::Left,
103 [m = std::move(mapped), open = open_state, surface, hid](uint32_t, glm::vec2) mutable {
104 const bool next = !open->value;
105 open->write(next);
106 for (auto rel_id : surface.layer().related_ids(hid))
107 surface.layer().set_visible(rel_id, next);
108 m.sync();
109 });
110
111 header_id = hid;
112 open = open_state;
113 cursor_out = cursor;
114 return *this;
115}
116
117void Collapsible::attach(Layer& layer, uint32_t body_id) const
118{
119 layer.relate(header_id, body_id);
120 layer.set_visible(body_id, open->value);
121}
122
123// =============================================================================
124// Free function escape hatch
125// =============================================================================
126
128 std::shared_ptr<Buffers::FormaBuffer> buf,
129 Surface& surface,
130 LayoutCursor& cursor,
131 float x_min,
132 float x_max,
133 float row_h,
134 bool initially_open,
135 glm::vec3 color_closed,
136 glm::vec3 color_open)
137{
138 return Collapsible {}
139 .initially_open(initially_open)
140 .closed_color(color_closed)
141 .open_color(color_open)
142 .place(std::move(buf), surface, cursor, x_min, x_max, row_h);
143}
144
145} // namespace MayaFlux::Portal::Forma
void on_press(uint32_t id, IO::MouseButtons btn, PressFn fn)
Called when a mouse button is pressed over an element.
Definition Context.cpp:33
bool set_visible(uint32_t id, bool visible)
Definition Layer.cpp:63
bool relate(uint32_t primary_id, uint32_t related_id)
Record that related_id belongs with primary_id.
Definition Layer.cpp:152
std::vector< uint32_t > related_ids(uint32_t primary_id) const
Return the ids related to primary_id, or empty if none.
Definition Layer.cpp:185
Slot add(Element element)
Add an element to the layer.
Definition Layer.cpp:9
Flat registry of Elements on a surface.
Definition Layer.hpp:21
Kinesis::AABB2D advance(float height)
Advance the cursor downward by height and return the NDC AABB occupied by the primitive just placed.
Reactive Y-position accumulator for vertical primitive stacking.
Context & ctx() noexcept
Access the event router.
Definition Surface.hpp:118
Layer & layer() noexcept
Access the spatial registry.
Definition Surface.hpp:107
Named owner of a (Window, Layer, Context) triple - the Forma canvas.
Definition Surface.hpp:58
Collapsible make_collapsible(std::shared_ptr< Buffers::FormaBuffer > 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)
uint32_t stride_bytes
Total bytes per vertex (stride in Vulkan terms) e.g., 3 floats (position) + 3 floats (normal) = 24 by...
static VertexLayout for_meshes(uint32_t stride=60)
Factory: layout for MeshVertex (position, color, weight, uv, normal, tangent)
Axis-aligned bounding rectangle in a 2D coordinate space.
Definition Bounds.hpp:21
std::shared_ptr< MappedState< bool > > open
Open/closed state. Valid after place(). Write to toggle.
std::shared_ptr< Buffers::FormaBuffer > buf
FormaBuffer backing the header geometry. Valid after place().
uint32_t header_id
Element id of the header strip. Valid after place().
Collapsible & closed_color(glm::vec3 c)
glm::vec3 m_color_closed
Background color when closed. Default: glm::vec3(0.25F).
std::shared_ptr< Core::VKImage > m_label
Optional GPU image overlaid as a text label. nullptr = color only.
Collapsible & open_color(glm::vec3 c)
MAYAFLUX_API Collapsible & place(std::shared_ptr< Buffers::FormaBuffer > buf, Surface &surface, LayoutCursor &cursor, float x_min, float x_max, float row_h)
Register the header element and wire the toggle callback.
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).
LayoutCursor cursor_out
Cursor positioned below the header, ready for body elements. Valid after place().
A collapsible header strip.
std::shared_ptr< Buffers::FormaBuffer > buffer
Buffer whose rendered output occupies this region.
Definition Element.hpp:72
uint32_t id
Stable id assigned by Layer::add. Never zero.
Definition Element.hpp:60
std::optional< Kinesis::AABB2D > bounds_hint
Optional fast-reject bounds in NDC space.
Definition Element.hpp:64
std::shared_ptr< MappedState< T > > state
Shared value carrier. External systems hold a copy of this ptr.
Definition Mapped.hpp:91
void sync()
Call once per graphics tick.
Definition Mapped.hpp:119
GeometryFn< T > geometry_fn
Geometry regeneration function. Set once at construction.
Definition Mapped.hpp:94
Element element
The Element registered with the Layer.
Definition Mapped.hpp:98
Infrastructure for a continuously-mapped value whose GPU geometry tracks it.
Definition Mapped.hpp:89