Merge commit '42b2e5ca519766e37ce6941ba4faecc9691cc403' into upstream
[debian/openrocket] / android-libraries / achartengine / src / org / achartengine / GraphicalView.java
diff --git a/android-libraries/achartengine/src/org/achartengine/GraphicalView.java b/android-libraries/achartengine/src/org/achartengine/GraphicalView.java
new file mode 100644 (file)
index 0000000..e9aebff
--- /dev/null
@@ -0,0 +1,337 @@
+/**\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.model.Point;\r
+import org.achartengine.model.SeriesSelection;\r
+import org.achartengine.renderer.DefaultRenderer;\r
+import org.achartengine.renderer.XYMultipleSeriesRenderer;\r
+import org.achartengine.tools.FitZoom;\r
+import org.achartengine.tools.PanListener;\r
+import org.achartengine.tools.Zoom;\r
+import org.achartengine.tools.ZoomListener;\r
+\r
+import android.content.Context;\r
+import android.graphics.Bitmap;\r
+import android.graphics.BitmapFactory;\r
+import android.graphics.Canvas;\r
+import android.graphics.Color;\r
+import android.graphics.Paint;\r
+import android.graphics.Rect;\r
+import android.graphics.RectF;\r
+import android.os.Build;\r
+import android.os.Handler;\r
+import android.view.MotionEvent;\r
+import android.view.View;\r
+\r
+/**\r
+ * The view that encapsulates the graphical chart.\r
+ */\r
+public class GraphicalView extends View {\r
+  /** The chart to be drawn. */\r
+  private AbstractChart mChart;\r
+  /** The chart renderer. */\r
+  private DefaultRenderer mRenderer;\r
+  /** The view bounds. */\r
+  private Rect mRect = new Rect();\r
+  /** The user interface thread handler. */\r
+  private Handler mHandler;\r
+  /** The zoom buttons rectangle. */\r
+  private RectF mZoomR = new RectF();\r
+  /** The zoom in icon. */\r
+  private Bitmap zoomInImage;\r
+  /** The zoom out icon. */\r
+  private Bitmap zoomOutImage;\r
+  /** The fit zoom icon. */\r
+  private Bitmap fitZoomImage;\r
+  /** The zoom area size. */\r
+  private int zoomSize = 50;\r
+  /** The zoom buttons background color. */\r
+  private static final int ZOOM_BUTTONS_COLOR = Color.argb(175, 150, 150, 150);\r
+  /** The zoom in tool. */\r
+  private Zoom mZoomIn;\r
+  /** The zoom out tool. */\r
+  private Zoom mZoomOut;\r
+  /** The fit zoom tool. */\r
+  private FitZoom mFitZoom;\r
+  /** The paint to be used when drawing the chart. */\r
+  private Paint mPaint = new Paint();\r
+  /** The touch handler. */\r
+  private ITouchHandler mTouchHandler;\r
+  /** The old x coordinate. */\r
+  private float oldX;\r
+  /** The old y coordinate. */\r
+  private float oldY;\r
+\r
+  /**\r
+   * Creates a new graphical view.\r
+   * \r
+   * @param context the context\r
+   * @param chart the chart to be drawn\r
+   */\r
+  public GraphicalView(Context context, AbstractChart chart) {\r
+    super(context);\r
+    mChart = chart;\r
+    mHandler = new Handler();\r
+    if (mChart instanceof XYChart) {\r
+      mRenderer = ((XYChart) mChart).getRenderer();\r
+    } else {\r
+      mRenderer = ((RoundChart) mChart).getRenderer();\r
+    }\r
+    if (mRenderer.isZoomButtonsVisible()) {\r
+      zoomInImage = BitmapFactory.decodeStream(GraphicalView.class\r
+          .getResourceAsStream("image/zoom_in.png"));\r
+      zoomOutImage = BitmapFactory.decodeStream(GraphicalView.class\r
+          .getResourceAsStream("image/zoom_out.png"));\r
+      fitZoomImage = BitmapFactory.decodeStream(GraphicalView.class\r
+          .getResourceAsStream("image/zoom-1.png"));\r
+    }\r
+\r
+    if (mRenderer instanceof XYMultipleSeriesRenderer\r
+        && ((XYMultipleSeriesRenderer) mRenderer).getMarginsColor() == XYMultipleSeriesRenderer.NO_COLOR) {\r
+      ((XYMultipleSeriesRenderer) mRenderer).setMarginsColor(mPaint.getColor());\r
+    }\r
+    if (mRenderer.isZoomEnabled() && mRenderer.isZoomButtonsVisible()\r
+        || mRenderer.isExternalZoomEnabled()) {\r
+      mZoomIn = new Zoom(mChart, true, mRenderer.getZoomRate());\r
+      mZoomOut = new Zoom(mChart, false, mRenderer.getZoomRate());\r
+      mFitZoom = new FitZoom(mChart);\r
+    }\r
+    int version = 7;\r
+    try {\r
+      version = Integer.valueOf(Build.VERSION.SDK);\r
+    } catch (Exception e) {\r
+      // do nothing\r
+    }\r
+    if (version < 7) {\r
+      mTouchHandler = new TouchHandlerOld(this, mChart);\r
+    } else {\r
+      mTouchHandler = new TouchHandler(this, mChart);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Returns the current series selection object.\r
+   * \r
+   * @return the series selection\r
+   */\r
+  public SeriesSelection getCurrentSeriesAndPoint() {\r
+    return mChart.getSeriesAndPointForScreenCoordinate(new Point(oldX, oldY));\r
+  }\r
+\r
+  /**\r
+   * Transforms the currently selected screen point to a real point.\r
+   * \r
+   * @param scale the scale\r
+   * @return the currently selected real point\r
+   */\r
+  public double[] toRealPoint(int scale) {\r
+    if (mChart instanceof XYChart) {\r
+      XYChart chart = (XYChart) mChart;\r
+      return chart.toRealPoint(oldX, oldY, scale);\r
+    }\r
+    return null;\r
+  }\r
+\r
+  @Override\r
+  protected void onDraw(Canvas canvas) {\r
+    super.onDraw(canvas);\r
+    canvas.getClipBounds(mRect);\r
+    int top = mRect.top;\r
+    int left = mRect.left;\r
+    int width = mRect.width();\r
+    int height = mRect.height();\r
+    if (mRenderer.isInScroll()) {\r
+      top = 0;\r
+      left = 0;\r
+      width = getMeasuredWidth();\r
+      height = getMeasuredHeight();\r
+    }\r
+    mChart.draw(canvas, left, top, width, height, mPaint);\r
+    if (mRenderer != null && mRenderer.isZoomEnabled() && mRenderer.isZoomButtonsVisible()) {\r
+      mPaint.setColor(ZOOM_BUTTONS_COLOR);\r
+      zoomSize = Math.max(zoomSize, Math.min(width, height) / 7);\r
+      mZoomR.set(left + width - zoomSize * 3, top + height - zoomSize * 0.775f, left + width, top\r
+          + height);\r
+      canvas.drawRoundRect(mZoomR, zoomSize / 3, zoomSize / 3, mPaint);\r
+      float buttonY = top + height - zoomSize * 0.625f;\r
+      canvas.drawBitmap(zoomInImage, left + width - zoomSize * 2.75f, buttonY, null);\r
+      canvas.drawBitmap(zoomOutImage, left + width - zoomSize * 1.75f, buttonY, null);\r
+      canvas.drawBitmap(fitZoomImage, left + width - zoomSize * 0.75f, buttonY, null);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Sets the zoom rate.\r
+   * \r
+   * @param rate the zoom rate\r
+   */\r
+  public void setZoomRate(float rate) {\r
+    if (mZoomIn != null && mZoomOut != null) {\r
+      mZoomIn.setZoomRate(rate);\r
+      mZoomOut.setZoomRate(rate);\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Do a chart zoom in.\r
+   */\r
+  public void zoomIn() {\r
+    if (mZoomIn != null) {\r
+      mZoomIn.apply(Zoom.ZOOM_AXIS_XY);\r
+      repaint();\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Do a chart zoom out.\r
+   */\r
+  public void zoomOut() {\r
+    if (mZoomOut != null) {\r
+      mZoomOut.apply(Zoom.ZOOM_AXIS_XY);\r
+      repaint();\r
+    }\r
+  }\r
+  \r
+\r
+\r
+  /**\r
+   * Do a chart zoom reset / fit zoom.\r
+   */\r
+  public void zoomReset() {\r
+    if (mFitZoom != null) {\r
+      mFitZoom.apply();\r
+      mZoomIn.notifyZoomResetListeners();\r
+      repaint();\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Adds a new zoom listener.\r
+   * \r
+   * @param listener zoom listener\r
+   */\r
+  public void addZoomListener(ZoomListener listener, boolean onButtons, boolean onPinch) {\r
+    if (onButtons) {\r
+      if (mZoomIn != null) {\r
+        mZoomIn.addZoomListener(listener);\r
+        mZoomOut.addZoomListener(listener);\r
+      }\r
+      if (onPinch) {\r
+        mTouchHandler.addZoomListener(listener);\r
+      }\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Removes a zoom listener.\r
+   * \r
+   * @param listener zoom listener\r
+   */\r
+  public synchronized void removeZoomListener(ZoomListener listener) {\r
+    if (mZoomIn != null) {\r
+      mZoomIn.removeZoomListener(listener);\r
+      mZoomOut.removeZoomListener(listener);\r
+    }\r
+    mTouchHandler.removeZoomListener(listener);\r
+  }\r
+\r
+  /**\r
+   * Adds a new pan listener.\r
+   * \r
+   * @param listener pan listener\r
+   */\r
+  public void addPanListener(PanListener listener) {\r
+    mTouchHandler.addPanListener(listener);\r
+  }\r
+\r
+  /**\r
+   * Removes a pan listener.\r
+   * \r
+   * @param listener pan listener\r
+   */\r
+  public void removePanListener(PanListener listener) {\r
+    mTouchHandler.removePanListener(listener);\r
+  }\r
+\r
+  protected RectF getZoomRectangle() {\r
+    return mZoomR;\r
+  }\r
+\r
+  @Override\r
+  public boolean onTouchEvent(MotionEvent event) {\r
+    if (event.getAction() == MotionEvent.ACTION_DOWN) {\r
+      // save the x and y so they can be used in the click and long press\r
+      // listeners\r
+      oldX = event.getX();\r
+      oldY = event.getY();\r
+    }\r
+    if (mRenderer != null && (mRenderer.isPanEnabled() || mRenderer.isZoomEnabled())) {\r
+      if (mTouchHandler.handleTouch(event)) {\r
+        return true;\r
+      }\r
+    }\r
+    return super.onTouchEvent(event);\r
+  }\r
+\r
+  /**\r
+   * Schedule a view content repaint.\r
+   */\r
+  public void repaint() {\r
+    mHandler.post(new Runnable() {\r
+      public void run() {\r
+        invalidate();\r
+      }\r
+    });\r
+  }\r
+\r
+  /**\r
+   * Schedule a view content repaint, in the specified rectangle area.\r
+   * \r
+   * @param left the left position of the area to be repainted\r
+   * @param top the top position of the area to be repainted\r
+   * @param right the right position of the area to be repainted\r
+   * @param bottom the bottom position of the area to be repainted\r
+   */\r
+  public void repaint(final int left, final int top, final int right, final int bottom) {\r
+    mHandler.post(new Runnable() {\r
+      public void run() {\r
+        invalidate(left, top, right, bottom);\r
+      }\r
+    });\r
+  }\r
+\r
+  /**\r
+   * Saves the content of the graphical view to a bitmap.\r
+   * \r
+   * @return the bitmap\r
+   */\r
+  public Bitmap toBitmap() {\r
+    setDrawingCacheEnabled(false);\r
+    if (!isDrawingCacheEnabled()) {\r
+      setDrawingCacheEnabled(true);\r
+    }\r
+    if (mRenderer.isApplyBackgroundColor()) {\r
+      setDrawingCacheBackgroundColor(mRenderer.getBackgroundColor());\r
+    }\r
+    setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);\r
+    return getDrawingCache(true);\r
+  }\r
+\r
+}
\ No newline at end of file