Expand description
The generic, schema-driven egui form engine — ONE per-field renderer for BOTH the display-settings dialog AND the schema-driven feature dialogs (the user’s principle: the structure of a thing drives the UI; you don’t rewrite UI code per field, and you don’t write two dialog engines).
field_input emits ONLY the input widget(s) for one FormField — no
leading label, no forced row layout — so the CALLER owns the placement. Both
side trees drive it DIRECTLY: the history feature tree (panels::history) and
the settings tree (panels::settings) each render a field as a tree LEAF
whose node label is the field label and whose right-aligned content is this
input. The widget per FieldKind:
Color→color_edit_button_srgbBool→ checkboxEnum→ combo boxNumber/Range→ slider (bounded settings)Scalar→ an EXPRESSION-CAPABLE single-line field (unbounded feature numbers): the user types a plain number OR a variable name / inline equation (width * 2) that the kernel evaluates against the history’sexpressionssheet; while focused, the mouse wheel steps a pure number.Text→ single-line edit (disabled for a read-onlyid)Vec3→ three drag values (transform position/rotation/scale)Button→ an action button; a click is surfaced to the caller by the field key (via theclickedout-param) — e.g.editSketchopens the engine-native sketcher.Reference→ a full-width activation button with the current selection listed BENEATH it, one line per entity, each with an✕to remove it. The✕is pinned to the line’s RIGHT edge and the name truncates into what is left (hover for the whole one) — an entity name is as long as the modelling history made it, and a line laid out name-first would push its own remove button off the panel. Pressing the button is surfaced to the caller by the field key (the sameclickedout-param aButtonuses) — entering the picker needs the engine, and this file deliberately has none. HOVERING a line reports the entity NAME on it the same way (FieldActions::hovered_entity), so the caller can light that entity in the 3D scene.
§Width, and who decides it
An input fills the width it is given in a TOP-DOWN layout (the label-above
form view: crate::form_view) and stays COMPACT in a RIGHT-TO-LEFT row
(the tree/settings idiom, where the label is the tree node and the input sits
at the panel edge). ui.layout().prefer_right_to_left() is the one
discriminator — the same one Vec3 has always used to order its components —
so neither caller passes a layout flag and neither can drift from the other.
A field binds to a path (a chain of JSON object keys), so it can read/write
a NESTED value (["transform","position"], ["boolean","operation"]), not
just a top-level key. On any change it writes back into current (the JSON
document being edited — settings JSON, or a feature’s inputParams) and
returns true; the caller re-applies / re-runs. There is deliberately NO
per-field code, so this file is reusable verbatim by a later brep-ui crate.
Structs§
- Field
Actions - What the user did to a field that only the CALLER can act on — both of these need an engine (entering the reference picker; lighting an entity in the 3D scene), and this file deliberately has none.
Functions§
- field_
input - Emit ONLY the input widget(s) for one field — NO leading label, NO forced row
layout (the caller supplies both: the form view puts the label ABOVE and gives
the input the full width; the settings tree puts the label in the tree node
and this input in the row’s right-aligned content). Writes any change back
into
currentat the field’spath, returns(changed, interactive_widget_rect).