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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.g2d.participant;
\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
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
30 * Restores orientation of the canvas back to normal (north is up)
\r
33 * @author Toni Kalajainen
\r
35 public class OrientationRestorer extends AbstractCanvasParticipant {
\r
42 CanvasBoundsParticipant bounds;
\r
45 Point2D centerPoint = new Point2D.Double();
\r
47 transient Timer timer = new Timer("Rotate restore");
\r
48 transient boolean checkRotatePending = false;
\r
50 TimerTask task = new TimerTask() {
\r
53 ICanvasContext ctx = getContext();
\r
54 if (ctx.getDisposeState() != DisposeState.Alive)
\r
56 IThreadWorkQueue thread = ctx.getThreadAccess();
\r
59 thread.asyncExec(new Runnable() {
\r
62 if (checkRotatePending)
\r
64 checkRotatePending = true;
\r
72 public void removedFromContext(ICanvasContext ctx) {
\r
74 super.removedFromContext(ctx);
\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
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
92 ICanvasContext ctx = getContext();
\r
95 if (ctx.getDisposeState() != DisposeState.Alive)
\r
97 long cur = System.currentTimeMillis();
\r
98 long delta = cur - lastTrigger;
\r
100 checkRotatePending = false;
\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
113 // turn the canvas a bit
\r
114 double theta = util.getRotate();
\r
117 // if (Math.abs(theta) < 0.0001) {
\r
121 if (Math.abs(theta) < 0.001) {
\r
122 util.restoreOrientation(centerPoint);
\r
127 double momentum = theta * 100;
\r
128 double dt = ((double) delta) / 1000;
\r
131 angVel += momentum * dt;
\r
132 util.rotate(centerPoint, -angVel * dt);
\r
136 double angVel = 0.0;
\r