Add's support for `[at]editable` on optionals:
`FOptionalProperty` changes:
- Added custom `__INIT__` logic for `FOptionalProperty::ExportText` which previously could output no text as the optional value was initialized but returned an empty string as its export text (ie: empty arrays, maps, sets, etc). This caused the future text imports to be incorrect.
`FPropertyNode` changes:
- Added `OptionalValueNode` as private member similar in idea to existing `PropertyKeyNode`. It stores the generated `FPropertyNode` for a FOptionalValue's Value when it is set.
- Added helper function `GetOrCreateOptionalValueNode` which either returns the existing `OptionalValueNode` OR creates one if appropriate.
- Note: This is where we bind a lambda to our Optional's Value FPropertyNode's `RebuildChildren` event which is how we update/rebuild when needed. In places where we would update/rebuild we instead call our Value to do so instead if set and then update after that has been done via this callback.
Added new widget `SPropertyEditorOptional`
- This either:
- shows a dropdown of "Set all" or "Unset all" if we have multiple values selected
- generates the editor for whatever our set value is if we have a single value (See `GetSingleReadAddress`)
- shows a 'set value' button if we are not set
#JIRA UE-191200
#rb karen.jirak
#rb kurtis.schmidt
[CL 28253719 by jared cotton in ue5-main branch]
There's a window after undo (between undo and next property view tick) where property nodes point to the previous data.
If e.g. a property customization needs to refresh cached data after undo, they will try to access the data via old pointers.
Similar issue happens when removing item from array, the tick of IDetailCustomNodeBuilder gets called before we have updates the property nodes.
All these issues happen because when we update the child nodes, there are some parts of code that still hold hard refereces to them, and they are not
actually cleared on FPropertyNode::DestroyTree(). That in turn will cause IPropertyHandle to be in valid state, but pointing to data that has been freed.
- Added bIsDestroyed on property nodes to be able distinguish property nodes which are still alive but destoyed
- Prevent calling Tick() on property tree nodes, whose property node is destroyed
- Changed Gameplay Tag, Tag Container and Query to poll for changes, because undo callbacks are triggered at times when the property handle (and underlying node) is pointing to old data
- The above gameplay tag & co change will also react to property changes from outside the details panel
#jira UE-188117 UE-190882
[CL 27705747 by mikko mononen in ue5-main branch]
[FYI] mikko.mononen
Original CL Desc
-----------------------------------------------------------------
Prevent accessing of invalid property nodes after undo and redo.
There's a window after undo (between undo and next property view tick) where property nodes point to the previous data.
If e.g. a property customization needs to refresh cached data after undo, they will try to access the data via old pointers.
Similar issue happens when removing item from array, the tick of IDetailCustomNodeBuilder gets called before we have updates the property nodes.
All these issues happen because when we update the child nodes, there are some parts of code that still hold hard refereces to them, and they are not
actually cleared on FPropertyNode::DestroyTree(). That in turn will cause IPropertyHandle to be in valid state, but pointing to data that has been freed.
- Detach property nodes recursively on FPropertyNode::DestroyTree(), also clearing parent pointers to that the invlidate property path cannot be followed.
- Call update view (same as tick) after undo to invalidate property nodes which do not point to correct memory anymore
- Use FEditorDelegates::PostUndoRedo instead of undo client, as in some rare cases with consequtive undo/redo the undo client callbacks get called on a stale pointer
- Postpone gameplay tag caching to next tick, since the delegates are called in reverse and SDetailsView gets OnUndoRedo gets called after out customization
#jira UE-190882
[CL 27169489 by mikko mononen in ue5-main branch]
There's a window after undo (between undo and next property view tick) where property nodes point to the previous data.
If e.g. a property customization needs to refresh cached data after undo, they will try to access the data via old pointers.
Similar issue happens when removing item from array, the tick of IDetailCustomNodeBuilder gets called before we have updates the property nodes.
All these issues happen because when we update the child nodes, there are some parts of code that still hold hard refereces to them, and they are not
actually cleared on FPropertyNode::DestroyTree(). That in turn will cause IPropertyHandle to be in valid state, but pointing to data that has been freed.
- Detach property nodes recursively on FPropertyNode::DestroyTree(), also clearing parent pointers to that the invlidate property path cannot be followed.
- Call update view (same as tick) after undo to invalidate property nodes which do not point to correct memory anymore
- Use FEditorDelegates::PostUndoRedo instead of undo client, as in some rare cases with consequtive undo/redo the undo client callbacks get called on a stale pointer
- Postpone gameplay tag caching to next tick, since the delegates are called in reverse and SDetailsView gets OnUndoRedo gets called after out customization
#jira UE-190882
[CL 27098189 by mikko mononen in ue5-main branch]
This fixes the case that the address pointed by a structure provider changes outside the usual editor functionality.
#preflight 646492952d446eac96a704e3
[CL 25504258 by mikko mononen in ue5-main branch]
- Added IStructureProvider which allows to edit multiple instances of structs at a time
- Improved default value handling in standalone structure nodes
- Fixed bug where expanded nodes did not retain their expansion state when structure nodes were rebuild (e.g. when editing a component)
- Removed caching from Instanced struct customization
#jira UE-172047
#rb Jamie.Dale, Adrien.Logut
#preflight 644a48360f12404fb77173f6
[CL 25214019 by mikko mononen in ue5-main branch]
Add the ability to add customizations via property handle that disable object instancing logic associated with CPF_InstancedReference
[REVIEW] [at]marcus.wassmer
#rb jp.flouret,marcus.wassmer,dan.oconner
#preflight 6401477c1d304a54717d2953
#localization none
#tests all relevant operations on array and non-array editable versedevices in the details panel
#preferred_allowlister marcus.wassmer
[CL 24494803 by marcus wassmer in ue5-main branch]
This fixes nodes not rebuilding when there are multiple listeners.
E.g. FDetailArrayBuilder generating a row that contains instanced object property. Previously changing the object instance would "freeze" the array builder.
#rb Sebastian.Nordgren
#preflight 63e4b920902d6ba787efe0e6
[CL 24094515 by mikko mononen in ue5-main branch]
For this, as the children of a property node were built, the value of the Expanded flag was not passed from the old child to the rebuilt one. The fix is to, in rebuildChildren in PropertyNode.cpp, save off the property paths of the expanded children prior to the rebuild, and post rebuild of the children, if the property path of a new child is in the saved expansion paths, set the child's expanded flag to true, as well.
#jira UE-170440
#rb sebastian.nordgren
#preflight 6398b41a2540a78d272bd90c
[CL 23494250 by karen jirak in ue5-main branch]
When FPropertyNode::EnsureDataIsValid() returns ChildrenRebuilt, it was only marking itself as bChildrenRebuilt = false.
SDetailsViewBase now calls FPropertyNode::MarkChildrenAsRebuilt, which recursively clears the flag from everything.
[REVIEW] [at]lauren.barnes, [at]patrick.boutot, [at]jay.nakai
#preflight 635a889e0d3a231123cb1f6c
[CL 22810916 by sebastian nordgren in ue5-main branch]
In PropertyNode::FilterNodes, filter the property key node, if present, to prevent this.
#jira: UE-165084
#rb sebastian.nordgren
#preflight 63497bbace524ed356e3c61c
[CL 22580642 by karen jirak in ue5-main branch]
This is particularly useful for details panel external structures/objects, as these don't have the "PostEditChange" calls bubble up to the actual owning object.
This enables us to detect whether an interactive change or a direct set change has taken place on an external property, so we can manually call NotifyPostChange with the correct data
#jira none
#rb vincent.gauthier
#preflight skip
[CL 21200722 by Mateo Egey in ue5-main branch]
We already had a ParentNodeWeakPtr that we were checking to make sure the pointer was valid - now we just use that value directly instead.
#review-20890479 @lauren.barnes
#rnx
#preflight 62bef0445d53ca5bcea7785a
[CL 20913710 by sebastian nordgren in ue5-main branch]