Package com.cburch.draw.tools

Source Code of com.cburch.draw.tools.CurveTool

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.draw.tools;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.List;

import javax.swing.Icon;

import com.cburch.draw.actions.ModelAddAction;
import com.cburch.draw.canvas.Canvas;
import com.cburch.draw.model.CanvasModel;
import com.cburch.draw.shapes.Curve;
import com.cburch.draw.shapes.CurveUtil;
import com.cburch.draw.shapes.DrawAttr;
import com.cburch.draw.shapes.LineUtil;
import com.cburch.logisim.data.Attribute;
import com.cburch.logisim.data.Location;
import com.cburch.logisim.util.Icons;

public class CurveTool extends AbstractTool {
  private static final int BEFORE_CREATION = 0;
  private static final int ENDPOINT_DRAG = 1;
  private static final int CONTROL_DRAG = 2;
 
  private DrawingAttributeSet attrs;
  private int state;
  private Location end0;
  private Location end1;
  private Curve curCurve;
  private boolean mouseDown;
  private int lastMouseX;
  private int lastMouseY;
 
  public CurveTool(DrawingAttributeSet attrs) {
    this.attrs = attrs;
    state = BEFORE_CREATION;
    mouseDown = false;
  }
 
  @Override
  public Icon getIcon() {
    return Icons.getIcon("drawcurv.gif");
  }

  @Override
  public Cursor getCursor(Canvas canvas) {
    return Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
  }
 
  @Override
  public void toolDeselected(Canvas canvas) {
    state = BEFORE_CREATION;
    repaintArea(canvas);
  }
 
  @Override
  public void mousePressed(Canvas canvas, MouseEvent e) {
    int mx = e.getX();
    int my = e.getY();
    lastMouseX = mx;
    lastMouseY = my;
    mouseDown = true;
    int mods = e.getModifiersEx();
    if ((mods & InputEvent.CTRL_DOWN_MASK) != 0) {
      mx = canvas.snapX(mx);
      my = canvas.snapY(my);
    }
   
    switch (state) {
    case BEFORE_CREATION:
    case CONTROL_DRAG:
      end0 = Location.create(mx, my);
      end1 = end0;
      state = ENDPOINT_DRAG;
      break;
    case ENDPOINT_DRAG:
      curCurve = new Curve(end0, end1, Location.create(mx, my));
      state = CONTROL_DRAG;
      break;
    }
    repaintArea(canvas);
  }
 
  @Override
  public void mouseDragged(Canvas canvas, MouseEvent e) {
    updateMouse(canvas, e.getX(), e.getY(), e.getModifiersEx());
    repaintArea(canvas);
  }
 
  @Override
  public void mouseReleased(Canvas canvas, MouseEvent e) {
    Curve c = updateMouse(canvas, e.getX(), e.getY(), e.getModifiersEx());
    mouseDown = false;
    if (state == CONTROL_DRAG) {
      if (c != null) {
        attrs.applyTo(c);
        CanvasModel model = canvas.getModel();
        canvas.doAction(new ModelAddAction(model, c));
        canvas.toolGestureComplete(this, c);
      }
      state = BEFORE_CREATION;
    }
    repaintArea(canvas);
  }
 
  @Override
  public void keyPressed(Canvas canvas, KeyEvent e) {
    int code = e.getKeyCode();
    if (mouseDown && (code == KeyEvent.VK_SHIFT
        || code == KeyEvent.VK_CONTROL || code == KeyEvent.VK_ALT)) {
      updateMouse(canvas, lastMouseX, lastMouseY, e.getModifiersEx());
      repaintArea(canvas);
    }
  }
 
  @Override
  public void keyReleased(Canvas canvas, KeyEvent e) {
    keyPressed(canvas, e);
  }

  @Override
  public void keyTyped(Canvas canvas, KeyEvent e) {
    char ch = e.getKeyChar();
    if (ch == '\u001b') { // escape key
      state = BEFORE_CREATION;
      repaintArea(canvas);
      canvas.toolGestureComplete(this, null);
    }
  }
 
  private Curve updateMouse(Canvas canvas, int mx, int my, int mods) {
    lastMouseX = mx;
    lastMouseY = my;
   
    boolean shiftDown = (mods & MouseEvent.SHIFT_DOWN_MASK) != 0;
    boolean ctrlDown = (mods & MouseEvent.CTRL_DOWN_MASK) != 0;
    boolean altDown = (mods & MouseEvent.ALT_DOWN_MASK) != 0;
    Curve ret = null;
    switch (state) {
    case ENDPOINT_DRAG:
      if (mouseDown) {
        if (shiftDown) {
          Location p = LineUtil.snapTo8Cardinals(end0, mx, my);
          mx = p.getX();
          my = p.getY();
        }
        if (ctrlDown) {
          mx = canvas.snapX(mx);
          my = canvas.snapY(my);
        }
        end1 = Location.create(mx, my);
      }
      break;
    case CONTROL_DRAG:
      if (mouseDown) {
        int cx = mx;
        int cy = my;
        if (ctrlDown) {
          cx = canvas.snapX(cx);
          cy = canvas.snapY(cy);
        }
        if (shiftDown) {
          double x0 = end0.getX();
          double y0 = end0.getY();
          double x1 = end1.getX();
          double y1 = end1.getY();
          double midx = (x0 + x1) / 2;
          double midy = (y0 + y1) / 2;
          double dx = x1 - x0;
          double dy = y1 - y0;
          double[] p = LineUtil.nearestPointInfinite(cx, cy,
              midx, midy, midx - dy, midy + dx);
          cx = (int) Math.round(p[0]);
          cy = (int) Math.round(p[1]);
        }
        if (altDown) {
          double[] e0 = { end0.getX(), end0.getY() };
          double[] e1 = { end1.getX(), end1.getY() };
          double[] mid = { cx, cy };
          double[] ct = CurveUtil.interpolate(e0, e1, mid);
          cx = (int) Math.round(ct[0]);
          cy = (int) Math.round(ct[1]);
        }
        ret = new Curve(end0, end1, Location.create(cx, cy));
        curCurve = ret;
      }
      break;
    }
    return ret;
  }

  private void repaintArea(Canvas canvas) {
    canvas.repaint();
  }
 
  @Override
  public List<Attribute<?>> getAttributes() {
    return DrawAttr.getFillAttributes(attrs.getValue(DrawAttr.PAINT_TYPE));
  }

  @Override
  public void draw(Canvas canvas, Graphics g) {
    g.setColor(Color.GRAY);
    switch (state) {
    case ENDPOINT_DRAG:
      g.drawLine(end0.getX(), end0.getY(), end1.getX(), end1.getY());
      break;
    case CONTROL_DRAG:
      ((Graphics2D) g).draw(curCurve.getCurve2D());
      break;
    }
  }
}
TOP

Related Classes of com.cburch.draw.tools.CurveTool

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.