001/* The graph controller for the icon editor.
002
003 Copyright (c) 2003-2016 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.vergil.icon;
029
030import javax.swing.JMenu;
031import javax.swing.JToolBar;
032
033import diva.canvas.interactor.SelectionDragger;
034import diva.graph.EdgeController;
035import diva.graph.GraphPane;
036import diva.graph.NodeController;
037import ptolemy.actor.gui.Configuration;
038import ptolemy.kernel.util.Attribute;
039import ptolemy.kernel.util.InternalErrorException;
040import ptolemy.kernel.util.Locatable;
041import ptolemy.vergil.basic.BasicGraphController;
042import ptolemy.vergil.basic.NamedObjController;
043import ptolemy.vergil.kernel.AttributeController;
044
045///////////////////////////////////////////////////////////////////
046//// EditIconGraphController
047
048/**
049 A graph controller for the Ptolemy II icon editor.
050 This controller contains a set of default node controllers for attributes,
051 which are the only objects that an icon editor can contain. The default
052 controller can be overridden by attributes of type NodeControllerFactory.
053 The getNodeController() method always returns an attribute controller.
054
055 @author Edward A. Lee
056 @version $Id$
057 @since Ptolemy II 4.0
058 @Pt.ProposedRating Yellow (eal)
059 @Pt.AcceptedRating Red (johnr)
060 */
061public class EditIconGraphController extends BasicGraphController {
062    /** Create a new basic controller with default
063     *  terminal and edge interactors and default context menus.
064     */
065    public EditIconGraphController() {
066        super();
067        _createControllers();
068    }
069
070    ///////////////////////////////////////////////////////////////////
071    ////                         public methods                    ////
072
073    /** Add hot key for look inside.
074     *  @param menu The menu to add to, which is ignored.
075     *  @param toolbar The toolbar to add to, which is also ignored.
076     */
077    @Override
078    public void addToMenuAndToolbar(JMenu menu, JToolBar toolbar) {
079        super.addToMenuAndToolbar(menu, toolbar);
080
081        // FIXME: Placeholder for adding support for icon editing here.
082    }
083
084    /** Throw an exception. This should not be called.
085     *  @param edge The edge object.
086     *  @exception InternalErrorException If this is called.
087     *  @return An exception.
088     */
089    @Override
090    public EdgeController getEdgeController(Object edge) {
091        throw new InternalErrorException("An icon editor has no edges.");
092    }
093
094    /** Return the node controller appropriate for the specified object.
095     *  If the specified object is an instance of Locatable and
096     *  its container contains a NodeControllerFactory
097     *  (which is an attribute), then invoke that factory
098     *  to create a node controller.  Otherwise,
099     *  if the object implements Locatable and is contained by an
100     *  instance of Attribute, then return the attribute controller.
101     *  Otherwise, throw a runtime exception.
102     *  @param object A Vertex, Locatable, or Port.
103     *  @return object The node controller.
104     *  @exception RuntimeException If the specified object is not
105     *   a Locatable contained by an Attribute.
106     */
107    @Override
108    public NodeController getNodeController(Object object) {
109        // Defer to the superclass if it can provide a controller.
110        NodeController result = super.getNodeController(object);
111
112        if (result != null) {
113            ((NamedObjController) result).setSnapResolution(_SNAP_RESOLUTION);
114            return result;
115        }
116
117        // Superclass cannot provide a controller. Use defaults.
118        if (object instanceof Locatable) {
119            Object semanticObject = getGraphModel().getSemanticObject(object);
120
121            if (semanticObject instanceof Attribute) {
122                return _attributeController;
123            } else {
124                throw new RuntimeException(
125                        "Unrecognized object: " + semanticObject);
126            }
127        } else if (object == null) {
128            return _attributeController;
129        }
130
131        throw new RuntimeException(
132                "Node with unknown semantic object: " + object);
133    }
134
135    /** Set the configuration.  The configuration is used when
136     *  opening documentation files, for example.
137     *  @param configuration The configuration.
138     */
139    @Override
140    public void setConfiguration(Configuration configuration) {
141        super.setConfiguration(configuration);
142        _attributeController.setConfiguration(configuration);
143    }
144
145    ///////////////////////////////////////////////////////////////////
146    ////                         protected methods                 ////
147
148    /** Create the controllers for nodes in this graph.
149     *  This is called by the constructor, so derived classes that
150     *  override this must be careful not to reference local variables
151     *  defined in the derived classes, because the derived classes
152     *  will not have been fully constructed by the time this is called.
153     */
154    @Override
155    protected void _createControllers() {
156        super._createControllers();
157        _attributeController = new AttributeController(this,
158                AttributeController.FULL);
159
160        // Set the snap resolution smaller than the default of 5.0.
161        _attributeController.setSnapResolution(_SNAP_RESOLUTION);
162    }
163
164    /** Initialize all interaction on the graph pane. This method
165     *  is called by the setGraphPane() method of the superclass.
166     *  This initialization cannot be done in the constructor because
167     *  the controller does not yet have a reference to its pane
168     *  at that time.
169     */
170    @Override
171    protected void initializeInteraction() {
172        GraphPane pane = getGraphPane();
173
174        // Create and set up the selection dragger
175        _selectionDragger = new SelectionDragger(pane);
176        _selectionDragger.addSelectionModel(getSelectionModel());
177
178        super.initializeInteraction();
179    }
180
181    ///////////////////////////////////////////////////////////////////
182    ////                         protected variables               ////
183
184    /** The attribute controller. */
185    protected NamedObjController _attributeController;
186
187    ///////////////////////////////////////////////////////////////////
188    ////                         private variables                 ////
189    // The selection interactor for drag-selecting nodes
190    private SelectionDragger _selectionDragger;
191
192    // Default snap resolution.
193    private static double _SNAP_RESOLUTION = 1.0;
194}