Move focus failing animation

This commit is contained in:
Daniil Vinogradov
2025-02-23 22:25:11 +01:00
parent fbfd241521
commit d04bb3acb3
6 changed files with 57 additions and 7 deletions
+1
View File
@@ -69,6 +69,7 @@ public:
virtual void willGainFocus();
virtual void willLoseFocus();
virtual void focusFailedToMove(UIFocusHeading heading);
virtual void willChangeFocusHighlight(bool highlighted);
virtual void willChangeHighlight(bool highlighted);
+12 -3
View File
@@ -47,9 +47,14 @@ void UIControl::didUpdateFocusIn(UIFocusUpdateContext context, UIFocusAnimationC
UIView::didUpdateFocusIn(context, coordinator);
if (context.nextFocusedItem().lock() == shared_from_this()) {
coordinator->addCoordinatedAnimations([this]() {
willGainFocus();
});
// If previous and next focus items are the same, means that navigation failed
if (context.previouslyFocusedItem().lock() == context.nextFocusedItem().lock()) {
focusFailedToMove(context.focusHeading());
} else {
coordinator->addCoordinatedAnimations([this]() {
willGainFocus();
});
}
} else {
coordinator->addCoordinatedAnimations([this]() {
_state[uint8_t (UIControlState::highlighted)] = false; // need to be revised
@@ -76,6 +81,10 @@ void UIControl::willLoseFocus() {
layer()->setZPosition(0);
}
void UIControl::focusFailedToMove(UIFocusHeading heading) {
}
void UIControl::willChangeFocusHighlight(bool highlighted) {
if (highlighted) {
setTransform(NXAffineTransform::scale(1.02f));
+9 -3
View File
@@ -95,7 +95,9 @@ void UIFocusSystem::sendEvent(const std::shared_ptr<UIEvent>& event) {
}
}
if (nextItem.expired()) return;
if (nextItem.expired()) {
nextItem = _focusedItem;
}
context._nextFocusedItem = nextItem;
applyFocusToItem(nextItem.lock(), context);
@@ -124,8 +126,12 @@ void UIFocusSystem::applyFocusToItem(const std::shared_ptr<UIFocusItem>& item, U
UIFocusAnimationCoordinator coordinator;
_focusedItem = item;
if (!context.previouslyFocusedItem().expired()) { context.previouslyFocusedItem().lock()->didUpdateFocusIn(context, &coordinator); }
if (!context.nextFocusedItem().expired()) { context.nextFocusedItem().lock()->didUpdateFocusIn(context, &coordinator); }
if (context.previouslyFocusedItem().lock() == context.nextFocusedItem().lock()) {
if (!context.previouslyFocusedItem().expired()) { context.previouslyFocusedItem().lock()->didUpdateFocusIn(context, &coordinator); }
} else {
if (!context.previouslyFocusedItem().expired()) { context.previouslyFocusedItem().lock()->didUpdateFocusIn(context, &coordinator); }
if (!context.nextFocusedItem().expired()) { context.nextFocusedItem().lock()->didUpdateFocusIn(context, &coordinator); }
}
UIFocusAnimationContext animationContext;
UIView::animate(animationContext.duration(), 0, curveEaseOut, [context, coordinator, animationContext]() {
-1
View File
@@ -395,7 +395,6 @@ void UIView::drawAndLayoutTreeIfNeeded() {
updateSafeAreaInsetsIfNeeded();
updateLayoutMarginIfNeeded();
layoutIfNeeded();
_yoga->layoutIfNeeded();
for (auto& subview: _subviews) {
subview->drawAndLayoutTreeIfNeeded();
+8
View File
@@ -232,4 +232,12 @@ bool YGLayout::isRoot() {
return false;
}
bool YGLayout::isDirty() {
if (_isEnabled) {
return YGNodeIsDirty(_node);
}
return false;
}
}
@@ -77,6 +77,33 @@ public:
setBackgroundColor(std::nullopt);
}
void focusFailedToMove(UIFocusHeading heading) override {
NXFloat x = 0;
NXFloat y = 0;
NXFloat power = 10;
switch (heading) {
case UIFocusHeading::up:
y = -1;
break;
case UIFocusHeading::down:
y = 1;
break;
case UIFocusHeading::left:
x = -1;
break;
case UIFocusHeading::right:
x = 1;
break;
default: break;
}
setTransform(NXAffineTransform::translationBy(x * power, y * power));
UIView::animate(0.3, 0, 0.4, 3, UIViewAnimationOptions::allowUserInteraction, [this]() {
setTransform(NXAffineTransform::identity);
});
}
void setSelected(bool selected) override {
UIControl::setSelected(selected);
if (selected) {