Package com.cburch.draw.tools

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

/* 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.event.KeyEvent;
import java.awt.event.MouseEvent;

import com.cburch.draw.actions.ModelAddAction;
import com.cburch.draw.canvas.Canvas;
import com.cburch.draw.model.CanvasModel;
import com.cburch.draw.model.CanvasObject;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.data.Location;

abstract class RectangularTool extends AbstractTool {
  private boolean active;
  private Location dragStart;
  private int lastMouseX;
  private int lastMouseY;
  private Bounds currentBounds;
 
  public RectangularTool() {
    active = false;
    currentBounds = Bounds.EMPTY_BOUNDS;
  }
 
  public abstract CanvasObject createShape(int x, int y, int w, int h);
  public abstract void drawShape(Graphics g, int x, int y, int w, int h);
  public abstract void fillShape(Graphics g, int x, int y, int w, int h);
 
  @Override
  public Cursor getCursor(Canvas canvas) {
    return Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
  }
 
  @Override
  public void toolDeselected(Canvas canvas) {
    Bounds bds = currentBounds;
    active = false;
    repaintArea(canvas, bds);
  }
 
  @Override
  public void mousePressed(Canvas canvas, MouseEvent e) {
    Location loc = Location.create(e.getX(), e.getY());
    Bounds bds = Bounds.create(loc);
    dragStart = loc;
    lastMouseX = loc.getX();
    lastMouseY = loc.getY();
    active = canvas.getModel() != null;
    repaintArea(canvas, bds);
  }
 
  @Override
  public void mouseDragged(Canvas canvas, MouseEvent e) {
    updateMouse(canvas, e.getX(), e.getY(), e.getModifiersEx());
  }
 
  @Override
  public void mouseReleased(Canvas canvas, MouseEvent e) {
    if (active) {
      Bounds oldBounds = currentBounds;
      Bounds bds = computeBounds(canvas, e.getX(), e.getY(), e.getModifiersEx());
      currentBounds = Bounds.EMPTY_BOUNDS;
      active = false;
      CanvasObject add = null;
      if (bds.getWidth() != 0 && bds.getHeight() != 0) {
        CanvasModel model = canvas.getModel();
        add = createShape(bds.getX(), bds.getY(),
            bds.getWidth(), bds.getHeight());
        canvas.doAction(new ModelAddAction(model, add));
        repaintArea(canvas, oldBounds.add(bds));
      }
      canvas.toolGestureComplete(this, add);
    }
  }
 
  @Override
  public void keyPressed(Canvas canvas, KeyEvent e) {
    int code = e.getKeyCode();
    if (active && (code == KeyEvent.VK_SHIFT || code == KeyEvent.VK_ALT
        || code == KeyEvent.VK_CONTROL)) {
      updateMouse(canvas, lastMouseX, lastMouseY, e.getModifiersEx());
    }
  }
 
  @Override
  public void keyReleased(Canvas canvas, KeyEvent e) {
    keyPressed(canvas, e);
  }
 
  private void updateMouse(Canvas canvas, int mx, int my, int mods) {
    Bounds oldBounds = currentBounds;
    Bounds bds = computeBounds(canvas, mx, my, mods);
    if (!bds.equals(oldBounds)) {
      currentBounds = bds;
      repaintArea(canvas, oldBounds.add(bds));
    }
  }
 
  private Bounds computeBounds(Canvas canvas, int mx, int my, int mods) {
    lastMouseX = mx;
    lastMouseY = my;
    if (!active) {
      return Bounds.EMPTY_BOUNDS;
    } else {
      Location start = dragStart;
      int x0 = start.getX();
      int y0 = start.getY();
      int x1 = mx;
      int y1 = my;
      if (x0 == x1 && y0 == y1) {
        return Bounds.EMPTY_BOUNDS;
      }

      boolean ctrlDown = (mods & MouseEvent.CTRL_DOWN_MASK) != 0;
      if (ctrlDown) {
        x0 = canvas.snapX(x0);
        y0 = canvas.snapY(y0);
        x1 = canvas.snapX(x1);
        y1 = canvas.snapY(y1);
      }
     
      boolean altDown = (mods & MouseEvent.ALT_DOWN_MASK) != 0;
      boolean shiftDown = (mods & MouseEvent.SHIFT_DOWN_MASK) != 0;
      if (altDown) {
        if (shiftDown) {
          int r = Math.min(Math.abs(x0 - x1), Math.abs(y0 - y1));
          x1 = x0 + r;
          y1 = y0 + r;
          x0 -= r;
          y0 -= r;
        } else {
          x0 = x0 - (x1 - x0);
          y0 = y0 - (y1 - y0);
        }
      } else {
        if (shiftDown) {
          int r = Math.min(Math.abs(x0 - x1), Math.abs(y0 - y1));
          y1 = y1 < y0 ? y0 - r : y0 + r;
          x1 = x1 < x0 ? x0 - r : x0 + r;
        }
      }
     
      int x = x0;
      int y = y0;
      int w = x1 - x0;
      int h = y1 - y0;
      if (w < 0) {
        x = x1;
        w = -w;
      }
      if (h < 0) {
        y = y1;
        h = -h;
      }
      return Bounds.create(x, y, w, h);
    }
  }

  private void repaintArea(Canvas canvas, Bounds bds) {
    canvas.repaint();
    /* The below doesn't work because Java doesn't deal correctly with stroke
     * widths that go outside the clip area
    canvas.repaintCanvasCoords(bds.getX() - 10, bds.getY() - 10,
        bds.getWidth() + 20, bds.getHeight() + 20);
     */
  }
 
  @Override
  public void draw(Canvas canvas, Graphics g) {
    Bounds bds = currentBounds;
    if (active && bds != null && bds != Bounds.EMPTY_BOUNDS) {
      g.setColor(Color.GRAY);
      drawShape(g, bds.getX(), bds.getY(), bds.getWidth(), bds.getHeight());
    }
  }

}
TOP

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

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.