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