I have a custom UWidget that correctly calls SynchronizeProperties to update the backing SWidgets proeprties when the properties are changed in the UMG editor.
However despite setting up the SLATE_ARGUMENT, TSlateAttribute, and PrivateRegisterAttributes declarations the widget doesn’t visually update until you recompile.
I’ve stepped through the code at runtime, and the underlying slate’s property does update. It’s just the EInvalidateWidgetReason::Layout doesn’t seem to have any impact. I thought that invalidating the layour would re call construct
What am I missing in order to get the widget to update in the editor without having to recompile every time?
/* In the UWidget */
void UCarousel::SynchronizeProperties() {
Super::SynchronizeProperties();
if (slateBacking.IsValid()) {
slateBacking->SetIsTest(isTest);
}
}
I’ve looked into utilizing the PostEditChangeProperty to manually force a rebuild of the slate structure but I don’t think that’s the solution to my underlying issue. I’ve come to this conclusion after reviewing much of the UMG/Slate source code as the PostEditChangeProperty is generally only used to perform data validation and then (usually) calls SynchronizeProperties itself which places me in the same position.
The reality is despite using TSlateAttribute and SLATE_ADD_MEMBER_ATTRIBUTE_DEFINITION with my synced properties, they’re not triggering their invalidation/dirty correctly. If I were to manually force a rebuild in the editor it wouldn’t address the underlying issue which is likely to pop up at runtime too.
I’m certainly missing some macro, declaration, or overridable function I’m just not able to locate it.
Ironically the most success I’ve had was to revert to the old way of managing slate attributes by not using TArrtibute or TSlateAttribute at all…
(All this pain because widget switchers are fundamentally flawed and don’t set their non-visible children as disabled/collapsed or trigger the “Construct”/“Destruct” events when they’re shown/hidden like other slots.)
In addition to what I had in my first post, I also needed to do the following:
Change the function void SCarousel::SetIsTest(bool value); to void SCarousel::SetIsTest(TAttribute<bool> value);
Created a TSlateAttribute<FSlateColor> color; attribute to bind the changed color to as isTest was a bool flag. (only needed as i used color, the existing assign would work file if passing the color in instead of a bool.)
In SCarousel::Construct don’t use args._isTest or isTest directly, instead pass args._isTest into the SetIsTest(TAttribute<bool> value) function and use a TAttribute constructed with a lambda in any property assignments. EG:.ColorAndOpacity(TAttribute<FSlateColor>::Create([this]() { return color.Get(); }))
In the SCarousel::SetIsTest(TAttribute<bool> value); function, add an assign for the new color attribute using a TAttribute::Create lambda expression to perform the actual color selection.
Example below also added a padding parameter to show direct consumption unlike the color which required an extra parameter.
After these additional changes, when i make changes to the properties in the editor, they update immediately. I don’t know if it’s ‘correct’, but it functions the same as the other widgets and doesn’t require manually updating the widget tree via editor only functions.