/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g2d.multileveldiagram; import java.awt.geom.AffineTransform; import java.util.List; import org.simantics.g2d.canvas.Hints; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; import org.simantics.g2d.canvas.impl.HintReflection.HintListener; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.diagram.impl.Diagram; import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant; import org.simantics.g2d.multileveldiagram.LayerComposition.LayerInfo; import org.simantics.g2d.participant.TransformUtil; import org.simantics.g2d.utils.GeometryUtils; import org.simantics.utils.datastructures.hints.IHintListener; import org.simantics.utils.datastructures.hints.IHintObservable; import org.simantics.utils.datastructures.hints.IHintContext.Key; /** * This participant changes the diagram according to zoom level. * * @author Toni Kalajainen */ public class ZoomTransitionParticipant extends AbstractDiagramParticipant { @Dependency TransformUtil util; /** Set dirty if transform changes */ @HintListener(Class=Hints.class, Field="KEY_CANVAS_TRANSFORM") public void transformChanged( IHintObservable sender, Key key, Object oldValue, Object newValue) { if (composition==null) return; if (newValue==null) return; AffineTransform at = (AffineTransform) newValue; _setZoom(at); } IHintListener compositeHintListener = new IHintListener() { @Override public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { composition = (List) newValue; AffineTransform at = util.getTransform(); _setZoom(at); } @Override public void hintRemoved(IHintObservable sender, Key key, Object oldValue) { composition = null; }}; List composition; TransitionFunction function; public ZoomTransitionParticipant(TransitionFunction function) { super(); this.function = function; } @Override public void addedToContext(ICanvasContext ctx) { AffineTransform at = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM); _setZoom(at); super.addedToContext(ctx); } @Override protected void onDiagramSet(IDiagram newDiagram, IDiagram oldDiagram) { if (newDiagram==oldDiagram) return; if (oldDiagram!=null && newDiagram==null && composition!=null&& oldDiagram.getHint(DiagramHints.KEY_LAYER_COMPOSITION)==composition) { composition = null; oldDiagram.removeKeyHintListener(DiagramHints.KEY_LAYER_COMPOSITION, compositeHintListener); } if (newDiagram!=null && composition==null && newDiagram.getHint(DiagramHints.KEY_LAYER_COMPOSITION)!=null) { newDiagram.addKeyHintListener(DiagramHints.KEY_LAYER_COMPOSITION, compositeHintListener); composition = newDiagram.getHint(DiagramHints.KEY_LAYER_COMPOSITION); } if (newDiagram != null && util!=null) _setZoom(util.getTransform()); } private void _setDiagramAndPhase(IDiagram d, Double newPhase) { Double oldPhase = diagram.getHint(TransitionDiagram.KEY_PHASE); IDiagram currentDiagram = diagram; IDiagram nextDiagram = d; if (currentDiagram!=nextDiagram) { setHint(DiagramHints.KEY_DIAGRAM, nextDiagram); System.out.println("Switching to "+nextDiagram); setDirty(); } if (newPhase!=null) { diagram.setHint(TransitionDiagram.KEY_PHASE, newPhase); setDirty(); } else if (oldPhase!=null) { diagram.removeHint(TransitionDiagram.KEY_PHASE); setDirty(); } } private void _setZoom(double zoomLevel) { if (composition==null) return; IDiagram d = Diagram.EMPTY_DIAGRAM; double phase = 0.0; for (int i=0; i=zoomLevel && li.ul<=zoomLevel) { d = li.diagram; phase = (zoomLevel - li.ul) / (li.ll - li.ul); phase = function.f(phase); phase = Math.min(phase, 1); phase = Math.max(phase, 0); break; } } _setDiagramAndPhase(d, phase); } private void _setZoom(AffineTransform at) { if (diagram==null) return; if (at==null) { _setZoom(1.0); return; } double scale = GeometryUtils.getScale(at); _setZoom(scale); } }