]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/multileveldiagram/ZoomTransitionParticipant.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / multileveldiagram / ZoomTransitionParticipant.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.g2d.multileveldiagram;\r
13 \r
14 import java.awt.geom.AffineTransform;\r
15 import java.util.List;\r
16 \r
17 import org.simantics.g2d.canvas.Hints;\r
18 import org.simantics.g2d.canvas.ICanvasContext;\r
19 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
20 import org.simantics.g2d.canvas.impl.HintReflection.HintListener;\r
21 import org.simantics.g2d.diagram.DiagramHints;\r
22 import org.simantics.g2d.diagram.IDiagram;\r
23 import org.simantics.g2d.diagram.impl.Diagram;\r
24 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;\r
25 import org.simantics.g2d.multileveldiagram.LayerComposition.LayerInfo;\r
26 import org.simantics.g2d.participant.TransformUtil;\r
27 import org.simantics.g2d.utils.GeometryUtils;\r
28 import org.simantics.utils.datastructures.hints.IHintListener;\r
29 import org.simantics.utils.datastructures.hints.IHintObservable;\r
30 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
31 \r
32 /**\r
33  * This participant changes the diagram according to zoom level.\r
34  * \r
35  * @author Toni Kalajainen\r
36  */\r
37 public class ZoomTransitionParticipant extends AbstractDiagramParticipant {\r
38 \r
39     @Dependency TransformUtil util;\r
40 \r
41     /** Set dirty if transform changes */\r
42     @HintListener(Class=Hints.class, Field="KEY_CANVAS_TRANSFORM")\r
43     public void transformChanged(\r
44             IHintObservable sender,\r
45             Key key,\r
46             Object oldValue,\r
47             Object newValue)\r
48     {\r
49         if (composition==null) return;\r
50         if (newValue==null) return;\r
51         AffineTransform at = (AffineTransform) newValue;\r
52         _setZoom(at);\r
53     }\r
54 \r
55     IHintListener compositeHintListener = new IHintListener() {\r
56         @Override\r
57         public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
58             composition = (List<LayerInfo>) newValue;\r
59             AffineTransform at = util.getTransform();\r
60             _setZoom(at);\r
61         }\r
62 \r
63         @Override\r
64         public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {\r
65             composition = null;\r
66         }};\r
67 \r
68         List<LayerInfo> composition;\r
69         TransitionFunction function;\r
70 \r
71         public ZoomTransitionParticipant(TransitionFunction function) {\r
72             super();\r
73             this.function = function;\r
74         }\r
75 \r
76         @Override\r
77         public void addedToContext(ICanvasContext ctx) {\r
78             AffineTransform at = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM);\r
79             _setZoom(at);\r
80             super.addedToContext(ctx);\r
81         }\r
82 \r
83 \r
84         @Override\r
85         protected void onDiagramSet(IDiagram newDiagram, IDiagram oldDiagram) {\r
86             if (newDiagram==oldDiagram) return;\r
87             if (oldDiagram!=null && newDiagram==null && composition!=null&& oldDiagram.getHint(DiagramHints.KEY_LAYER_COMPOSITION)==composition) {\r
88                 composition = null;\r
89                 oldDiagram.removeKeyHintListener(DiagramHints.KEY_LAYER_COMPOSITION, compositeHintListener);\r
90             }\r
91             if (newDiagram!=null && composition==null && newDiagram.getHint(DiagramHints.KEY_LAYER_COMPOSITION)!=null) {\r
92                 newDiagram.addKeyHintListener(DiagramHints.KEY_LAYER_COMPOSITION, compositeHintListener);\r
93                 composition = newDiagram.getHint(DiagramHints.KEY_LAYER_COMPOSITION);\r
94             }\r
95             if (newDiagram != null && util!=null)\r
96                 _setZoom(util.getTransform());\r
97         }\r
98 \r
99         private void _setDiagramAndPhase(IDiagram d, Double newPhase)\r
100         {\r
101             Double oldPhase = diagram.getHint(TransitionDiagram.KEY_PHASE);\r
102             IDiagram currentDiagram = diagram;\r
103             IDiagram nextDiagram = d;\r
104             if (currentDiagram!=nextDiagram) {\r
105                 setHint(DiagramHints.KEY_DIAGRAM, nextDiagram);\r
106                 System.out.println("Switching to "+nextDiagram);\r
107                 setDirty();\r
108             }\r
109             if (newPhase!=null) {\r
110                 diagram.setHint(TransitionDiagram.KEY_PHASE, newPhase);\r
111                 setDirty();\r
112             } else if (oldPhase!=null) {\r
113                 diagram.removeHint(TransitionDiagram.KEY_PHASE);\r
114                 setDirty();\r
115             }\r
116         }\r
117 \r
118         private void _setZoom(double zoomLevel) {\r
119             if (composition==null) return;\r
120             IDiagram d = Diagram.EMPTY_DIAGRAM;\r
121             double phase = 0.0;\r
122             for (int i=0; i<composition.size(); i++)\r
123             {\r
124                 LayerInfo li = composition.get(i);\r
125                 if (li.ll>=zoomLevel && li.ul<=zoomLevel)\r
126                 {\r
127                     d = li.diagram;\r
128                     phase = (zoomLevel - li.ul) / (li.ll - li.ul);\r
129                     phase = function.f(phase);\r
130                     phase = Math.min(phase, 1);\r
131                     phase = Math.max(phase, 0);\r
132                     break;\r
133                 }\r
134             }\r
135             _setDiagramAndPhase(d, phase);\r
136         }\r
137 \r
138         private void _setZoom(AffineTransform at) {\r
139             if (diagram==null) return;\r
140             if (at==null) {\r
141                 _setZoom(1.0);\r
142                 return;\r
143             }\r
144             double scale = GeometryUtils.getScale(at);\r
145             _setZoom(scale);\r
146         }\r
147 \r
148 }\r