/** * Get the relative coordinates of a point within the coordinate system of a * particular SVG Element. * * @param evt Event, needs to be a DOMMouseEvent * @param reference SVG Element the coordinate system is used of * @return Array containing the X and Y values */ public static double[] getRelativeCoordinates(Event evt, Element reference) { if(evt instanceof DOMMouseEvent && reference instanceof SVGLocatable && reference instanceof SVGElement) { // Get the screen (pixel!) coordinates DOMMouseEvent gnme = (DOMMouseEvent) evt; SVGMatrix mat = ((SVGLocatable) reference).getScreenCTM(); SVGMatrix imat = mat.inverse(); SVGPoint cPt = ((SVGElement) reference).getOwnerSVGElement().createSVGPoint(); cPt.setX(gnme.getClientX()); cPt.setY(gnme.getClientY()); // Have Batik transform the screen (pixel!) coordinates into SVG element // coordinates cPt = cPt.matrixTransform(imat); return new double[] { cPt.getX(), cPt.getY() }; } return null; }
/** * Convert the coordinates of an DOM Event from screen into element * coordinates. * * @param doc Document context * @param tag Element containing the coordinate system * @param evt Event to interpret * @return coordinates */ public static SVGPoint elementCoordinatesFromEvent(Document doc, Element tag, Event evt) { try { DOMMouseEvent gnme = (DOMMouseEvent) evt; SVGMatrix mat = ((SVGLocatable) tag).getScreenCTM(); SVGMatrix imat = mat.inverse(); SVGPoint cPt = ((SVGDocument) doc).getRootElement().createSVGPoint(); cPt.setX(gnme.getClientX()); cPt.setY(gnme.getClientY()); return cPt.matrixTransform(imat); } catch(Exception e) { LoggingUtil.warning("Error getting coordinates from SVG event.", e); return null; } }
public void updateMouseDot(final Point currentLocation) { // this is only used to test the screen to document transform UpdateManager updateManager = graphPanel.svgCanvas.getUpdateManager(); if (updateManager != null) { updateManager.getUpdateRunnableQueue().invokeLater(new Runnable() { public void run() { Element labelGroup = graphPanel.doc.getElementById("LabelsGroup"); Element mouseDotElement = graphPanel.doc.getElementById("MouseDot"); if (mouseDotElement == null) { mouseDotElement = graphPanel.doc.createElementNS(graphPanel.svgNameSpace, "circle"); mouseDotElement.setAttribute("id", "MouseDot"); mouseDotElement.setAttribute("r", "5"); mouseDotElement.setAttribute("fill", "blue"); mouseDotElement.setAttribute("stroke", "none"); labelGroup.appendChild(mouseDotElement); } SVGLocatable labelGroupLocatable = (SVGLocatable) labelGroup; SVGOMPoint pointOnDocument = getPointOnDocument(currentLocation, labelGroupLocatable); mouseDotElement.setAttribute("cx", Float.toString(pointOnDocument.getX())); mouseDotElement.setAttribute("cy", Float.toString(pointOnDocument.getY())); } }); } }
public Rectangle2D.Float getBorderScreenPosition() { Rectangle2D.Float rect = getBorder(); SVGElement eleBorder = getElement(SvgElementType.Border); SVGMatrix matrix = ((SVGLocatable) eleBorder).getScreenCTM(); SVGPoint leftTopCoordinatePoint = new SVGOMPoint(rect.x, rect.y); SVGPoint leftTopScreenPoint = leftTopCoordinatePoint .matrixTransform(matrix); SVGPoint rightBottomCoordinatePoint = new SVGOMPoint(rect.x + rect.width, rect.y + rect.height); SVGPoint rightBottomScreenPoint = rightBottomCoordinatePoint .matrixTransform(matrix); Rectangle2D.Float result = new Rectangle2D.Float( leftTopScreenPoint.getX(), leftTopScreenPoint.getY(), rightBottomScreenPoint.getX() - leftTopScreenPoint.getX(), rightBottomScreenPoint.getY() - leftTopScreenPoint.getY()); return result; }
private Field addChildObjectToTree(_Object obj) { // add to tree // int index = obj.getOwner().getChildIndex(obj); Field f = obj.getOwnerField(); Element background = diagramPanel.getScene().getDocument() .getElementById("background"); SVGMatrix mat = ((SVGLocatable) background).getScreenCTM(); Point screenPosition = diagramPanel.getPopupMenuPosition(); SVGOMPoint elePosition = SVGUtils.screenToElement(mat, screenPosition); float startX = elePosition.getX() / ( f.svgScale); float startY =elePosition.getY() / ( f.svgScale); f.setStartPosition(startX, startY); treeModel.insertNodeInto(new DefaultMutableTreeNode(f), getSelectedTreeNode(), getSelectedTreeNode().getChildCount()); reloadDiagram(); return f; }
@Override public final void handleEvent(Event evt) { if (evt instanceof MouseEvent) { MouseEvent me = (MouseEvent) evt; SVGOMPoint point = screenToDocument((SVGLocatable) me.getTarget(), new SVGOMPoint(me.getClientX(), me.getClientY())); event(point, me); evt.stopPropagation(); } }
private Rectangle getRectOnDocument(final Rectangle screenRectangle, SVGLocatable targetGroupElement) { SVGOMPoint pointOnScreen = new SVGOMPoint(screenRectangle.x, screenRectangle.y); SVGOMPoint sizeOnScreen = new SVGOMPoint(screenRectangle.width, screenRectangle.height); SVGMatrix mat = targetGroupElement.getScreenCTM(); // this gives us the element to screen transform // todo: mat can be null mat = mat.inverse(); // this converts that into the screen to element transform SVGPoint pointOnDocument = pointOnScreen.matrixTransform(mat); // the diagram keeps the x and y scale equal so we can just use getA here SVGPoint sizeOnDocument = new SVGOMPoint(sizeOnScreen.getX() * mat.getA(), sizeOnScreen.getY() * mat.getA()); System.out.println("sizeOnScreen: " + sizeOnScreen); System.out.println("sizeOnDocument: " + sizeOnDocument); return new Rectangle((int) pointOnDocument.getX(), (int) pointOnDocument.getY(), (int) sizeOnDocument.getX(), (int) sizeOnDocument.getY()); }
protected void startDrag() { // dragRemainders is used to store the remainder after snap between drag updates // reset all remainders float[][] tempRemainders = new float[graphPanel.selectedGroupId.size()][]; for (int dragCounter = 0; dragCounter < tempRemainders.length; dragCounter++) { tempRemainders[dragCounter] = new float[]{0, 0}; } synchronized (SvgUpdateHandler.this) { dragRemainders = tempRemainders; // Element entityGroup = graphPanel.doc.getElementById("EntityGroup"); SVGMatrix draggedElementScreenMatrix = ((SVGLocatable) graphPanel.doc.getDocumentElement()).getScreenCTM().inverse(); dragScale = draggedElementScreenMatrix.getA(); // the drawing is proportional so only using X is adequate here } }
public SVGOMPoint getCoordinatePoint(Point2D rightBottomScreenPoint) { // convert it to a point for use with the Matrix SVGPoint pt = new SVGOMPoint((float) rightBottomScreenPoint.getX(), (float) rightBottomScreenPoint.getY()); // Get the items screen coordinates, and apply the // transformation // elem -> screen SVGMatrix mat = ((SVGLocatable) borderElement).getScreenCTM(); mat = mat.inverse(); // screen -> elem SVGOMPoint screenPoint = (SVGOMPoint) pt.matrixTransform(mat); return screenPoint; }
public void panToSelected(UniqueIdentifier[] targetIdentifiers) { Rectangle selectionSize = null; for (UniqueIdentifier currentIdentifier : targetIdentifiers) { Point currentPoint = graphPanel.entitySvg.getEntityLocationOffset(currentIdentifier); if (currentPoint != null) { if (selectionSize == null) { selectionSize = new Rectangle(currentPoint.x, currentPoint.y, 1, 1); } else { selectionSize.add(currentPoint); } } } final Rectangle selectionRect = selectionSize; // if (selectionRect != null) { // System.out.println("selectionRect: " + selectionRect.toString()); // addTestRect(selectionRect, 0); // } Rectangle renderRectScreen = graphPanel.svgCanvas.getBounds(); // System.out.println("getBounds: "+graphPanel.svgCanvas.getBounds().toString()); // System.out.println("getRenderRect: "+graphPanel.svgCanvas.getRenderRect().toString()); // System.out.println("getVisibleRect: "+graphPanel.svgCanvas.getVisibleRect().toString()); // System.out.println("renderRectScreen:" + renderRectScreen.toString()); Element labelGroup = graphPanel.doc.getElementById("LabelsGroup"); final SVGLocatable labelGroupLocatable = (SVGLocatable) labelGroup; // todo: should this be moved into the svg thread? final Rectangle renderRectDocument = getRectOnDocument(renderRectScreen, labelGroupLocatable); // System.out.println("renderRectDocument: " + renderRectDocument); // SVGOMPoint pointOnDocument = getPointOnDocument(new Point(0, 0), labelGroupLocatable); // renderRect.translate((int) pointOnDocument.getX(), (int) pointOnDocument.getY()); // addTestRect(renderRectDocument, 1); if (selectionRect != null && selectionRect != null && !renderRectDocument.contains(selectionRect)) { UpdateManager updateManager = graphPanel.svgCanvas.getUpdateManager(); if (updateManager != null) { updateManager.getUpdateRunnableQueue().invokeLater(new Runnable() { public void run() { SVGLocatable diagramGroupLocatable = (SVGLocatable) graphPanel.doc.getElementById("DiagramGroup"); final double scaleFactor = diagramGroupLocatable.getScreenCTM().getA(); // final double scaleFactor = graphPanel.svgCanvas.getRenderingTransform().getScaleX(); // System.out.println("scaleFactor: " + scaleFactor); AffineTransform at = new AffineTransform(); final double offsetX = renderRectDocument.getCenterX() - selectionRect.getCenterX(); final double offsetY = renderRectDocument.getCenterY() - selectionRect.getCenterY(); // System.out.println("offset: " + offsetX + ":" + offsetY); // SVGOMPoint offsetOnScreen = getPointOnDocument(new Point((int) offsetX, (int) offsetY), labelGroupLocatable); // System.out.println("screen offset: " + offsetOnScreen.getX() + " : " + offsetOnScreen.getY()); // at.translate(offsetOnScreen.getX(), offsetOnScreen.getY()); at.translate((offsetX / 2) * scaleFactor, (offsetY / 2) * scaleFactor); // at.scale(scaleFactor, scaleFactor); at.concatenate(graphPanel.svgCanvas.getRenderingTransform()); graphPanel.svgCanvas.setRenderingTransform(at); //... at.concatenate(diagramGroupLocatable.getTransformToElement(null)); //... graphPanel.svgCanvas.setRenderingTransform(at); } }); } } }
public Point getEntityPointOnDocument(final Point screenLocation) { Element etityGroup = graphPanel.doc.getElementById("EntityGroup"); SVGOMPoint pointOnDocument = getPointOnDocument(screenLocation, (SVGLocatable) etityGroup); return new Point((int) pointOnDocument.getX(), (int) pointOnDocument.getY()); // we discard the float precision because the diagram does not need that level of resolution }
private SVGOMPoint getPointOnScreen(final Point documentLocation, SVGLocatable targetGroupElement) { SVGOMPoint pointOnDocument = new SVGOMPoint(documentLocation.x, documentLocation.y); SVGMatrix mat = targetGroupElement.getScreenCTM(); // this gives us the element to screen transform return (SVGOMPoint) pointOnDocument.matrixTransform(mat); }
private SVGOMPoint getPointOnDocument(final Point screenLocation, SVGLocatable targetGroupElement) { SVGOMPoint pointOnScreen = new SVGOMPoint(screenLocation.x, screenLocation.y); SVGMatrix mat = targetGroupElement.getScreenCTM(); // this gives us the element to screen transform mat = mat.inverse(); // this converts that into the screen to element transform return (SVGOMPoint) pointOnScreen.matrixTransform(mat); }
public void addGraphics(final GraphicsTypes graphicsType, final Point locationOnScreen) { UpdateManager updateManager = graphPanel.svgCanvas.getUpdateManager(); if (updateManager != null) { updateManager.getUpdateRunnableQueue().invokeLater(new Runnable() { public void run() { Element labelText; switch (graphicsType) { case Circle: labelText = graphPanel.doc.createElementNS(graphPanel.svgNameSpace, "circle"); labelText.setAttribute("r", "100"); labelText.setAttribute("fill", "#ffffff"); labelText.setAttribute("stroke", "#000000"); labelText.setAttribute("stroke-width", "2"); break; case Ellipse: labelText = graphPanel.doc.createElementNS(graphPanel.svgNameSpace, "ellipse"); labelText.setAttribute("rx", "100"); labelText.setAttribute("ry", "100"); labelText.setAttribute("fill", "#ffffff"); labelText.setAttribute("stroke", "#000000"); labelText.setAttribute("stroke-width", "2"); break; case Label: labelText = graphPanel.doc.createElementNS(graphPanel.svgNameSpace, "text"); labelText.setAttribute("fill", "#000000"); labelText.setAttribute("stroke-width", "0"); labelText.setAttribute("font-size", "28"); Text textNode = graphPanel.doc.createTextNode("Label"); labelText.appendChild(textNode); break; case Polyline: labelText = graphPanel.doc.createElementNS(graphPanel.svgNameSpace, "polyline"); break; case Square: labelText = graphPanel.doc.createElementNS(graphPanel.svgNameSpace, "rect"); labelText.setAttribute("width", "100"); labelText.setAttribute("height", "100"); labelText.setAttribute("fill", "#ffffff"); labelText.setAttribute("stroke", "#000000"); labelText.setAttribute("stroke-width", "2"); break; default: return; } // * Rectangle <rect> // * Circle <circle> // * Ellipse <ellipse> // * Line <line> // * Polyline <polyline> // * Polygon <polygon> // * Path <path> UniqueIdentifier labelId = new UniqueIdentifier(UniqueIdentifier.IdentifierType.gid); labelText.setAttribute("id", labelId.getAttributeIdentifier()); // put this into the geometry group or the label group depending on its type so that labels sit above entitis and graphics sit below entities Element targetGroup; if (graphicsType.equals(GraphicsTypes.Label)) { targetGroup = graphPanel.doc.getElementById("LabelsGroup"); } else { targetGroup = graphPanel.doc.getElementById("GraphicsGroup"); } SVGOMPoint pointOnDocument = getPointOnDocument(locationOnScreen, (SVGLocatable) targetGroup); Point labelPosition = new Point((int) pointOnDocument.getX(), (int) pointOnDocument.getY()); // we discard the float precision because the diagram does not need that level of resolution final String transformAttribute = "translate(" + Integer.toString(labelPosition.x) + ", " + Integer.toString(labelPosition.y) + ")"; System.out.println("transformAttribute:" + transformAttribute); labelText.setAttribute("transform", transformAttribute); targetGroup.appendChild(labelText); graphPanel.entitySvg.entityPositions.put(labelId, new Point(labelPosition)); ((EventTarget) labelText).addEventListener("mousedown", graphPanel.mouseListenerSvg, false); resizeCanvas(graphPanel.doc.getDocumentElement(), graphPanel.doc.getElementById("DiagramGroup"), false); } }); } }
/** * Converts a point in screen coordinates to a point in document * coordinates. * * @param locatable * @param screenPoint * the point in screen coordinates * @return the point in document coordinates */ public static SVGOMPoint screenToDocument(SVGLocatable locatable, SVGOMPoint screenPoint) { SVGMatrix mat = ((SVGLocatable) locatable.getFarthestViewportElement()) .getScreenCTM().inverse(); return (SVGOMPoint) screenPoint.matrixTransform(mat); }