diff options
author | Ilia Motornyi <elmot@vaadin.com> | 2017-04-05 14:14:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-05 14:14:03 +0200 |
commit | 535b879cb8180983c2da6444ec275e588fb4125f (patch) | |
tree | b92535ccbc9bd9f43b1000a73fcf2d5bf9223a30 /server | |
parent | 1a30320913e8b9ea851af3ed4a659f969aa92ee6 (diff) | |
download | vaadin-framework-535b879cb8180983c2da6444ec275e588fb4125f.tar.gz vaadin-framework-535b879cb8180983c2da6444ec275e588fb4125f.zip |
TreeGrid keyboard navigation
Fixes #8758
Diffstat (limited to 'server')
3 files changed, 68 insertions, 17 deletions
diff --git a/server/src/main/java/com/vaadin/data/provider/HierarchicalDataCommunicator.java b/server/src/main/java/com/vaadin/data/provider/HierarchicalDataCommunicator.java index b93d0c3952..b986f74ea3 100644 --- a/server/src/main/java/com/vaadin/data/provider/HierarchicalDataCommunicator.java +++ b/server/src/main/java/com/vaadin/data/provider/HierarchicalDataCommunicator.java @@ -335,14 +335,16 @@ public class HierarchicalDataCommunicator<T> extends DataCommunicator<T> { } /** - * Collapses given row, removing all its subtrees. + * Collapses given row, removing all its subtrees. Calling this method will + * have no effect if the row is already collapsed. * * @param collapsedRowKey * the key of the row, not {@code null} * @param collapsedRowIndex * the index of row to collapse + * @return {@code true} if the row was collapsed, {@code false} otherwise */ - public void doCollapse(String collapsedRowKey, int collapsedRowIndex) { + public boolean doCollapse(String collapsedRowKey, int collapsedRowIndex) { if (collapsedRowIndex < 0 | collapsedRowIndex >= mapper.getTreeSize()) { throw new IllegalArgumentException("Invalid row index " + collapsedRowIndex + " when tree grid size of " @@ -353,24 +355,30 @@ public class HierarchicalDataCommunicator<T> extends DataCommunicator<T> { Objects.requireNonNull(collapsedItem, "Cannot find item for given key " + collapsedItem); + if (mapper.isCollapsed(collapsedRowKey)) { + return false; + } int collapsedSubTreeSize = mapper.collapse(collapsedRowKey, collapsedRowIndex); - - getClientRpc().removeRows(collapsedRowIndex + 1, collapsedSubTreeSize); + getClientRpc().removeRows(collapsedRowIndex + 1, + collapsedSubTreeSize); // FIXME seems like a slight overkill to do this just for refreshing // expanded status refresh(collapsedItem); + return true; } /** - * Expands the given row. + * Expands the given row. Calling this method will have no effect if the row + * is already expanded. * * @param expandedRowKey * the key of the row, not {@code null} * @param expandedRowIndex * the index of the row to expand + * @return {@code true} if the row was expanded, {@code false} otherwise */ - public void doExpand(String expandedRowKey, final int expandedRowIndex) { + public boolean doExpand(String expandedRowKey, final int expandedRowIndex) { if (expandedRowIndex < 0 | expandedRowIndex >= mapper.getTreeSize()) { throw new IllegalArgumentException("Invalid row index " + expandedRowIndex + " when tree grid size of " @@ -388,16 +396,21 @@ public class HierarchicalDataCommunicator<T> extends DataCommunicator<T> { + " returned no child nodes."); } + if (!mapper.isCollapsed(expandedRowKey)) { + return false; + } mapper.expand(expandedRowKey, expandedRowIndex, expandedNodeSize); - getClientRpc().insertRows(expandedRowIndex + 1, expandedNodeSize); - // TODO optimize by sending "just enough" of the expanded items directly - doPushRows(Range.withLength(expandedRowIndex + 1, expandedNodeSize)); + // TODO optimize by sending "just enough" of the expanded items + // directly + doPushRows( + Range.withLength(expandedRowIndex + 1, expandedNodeSize)); // expanded node needs to be updated to be marked as expanded // FIXME seems like a slight overkill to do this just for refreshing // expanded status refresh(expandedItem); + return true; } /** @@ -419,4 +432,13 @@ public class HierarchicalDataCommunicator<T> extends DataCommunicator<T> { getActiveDataHandler().getActiveData().forEach(this::refresh); } + /** + * Returns parent index for the row or {@code null} + * + * @param rowIndex the row index + * @return the parent index or {@code null} for top-level items + */ + public Integer getParentIndex(int rowIndex) { + return mapper.getParentIndex(rowIndex); + } } diff --git a/server/src/main/java/com/vaadin/data/provider/HierarchyMapper.java b/server/src/main/java/com/vaadin/data/provider/HierarchyMapper.java index 040be6cf2f..6c6f8fdaef 100644 --- a/server/src/main/java/com/vaadin/data/provider/HierarchyMapper.java +++ b/server/src/main/java/com/vaadin/data/provider/HierarchyMapper.java @@ -442,4 +442,20 @@ class HierarchyMapper implements Serializable { } } + /** + * Returns parent index for the row or {@code null} + * + * @param rowIndex the row index + * @return the parent index or {@code null} for top-level items + */ + public Integer getParentIndex(int rowIndex) { + return nodes.stream() + .filter(treeNode -> treeNode.getParentKey() != null + && treeNode.getStartIndex() <= rowIndex + && treeNode.getEndIndex() >= rowIndex) + .min((a, b) -> Math.min(a.getEndIndex() - a.getStartIndex(), + b.getEndIndex() - b.getStartIndex())) + .map(treeNode -> treeNode.getStartIndex() - 1) + .orElse(null); + } } diff --git a/server/src/main/java/com/vaadin/ui/TreeGrid.java b/server/src/main/java/com/vaadin/ui/TreeGrid.java index 6f961990de..d91a0f9af1 100644 --- a/server/src/main/java/com/vaadin/ui/TreeGrid.java +++ b/server/src/main/java/com/vaadin/ui/TreeGrid.java @@ -37,6 +37,8 @@ import com.vaadin.data.provider.HierarchicalQuery; import com.vaadin.data.provider.InMemoryHierarchicalDataProvider; import com.vaadin.server.SerializablePredicate; import com.vaadin.shared.Registration; +import com.vaadin.shared.ui.treegrid.FocusParentRpc; +import com.vaadin.shared.ui.treegrid.FocusRpc; import com.vaadin.shared.ui.treegrid.NodeCollapseRpc; import com.vaadin.shared.ui.treegrid.TreeGridState; import com.vaadin.ui.declarative.DesignAttributeHandler; @@ -120,7 +122,7 @@ public class TreeGrid<T> extends Grid<T> { * * @param source * the tree grid this event originated from - * @param item + * @param expandedItem * the item that was expanded */ public ExpandEvent(TreeGrid<T> source, T expandedItem) { @@ -156,7 +158,7 @@ public class TreeGrid<T> extends Grid<T> { * * @param source * the tree grid this event originated from - * @param item + * @param collapsedItem * the item that was collapsed */ public CollapseEvent(TreeGrid<T> source, T collapsedItem) { @@ -182,13 +184,24 @@ public class TreeGrid<T> extends Grid<T> { public void setNodeCollapsed(String rowKey, int rowIndex, boolean collapse) { if (collapse) { - getDataCommunicator().doCollapse(rowKey, rowIndex); - fireCollapseEvent( - getDataCommunicator().getKeyMapper().get(rowKey)); + if (getDataCommunicator().doCollapse(rowKey, rowIndex)) { + fireCollapseEvent(getDataCommunicator().getKeyMapper() + .get(rowKey)); + } } else { - getDataCommunicator().doExpand(rowKey, rowIndex); - fireExpandEvent( - getDataCommunicator().getKeyMapper().get(rowKey)); + if (getDataCommunicator().doExpand(rowKey, rowIndex)) { + fireExpandEvent(getDataCommunicator().getKeyMapper() + .get(rowKey)); + } + } + } + }); + registerRpc(new FocusParentRpc() { + @Override + public void focusParent(int rowIndex, int cellIndex) { + Integer parentIndex = getDataCommunicator().getParentIndex(rowIndex); + if (parentIndex != null) { + getRpcProxy(FocusRpc.class).focusCell(parentIndex, cellIndex); } } }); |