SwitchByte will take less memory than SwitchInt
(SwitchWildcard This is already a show off)
this function should be in Ue4
// Переназначить поведение навигации получив виджет для курсора
UFUNCTION(Category="IVS|Set", BlueprintCallable, BlueprintCosmetic, Meta=(DefaultToSelf="Widget")) static void EscapeNavigation(UWidget* Widget, EUINavigation Direction, UWidget*& R);
void UILbr::EscapeNavigation(UWidget * Widget, EUINavigation Direction, UWidget * & R) {
FVector2D Position = Widget -> GetCachedWidget() -> GetPaintSpaceGeometry().GetAbsolutePosition(), NewPosition, OldPosition;
FVector2D Size = Widget -> GetCachedWidget() -> GetPaintSpaceGeometry().GetAbsoluteSize(), NewSize, OldSize;
TSharedPtr < SWidget > C;
UWorld *
const World = GEngine -> GetWorldFromContextObject(Widget, EGetWorldErrorMode::ReturnNull);
if (!World) {
return;
}
bool expr = false;
auto F {
[](UWidget * R, float NewP, float OldP, float New, float Old, float Pos, bool & expr) {
if (expr && IsValid(R)) {
expr = NewP > OldP || (NewP == OldP && abs(New - Pos) < abs(Old - Pos));
}
}
};
for (TObjectIterator < UWidget > Itr; Itr; ++Itr) {
if (Itr -> GetWorld() != World || * Itr == Widget) {
continue;
}
// GetCachedWidget() получить ссылку. TakeWidget() получить ссылку, при неудаче создает SWidget
C = Itr -> GetCachedWidget();
if (C.IsValid() && C -> GetVisibility().IsVisible() && C -> SupportsKeyboardFocus()) {
NewPosition = C -> GetPaintSpaceGeometry().GetAbsolutePosition();
NewSize = C -> GetPaintSpaceGeometry().GetAbsoluteSize();
//X длина. Y Высота. Отсчёт сверху слева. Элементы могут перекрываться так что Size не используем)IsInteractable
switch (Direction) {
case EUINavigation::Left:
expr = NewPosition.X + NewSize.X <= Position.X;
F(R, NewPosition.X + NewSize.X, OldPosition.X + OldSize.X, NewPosition.Y, OldPosition.Y, Position.Y, expr);
break;
case EUINavigation::Right:
expr = NewPosition.X >= Position.X + Size.X;
F(R, OldPosition.X + OldSize.X, NewPosition.X + NewSize.X, NewPosition.Y, OldPosition.Y, Position.Y, expr);
break;
case EUINavigation::Up:
expr = NewPosition.Y + NewSize.Y <= Position.Y;
F(R, NewPosition.Y + NewSize.Y, OldPosition.Y + OldSize.Y, NewPosition.X, OldPosition.X, Position.X, expr);
break;
case EUINavigation::Down:
expr = NewPosition.Y >= Position.Y + Size.Y;
F(R, OldPosition.Y + OldSize.Y, NewPosition.Y + NewSize.Y, NewPosition.X, OldPosition.X, Position.X, expr);
}
if (expr) {
R = * Itr;
OldPosition = NewPosition;
OldSize = NewSize;
}
}
}
}