I mostly separate the UI design proces from the programming by binding optional widgets from the blueprint designer to a pointer in c++. If you are not familiar with such pointer property, it looks like this:
UPROPERTY(meta = (BindWidgetOptional))
UMyWidget* MyWidget = nullptr;
This works very well except that if you bind a ton of widgets this way, you end up with a ton of pointers. Meaning you have to constantly check the pointers before accessing your widget data.
The normal way:
if (IsValid(A)) {
A->SetVisibility(NewVisibility);
}
if (IsValid(B)) {
B->SetVisibility(NewVisibility);
}
if (IsValid(C)) {
C->SetVisibility(NewVisibility);
}
if (IsValid(D)) {
D->SetVisibility(NewVisibility);
}
The typing less way:
auto TrySetVisibility = [&NewVisibility] (UWidget* InWidget) {
if (IsValid(InWidget)) {
InWidget->SetVisibility(NewVisibility);
}
};
TrySetVisibility (A);
TrySetVisibility (B);
TrySetVisibility (C);
TrySetVisibility (D);
// Doing it in a loop would require you to actually know what panel they are on, or add an array of widgets, which is out of the question.
Not a big deal, unless you are working with an amount of widgets this is going to cost too much time or were a copy pasta mistake is likely.
Getting creative…
UObject* A = nullptr;
UObject* B = nullptr;
UObject* C = nullptr;
auto Test = [](UObject& InObject) -> bool {
// dostuff
return true;
};
auto DoIfValid = [](UObject* InObject, auto&& InFunc) {
if (IsValid(InObject)) {
return InFunc(*InObject);
}
};
bool X = DoIfValid(A, Test);
DoIfValid(B, Test);
DoIfValid(C, Test);
Lambdas… Templates… What is your recommended way in 2023?