// 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: Layer.java // Classes: Layer // Original Author: jrobbins@ics.uci.edu // $Id: Layer.java,v 1.19 1997/06/10 23:42:56 jrobbins Exp $ package uci.graphedit; import java.awt.*; import java.util.*; import java.io.*; import uci.util.*; /** A Layer is like a drawing layer in high-end drawing applications * (e.g., MacDraw Pro). A Layer is like a sheet of clear plastic that * can contain part of the picture being drawn and multiple layers are * put on top of each other to make the overall picture. Different * layers can be hidden, locked, or grayed out independently. In The * UCI Graph Editing Framework the Layer class is more abstract than * described above. LayerDiagram is a Subclass of Layer that does what * is described above. Other subclasses of Layer can provide * functionality. For example the background drawing grid is a * subclass of Layer that computes its display rather than displaying * what is stored in a data structure. Generalizing the concept of a * layer to handle grids and other computed display features gives * more power and allows the framework to be extended in building * various applications. For example an application that needs polar * coordinates might use LayerPolar, and an application that used a * world map might implement LayerMap. But since layers can be * composed, the user could put a grid in front of or behind the map.

* * This approach to implementing drawing editors is described in one * or more published papers.. UIST?

* * * FEATURE: layers * * @see LayerComposite * @see LayerDiagram * @see LayerGrid * @see LayerPolar */ public abstract class Layer extends Observable implements Observer, GEF { //////////////////////////////////////////////////////////////// // instance variables /** The name of the layer as it should appear in a menu. */ private String _name = "aLayer"; /** The type of perspectives that should appear in this layer. */ private String _type = "aLayer"; /** Does the user not want to see this layer right now? * Needs-More-Work. * * FEATURE: layers_hidden */ private boolean _hidden = false; /** Is this layer demphasized by making everything in it gray? * Needs-More-Work. * * FEATURE: layers_dimmed */ private boolean _grayed = false; /** Is this layer locked so that the user can not modify it? * Needs-More-Work. * * FEATURE: layers_locked */ private boolean _locked = false; /** Should the user be able to hide, lock, or gray this layer? * Needs-More-Work. * * FEATURE: layers_menu */ protected boolean _onMenu = false; /** * FEATURE: multiple_views */ public Vector _editors = new Vector(); //////////////////////////////////////////////////////////////// // constructors /** Construct a new layer. This abstract class really does nothing * in its constructor, but subclasses may have meaningful * constructors. */ public Layer() { } /** Set the name of the layer. */ public Layer(String name, String type) { _name = name; _type = type; } public Layer(String name) { this(name, name); } public Layer shallowCopy() { Layer lay; try { lay = (Layer) (this.getClass().newInstance()); } catch (java.lang.IllegalAccessException ignore) { return null; } catch (java.lang.InstantiationException ignore) { return null; } lay._name = _name; lay._type = _type; lay._onMenu = _onMenu; lay._grayed = _grayed; return lay; } //////////////////////////////////////////////////////////////// // accessors public String name() { return _name; } /** Reply a string useful for debugging */ public String toString() { return super.toString() + "[" + _name + "]"; } /** If this layer has the given name then return 'this', else null */ public Layer findLayerNamed(String aName) { if (aName.equals(_name)) return this; else return null; } /** get and set methods */ public void hidden(boolean b) { _hidden = b; } public boolean hidden() { return _hidden; } public void grayed(boolean b) { _grayed = b; } public boolean grayed() { return _grayed; } public void locked(boolean b) { _locked = b; } public boolean locked() { return _locked; } public void onMenu(boolean b) { _onMenu = b; } public boolean onMenu() { return _onMenu; } public Vector contents() { return null; } /** * FEATURE: multiple_views */ public Vector editors() { return _editors; } /** Most layers contain things, so I have empty implementations of * add, remove, removeAll, elements, and pick. * * @see LayerDiagram */ public void add(DiagramElement de) { } public void remove(DiagramElement de) { } public void removeAll() { } public Enumeration elements() { return (new Vector()).elements(); } /** * FEATURE: pick_objects */ public final DiagramElement pick(Point p) { return pick(p.x, p.y); } /** * FEATURE: pick_objects */ public DiagramElement pick(int x, int y) { return null; } public Enumeration elementsIn(Rectangle r) { return new EnumerationPredicate(elements(), new PredDEInRect(r)); } /** Given an object from the net-level model (e.g., NetNode or * NetPort), reply the graphical depiction of that object in this * layer, if there is one. Otherwise reply null. */ public DiagramElement perspectiveFor(Object obj) { return null; } /** By default layers do not delegate operations to * sublayers. LayerComposite overrides this operation to delegate to * one of its layers that is considered active. */ public Layer activeLayer() { return this; } /** Return a string that can be used to make some Layers show nodes * in one way and some layers show the same nodes in a different * way. By default just use the name of the layer, but in general * names are for users to specify as reminders to themselves and the * perspectiveType controls what kinds of node Perspectives will be * added to that view. */ public String perspectiveType() { return _type; } public void perspectiveType(String t) { _type = t; } /** Most layers will contain things in back to front order, so I * define empty reordering functions here. Subclasses can implement * these if appropriate. */ public void sendToBack(DiagramElement de) { } public void bringForward(DiagramElement de) { } public void sendBackward(DiagramElement de) { } public void bringToFront(DiagramElement de) { } public void reorder(DiagramElement de, int function) { } //////////////////////////////////////////////////////////////// // drawing methods /** Draw this Layer on the given Graphics. Sublasses should define * methods for drawContents, which is called from here if the layer * is not hidden. */ public void draw(Graphics g) { if (_hidden) return; if (! _grayed) drawContents(g); else drawGrayContents(g); } /** Draw the contents of this layer, subclasses must define * this. For example, LayerDiagram draws itself by drawing a list of * DiagramElement's and LayerGrid draws itself by drawing a lot * lines. */ public abstract void drawContents(Graphics g); /** Draw the contents in a dimmed, demphasized way. Calls * drawContents. Needs-More-Work: * really needs a new kind of Graphics to work right. */ public void drawGrayContents(Graphics g) { g.setColor(Color.lightGray); // g.lockColor(); // Needs-More-Work: not implemented drawContents(g); // g.unlockColor(); // Needs-More-Work: not implemented } //////////////////////////////////////////////////////////////// // notifications and updates /** When an object contained in a Layer changes state it notifies * the Layer. The Layer in turn notifies its parent Layer or some * Editor's. * * FEATURE: multiple_views */ public void update(Observable o, Object arg) { setChanged(); notifyObservers(arg); notifyEditors(arg); } /** * FEATURE: multiple_views */ public void notifyRemoved(DiagramElement de) { Enumeration eds = _editors.elements(); while (eds.hasMoreElements()) { Editor ed = (Editor) eds.nextElement(); ed.notifyRemoved(de); } } /** * FEATURE: multiple_views */ public void notifyChanged(DiagramElement de) { Enumeration eds = _editors.elements(); while (eds.hasMoreElements()) { Editor ed = (Editor) eds.nextElement(); ed.notifyChanged(de); } } /** * FEATURE: multiple_views */ public void notifyEditors(Object arg) { Enumeration eds = _editors.elements(); while (eds.hasMoreElements()) { Editor ed = (Editor) eds.nextElement(); ed.update(this, arg); } } /** * FEATURE: multiple_views */ public void refreshEditors() { Enumeration eds = _editors.elements(); while (eds.hasMoreElements()) { Editor ed = (Editor) eds.nextElement(); ed.damageAll(); } } /** * FEATURE: multiple_views */ public void addEditor(Editor ed) { _editors.addElement(ed); } /** * FEATURE: multiple_views */ public void addEditors(Vector eds) { Enumeration eachEd = eds.elements(); while (eachEd.hasMoreElements()) { Editor ed = (Editor) eachEd.nextElement(); addEditor(ed); } } /** * FEATURE: multiple_views */ public void removeEditor(Editor ed) { _editors.removeElement(ed); } /** * FEATURE: multiple_views */ public void removeEditors(Vector eds) { Enumeration eachEd = eds.elements(); while (eachEd.hasMoreElements()) { Editor ed = (Editor) eachEd.nextElement(); removeEditor(ed); } } //////////////////////////////////////////////////////////////// // user interface /** Allow the user to edit the properties of this layer (not the * properties of the contents of this layer). For example, in * LayerGrid this could set the grid size. * * @see LayerGrid */ public void adjust() { // subclasses implement this to being up dialog boxes with // prefernces related to that particular layer // Needs-More-Work: generic layer dialog box } } /* end class Layer */