]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/participant/OrientationRestorer.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / participant / OrientationRestorer.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.participant;\r
13 \r
14 import java.awt.geom.Point2D;\r
15 import java.awt.geom.Rectangle2D;\r
16 import java.util.Timer;\r
17 import java.util.TimerTask;\r
18 \r
19 import org.simantics.g2d.canvas.Hints;\r
20 import org.simantics.g2d.canvas.ICanvasContext;\r
21 import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;\r
22 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
23 import org.simantics.g2d.canvas.impl.HintReflection.HintListener;\r
24 import org.simantics.utils.datastructures.disposable.DisposeState;\r
25 import org.simantics.utils.datastructures.hints.IHintObservable;\r
26 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
27 import org.simantics.utils.threads.IThreadWorkQueue;\r
28 \r
29 /**\r
30  * Restores orientation of the canvas back to normal (north is up)\r
31  * \r
32  * \r
33  * @author Toni Kalajainen\r
34  */\r
35 public class OrientationRestorer extends AbstractCanvasParticipant {\r
36 \r
37     @Dependency\r
38     TransformUtil           util;\r
39     @Dependency\r
40     CanvasGrab              grab;\r
41     @Dependency\r
42     CanvasBoundsParticipant bounds;\r
43 \r
44     long                    lastTrigger;\r
45     Point2D                 centerPoint        = new Point2D.Double();\r
46 \r
47     transient Timer         timer              = new Timer("Rotate restore");\r
48     transient boolean       checkRotatePending = false;\r
49 \r
50     TimerTask               task               = new TimerTask() {\r
51         @Override\r
52         public void run() {\r
53             ICanvasContext ctx = getContext();\r
54             if (ctx.getDisposeState() != DisposeState.Alive)\r
55                 return;\r
56             IThreadWorkQueue thread = ctx.getThreadAccess();\r
57             if (thread == null)\r
58                 return;\r
59             thread.asyncExec(new Runnable() {\r
60                 @Override\r
61                 public void run() {\r
62                     if (checkRotatePending)\r
63                         return;\r
64                     checkRotatePending = true;\r
65                     timerEvent();\r
66                 }\r
67             });\r
68         }\r
69     };\r
70 \r
71     @Override\r
72     public void removedFromContext(ICanvasContext ctx) {\r
73         timer.cancel();\r
74         super.removedFromContext(ctx);\r
75     }\r
76 \r
77     @Override\r
78     public void addedToContext(ICanvasContext ctx) {\r
79         super.addedToContext(ctx);\r
80         long delay = 1000 / 25;\r
81         lastTrigger = System.currentTimeMillis();\r
82         timer.scheduleAtFixedRate(task, delay, delay);\r
83     }\r
84 \r
85     @HintListener(Class = Hints.class, Field = "KEY_CANVAS_BOUNDS")\r
86     public void selectionChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
87         Rectangle2D cb = (Rectangle2D) newValue;\r
88         this.centerPoint.setLocation(cb.getCenterX(), cb.getCenterY());\r
89     }\r
90 \r
91     void timerEvent() {\r
92         ICanvasContext ctx = getContext();\r
93         if (ctx == null)\r
94             return;\r
95         if (ctx.getDisposeState() != DisposeState.Alive)\r
96             return;\r
97         long cur = System.currentTimeMillis();\r
98         long delta = cur - lastTrigger;\r
99         lastTrigger = cur;\r
100         checkRotatePending = false;\r
101 \r
102         Point2D centerPoint = new Point2D.Double();\r
103         int grabCount = grab.grabInfo.size();\r
104         if (grabCount == 0) {\r
105             centerPoint = this.centerPoint;\r
106         } else if (grabCount == 1) {\r
107             centerPoint = grab.grabInfo.values().iterator().next().anchorPos;\r
108         } else {\r
109             angVel = 0.0;\r
110             return;\r
111         }\r
112 \r
113         // turn the canvas a bit\r
114         double theta = util.getRotate();\r
115         if (theta == 0.0)\r
116             return;\r
117 //        if (Math.abs(theta) < 0.0001) {\r
118 //            angVel = 0.0;\r
119 //            return;\r
120 //        }\r
121         if (Math.abs(theta) < 0.001) {\r
122             util.restoreOrientation(centerPoint);\r
123             angVel = 0.0;\r
124             return;\r
125         }\r
126 \r
127         double momentum = theta * 100;\r
128         double dt = ((double) delta) / 1000;\r
129         if (dt > 0.150)\r
130             dt = 0.150;\r
131         angVel += momentum * dt;\r
132         util.rotate(centerPoint, -angVel * dt);\r
133         angVel *= 0.5;\r
134     }\r
135 \r
136     double angVel = 0.0;\r
137 \r
138 }\r