Editor API

The custom editor module (The IC Control Panel, Presets, Level-wide export / import). Scoped from Source/MovaInteractEditor/Public.

Control panel

struct FMovaIxActorGridInfo
#include <MovaIxControlPanel.h>

One row of the multi-selection Actor grid.

Public Members

TWeakObjectPtr<AActor> Actor

Weak reference to the tracked Actor.

bool bHasIC = false

True if the Target Actor has at least one Interactive Component.

int32 TagCount = 0

Number of interaction Tags on the Actor's primary Interactive Component.

struct FMovaIxComponentTreeInfo
#include <MovaIxControlPanel.h>

One node of the hierarchy tree: an Actor, a Component, or a bone.

Public Functions

inline FMovaIxComponentTreeInfo(UActorComponent *InComp)

Node initializer for a plain Component.

FMovaIxComponentTreeInfo(AActor *InActor)

Node initializer for the owning Actor (the clickable Root above the Components). Defined in the .cpp (needs the full AActor type).

inline FMovaIxComponentTreeInfo(USceneComponent *InMesh, FName InBone)

Node initializer for a bone of a skeletal / poseable mesh (targetable as "@Mesh/Bone").

inline bool IsBoneNode() const

True when this node represents a bone, not a Component or the Actor.

DECLARE_DELEGATE_RetVal_OneParam(bool, FCommitRenameForTesting, const FString&)

Commits a name into this row's editable label, for tests.

inline bool IsActorNode() const

True when this node represents the owning Actor itself, not one of its Components.

Public Members

FSimpleDelegate RenameRequestEvent

Fired when F2 asks this row to start editing its name.

FCommitRenameForTesting CommitRenameForTestingEvent
bool bActionTarget = false

Is the Component a Target of one of the ActionGroups?

FName BoneName = NAME_None

Bone this node represents (None for Actor / Component nodes).

TWeakObjectPtr<AActor> Actor

Owning Actor when this is the Root Actor node (empty for Component nodes).

TArray<TSharedPtr<FMovaIxComponentTreeInfo>> Children

Child nodes under this one in the tree.

TWeakObjectPtr<UActorComponent> Component

Weak reference to the Component this node represents.

TWeakObjectPtr<USceneComponent> ParentMesh

Skeletal / poseable mesh a bone node hangs under (empty for non-bone nodes).

FText DisplayName

Row label text.

class SMovaIxControlPanel : public SCompoundWidget
#include <MovaIxControlPanel.h>

Custom Slate panel to:

  • Manage multi-selected interactive Components.

  • Edit tags.

  • Manipulate timelines.

  • Edit whitelisted details arrays.

Public Functions

inline SLATE_BEGIN_ARGS(SMovaIxControlPanel)
virtual ~SMovaIxControlPanel() override

Blueprint mode: edit this Blueprint's IC template instead of the level selection. Hosting Blueprint editor: lets Blueprint-mode viewport clicks be followed. Optional, Level mode leaves it unset.

virtual FReply OnKeyDown(const FGeometry &MyGeometry, const FKeyEvent &InKeyEvent) override
virtual FReply OnKeyUp(const FGeometry &MyGeometry, const FKeyEvent &InKeyEvent) override
inline virtual bool SupportsKeyboardFocus() const override
void Construct(const FArguments &InArgs)

Initializes the control panel.

  • Builds the widget layout.

  • Hooks up selection listener delegates.

void CaptureManualRecordSample()

Captures one manual pose sample while recording.

inline bool IsRecording() const

True while the Interactive Object Recorder is actively sampling.

FReply OnRecordClicked()

Toggles the Interactive Object Recorder.

  • Start snapshots every scene Component's relative transform.

  • Start also auto-samples on a timer when UMovaIxSettings::bAutoKeyWhileRecording is on, off by default.

  • Stop generates States + an Action per moved Component into a new "Recorded" Group, restores poses.

bool CommitRenameForTesting(const FString &NewName)

Commits NewName into the row currently being renamed.

Returns:

False when no row is in editing mode.

inline void CopyActionsToClipboardForTesting()

Calls CopyActionsToClipboard(): the real right-click "Copy Actions" handler.

bool FlushDetailsRebuildForTesting()

Forces a pending details rebuild at once, closing the epoch, false when none was pending.

void FlushTreeSyncForTesting()

Forces a pending hierarchy highlight now instead of on the next tick.

bool GenerateSelectedRowForTesting()

Builds the selected row's widget, which a paint normally does.

TArray<FString> GetSelectedHierarchyRowNames() const

Names of the hierarchy rows currently highlighted, empty when none are.

inline bool IsPlayingForTesting() const

True while the sequencer playback loop is currently evaluating.

inline bool IsTestOneShotForTesting() const

True while a playback run in progress will stop at the end instead of looping, ex: TestGroup's preview.

inline void PlayPauseForTesting()

Calls OnPlayPauseClicked(): toggles bPlaying, always clears one-shot.

bool RequestRenameSelectedRowForTesting()

Fires the selected row's rename request, as F2 does.

void TestGroupForTesting(FName GroupName)

Calls TestGroup(GroupName): selects its Targets and starts one-shot playback, without the widget click.

void TickTimelinePlaybackForTesting(float DeltaTime)

Calls one TickTimelinePlayback step of DeltaTime seconds, without a live active-timer window.

Public Static Functions

static void GatherScrubGroupKeys(const UMovaIxComponent *IC, const FName &GroupName, TArray<FName> &OutKeys)

Runtime Group keys to scrub, one per template Group, not both a template and its clones.

Parameters:
  • IC -- Component whose ActionGroupsEx is being scrubbed.

  • GroupName -- Template Group to play, None for every Group.

  • OutKeys -- Out: runtime keys to drive, one entry per template Group.

static TArray<FName> GetScrubGroupKeysForTesting(const UMovaIxComponent *IC, FName GroupName)

Runtime ActionGroupsEx keys a scrub drives for GroupName, None meaning every Group.

Private Functions

void CleanOrphanedStates(UMovaIxComponent *PrimaryIC)
void RebuildActionSourceData()

Populate or refresh the options source pool backing the Action combo box, all Groups if None.

void RebuildGroupSourceData()

Populate or refresh the options source pool backing the ActionGroup combo box.

void AppendCommonHierarchyMenuEntries(FMenuBuilder &MenuBuilder, FSimpleDelegate CopyHierarchyAction, FText CopyHierarchyTip, UBlueprint *OwnerBP)

Appends the entries every hierarchy-related context menu shares: Copy Hierarchy, Copy Actions, Edit in Blueprint.

Parameters:
  • CopyHierarchyAction -- "Copy Hierarchy": row vs whole Actor.

  • CopyHierarchyTip -- Tooltip matching CopyHierarchyAction's actual scope.

  • OwnerBP -- Owning Actor, or nullptr to skip Edit in Blueprint.

TSharedRef<SWidget> BuildAddICCard(const FName &IconBrush, const TAttribute<FText> &Title, const TAttribute<FText> &ScopeBadge, const TAttribute<FText> &Description, bool bPrimary, FOnClicked OnClicked, const TAttribute<EVisibility> &CardVisibility)

Builds one card of the "no Interactive Component yet" empty State.

TSharedRef<SWidget> BuildGearMenu()

Popup menu behind the gear button: Show Presets / Show Timeline toggles, Settings entry.

TSharedPtr<SWidget> BuildHierarchyContextMenu()

Right-click menu for a hierarchy row: Copy Hierarchy, Edit in Blueprint.

TSharedPtr<SWidget> BuildHierarchyHeaderMenu()

Right-click menu for the tree header: Copy Hierarchy, Edit in Blueprint, for the whole Actor.

void CopyActionsToClipboard()

Copies the selected IC's non-default ActionCycles/Groups/States to the clipboard in a YAML-like format.

void CopyHierarchyToClipboard(const TSharedPtr<FMovaIxComponentTreeInfo> &Root)

Copies the node and its descendants to the clipboard as an indented "Name: Tags" tree.

void CopyOwnerHierarchyToClipboard()

Copies the whole owning Actor to the clipboard, name header + every Component subtree.

int32 CountBlueprintInstances() const

Counts Actors in the editor worlds sharing the selected Actor's generated class.

int32 CountMultiSelectMissingIC() const

How many Actors in the current multi-selection have no Interactive Component yet.

int32 DeleteAllComponentTags(AActor *OwnerActor)

Clears the interaction tags from every Component of the owning Actor, then refreshes.

Returns:

Number of tags removed, across all Components.

void DeleteHierarchyComponent(UActorComponent *Component)

Removes a Component selected in the panel hierarchy, ex: the Delete key.

  • Routes the Interactive Component, a Blueprint SCS node, and a plain instance Component each to their own path.

void DeleteInteractiveComponent(UMovaIxComponent *InteractiveComponent)

Removes an Interactive Component from its Actor, right-click Delete on the IC node, then refreshes.

bool DeleteInteractiveComponentFromBlueprint(AActor *Owner)

Removes the IC's SCS node from the owning Blueprint, then recompiles.

See also

DeleteInteractiveComponent

Parameters:

Owner -- Actor whose Blueprint owns the node.

Returns:

True when a node was removed, false to fall back to the plain instance destroy.

void ExpandTreeNodesRecursive(const TSharedPtr<FMovaIxComponentTreeInfo> &Node)

Recursively expands tree nodes from absolute Roots downwards.

USceneComponent *FindRecordedComponent(const FName &CompName) const

Resolves a recorded Component by name on the Actor currently being recorded.

Returns:

Live Component, or nullptr if the Actor or the named Component is gone.

TSharedPtr<FMovaIxComponentTreeInfo> FindTreeNode(const UActorComponent *Comp) const

Deep-searches the active hierarchy tree to locate the wrapper info node for a specific Component.

int32 GetAddICLayoutIndex() const

Layout index for AddICLayoutSwitcher, 0 stacked or 1 side by side.

EVisibility GetAddICToBlueprintVisibility() const

Visible only when the selected Actor is a Blueprint Actor. Drives the "Add to Blueprint" button.

FText GetAddInteractiveComponentMultiLabelText() const

"Make N Actors interactive" label text, N = CountMultiSelectMissingIC().

EVisibility GetAddInteractiveComponentMultiVisibility() const

Visible only while multi-selected and at least one selected Actor still lacks an IC.

EVisibility GetAddInteractiveComponentVisibility() const

Visible only when an Actor is selected that has no Interactive Component yet. Drives the Add button.

FText GetBlueprintCardDescriptionText() const

Description of the Blueprint card, names the Blueprint and makes the destination explicit.

FText GetBlueprintCardTitleText() const

Title of the Blueprint card, naming the Blueprint that receives the Component.

FText GetBlueprintScopeText() const

Badge on the Blueprint card, counting instances in the open levels.

FVector2D GetEmptyStateAvailableSize() const

Space the empty-State block truly has, read from EmptyStateArea's arranged geometry. Zero on the first frame.

FText GetEmptyStateTitleText() const

Heading of the empty State, naming the selected Actor.

float GetEmptyStateWrapWidth() const

Pixel width the empty-State heading and subtitle wrap at, capped at EmptyStateMaxWidth.

EVisibility GetHierarchyTreeVisibility() const

Visibility of the hierarchy tree and of the overlay slot holding it, collapsed while multi selecting.

FText GetInstanceScopeText() const

Badge on the instance card, always a single Actor.

int32 GetSequencerSplitSizingRuleValue() const

SizingRule for the top Hierarchy / Add-IC SSplitter::Slot, as SSplitter::ESizeRule's underlying int.

EVisibility GetTimelineSectionVisibility() const

Visible only when an Interactive Component is current. Drives the combos/transport/timeline block.

bool IsEmptyStateCramped() const

True when the empty-State block is too narrow to afford the cards' descriptions.

bool IsTreeSelected(const UActorComponent *Comp) const

Checks whether the tree wrapper node corresponding to the given Component is currently highlighted.

FReply OnAddInteractiveComponentClicked()

Adds the Interactive Component, from Settings, to the selected Actor, then shows its hierarchy.

FReply OnAddInteractiveComponentToBlueprintClicked()

Adds the Interactive Component to the selected Actor's Blueprint, then refreshes. Reaches every instance.

FReply OnAddInteractiveComponentToMultiSelectClicked()

Bulk version of OnAddInteractiveComponentClicked. Adds the Interactive Component as instance, to multiple Actors.

FReply OnCopyActionsToBlueprintClicked()

Pushes the selected instance IC's Actions onto its Blueprint's IC template, then recompiles.

TSharedRef<ITableRow> OnGenerateHierarchyRow(TSharedPtr<FMovaIxComponentTreeInfo> Item, const TSharedRef<STableViewBase> &OwnerTable)

Binds text properties into localized interface widget rows.

void OnGetTreeChildren(TSharedPtr<FMovaIxComponentTreeInfo> InItem, TArray<TSharedPtr<FMovaIxComponentTreeInfo>> &OutChildren)

Walks tree nodes to pass nested child elements to the layout array builder.

FReply OnHierarchyKeyDown(const FGeometry &MyGeometry, const FKeyEvent &InKeyEvent)

F2 on the hierarchy tree starts an inline rename of the single selected row.

void OnHierarchySelectionChanged(TSharedPtr<FMovaIxComponentTreeInfo> SelectedItem, ESelectInfo::Type SelectInfo)
void OnObjectMovementBegin(UObject &InObject)

Called when the editor starts to move, rotate or scale an object. => Panel transform rows follow the drag live.

void OnObjectMovementEnd(UObject &InObject)

Called when the drag ends: does one final refresh.

void RebuildHierarchyTree()

Scrapes the active workspace hierarchy to build the Component tree.

void SyncTreeSelection()

Matches the tree view's visual selection to the internal selection cache.

EActiveTimerReturnType TickBlueprintComponentSelection(double InCurrentTime, float InDeltaTime)

Polls the hosting Blueprint editor's own Components-mode viewport selection. No-op outside Blueprint mode.

EActiveTimerReturnType TickDetailsRebuild(double InCurrentTime, float InDeltaTime)

Does the coalesced rebuild and clears the pending timer.

EActiveTimerReturnType TickDragRefresh(double InCurrentTime, float InDeltaTime)

Per-frame repaint while a drag is in progress. Self-stops when the drag finishes.

EActiveTimerReturnType TickTreeSync(double InCurrentTime, float InDeltaTime)

Applies the pending hierarchy highlight, once the requested tree refresh has run.

void TriggerCopyFlash()

Restarts CopyFlashSequence from its bright end, and plays back down to transparent.

void ApplyPresetByName(const FString &PresetName)

Apply the named preset to the selected Components.

  • Undoable.

  • No confirm prompt.

bool ConfirmReapplyPreset(const FString &PresetName) const

Asks whether to apply the already-selected Preset again.

  • Re-picking it means "Update this object from the Preset as it is now".

Returns:

True when the user chose to reapply.

void DetectPreset()

Select the preset matching the current Component's Action data, else "Custom Preset".

FReply OnDetectPresetClicked()

Run DetectPreset from the toolbar button.

FReply OnManagePresetsClicked()

Opens the Manage Presets window.

void RefreshPresetList()

Rebuilds the preset combo box source list from the plugin and project preset folders.

void SelectInBlueprintTree(UActorComponent *Comp)

Mirrors a selection into the hosting Blueprint editor's own Components tree. No-op outside Blueprint mode.

void SelectPresetName(const FString &PresetName)

Set the combo selection by name without triggering an apply.

TSharedRef<ITableRow> OnGenerateGridRow(TSharedPtr<FMovaIxActorGridInfo> Item, const TSharedRef<STableViewBase> &OwnerTable)

Row generator for the multi-selection grid list view.

void OnGridSelectionChanged(TSharedPtr<FMovaIxActorGridInfo> SelectedItem, ESelectInfo::Type SelectInfo)

Focuses a single Actor from a click in the multi-selection grid.

void RebuildICDetailsCustomization()

Rebuilds the IC details customization. Filters to what references selected Components, or shows all for the IC itself.

void ShowBlueprintIC()

Blueprint mode: point the panel at EditedBlueprint's IC template. Edits persist to the Blueprint.

void UpdateDetailsView()

Forwards newly targeted selection arrays into internal property viewer widgets.

void UpdateDetailsViewNow()

Rebuild body, reached at most once a frame via TickDetailsRebuild.

void UpdateInspector()

Mirrors the current selection into the custom Inspector, alongside the stock Details.

EActiveTimerReturnType SampleRecording(double InCurrentTime, float InDeltaTime)

Active-timer tick while recording: appends one pose sample per tracked Component.

void StopRecordingAndGenerate()

Stop path: trims + simplifies each track, writes the generated Group, restores poses.

TSharedRef<SWidget> BuildTimelineTrack()

Rebuilds the unified layered overlay track showing interactive keyframes, playhead, and interception plane.

void DeleteKeyframeAtTime(float KFTime)

Removes all keyframes at the given time from the selected Group.

void EndKeyframeMoveTransaction()

Closes the FScopedTransaction opened by MoveKeyframeToTime, ending the current keyframe-move undo step.

FText GetKeyframeTooltip(float KFTime) const

Builds the hovered keyframe's tooltip: Time + the Action Targets at that time, honoring filters.

void MoveKeyframeToTime(float OldTime, float NewTime)

Moves every keyframe at OldTime to NewTime, across all Actions in the selected Group.

  • Called continuously while dragging a diamond in SMovaIxTimeline, or once for an exact-time menu commit.

FReply OnAddKeyframeClicked()

Captures a new keyframe layout sequence frame from current Component parameters.

FReply OnNextKeyframeClicked()

Moves the playhead to the next keyframe on the timeline.

FReply OnPlayPauseClicked()

Handles Play/Pause clicks.

FReply OnPrevKeyframeClicked()

Moves the playhead to the previous keyframe on the timeline.

FReply OnTimelineClicked(float NewTime)

Processes playhead scrubbing calculations and updates the underlying Actor visualization States.

void StepToKeyframe(bool bNext)

Scrubs to the keyframe before (bNext=false) or after (bNext=true) the current playhead time.

void TestGroup(FName GroupName)

Selects GroupName + plays it from the start on the timeline, once, and selects its Targets.

  • Reuses the Group combo's selection path, then triggers playback.

  • Drives the inspector Group rows' Test button.

EActiveTimerReturnType TickTimelinePlayback(double InCurrentTime, float InDeltaTime)

Active timer driving frame-rate-independent timeline playback.

void ApplyGroupIsolation(const FName &GroupName)

Updates the IsolatedGroupName in settings and triggers a visualizer + hierarchy redraw. Pass NAME_None to show everything.

TSet<USceneComponent*> CollectIsolatedGroupComponents()

Collects all USceneComponent* that are directly targeted by the currently isolated Group. Uses the cached result if bIsolatedCompsCacheDirty is false.

Returns:

Empty set when no Group is isolated (show all).

USceneComponent *FindBestRootComponent(USceneComponent *ClickedComp)

Finds the best logical Root Component for selection routing (ex: Drawer1 instead of Drawer1Front).

void InvalidateComponentCaches()

Invalidates all component-level caches (isolated comps, resolve results, Root Component mapping).

bool IsReconstructionSelectionEcho() const

True if the current selection event is reconstruction churn, not a genuine user click.

void OnActorComponentsChanged(AActor *Actor)

Fired when an Actor's Component array changes in the editor.

void OnInspectorKeyframesChanged()

Rebuilds the timeline after the inspector edits Keyframe times, which the ruler length follows.

void OnObjectsReplaced(const TMap<UObject*, UObject*> &ReplacementMap)

Re-acquires selection after a Blueprint Actor is reconstructed.

void OnSelectedActors(UObject *InSelection)

Fired when the engine's Actor selection changes.

void OnSelectedComponents(UObject *InSelection)

Fired when the engine's Component selection changes.

void OnUndoRedo()

Rebuilds the panel after an undo or redo.

void RefreshSelection(UObject *InSelection, bool bAllowBlank = true)

Captures global editor State adjustments to find applicable interactive objects.

Parameters:
  • InSelection -- Engine selection object that triggered the refresh.

  • bAllowBlank -- Actor-selection events pass true, a cleanly empty selection is a real deselect. Component-selection events pass false, an empty result recovers the last shown Actor.

Private Members

TSharedPtr<SNameComboBox> ActionComboBox

Persistent reference to the Action selector combo box, filtered by the chosen Group.

TArray<TSharedPtr<FName>> ActionNamesSource

Source list backing the Action selector combo box entries.

TSharedPtr<SNameComboBox> GroupComboBox

Persistent reference to the Group selector combo box.

TArray<TSharedPtr<FName>> GroupNamesSource

Source list backing Action slot dynamic combo box entries.

FName SelectedActionName

Currently chosen Action identifier within the selected Group. NAME_None = "(All)": no isolation, operations span every Action of the Group.

FName SelectedGroupName

Currently chosen Action Group identifier sequence for timeline sampling operations. NAME_None = "(All)": no isolation, timeline aggregates all Groups.

int32 BlankTreeRetries = 0

Frames the hierarchy tree comes up blank during a Blueprint reconstruction, no blank past 1 frame.

int32 BlueprintPreviewRetryCount = 0

Attempts made by the ShowBlueprintIC preview-actor retry.

bool bBlueprintPreviewRetryQueued = false

True while a deferred Blueprint-mode preview-actor retry is already scheduled.

TSharedPtr<FActiveTimerHandle> DetailsRebuildTimerHandle

One-shot timer running the coalesced rebuild, null when none is pending.

TSharedPtr<SSplitter> DetailsSplitter

Splitter widget resizing the details section.

bool bDetailsViewDirty = false

True while a coalesced details rebuild is pending.

TSharedPtr<FActiveTimerHandle> DragRefreshTimerHandle

Active while a viewport drag is in progress, driving TickDragRefresh.

TSharedPtr<ITableRow> GeneratedTestRow

Keeps a test-generated row alive, since nothing paints to own it.

double LastReconstructTime = -1.0

Slate time of the last Blueprint reconstruction (any OnObjectsReplaced), -1 = none yet.

TSharedPtr<SSplitter> MainSplitter

Splitter widget resizing the vertical workspace section.

FDelegateHandle ObjectMovementBeginHandle

Editor drag begin and end subscriptions, kept for the panel to stay live during a gizmo drag.

FDelegateHandle ObjectMovementEndHandle
FDelegateHandle ObjectsReplacedHandle

Delegate handle tracking a Blueprint reconstruction, for re-acquiring cached pointers.

TSharedPtr<STextBlock> PanelTitleText

Header text block showing the current single/multi-selection context.

bool bReacquireQueued = false

True while a deferred selection re-acquire is already scheduled, after Blueprint reconstruction.

uint32 RoutingFlags = 0

Gates against an infinite selection-callback loop between Slate and the viewport.

FDelegateHandle SelectedActorsHandle

Delegate handle tracking the engine's multi-Actor viewport selection.

FDelegateHandle SelectedComponentsHandle

Delegate handle tracking the engine's Component-level viewport selection.

bool bTreeSyncQueued = false

True while a hierarchy highlight is waiting for the requested tree refresh.

FDelegateHandle UndoRedoHandle

Undo / redo subscription.

TSharedPtr<IDetailsView> ActorDetails

Details view driving the stock Actor/Component property filtering.

bool bBlueprintMode = false

True when hosted in a Blueprint editor tab (edits the IC template, ignores the level selection).

mutable TSet<USceneComponent*> CachedIsolatedComps

Cached result of CollectIsolatedGroupComponents().

TSharedPtr<SBox> DetailsContainer

Box swapping visibility between the stock Component viewport and the interactive panels.

TWeakObjectPtr<UBlueprint> EditedBlueprint

Blueprint being edited when bBlueprintMode is set (the source of the IC template shown).

TWeakPtr<class FBlueprintEditor> HostingBlueprintEditor

Hosting Blueprint editor, set only in Blueprint mode.

bool bICOwnedByOurPanel = false

True when the IC was selected from the hierarchy tree, InteractiveDetails owning the IC view.

bool bICOwnedByStockDetails = false

True when the IC was selected from the stock Details, globally component-selected.

TSharedPtr<class SMovaIxInspector> Inspector

Custom inspector shown alongside the stock Details views: Tags / Transform + Action maps + Proximity.

TSharedPtr<IDetailsView> InteractiveDetails

Details view driving the IC's own runtime property filtering.

bool bIsolatedCompsCacheDirty = true

True when CachedIsolatedComps needs to be rebuilt.

FString LastCustomizationKey

Signature of the last applied IC details customization (filter State + visible Groups/cycles/States).

TWeakObjectPtr<UActorComponent> LastPolledBlueprintSelection

Last Component the Blueprint editor's own SSubobjectEditor selection reported.

TArray<TSharedPtr<FMovaIxActorGridInfo>> MultiActorItems

Multi-selection Actor rows backing MultiActorListView.

TSharedPtr<SListView<TSharedPtr<FMovaIxActorGridInfo>>> MultiActorListView

Grid view listing every Actor under multi-selection.

bool bMultiSelect = false

True while more than one object is selected in the workspace.

TArray<TWeakObjectPtr<UMovaIxComponent>> SelectedICs

Interactive Components read from the current selection.

FText ActorNameText

Displays the currently selected Actor name at the top of the panel.

ECheckBoxState BoundFilterState = ECheckBoxState::Unchecked

Filter Components that have Tags or that are Targets.

TMap<TWeakObjectPtr<USceneComponent>, TWeakObjectPtr<USceneComponent>> ComponentRoots

Maps a Component to its logical parent for Root resolution.

FCurveSequence CopyFlashSequence

Drives the brief highlight flash over the hierarchy tree, fired by TriggerCopyFlash.

TSharedPtr<STreeView<TSharedPtr<FMovaIxComponentTreeInfo>>> HierarchyTreeView

Hierarchy tree widget.

TWeakObjectPtr<AActor> LastShownActor

Last Actor successfully shown.

See also

RefreshSelection

FString SearchString

Filter Components by name.

TWeakObjectPtr<AActor> SelectedActorNode

Set while the Actor Root node is the current selection: the details panel shows the Actor itself.

TArray<TWeakObjectPtr<UActorComponent>> SelectedComps

All currently selected Components, supporting multi-select.

TArray<TSharedPtr<FMovaIxComponentTreeInfo>> TreeRootItems

Root nodes of the hierarchy tree.

TSharedPtr<class SWidgetSwitcher> AddICLayoutSwitcher

Switches the Add-IC empty-State cards between stacked (0) and side-by-side (1) layout.

TSharedPtr<class SBox> EmptyStateArea

Box that holds the empty-State block, "this Actor is not interactive yet".

FString LastDetectedSignature

Signature DetectPreset last matched, and skips repeated refreshes of the same click.

TSharedPtr<SComboBox<TSharedPtr<FString>>> PresetComboBox

Preset selector combo box, listing plugin built-in presets then project user presets.

TArray<TSharedPtr<FString>> PresetNamesSource

Source list backing the preset combo box, holding display names.

TMap<FString, FString> PresetNameToPath

Maps a preset display name to its absolute .json file path.

TMap<FString, FString> PresetSignatures

Maps a preset's serialized signature to its display name, filled by RefreshPresetList.

FString SelectedPresetName

Currently selected preset display name.

bool bSuppressPresetApply = false

Gates the combo's OnSelectionChanged from applying during a programmatic selection, ex: Detect.

TSharedPtr<class IInputProcessor> RecorderInputProcessor

Global input processor forwarding the Recorder's hotkeys regardless of keyboard focus.

bool bRecordingIx = false

True while the Interactive Object Recorder is sampling.

TArray<float> RecordMarkerTimes

Time in the current recording each pose sample landed, for the timeline's own display.

TWeakObjectPtr<USceneComponent> RecordPressedComponent

Component that was selected when Rec was pressed, if any.

TArray<TWeakObjectPtr<USceneComponent>> RecordPressedComponents

Every Component that was selected when Rec was pressed.

  • Each entry gets tagged "!<Group/Cycle> #Parent" at Stop.

  • RecordPressedComponent gets the single Tag "!<Group/Cycle>" instead.

TMap<FName, FTransform> RecordStartPoses

Relative transform of every tracked Component at record-start, for delta baking and pose restore.

double RecordStartSeconds = 0.0

Platform seconds when recording started, sample times are relative to it.

TSharedPtr<FActiveTimerHandle> RecordTimerHandle

Sampling active timer, unregistered on Stop.

TMap<FName, TArray<TPair<float, FTransform>>> RecordTracks

Per-component recorded track: seconds since start paired with a relative transform, keyed by Component name.

TUniquePtr<class FScopedTransaction> KeyframeMoveTransaction

Open transaction spanning one whole keyframe drag, or one exact-time menu commit.

  • Opened in MoveKeyframeToTime on the first move.

  • Closed by EndKeyframeMoveTransaction.

float MaxTimelineDuration = 1.0f

Max sequence time bounding threshold.

bool bPlaying = false

True while the sequencer playback loop is currently evaluating.

float PreviewAlpha = 0.0f

Timeline interpolation alpha driving the viewport preview each render.

bool bPreviewing = false

True while the user is actively scrubbing/playing the timeline.

bool bScrubbing = false

True while the mouse is scrubbing the timeline.

bool bTestOneShot = false

True while the current playback run should stop at the end instead of looping.

TArray<float> TimelineKeyframeTimes

Sorted keyframe times currently displayed on the timeline (used by prev/next keyframe stepping).

float TimelineLength = 0.0f

User-set timeline length, extends the auto-fit duration past the last keyframe. 0 = auto.

TSharedPtr<SOverlay> TimelineOverlay

Unified overlay container holding background plates, diamond track buttons, handles, and mouse input buffers.

Inspector (Details panel customization)

Functions

DECLARE_DELEGATE_OneParam(FMovaIxOnTestGroup, FName)

Fired when a Group row's "Test" button is clicked, so the host can preview that Group.

DECLARE_DELEGATE(FMovaIxOnKeyframesChanged)

Fired when an edit changes keyframe times, so the host can refit its timeline.

TArray<FName> FindGroupsAlreadyTargeting(UMovaIxComponent *IC, const USceneComponent *TargetComp)

Every Group whose own Actions resolve a Target onto TargetComp.

Parameters:
  • IC -- Interactive Component whose ActionGroups are searched.

  • TargetComp -- Component to find every targeting Group for.

Returns:

Every Group name that resolves a Target onto TargetComp, empty if none do.

struct FMovaIxGateDraft
#include <MovaIxInspector.h>

A gate condition composed one step at a time by the guided builder. Steps: 0 what it reads, 1 which State, 2 when it counts.

Public Functions

inline FString Compose() const

Composed token, ex: "?@Drawer3:!=Open".

inline void GoToStep(int32 NewStep)

Rewinds to NewStep, clearing everything set after it.

inline FString StateWithMarks() const

State with its '!' and phase marks, ex: "!=Open".

Public Members

bool bNot = false

True negates the test, the ':!State' form.

bool bTagGate = false

True prefixes the composed token with '?', for an interaction-Tag row.

MovaIx::EMovaIxStatePhase Phase = MovaIx::EMovaIxStatePhase::Either

Which part of the move counts, unmarked by default.

FString State

State name being tested for.

int32 Step = 0

Question the popup is on.

FString Target

What the condition reads: empty is self, otherwise '@Comp' or 'Actor'.

class SMovaIxInspector : public SCompoundWidget
#include <MovaIxInspector.h>

Custom inspector for the IC Control Panel.

  • Details: the selected Actor's Tag array (editable) + Transform (editable), each edit undoable.

  • InteractiveDetails: the selected UMovaIxComponent's ActionCycles, ActionGroups, ActionStates, Proximity.

Public Functions

inline SLATE_BEGIN_ARGS(SMovaIxInspector)
virtual ~SMovaIxInspector() override

Fired when an edit changes keyframe times, so the host can refit its timeline. Fired when a Group row's Test button is clicked, so the host can preview that Group. Closes a drag transaction still open because the panel died mid-gesture.

virtual void Tick(const FGeometry &AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override

Tracks the panel width, swapping add buttons to icons + wrapping the Action/Target row when narrow.

void Construct(const FArguments &InArgs)

Builds the empty inspector shell, call SetSubject to populate it.

void ApplyToLinked()

Stamps the primary IC's data (Cycles / Groups / States / Proximity) onto every linked IC, one transaction.

void ClassifyStateToken(const FString &Token, FLinearColor &OutColor, bool &bOutResolved, FString &OutSuggestion) const

Classifies one keyframe State token for the chip strip: color + resolution + suggestion. A special marker (@Zero / @Loop / ...) or a known State resolves, anything else gets a suggestion.

void ClassifyTagToken(const FString &Token, bool bFirstToken, const FString &DelegateToken, FLinearColor &OutColor, bool &bOutResolved, FString &OutSuggestion) const

Classifies one token of a full interaction Tag for the chip strip.

Parameters:
  • Token -- One space-separated token, ex: "!Open", "?@Lock:Off", "@Door".

  • bFirstToken -- A Tag's leading token needs no '!', ex: "Open @Door".

  • DelegateToken -- "%Tag" this token's verb delegates to, empty when it runs locally.

  • OutColor -- Chip tint for the token's role.

  • bOutResolved -- True when the token is valid and names something that exists.

  • OutSuggestion -- Closest known name when it does not resolve, else empty.

void ClassifyTargetToken(const FString &Token, FLinearColor &OutColor, bool &bOutResolved, FString &OutSuggestion) const

Classifies one Target token for the chip strip: color + resolution + suggestion. @ internal, ^ % external, # special. A '*' or '?' token resolves by wildcard.

void ClassifyVerbToken(const FString &Token, const FString &DelegateToken, FLinearColor &OutColor, bool &bOutResolved, FString &OutSuggestion) const

Classifies an interaction Tag's leading verb token for the chip strip: color + resolution + suggestion. Strips a flow prefix (! / > / +) and a "/UILabel" suffix, then resolves against the IC's cycles + Groups. A delegated verb resolves against the "%Tag" Actor's own IC instead.

bool FlushInteractiveRebuildForTesting()

Runs a requested rebuild now, as Tick does, and reports whether one was pending.

void FocusOnGroup(FName GroupName)

Collapses everything, then expands only the chain relevant to GroupName: its own Groups/Cycles/States. Pass None to leave expansion untouched.

void RebuildAll()

Rebuilds both sections (Details + InteractiveDetails) from the current subject.

void RebuildInteractiveDetails()

Rebuilds the InteractiveDetails section (the 3 Action maps + Proximity) from CurrentComponent.

void SetSubject(AActor *InActor, UMovaIxComponent *InComponent, class UActorComponent *InSelectedComp = nullptr, const TArray<UMovaIxComponent*> &InLinkedICs = TArray<UMovaIxComponent*>())

Points the inspector at an Actor and (optionally) one of its IC Components, or nullptrs to clear.

Parameters:
  • InActor -- Actor whose Transform + Tags render in the Details box.

  • InComponent -- Primary IC driving the InteractiveDetails.

  • InSelectedComp -- Selected sub-Component, optional.

  • InLinkedICs -- Other selected ICs (multi-select), targeted by the "Apply to N selected" bar.

void OnTransformCommitted(double NewValue, ETextCommit::Type CommitType, int32 Which, int32 Axis)

A typed, pasted or arrow-nudged transform value, as opposed to a drag. Which: 0 = Location, 1 = Rotation, 2 = Scale. Axis: 0 = X, 1 = Y, 2 = Z.

void OnTransformSpin(double NewValue, int32 Which, int32 Axis)

Live spin-drag update of one transform axis, inside the drag's transaction.

void OnTransformSpinBegin(int32 Which, int32 Axis)

One transform spin drag: begin, live frames, then release.

void OnTransformSpinEnd(double NewValue, int32 Which, int32 Axis)

Spin drag released: closes the transaction, leaving one undo step.

Public Static Functions

static void CreateContinuousLoopCycle(UMovaIxComponent *IC, const FString &Stem, float Duration, FName &OutCycle, FName &OutStart, FName &OutStop)

Creates a Start/Stop cycle for an endlessly looping animation onto IC, ex: a fan, a conveyor. Start ramps in over 1s and holds until Stop, which halts it in place over 1s. Names are Stem+"Start" / Stem+"Stop", uniquified against what IC already holds.

Parameters:
  • IC -- Component to add to, caller owns Modify() and the transaction.

  • Stem -- Actor stem to prefix every generated Group with, empty prefixes nothing.

  • Duration -- Seconds from @Start to @Loop.

  • OutCycle -- Key of the new cycle.

  • OutStart -- Key of the new Start Group.

  • OutStop -- Key of the new Stop Group.

static void CreateToggleCycle(UMovaIxComponent *IC, const FString &Stem, float Duration, FName &OutCycle, FName &OutOpen, FName &OutClose, FName &OutState)

Creates a Toggle cycle onto IC: 2 Action Groups and the State the first one reaches. Open travels to "Opened" over Duration, Close returns to @Zero. Stem is prepended to every generated name when non-empty, ex: a Door gets DoorOpen / DoorClose.

Parameters:
  • IC -- Component to add to, caller owns Modify() and the transaction.

  • Stem -- Actor stem to prefix every generated Group/State with, empty prefixes nothing.

  • Duration -- Seconds each half takes.

  • OutCycle -- Key of the new cycle.

  • OutOpen -- Key of the new forward Group.

  • OutClose -- Key of the new return Group.

  • OutState -- Key of the new State the forward Group reaches.

static void CreateVerbGroup(UMovaIxComponent *IC, const FString &Stem, const TCHAR *Verb, float Duration, FName &OutGroup, FName &OutState)

Creates one Action Group onto IC, plus the State it travels to. Named for the verb an interaction Tag types, ex: Open reaching "Opened" at Time Duration. Stem is prepended when non-empty, ex: "DoorOpen" for a Door.

Parameters:
  • IC -- Component to add to, caller owns Modify() and the transaction.

  • Stem -- Actor stem to prefix the verb with, ex: "Door", empty prefixes nothing.

  • Verb -- Group name to try first, ex: "Open".

  • Duration -- Seconds the Group takes, ie the time on its single keyframe.

  • OutGroup -- Key of the new Group.

  • OutState -- Key of the new State it reaches.

static FVector ApplyScaleWithRatio(const FVector &OldScale, double NewValue, int32 Axis, bool bPreserveRatio)

Applies NewValue to one axis of OldScale, scaling the other two by the same ratio when locked. A zero OldValue on the edited axis falls back to a direct set instead.

static FString GuessSelfIdentityTag(const AActor *Actor, const TSet<FString> &ExistingTags)

Guesses a self-identity "=Name" candidate from Actor's class, ex: "BP_Door_Basic_09" => "Door". Strips a leading "BP_" / trailing "_C" and any trailing "_##" instance number.

Returns:

A "=Name" not present in ExistingTags, "=Actor" if nothing else fits.

static FString MakeExternalToken(const AActor *Tagged, FName Tag)

Builds the external Target token a picker should offer for Tag, on Actor's level. "%Light^" when the tagged Actor has an IC, "%Light" when it does not.

Parameters:
  • Tagged -- Actor holding the "=" Tag.

  • Tag -- The "=" Tag itself, ex: "=Light".

Returns:

The token to offer, ex: "%Light" or "%Light^".

template<typename TValue>
static inline void RenameKeyPreserveOrder(TMap<FName, TValue> &Map, FName OldKey, FName NewKey)

Renames OldKey to NewKey in Map, preserving insertion order (no-op if OldKey is absent or NewKey exists).

static int32 VerbInsertIndex(const TArray<FString> &Tokens)

Where a picked Action goes in a Tag row: attaches to the verb already seen. Returns 0 only for a verbless row.

Parameters:

Tokens -- Row as it stands, space-split.

Returns:

Index to insert the new verb token at.

static FText DescribeTagToken(const FString &Token, bool bFirstToken)

Plain-English description of one interaction-tag token, for its hover tooltip.

Parameters:
  • Token -- One space-separated token, ex: "!Open", "@Door:Shut", "?@Lock:!Off".

  • bFirstToken -- True for a tag's first token, which needs no flow prefix.

Returns:

Description, empty for a token whose role carries no explanation.

Private Types

enum class EActionMap : uint8

Which Action map an add or remove Targets.

Values:

enumerator Cycles
enumerator Groups
enumerator States

Private Functions

void AddListHeader(const TSharedRef<SVerticalBox> &Box, const FText &Title, int32 Count, TFunction<FReply()> OnAdd, TFunction<FReply()> OnClearAll, float LeftIndent = 0.0f, const FText &AddButtonText = FText::GetEmpty(), TFunction<void()> OnCopy = nullptr, TFunction<void()> OnPaste = nullptr, const FText &DocTip = FText::GetEmpty(), TFunction<void()> OnSuggestSelfID = nullptr)

Appends a section-band header "{Title} (Count) [+]" (label + add + Remove All) to Box. AddButtonText overrides the wide "+" label, empty falls back to "Add {Title}". OnCopy / OnPaste (when both set) add the header's Shift+click / right-click copy/paste.

void AttachViewportPickAccessory(TArray<FPickSection> &Sections, TFunction<void(const FString&)> OnPick, TWeakPtr<SComboButton> WeakCombo)

Hangs a viewport eyedropper off every address section header of a built section list.

  • Both "@" and "%" take one: the pick resolves to a Component via its own popup.

  • Sections absent from the list are skipped.

TSharedRef<SWidget> BuildAddInteractionMenu(TFunction<void(const FString&)> OnAddTag)

Builds the "Add Interaction" popup: a guided builder that composes an interaction Tag. Hands the composed Tag to OnAddTag on "Add Interaction".

TSharedRef<SWidget> BuildAddressPickerPopup(const TArray<FString> &OnRowTokens, TFunction<void(const FString&)> OnPick, const FText &OnRowLabelFormat, const FText &SearchHint, TWeakPtr<SComboButton> WeakCombo)

One address-token popup, shared by every Target picker: search box, sections, colors.

  • Callers differ only in which tokens read as already-on and what a pick does.

Parameters:
  • OnRowTokens -- Tokens already chosen, drawn to remove.

  • OnPick -- Receives the token picked.

  • OnRowLabelFormat -- Label format for an already-chosen entry, ex: "X {0}".

  • SearchHint -- Placeholder for the search box.

TArray<FPickSection> BuildAddressTokenSections(AActor *Owner, UWorld *World, TFunction<FPickEntry(const FString&, const FText&, const FText&, const FText&, TFunction<void()>)> MakeEntry, TFunction<TFunction<void()>(const FString&)> MakePick)

Shared #Specials / @Internal Components (+ bones, wildcards) / External Actors sections.

  • Ordered Specials, Internals, Externals: this Actor's own short lists ahead of the level.

Parameters:
  • MakeEntry -- Wraps a candidate token into one FPickEntry: label, color, tooltip.

  • MakePick -- Wraps a candidate token into its own click Action.

void BuildAdvancedSection()

Collapsible "Advanced" Group: Component's native Detection / Network / Typing / Runtime categories.

TSharedRef<SWidget> BuildBuilderTargetPickerMenu(const FString &Current, TFunction<void(const FString&)> OnAppend, TWeakPtr<SComboButton> WeakCombo)

Target picker for the "+ Add Interaction" builder, the same sections the Action Target field offers.

Parameters:
  • Current -- Tokens already composed, shown as removable.

  • OnAppend -- Receives each picked token.

TSharedRef<SWidget> BuildConditionBuilderMenu(TFunction<void(const FString&)> OnAddCondition, bool bAsTagGate = false)

Builds the guided "Add Condition" popup: a stepper that asks one question at a time. Composes an "Address:State" (or ":!State") gate condition and hands it to OnAddCondition.

See also

BuildInteractionTagPickerMenu, which opens this as its [+ Add Gate] entry.

Parameters:

bAsTagGate -- True prefixes the result with '?', for an interaction-Tag row.

void BuildConditionList(const TSharedPtr<SVerticalBox> &Box, const FText &Title, const TArray<FName> &Conditions, TFunction<void(int32, const FText&, ETextCommit::Type)> OnCommit, TFunction<FReply(int32)> OnRemove, TFunction<void(const FString&)> OnAdd, float LeftIndent = 0.0f)

Appends a gate-condition list to Box, ex: a Group's Gates. Ends with a "+ Add Condition" guided builder.

Parameters:
  • Box -- Vertical box to append to.

  • Title -- Header label, ex: "Gates", empty skips the header.

  • Conditions -- Conditions to render.

  • OnCommit -- Called when a row's text commits.

  • OnRemove -- Called when a row's remove button is clicked.

  • OnAdd -- Called by the builder with the composed condition.

  • LeftIndent -- Row inset.

TSharedRef<SWidget> BuildInteractionTagPickerMenu(const FName &CurrentTag, TFunction<void(const FString&)> OnPicked, bool bGroupsOnly, TWeakPtr<SComboButton> WeakCombo, int32 CaretOffset = INDEX_NONE)

Menu listing this IC's Cycles and Groups for an interaction-Tag row, ex: Proximity Enter/Leave. Each entry toggles: picking appends "!Name" (shown as "X Name"), picking that removes it again.

Parameters:
  • bGroupsOnly -- True lists Groups only, for Proximity Enter/Leave where a Cycle makes no sense.

  • CaretOffset -- Character offset of the row's live text cursor, or INDEX_NONE to append at the end.

TSharedRef<SWidget> BuildOffsetBuilderMenu(TFunction<void(const FString&)> OnAddOffset, TOptional<FVector> Initial = TOptional<FVector>())

Builds the "+ Add Offset" page: an X/Y/Z row composing a "$X,Y,Z" token, an offset relative to the Target.

See also

BuildInteractionTagPickerMenu.

Parameters:
  • OnAddOffset -- Receives the composed "$X,Y,Z" token.

  • Initial -- Row's current offset, when it already has one, set opens on it and reads "Replace Offset", unset opens a fresh zeroed offset.

TSharedRef<SWidget> BuildStatePickerMenu(TSharedRef<FName> GroupNameH, TSharedRef<FName> ActionKeyH, int32 KeyIndex, TWeakPtr<SComboButton> WeakCombo)

Builds the keyframe State picker popup (search box + this IC's Action States + special markers). Picking replaces the keyframe's State.

void BuildTagList(const TSharedPtr<SVerticalBox> &Box, const FText &Title, const TArray<FName> &Tags, TFunction<void(int32, const FText&, ETextCommit::Type)> OnCommit, TFunction<FReply(int32)> OnRemove, TFunction<FReply()> OnAdd, TFunction<FReply()> OnClearAll, float LeftIndent = 0.0f, const FText &AddButtonText = FText::GetEmpty(), TFunction<void()> OnCopy = nullptr, TFunction<void()> OnPaste = nullptr, bool bInteractionTags = false, TFunction<void(const FString&)> OnAddInteraction = nullptr, const FText &DocTip = FText::GetEmpty(), bool bPickGroupsOnly = false, TFunction<void()> OnSuggestSelfID = nullptr)

Appends a compact "{Title} (N) [+]" header + one editable row per Tag (edit + X) to Box.

Parameters:
  • Box -- Vertical box to append the rows to.

  • Title -- Header label (ex: "Tags", "Enter Tags").

  • Tags -- Tags to render.

  • OnCommit -- Called when a row's text is committed (index, new text, commit type).

  • OnRemove -- Called when a row's X is clicked (index).

  • OnAdd -- Called when the header [+] is clicked.

  • AddButtonText -- Overrides the wide "+" label (ex: "Add Tag"), empty falls back to "Add {Title}".

  • OnCopy -- Copies the whole list to the clipboard (empty means no copy/paste on the header).

  • OnPaste -- Pastes the whole list from the clipboard.

  • bInteractionTags -- True adds a per-row validation chip strip, false for simple trigger tags.

  • OnAddInteraction -- When set, adds a "+ Add Interaction" guided builder that hands the composed Tag here.

  • bPickGroupsOnly -- True limits each row's "..." picker to Groups, leaving out Cycles.

TSharedRef<SWidget> BuildTargetPickerMenu(TSharedRef<FName> GroupNameH, TSharedRef<FName> ActionKeyH, TWeakPtr<SComboButton> WeakCombo)

Builds the Target picker popup content: search box plus @, ^ and # sections. WeakCombo closes it on pick.

TSharedRef<SWidget> BuildTokenReplaceMenu(const FString &Token, TFunction<void(const FString&)> OnReplace, TFunction<void()> OnRemove, TWeakPtr<SComboButton> WeakCombo)

Builds the popup that swaps one Target token of a tag for another.

Parameters:
  • Token -- Token being replaced, ex: "@Door" from "!Open @Door".

  • OnReplace -- Receives the chosen token.

  • OnRemove -- Removes the token instead of replacing it, when set, on picking its own entry.

  • WeakCombo -- Closes the popup on pick.

TSharedRef<SWidget> BuildVerbReplaceMenu(const FString &Token, TCHAR Flow, TFunction<void(const FString&)> OnReplace, TFunction<void()> OnRemove, TWeakPtr<SComboButton> WeakCombo)

Right-click swap menu for a Tag's Verb token: this IC's own Cycles and Groups.

Parameters:
  • Token -- Verb token being replaced, ex: "Open" from "!Open @Door".

  • Flow -- The token's own flow prefix (!>+), echoed on the header and every entry label.

  • OnReplace -- Receives the chosen Action name.

  • OnRemove -- Removes the token instead of replacing it, when set, on picking its own entry.

  • WeakCombo -- Closes the popup on pick.

TSharedRef<SWidget> BuildViewportComponentPicker(AActor *PickedActor, bool bSelf, TFunction<void(const FString&)> OnCommit)

Popup listing a viewport-picked Actor's Components.

  • A click names an Actor, so the Component is chosen here.

  • First entry is the Actor itself, addressing the whole thing.

Parameters:
  • bSelf -- True when the Actor is the inspected one, whose Components need no "%" prefix.

  • OnCommit -- Receives "" for the Actor itself, else "@Component".

FString ComposeViewportPickAddress(AActor *PickedActor, bool bSelf, const FString &CompToken)

One address from a viewport pick, the Actor clicked plus the Component chosen.

  • Creates the identity Tag when the Actor carries none, so it is called on commit only.

Parameters:
  • bSelf -- True for the inspected Actor, whose Components need no "%" prefix.

  • CompToken -- "" for the Actor itself, else "@Component".

Returns:

"@Comp", "%Tag", or "%Tag@Comp", empty when nothing can be addressed.

void CopyPropertyText(const FProperty *Prop, const void *Container, UObject *Owner) const

Copies a property value to the clipboard as stock UE Details text (PPF_Copy).

FString EnsureExternalTagToken(AActor *Actor)

That Actor's "%Tag" address, creating the identity Tag when it carries none.

  • Called on commit, so an abandoned pick never writes a Tag.

Returns:

"%Tag", or empty when Actor is null.

void FillTagPickerActorActions(TSharedRef<SBox> Swap, TArray<FString> RowTokens, TFunction<void(const FString&)> OnPicked, bool bGroupsOnly, TWeakPtr<SComboButton> WeakCombo, FString Ext, int32 InsertIndex, TCHAR Flow = TEXT('!'))

Fills the Tag picker with one external Actor's own Actions, replacing the root page. Picking one writes the finished pair verb-first, ex: "!OpenLeft %Door^".

Parameters:
  • Swap -- Box holding whichever page is showing.

  • RowTokens -- Row as it stands, the pick inserts into this.

  • Ext -- That Actor's "%Tag", without any '^'.

  • InsertIndex -- Token index the pick lands at, clamped to RowTokens.Num().

  • Flow -- Flow the picked verb is written with ('!', '>', or '+').

void FillTagPickerRoot(TSharedRef<SBox> Swap, TArray<FString> RowTokens, TFunction<void(const FString&)> OnPicked, bool bGroupsOnly, TWeakPtr<SComboButton> WeakCombo, bool bScrollToTargets = false, int32 InsertIndex = INDEX_NONE, TCHAR InitialFlow = TEXT('!'))

Fills the Tag picker's first page: this IC's Actions, external Actors, and "+ Add Gate".

Parameters:
  • bScrollToTargets -- Lands on the Targets section instead of the top.

  • InsertIndex -- Token index the pick lands at, clamped to RowTokens.Num().

  • InitialFlow -- "!Actions" header starts on this flow ('!', '>', or '+'), defaults to '!'.

TSharedRef<SWidget> MakeAddButton(const FText &AddLabel, const FText &Tooltip, FOnClicked OnClicked)

A section "+" add button, labeled "[+ AddLabel]" when the panel is wide, a [+] when narrow.

TSharedRef<SWidget> MakeAddressField(const FName &Value, bool bStateContext, TFunction<void(const FText&, ETextCommit::Type)> OnCommitted, const TSharedRef<SWidget> &Picker, const FText &EmptyHint = FText::GetEmpty())

Builds one Target or State address field: autocomplete box + "..." picker + colored text. Left click focuses the box, right click swaps a Target token.

See also

MakeTagColoredText.

Parameters:
  • Value -- Current field value.

  • bStateContext -- True for a State field, false for a Target field.

  • OnCommitted -- Called when the box's text commits.

  • Picker -- The "..." picker button embedded on the box's right edge.

  • EmptyHint -- Placeholder text shown when Value is empty.

TSharedRef<SWidget> MakeClassifiedChip(const FString &Token, const FLinearColor &Color, bool bResolved, const FString &Suggestion, bool bShowResolved = false) const

Builds one token chip from a classification result. Resolved: a solid category color, no tooltip. Unresolved: amber + "?" + a "did you mean" tooltip.

TSharedRef<SWidget> MakeConditionChips(const FName &Condition)

Builds the read-only chip strip under a gate condition (ex: "@Lock:Off"). One chip for the Target address, one for the ":State".

TSharedRef<SWidget> MakeExpander(FName Key)

Native disclosure-triangle toggle (like UE Details) for the row keyed by Key.

TSharedRef<SWidget> MakeInteractionTagField(const FName &Value, TFunction<void(const FText&, ETextCommit::Type)> OnCommitted, bool bPickGroupsOnly, TSharedPtr<SSuggestionTextBox> &OutBox)

Interaction-Tag field: colored token face over a live suggestion box, plus the "..." Tag picker.

  • One builder for every Tag row: the Tags list, Proximity Enter/Leave, and a Cycle step.

Parameters:
  • Value -- Tag text the row currently holds.

  • OnCommitted -- Receives the edited text.

  • bPickGroupsOnly -- True lists Groups only, for a row where a Cycle makes no sense.

  • OutBox -- Receives the suggestion box the face tracks focus on.

TSharedRef<SWidget> MakeProximityShapeCombo()

A native-style dropdown for the IC's Proximity.Shape enum (None / Box / Sphere / Volume).

TSharedRef<SWidget> MakeScaleLockWidget()

Builds the Scale-lock checkbox: a lock/unlock icon toggling bPreserveScaleRatio.

TSharedRef<SWidget> MakeStatePickerButton(TSharedRef<FName> GroupNameH, TSharedRef<FName> ActionKeyH, int32 KeyIndex)

"..." button placed inside a keyframe's State field. Opens a searchable picker: this IC's Action States + special markers (@Zero, @Loop, @Stop...).

TSharedRef<SWidget> MakeStructEditor(UScriptStruct *StructType, const void *InitialData, TFunction<void(const FStructOnScope&)> WriteBack, const TSet<FName> &HiddenProperties = TSet<FName>(), bool bAllowSearch = true, FName MoreKey = NAME_None)

Builds an embedded UE struct property editor for one struct value. Edits a private copy, WriteBack syncs it onto the live data on each change.

Parameters:
  • HiddenProperties -- Dropped from the native view, the caller renders them itself.

  • MoreKey -- Identifies this struct view for expansion memory, ex: "more.state.Ajar". Engine keys its own memory by struct type, one shared value per State's "More". NAME_None keeps the category collapsed with no memory.

TSharedRef<SWidget> MakeTagChips(const FName &Tag)

Builds the read-only chip strip under an interaction Tag (Component / Actor Tags). Token 0 = flow-prefixed verb, remaining tokens = Targets.

TSharedRef<SWidget> MakeTagColoredText(const FName &Tag, bool bStateContext, bool bTagContext, TFunction<void(const FString&)> OnCommitTag = nullptr, TFunction<void(float)> OnLeftPress = nullptr, const FText &EmptyText = FText())

Builds the Tag's own text with each token colored by role, standing in for the input.

See also

DescribeTagToken.

Parameters:
  • Tag -- Tag to render.

  • bStateContext -- True classifies each token as a State, false as an interaction Tag/Target.

  • bTagContext -- True marks Tag's first token as its verb, false as a Target address (ex: @Door).

  • OnCommitTag -- Optional: receives the whole rewritten Tag when a token is swapped.

  • OnLeftPress -- Optional: called with the press's absolute X (caret position) when left-pressed.

  • EmptyText -- Shown, in the field's idle color, when Tag is empty/None.

TSharedRef<SWidget> MakeTargetPickerButton(TSharedRef<FName> GroupNameH, TSharedRef<FName> ActionKeyH)

"..." button placed next to an Action's Target field. Opens a searchable picker: @ internal Components, ^ external tags, # specials.

TSharedRef<SWidget> MakeTokenChips(const FName &Value, bool bStateContext, bool bAllTokens = false, bool bTagContext = false)

Builds the chip strip for a Target or State field.

Parameters:
  • bStateContext -- State grammar (specials + State names), else Target grammar (@ / ^ / #).

  • bAllTokens -- True shows every token as a colored chip, false shows only unresolved as an error chip.

  • bTagContext -- Marks Value as a whole interaction Tag, whose first token is its verb.

TSharedRef<SWidget> MakeTransformRow(const FText &Label, TFunction<TOptional<double>(int32 Axis)> GetValue, TFunction<void(double NewValue, int32 Axis)> OnChanged, TFunction<void(double NewValue, ETextCommit::Type, int32)> OnCommitted, double Delta, float LeftIndent, TFunction<void()> OnCopy, TFunction<void()> OnPaste, const FText &Tooltip = FText::GetEmpty(), TFunction<FText(int32 Axis)> GetAxisTip = nullptr, TSharedPtr<SWidget> LeadWidget = nullptr, TFunction<void(int32 Axis)> OnBeginSpin = nullptr, TFunction<void(double NewValue, int32 Axis)> OnEndSpin = nullptr)

Builds one labeled Location / Rotation / Scale transform row.

Parameters:
  • LeadWidget -- Optional widget in a fixed-width column right after the label (ex: the Scale lock).

  • OnBeginSpin -- Reports the real drag boundaries.

  • OnEndSpin -- Reports the real drag boundaries.

TSharedRef<SWidget> MakeViewportPickAccessory(TFunction<void(const FString&)> OnPick, TWeakPtr<SComboButton> WeakCombo)

Eyedropper button for the External section header, starting a viewport Actor pick.

void PastePropertyText(const FProperty *Prop, void *Container, UObject *Owner, const FText &TransactionLabel)

Pastes stock UE Details text from the clipboard into a property (undoable), then rebuilds. No-op when the clipboard text does not parse as that property's type.

void RebuildDetails()

Rebuilds the Details section (Tag array + Transform) from CurrentActor.

void RebuildGateStep(TSharedRef<FMovaIxGateDraft> Draft, TSharedRef<SVerticalBox> Body, TSharedRef<TFunction<void()>> Rebuild, TFunction<void(const FString&)> OnAddCondition)

Draws one step of that builder into Body, replacing whatever was there. Last step commits and hands the composed condition to OnAddCondition.

Parameters:
  • Draft -- Condition being composed, kept across steps.

  • Body -- Vertical box redrawn in place.

  • Rebuild -- Calls back here. A row can advance or rewind the stepper.

void RebuildInteractiveNow()

Rebuilds the interactive section now, skipping Tick's menu-open deferral. A popup that stays open must not call this: the rebuild destroys the combo button owning it.

See also

RequestInteractiveRebuild.

void RefreshTokenCaches()

Refreshes the token candidate caches from the current IC + level, once per interactive rebuild.

  • CachedComponentTokens: "@Name" per Component.

  • CachedExternalTokens: "%Tag" per level Tag.

  • CachedStateNames: the IC's own ActionState keys.

void RequestInteractiveRebuild()

Requests a deferred InteractiveDetails rebuild instead of rebuilding immediately. Tick coalesces a burst of edits in one frame into a single rebuild next tick.

void ShowTokenReplaceMenu(const TArray<FString> &Tokens, int32 TokenIndex, bool bTagContext, TFunction<void(const FString&)> OnCommitTag, FVector2D ScreenPos)

Opens the swap popup for one token of a tag, at the cursor.

Parameters:
  • Tokens -- Tag's tokens, in order.

  • TokenIndex -- Which one is being replaced.

  • bTagContext -- True if Tokens[0] is a verb (a whole interaction Tag), false for a Target/State address.

  • OnCommitTag -- Receives the rebuilt tag.

  • ScreenPos -- Where to open the popup.

void ShowTransformRowMenu(TFunction<void()> OnCopy, TFunction<void()> OnPaste, FVector2D ScreenPos)

Opens the transform-row Copy/Paste popup at ScreenPos (right-click).

TSharedRef<SWidget> WrapHeaderCopyPaste(const TSharedRef<SWidget> &Header, TFunction<void()> OnCopy, TFunction<void()> OnPaste, const FText &DocTip = FText::GetEmpty())

Wraps a section / list header for copy/paste, matching the transform rows. Shift+Right-Click copies, Shift+Left-Click pastes, Right-Click opens a Copy/Paste menu.

void ApplyTransformValue(double NewValue, int32 Which, int32 Axis)

Writes one transform axis on the selected scene Component (relative) or the Actor (world).

TArray<USceneComponent*> GatherTransformTargets() const

Every scene Component a transform edit writes to: the selected ones plus the primary.

FName GetExpandKeyFor(EActionMap Map, FName BaseKey) const

Returns the expansion key for a map entry.

TArray<AActor*> GetMultiEditActors() const

Returns every Actor selected in the level when this is a multi-Actor world-transform edit.

  • Empty unless no sub-Component is selected and more than one Actor is selected.

  • Callers apply Transform edits as a delta to each, so the Actors move together.

double GetTransformValue(int32 Which, int32 Axis) const

Reads one live transform axis (0=Loc/1=Rot/2=Scale, Rot=Pitch/Yaw/Roll) so the spin box tracks the drag.

void ModifyTransformTarget()

Modify() the transform's owning object for undo: the selected Component, else the Actor + its Root.

void NotifyEditorTransformChanged()

Notifies the editor after a direct transform write, refreshing the gizmo pivot + redrawing viewports.

FReply OnAddTag()

Appends a new empty Tag to the Actor and rebuilds the Details.

FReply OnClearTags()

Clears every Tag from the Actor, then rebuilds the Details.

FReply OnRemoveTag(int32 Index)

Removes the Tag at Index from the Actor and rebuilds the Details.

void OnTagCommitted(const FText &NewText, ETextCommit::Type CommitType, int32 Index)

Commits an edited Tag value at Index back to the Actor's Tags array.

void AppendTargetToken(FName GroupName, FName ActionKey, const FString &Token)

Appends Token to the (GroupName, ActionKey) Action's space-separated Target. Replaces instead when the current Target is empty / "None".

void ApplyGlobalPropertySearchText()

Pushes GlobalPropertySearchText into every live StructViews/AdvancedViews native details view.

void ApplyProximityVector(double NewValue, int32 Which, int32 Axis)

Writes one Proximity vector axis, Which: 0 = RelativeLocation, 1 = RelativeRotation, 2 = BoxExtent.

void ApplyStateVector(double NewValue, FName StateName, int32 Which, int32 Axis)

Writes one Location/Rotation axis on ActionState[StateName].

bool DoesActionMatchGlobalSearch(FName ActionKey, const struct FMovaIxAction &Action) const

True if this Action's own displayed text (its key, Target, or any Keyframe State) matches the global search.

bool DoesCycleMatchGlobalSearch(FName CycleName, const struct FMovaIxActionCycle &Cycle) const

True if CycleName, or any Group it steps over (recursively, by its own name/Action/Target match), matches.

bool DoesGroupMatchGlobalSearch(FName GroupName, const struct FMovaIxActionGroup &Group) const

True if GroupName, any Action key/Target inside it, or any property in its "More" matches the global search.

bool DoesGroupNameOrTargetMatchGlobalSearch(FName GroupName, const struct FMovaIxActionGroup &Group) const

True if GroupName or any Action key/Target inside it matches, by name only, ignoring "More" properties.

  • Drives whether an ActionCycle row (which has no "More" of its own) is worth showing at all.

  • Drives whether a Group's own hand-built rows stay visible or collapse to only the matching "More".

EMovaIxProximityShape GetProximityShape() const

Reads IC->Proximity.Shape (None if no IC).

double GetProximityVector(int32 Which, int32 Axis) const

Reads one live Proximity vector axis (0=RelativeLocation/1=RelativeRotation/2=BoxExtent).

double GetStateVector(FName StateName, int32 Which, int32 Axis) const

Reads one live State axis (0=Location/1=Rotation, Rotation=Pitch/Yaw/Roll) so the spin box tracks the drag.

inline bool IsExpanded(FName Key) const

True when the entry keyed by Key is expanded.

inline bool IsExpandedForSearch(FName Key) const

True when the entry keyed by Key is expanded, OR a global "More" search is active.

  • Only for gates that guard building a State/Group's native "More" and Advanced content.

  • Unrelated rows keep using IsExpanded.

inline bool MatchesGlobalSearch(const FString &Text) const

True when Text contains GlobalPropertySearchText (case-insensitive), or the search is empty.

  • Shared by every hand-built row's own name/Target-address match.

  • Ex: "DoorLeft" matches a Group/State/Cycle by name, and by any Action Target address inside it.

void OnActionTargetCommitted(const FText &NewText, ETextCommit::Type CommitType, FName GroupName, FName ActionKey)

Commits an Action's Target name (Group GroupName, Action ActionKey).

FReply OnAddAction(FName GroupName)

Adds a uniquely-named empty Action to GroupName, then rebuilds.

FReply OnAddCycleGroup(FName CycleName)

Appends an empty Group to CycleName, then rebuilds.

FReply OnAddKeyframe(FName GroupName, FName ActionKey)

Appends an empty keyframe to the Action (GroupName, ActionKey), then rebuilds.

FReply OnAddMapEntry(EActionMap Map)

Adds a new uniquely-named empty entry to the given Action map, then rebuilds.

FReply OnAddProximityTag(bool bEnter)

Appends a new empty proximity Tag, bEnter picks the Enter vs Leave list, then rebuilds.

FReply OnClearMap(EActionMap Map)

Clears every entry from the given Action map, then rebuilds.

FReply OnClearProximityTags(bool bEnter)

Clears every proximity Tag, bEnter picks the Enter vs Leave list, then rebuilds.

void OnCycleGroupCommitted(const FText &NewText, ETextCommit::Type CommitType, FName CycleName, int32 GroupIndex)

Commits an edited Group name at GroupIndex on CycleName.

void OnCycleStartIndexCommitted(int32 NewValue, FName CycleName)

Commits StartIndex on CycleName, clamped to its Group count, then rebuilds.

FReply OnInsertKeyframe(FName GroupName, FName ActionKey, int32 KeyIndex, bool bAfter)

Inserts a new keyframe adjacent to KeyIndex in the Action (GroupName, ActionKey), then rebuilds. Inserts before KeyIndex when bAfter is false, after it otherwise. New keyframe's State is left None.

void OnKeyframeStateCommitted(const FText &NewText, ETextCommit::Type CommitType, FName GroupName, FName ActionKey, int32 KeyIndex)

Commits a keyframe State name on an Action (Group, Action, keyframe index).

void OnKeyframeTimeCommitted(float NewValue, ETextCommit::Type CommitType, FName GroupName, FName ActionKey, int32 KeyIndex)

Commits a keyframe Time on an Action (Group, Action, keyframe index).

void OnProximityShapeChanged(EMovaIxProximityShape NewShape)

Sets IC->Proximity.Shape (transaction) + rebuilds (the shape's conditional fields change).

void OnProximitySphereRadiusCommitted(float NewValue, ETextCommit::Type CommitType)

Commits IC->Proximity.SphereRadius (transaction).

void OnProximitySphereRadiusSpin(float NewValue)

Live drag of IC->Proximity.SphereRadius, before the commit transaction.

void OnProximityTagCommitted(const FText &NewText, ETextCommit::Type CommitType, bool bEnter, int32 Index)

Commits an edited proximity Tag at Index, bEnter picks the Enter vs Leave list.

void OnProximityVectorCommitted(double NewValue, ETextCommit::Type CommitType, int32 Which, int32 Axis)

Commits one Proximity vector axis (final value, in a transaction).

void OnProximityVectorSpin(double NewValue, int32 Which, int32 Axis)

Live spin-drag of one Proximity vector axis (no per-frame transaction).

void OnProximityVolumeTagCommitted(const FText &NewText, ETextCommit::Type CommitType)

Commits IC->Proximity.VolumeTag (transaction).

FReply OnRemoveAction(FName GroupName, FName ActionKey)

Removes ActionKey from GroupName's Actions map, then rebuilds.

FReply OnRemoveCycleGroup(FName CycleName, int32 GroupIndex)

Removes the Group at GroupIndex from CycleName, then rebuilds.

FReply OnRemoveKeyframe(FName GroupName, FName ActionKey, int32 KeyIndex)

Removes keyframe KeyIndex from the Action (GroupName, ActionKey), then rebuilds.

FReply OnRemoveMapEntry(EActionMap Map, FName Key)

Removes the entry Key from the given Action map, then rebuilds.

FReply OnRemoveProximityTag(bool bEnter, int32 Index)

Removes the proximity Tag at Index, bEnter picks the Enter vs Leave list, then rebuilds.

void OnRenameActionKey(TSharedRef<FName> GroupNameH, TSharedRef<FName> ActionKeyH, const FText &NewText)

Renames an Action in place, with no rebuild: updates the data key, the row's expansion, and ActionKeyH.

void OnRenameMapKey(EActionMap Map, TSharedRef<FName> NameHandle, const FText &NewText)

Renames an entry in place, with no rebuild: updates the data key, NameHandle, and the expand keys.

void OnStateVectorCommitted(double NewValue, ETextCommit::Type CommitType, FName StateName, int32 Which, int32 Axis)

Commits one State Location or Rotation axis, final value, in a transaction.

void OnStateVectorSpin(double NewValue, FName StateName, int32 Which, int32 Axis)

Live spin-drag update of one State Location/Rotation axis (no transaction per frame).

void OnViewportTargetPicked(AActor *PickedActor, TFunction<void(const FString&)> OnPick)

Viewport eyedropper result: appends the picked Actor/Component as a Target token. Same Actor becomes "@<RootComponent>", external Actor becomes "%Tag" from its first "=" Tag.

void RenameCycleGroup(FName CycleName, int32 GroupIndex)

Renames the Group a Cycle step names, from that step's own row, routes via OnRenameMapKey.

void SetGlobalPropertySearchText(const FText &NewText)

Sets GlobalPropertySearchText and re-applies it, rebuilding first if the search changed what must be open.

void StartViewportTargetPick(TFunction<void(const FString&)> OnPick)

Enters the editor's actor-picking mode. Next viewport click becomes a Target token.

void ToggleExpanded(FName Key)

Toggles whether an entry row (keyed by a stable id) is expanded, then rebuilds.

Private Members

bool bInteractiveRebuildRequested = false

Set by RequestInteractiveRebuild, Tick coalesces it into one deferred RebuildInteractiveDetails.

TArray<TSharedPtr<class IDetailsView>> AdvancedViews

Native IDetailsView instances for the Advanced Group (alive across a rebuild).

TArray<FString> CachedComponentTokens

"@Name" for every scene Component on the owner, feeding internal Target chip resolution + suggestions.

TMap<FString, TArray<FString>> CachedExternalStateNames

State names each "%Tag" external Actor has, read from that Actor's own IC.

TArray<FString> CachedExternalTokens

"%Tag" for every addressable "=" Tag in the level, feeding external Target chip resolution + suggestions.

TMap<FString, TArray<FString>> CachedExternalVerbNames

Verb names each "%Tag" external Actor can run, read from that Actor's own IC.

  • A delegated "!Verb %Tag^" names a Group on the Target Actor. => Chip resolves such a verb instead of flagging a valid Tag as unresolved.

TSet<FString> CachedExternalWithIC

Subset of CachedExternalTokens whose Actor holds an Interactive Component.

  • A trailing "^" means "delegate the rest to that Actor's own IC", only meaningful here.

  • Offering "%Light^" for an Actor with no IC hands the user an address that cannot resolve.

  • Picker offers "%Light^" for these, and "%Light" for the rest.

TArray<FString> CachedStateNames

IC's own ActionState keys, feeding State chip resolution + suggestions.

TArray<FString> CachedVerbNames

IC's cycle + Group keys, feeding interaction-Tag verb chip resolution + suggestions.

TWeakObjectPtr<AActor> CurrentActor

Actor whose Details are shown.

TWeakObjectPtr<UMovaIxComponent> CurrentComponent

IC whose InteractiveDetails are shown.

TWeakObjectPtr<class UActorComponent> CurrentSelectedComp

Selected sub-Component, when a Component (not the Actor row) is selected, its transform drives Details.

TSharedPtr<SVerticalBox> DetailsBox

Container for the Details section widgets.

FText GlobalPropertySearchText

Global search box filtering every State/Group "More" field plus the Advanced section.

  • Only searches the native Details panel content, not this panel's own hand-built rows.

  • Non-empty text forces every State/Group and the Advanced section open, see IsExpandedForSearch.

TSharedPtr<SVerticalBox> InteractiveBox

Container for the InteractiveDetails section widgets.

float LastPanelWidth = 480.0f

Last painted panel width, driving the narrow/wide responsive layout.

TArray<TWeakObjectPtr<UMovaIxComponent>> LinkedComponents

Other selected ICs (multi-select), targeted by "Apply to N selected".

bool bNarrowLayout = false

True while the panel is too narrow for the wide layout: add buttons collapse, Target row wraps.

FMovaIxOnKeyframesChanged OnKeyframesChangedDelegate

Notifies the host that keyframe times changed, so it can refit the timeline.

FMovaIxOnTestGroup OnTestGroupDelegate

Host callback that previews a Group, driving the Group row's Test button.

bool bPreserveScaleRatio = false

If true, editing one Scale axis multiplies the other two by the same ratio, keeping proportions.

double StatePreSpinValue = 0.0

Value of the dragged ActionState axis at spin-start.

int32 StateSpinAxis = INDEX_NONE

Axis StatePreSpinValue belongs to, X/Y/Z.

FName StateSpinName

ActionState whose axis is being dragged.

int32 StateSpinWhich = INDEX_NONE

Which vector of that State is being dragged: Location, Rotation or Scale.

bool bStateTransformSliderActive = false

True while an ActionState spin-drag is mid-transaction, separate from bTransformSliderActive above.

TArray<TSharedPtr<IStructureDetailsView>> StructViews

Embedded struct property views (State + Group settings), alive across a rebuild, reset on the next one.

bool bTransformSliderActive = false

True while a transform spin-drag is mid-transaction, so a trailing commit does not open a second one.

TWeakPtr<IMenu> ViewportPickMenu

Popup a viewport pick opened, so committing can close that one menu.

  • Weak: the menu stack owns it, and a click elsewhere can dismiss it first.

Private Static Attributes

static TSet<FName> ExpandedRows

Per-row expansion State, keyed by a stable "section.key" id. Static makes the layout survive a widget rebuild, including leaving PIE.

Friends

friend class FMovaIxAddInteractionPopupLayoutTest
friend class FMovaIxBuilderTargetPickerTest
friend class FMovaIxCycleStepColoredRowTest
friend class FMovaIxCycleStepRepaintTest
friend class FMovaIxExternalTagCacheRefreshTest
friend class FMovaIxGroupLazyBodyTest
friend class FMovaIxGroupLazyCostTest
friend class FMovaIxPickerSectionOrderTest
friend class FMovaIxRenameGroupTest
friend class FMovaIxRenameStateTest
friend class FMovaIxStateSpinCrossFieldTest
friend class FMovaIxViewportPickClosesTest
friend class FMovaIxViewportPickComponentTest
friend class FMovaIxViewportPickEmptyExternalTest
friend class FMovaIxViewportPickPerSectionTest
friend class FMovaIxViewportPickResolvesTest
friend class FMovaIxViewportPickShared
friend class FMovaIxViewportPickUncoversTest

Timeline widget

class SMovaIxTimeline : public SLeafWidget
#include <MovaIxTimeline.h>

Slate timeline widget for the Interactive Control Panel. Renders keyframe markers and a scrub cursor, and handles the mouse.

  • Right-click menu deletes a keyframe or types an exact time.

  • Cursor position rounds to 0.1s.

  • Hold Shift for full precision.

Keyframe diamonds are hit-tested in both X and Y, not X by itself.

  • A click landing ON a diamond grabs and drags it.

  • Cursor becomes EMouseCursor::GrabHand.

  • A click anywhere else, including directly above or below a diamond, scrubs the playhead.

Public Functions

DECLARE_DELEGATE_OneParam(FOnKeyframeAdd, float)

Typed callback: requests a new keyframe at a time in seconds. Right-click on empty track.

DECLARE_DELEGATE_OneParam(FOnKeyframeClicked, float)

Typed callback: passes the time in seconds of the left-clicked keyframe.

DECLARE_DELEGATE_OneParam(FOnKeyframeRightClicked, float)

Typed callback: passes the time in seconds of the right-clicked keyframe.

DECLARE_DELEGATE_TwoParams(FOnKeyframeMoved, float, float)

Typed callback: a keyframe is moving from OldTime to NewTime.

  • Fired continuously while dragging.

  • OldTime updates to match each call.

  • A find-by-time lookup keeps matching the keyframe it is already moving.

  • Also fired once, a single OldTime -> NewTime jump, on an exact time typed in the menu.

DECLARE_DELEGATE_OneParam(FOnScrubbed, float)

Typed callback: normalized alpha 0.0 to 1.0 while the user scrubs.

DECLARE_DELEGATE_RetVal_OneParam(FText, FOnKeyframeTooltip, float)

Typed callback: tooltip text for the keyframe at a time, respecting the active filters.

inline SLATE_BEGIN_ARGS(SMovaIxTimeline)
virtual FVector2D ComputeDesiredSize(float LayoutScaleMultiplier) const override

Sorted list of keyframe timestamps to render as markers. Total duration of the timeline in seconds. Returns the current normalized preview alpha, 0.0 to 1.0. Called when the user right-clicks empty track to add a keyframe.

  • Passes the time in seconds. Called when the user left-clicks a keyframe marker, on mouse down, before any drag.

  • Passes the time in seconds of the clicked keyframe. Called continuously while the user drags a keyframe marker to a new time.

  • Called once more when they commit an exact time in the right-click menu's time field. Called once when a keyframe drag ends, for the owner to do one full data refresh. Called when the user right-clicks a keyframe marker.

  • Passes the time in seconds of the clicked keyframe. Called to build the hovered keyframe's tooltip: Time plus the Action Targets at that time. Called when the user scrubs the timeline, by click or by drag.

  • Passes a normalized alpha, 0.0 to 1.0. Called when the user releases the scrub.

virtual FCursorReply OnCursorQuery(const FGeometry &MyGeometry, const FPointerEvent &CursorEvent) const override
virtual FReply OnMouseButtonDown(const FGeometry &MyGeometry, const FPointerEvent &MouseEvent) override
virtual FReply OnMouseButtonUp(const FGeometry &MyGeometry, const FPointerEvent &MouseEvent) override
virtual void OnMouseLeave(const FPointerEvent &MouseEvent) override
virtual FReply OnMouseMove(const FGeometry &MyGeometry, const FPointerEvent &MouseEvent) override
virtual int32 OnPaint(const FPaintArgs &Args, const FGeometry &AllottedGeometry, const FSlateRect &MyCullingRect, FSlateWindowElementList &OutDrawElements, int32 LayerId, const FWidgetStyle &InWidgetStyle, bool bParentEnabled) const override
inline virtual bool SupportsKeyboardFocus() const override
void Construct(const FArguments &InArgs)

Builds the timeline widget: caches the argument rules and the event bindings.

Private Functions

FText GetHoveredKeyframeTooltip() const

Tooltip text for the keyframe currently hovered, or empty when none is.

float HitTestKeyframeXY(float LocalX, float LocalY, float Width, float Height) const

Keyframe time at (LocalX, LocalY) when within the diamond's hit radius on both axes, else -1.0f.

  • X-only proximity does not count as a hit.

  • Ex: directly above or below a diamond.

  • Drives left-click drag-start, right-click hit detection, and cursor feedback.

float LocalXToAlpha(float LocalX, float Width) const

Converts a local X pixel position to a normalized alpha, 0.0 to 1.0.

float RoundTime(float TimeSeconds, bool bHighPrecision) const

Rounds a time value to the nearest 0.1s step.

  • Full precision is preserved when bHighPrecision is set, which is Shift held.

void ScrubToLocalX(float LocalX, const FGeometry &MyGeometry, bool bHighPrecision)

Fires OnScrubbed with the alpha at a local X position.

Private Members

float DragCurrentTime = -1.0f

Dragged keyframe's current authoritative time, matching what the owner's data holds.

  • Starts equal to DragSourceKFTime, then updates every move.

  • Each OnKeyframeMoved's OldTime keeps matching the value the owner stored last.

  • Also the position the dragged diamond is drawn at.

bool bDragging = false

Whether the user is dragging the scrub cursor, as opposed to dragging a keyframe.

bool bDraggingKeyframe = false

Whether the user is dragging a keyframe marker to a new time.

  • Mutually exclusive with bDragging.

  • A drag is either the scrub cursor or a keyframe, not both.

float DragSourceKFTime = -1.0f

Keyframe's time as it exists in the KeyframeTimes array, which does not change until drag end.

  • Fixed for the whole drag.

  • It only finds which entry of that array to substitute visually in OnPaint.

float HoveredKFTime = -1.0f

Time in seconds of the keyframe under the mouse, or -1.0f when there is none.

float HoverTime = -1.0f

Time in seconds under the mouse cursor on a free hover, or -1.0f when not hovering.

TArray<float> KeyframeTimes

Sorted keyframe timestamps.

float MaxDuration = 1.0f

Total duration in seconds.

FOnKeyframeAdd OnKeyframeAddDelegate

Called to add a keyframe at a time. Right-click on empty track.

FOnKeyframeClicked OnKeyframeClickedDelegate

Called when a keyframe is left-clicked.

  • Passes the time in seconds.

FSimpleDelegate OnKeyframeDragEndDelegate

Called once when a keyframe drag ends.

FOnKeyframeMoved OnKeyframeMovedDelegate

Called continuously while dragging a keyframe.

  • Called once more for an exact-time menu commit.

FOnKeyframeRightClicked OnKeyframeRightClickedDelegate

Called when a keyframe is right-clicked.

  • Passes the time in seconds.

FOnKeyframeTooltip OnKeyframeTooltipDelegate

Called to build the hovered keyframe's tooltip text.

FOnScrubbed OnScrubbedDelegate

Called when scrubbing.

  • Passes the normalized alpha.

FSimpleDelegate OnScrubReleasedDelegate

Called when the scrub is released.

TAttribute<float> PreviewAlpha

Normalized preview cursor position, 0.0 to 1.0.

Presets

struct FMovaIxComponentTags
#include <MovaIxPresets.h>

Component tags captured into a preset, keyed by Component name.

Public Members

TArray<FName> Tags

Component's tags.

  • Each may itself be a space-separated interaction Tag string.

class UMovaIxPresetData : public UObject
#include <MovaIxPresets.h>

Transient holder for a preset's full Action bundle. Bound to a details view in the Manage Presets window.

  • Presets can be edited with the same property editors used by the InteractiveComponent itself.

Public Members

TMap<FName, FMovaIxActionCycle> ActionCycles

Map of interaction sequences that step over multiple Groups.

TMap<FName, FMovaIxActionGroup> ActionGroups

Map of parallel Action definitions.

TMap<FName, FMovaIxActionState> ActionStates

Library of reusable State snapshots for keyframes.

TMap<FName, FMovaIxComponentTags> ComponentTags

Tags of every Component on the source Actor, keyed by Component name.

FMovaIxProximity Proximity

Full proximity block, mirroring UMovaIxComponent::Proximity.

class SMovaIxPresetsWindow : public SCompoundWidget
#include <MovaIxPresets.h>

Manage Presets window:

  • Lists presets.

  • Creates one from the current selection.

  • Edits a preset's Action bundle in a details view, plus rename, save and delete.

Public Functions

inline SLATE_BEGIN_ARGS(SMovaIxPresetsWindow)
void Construct(const FArguments &InArgs)

Called whenever the saved preset files change: save, delete or rename. Builds the presets window widget tree.

Public Static Functions

static void OpenWindow(FSimpleDelegate OnPresetsChanged = FSimpleDelegate())

Opens the singleton Manage Presets window, or focuses it when it is already up.

Private Functions

TSharedPtr<SWidget> BuildRowContextMenu()

Right-click menu for a preset row, with Duplicate.

  • Null for Current and Header rows.

UMovaIxComponent *GetSelectedActorIC() const

InteractiveComponent of the currently selected editor Actor, or null.

void NotifyChanged()

Notifies listeners that the saved preset files changed.

  • Ex: the control panel.

FReply OnDeleteClicked()

Deletes the selected user preset.

  • Built-ins are protected.

void OnDuplicateSelected()

Duplicates the selected preset into a new user preset.

TSharedRef<ITableRow> OnGenerateRow(TSharedPtr<MovaIx::Presets::FMovaIxPresetInfo> Item, const TSharedRef<STableViewBase> &OwnerTable)

Generates a row widget for a preset entry in the list view.

FReply OnNewClicked()

Starts a new blank preset in the editor.

FReply OnSaveClicked()

Saves the edited data as a user preset under the entered name.

void OnSelectionChanged(TSharedPtr<MovaIx::Presets::FMovaIxPresetInfo> Item, ESelectInfo::Type SelectInfo)

Loads the selected preset into the editor, or the live IC data for the Current row.

void PopulateFromCurrentSelection()

Fills EditData from the currently selected Actor's InteractiveComponent.

void RefreshPresetList()

Rebuilds the grouped preset list: Current, User, Built-in.

void SelectItemByName(const FString &Name)

Selects a list item by name.

  • Ex: after a save or a duplicate.

Private Members

TStrongObjectPtr<UMovaIxPresetData> EditData

Transient object edited by the details view.

TSharedPtr<SEditableTextBox> NameTextBox

Editable preset name input box.

FSimpleDelegate OnPresetsChangedDelegate

Fired when presets change: the owning panel can refresh its combo box.

TSharedPtr<IDetailsView> PresetDetailsView

Details view bound to EditData for inline preset editing.

TArray<TSharedPtr<MovaIx::Presets::FMovaIxPresetInfo>> PresetItems

Backing data array for the preset list view.

TSharedPtr<SListView<TSharedPtr<MovaIx::Presets::FMovaIxPresetInfo>>> PresetListView

Preset list widget.

TSharedPtr<MovaIx::Presets::FMovaIxPresetInfo> SelectedPreset

Currently selected preset, when there is one.

bool bShowBuiltIn = true

Show built-in presets in the list.

Private Static Attributes

static TWeakPtr<SWindow> PresetsWindowPtr

Weak handle to the singleton hosting window, for focus and close management.

namespace MovaIx
namespace Presets

Enums

enum class EMovaIxPresetKind : uint8

Row category in the Manage window list.

Values:

enumerator Header

Non-selectable Group separator.

enumerator BuiltIn

Read-only plugin preset.

enumerator Current

Live data from the selected IC.

enumerator User

Writable project preset.

Functions

bool ApplyPresetToComponent(const FString &FilePath, UMovaIxComponent *IC)

Applies a preset file onto an InteractiveComponent, replacing its existing Action data.

  • Caller owns the surrounding transaction and Modify().

Returns:

True on success.

bool ApplyPresetToComponentRemapped(const FString &FilePath, UMovaIxComponent *IC, const TMap<FName, FName> &Mapping)

Applies a preset onto an IC, renaming the preset's Component names as it goes.

  • User maps the preset's names onto their own Components once.

  • Every address that mentions them is rewritten to match.

Substitution is applied everywhere an address can live:

  • Component tags, Action Targets, Group OffsetTarget.

  • Authorized/Disallowed State lists, proximity Enter/Leave tags.

  • Captured component-Tag map's own keys.

Parameters:
  • FilePath -- Preset file to apply.

  • IC -- Destination Component. Caller owns the transaction and Modify().

  • Mapping -- Preset name -> name on the destination Actor.

    • An entry mapping a name to itself, to NAME_None or to an empty name is skipped.

    • That is how the dialog expresses "leave this one unresolved".

Returns:

True on success.

bool DeleteUserPreset(const FString &FilePath)

Deletes a user preset file. Built-ins cannot be deleted.

Returns:

True on success.

FString DuplicateToUserPreset(const FString &SourceFilePath, const FString &DesiredName)

Copies any preset to a new user preset, auto-suffixing the name when it collides.

Returns:

The new name.

void GatherUnresolvedPresetNames(const FString &FilePath, const UMovaIxComponent *IC, TArray<FString> &OutMissingComponents, TArray<FString> &OutMissingTargets)

Checks whether every Component name and action-Target token a preset references exists on the Actor.

  • Populates the 2 out-arrays with whatever could not be resolved.

  • Both empty means a clean apply.

FString GetBuiltInPresetsDir()

Built-in presets folder shipped inside the plugin.

  • Read-only.

FString GetUserPresetsDir()

Writable project/user presets folder: <Project>/_Ix/Presets/.

TArray<FMovaIxPresetInfo> ListPresets()

Lists every preset from the plugin and the project folders, sorted by name.

  • A user preset replaces a built-in preset that shares its name.

bool LoadPresetIntoData(const FString &FilePath, UMovaIxPresetData *OutData)

Loads a preset JSON file into a preset data object for editing.

Returns:

True on success.

int32 RemapBundleNames(const TMap<FName, FName> &Mapping, TMap<FName, FMovaIxActionCycle> &Cycles, TMap<FName, FMovaIxActionGroup> &Groups, TMap<FName, FMovaIxActionState> &States, TMap<FName, FMovaIxComponentTags> &ComponentTags, FMovaIxProximity &Proximity)

Rewrites every address in a loaded bundle, renaming Components of the current Actor.

Returns:

Number of individual fields changed.

bool SaveUserPreset(const FString &Name, const FString &JsonString, FString &OutPath)

Saves a JSON bundle as a user preset named Name, overwriting any existing one.

Parameters:

OutPath -- Receives the absolute path written to.

Returns:

True on success.

FString SerializeComponent(const UMovaIxComponent *IC)

Serializes an InteractiveComponent's full Action bundle to a JSON string.

FString SerializePresetData(const UMovaIxPresetData *Data)

Serializes a preset data object's full Action bundle to a JSON string.

struct FMovaIxPresetInfo
#include <MovaIxPresets.h>

A single discoverable preset file, or a list pseudo-entry.

Public Members

bool bBuiltIn = false

True when it ships with the plugin, which makes it read-only.

  • False for project and user presets.

FString FilePath

Absolute path to the .json file.

  • Empty for Current and Header.

EMovaIxPresetKind Kind = EMovaIxPresetKind::User

Row category.

FString Name

Display name, the file name without its extension.

The preset remap dialog (MovaIxPresetRemapDialog.h) extends the same MovaIx::Presets namespace shown above.

Commands, menu, style, visualizers

class FMovaIxCommands : public TCommands<FMovaIxCommands>
#include <MovaIxCommands.h>

Defines all editor commands for Mova Interact. These commands drive the menu entries, the toolbar buttons and the keyboard shortcuts.

Public Functions

FMovaIxCommands()
virtual void RegisterCommands() override

Registers all commands.

Public Members

TSharedPtr<FUICommandInfo> ExportJSON

Export all Actions to JSON.

TSharedPtr<FUICommandInfo> ImportJSON

Import all Actions from JSON.

TSharedPtr<FUICommandInfo> OpenSettings

Open the Mova Interact settings.

TSharedPtr<FUICommandInfo> Validate

Validate all Mova Interact objects in the current level.

class UMovaIxMenu : public UObject
#include <MovaIxMenu.h>

Editor-only utility class that provides menu entries for exporting/importing Actions from placed interactive Actors:

  • ActionCycles.

  • ActionGroups.

  • ActionStates.

class FMovaInteractStyle
#include <MovaIxStyle.h>

Custom style set for the MovaInteract plugin.

  • Provides icons for menu entries and submenus.

Public Static Functions

static FString EnsureHexTextStyle(const FString &Hex, bool bLight)

Registers a tooltip text style for one hex tint, unless it is registered already.

Parameters:
  • Hex -- Color, "#" optional.

    • Long form: "rrggbb" or "rrggbbaa".

    • Short form: "rgb" or "rgba"..

  • bLight -- Which tooltip theme the style belongs to.

Returns:

Style name to put in a run, empty when Hex does not parse.

static const ISlateStyle &Get()

Accesses the singleton instance of the style set.

static FName GetStyleSetName()

Retrieves the unique identifier name for this style set.

static void Initialize()

Initializes the style set and registers it with the Slate Style Registry.

static void Shutdown()

Unregisters the style set and cleans up the StyleInstance.

Private Static Functions

static TSharedRef<FSlateStyleSet> Create()

Creates and configures the style set, defining paths for icons and brushes.

Private Static Attributes

static TSharedPtr<FSlateStyleSet> StyleInstance

Singleton instance of the Slate style set.

class FMovaIxComponentVisualizer : public FComponentVisualizer
#include <MovaIxComponentVisualizer.h>

Draws the interaction badges and the animation preview for an Interactive Component.

Public Functions

virtual void DrawVisualization(const UActorComponent *Component, const FSceneView *View, FPrimitiveDrawInterface *PDI) override

Draws the keyframe ghosts, the motion path and the proximity volume in the viewport.

virtual void DrawVisualizationHUD(const UActorComponent *Component, const FViewport *Viewport, const FSceneView *View, FCanvas *Canvas) override

Draws the screen-space text: the keyframe badges and the [TAG] / [Target] labels.

virtual bool VisProxyHandleClick(FEditorViewportClient *InViewportClient, HComponentVisProxy *VisProxy, const FViewportClick &Click) override

Handles a click on a [TAG] / [Target] badge: selects that Component.

  • Clicking a badge in the viewport is equivalent to clicking the Control Panel row.

Private Functions

void DrawChoicePreview(UMovaIxComponent *IC, const FSceneView *View, FCanvas *Canvas)

Draws the numbered choice-list preview from each interactive Point on IC, ex: "1 OpenLeft / 2 CloseLeft / 3 OpenRight", matching the real in-game prompt without Play.

  • Reuses UMovaIxInteractorComponent::BuildPromptChoices on an unregistered instance, never ticked.

void DrawTagTargetLabels(UMovaIxComponent *IC, const FSceneView *View, FCanvas *Canvas)

Draws a colored [TAG] / [Target] badge over every scene Component of the IC's owner.

  • Colors match the ones the Control Panel hierarchy uses.

  • Each badge holds a hit proxy, so it is clickable.

void RestoreRealComponents()

Restores Components moved by the "animate real component" preview to their saved transforms.

Private Members

TMap<TWeakObjectPtr<USceneComponent>, FTransform> RealAnimSavedTransforms

Relative transforms saved before the "animate real component" preview moved anything.

class FMovaIxInteractorVisualizer : public FComponentVisualizer
#include <MovaIxInteractorVisualizer.h>

Draws an interactor's detection volume in the editor viewport: reach is visible while placing it.

  • Registered against UMovaIxInteractorComponent.

  • Shows the DetectionRadius sphere and the ViewAngle cone along the owner's forward.

  • During play it also draws a highlight line to the currently-focused interactable (GetCurrentPoint).

Public Functions

virtual void DrawVisualization(const UActorComponent *Component, const FSceneView *View, FPrimitiveDrawInterface *PDI) override