Class HudElementTreeOrderGui
The Unity-side adapter over HudElementTreeOrder: projects a HUD's serialized element list into the pure solver's input, and carries out the sibling-aware move, remove and duplicate operations the nested list's row actions need.
Inherited Members
Namespace: Serenity.GameUi.Infrastructure.Editor.Builder
Assembly: Serenity.UnityGameUi.Infrastructure.Editor.dll
Syntax
public static class HudElementTreeOrderGui
Remarks
Every method here reads and writes UnityEditor.SerializedProperty only, never the deserialized
UnityHudDefinition target object. CreateHudWindow applies its scratch instance's
modified properties once, at the end of OnGUI — reading the target object mid-frame would see last
frame's data and index straight past the end of an array a row action just grew or shrank this frame.
Methods
DescendantsOf(IReadOnlyList<Row>, int)
Every descendant of the element at elementIndex, in tree display order — usable
past HudDefinitionScanner.MaxChainWalkDepth, since
ParentElementIndex never clamps.
Declaration
public static List<int> DescendantsOf(IReadOnlyList<HudElementTreeOrder.Row> rows, int elementIndex)
Parameters
| Type | Name | Description |
|---|---|---|
| IReadOnlyList<HudElementTreeOrder.Row> | rows | Rows from SolveFrom(SerializedProperty). |
| int | elementIndex | The element whose descendants to collect. |
Returns
| Type | Description |
|---|---|
| List<int> | Every descendant's array index, in display order. |
Remarks
Walks the actual parent edges rather than comparing Depth, which is clamped for readable indentation, so a box nested past the cap and its own children can end up reporting the SAME depth number — a depth-only comparison would then read the children as siblings instead, silently orphaning them from remove/duplicate/filter. SolveFrom(SerializedProperty) still guarantees depth-first order (a node's whole subtree is a contiguous run right after it), so this only needs to track which element indices are "inside" as it scans forward, not compare numbers.
DuplicateSubtree(SerializedProperty, int, Func<string, string>)
Duplicates an element. A childless one is copied on its own, exactly as before; one holding children duplicates the whole subtree, so a copied box arrives with its own copied contents rather than an empty shell.
Declaration
public static int DuplicateSubtree(SerializedProperty elements, int index, Func<string, string> makeUniqueId)
Parameters
| Type | Name | Description |
|---|---|---|
| SerializedProperty | elements | The serialized element list. |
| int | index | Position of the element to duplicate. |
| Func<string, string> | makeUniqueId | Given a candidate id, returns one not already used in |
Returns
| Type | Description |
|---|---|
| int | The array index the duplicated root element ends up at. |
Remarks
A duplicated subtree's copies intentionally still reference whatever layer assets, feedback definitions and other shared assets the originals did — the same divergence warning an ordinary single-element duplicate already risks applies here too, once for every copied member.
Acknowledged tradeoff: Serenity.GameUi.Infrastructure.Editor.Builder.HudElementTreeOrderGui.ParkDuplicate(UnityEditor.SerializedProperty,System.Int32)'s insert-then-move-to-end shuffles which
trailing rows' isExpanded foldout state (Unity's own, keyed by array position rather
than element identity) survives a park operation, since isExpanded is not carried explicitly
through the move. In practice this only ever touches already-collapsed rows past the array's tail —
nothing a duplicate operation itself expands — so it is not worth the extra bookkeeping to preserve.
MoveWithinSiblings(SerializedProperty, in Row, bool)
Swaps a row with its previous or next sibling — never with a row of another parent, which is what makes the move buttons behave sensibly under nesting instead of hopping across box boundaries.
Declaration
public static int MoveWithinSiblings(SerializedProperty elements, in HudElementTreeOrder.Row row, bool up)
Parameters
| Type | Name | Description |
|---|---|---|
| SerializedProperty | elements | The serialized element list. |
| HudElementTreeOrder.Row | row | The row to move; its sibling indices come from SolveFrom(SerializedProperty). |
| bool | up | Whether to swap with the previous sibling (true) or the next one (false). |
Returns
| Type | Description |
|---|---|
| int | The element's array index after the move — unchanged when there was no such sibling. |
RemoveWithChildrenChoice(SerializedProperty, int)
Removes an element. A childless one is simply deleted; one holding children asks whether to move them to the root or take the whole subtree with it.
Declaration
public static bool RemoveWithChildrenChoice(SerializedProperty elements, int index)
Parameters
| Type | Name | Description |
|---|---|---|
| SerializedProperty | elements | The serialized element list. |
| int | index | Position of the element to remove. |
Returns
| Type | Description |
|---|---|
| bool | Whether anything was actually removed — false when the author cancelled the dialog. |
SolveFrom(SerializedProperty)
Projects the serialized element list into HudElementTreeOrder.Nodes and solves the display order.
Declaration
public static IReadOnlyList<HudElementTreeOrder.Row> SolveFrom(SerializedProperty elements)
Parameters
| Type | Name | Description |
|---|---|---|
| SerializedProperty | elements | The serialized list of |
Returns
| Type | Description |
|---|---|
| IReadOnlyList<HudElementTreeOrder.Row> | One row per element, in display order; empty when |