modules/graphics/src/main/java/com/sun/javafx/scene/traversal/Hueristic2D.java
Print this page
*** 77,104 ****
else {
newNode = traversalNodeStack.pop();
}
}
Bounds currentB = node.localToScene(node.getLayoutBounds());
-
if (cacheStartTraversalNode != null) {
Bounds cachedB = cacheStartTraversalNode.localToScene(cacheStartTraversalNode.getLayoutBounds());
switch (dir) {
case UP:
case DOWN:
! newNode = getNearestNodeUpOrDown(currentB, cachedB, engine, node, newNode, dir);
break;
case LEFT:
case RIGHT:
! newNode = getNearestNodeLeftOrRight(currentB, cachedB, engine, node, newNode, dir);
break;
default:
break;
}
}
}
if (focusLogger.isLoggable(Level.FINER)) {
if (newNode != null) {
focusLogger.finer("new focus owner : "+newNode+", bounds : "+engine.getBounds(newNode));
}
--- 77,105 ----
else {
newNode = traversalNodeStack.pop();
}
}
+ if (newNode == null) {
Bounds currentB = node.localToScene(node.getLayoutBounds());
if (cacheStartTraversalNode != null) {
Bounds cachedB = cacheStartTraversalNode.localToScene(cacheStartTraversalNode.getLayoutBounds());
switch (dir) {
case UP:
case DOWN:
! newNode = getNearestNodeUpOrDown(currentB, cachedB, engine, node, dir);
break;
case LEFT:
case RIGHT:
! newNode = getNearestNodeLeftOrRight(currentB, cachedB, engine, node, dir);
break;
default:
break;
}
}
}
+ }
if (focusLogger.isLoggable(Level.FINER)) {
if (newNode != null) {
focusLogger.finer("new focus owner : "+newNode+", bounds : "+engine.getBounds(newNode));
}
*** 445,466 ****
public Double apply(Bounds t) {
return t.getMaxY();
}
};
! protected Node getNearestNodeUpOrDown(Bounds currentB, Bounds originB, TraversalEngine engine, Node node, Node reversingNode, Direction dir) {
List<Node> nodes = engine.getAllTargetNodes();
Function<Bounds, Double> ySideInDirection = dir == DOWN ? BOUNDS_BOTTOM_SIDE : BOUNDS_TOP_SIDE;
Function<Bounds, Double> ySideInOpositeDirection = dir == DOWN ? BOUNDS_TOP_SIDE : BOUNDS_BOTTOM_SIDE;
Bounds biasedB = new BoundingBox(originB.getMinX(), currentB.getMinY(), originB.getWidth(), currentB.getHeight());
! Point2D currentMid2D = new Point2D(currentB.getMinX()+(currentB.getWidth()/2), currentB.getMinY());
! Point2D currenLeftCorner2D = new Point2D(currentB.getMinX(),ySideInDirection.apply(currentB));
Point2D currentRightCorner2D = new Point2D(currentB.getMaxX(), ySideInDirection.apply(currentB));
Point2D originLeftCorner2D = new Point2D(originB.getMinX(), ySideInDirection.apply(originB));
TargetNode targetNode = new TargetNode();
TargetNode nearestNodeCurrentSimple2D = null;
--- 446,470 ----
public Double apply(Bounds t) {
return t.getMaxY();
}
};
! protected Node getNearestNodeUpOrDown(Bounds currentB, Bounds originB, TraversalEngine engine, Node node, Direction dir) {
List<Node> nodes = engine.getAllTargetNodes();
Function<Bounds, Double> ySideInDirection = dir == DOWN ? BOUNDS_BOTTOM_SIDE : BOUNDS_TOP_SIDE;
Function<Bounds, Double> ySideInOpositeDirection = dir == DOWN ? BOUNDS_TOP_SIDE : BOUNDS_BOTTOM_SIDE;
Bounds biasedB = new BoundingBox(originB.getMinX(), currentB.getMinY(), originB.getWidth(), currentB.getHeight());
! Point2D currentMid2D = new Point2D(currentB.getMinX()+(currentB.getWidth()/2), ySideInDirection.apply(currentB));
! Point2D biasedMid2D = new Point2D(originB.getMinX()+(originB.getWidth()/2), ySideInDirection.apply(currentB));
! Point2D currentLeftCorner2D = new Point2D(currentB.getMinX(),ySideInDirection.apply(currentB));
! Point2D biasedLeftCorner2D = new Point2D(originB.getMinX(),ySideInDirection.apply(currentB));
Point2D currentRightCorner2D = new Point2D(currentB.getMaxX(), ySideInDirection.apply(currentB));
+ Point2D biasedRightCorner2D = new Point2D(originB.getMaxX(), ySideInDirection.apply(currentB));
Point2D originLeftCorner2D = new Point2D(originB.getMinX(), ySideInDirection.apply(originB));
TargetNode targetNode = new TargetNode();
TargetNode nearestNodeCurrentSimple2D = null;
*** 469,558 ****
TargetNode nearestNodeOnOriginX = null;
TargetNode nearestNodeOnCurrentX = null;
TargetNode nearestNodeLeft = null;
TargetNode nearestNodeAnythingAnywhere = null;
- if (nodes.size() > 0) {
- /*
- ** we've just changed direction, and have a node on stack.
- ** there is a strong preference for this node, just make sure
- ** it's not a bad choice, as sometimes we got here as a last-chance
- */
- if (reversingNode != null) {
- return reversingNode;
- }
-
for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
final Node n = nodes.get(nodeIndex);
Bounds targetBounds = n.localToScene(n.getLayoutBounds());
/*
** check that the target node starts after we
** and the target node ends after we end
*/
! if (dir == UP ? (currentB.getMinY() > targetBounds.getMaxY()) :
! currentB.getMaxY() < targetBounds.getMinY()) {
targetNode.node = n;
targetNode.bounds = targetBounds;
/*
! ** closest biased : simple 2d
*/
! double outdB = outDistance(dir, biasedB, targetBounds);
if (isOnAxis(dir, biasedB, targetBounds)) {
targetNode.biased2DMetric = outdB + centerSideDistance(dir, biasedB, targetBounds) / 100;
! }
! else {
final double cosd = cornerSideDistance(dir, biasedB, targetBounds);
! targetNode.biased2DMetric = 100000 + outdB*outdB + 9*cosd*cosd;
}
/*
! ** closest current : simple 2d
*/
! double outdC = outDistance(dir, currentB, targetBounds);
if (isOnAxis(dir, currentB, targetBounds)) {
targetNode.current2DMetric = outdC + centerSideDistance(dir, currentB, targetBounds) / 100;
! }
! else {
final double cosd = cornerSideDistance(dir, currentB, targetBounds);
! targetNode.current2DMetric = 100000 + outdC*outdC + 9*cosd*cosd;
}
! targetNode.leftCornerDistance = currenLeftCorner2D.distance(targetBounds.getMinX(), ySideInOpositeDirection.apply(targetBounds));
! targetNode.midDistance = currentMid2D.distance(targetBounds.getMinX()+(originB.getWidth()/2), ySideInOpositeDirection.apply(targetBounds));
! targetNode.rightCornerDistance = currentRightCorner2D.distance(originB.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
!
! double currentTopLeftToTargetMidDistance = currenLeftCorner2D.distance(targetBounds.getMinX()+(targetBounds.getWidth()/2), ySideInOpositeDirection.apply(targetBounds));
! double currentTopLeftToTargetBottomRightDistance = currenLeftCorner2D.distance(targetBounds.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
! double currentTopRightToTargetBottomLeftDistance = currentRightCorner2D.distance(targetBounds.getMinX(), ySideInOpositeDirection.apply(targetBounds));
! double currentTopRightToTargetMidDistance = currentRightCorner2D.distance(targetBounds.getMinX()+(targetBounds.getWidth()/2), ySideInOpositeDirection.apply(targetBounds));
! double currentTopRightToTargetBottomRightDistance = currentRightCorner2D.distance(targetBounds.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
! double currentMidToTargetBottomLeftDistance = currentMid2D.distance(targetBounds.getMinX(), ySideInOpositeDirection.apply(targetBounds));
! double currentMidToTargetMidDistance = currentMid2D.distance(targetBounds.getMinX()+(targetBounds.getWidth()/2), ySideInOpositeDirection.apply(targetBounds));
! double currentMidToTargetBottomRightDistance = currentMid2D.distance(targetBounds.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
!
! double biasTopLeftToTargetMidDistance = currenLeftCorner2D.distance(targetBounds.getMinX()+(originB.getWidth()/2), ySideInOpositeDirection.apply(targetBounds));
! double biasTopLeftToTargetBottomRightDistance = currenLeftCorner2D.distance(originB.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
! double biasTopRightToTargetMidDistance = currentRightCorner2D.distance(targetBounds.getMinX()+(originB.getWidth()/2), ySideInOpositeDirection.apply(targetBounds));
! double biasMidToTargetBottomRightDistance = currentMid2D.distance(originB.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
!
! targetNode.averageDistance =
! (targetNode.leftCornerDistance+biasTopLeftToTargetMidDistance+biasTopLeftToTargetBottomRightDistance+
! currentTopRightToTargetBottomLeftDistance+targetNode.rightCornerDistance+biasTopRightToTargetMidDistance+targetNode.midDistance)/7;
!
! targetNode.biasShortestDistance =
! findMin(targetNode.leftCornerDistance, biasTopLeftToTargetMidDistance, biasTopLeftToTargetBottomRightDistance,
! currentTopRightToTargetBottomLeftDistance, biasTopRightToTargetMidDistance, targetNode.rightCornerDistance,
! currentMidToTargetBottomLeftDistance, targetNode.midDistance, biasMidToTargetBottomRightDistance);
!
! targetNode.shortestDistance =
! findMin(targetNode.leftCornerDistance, currentTopLeftToTargetMidDistance, currentTopLeftToTargetBottomRightDistance,
! currentTopRightToTargetBottomLeftDistance, currentTopRightToTargetMidDistance, currentTopRightToTargetBottomRightDistance,
! currentMidToTargetBottomLeftDistance, currentMidToTargetMidDistance, currentMidToTargetBottomRightDistance);
/*
** closest biased : simple 2d
*/
if (outdB >= 0.0) {
--- 473,552 ----
TargetNode nearestNodeOnOriginX = null;
TargetNode nearestNodeOnCurrentX = null;
TargetNode nearestNodeLeft = null;
TargetNode nearestNodeAnythingAnywhere = null;
for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
final Node n = nodes.get(nodeIndex);
Bounds targetBounds = n.localToScene(n.getLayoutBounds());
/*
** check that the target node starts after we
** and the target node ends after we end
*/
! if (dir == UP ? (currentB.getMinY() > targetBounds.getMaxY())
! : currentB.getMaxY() < targetBounds.getMinY()) {
targetNode.node = n;
targetNode.bounds = targetBounds;
/*
! * closest biased : simple 2d
! * Negative means the Node is on the same Y axis. This will result in outdB == 0, making this a preferred Node.
*/
! double outdB = Math.max(0, outDistance(dir, biasedB, targetBounds));
if (isOnAxis(dir, biasedB, targetBounds)) {
targetNode.biased2DMetric = outdB + centerSideDistance(dir, biasedB, targetBounds) / 100;
! } else {
final double cosd = cornerSideDistance(dir, biasedB, targetBounds);
! targetNode.biased2DMetric = 100000 + outdB * outdB + 9 * cosd * cosd;
}
/*
! * closest current : simple 2d
! * Negative means the Node is on the same Y axis. This will result in outdB == 0, making this a preferred Node.
*/
! double outdC = Math.max(0, outDistance(dir, currentB, targetBounds));
if (isOnAxis(dir, currentB, targetBounds)) {
targetNode.current2DMetric = outdC + centerSideDistance(dir, currentB, targetBounds) / 100;
! } else {
final double cosd = cornerSideDistance(dir, currentB, targetBounds);
! targetNode.current2DMetric = 100000 + outdC * outdC + 9 * cosd * cosd;
}
! targetNode.leftCornerDistance = currentLeftCorner2D.distance(targetBounds.getMinX(), ySideInOpositeDirection.apply(targetBounds));
! targetNode.rightCornerDistance = currentRightCorner2D.distance(targetBounds.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
!
! double midDistance = currentMid2D.distance(targetBounds.getMinX() + (targetBounds.getWidth() / 2), ySideInOpositeDirection.apply(targetBounds));
! double currentLeftToTargetMidDistance = currentLeftCorner2D.distance(targetBounds.getMinX() + (targetBounds.getWidth() / 2), ySideInOpositeDirection.apply(targetBounds));
! double currentLeftToTargetRightDistance = currentLeftCorner2D.distance(targetBounds.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
! double currentRightToTargetLeftDistance = currentRightCorner2D.distance(targetBounds.getMinX(), ySideInOpositeDirection.apply(targetBounds));
! double currentRightToTargetMidDistance = currentRightCorner2D.distance(targetBounds.getMinX() + (targetBounds.getWidth() / 2), ySideInOpositeDirection.apply(targetBounds));
! double currentRightToTargetRightDistance = currentRightCorner2D.distance(targetBounds.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
! double currentMidToTargetLeftDistance = currentMid2D.distance(targetBounds.getMinX(), ySideInOpositeDirection.apply(targetBounds));
! double currentMidToTargetMidDistance = currentMid2D.distance(targetBounds.getMinX() + (targetBounds.getWidth() / 2), ySideInOpositeDirection.apply(targetBounds));
! double currentMidToTargetRightDistance = currentMid2D.distance(targetBounds.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
!
! double biasLeftToTargetMidDistance = biasedLeftCorner2D.distance(targetBounds.getMinX() + (targetBounds.getWidth() / 2), ySideInOpositeDirection.apply(targetBounds));
! double biasLeftToTargetRightDistance = biasedLeftCorner2D.distance(targetBounds.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
! double biasRightToTargetMidDistance = biasedRightCorner2D.distance(targetBounds.getMinX() + (targetBounds.getWidth() / 2), ySideInOpositeDirection.apply(targetBounds));
! double biasMidToTargetRightDistance = biasedMid2D.distance(targetBounds.getMaxX(), ySideInOpositeDirection.apply(targetBounds));
!
! targetNode.averageDistance
! = (targetNode.leftCornerDistance + biasLeftToTargetMidDistance + biasLeftToTargetRightDistance
! + currentRightToTargetLeftDistance + targetNode.rightCornerDistance + biasRightToTargetMidDistance + midDistance) / 7;
!
! targetNode.biasShortestDistance
! = findMin(targetNode.leftCornerDistance, biasLeftToTargetMidDistance, biasLeftToTargetRightDistance,
! currentRightToTargetLeftDistance, biasRightToTargetMidDistance, targetNode.rightCornerDistance,
! currentMidToTargetLeftDistance, midDistance, biasMidToTargetRightDistance);
!
! targetNode.shortestDistance
! = findMin(targetNode.leftCornerDistance, currentLeftToTargetMidDistance, currentLeftToTargetRightDistance,
! currentRightToTargetLeftDistance, currentRightToTargetMidDistance, currentRightToTargetRightDistance,
! currentMidToTargetLeftDistance, currentMidToTargetMidDistance, currentMidToTargetRightDistance);
/*
** closest biased : simple 2d
*/
if (outdB >= 0.0) {
*** 602,624 ****
}
/*
** Closest top left / bottom left corners.
*/
if (nearestNodeLeft == null || nearestNodeLeft.leftCornerDistance > targetNode.leftCornerDistance) {
! if (((originB.getMinX() >= currentB.getMinX()) && (targetBounds.getMinX() >= currentB.getMinX())) ||
! ((originB.getMinX() <= currentB.getMinX()) && (targetBounds.getMinX() <= currentB.getMinX()))) {
if (nearestNodeLeft == null) {
nearestNodeLeft = new TargetNode();
}
nearestNodeLeft.copy(targetNode);
}
}
if (nearestNodeAverage == null || nearestNodeAverage.averageDistance > targetNode.averageDistance) {
! if (((originB.getMinX() >= currentB.getMinX()) && (targetBounds.getMinX() >= currentB.getMinX())) ||
! ((originB.getMinX() <= currentB.getMinX()) && (targetBounds.getMinX() <= currentB.getMinX()))) {
if (nearestNodeAverage == null) {
nearestNodeAverage = new TargetNode();
}
nearestNodeAverage.copy(targetNode);
--- 596,618 ----
}
/*
** Closest top left / bottom left corners.
*/
if (nearestNodeLeft == null || nearestNodeLeft.leftCornerDistance > targetNode.leftCornerDistance) {
! if (((originB.getMinX() >= currentB.getMinX()) && (targetBounds.getMinX() >= currentB.getMinX()))
! || ((originB.getMinX() <= currentB.getMinX()) && (targetBounds.getMinX() <= currentB.getMinX()))) {
if (nearestNodeLeft == null) {
nearestNodeLeft = new TargetNode();
}
nearestNodeLeft.copy(targetNode);
}
}
if (nearestNodeAverage == null || nearestNodeAverage.averageDistance > targetNode.averageDistance) {
! if (((originB.getMinX() >= currentB.getMinX()) && (targetBounds.getMinX() >= currentB.getMinX()))
! || ((originB.getMinX() <= currentB.getMinX()) && (targetBounds.getMinX() <= currentB.getMinX()))) {
if (nearestNodeAverage == null) {
nearestNodeAverage = new TargetNode();
}
nearestNodeAverage.copy(targetNode);
*** 632,642 ****
}
nearestNodeAnythingAnywhere.copy(targetNode);
}
}
}
- }
nodes.clear();
if (nearestNodeOnOriginX != null) {
nearestNodeOnOriginX.originLeftCornerDistance = originLeftCorner2D.distance(nearestNodeOnOriginX.bounds.getMinX(), ySideInOpositeDirection.apply(nearestNodeOnOriginX.bounds));
}
--- 626,635 ----
*** 671,681 ****
if (nearestNodeAnythingAnywhere != null) {
focusLogger.finer("nearestNodeAnythingAnywhereUp.node : "+nearestNodeAnythingAnywhere.node);
}
}
! if (nearestNodeOnOriginX != null && nearestNodeOnOriginX.biasShortestDistance < Double.MAX_VALUE) {
/*
** there's a preference, all else being equal, to return nearestNodeOnOriginX
*/
if (nearestNodeOnCurrentX != null && nearestNodeOnOriginX.node == nearestNodeOnCurrentX.node
&& ((nearestNodeAverage != null && nearestNodeOnOriginX.node == nearestNodeAverage.node)
--- 664,674 ----
if (nearestNodeAnythingAnywhere != null) {
focusLogger.finer("nearestNodeAnythingAnywhereUp.node : "+nearestNodeAnythingAnywhere.node);
}
}
! if (nearestNodeOnOriginX != null) {
/*
** there's a preference, all else being equal, to return nearestNodeOnOriginX
*/
if (nearestNodeOnCurrentX != null && nearestNodeOnOriginX.node == nearestNodeOnCurrentX.node
&& ((nearestNodeAverage != null && nearestNodeOnOriginX.node == nearestNodeAverage.node)
*** 686,723 ****
}
if (nearestNodeAverage != null && nearestNodeOnOriginX.node == nearestNodeAverage.node) {
return nearestNodeOnOriginX.node;
}
! if (nearestNodeOnCurrentX != null && nearestNodeOnCurrentX.biasShortestDistance < Double.MAX_VALUE) {
if ((nearestNodeOnCurrentX.leftCornerDistance < nearestNodeOnOriginX.leftCornerDistance) &&
(nearestNodeOnCurrentX.originLeftCornerDistance < nearestNodeOnOriginX.originLeftCornerDistance) &&
! (nearestNodeOnCurrentX.bounds.getMinX() - currenLeftCorner2D.getX()) < (nearestNodeOnOriginX.bounds.getMinX() - currenLeftCorner2D.getX())) {
return nearestNodeOnCurrentX.node;
} else if (nearestNodeAverage == null || nearestNodeOnOriginX.averageDistance < nearestNodeAverage.averageDistance) {
return nearestNodeOnOriginX.node;
}
}
} else {
! if (nearestNodeOnOriginX == null && nearestNodeOnCurrentX == null && nearestNodeCurrentSimple2D != null) {
if (nearestNodeAverage != null && nearestNodeLeft != null && (nearestNodeAverage.node == nearestNodeLeft.node && nearestNodeAverage.node == nearestNodeAnythingAnywhere.node)) {
return nearestNodeAverage.node;
}
return nearestNodeCurrentSimple2D.node;
} else if (nearestNodeAverage != null && nearestNodeLeft != null && nearestNodeAnythingAnywhere != null
&& nearestNodeAverage.biasShortestDistance == nearestNodeLeft.biasShortestDistance &&
nearestNodeAverage.biasShortestDistance == nearestNodeAnythingAnywhere.biasShortestDistance &&
nearestNodeAverage.biasShortestDistance < Double.MAX_VALUE) {
- if (nearestNodeOnOriginX != null && nearestNodeOnOriginX.originLeftCornerDistance < nearestNodeAverage.originLeftCornerDistance) {
- return nearestNodeOnOriginX.node;
- } else {
return nearestNodeAverage.node;
}
}
- }
/*
** is the average closer?
*/
if (nearestNodeAverage != null && (nearestNodeOnOriginX == null || (nearestNodeAverage.biasShortestDistance < nearestNodeOnOriginX.biasShortestDistance))) {
--- 679,712 ----
}
if (nearestNodeAverage != null && nearestNodeOnOriginX.node == nearestNodeAverage.node) {
return nearestNodeOnOriginX.node;
}
! if (nearestNodeOnCurrentX != null) {
if ((nearestNodeOnCurrentX.leftCornerDistance < nearestNodeOnOriginX.leftCornerDistance) &&
(nearestNodeOnCurrentX.originLeftCornerDistance < nearestNodeOnOriginX.originLeftCornerDistance) &&
! (nearestNodeOnCurrentX.bounds.getMinX() - currentLeftCorner2D.getX()) < (nearestNodeOnOriginX.bounds.getMinX() - currentLeftCorner2D.getX())) {
return nearestNodeOnCurrentX.node;
} else if (nearestNodeAverage == null || nearestNodeOnOriginX.averageDistance < nearestNodeAverage.averageDistance) {
return nearestNodeOnOriginX.node;
}
}
} else {
! if (nearestNodeOnCurrentX == null && nearestNodeCurrentSimple2D != null) {
if (nearestNodeAverage != null && nearestNodeLeft != null && (nearestNodeAverage.node == nearestNodeLeft.node && nearestNodeAverage.node == nearestNodeAnythingAnywhere.node)) {
return nearestNodeAverage.node;
}
return nearestNodeCurrentSimple2D.node;
} else if (nearestNodeAverage != null && nearestNodeLeft != null && nearestNodeAnythingAnywhere != null
&& nearestNodeAverage.biasShortestDistance == nearestNodeLeft.biasShortestDistance &&
nearestNodeAverage.biasShortestDistance == nearestNodeAnythingAnywhere.biasShortestDistance &&
nearestNodeAverage.biasShortestDistance < Double.MAX_VALUE) {
return nearestNodeAverage.node;
}
}
/*
** is the average closer?
*/
if (nearestNodeAverage != null && (nearestNodeOnOriginX == null || (nearestNodeAverage.biasShortestDistance < nearestNodeOnOriginX.biasShortestDistance))) {
*** 787,808 ****
public Double apply(Bounds t) {
return t.getMaxX();
}
};
! protected Node getNearestNodeLeftOrRight(Bounds currentB, Bounds originB, TraversalEngine engine, Node node, Node reversingNode, Direction dir) {
List<Node> nodes = engine.getAllTargetNodes();
Function<Bounds, Double> xSideInDirection = dir == LEFT ? BOUNDS_LEFT_SIDE : BOUNDS_RIGHT_SIDE;
Function<Bounds, Double> xSideInOpositeDirection = dir == LEFT ? BOUNDS_RIGHT_SIDE : BOUNDS_LEFT_SIDE;
! Bounds biasedB = new BoundingBox(xSideInDirection.apply(currentB), originB.getMinY(), currentB.getWidth(), originB.getHeight());
Point2D currentMid2D = new Point2D(xSideInDirection.apply(currentB), currentB.getMinY()+(currentB.getHeight()/2));
Point2D currentTopCorner2D = new Point2D(xSideInDirection.apply(currentB), currentB.getMinY());
Point2D currentBottomCorner2D = new Point2D(xSideInDirection.apply(currentB), currentB.getMaxY());
Point2D originTopCorner2D = new Point2D(xSideInDirection.apply(originB), originB.getMinY());
TargetNode targetNode = new TargetNode();
TargetNode nearestNodeCurrentSimple2D = null;
--- 776,800 ----
public Double apply(Bounds t) {
return t.getMaxX();
}
};
! protected Node getNearestNodeLeftOrRight(Bounds currentB, Bounds originB, TraversalEngine engine, Node node, Direction dir) {
List<Node> nodes = engine.getAllTargetNodes();
Function<Bounds, Double> xSideInDirection = dir == LEFT ? BOUNDS_LEFT_SIDE : BOUNDS_RIGHT_SIDE;
Function<Bounds, Double> xSideInOpositeDirection = dir == LEFT ? BOUNDS_RIGHT_SIDE : BOUNDS_LEFT_SIDE;
! Bounds biasedB = new BoundingBox(currentB.getMinX(), originB.getMinY(), currentB.getWidth(), originB.getHeight());
Point2D currentMid2D = new Point2D(xSideInDirection.apply(currentB), currentB.getMinY()+(currentB.getHeight()/2));
+ Point2D biasedMid2D = new Point2D(xSideInDirection.apply(currentB), originB.getMinY()+(originB.getHeight()/2));
Point2D currentTopCorner2D = new Point2D(xSideInDirection.apply(currentB), currentB.getMinY());
+ Point2D biasedTopCorner2D = new Point2D(xSideInDirection.apply(currentB), originB.getMinY());
Point2D currentBottomCorner2D = new Point2D(xSideInDirection.apply(currentB), currentB.getMaxY());
+ Point2D biasedBottomCorner2D = new Point2D(xSideInDirection.apply(currentB), originB.getMaxY());
Point2D originTopCorner2D = new Point2D(xSideInDirection.apply(originB), originB.getMinY());
TargetNode targetNode = new TargetNode();
TargetNode nearestNodeCurrentSimple2D = null;
*** 811,900 ****
TargetNode nearestNodeOnOriginY = null;
TargetNode nearestNodeOnCurrentY = null;
TargetNode nearestNodeTopLeft = null;
TargetNode nearestNodeAnythingAnywhereLeft = null;
- if (nodes.size() > 0) {
- /*
- ** we've just changed direction, and have a node on stack.
- ** there is a strong preference for this node, just make sure
- ** it's not a bad choice, as sometimes we got here as a last-chance
- */
- if (reversingNode != null) {
- return reversingNode;
- }
-
for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
final Node n = nodes.get(nodeIndex);
Bounds targetBounds = n.localToScene(n.getLayoutBounds());
/*
** check that the target node starts after we start
** and the target node ends after we end
*/
! if (dir == LEFT ? currentB.getMinX() > targetBounds.getMinX() :
! currentB.getMaxX() < targetBounds.getMaxX()) {
targetNode.node = n;
targetNode.bounds = targetBounds;
/*
! ** closest biased : simple 2d
*/
! double outdB = outDistance(dir, biasedB, targetBounds);
if (isOnAxis(dir, biasedB, targetBounds)) {
targetNode.biased2DMetric = outdB + centerSideDistance(dir, biasedB, targetBounds) / 100;
! }
! else {
final double cosd = cornerSideDistance(dir, biasedB, targetBounds);
! targetNode.biased2DMetric = 100000 + outdB*outdB + 9*cosd*cosd;
}
/*
! ** closest current : simple 2d
*/
! double outdC = outDistance(dir, currentB, targetBounds);
if (isOnAxis(dir, currentB, targetBounds)) {
targetNode.current2DMetric = outdC + centerSideDistance(dir, currentB, targetBounds) / 100;
! }
! else {
final double cosd = cornerSideDistance(dir, currentB, targetBounds);
! targetNode.current2DMetric = 100000 + outdC*outdC + 9*cosd*cosd;
}
targetNode.topCornerDistance = currentTopCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY());
! targetNode.midDistance = currentMid2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY()+(originB.getHeight()/2));
! targetNode.bottomCornerDistance = currentBottomCorner2D.distance(xSideInOpositeDirection.apply(originB), targetBounds.getMaxY());
! double currentTopLeftToTargetBottomRightDistance = currentTopCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMaxY());
! double currentTopLeftToTargetMidDistance = currentTopCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY()+(targetBounds.getHeight()/2));
! double currentBottomLeftToTargetTopRightDistance = currentBottomCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY());
! double currentBottomLeftToTargetBottomRightDistance = currentBottomCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMaxY());
! double currentBottomLeftToTargetMidDistance = currentBottomCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY()+(targetBounds.getHeight()/2));
! double currentMidToTargetTopRightDistance = currentMid2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY());
! double currentMidToTargetBottomRightDistance = currentMid2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMaxY());
! double currentMidToTargetMidDistance = currentMid2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY()+(targetBounds.getHeight()/2));
!
! double biasTopLeftToTargetBottomRightDistance = currentTopCorner2D.distance(xSideInOpositeDirection.apply(originB), targetBounds.getMaxY());
! double biasTopLeftToTargetMidDistance = currentTopCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY()+(originB.getHeight()/2));
! double biasBottomLeftToTargetMidDistance = currentBottomCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY()+(originB.getHeight()/2));
! double biasMidToTargetBottomRightDistance = currentMid2D.distance(xSideInOpositeDirection.apply(originB), targetBounds.getMaxY());
!
! targetNode.averageDistance =
! (targetNode.topCornerDistance+biasTopLeftToTargetBottomRightDistance+biasTopLeftToTargetMidDistance+
! currentBottomLeftToTargetTopRightDistance+targetNode.bottomCornerDistance+biasBottomLeftToTargetMidDistance)/7;
!
! targetNode.biasShortestDistance =
! findMin(targetNode.topCornerDistance, biasTopLeftToTargetBottomRightDistance, biasTopLeftToTargetMidDistance,
! currentBottomLeftToTargetTopRightDistance, targetNode.bottomCornerDistance, biasBottomLeftToTargetMidDistance,
! currentMidToTargetTopRightDistance, biasMidToTargetBottomRightDistance, targetNode.midDistance);
!
! targetNode.shortestDistance =
! findMin(targetNode.topCornerDistance, currentTopLeftToTargetBottomRightDistance, currentTopLeftToTargetMidDistance,
! currentBottomLeftToTargetTopRightDistance, currentBottomLeftToTargetBottomRightDistance, currentBottomLeftToTargetMidDistance,
! currentMidToTargetTopRightDistance, currentMidToTargetBottomRightDistance, currentMidToTargetMidDistance);
/*
** closest biased : simple 2d
*/
if (outdB >= 0.0) {
--- 803,882 ----
TargetNode nearestNodeOnOriginY = null;
TargetNode nearestNodeOnCurrentY = null;
TargetNode nearestNodeTopLeft = null;
TargetNode nearestNodeAnythingAnywhereLeft = null;
for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
final Node n = nodes.get(nodeIndex);
Bounds targetBounds = n.localToScene(n.getLayoutBounds());
/*
** check that the target node starts after we start
** and the target node ends after we end
*/
! if (dir == LEFT ? currentB.getMinX() > targetBounds.getMinX()
! : currentB.getMaxX() < targetBounds.getMaxX()) {
targetNode.node = n;
targetNode.bounds = targetBounds;
/*
! * closest biased : simple 2d.
! * Negative means the Node is on the same Y axis. This will result in outdB == 0, making this a preferred Node.
*/
! double outdB = Math.max(0, outDistance(dir, biasedB, targetBounds));
if (isOnAxis(dir, biasedB, targetBounds)) {
targetNode.biased2DMetric = outdB + centerSideDistance(dir, biasedB, targetBounds) / 100;
! } else {
final double cosd = cornerSideDistance(dir, biasedB, targetBounds);
! targetNode.biased2DMetric = 100000 + outdB * outdB + 9 * cosd * cosd;
}
/*
! * closest current : simple 2d
! *Negative means the Node is on the same Y axis. This will result in outdB == 0, making this a preferred Node.
*/
! double outdC = Math.max(0, outDistance(dir, currentB, targetBounds));
if (isOnAxis(dir, currentB, targetBounds)) {
targetNode.current2DMetric = outdC + centerSideDistance(dir, currentB, targetBounds) / 100;
! } else {
final double cosd = cornerSideDistance(dir, currentB, targetBounds);
! targetNode.current2DMetric = 100000 + outdC * outdC + 9 * cosd * cosd;
}
targetNode.topCornerDistance = currentTopCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY());
! targetNode.bottomCornerDistance = currentBottomCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMaxY());
! double midDistance = currentMid2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY() + (targetBounds.getHeight() / 2));
! double currentTopToTargetBottomDistance = currentTopCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMaxY());
! double currentTopToTargetMidDistance = currentTopCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY() + (targetBounds.getHeight() / 2));
! double currentBottomToTargetTopDistance = currentBottomCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY());
! double currentBottomToTargetBottomDistance = currentBottomCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMaxY());
! double currentBottomToTargetMidDistance = currentBottomCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY() + (targetBounds.getHeight() / 2));
! double currentMidToTargetTopDistance = currentMid2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY());
! double currentMidToTargetBottomDistance = currentMid2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMaxY());
! double currentMidToTargetMidDistance = currentMid2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY() + (targetBounds.getHeight() / 2));
!
! double biasTopToTargetBottomDistance = biasedTopCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMaxY());
! double biasTopToTargetMidDistance = biasedTopCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY() + (targetBounds.getHeight() / 2));
! double biasBottomToTargetMidDistance = biasedBottomCorner2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMinY() + (targetBounds.getHeight() / 2));
! double biasMidToTargetBottomDistance = biasedMid2D.distance(xSideInOpositeDirection.apply(targetBounds), targetBounds.getMaxY());
!
! targetNode.averageDistance
! = (targetNode.topCornerDistance + biasTopToTargetBottomDistance + biasTopToTargetMidDistance
! + currentBottomToTargetTopDistance + targetNode.bottomCornerDistance + biasBottomToTargetMidDistance + midDistance) / 7;
!
! targetNode.biasShortestDistance
! = findMin(targetNode.topCornerDistance, biasTopToTargetBottomDistance, biasTopToTargetMidDistance,
! currentBottomToTargetTopDistance, targetNode.bottomCornerDistance, biasBottomToTargetMidDistance,
! currentMidToTargetTopDistance, biasMidToTargetBottomDistance, midDistance);
!
! targetNode.shortestDistance
! = findMin(targetNode.topCornerDistance, currentTopToTargetBottomDistance, currentTopToTargetMidDistance,
! currentBottomToTargetTopDistance, currentBottomToTargetBottomDistance, currentBottomToTargetMidDistance,
! currentMidToTargetTopDistance, currentMidToTargetBottomDistance, currentMidToTargetMidDistance);
/*
** closest biased : simple 2d
*/
if (outdB >= 0.0) {
*** 968,978 ****
}
nearestNodeAnythingAnywhereLeft.copy(targetNode);
}
}
}
- }
nodes.clear();
if (nearestNodeOnOriginY != null) {
nearestNodeOnOriginY.originTopCornerDistance = originTopCorner2D.distance(xSideInOpositeDirection.apply(nearestNodeOnOriginY.bounds), nearestNodeOnOriginY.bounds.getMinY());
}
--- 950,959 ----
*** 1014,1024 ****
if (nearestNodeAnythingAnywhereLeft != null) {
focusLogger.finer("nearestNodeAnythingAnywhereLeft.node : "+nearestNodeAnythingAnywhereLeft.node);
}
}
! if (nearestNodeOnOriginY != null && nearestNodeOnOriginY.biasShortestDistance < Double.MAX_VALUE) {
/*
** there's a preference, all else being equal, to return nearestNodeOnOriginY
*/
if (nearestNodeOnCurrentY != null && nearestNodeOnOriginY.node == nearestNodeOnCurrentY.node
&& ((nearestNodeAverage != null && nearestNodeOnOriginY.node == nearestNodeAverage.node)
--- 995,1005 ----
if (nearestNodeAnythingAnywhereLeft != null) {
focusLogger.finer("nearestNodeAnythingAnywhereLeft.node : "+nearestNodeAnythingAnywhereLeft.node);
}
}
! if (nearestNodeOnOriginY != null) {
/*
** there's a preference, all else being equal, to return nearestNodeOnOriginY
*/
if (nearestNodeOnCurrentY != null && nearestNodeOnOriginY.node == nearestNodeOnCurrentY.node
&& ((nearestNodeAverage != null && nearestNodeOnOriginY.node == nearestNodeAverage.node)
*** 1029,1067 ****
if (nearestNodeAverage != null && nearestNodeOnOriginY.node == nearestNodeAverage.node) {
return nearestNodeOnOriginY.node;
}
! if (nearestNodeOnCurrentY != null && nearestNodeOnCurrentY.biasShortestDistance < Double.MAX_VALUE) {
if ((nearestNodeOnCurrentY.bottomCornerDistance < nearestNodeOnOriginY.bottomCornerDistance)
&& (nearestNodeOnCurrentY.originTopCornerDistance < nearestNodeOnOriginY.originTopCornerDistance)
&& (nearestNodeOnCurrentY.bounds.getMinY() - currentTopCorner2D.getY()) < (nearestNodeOnOriginY.bounds.getMinY() - currentTopCorner2D.getY())) {
return nearestNodeOnCurrentY.node;
} else if (nearestNodeAverage == null || nearestNodeOnOriginY.averageDistance < nearestNodeAverage.averageDistance) {
return nearestNodeOnOriginY.node;
}
}
} else {
! if (nearestNodeOnOriginY == null && nearestNodeOnCurrentY == null && nearestNodeCurrentSimple2D != null) {
if (nearestNodeAverage != null && nearestNodeTopLeft != null
&& nearestNodeAverage.node == nearestNodeTopLeft.node && nearestNodeAverage.node == nearestNodeAnythingAnywhereLeft.node) {
return nearestNodeAverage.node;
}
return nearestNodeCurrentSimple2D.node;
} else if (nearestNodeAverage != null && nearestNodeTopLeft != null && nearestNodeAnythingAnywhereLeft != null
&& nearestNodeAverage.biasShortestDistance == nearestNodeTopLeft.biasShortestDistance
&& nearestNodeAverage.biasShortestDistance == nearestNodeAnythingAnywhereLeft.biasShortestDistance
&& nearestNodeAverage.biasShortestDistance < Double.MAX_VALUE) {
-
- if (nearestNodeOnOriginY != null && nearestNodeOnOriginY.originTopCornerDistance < nearestNodeAverage.originTopCornerDistance) {
- return nearestNodeOnOriginY.node;
- } else {
return nearestNodeAverage.node;
}
}
- }
/*
** is the average closer?
*/
if (nearestNodeAverage != null && (nearestNodeOnOriginY == null || nearestNodeAverage.biasShortestDistance < nearestNodeOnOriginY.biasShortestDistance)) {
--- 1010,1043 ----
if (nearestNodeAverage != null && nearestNodeOnOriginY.node == nearestNodeAverage.node) {
return nearestNodeOnOriginY.node;
}
! if (nearestNodeOnCurrentY != null) {
if ((nearestNodeOnCurrentY.bottomCornerDistance < nearestNodeOnOriginY.bottomCornerDistance)
&& (nearestNodeOnCurrentY.originTopCornerDistance < nearestNodeOnOriginY.originTopCornerDistance)
&& (nearestNodeOnCurrentY.bounds.getMinY() - currentTopCorner2D.getY()) < (nearestNodeOnOriginY.bounds.getMinY() - currentTopCorner2D.getY())) {
return nearestNodeOnCurrentY.node;
} else if (nearestNodeAverage == null || nearestNodeOnOriginY.averageDistance < nearestNodeAverage.averageDistance) {
return nearestNodeOnOriginY.node;
}
}
} else {
! if (nearestNodeOnCurrentY == null && nearestNodeCurrentSimple2D != null) {
if (nearestNodeAverage != null && nearestNodeTopLeft != null
&& nearestNodeAverage.node == nearestNodeTopLeft.node && nearestNodeAverage.node == nearestNodeAnythingAnywhereLeft.node) {
return nearestNodeAverage.node;
}
return nearestNodeCurrentSimple2D.node;
} else if (nearestNodeAverage != null && nearestNodeTopLeft != null && nearestNodeAnythingAnywhereLeft != null
&& nearestNodeAverage.biasShortestDistance == nearestNodeTopLeft.biasShortestDistance
&& nearestNodeAverage.biasShortestDistance == nearestNodeAnythingAnywhereLeft.biasShortestDistance
&& nearestNodeAverage.biasShortestDistance < Double.MAX_VALUE) {
return nearestNodeAverage.node;
}
}
/*
** is the average closer?
*/
if (nearestNodeAverage != null && (nearestNodeOnOriginY == null || nearestNodeAverage.biasShortestDistance < nearestNodeOnOriginY.biasShortestDistance)) {
*** 1124,1134 ****
Bounds bounds = null;
double biased2DMetric = Double.MAX_VALUE;
double current2DMetric = Double.MAX_VALUE;
double leftCornerDistance = Double.MAX_VALUE;
- double midDistance = Double.MAX_VALUE;
double rightCornerDistance = Double.MAX_VALUE;
double topCornerDistance = Double.MAX_VALUE;
double bottomCornerDistance = Double.MAX_VALUE;
double shortestDistance = Double.MAX_VALUE;
--- 1100,1109 ----
*** 1143,1153 ****
bounds = source.bounds;
biased2DMetric = source.biased2DMetric;
current2DMetric = source.current2DMetric;
leftCornerDistance = source.leftCornerDistance;
- midDistance = source.midDistance;
rightCornerDistance = source.rightCornerDistance;
shortestDistance = source.shortestDistance;
biasShortestDistance = source.biasShortestDistance;
averageDistance = source.averageDistance;
--- 1118,1127 ----