// Copyright (c) 1995, 1996 Regents of the University of California. // All rights reserved. // // This software was developed by the Arcadia project // at the University of California, Irvine. // // Redistribution and use in source and binary forms are permitted // provided that the above copyright notice and this paragraph are // duplicated in all such forms and that any documentation, // advertising materials, and other materials related to such // distribution and use acknowledge that the software was developed // by the University of California, Irvine. The name of the // University may not be used to endorse or promote products derived // from this software without specific prior written permission. // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED // WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. // File: ModeSelect.java // Classes: ModeSelect // Original Author: ics125b spring 1996 // $Id: ModeSelect.java,v 1.1.1.1 1997/02/27 20:52:45 chandra Exp $ package uci.graphedit; import java.awt.Frame; import java.awt.Point; import java.awt.Rectangle; import java.awt.Graphics; import java.awt.Event; import java.awt.Color; import java.util.Vector; import java.util.Enumeration; /** This class implements a Mode that interperts user input as * selecting one or more DiagramElement's. Clicking on a * DiagramElement will select it. Shift-clicking will toggle whether * it is selected. Dragging in open space will draw a selection * rectangle. Dragging on a DiagramElement will switch to * ModeModify. Dragging from a port will switch to * ModeCreateArc. ModeSelect draws itself by displaying its selection * rectangle if any.

* * Needs-More-Work: this mode has more responsibility than just making * selections, it has become the "main mode" of the editor and it has * taken resposibility for switching to other modes. I shuold probably * implement a "UIDialog" class that would have a state machine that * describes the various transitions between UI modes.

* * Needs-More-Work: there is currently a bug in shift clicking, you * cannot unselect an individual item by shift-clicking on it. * * @see ModeCreateArc * @see ModeModify * @see DiagramElement * @see Editor */ public class ModeSelect extends Mode { /** If the user drags a selection rectangle, this is the first corner */ private Point selectAnchor = new Point(0, 0); /** This is the seclection rectangle. */ private Rectangle selectRect = new Rectangle(0,0,0,0); /** True when the selection rectangle should be drawn */ private boolean showSelectRect = false; /** True when the user holds the shift key to toggle selections */ private boolean toggleSelection = false; /** Construct a new ModeSelect with the given parent */ public ModeSelect(Document par,Editor ed) { super(par); ed.setCursor(ed.DEFAULT_CURSOR); } /** Handle mouse down events by preparing for a drag. If the mouse * down event happens on a handle or an already selected object, and * the shift key is not down, then go to ModeModify. If the mouse * down event happens on a port, to to ModeCreateArc. */ public boolean mouseDown(Event e, int x, int y) { /* if control, alt, or meta is down, ModeSelect is not interested */ if ((e.modifiers & ~Event.SHIFT_MASK) != 0 ) return super.mouseDown(e, x, y); /* if multiple things are selected and the user clicked one of them */ selectAnchor = new Point(x, y); selectRect.reshape(x, y, 0, 0); toggleSelection = e.shiftDown(); DiagramElement underMouse = parent.pick(selectAnchor); if (underMouse == null) return true; if(e.clickCount==2) { Action act=new ActionSetUmlAttr(parent.getEditor(),parent); act.doIt(); } if (!parent.selection().contains(underMouse)) { if (toggleSelection) parent.toggleItem(underMouse); else parent.selectItem(underMouse); } else if (toggleSelection) parent.toggleItem(underMouse); /* Selection sel = parent.selection(); if (sel.inside(selectAnchor)) { gotoModifyMode(e, x, y); return true; } */ return true; } /** On mouse dragging, modify the selection rectangle */ public boolean mouseDrag(Event e, int x, int y) { /* if control, alt, or meta is down, ModeSelect is not interested */ if ((e.modifiers & ~Event.SHIFT_MASK) != 0 ) return super.mouseDrag(e, x, y); Selection sel = parent.selection(); if (sel.inside(selectAnchor)) { gotoModifyMode(e, x, y); return true; } showSelectRect = true; int bound_x = Math.min(selectAnchor.x, x); int bound_y = Math.min(selectAnchor.y, y); int bound_w = Math.max(selectAnchor.x, x) - bound_x; int bound_h = Math.max(selectAnchor.y, y) - bound_y; parent.damaged(selectRect); selectRect.reshape(bound_x, bound_y, bound_w, bound_h); parent.damaged(selectRect); parent.repairDamage(); // ??? should I really do this? return true; } /** On mouse up, select or toggle the selection of items under the * mouse or in the selection rectangle. */ public boolean mouseUp(Event e,int x,int y) { /* if control, alt, or meta is down, ModeSelect is not interested */ if ((e.modifiers & ~Event.SHIFT_MASK) != 0 ) return super.mouseUp(e, x, y); showSelectRect = false; Vector selectList = new Vector(); Enumeration eles = parent.view().contents().elements(); while (eles.hasMoreElements()) { DiagramElement de = (DiagramElement) eles.nextElement(); if ((selectRect.isEmpty() && de.inside(selectRect.x, selectRect.y)) || (!selectRect.isEmpty() && de.intersects(selectRect))) { selectList.addElement(de); } } if (toggleSelection) parent.toggleItems(selectList); else parent.selectItems(selectList); selectRect.grow(1,1); /* make sure it is not empty for redraw */ parent.damaged(selectRect); return true; } /** Draw this mode by drawing the selection rectangle if appropriate */ public void draw(Graphics g) { if (showSelectRect) { Color selectRectColor = (Color) Globals.prefs().rubberbandAttrs().get("LineColor"); g.setColor(selectRectColor); g.drawRect(selectRect.x, selectRect.y, selectRect.width, selectRect.height); } } /** Set the Editor's Mode to ModeModify */ protected void gotoModifyMode(Event e, int x, int y) { Mode m=new ModeModify(parent); parent.mode(m); m.mouseDown(e, x, y); } } /* end class ModeSelect */