public void createSubNode(Point point) { if (selectedNode != null) { // create sub-module final ZNodeType subtype; switch (selectedNode.getNodeType()) { case METHOD: subtype = ZNodeType.CALLEE; break; case CLASS: subtype = ZNodeType.METHOD; break; case PACKAGE: subtype = ZNodeType.CLASS; break; case CALLEE: case CALLER: case DEPENDENCY: return; default: subtype = ZNodeType.PACKAGE; } ZNode sub = createNewZ(point, subtype); if (sub != null) selectedNode.getSubmodules().add(sub); } }
@Override public void mouseReleased(MouseEvent e) { log.info("released: " + e); if (point1 != null && point2 != null) { if (draggedNode == null) { ZNode z = findZNodeAt(e.getPoint()); if (z == null) { createSubNode(e.getPoint()); } else dragged(z); } else if (e.getPoint().y >= display.getHeight() - 40) { final ZTask task = taskList.getTaskAt(e.getPoint().x, 20); if (task == null) { // TODO: show confirmation? synchronized (zNodes) { zNodes.remove(draggedNode); } } else task.add(draggedNode); draggedNode = null; } else { draggedNode.getLocation().setLocation(translateToZNodePoint(point2)); updateSubLocations(draggedNode, true, draggedNode.getLocation()); draggedNode = null; } point1 = point2 = null; } }
@Override public void keyPressed(KeyEvent e) { if (!links.isEmpty()) return; switch (e.getKeyChar()) { case 's': // TODO: Search!!!! String name = display.showInputDialog("Search", "Z"); ZTask activeTask = taskList.getActiveTask(); for (ZNode node : getZNodes()) { if (node.getName().startsWith(name)) { log.info("found {}", node.getName()); if (activeTask != null) { activeTask.add(node); } } } break; case 'm': if (selectedNode.getNodeType() == ZNodeType.CLASS) { addMethodLinks(); } break; case 'p': // TODO: add polymorphic links case 'i': case 'r': // TODO: add import/require links case 'h': case 'f': addFieldLinks(); } }
ZNode findZNodeAt(Point p) { ZNode found = null; synchronized (zNodes) { for (ZNode z : zNodes) { final double hs = z.getSize() * scale * 0.5; if (translateToDisplayPoint(z.getLocation()).distance(p.x, p.y) < hs) { found = z; } } } return found; }
public void activateGoUp() { File pFile = selectedNode.getParentFile(); if (selectedNode.getNodeType() == ZNodeType.PACKAGE) { for (int i = 0; i < selectedNode.getName().split("\\.").length; i++) { pFile = pFile.getParentFile(); } } else if (selectedNode.getNodeType() == ZNodeType.MODULE) { pFile = pFile.getParentFile(); } selectedNode = new ZCodeLoader(apiFactory).load(pFile); clicked(selectedNode); }
private void updateSubLocations(ZNode node, boolean immediate, Point2D loc) { final Point center = new Point((int) Math.round(loc.getX()), (int) Math.round(loc.getY())); // make bigger when more nodes final float factor = selectedNode == node ? (1.3f + logSize(node.getSubmodules().size()) / 2.2f) : 1.2f; int size = Math.round(sizeMap.get(node) * factor); final float xRatio = display.getWidth() / display.getHeight(); Map<ZNode, Point2D> map = new PixelZNodePositioner( center, new Dimension((int) (size * xRatio), size), new DirectionZNodePositioner(direction, makeNodePositioner())) .getNewPositions(node); for (ZNode sub : node.getSubmodules()) { pointMap.put(sub, map.get(sub)); if (immediate) sub.setLocation((java.awt.geom.Point2D.Float) map.get(sub)); updateSubLocations(sub, immediate, map.get(sub)); } if (node == selectedNode) for (ZNode dep : node.getDependencies()) { pointMap.put(dep, map.get(dep)); if (immediate) dep.setLocation((java.awt.geom.Point2D.Float) map.get(dep)); } }
protected void addFieldLinks() { log.info("addFieldLinks()"); final Map<String, ZNode> nodeMap = new HashMap<String, ZNode>(); final Pattern patt = Pattern.compile("(private |protected |public |final |static )+\\s*(\\w+)"); // TODO redo this to actually include packages for (ZNode node : selectedNode.getSubmodules()) { if (node.getNodeType() == ZNodeType.CLASS) { nodeMap.put(node.getName(), node); } } log.info("nodeMap={}", nodeMap); for (ZNode node : selectedNode.getSubmodules()) { for (String line : node.getCodeLines()) { final Matcher matcher = patt.matcher(line); if (matcher.find()) { log.info("group2={}", matcher.group(2)); if (nodeMap.containsKey(matcher.group(2))) { links.add(new ZNodeLink(node, nodeMap.get(matcher.group(2)), LinkType.HAS_A)); } } } } // just add 1 so there's at least 1 links.add(new ZNodeLink(selectedNode, selectedNode, LinkType.HAS_A)); }
protected void clicked(ZNode node) { log.info("selected: " + node); selectedNode = new ZCodeLoader(apiFactory).load(node); synchronized (zNodes) { zNodes.clear(); zNodes.add(selectedNode); zNodes.addAll(selectedNode.getDependencies()); zNodes.addAll(selectedNode.getSubmodules()); } count.set(0); state = State.ANIMATING; aniCount.set(0); final Dimension dim = display.getDimension(); sortNodes(); float selSize = (float) Math.min(dim.getWidth(), dim.getHeight()) / 2.2f; sizeMap.put(selectedNode, selSize); float shrinkFactor = 0.2f; float size = (float) (selSize * shrinkFactor); for (ZNode dep : selectedNode.getDependencies()) { sizeMap.put(dep, size); } for (ZNode sub : selectedNode.getSubmodules()) { sub = new ZCodeLoader(apiFactory).load(sub); sizeMap.put(sub, size + logSize(sub.getSubmodules().size())); synchronized (zNodes) { zNodes.addAll(sub.getSubmodules()); } for (ZNode sub2 : sub.getSubmodules()) { sizeMap.put(sub2, size * shrinkFactor + logSize(sub2.getCodeLineSize())); } } Point2D.Float center = new Point2D.Float(selSize * 1.25f, selSize); pointMap.put(node, center); updateSubLocations(selectedNode, false, center); }
private void addMethodLinks() { log.info("addMethodLinks()"); final Map<String, ZNode> nodeMap = new HashMap<String, ZNode>(); final Pattern patt = Pattern.compile("(\\w+)\\("); for (ZNode method : selectedNode.getSubmodules()) { final Matcher matcher = patt.matcher(method.getName()); if (matcher.find()) { final String name = matcher.group(1); nodeMap.put(name, method); } } log.info("nodeMap={}", nodeMap); for (ZNode method : selectedNode.getSubmodules()) { for (ZNode call : method.getSubmodules()) { // TODO fix if (nodeMap.containsKey(call.getName())) { links.add(new ZNodeLink(method, nodeMap.get(call.getName()), LinkType.METHOD_CALL)); } } } // just add 1 so there's at least 1 links.add(new ZNodeLink(selectedNode, selectedNode, LinkType.HAS_A)); }
private void sortNodes() { Collections.sort( selectedNode.getSubmodules(), new Comparator<ZNode>() { @Override public int compare(ZNode node1, ZNode node2) { switch (order) { case ALPHA: return node1.getName().compareTo(node2.getName()); case SIZE: return node1.getCodeLineSize() - node2.getCodeLineSize(); case TIME: return (int) (node1.getLastModified() - node2.getLastModified()); default: return 0; } } }); }
@Override public void mouseMoved(MouseEvent e) { final ZNode node = findZNodeAt(e.getPoint()); if (node == selectedNode) { return; } if (hoveredNode != node && hoveredNode != null) { hoveredNode.setSize(hoveredNode.getSize() * 1f / 1.1f); } if (node != null && hoveredNode != node) { node.setSize(node.getSize() * 1.1f); } hoveredNode = node; hoverText = node == null ? null : node.getName(); mouseLocation = e.getPoint(); }
public void showNewEditor(final ZNode z) { removeListeners(); final Editor editor = edit.getEditorFor(z, apiFactory); display.getContentPane().add(edit.getScrollPane()); edit.getPane().setMaximumSize(new Dimension(display.getWidth(), Integer.MAX_VALUE)); final KeyListener keyAdapter = new KeyListener() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { endEditing(); } else if (e.getKeyCode() == KeyEvent.VK_S && e.isControlDown()) { ((ZCodeEditor) editor).save(); } else if (e.getKeyCode() == KeyEvent.VK_W && e.isControlDown()) { // close just this editor. edit.remove(editor); edit.getPane().remove(editor.getEditorPanel()); display.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); if (edit.getEditors().isEmpty()) { endEditing(); } } else if (e.getKeyCode() == KeyEvent.VK_F1) { try { display.showEditorHelp(); } catch (IOException e1) { log.error(e1.getMessage()); } display.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } } @Override public void keyReleased(KeyEvent e) {} @Override public void keyTyped(KeyEvent e) { if (e.getKeyChar() == '\n') { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { try { Thread.sleep(100); // 1/10 second } catch (InterruptedException e) { } ((ZCodeEditor) editor).save(); Swutil.flashMessage(display, "Saved " + z.getName()); } }); } } }; ((ZCodeEditor) editor).addKeyListener(keyAdapter); final int size = (int) z.getSize(); editor.getEditorPanel().setSize(new Dimension(2 * size, size)); editor .getEditorPanel() .setLocation((int) z.getLocation().x - size / 2, (int) z.getLocation().y - size / 2); editor.setScale(0.25f); state = State.SELECTING; aniCount.set(10); edit.updatePaneSize(); ThreadingUtil.runAsThread( new Runnable() { @Override public void run() { // display.stop(); display.doLayout(); display.getContentPane().doLayout(); edit.getScrollPane().doLayout(); // edit.getPane().doLayout(); } }) .start(); }
private void updateEditorSize(Editor editor) { ZNode editorNode = edit.getNode(editor); int width = display.getWidth() - 50; int height = 50 + editorNode.getCodeLineSize() * 14; editor.getEditorPanel().setPreferredSize(new Dimension(width, height)); }
@Override public void run() { if ((state == State.ANIMATING && aniCount.incrementAndGet() >= 100) || (state == State.TIME_TRAVEL && aniCount.addAndGet(1) >= 999) || (state == State.SELECTING && aniCount.addAndGet(2) >= 100)) { if (state == State.ANIMATING || state == State.TIME_TRAVEL) { state = State.NORMAL; links.clear(); } else if (state == State.SELECTING) { if (edit.getEditors().isEmpty()) { state = State.NORMAL; } else { state = State.EDITING; updateEditorSize(edit.getEditors().get(0)); edit.updatePaneSize(); } } } count.incrementAndGet(); if (count.get() >= 20) { count.set(0); } final float time = aniCount.get() / 100f; if (getState() == State.SELECTING) { Editor ed = edit.getEditors().get(0); ZNode editorNode = edit.getNode(ed); Editor previousEd = edit.getEditors().size() == 1 ? null : edit.getEditors().get(1); int y = 8; if (previousEd != null) { JPanel previousPanel = previousEd.getEditorPanel(); y += previousPanel.getY() + previousPanel.getHeight(); } ed.setScale(0.25f + 0.75f * time); final Point2D point = animator.animate( editorNode.getLocation(), new Point2D.Float(8, y), time, AnimationType.COSINE); ed.getEditorPanel().setLocation((int) point.getX(), (int) point.getY()); } else if (getState() == State.ANIMATING) synchronized (zNodes) { for (ZNode node : zNodes) { if (pointMap.containsKey(node)) { node.getLocation() .setLocation( animator.animate( node.getLocation(), pointMap.get(node), time, AnimationType.COSINE)); } if (sizeMap.containsKey(node)) { final Float size = sizeMap.get(node); final Float currentSize = node.getSize(); node.setSize( (float) animator .animate( new Point2D.Float(currentSize, 0), new Point2D.Float(size, 0), time, AnimationType.COSINE) .getX()); } } } else if (getState() == State.TIME_TRAVEL && aniCount.get() * diffsMap.getLogSize() / 1000 > (aniCount.get() - 1) * diffsMap.getLogSize() / 1000) synchronized (zNodes) { final Collection<ZNodeLink> nodeLinks = diffsMap.getNodeLinks(aniCount.get() * diffsMap.getLogSize() / 1000, zNodes); if (!nodeLinks.isEmpty()) { links.clear(); links.addAll(nodeLinks); } } else if (getState() == State.TIME_TRAVEL) { if (diffsMap.author != null) { ZNode node = diffsMap.author; float t = aniCount.get() % 100 / 100f; node.getLocation() .setLocation( animator.animate( node.getLocation(), diffsMap.authorLocation, t, AnimationType.COSINE)); } } }
protected void dragged(ZNode z) { log.info("dragged: " + z); // create dependency on z? if (z.getNodeType() == ZNodeType.DEPENDENCY) selectedNode.getDependencies().add(z); }
private ZNode createNewZNode(Point point, ZNodeType type, String name) { if (name == null) { return null; } final Point2D.Float zp = translateToZNodePoint(point); final ZNode zNode = new ZNode(zp.x, zp.y, name.trim()); zNode.setNodeType(type); zNode.setParentFile(selectedNode.getParentFile()); if (type == ZNodeType.DEPENDENCY) { zNode.setCode(asList("artifactId=" + name, "groupId=" + name)); } synchronized (zNodes) { zNodes.add(zNode); } if (type == ZNodeType.METHOD) { zNode.setParentFile( new File( selectedNode.getParentFile(), selectedNode.getName() + "." + selectedNode.getExtension())); int end = selectedNode.getEndLineNumber(apiFactory.getLanguageParser()); for (ZNode method : selectedNode.getSubmodules()) { end += method.getCodeLineSize(); } zNode.setExtension(String.valueOf(end)); System.err.println("ext=" + zNode.getExtension()); } else if (type == ZNodeType.CALLEE) { selectedNode.addCodeLine(zNode.getName()); } new ZCodeSaver(apiFactory).save(zNode); return zNode; }