Package org.joshy.sketch.tools

Source Code of org.joshy.sketch.tools.DrawPathTool

package org.joshy.sketch.tools;

import org.joshy.gfx.draw.FlatColor;
import org.joshy.gfx.draw.Font;
import org.joshy.gfx.draw.GFX;
import org.joshy.gfx.draw.Transform;
import org.joshy.gfx.event.ActionEvent;
import org.joshy.gfx.event.Callback;
import org.joshy.gfx.event.KeyEvent;
import org.joshy.gfx.event.MouseEvent;
import org.joshy.gfx.node.NodeUtils;
import org.joshy.gfx.node.control.Togglebutton;
import org.joshy.gfx.node.control.Button;
import org.joshy.gfx.node.layout.FlexBox;
import org.joshy.gfx.node.layout.HFlexBox;
import org.joshy.sketch.Main;
import org.joshy.sketch.actions.UndoManager;
import org.joshy.sketch.actions.UndoableAddNodeAction;
import org.joshy.sketch.model.SPath;
import org.joshy.sketch.model.SketchDocument;
import org.joshy.sketch.modes.vector.VectorDocContext;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class DrawPathTool extends CanvasTool {
    private SPath node;
    private SPath.PathPoint currentPoint;
    private boolean couldClose;
    private SPath.PathPoint hoverPoint = null;
    private boolean couldDelete;
    private boolean couldReshape;
    private boolean adjusting;
    private boolean spacePressed;
    private boolean altPressed;
    private boolean couldMove;
    private Point2D.Double prev;
    private Point2D.Double curr;
    private Point2D.Double start;
    private boolean editingExisting;
    private SPath.PathTuple addLocation;
    private SPath.PathPoint selectedPoint;
    private boolean adjustingControlPoint;
    private int activeControlPoint;
    private Cursor penCursor;
    private Cursor reshapeCursor;
    private Cursor deleteCursor;
    private Cursor addCursor;
    private SPath.PathPoint undoReference;
    private SPath.PathPoint redoReference;
    private FlexBox panel;
    private Togglebutton moveButton;
    private Togglebutton deleteButton;
    private Togglebutton reshapeButton;
    private Button endButton;
    private SPath.SubPath hoverSubpath;

    private enum Tool { Delete, Reshape, Move };
    private Tool defaultTool = Tool.Move;

    public DrawPathTool(VectorDocContext context) {
        super(context);
        try {
            BufferedImage cursorImage = ImageIO.read(Main.class.getResource("resources/pentool_cursor.png"));
            penCursor = java.awt.Toolkit.getDefaultToolkit().createCustomCursor(cursorImage, new java.awt.Point(5,0),"pen");
            BufferedImage reshapeCursorImage = ImageIO.read(Main.class.getResource("resources/pen_^.png"));
            reshapeCursor = java.awt.Toolkit.getDefaultToolkit().createCustomCursor(reshapeCursorImage, new java.awt.Point(5,0),"pen");
            BufferedImage deleteCursorImage = ImageIO.read(Main.class.getResource("resources/pen_-.png"));
            deleteCursor = java.awt.Toolkit.getDefaultToolkit().createCustomCursor(deleteCursorImage, new java.awt.Point(5,0),"pen");
            BufferedImage addCursorImage = ImageIO.read(Main.class.getResource("resources/pen_+.png"));
            addCursor = java.awt.Toolkit.getDefaultToolkit().createCustomCursor(addCursorImage, new java.awt.Point(5,0),"pen");
        } catch (IOException e) {
            e.printStackTrace();
        }
        panel = new HFlexBox().setBoxAlign(HFlexBox.Align.Baseline);
        moveButton = new Togglebutton("move");
        moveButton.onClicked(new Callback<ActionEvent>() {
            public void call(ActionEvent actionEvent) throws Exception {
                defaultTool = Tool.Move;
                updateToolButtons();
            }
        });
        panel.add(moveButton);
        deleteButton = new Togglebutton("delete");
        deleteButton.onClicked(new Callback<ActionEvent>() {
            public void call(ActionEvent actionEvent) throws Exception {
                defaultTool = Tool.Delete;
                updateToolButtons();
            }
        });
        panel.add(deleteButton);
        reshapeButton = new Togglebutton("reshape");
        reshapeButton.onClicked(new Callback<ActionEvent>() {
            public void call(ActionEvent actionEvent) throws Exception {
                defaultTool = Tool.Reshape;
                updateToolButtons();
            }
        });
        panel.add(reshapeButton);
        endButton = new Button("end");
        endButton.onClicked(new Callback<ActionEvent>() {
            public void call(ActionEvent actionEvent) throws Exception {
                DrawPathTool.this.context.releaseControl();
            }
        });
        panel.add(endButton);
        panel.setTranslateX(100);
        panel.setTranslateY(20);

        defaultTool = Tool.Move;
        updateToolButtons();
    }

    @Override
    protected void call(KeyEvent event) {
        if(event.getType() == KeyEvent.KeyPressed) {
            if(event.getKeyCode() == KeyEvent.KeyCode.KEY_SPACE) {
                spacePressed = true;
            }
            if(event.getKeyCode() == KeyEvent.KeyCode.KEY_ALT) {
                altPressed = true;
            }
            if(event.getKeyCode() == KeyEvent.KeyCode.KEY_X) {
                cycleTool();
            }
            refreshStates();
        }
        if(event.getType() == KeyEvent.KeyReleased) {
            if(event.getKeyCode() == KeyEvent.KeyCode.KEY_SPACE) {
                spacePressed = false;
            }
            if(event.getKeyCode() == KeyEvent.KeyCode.KEY_ALT) {
                altPressed = false;
            }
            if(event.getKeyCode() == KeyEvent.KeyCode.KEY_ESCAPE) {
                context.releaseControl();
            }
            refreshStates();
        }
        context.redraw();
    }

    private void setCursor(Cursor cursor) {
        Frame frame = (Frame) context.getStage().getNativeWindow();
        frame.setCursor(cursor);
    }

    private void setDefaultCursor() {
        Frame frame = (Frame) context.getStage().getNativeWindow();
        frame.setCursor(Cursor.getDefaultCursor());
    }


    private void cycleTool() {
        switch(defaultTool) {
            case Move: defaultTool = Tool.Delete; break;
            case Delete: defaultTool = Tool.Reshape; break;
            case Reshape: defaultTool = Tool.Move; break;
        }
        updateToolButtons();
        context.redraw();
    }

    private void updateToolButtons() {
        moveButton.setSelected(defaultTool==Tool.Move);
        deleteButton.setSelected(defaultTool == Tool.Delete);
        reshapeButton.setSelected(defaultTool == Tool.Reshape);
    }

    public void enable() {
        super.enable();
        setCursor(penCursor);
        NodeUtils.doSkins(panel);
        panel.doPrefLayout();
        panel.doLayout();
        panel.setFill(FlatColor.BLACK.deriveWithAlpha(0.3));
        context.getCanvas().getParent().getStage().getPopupLayer().add(panel);
        Point2D pt = NodeUtils.convertToScene(context.getCanvas(), 20, 20);
        panel.setTranslateX(pt.getX());
        panel.setTranslateY(pt.getY());
    }

    public void disable() {
        if(enabled) {
            setDefaultCursor();
            if(node != null) {
                if(!editingExisting) {
                    SketchDocument doc = context.getDocument();
                    doc.getCurrentPage().add(node);
                    context.getUndoManager().pushAction(new UndoableAddNodeAction(context,node,"path"));
                }
                node = null;
                clear();
                editingExisting = false;
            }
        }
        super.disable();
        context.getCanvas().getParent().getStage().getPopupLayer().remove(panel);
    }


    private void clear() {
        adjusting = false;
        currentPoint = null;
        couldClose = false;
        couldDelete = false;
        couldReshape = false;
        couldMove = false;
        spacePressed = false;
        hoverPoint = null;
        adjustingControlPoint = false;
        activeControlPoint = 0;
    }

    @Override
    protected void mouseMoved(MouseEvent event, Point2D.Double cursor) {
        curr = toolToModel(cursor);
        refreshStates();
    }

    private double getPointThreshold() {
        return 10.0/context.getSketchCanvas().getScale();
    }

    private void refreshStates() {
        if(node != null && !adjusting && curr != null) {
            hoverPoint = null;
            hoverSubpath = null;
            couldClose = false;
            couldDelete = false;
            couldReshape = false;
            couldMove = false;

            setCursor(penCursor);
           
            for(SPath.SubPath sub : node.getSubPaths()) {
                //hovering over close point
                SPath.PathPoint start = sub.getPoint(0);
                if(start.distance(curr.x,curr.y) < getPointThreshold() && !sub.closed()) {
                    hoverSubpath = sub;
                    couldClose = true;
                    hoverPoint = start;
                    context.redraw();
                    return;
                }

                for(SPath.PathPoint pt : sub.getPoints()) {
                    if(pt.distance(curr.x,curr.y)<getPointThreshold()) {
                        hoverSubpath = sub;
                        if(!couldClose) {
                            hoverPoint = pt;
                            if(defaultTool == Tool.Move) {
                                couldMove = true;
                                setCursor(penCursor);
                                addLocation = null;
                                context.redraw();
                                return;
                            }
                            if(defaultTool == Tool.Reshape) {
                                couldReshape = true;
                                setCursor(reshapeCursor);
                                addLocation = null;
                                context.redraw();
                                return;
                            }
                            if(defaultTool == Tool.Delete) {
                                couldDelete = true;
                                setCursor(deleteCursor);
                                addLocation = null;
                                context.redraw();
                                return;
                            }
                        }
                    }
                }
            }

            boolean foundClose = false;
            for(SPath.SubPath sub : node.getSubPaths()) {
                for(SPath.PathSegment seg : sub.calculateSegments()) {
                    SPath.PathTuple closest = seg.closestDistance(curr);
                    if(closest.distance < getPointThreshold()) {
                        addLocation = closest;
                        hoverSubpath = sub;
                        foundClose = true;
                    }
                }
            }
            if(!foundClose) {
                addLocation = null;
            } else {
                setCursor(addCursor);               
            }

            //main for hovering over possible deletion point
            context.redraw();
        }
    }


    @Override
    protected void mousePressed(MouseEvent event, Point2D.Double cursor) {
        start = toolToModel(cursor);
        prev = toolToModel(cursor);
        if(node == null) {
            node = new SPath();
            currentPoint = new SPath.PathPoint(start.x,start.y);
            currentPoint.startPath = true;
            node.addPoint(currentPoint);
            context.getUndoManager().pushAction(new UndoableAddNodeAction(context,node,"path"));
            context.redraw();
            return;
        }

        if(selectedPoint != null && (defaultTool == Tool.Move || defaultTool == Tool.Reshape)) {
            undoReference = selectedPoint.copy();
            redoReference = selectedPoint;
            if(start.distance(selectedPoint.x,selectedPoint.y) < getPointThreshold()) {
                //u.p("can reshape the center of the point");
                adjusting = true;
                context.redraw();
                return;
            }
            if(start.distance(selectedPoint.cx1,selectedPoint.cy1) < getPointThreshold()) {
                //u.p("can adjust the control point 1");
                adjustingControlPoint = true;
                activeControlPoint = 1;
                context.redraw();
                return;
            }
            if(start.distance(selectedPoint.cx2,selectedPoint.cy2) < getPointThreshold()) {
                //u.p("can adjust the control point 2");
                adjustingControlPoint = true;
                activeControlPoint = 2;
                context.redraw();
                return;
            }
        }

        if(couldMove) {
            adjusting = true;
            selectedPoint = hoverPoint;
            undoReference = selectedPoint.copy();
            redoReference = selectedPoint;
            context.redraw();
            return;
        }

        if(spacePressed && hoverPoint != null) {
            context.redraw();
            return;
        }
       
        undoReference = null;
        redoReference = null;

        if(couldClose) {
            SPath.PathPoint start = hoverSubpath.getPoint(0);
            if(start.distance(start.x,start.y) < getPointThreshold()) {
                couldClose = false;
                hoverSubpath.doAutoclose();
                SketchDocument doc = context.getDocument();
                doc.getCurrentPage().add(node);
                //node already added at this point
                //context.getUndoManager().pushAction(new UndoableAddNodeAction(context,node,"path"));
                node.normalize();
                currentPoint = null;
                node = null;
                context.releaseControl();
            }
            context.redraw();
            return;
        }

        if(couldReshape) {
            hoverPoint.cx1 = hoverPoint.x;
            hoverPoint.cx2 = hoverPoint.x;
            hoverPoint.cy1 = hoverPoint.y;
            hoverPoint.cy2 = hoverPoint.y;
            selectedPoint = hoverPoint;
            adjusting = true;
            undoReference = selectedPoint.copy();
            redoReference = selectedPoint;
            context.redraw();
            return;
        }

        if(couldDelete) {
            deletePoint(hoverPoint);
            return;
        }
       
        if(addLocation != null) {
            insertPoint();
            return;
        }


        if(!editingExisting) {
            addPoint(start);
            return;
        }
    }

    private void addPoint(Point2D.Double start) {
        if(start == null) return;
        if(hoverSubpath == null) {
            hoverSubpath = node.getSubPaths().get(0);
        }
        currentPoint = new SPath.PathPoint(start.x,start.y);
        final SPath.PathPoint temp = currentPoint;
        hoverSubpath.addPoint(currentPoint);
        final SPath.SubPath tempsub = hoverSubpath;
        context.redraw();       
        context.getUndoManager().pushAction(new UndoManager.UndoableAction(){
            public void executeUndo() {
                tempsub.removePoint(temp);
            }
            public void executeRedo() {
                tempsub.addPoint(temp);
            }
            public String getName() {
                return "add point";
            }
        });       
    }

    private void insertPoint() {
        if(hoverSubpath == null) return;
        if(addLocation == null) return;
        final SPath.PathTuple temp = addLocation.copy();
        final SPath.PathPoint a = addLocation.a.copy();
        final SPath.PathPoint b = addLocation.b.copy();
        final SPath.PathPoint pt = hoverSubpath.splitPath(addLocation);
        final SPath.SubPath tempsub = hoverSubpath;
        context.getUndoManager().pushAction(new UndoManager.UndoableAction(){
            public void executeUndo() {
                tempsub.unSplitPath(temp, a, b, pt);
            }
            public void executeRedo() {
                tempsub.splitPath(temp);
            }
            public String getName() {
                return "insert point";
            }
        });
        context.redraw();
        addLocation = null;
    }

    private void deletePoint(SPath.PathPoint hoverPoint) {
        if(hoverPoint == null) return;
        if(hoverSubpath == null) return;
        final SPath.PathPoint temp = hoverPoint.copy();
        final SPath.SubPath cs = hoverSubpath;
        final int tempIndex = hoverSubpath.getPoints().indexOf(hoverPoint);
        hoverSubpath.removePoint(hoverPoint);
        context.getUndoManager().pushAction(new UndoManager.UndoableAction(){
            public void executeUndo() {
                cs.getPoints().add(tempIndex, temp);
            }
            public void executeRedo() {
                cs.getPoints().remove(temp);
            }
            public String getName() {
                return "remove point";
            }
        });
        context.redraw();
    }

    @Override
    protected void mouseDragged(MouseEvent event, Point2D.Double cursor) {
        SPath.PathPoint point = null;
        curr = toolToModel(cursor);

        if(this.currentPoint != null) {
            point = this.currentPoint;
        }
        if(adjusting) {
            point = hoverPoint;
        }
        if(adjustingControlPoint) {
            point = selectedPoint;
        }
       
        if(point != null) {

            if(adjustingControlPoint) {
                if(activeControlPoint == 1) {
                    point.cx1 = curr.x;
                    point.cy1 = curr.y;
                }
                if(activeControlPoint == 2) {
                    point.cx2 = curr.x;
                    point.cy2 = curr.y;
                }
            } else if(spacePressed || couldMove) {
                //move a point uniformly
                double nx = curr.x;
                double ny = curr.y;
                SketchDocument doc = context.getDocument();
                if(doc.isSnapGrid()) {
                    nx = ((int)(nx/doc.getGridWidth()))*doc.getGridWidth();
                    ny = ((int)(ny/doc.getGridHeight()))*doc.getGridHeight();
                }

                boolean hsnap = false;
                boolean vsnap = false;
                //snap with guidelines next if not already snapped
                nx += node.getTranslateX();
                ny += node.getTranslateY();
                for(SketchDocument.Guideline gl : context.getDocument().getCurrentPage().getGuidelines()) {
                    double threshold = 15;
                    if(!gl.isVertical()) {
                        if(!vsnap) {
                            if(Math.abs(ny - gl.getPosition()) < threshold) {
                                ny = gl.getPosition();
                                context.getCanvas().showVSnap(gl.getPosition());
                                vsnap = true;
                            }
                        }
                    } else {
                        if(!hsnap) {
                            if(Math.abs(nx - gl.getPosition()) < threshold) {
                                nx = gl.getPosition();
                                context.getCanvas().showHSnap(gl.getPosition());
                                hsnap = true;
                            }
                        }
                    }
                }
                nx -= node.getTranslateX();
                ny -= node.getTranslateY();

                double px = point.x;
                double py = point.y;
                point.x = nx;
                point.y = ny;
                double dx = point.x - px;
                double dy = point.y - py;
                point.cx1 +=dx;
                point.cx2 +=dx;
                point.cy1 +=dy;
                point.cy2 +=dy;
            } else {
                //adjust the control points
                point.cx2 = curr.x;
                point.cy2 = curr.y;
                double dx = point.cx2-point.x;
                double dy = point.cy2-point.y;
                point.cx1 = point.x-dx;
                point.cy1 = point.y-dy;
            }
            context.redraw();
        }
        prev = toolToModel(cursor);
    }

    @Override
    protected void mouseReleased(MouseEvent event, Point2D.Double cursor) {
        if(adjusting || adjustingControlPoint) {
            final SPath.PathPoint startReference = undoReference.copy();
            final SPath.PathPoint endReference = redoReference.copy();
            final SPath.PathPoint tempPathPoint = redoReference;
            context.getUndoManager().pushAction(new UndoManager.UndoableAction(){
                public void executeUndo() {
                    tempPathPoint.copyFrom(startReference);
                    context.redraw();
                }
                public void executeRedo() {
                    tempPathPoint.copyFrom(endReference);
                    context.redraw();
                }
                public String getName() {
                    return "modify point";
                }
            });
        }

        if(node != null) {
            node.recalcPath();
        }
        clear();
    }

    public void drawOverlay(GFX g) {

        //draw overlays
        if(node != null) {

            //draw the path and handle overlays
            g.setPureStrokes(true);
            Path2D.Double path = SPath.toPath(node);

            g.translate(context.getSketchCanvas().getPanX(), context.getSketchCanvas().getPanY());
            g.scale(context.getSketchCanvas().getScale(), context.getSketchCanvas().getScale());
            g.translate(node.getTranslateX(), node.getTranslateY());
            g.translate(node.getAnchorX(), node.getAnchorY());
            g.rotate(node.getRotate(), Transform.Z_AXIS);
            g.scale(node.getScaleX(), node.getScaleY());
            g.translate(-node.getAnchorX(), -node.getAnchorY());
            g.setPaint(FlatColor.GREEN);
            g.drawPath(path);
            if(hoverSubpath != null) {
                Path2D.Double subpath = SPath.toPath(hoverSubpath);
                g.setPaint(FlatColor.RED);
                g.drawPath(subpath);
            }

            g.translate(node.getAnchorX(), node.getAnchorY());
            g.scale(1 / node.getScaleX(), 1 / node.getScaleY());
            g.rotate(-node.getRotate(), Transform.Z_AXIS);
            g.translate(-node.getAnchorX(), -node.getAnchorY());
            g.translate(-node.getTranslateX(),-node.getTranslateY());
            g.scale(1/context.getSketchCanvas().getScale(), 1/context.getSketchCanvas().getScale());
            g.translate(-context.getSketchCanvas().getPanX(), -context.getSketchCanvas().getPanY());
            g.setPureStrokes(false);



            //draw the add location
            if(addLocation != null) {
                g.setPaint(FlatColor.RED);
                Point2D pt = modelToScreen(addLocation.point);
                double size = 10.0/context.getSketchCanvas().getScale();
                g.drawOval(pt.getX()-size/2,pt.getY()-size/2,size,size);
            }


            if(adjusting) {
                drawHandles(g,hoverPoint);
            }
            if(selectedPoint != null) {
                drawHandles(g,selectedPoint);
            }
            drawHandles(g,node,5.0,1.0);

            //draw text notifications
            if(couldClose && hoverSubpath != null) {
                SPath.PathPoint point = hoverSubpath.getPoint(0);
                Point2D pt = modelToScreen(point.x,point.y);
                g.setPaint(FlatColor.RED);
                g.drawRect(pt.getX()-2,pt.getY()-2,5,5);

                g.setPaint(FlatColor.BLACK);
                g.drawText("close", Font.DEFAULT,pt.getX()-3,pt.getY()+30);
            }

            if(hoverPoint != null) {
                Point2D.Double hp = modelToScreen(hoverPoint.x,hoverPoint.y);
                if(couldMove && hoverPoint != null) {
                    g.setPaint(FlatColor.RED);
                    g.drawRect(hp.x-2,hp.y-2,5,5);

                    g.setPaint(FlatColor.BLACK);
                    g.drawText("move", Font.DEFAULT,hp.x-3,hp.y+30);
                }
                if(couldDelete) {
                    g.setPaint(FlatColor.RED);
                    g.drawRect(hp.x-2,hp.y-2,5,5);

                    g.setPaint(FlatColor.BLACK);
                    g.drawText("delete", Font.DEFAULT,hp.x-3,hp.y+30);
                }
                if(couldReshape && hoverPoint != null) {
                    g.setPaint(FlatColor.RED);
                    g.drawRect(hp.x-2,hp.y-2,5,5);

                    g.setPaint(FlatColor.BLACK);
                    if(spacePressed) {
                        g.drawText("move", Font.DEFAULT,hp.x-3,hp.y+30);
                    } else {
                        g.drawText("reshape", Font.DEFAULT,hp.x-3,hp.y+30);
                    }
                }
            }
        }
    }

    private void drawHandles(GFX g, SPath node, double size, double sw) {
        g.setPureStrokes(true);
        g.setPaint(FlatColor.BLACK);

        SPath.PathPoint last = null;
        for(SPath.SubPath path : node.getSubPaths()) {
            for(SPath.PathPoint point : path.getPoints()) {
                last = modelToScreen(point);
                g.setPaint(FlatColor.BLACK);
                g.fillRect(last.x - size / 2,last.y - size / 2, size, size);
                g.setPaint(FlatColor.WHITE);
                g.fillRect(last.x-size/2+sw,last.y-size/2+sw,size-sw*2,size-sw*2);
            }
        }
       
        if(last != null) {
            g.setPaint(FlatColor.BLACK);
            g.fillRect(last.cx1-2-1,last.cy1-2-1,size+2,size+2);
            g.fillRect(last.cx2-2-1,last.cy2-2-1,size+2,size+2);
            g.setPaint(FlatColor.RED);
            g.fillRect(last.cx1-2,last.cy1-2,size,size);
            g.fillRect(last.cx2-2,last.cy2-2,size,size);
            g.setPaint(FlatColor.RED);
            g.drawLine(last.x,last.y,last.cx1,last.cy1);
            g.drawLine(last.x,last.y,last.cx2,last.cy2);
        }
        g.setPureStrokes(false);
    }

    private void drawHandles(GFX g, SPath.PathPoint point) {
        double size = 5.0;
        point = modelToScreen(point);

        //the point itself
        g.drawRect(point.x-2,point.y-2,size,size);

        //the control points
        g.drawRect(point.cx1-2,point.cy1-2,size,size);
        g.drawRect(point.cx2-2,point.cy2-2,size,size);
        //line connecting the control points
        g.setPaint(FlatColor.RED);
        g.drawLine(point.x,point.y,point.cx1,point.cy1);
        g.drawLine(point.x,point.y,point.cx2,point.cy2);
    }

    private SPath.PathPoint modelToScreen(SPath.PathPoint point) {
        Point2D.Double xy = modelToScreen(point.x,point.y);
        Point2D.Double c1 = modelToScreen(point.cx1,point.cy1);
        Point2D.Double c2 = modelToScreen(point.cx2,point.cy2);
        return new SPath.PathPoint(xy.x,xy.y,c1.x,c1.y,c2.x,c2.y);
    }
    private Point2D.Double modelToScreen(Point2D pt) {
        return modelToScreen(pt.getX(), pt.getY());
    }
    private Point2D.Double modelToScreen(double x, double y) {
        return context.getSketchCanvas().transformToDrawing(modelToTool(new Point2D.Double(x,y),node));
    }
    private Point2D.Double modelToTool(Point2D pt, SPath node) {
        if(node != null) {
            AffineTransform af = new AffineTransform();
            af.translate(node.getTranslateX(),node.getTranslateY());
            af.translate(node.getAnchorX(),node.getAnchorY());
            af.rotate(Math.toRadians(node.getRotate()));
            af.scale(node.getScaleX(), node.getScaleY());
            af.translate(-node.getAnchorX(), -node.getAnchorY());
            Point2D pt2 = af.transform(pt, null);
            return new Point2D.Double(pt2.getX(),pt2.getY());
        }
        return new Point2D.Double(pt.getX(),pt.getY());
    }

    private Point2D.Double toolToModel(Point2D pt) {
        if(node != null) {
            try {
                AffineTransform af = new AffineTransform();
                af.translate(node.getTranslateX(),node.getTranslateY());
                af.translate(node.getAnchorX(),node.getAnchorY());
                af.rotate(Math.toRadians(node.getRotate()));
                af.scale(node.getScaleX(), node.getScaleY());
                af.translate(-node.getAnchorX(), -node.getAnchorY());
                Point2D pt2 = af.inverseTransform(pt, null);
                return new Point2D.Double(pt2.getX(),pt2.getY());
            } catch (NoninvertibleTransformException e) {
                e.printStackTrace();
            }
        }
        return new Point2D.Double(pt.getX(),pt.getY());
    }

    public void startEditing(SPath path) {
        clear();
        this.node = path;
        editingExisting = true;
        context.redraw();
    }
}
TOP

Related Classes of org.joshy.sketch.tools.DrawPathTool

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.