com.sun.javafx.scene.traversal.TabOrderHelper Maven / Gradle / Ivy
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.javafx.scene.traversal;
import com.sun.javafx.scene.NodeHelper;
import com.sun.javafx.scene.ParentHelper;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Parent;
import java.util.List;
final class TabOrderHelper {
private static Node findPreviousFocusableInList(List nodeList, int startIndex) {
for (int i = startIndex ; i >= 0 ; i--) {
Node prevNode = nodeList.get(i);
// ParentTraverEngine can override traversability, so we need to check it first
if (isDisabledOrInvisible(prevNode)) continue;
final ParentTraversalEngine traversalEngine = prevNode instanceof Parent
? ParentHelper.getTraversalEngine((Parent) prevNode) : null;
if (prevNode instanceof Parent) {
if (traversalEngine != null && traversalEngine.canTraverse()) {
Node selected = traversalEngine.selectLast();
if (selected != null) {
return selected;
}
} else {
List prevNodesList = ((Parent) prevNode).getChildrenUnmodifiable();
if (prevNodesList.size() > 0) {
Node newNode = findPreviousFocusableInList(prevNodesList, prevNodesList.size() - 1);
if (newNode != null) {
return newNode;
}
}
}
}
if (traversalEngine != null
? traversalEngine.isParentTraversable()
: prevNode.isFocusTraversable()) {
return prevNode;
}
}
return null;
}
private static boolean isDisabledOrInvisible(Node prevNode) {
return prevNode.isDisabled() || !NodeHelper.isTreeVisible(prevNode);
}
public static Node findPreviousFocusablePeer(Node node, Parent root) {
Node startNode = node;
Node newNode = null;
List parentNodes = findPeers(startNode);
if (parentNodes == null) {
// We are at top level, so select the last focusable node
ObservableList rootChildren = ((Parent) node).getChildrenUnmodifiable();
return findPreviousFocusableInList(rootChildren, rootChildren.size() - 1);
}
int ourIndex = parentNodes.indexOf(startNode);
// Start with the siblings "to the left"
newNode = findPreviousFocusableInList(parentNodes, ourIndex - 1);
/*
** we've reached the end of the peer nodes, and none have been selected,
** time to look at our parents peers.....
*/
while (newNode == null && startNode.getParent() != root) {
List peerNodes;
int parentIndex;
Parent parent = startNode.getParent();
if (parent != null) {
// If the parent itself is traversable, select it
final ParentTraversalEngine parentEngine
= ParentHelper.getTraversalEngine(parent);
if (parentEngine != null ? parentEngine.isParentTraversable() : parent.isFocusTraversable()) {
newNode = parent;
} else {
peerNodes = findPeers(parent);
if (peerNodes != null) {
parentIndex = peerNodes.indexOf(parent);
newNode = findPreviousFocusableInList(peerNodes, parentIndex - 1);
}
}
}
startNode = parent;
}
return newNode;
}
private static List findPeers(Node node) {
List parentNodes = null;
Parent parent = node.getParent();
/*
** check that we haven't hit the top-level
*/
if (parent != null) {
parentNodes = parent.getChildrenUnmodifiable();
}
return parentNodes;
}
private static Node findNextFocusableInList(List nodeList, int startIndex) {
for (int i = startIndex ; i < nodeList.size() ; i++) {
Node nextNode = nodeList.get(i);
if (isDisabledOrInvisible(nextNode)) continue;
final ParentTraversalEngine traversalEngine = nextNode instanceof Parent
? ParentHelper.getTraversalEngine((Parent) nextNode) : null;
// ParentTraverEngine can override traversability, so we need to check it first
if (traversalEngine != null
? traversalEngine.isParentTraversable()
: nextNode.isFocusTraversable()) {
return nextNode;
}
else if (nextNode instanceof Parent) {
if (traversalEngine!= null && traversalEngine.canTraverse()) {
Node selected = traversalEngine.selectFirst();
if (selected != null) {
return selected;
} else {
// If the Parent has it's own engine, but no selection can be done, skip it
continue;
}
}
List nextNodesList = ((Parent)nextNode).getChildrenUnmodifiable();
if (nextNodesList.size() > 0) {
Node newNode = findNextFocusableInList(nextNodesList, 0);
if (newNode != null) {
return newNode;
}
}
}
}
return null;
}
public static Node findNextFocusablePeer(Node node, Parent root, boolean traverseIntoCurrent) {
Node startNode = node;
Node newNode = null;
// First, try to find next peer among the node children
if (traverseIntoCurrent && node instanceof Parent) {
newNode = findNextFocusableInList(((Parent)node).getChildrenUnmodifiable(), 0);
}
// Next step is to select the siblings "to the right"
if (newNode == null) {
List parentNodes = findPeers(startNode);
if (parentNodes == null) {
// We got a top level Node that has no focusable children (we know that from the first step above), so
// there's nothing to do.
return null;
}
int ourIndex = parentNodes.indexOf(startNode);
newNode = findNextFocusableInList(parentNodes, ourIndex + 1);
}
/*
** we've reached the end of the peer nodes, and none have been selected,
** time to look at our parents peers.....
*/
while (newNode == null && startNode.getParent() != root) {
List peerNodes;
int parentIndex;
Parent parent = startNode.getParent();
if (parent != null) {
peerNodes = findPeers(parent);
if (peerNodes != null) {
parentIndex = peerNodes.indexOf(parent);
newNode = findNextFocusableInList(peerNodes, parentIndex + 1);
}
}
startNode = parent;
}
return newNode;
}
public static Node getFirstTargetNode(Parent p) {
if (p == null || isDisabledOrInvisible(p)) return null;
final ParentTraversalEngine traversalEngine
= ParentHelper.getTraversalEngine(p);
if (traversalEngine!= null && traversalEngine.canTraverse()) {
Node selected = traversalEngine.selectFirst();
if (selected != null) {
return selected;
}
}
List parentsNodes = p.getChildrenUnmodifiable();
for (Node n : parentsNodes) {
if (isDisabledOrInvisible(n)) continue;
final ParentTraversalEngine parentEngine = n instanceof Parent
? ParentHelper.getTraversalEngine((Parent)n) : null;
if (parentEngine != null ? parentEngine.isParentTraversable() : n.isFocusTraversable()) {
return n;
}
if (n instanceof Parent) {
Node result = getFirstTargetNode((Parent)n);
if (result != null) return result;
}
}
return null;
}
public static Node getLastTargetNode(Parent p) {
if (p == null || isDisabledOrInvisible(p)) return null;
final ParentTraversalEngine traversalEngine
= ParentHelper.getTraversalEngine(p);
if (traversalEngine!= null && traversalEngine.canTraverse()) {
Node selected = traversalEngine.selectLast();
if (selected != null) {
return selected;
}
}
List parentsNodes = p.getChildrenUnmodifiable();
for (int i = parentsNodes.size() - 1; i >= 0; --i) {
Node n = parentsNodes.get(i);
if (isDisabledOrInvisible(n)) continue;
if (n instanceof Parent) {
Node result = getLastTargetNode((Parent) n);
if (result != null) return result;
}
final ParentTraversalEngine parentEngine = n instanceof Parent
? ParentHelper.getTraversalEngine((Parent) n) : null;
if (parentEngine != null ? parentEngine.isParentTraversable() : n.isFocusTraversable()) {
return n;
}
}
return null;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy