/******************************************************************************* * CogTool Copyright Notice and Distribution Terms * CogTool 1.3, Copyright (c) 2005-2013 Carnegie Mellon University * This software is distributed under the terms of the FSF Lesser * Gnu Public License (see LGPL.txt). * * CogTool is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * CogTool is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with CogTool; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * CogTool makes use of several third-party components, with the * following notices: * * Eclipse SWT version 3.448 * Eclipse GEF Draw2D version 3.2.1 * * Unless otherwise indicated, all Content made available by the Eclipse * Foundation is provided to you under the terms and conditions of the Eclipse * Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this * Content and is also available at http://www.eclipse.org/legal/epl-v10.html. * * CLISP version 2.38 * * Copyright (c) Sam Steingold, Bruno Haible 2001-2006 * This software is distributed under the terms of the FSF Gnu Public License. * See COPYRIGHT file in clisp installation folder for more information. * * ACT-R 6.0 * * Copyright (c) 1998-2007 Dan Bothell, Mike Byrne, Christian Lebiere & * John R Anderson. * This software is distributed under the terms of the FSF Lesser * Gnu Public License (see LGPL.txt). * * Apache Jakarta Commons-Lang 2.1 * * This product contains software developed by the Apache Software Foundation * (http://www.apache.org/) * * jopt-simple version 1.0 * * Copyright (c) 2004-2013 Paul R. Holser, Jr. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Mozilla XULRunner 1.9.0.5 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/. * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The J2SE(TM) Java Runtime Environment version 5.0 * * Copyright 2009 Sun Microsystems, Inc., 4150 * Network Circle, Santa Clara, California 95054, U.S.A. All * rights reserved. U.S. * See the LICENSE file in the jre folder for more information. ******************************************************************************/ package edu.cmu.cs.hcii.cogtool.uimodel; import java.util.EventObject; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.TreeSearch; import org.eclipse.draw2d.XYLayout; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; import edu.cmu.cs.hcii.cogtool.model.Design; import edu.cmu.cs.hcii.cogtool.model.DoublePoint; import edu.cmu.cs.hcii.cogtool.model.DoubleSize; import edu.cmu.cs.hcii.cogtool.model.Frame; import edu.cmu.cs.hcii.cogtool.model.IWidget; import edu.cmu.cs.hcii.cogtool.model.InputDevice; import edu.cmu.cs.hcii.cogtool.model.Transition; import edu.cmu.cs.hcii.cogtool.model.TransitionSource; import edu.cmu.cs.hcii.cogtool.model.WidgetAttributes; import edu.cmu.cs.hcii.cogtool.model.WidgetType; import edu.cmu.cs.hcii.cogtool.util.Alerter; import edu.cmu.cs.hcii.cogtool.util.GraphicsUtil; import edu.cmu.cs.hcii.cogtool.util.AlertHandler; import edu.cmu.cs.hcii.cogtool.util.NameChangeAlert; import edu.cmu.cs.hcii.cogtool.util.NullSafe; import edu.cmu.cs.hcii.cogtool.util.PrecisionUtilities; import edu.cmu.cs.hcii.cogtool.util.WindowUtil; import edu.cmu.cs.hcii.cogtool.view.ScalableFrameFigure; import edu.cmu.cs.hcii.cogtool.view.ScalableInteractiveFigure; public class StructureViewUIModel extends Alerter { /** * Updates DesignEditorFrame in response to location changes in * the corresponding Frame and acts as the event for notifying * the UI enclosing this StructureView. */ public class OriginChangeHandler extends StructureViewUIModel.FrameShapeChange implements AlertHandler { public OriginChangeHandler(DesignEditorFrame figure) { super(StructureViewUIModel.this, figure); } public void handleAlert(EventObject alert) { Frame.OriginChange chg = (Frame.OriginChange) alert; if (chg != null) { Frame frame = (Frame) chg.getSource(); if (frame != null) { DoublePoint origin = frame.getFrameOrigin(); Point localOrigin = PrecisionUtilities.getDraw2DPoint(origin); frameFigure.setLocation(localOrigin); raiseAlert(this); } } } } /** * Notifies UI closing this StructureView when DesignEditorFrame * changes size as a result of a WidgetShapeChange alert. */ protected StructureViewUIModel.FrameShapeChange frameShapeChangeEvent = new StructureViewUIModel.FrameShapeChange(this, null); protected AlertHandler shapeChangeHandler = new AlertHandler() { public void handleAlert(EventObject alert) { FrameUIModel.WidgetShapeImageChange chg = (FrameUIModel.WidgetShapeImageChange) alert; FrameUIModel frameUIModel = (FrameUIModel) chg.getSource(); frameShapeChangeEvent.frameFigure = installedFrames.get(frameUIModel.getFrame()); raiseAlert(frameShapeChangeEvent); } }; protected Design design; protected boolean showToolTips; protected int sourceRolloverCursor; /** * Maps Frame to DesignEditorFrame */ protected Map<Frame, DesignEditorFrame> installedFrames = new HashMap<Frame, DesignEditorFrame>(); /** * Maps Transition to DesignEditorTransition */ protected Map<Transition, DesignEditorTransition> installedTransitions = new HashMap<Transition, DesignEditorTransition>(); /** * Set of transitions whose source widgets might be "hidden" */ protected Set<DesignEditorTransition> checkSrcTransitions = new HashSet<DesignEditorTransition>(); /** * Contains all elements which are displayed. * This includes the interaction layer which must always be on top * as well as the figures. */ protected ScalableInteractiveFigure contents; protected StructureViewUIModel.FrameAdd frameAddEvent = new StructureViewUIModel.FrameAdd(this); protected StructureViewUIModel.FrameNameChange frameNameChangeEvent = new StructureViewUIModel.FrameNameChange(this); protected StructureViewUIModel.FrameRecovery frameRecoveryEvent = new StructureViewUIModel.FrameRecovery(this); protected StructureViewUIModel.TransitionAddRemove transitionAddRemoveEvent = new StructureViewUIModel.TransitionAddRemove(this); protected AlertHandler frameNameChangeHandler = new AlertHandler() { public void handleAlert(EventObject alert) { frameNameChangeEvent.frame = (Frame) alert.getSource(); raiseAlert(frameNameChangeEvent); } }; protected AlertHandler widgetRecoveryHandler = new AlertHandler() { public void handleAlert(EventObject alert) { FrameUIModel.WidgetRecovery evt = (FrameUIModel.WidgetRecovery) alert; if (evt != null) { uninstallSourceTransitions(evt.widgetFigure); } } }; protected AlertHandler destinationChangeHandler = null; protected AlertHandler actionChangeHandler = null; // Only DesignEditorFrame or DesignEditorTransition public static final int NO_SOURCE = 6; // Only IGraphicalSource is ok public static final int SOURCE_ONLY = 5; // Only DesignEditorFrame is ok public static final int FRAME_ONLY = 4; // DesignEditorFrame or IGraphicalSource public static final int NO_TRANSITION = 3; // DesignEditorFrame, IGraphicalSource, DesignEditorTransition public static final int NO_LABEL = 2; // DesignEditorFrame.FrameLabel or DesignEditorFrame public static final int FRAME_LABEL = 1; // All four (below) are ok public static final int ALL_FIGURES = 0; /** * Constructor that allows the parent to be a Figure. * This allows the structure view UIModel to be associated with * the script editor. * * @param model * @param parent * */ public StructureViewUIModel(Design model, boolean supportToolTips) { this(model, null, null, supportToolTips, WindowUtil.SELECT_CURSOR); } public StructureViewUIModel(Design model, AlertHandler destinationChgHandler, AlertHandler actionChgHandler, int srcRolloverCursor) { this(model, destinationChgHandler, actionChgHandler, true, srcRolloverCursor); } public StructureViewUIModel(Design model, AlertHandler destinationChgHandler, AlertHandler actionChgHandler, boolean supportToolTips, int srcRolloverCursor) { super(); // long start = System.currentTimeMillis(); // System.out.println("\nStructureViewUIModel<init>:" + start + " { "); showToolTips = supportToolTips; sourceRolloverCursor = srcRolloverCursor; destinationChangeHandler = destinationChgHandler; actionChangeHandler = actionChgHandler; // If the passed in model is null, throw an invalid parameter. if (model == null) { throw new IllegalArgumentException("Cannot create a StructureViewUIModel with a null Design model"); } // Store model for reference design = model; // Show the frames & react to changes setUpContents(); AlertHandler deviceChangeHandler = new AlertHandler() { public void handleAlert(EventObject alert) { Iterator<DesignEditorFrame> allFrames = installedFrames.values().iterator(); while (allFrames.hasNext()) { DesignEditorFrame frameFig = allFrames.next(); frameFig.noteDeviceTypeAdd(); } } }; design.addHandler(this, Design.DeviceTypeChange.class, deviceChangeHandler); /** * Create the handler that will install the visible representation * a new frame or remove the representation of a removed frame. * <p> * One must create the representation of the frame itself before trying * to install the visible representations for the transitions * emanating from the frame's widgets and devices. * <p> * Installing/removing the visible representations of the transitions * incident on (that is, targeting) this frame is the responsibility of * a handler listening for changes in a source's transition set. These * changes will be made in the controller. * * @author mlh */ AlertHandler designChangeHandler = new AlertHandler() { public void handleAlert(EventObject alert) { Design.FrameChange chg = (Design.FrameChange) alert; if (chg != null) { if (chg.isAdd) { DesignEditorFrame frameFigure = installFrame((Frame) chg.element); // Install transitions from this frame installFrameTransitions((Frame) chg.element, frameFigure); frameAddEvent.setFrameFigure(frameFigure); raiseAlert(frameAddEvent); contents.repaint(); } else { recoverFrame((Frame) chg.element); } } } }; design.addHandler(this, Design.FrameChange.class, designChangeHandler); designChangeHandler = new AlertHandler() { public void handleAlert(EventObject alert) { Design.FrameSetChange chg = (Design.FrameSetChange) alert; if (chg != null) { if (chg.isAdd) { // Create frame representations first for (Frame frame : chg.frames) { installFrame(frame); } // Then, create transitions for (Frame frame : chg.frames) { installFrameTransitions(frame); } } } } }; design.addHandler(this, Design.FrameSetChange.class, designChangeHandler); // long end = System.currentTimeMillis(); // System.out.println("\n" + (end-start) + " } " + end); } protected void setUpContents() { contents = new ScalableFrameFigure(GraphicsUtil.defaultWidgetColor); contents.setScale(1.0); contents.setLayoutManager(new XYLayout()); installFrames(); // Resize to preferred size. DoubleSize s = getPreferredSize(); contents.setSize(PrecisionUtilities.round(s.width), PrecisionUtilities.round(s.height)); } /** * Provide public access to the ScalableContents. * @return */ public ScalableInteractiveFigure getContents() { return contents; } /** * Returns the size needed to see all elements at the current scale * @return */ public DoubleSize getPreferredSize() { return getPreferredSize(contents.getScale()); } /** * Returns the size needed to see all elements at the specified scale * @return */ public DoubleSize getPreferredSize(double scaleFactor) { Rectangle r = computeFrameArea(); // Apply scaling to result. return new DoubleSize(r.width * scaleFactor, r.height * scaleFactor); } protected Rectangle computeFrameArea() { Rectangle r = null; Iterator<DesignEditorFrame> frames = installedFrames.values().iterator(); while (frames.hasNext()) { DesignEditorFrame frameFigure = frames.next(); if (r == null) { r = new Rectangle(frameFigure.getBounds()); } else { r.union(frameFigure.getBounds()); } } return (r != null) ? r : new Rectangle(0, 0, 0, 0); } protected static class FigureFilterSearch implements TreeSearch { protected int filter; public FigureFilterSearch(int figFilter) { filter = figFilter; } public void setFilter(int newFigureFilter) { filter = newFigureFilter; } protected boolean canBeTransitionSource(IFigure figure) { if (figure instanceof GraphicalSource<?>) { if (figure instanceof GraphicalWidget<?>) { GraphicalWidget<?> gw = (GraphicalWidget<?>) figure; IWidget w = gw.getModel(); if (w.getWidgetType() == WidgetType.Noninteractive) { return false; } Object isSeparator = w.getAttribute(WidgetAttributes.IS_SEPARATOR_ATTR); if (NullSafe.equals(WidgetAttributes.IS_SEPARATOR, isSeparator)) { return false; } } return true; } return false; } public boolean accept(IFigure figure) { switch (filter) { case StructureViewUIModel.FRAME_LABEL: { return (figure instanceof DesignEditorFrame) || (figure instanceof DesignEditorFrame.FrameLabel); } case StructureViewUIModel.NO_LABEL: { return (figure instanceof DesignEditorFrame) || canBeTransitionSource(figure) || (figure instanceof DesignEditorTransition); } case StructureViewUIModel.NO_TRANSITION: { return (figure instanceof DesignEditorFrame) || canBeTransitionSource(figure); } case StructureViewUIModel.NO_SOURCE: { return (figure instanceof DesignEditorFrame) || (figure instanceof DesignEditorTransition); } case StructureViewUIModel.FRAME_ONLY: { return (figure instanceof DesignEditorFrame); } case StructureViewUIModel.SOURCE_ONLY: { return canBeTransitionSource(figure); } case StructureViewUIModel.ALL_FIGURES: default: { return true; } } } public boolean prune(IFigure figure) { return false; } } public static class FrameShapeChange extends EventObject { protected DesignEditorFrame frameFigure; public FrameShapeChange(StructureViewUIModel ui, DesignEditorFrame figure) { super(ui); frameFigure = figure; } public DesignEditorFrame getFrameFigure() { return frameFigure; } } public static class FrameNameChange extends EventObject { public Frame frame; public FrameNameChange(StructureViewUIModel ui) { super(ui); } public Frame getFrame() { return frame; } } public static class FrameAdd extends EventObject { public DesignEditorFrame frameFigure; public FrameAdd(StructureViewUIModel ui) { super(ui); } public DesignEditorFrame getFrameFigure() { return frameFigure; } public void setFrameFigure(DesignEditorFrame frameFig) { frameFigure = frameFig; } } public static class FrameRecovery extends EventObject { protected DesignEditorFrame frameFigure = null; public FrameRecovery(StructureViewUIModel ui) { super(ui); } public DesignEditorFrame getFrameFigure() { return frameFigure; } public void setFrameFigure(DesignEditorFrame frameFig) { frameFigure = frameFig; } } public static class TransitionAddRemove extends EventObject { protected DesignEditorTransition transitionFigure = null; public boolean isAdd = false; public TransitionAddRemove(StructureViewUIModel ui) { super(ui); } public DesignEditorTransition getTransitionFigure() { return transitionFigure; } public void setTransitionFigure(DesignEditorTransition transitionFig, boolean add) { transitionFigure = transitionFig; isAdd = add; } } protected static final FigureFilterSearch figureFilter = new FigureFilterSearch(StructureViewUIModel.ALL_FIGURES); public IFigure getFigureAtXY(int x, int y, int filter) { figureFilter.setFilter(filter); return contents.findFigureAt(x, y, figureFilter); } public DesignEditorFrame getFrameAtXY(int x, int y) { return (DesignEditorFrame) getFigureAtXY(x, y, StructureViewUIModel.FRAME_ONLY); } public GraphicalSource<?> getSourceAtXY(int x, int y) { return (GraphicalSource<?>) getFigureAtXY(x, y, StructureViewUIModel.SOURCE_ONLY); } public Iterator<DesignEditorFrame> getAllFrameFigures() { return installedFrames.values().iterator(); } public DesignEditorFrame getFrameFigure(Frame frame) { return installedFrames.get(frame); } public DesignEditorTransition getTransitionFigure(Transition transition) { return installedTransitions.get(transition); } /** * Override the dispose method so that it only disposes the view if it is * not null. * * Also removes listeners created on the frame. * */ public void dispose() { design.removeAllHandlers(this); // Call dispose on the DesignEditorFrameFigures, so that we // do not get called when a change in a frame occurs. (EVEN if we are // disposed) Alternative solution, have a dispose flag, and stop // events from "propagating" when disposed. // But that will likely cause memory to "Balloon" over time // Call recoverFrame(Frame frame) on all frames? maybe slow... but // cleans up EVERYTHING Iterator<Frame> frames = design.getFrames().iterator(); while (frames.hasNext()) { Frame frame = frames.next(); recoverFrame(frame); } } public double getZoom() { return contents.getScale(); } public void setZoom(double scale) { contents.setScale(scale); //... draw... //... repaint... } /** * Remove the visible representation of the given Frame. * <p> * ...here */ protected void recoverFrame(Frame frame) { DesignEditorFrame frameFigure = installedFrames.remove(frame); if (frameFigure != null) { frameRecoveryEvent.setFrameFigure(frameFigure); raiseAlert(frameRecoveryEvent); // Remove transitions from this frame Iterator<GraphicalSource<? extends TransitionSource>> sourceFigures = frameFigure.getSourceFigureIterator(); while (sourceFigures.hasNext()) { GraphicalSource<? extends TransitionSource> sourceFigure = sourceFigures.next(); uninstallSourceTransitions(sourceFigure); } // Transitions incident to this frame are removed in controller contents.remove(frameFigure); //TODO: Do we want to attempt shrinking of containing figure here via raiseAlert? // This will remove transitions from frame figure. frameFigure.dispose(); frame.removeAllHandlers(this); } else { throw new IllegalStateException("No DesignEditorFrame to recover for the given Frame."); } } /** * Creates the visible representation of a frame, installing * the "postage stamp" version, the devices, and the transitions * connecting sources to their corresponding destination frames. * * @param frame the model of the Frame to install * @return the <code>IFigure</code> representing the frame's visible * representation * @author mlh */ protected DesignEditorFrame installFrame(Frame frame) { frame.addHandler(this, NameChangeAlert.class, frameNameChangeHandler); // Create the figure for the frame // For the handlers below, we need the frame figure in order to // fetch the figure corresponding to each "modified" source. final DesignEditorFrame frameFig = new DesignEditorFrame(frame, showToolTips, sourceRolloverCursor); frameFig.addWidgetShapeChangeHandler(shapeChangeHandler); frameFig.addWidgetRecoveryHandler(widgetRecoveryHandler); frameFig.addOriginChangeHandler(new OriginChangeHandler(frameFig)); // Whenever a transition is added or removed from a source, // the transition's visible representation must be added or // removed as well. final AlertHandler transitionHandler = new AlertHandler() { public void handleAlert(EventObject alert) { TransitionSource.TransitionChange chg = (TransitionSource.TransitionChange) alert; if (chg != null) { GraphicalSource<?> sourceFigure = frameFig.getSourceFigure((TransitionSource) alert.getSource()); if (chg.isAdd) { installSourceTransition((Transition) chg.element, sourceFigure); } else { uninstallSourceTransition((Transition) chg.element, sourceFigure); } } } }; frameFig.addTransitionChangeHandler(transitionHandler); // When a widget is added to or removed from this frame during the // editing of this frame (see frame editing), install or remove the // visible representations of the widget's transitions. AlertHandler widgetHandler = new AlertHandler() { public void handleAlert(EventObject alert) { Frame.WidgetChange chg = (Frame.WidgetChange) alert; IWidget chgWidget = chg.getChangeElement(); if (chg != null) { if (chg.action == Frame.WidgetChange.ELEMENT_DELETE) { chgWidget.removeHandler (TransitionSource.TransitionChange.class, transitionHandler); } else if (chg.action == Frame.WidgetChange.ELEMENT_ADD) { installSourceTransitions(frameFig, chgWidget); chgWidget.addHandler (frameFig, TransitionSource.TransitionChange.class, transitionHandler); } // At the end of all widget Change Events, refresh. contents.repaint(); } } }; frameFig.addWidgetChangeHandler(widgetHandler); // Record the correspondence between the given frame and its figure. installedFrames.put(frame, frameFig); // Install the visible representation of the frame. contents.add(frameFig); return frameFig; } // installFrame /** * Create the visible representation for the given transition * emanating from a specific source. * <p> * Finds the figure for the transition's target frame, creates the * visible representation of the transition, adds that representation * to the drawing, and registers the new transition figure with the * source figure. * <p> * The figures for the source object and destination frames * must be created/installed before attempting to create/install * the visible representations for transitions. * * @param transition the transition to install * @param sourceFigure the figure for the transition's source * @author mlh */ protected void installSourceTransition(final Transition transition, final GraphicalSource<?> sourceFigure) { DesignEditorFrame targetFigure = getFrameFigure(transition.getDestination()); final DesignEditorTransition transitionFigure = new DesignEditorTransition(transition, sourceFigure, targetFigure, showToolTips); if (sourceFigure instanceof GraphicalChildWidget<?, ?>) { checkSrcTransitions.add(transitionFigure); } installedTransitions.put(transition, transitionFigure); AlertHandler localDestChangeHandler = new AlertHandler() { public void handleAlert(EventObject alert) { DesignEditorFrame newTargetFigure = installedFrames.get(transition.getDestination()); if (newTargetFigure != null) { sourceFigure.buildToolTip(); transitionFigure.changeTarget(newTargetFigure); } if (destinationChangeHandler != null) { destinationChangeHandler.handleAlert(alert); } } }; transitionFigure.addDestinationChangeHandler(localDestChangeHandler); if (actionChangeHandler != null) { transitionFigure.addActionChangeHandler(actionChangeHandler); } contents.add(transitionFigure); sourceFigure.addTransition(transition, transitionFigure); transitionAddRemoveEvent.setTransitionFigure(transitionFigure, true); raiseAlert(transitionAddRemoveEvent); } /** * Create the visible representations for all of the transitions * emanating from a specific source. * <p> * The figures for the source object and destination frames * must be created/installed before attempting to create/install * the visible representations for transitions. * * @param srcFrameFigure the figure for the frame containing the widget * @param widget the source widget whose transitions to install * @author mlh */ protected void installSourceTransitions(DesignEditorFrame srcFrameFigure, TransitionSource source) { // Find the figure for the source widget GraphicalSource<?> sourceFigure = srcFrameFigure.getSourceFigure(source); Iterator<Transition> transitions = source.getTransitions().values().iterator(); while (transitions.hasNext()) { Transition transition = transitions.next(); installSourceTransition(transition, sourceFigure); } } protected void recoverTransition(DesignEditorTransition transitionFig) { transitionAddRemoveEvent.setTransitionFigure(transitionFig, false); raiseAlert(transitionAddRemoveEvent); checkSrcTransitions.remove(transitionFig); contents.remove(transitionFig); transitionFig.dispose(); } protected void uninstallSourceTransition(Transition transition, GraphicalSource<?> sourceFigure) { DesignEditorTransition transitionFigure = sourceFigure.removeTransition(transition); recoverTransition(transitionFigure); } /** * Remove the visible representations of all transitions emanating * from the given widget figure. * <p> * This determines the source widget's figure and invokes the * one-parameter signature. * <p> * Removes each transition figure from the drawing and from the * source widget's figure's list. * * @param srcFrameFigure the figure for the frame containing the widget * @param widget the source widget whose transitions to remove * @author mlh */ protected void uninstallWidgetTransitions(DesignEditorFrame srcFrameFigure, IWidget widget) { GraphicalSource<?> sourceFigure = srcFrameFigure.getWidgetFigure(widget); uninstallSourceTransitions(sourceFigure); } /** * Remove the visible representations of all transitions emanating * from the given source figure. * <p> * Removes each transition figure from the drawing and from the * source figure's list. * * @param sourceFigure the figure of the source whose transitions to remove * @author mlh */ protected void uninstallSourceTransitions(GraphicalSource<?> sourceFigure) { Iterator<DesignEditorTransition> transitionFigures = sourceFigure.getTransitionsIterator(); while (transitionFigures.hasNext()) { DesignEditorTransition transitionFigure = transitionFigures.next(); recoverTransition(transitionFigure); transitionFigures.remove(); } } /** * Create the visible representations for all of the transitions * emanating from all source objects (widgets/devices) of a frame. * <p> * This signature fetches the figure representing frame in the * structure view and invokes the two-parameter signature. * <p> * The figures for transition sources and destination frames * must be created/installed before attempting to create/install * the visible representations for transitions. * * @param frame the frame containing the sources of the * transitions to install * @author mlh */ protected void installFrameTransitions(Frame frame) { DesignEditorFrame sourceFrame = installedFrames.get(frame); installFrameTransitions(frame, sourceFrame); } /** * Create the visible representations for all of the transitions * emanating from all source objects (widgets/devices) of a frame. * <p> * The figures for transition sources and destination frames * must be created/installed before attempting to create/install * the visible representations for transitions. * * @param frame the frame containing the sources of the * transitions to install * @param sourceFrame the figure representing frame in the structure view * @author mlh */ protected void installFrameTransitions(Frame frame, DesignEditorFrame sourceFrame) { Iterator<IWidget> widgets = frame.getWidgets().iterator(); while (widgets.hasNext()) { IWidget widget = widgets.next(); installSourceTransitions(sourceFrame, widget); } Iterator<InputDevice> devices = frame.getInputDevices().iterator(); while (devices.hasNext()) { InputDevice device = devices.next(); installSourceTransitions(sourceFrame, device); } } /** * Create visible representations for the frames and transitions of * a design. * * @author mlh */ protected void installFrames() { // Create frame representations first Iterator<Frame> frames = design.getFrames().iterator(); while (frames.hasNext()) { Frame frame = frames.next(); installFrame(frame); } // Then, create transitions frames = design.getFrames().iterator(); while (frames.hasNext()) { Frame frame = frames.next(); installFrameTransitions(frame); } } /** * Support for resetting transition source anchors for those transitions * whose sources may be "hidden". */ public void resetHiddenTransitionSources() { Iterator<DesignEditorTransition> checkTransitions = checkSrcTransitions.iterator(); while (checkTransitions.hasNext()) { DesignEditorTransition transitionFig = checkTransitions.next(); GraphicalSource<?> sourceFig = transitionFig.getSource(); while ((sourceFig != null) && (sourceFig instanceof GraphicalChildWidget<?, ?>) && ! sourceFig.isVisible()) { sourceFig = ((GraphicalChildWidget<?, ?>) sourceFig).getParentFigure(); } transitionFig.resetSourceAnchor(sourceFig); } } }