MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MayaFlux::Portal::Forma::TextField Struct Reference

An editable text region: keyboard/text-input wiring over an Element the caller already has a buffer for. More...

#include <TextField.hpp>

+ Collaboration diagram for MayaFlux::Portal::Forma::TextField:

Public Member Functions

Kinesis::AABB2D bounds () const noexcept
 Field region, satisfying Kinesis::HasBounds.
 
MAYAFLUX_API TextField & place (FormaTarget in_buf, Surface &surface, Kinesis::AABB2D bounds, std::shared_ptr< Portal::Text::PressParams > in_params, std::string initial_text={})
 Register the text field element and wire text editing onto it.
 
MAYAFLUX_API void reposition (Kinesis::AABB2D new_bounds)
 Move the field to a new NDC region, keeping its content.
 
MAYAFLUX_API TextField & scrollable (FormaTarget in_buf, Surface &surface, Scrollable &scroller, std::shared_ptr< Portal::Text::PressParams > in_params, std::string initial_text={}, float content_multiplier=3.F)
 Fluent creator: place this field inside an already-placed Scrollable, growing itself taller than its viewport and track()ing itself in, wired to scroll past a fixed clip.
 

Public Attributes

FormaTarget buf
 Target the text and caret draw into.
 
uint32_t element_id {}
 Element id of the text field. Valid after place().
 
Kinesis::AABB2D field_bounds {}
 NDC region occupied by the field. Valid after place().
 
std::shared_ptr< Portal::Text::PressParams > params
 Shared, mutable render params - every re-render reads this fresh, so a caller can change it once and have every subsequent keystroke see it.
 
std::shared_ptr< internal::TextSlice > slice
 The text and caret drawn into buf. Valid after place().
 
std::shared_ptr< MappedState< Portal::Text::EditableText > > state
 Live editable text and cursor. Valid after place().
 

Private Member Functions

void wire (Context &ctx)
 

Private Attributes

Element m_element
 
std::shared_ptr< Kinesis::AABB2D > m_live_bounds
 Same value as field_bounds, behind a shared_ptr so wire()'s already-captured Context closures see a reposition() that happens after they were registered - the same reason params is a shared_ptr instead of a captured-by-value copy.
 

Detailed Description

An editable text region: keyboard/text-input wiring over an Element the caller already has a buffer for.

Before place() is called, the struct carries no state. After place(), element_id, state, params, and field_bounds are populated. This mirrors the Scrollable/Collapsible pattern: place() takes a pre-built buffer (Portal::Forma::create_buffer at the call site) and does not itself depend on Forma.hpp - no file under Portal/Forma/ may, except Forma.cpp itself. Portal::Forma::create_text_field (in Forma.hpp) is the one-call convenience that builds the buffer and delegates here, the same split Portal::Forma::create<T> already has between itself and a Form<T>.

Editing state lives in a Portal::Text::EditableText, mutated through Portal::Text::move()/erase()/insert_codepoint()/insert_literal() - this struct only wires Context callbacks to those operations and re-renders. It does not manage focus visuals; wire on_focus_gained/on_focus_lost separately, same as any other Forma element.

Up/Down preserve the caret's horizontal position across lines. Clicking places the caret at the nearest text boundary. Both use the layout already drawn by the field's text run.

The text is drawn as glyph quads from the glyph atlas, and a caret rides in the same slice rather than owning a buffer, Element, or Layer entry of its own: it is one flat Kakshya::MeshVertex quad (Kinesis::textured_mesh_rect at weight 0, so forma_multi.frag draws the vertex colour with no texture read) appended after the glyphs. Every keystroke and every reposition() writes glyphs and caret together in one submit, since FormaBuffer::submit() has no partial-range write. Caret position comes from Portal::Text::TextRun::caret(), which shares the layout origin of the glyphs.

params is a shared, mutable Portal::Text::PressParams: every keystroke's re-render reads *params fresh, so a caller can change it once (e.g. a focus-driven background color) and have every subsequent keystroke see it, without re-wiring anything.

buf is exposed (same convention Scrollable/Collapsible use) so a field can be clipped or scrolled with no TextField-specific plumbing: pass it directly as Scrollable::track()'s clip_buf to get scissor-to-viewport clipping for free, and wire reposition() as the track() reposition callback to move the field on scroll:

surface.render_config({ .additional_textures = { { "text", nullptr } } }));
auto params = std::make_shared<Portal::Text::PressParams>(
Portal::Text::PressParams { .color = { 0.9F, 0.9F, 0.9F, 1.F }, .render_bounds = { 800, 64 } });
auto field = TextField {}.place(buf, surface, bounds, params, "hello");
// Living inside a Scrollable, composed by hand:
auto panel = Scrollable {}.place(viewport_buf, surface, viewport_bounds);
panel.track(surface.layer(), field.element_id, field.bounds(),
[field](Kinesis::AABB2D shifted) mutable { field.reposition(shifted); },
field.buf);
std::shared_ptr< Buffers::FormaBuffer > create_buffer(Graphics::RenderConfig render)
Construct and register a FormaBuffer without creating a Mapped<T>.
Definition Forma.cpp:103
std::shared_ptr< Portal::Text::PressParams > params
Shared, mutable render params - every re-render reads this fresh, so a caller can change it once and ...
Kinesis::AABB2D bounds() const noexcept
Field region, satisfying Kinesis::HasBounds.
FormaTarget buf
Target the text and caret draw into.
glm::vec4 color
RGBA color applied to all glyphs not covered by a span in spans.
Definition InkPress.hpp:70
Construction parameters for press().
Definition InkPress.hpp:65

scrollable() is the fluent equivalent of that same composition, for the common single-field case - but the Scrollable itself is entirely the caller's: build and configure it however (place(), indicator(), background_color(), wheel_speed() - all fluent) before calling scrollable(), which only needs a buffer for itself, that already-placed Scrollable to track into, and how tall to grow relative to its viewport. Everything Scrollable already owns (the viewport buffer, its bounds, any indicator) stays there - this struct has no reason to know about it a second time. Portal::Forma::create_text_field(..., scrollable=true) in Forma.hpp is nothing more than a call to this.

Definition at line 88 of file TextField.hpp.


The documentation for this struct was generated from the following files: