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