// Copyright (c) 1996-98 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation for educational, research and non-profit // purposes, without fee, and without a written agreement is hereby granted, // provided that the above copyright notice and this paragraph appear in all // copies. Permission to incorporate this software into commercial products may // be obtained by contacting the University of California. David F. Redmiles // Department of Information and Computer Science (ICS) University of // California Irvine, California 92697-3425 Phone: 714-824-3823. This software // program and documentation are copyrighted by The Regents of the University // of California. The software program and documentation are supplied "as is", // without any accompanying services from The Regents. The Regents do not // warrant that the operation of the program will be uninterrupted or // error-free. The end-user understands that the program was developed for // research purposes and is advised not to rely exclusively on the program for // any reason. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, // INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS // DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY // DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE // SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, // ENHANCEMENTS, OR MODIFICATIONS. // File: ModeSelect.java // Classes: ModeSelect // Original Author: ics125b spring 1996 // $Id: ModeSelect.java,v 1.16 1997/06/10 23:43:13 jrobbins Exp $ package uci.graphedit; import java.awt.*; import java.util.*; /** 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.

* * FEATURE: editing_modes_select * * @see ModeCreateArc * @see ModeModify * @see DiagramElement * @see Editor */ public class ModeSelect extends Mode { //////////////////////////////////////////////////////////////// // instance variables /** 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; //////////////////////////////////////////////////////////////// // constructors and related methods /** Construct a new ModeSelect with the given parent. */ public ModeSelect(Editor par) { super(par); } /** Construct a new ModeSelect instance. Its parent must be set * before this instance can be used. */ public ModeSelect() { } /** Always false because I never want to get out of selection mode. */ public boolean canExit() { return false; } //////////////////////////////////////////////////////////////// // event handlers /** 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. * * FEATURE: select_by_click * * FEATURE: select_none * * BUG: shift_click */ public boolean mouseDown(Event e, int x, int 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 (!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. * * FEATURE: select_by_area */ public boolean mouseDrag(Event e, int x, int y) { 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); 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) { 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; } //////////////////////////////////////////////////////////////// // drawing methods /** 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); } } //////////////////////////////////////////////////////////////// // methods related to transitions among modes /** Set the Editor's Mode to ModeModify. Needs-More-Work: This * should not be in ModeSelect, I wanted to move it to ModeStack, * but it is too tighly integrated with ModeSelect. */ protected void gotoModifyMode(Event e, int x, int y) { Mode nextMode = new ModeModify(parent); parent.mode(nextMode); nextMode.mouseDown(e, x, y); } } /* end class ModeSelect */