Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / android-libraries / achartengine / src / org / achartengine / tools / Pan.java
diff --git a/android-libraries/achartengine/src/org/achartengine/tools/Pan.java b/android-libraries/achartengine/src/org/achartengine/tools/Pan.java
new file mode 100644 (file)
index 0000000..2d4ea28
--- /dev/null
@@ -0,0 +1,163 @@
+/**\r
+ * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.achartengine.tools;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.achartengine.chart.AbstractChart;\r
+import org.achartengine.chart.RoundChart;\r
+import org.achartengine.chart.XYChart;\r
+\r
+/**\r
+ * The pan tool.\r
+ */\r
+public class Pan extends AbstractTool {\r
+  /** The pan listeners. */\r
+  private List<PanListener> mPanListeners = new ArrayList<PanListener>();\r
+  /** Pan limits reached on the X axis. */\r
+  private boolean limitsReachedX = false;\r
+  /** Pan limits reached on the X axis. */\r
+  private boolean limitsReachedY = false;\r
+\r
+  /**\r
+   * Builds and instance of the pan tool.\r
+   * \r
+   * @param chart the XY chart\r
+   */\r
+  public Pan(AbstractChart chart) {\r
+    super(chart);\r
+  }\r
+\r
+  /**\r
+   * Apply the tool.\r
+   * \r
+   * @param oldX the previous location on X axis\r
+   * @param oldY the previous location on Y axis\r
+   * @param newX the current location on X axis\r
+   * @param newY the current location on the Y axis\r
+   */\r
+  public void apply(float oldX, float oldY, float newX, float newY) {\r
+    boolean notLimitedUp = true;\r
+    boolean notLimitedBottom = true;\r
+    boolean notLimitedLeft = true;\r
+    boolean notLimitedRight = true;\r
+    if (mChart instanceof XYChart) {\r
+      int scales = mRenderer.getScalesCount();\r
+      double[] limits = mRenderer.getPanLimits();\r
+      boolean limited = limits != null && limits.length == 4;\r
+      XYChart chart = (XYChart) mChart;\r
+      for (int i = 0; i < scales; i++) {\r
+        double[] range = getRange(i);\r
+        double[] calcRange = chart.getCalcRange(i);\r
+        if (limitsReachedX\r
+            && limitsReachedY\r
+            && (range[0] == range[1] && calcRange[0] == calcRange[1] || range[2] == range[3]\r
+                && calcRange[2] == calcRange[3])) {\r
+          return;\r
+        }\r
+        checkRange(range, i);\r
+\r
+        double[] realPoint = chart.toRealPoint(oldX, oldY, i);\r
+        double[] realPoint2 = chart.toRealPoint(newX, newY, i);\r
+        double deltaX = realPoint[0] - realPoint2[0];\r
+        double deltaY = realPoint[1] - realPoint2[1];\r
+        double ratio = getAxisRatio(range);\r
+        if (chart.isVertical(mRenderer)) {\r
+          double newDeltaX = -deltaY * ratio;\r
+          double newDeltaY = deltaX / ratio;\r
+          deltaX = newDeltaX;\r
+          deltaY = newDeltaY;\r
+        }\r
+        if (mRenderer.isPanXEnabled()) {\r
+          if (limits != null) {\r
+            if (notLimitedLeft) {\r
+              notLimitedLeft = limits[0] <= range[0] + deltaX;\r
+            }\r
+            if (notLimitedRight) {\r
+              notLimitedRight = limits[1] >= range[1] + deltaX;\r
+            }\r
+          }\r
+          if (!limited || (notLimitedLeft && notLimitedRight)) {\r
+            setXRange(range[0] + deltaX, range[1] + deltaX, i);\r
+            limitsReachedX = false;\r
+          } else {\r
+            limitsReachedX = true;\r
+          }\r
+        }\r
+        if (mRenderer.isPanYEnabled()) {\r
+          if (limits != null) {\r
+            if (notLimitedBottom) {\r
+              notLimitedBottom = limits[2] <= range[2] + deltaY;\r
+            }\r
+            if (notLimitedUp) {\r
+              notLimitedUp = limits[3] >= range[3] + deltaY;\r
+            }\r
+          }\r
+          if (!limited || (notLimitedBottom && notLimitedUp)) {\r
+            setYRange(range[2] + deltaY, range[3] + deltaY, i);\r
+            limitsReachedY = false;\r
+          } else {\r
+            limitsReachedY = true;\r
+          }\r
+        }\r
+      }\r
+    } else {\r
+      RoundChart chart = (RoundChart) mChart;\r
+      chart.setCenterX(chart.getCenterX() + (int) (newX - oldX));\r
+      chart.setCenterY(chart.getCenterY() + (int) (newY - oldY));\r
+    }\r
+    notifyPanListeners();\r
+  }\r
+\r
+  /**\r
+   * Return the X / Y axis range ratio.\r
+   * \r
+   * @param range the axis range\r
+   * @return the ratio\r
+   */\r
+  private double getAxisRatio(double[] range) {\r
+    return Math.abs(range[1] - range[0]) / Math.abs(range[3] - range[2]);\r
+  }\r
+\r
+  /**\r
+   * Notify the pan listeners about a pan.\r
+   */\r
+  private synchronized void notifyPanListeners() {\r
+    for (PanListener listener : mPanListeners) {\r
+      listener.panApplied();\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Adds a new pan listener.\r
+   * \r
+   * @param listener pan listener\r
+   */\r
+  public synchronized void addPanListener(PanListener listener) {\r
+    mPanListeners.add(listener);\r
+  }\r
+\r
+  /**\r
+   * Removes a pan listener.\r
+   * \r
+   * @param listener pan listener\r
+   */\r
+  public synchronized void removePanListener(PanListener listener) {\r
+    mPanListeners.add(listener);\r
+  }\r
+\r
+}\r