Community
Participate
Working Groups
We are using Zest to show dependency graph in m2e and users asking to provide keyboard navigation trough the graph. I think it would make sense to implement such feature at the framework level. Thanks.
I agree. Do you have particular ideas? Arrow keys that navigate to the closest node in a particular direction?
(In reply to comment #1) > Arrow keys that navigate to the closest node in a particular direction? That make sense. Also, when graph is on the scrollable panel and is bigger then visible area it should scroll to selected element if it get behind visble area. In addition, user should be able to open popup menu using standard keyboard shortcuts (like Ctrl-F10) and perhaps be able to see a tooltip (like F2 in other Eclipse editors), but those should be easy to handle in the user's code, so I am not much worried about them.
I've had same problem and build a small solution. Here for all intrested persons. Extended GraphViewer: private void selectNearbyNode(int direction) { GraphNode node = (GraphNode)graph.getSelection().get(0); org.eclipse.draw2d.geometry.Point srcPt = node.getLocation(); List<GraphNode> nodes = graph.getNodes(); GraphNode bestMatch = null; int bestAlignmentDifference = 0; double bestDirectDifference = 0; for (Iterator iterator = nodes.iterator(); iterator.hasNext();) { GraphNode object = (GraphNode) iterator.next(); org.eclipse.draw2d.geometry.Point tgtPt = object.getLocation(); // Winkel: Links 0°, oben 90°, unten 270° rechts 180° float angle = (float)Math.atan2(tgtPt.y - srcPt.y, tgtPt.x - srcPt.x) * 180 / (float)Math.PI; // Winkel korrgieren, damit er von 0 -360° geht, nicht von 0 - -/+ 180° angle += 180; boolean useVertical = false; int min = 0; int max = 0; switch (direction) { case SWT.TOP: min = 45; max = 135; break; case SWT.BOTTOM: min = 225; max = 315; break; case SWT.LEFT: min = 315; max = 405; // Wegen dem 0 Übergang etwas nachhelfen if(angle > 0 && angle < 45) angle += 360; useVertical = true; break; case SWT.RIGHT: min = 135; max = 225; useVertical = true; break; default: break; } if(object != node) { if(angle > min && angle < max) { int diff = useVertical ? tgtPt.x - srcPt.x : tgtPt.y - srcPt.y; int otherDiff = useVertical ? tgtPt.y - srcPt.y : tgtPt.x - srcPt.x; if(diff < 0) diff *= -1; if(otherDiff < 0) otherDiff *= -1; if(bestMatch == null) { bestMatch = object; bestAlignmentDifference = diff; bestDirectDifference = Math.sqrt(Math.pow(diff, 2) + Math.pow(otherDiff, 2)); } else if(bestAlignmentDifference > diff) { bestMatch = object; bestAlignmentDifference = diff; bestDirectDifference = Math.sqrt(Math.pow(diff, 2) + Math.pow(otherDiff, 2)); } else if(bestAlignmentDifference == diff) { double diffx = Math.sqrt(Math.pow(diff, 2) + Math.pow(otherDiff, 2)); if(diffx < bestDirectDifference) { bestMatch = object; bestAlignmentDifference = diff; bestDirectDifference = Math.sqrt(Math.pow(diff, 2) + Math.pow(otherDiff, 2)); } } } } } if(bestMatch != null) graph.setSelection(new GraphItem[] {bestMatch}); } Registered Keylistener: public void keyReleased(KeyEvent e) { if(e.keyCode == SWT.ARROW_UP) selectNearbyNode(SWT.TOP); if(e.keyCode == SWT.ARROW_DOWN) selectNearbyNode(SWT.BOTTOM); if(e.keyCode == SWT.ARROW_LEFT) selectNearbyNode(SWT.LEFT); if(e.keyCode == SWT.ARROW_RIGHT) selectNearbyNode(SWT.RIGHT); }