Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / android-libraries / achartengine / src / org / achartengine / TouchHandler.java
diff --git a/android-libraries/achartengine/src/org/achartengine/TouchHandler.java b/android-libraries/achartengine/src/org/achartengine/TouchHandler.java
new file mode 100644 (file)
index 0000000..a06d05d
--- /dev/null
@@ -0,0 +1,204 @@
+/**\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;\r
+\r
+import org.achartengine.chart.AbstractChart;\r
+import org.achartengine.chart.RoundChart;\r
+import org.achartengine.chart.XYChart;\r
+import org.achartengine.renderer.DefaultRenderer;\r
+import org.achartengine.tools.Pan;\r
+import org.achartengine.tools.PanListener;\r
+import org.achartengine.tools.Zoom;\r
+import org.achartengine.tools.ZoomListener;\r
+\r
+import android.graphics.RectF;\r
+import android.view.MotionEvent;\r
+\r
+/**\r
+ * The main handler of the touch events.\r
+ */\r
+public class TouchHandler implements ITouchHandler {\r
+  /** The chart renderer. */\r
+  private DefaultRenderer mRenderer;\r
+  /** The old x coordinate. */\r
+  private float oldX;\r
+  /** The old y coordinate. */\r
+  private float oldY;\r
+  /** The old x2 coordinate. */\r
+  private float oldX2;\r
+  /** The old y2 coordinate. */\r
+  private float oldY2;\r
+  /** The zoom buttons rectangle. */\r
+  private RectF zoomR = new RectF();\r
+  /** The pan tool. */\r
+  private Pan mPan;\r
+  /** The zoom for the pinch gesture. */\r
+  private Zoom mPinchZoom;\r
+  /** The graphical view. */\r
+  private GraphicalView graphicalView;\r
+\r
+  /**\r
+   * Creates a new graphical view.\r
+   * \r
+   * @param view the graphical view\r
+   * @param chart the chart to be drawn\r
+   */\r
+  public TouchHandler(GraphicalView view, AbstractChart chart) {\r
+    graphicalView = view;\r
+    zoomR = graphicalView.getZoomRectangle();\r
+    if (chart instanceof XYChart) {\r
+      mRenderer = ((XYChart) chart).getRenderer();\r
+    } else {\r
+      mRenderer = ((RoundChart) chart).getRenderer();\r
+    }\r
+    if (mRenderer.isPanEnabled()) {\r
+      mPan = new Pan(chart);\r
+    }\r
+    if (mRenderer.isZoomEnabled()) {\r
+      mPinchZoom = new Zoom(chart, true, 1);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Handles the touch event.\r
+   * \r
+   * @param event the touch event\r
+   */\r
+  public boolean handleTouch(MotionEvent event) {\r
+    int action = event.getAction();\r
+    if (mRenderer != null && action == MotionEvent.ACTION_MOVE) {\r
+      if (oldX >= 0 || oldY >= 0) {\r
+        float newX = event.getX(0);\r
+        float newY = event.getY(0);\r
+        if (event.getPointerCount() > 1 && (oldX2 >= 0 || oldY2 >= 0) && mRenderer.isZoomEnabled()) {\r
+          float newX2 = event.getX(1);\r
+          float newY2 = event.getY(1);\r
+          float newDeltaX = Math.abs(newX - newX2);\r
+          float newDeltaY = Math.abs(newY - newY2);\r
+          float oldDeltaX = Math.abs(oldX - oldX2);\r
+          float oldDeltaY = Math.abs(oldY - oldY2);\r
+          float zoomRate = 1;\r
+\r
+          float tan1 = Math.abs(newY - oldY) / Math.abs(newX - oldX);\r
+          float tan2 = Math.abs(newY2 - oldY2) / Math.abs(newX2 - oldX2);\r
+          if ( tan1 <= 0.577 && tan2 <= 0.577) {\r
+            // horizontal pinch zoom, |deltaY| / |deltaX| is [0 ~ 0.577], 0.577 is the approximate value of tan(Pi/6)\r
+            zoomRate = newDeltaX / oldDeltaX;\r
+            if (zoomRate > 0.909 && zoomRate < 1.1) {\r
+              mPinchZoom.setZoomRate(zoomRate);\r
+              mPinchZoom.apply(Zoom.ZOOM_AXIS_X);\r
+            }\r
+          } else if ( tan1 >= 1.732 && tan2 >= 1.732 ) {\r
+            // pinch zoom vertically, |deltaY| / |deltaX| is [1.732 ~ infinity], 1.732 is the approximate value of tan(Pi/3)\r
+            zoomRate = newDeltaY / oldDeltaY;\r
+            if (zoomRate > 0.909 && zoomRate < 1.1) {\r
+              mPinchZoom.setZoomRate(zoomRate);\r
+              mPinchZoom.apply(Zoom.ZOOM_AXIS_Y);\r
+            }\r
+          } else if ( (tan1 > 0.577 && tan1 < 1.732) && (tan2 > 0.577 && tan2 < 1.732) ){\r
+            // pinch zoom diagonally\r
+            if (Math.abs(newX - oldX) >= Math.abs(newY - oldY)) {\r
+              zoomRate = newDeltaX / oldDeltaX;\r
+            } else {\r
+              zoomRate = newDeltaY / oldDeltaY;\r
+            }\r
+            if (zoomRate > 0.909 && zoomRate < 1.1) {\r
+              mPinchZoom.setZoomRate(zoomRate);\r
+              mPinchZoom.apply(Zoom.ZOOM_AXIS_XY);\r
+            }\r
+          }\r
+          oldX2 = newX2;\r
+          oldY2 = newY2;\r
+        } else if (mRenderer.isPanEnabled()) {\r
+          mPan.apply(oldX, oldY, newX, newY);\r
+          oldX2 = 0;\r
+          oldY2 = 0;\r
+        }\r
+        oldX = newX;\r
+        oldY = newY;\r
+        graphicalView.repaint();\r
+        return true;\r
+      }\r
+    } else if (action == MotionEvent.ACTION_DOWN) {\r
+      oldX = event.getX(0);\r
+      oldY = event.getY(0);\r
+      if (mRenderer != null && mRenderer.isZoomEnabled() && zoomR.contains(oldX, oldY)) {\r
+        if (oldX < zoomR.left + zoomR.width() / 3) {\r
+          graphicalView.zoomIn();\r
+        } else if (oldX < zoomR.left + zoomR.width() * 2 / 3) {\r
+          graphicalView.zoomOut();\r
+        } else {\r
+          graphicalView.zoomReset();\r
+        }\r
+        return true;\r
+      }\r
+    } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {\r
+      oldX = 0;\r
+      oldY = 0;\r
+      oldX2 = 0;\r
+      oldY2 = 0;\r
+      if (action == MotionEvent.ACTION_POINTER_UP) {\r
+        oldX = -1;\r
+        oldY = -1;\r
+      }\r
+    }\r
+    return !mRenderer.isClickEnabled();\r
+  }\r
+\r
+  /**\r
+   * Adds a new zoom listener.\r
+   * \r
+   * @param listener zoom listener\r
+   */\r
+  public void addZoomListener(ZoomListener listener) {\r
+    if (mPinchZoom != null) {\r
+      mPinchZoom.addZoomListener(listener);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Removes a zoom listener.\r
+   * \r
+   * @param listener zoom listener\r
+   */\r
+  public void removeZoomListener(ZoomListener listener) {\r
+    if (mPinchZoom != null) {\r
+      mPinchZoom.removeZoomListener(listener);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Adds a new pan listener.\r
+   * \r
+   * @param listener pan listener\r
+   */\r
+  public void addPanListener(PanListener listener) {\r
+    if (mPan != null) {\r
+      mPan.addPanListener(listener);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Removes a pan listener.\r
+   * \r
+   * @param listener pan listener\r
+   */\r
+  public void removePanListener(PanListener listener) {\r
+    if (mPan != null) {\r
+      mPan.removePanListener(listener);\r
+    }\r
+  }\r
+}
\ No newline at end of file