1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.g2d.multileveldiagram;
14 import java.awt.geom.AffineTransform;
15 import java.util.List;
17 import org.simantics.g2d.canvas.Hints;
18 import org.simantics.g2d.canvas.ICanvasContext;
19 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
20 import org.simantics.g2d.canvas.impl.HintReflection.HintListener;
21 import org.simantics.g2d.diagram.DiagramHints;
22 import org.simantics.g2d.diagram.IDiagram;
23 import org.simantics.g2d.diagram.impl.Diagram;
24 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
25 import org.simantics.g2d.multileveldiagram.LayerComposition.LayerInfo;
26 import org.simantics.g2d.participant.TransformUtil;
27 import org.simantics.g2d.utils.GeometryUtils;
28 import org.simantics.utils.datastructures.hints.IHintListener;
29 import org.simantics.utils.datastructures.hints.IHintObservable;
30 import org.simantics.utils.datastructures.hints.IHintContext.Key;
33 * This participant changes the diagram according to zoom level.
35 * @author Toni Kalajainen
37 public class ZoomTransitionParticipant extends AbstractDiagramParticipant {
39 @Dependency TransformUtil util;
41 /** Set dirty if transform changes */
42 @HintListener(Class=Hints.class, Field="KEY_CANVAS_TRANSFORM")
43 public void transformChanged(
44 IHintObservable sender,
49 if (composition==null) return;
50 if (newValue==null) return;
51 AffineTransform at = (AffineTransform) newValue;
55 IHintListener compositeHintListener = new IHintListener() {
57 public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
58 composition = (List<LayerInfo>) newValue;
59 AffineTransform at = util.getTransform();
64 public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {
68 List<LayerInfo> composition;
69 TransitionFunction function;
71 public ZoomTransitionParticipant(TransitionFunction function) {
73 this.function = function;
77 public void addedToContext(ICanvasContext ctx) {
78 AffineTransform at = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM);
80 super.addedToContext(ctx);
85 protected void onDiagramSet(IDiagram newDiagram, IDiagram oldDiagram) {
86 if (newDiagram==oldDiagram) return;
87 if (oldDiagram!=null && newDiagram==null && composition!=null&& oldDiagram.getHint(DiagramHints.KEY_LAYER_COMPOSITION)==composition) {
89 oldDiagram.removeKeyHintListener(DiagramHints.KEY_LAYER_COMPOSITION, compositeHintListener);
91 if (newDiagram!=null && composition==null && newDiagram.getHint(DiagramHints.KEY_LAYER_COMPOSITION)!=null) {
92 newDiagram.addKeyHintListener(DiagramHints.KEY_LAYER_COMPOSITION, compositeHintListener);
93 composition = newDiagram.getHint(DiagramHints.KEY_LAYER_COMPOSITION);
95 if (newDiagram != null && util!=null)
96 _setZoom(util.getTransform());
99 private void _setDiagramAndPhase(IDiagram d, Double newPhase)
101 Double oldPhase = diagram.getHint(TransitionDiagram.KEY_PHASE);
102 IDiagram currentDiagram = diagram;
103 IDiagram nextDiagram = d;
104 if (currentDiagram!=nextDiagram) {
105 setHint(DiagramHints.KEY_DIAGRAM, nextDiagram);
106 System.out.println("Switching to "+nextDiagram);
109 if (newPhase!=null) {
110 diagram.setHint(TransitionDiagram.KEY_PHASE, newPhase);
112 } else if (oldPhase!=null) {
113 diagram.removeHint(TransitionDiagram.KEY_PHASE);
118 private void _setZoom(double zoomLevel) {
119 if (composition==null) return;
120 IDiagram d = Diagram.EMPTY_DIAGRAM;
122 for (int i=0; i<composition.size(); i++)
124 LayerInfo li = composition.get(i);
125 if (li.ll>=zoomLevel && li.ul<=zoomLevel)
128 phase = (zoomLevel - li.ul) / (li.ll - li.ul);
129 phase = function.f(phase);
130 phase = Math.min(phase, 1);
131 phase = Math.max(phase, 0);
135 _setDiagramAndPhase(d, phase);
138 private void _setZoom(AffineTransform at) {
139 if (diagram==null) return;
144 double scale = GeometryUtils.getScale(at);