import java.awt.*; import java.awt.event.*; import java.util.*; /**************************************************************** * Canvas class. Accpets inputs and draws the graph. * * - initialize(): Initializes the whole graph; * * - mouseDown(): Reacts to clicks or shift-clicks; * * - mouseDrag(): Reacts to mouse drags; * * - addPoint(): Add a point and update display; * * - deletePoint():Delete a point and update display; * * - run(): Show animation; * * - paint(): Draw graphs. * ****************************************************************/ class DrawingArea extends Canvas implements MouseListener, MouseMotionListener { private BSPCell root; private Node prevMousePos, selectPos; private Image img; private Graphics gc; private int numLinksToHighlight; /* these are accessed by the Controls object */ boolean polygonMode; boolean closeMode; public static final int nodeSize = 6; // assume this to be even public static final int nodeSizeDiv2 = nodeSize/2; public DrawingArea(int x, int y) { super(); preferredSize = new Dimension(x, y); setBackground(Color.white); addMouseListener(this); addMouseMotionListener(this); initialize(); } Dimension preferredSize; public Dimension getPreferredSize() { return preferredSize; } void setImageAndGC(Image i, Graphics g) { img = i; gc = g; repaint(); } // Initialize data structure void initialize() { root = new BSPCell(preferredSize.width, preferredSize.height); eyePoint = new Node(preferredSize.width/2, preferredSize.height/2); anchorPoint = null; setEnabled(true); prevMousePos = null; repaint(); } /* need to make eye, which is draggable */ Node eyePoint; Node anchorPoint; public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); int modifier = e.getModifiers(); Util.dbgPrintln("mpressed: "+modifier+" "+MouseEvent.BUTTON3_MASK); // checking MouseEvent.BUTTON1_MASK doesn't work for netscape, // so check for button3 and reverse the if-condition claues instead if ((modifier & MouseEvent.BUTTON3_MASK) > 0) { Util.dbgPrintln("Adding point at (" +x+","+y+")."); anchorPoint = new Node(x, y); prevMousePos = new Node(x, y); } else { eyePoint.setLocation(x,y); prevMousePos = eyePoint; } selectPos = (Node) prevMousePos.clone(); repaint(); } private boolean isVerticalDisplacement(int x, int y) { Util.assert(selectPos != null, "DrawingArea::isVerticalDisplacement"); double slope = (double) (x - selectPos.x)/(y - selectPos.y); return Math.abs(slope) >= 1.0; } public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); int modifier = e.getModifiers(); /* to restrict displacement to either HORIZONTAL or VERTICAL */ if ((modifier & MouseEvent.SHIFT_MASK) > 0) { if(isVerticalDisplacement(x, y)) y = selectPos.y; else x = selectPos.x; } int xx = Math.max(Math.min(x, getPreferredSize().width-nodeSizeDiv2), nodeSizeDiv2); int yy = Math.max(Math.min(y, getPreferredSize().height-nodeSizeDiv2), nodeSizeDiv2); Util.assert(prevMousePos != null, "DrawingArea::mouseDragged()"); Util.dbgPrintln("Dragging: (" + xx + ", " + yy + ")"); prevMousePos.setLocation(xx, yy); repaint(); } public void mouseReleased(MouseEvent e) { if(anchorPoint != null) { BSPCell.insert(root, new Segment(anchorPoint, prevMousePos)); anchorPoint = null; repaint(); } } public void mouseClicked(MouseEvent e) { return; } public void mouseEntered(MouseEvent e) { return; } public void mouseExited(MouseEvent e) { return; } public void mouseMoved(MouseEvent e) { return; } public void clear() { initialize(); } public void update(Graphics g) { //double buffering to avoid flickering if(img != null) { gc = img.getGraphics(); paint(gc); g.drawImage(img, 0, 0, this); } } public void paint(Graphics g) { super.paint(g); g.clearRect(0, 0, getPreferredSize().width, getPreferredSize().height); if(eyePoint != null) { BSPCell c = BSPCell.Locate(root, eyePoint); c.draw(g, Color.cyan); eyePoint.draw(g, Color.red); g.drawString("E", eyePoint.x+3, eyePoint.y-3); BSPCell.resetOrder(); BSPCell.Traverse(g, root, eyePoint); } if(anchorPoint != null) { // dragging anchorPoint.draw(g, Color.blue); prevMousePos.draw(g, Color.blue); g.drawLine(anchorPoint.x, anchorPoint.y, prevMousePos.x, prevMousePos.y); } } }