Example usage for android.graphics PointF PointF

List of usage examples for android.graphics PointF PointF

Introduction

In this page you can find the example usage for android.graphics PointF PointF.

Prototype

public PointF(float x, float y) 

Source Link

Usage

From source file:com.bizcom.vc.widget.cus.SubsamplingScaleImageView.java

/**
 * Handle touch events. One finger pans, and two finger pinch and zoom plus
 * panning./*from   w w w .  j a v a  2 s  . c o  m*/
 */
@Override
public boolean onTouchEvent(MotionEvent event) {
    PointF vCenterEnd;
    float vDistEnd;
    // During non-interruptible anims, ignore all touch events
    if (anim != null && !anim.interruptible) {
        getParent().requestDisallowInterceptTouchEvent(true);
        return true;
    } else {
        anim = null;
    }

    // Abort if not ready
    if (vTranslate == null) {
        return true;
    }
    // Detect flings, taps and double taps
    if (detector == null || detector.onTouchEvent(event)) {
        return true;
    }

    int touchCount = event.getPointerCount();
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_POINTER_1_DOWN:
    case MotionEvent.ACTION_POINTER_2_DOWN:
        anim = null;
        getParent().requestDisallowInterceptTouchEvent(true);
        maxTouchCount = Math.max(maxTouchCount, touchCount);
        if (touchCount >= 2) {
            if (zoomEnabled) {
                // Start pinch to zoom. Calculate distance between touch
                // points and center point of the pinch.
                float distance = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1));
                scaleStart = scale;
                vDistStart = distance;
                vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
                vCenterStart = new PointF((event.getX(0) + event.getX(1)) / 2,
                        (event.getY(0) + event.getY(1)) / 2);
            } else {
                // Abort all gestures on second touch
                maxTouchCount = 0;
            }
            // Cancel long click timer
            handler.removeMessages(MESSAGE_LONG_CLICK);
        } else {
            // Start one-finger pan
            vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
            vCenterStart = new PointF(event.getX(), event.getY());

            // Start long click timer
            handler.sendEmptyMessageDelayed(MESSAGE_LONG_CLICK, 600);
        }
        return true;
    case MotionEvent.ACTION_MOVE:
        boolean consumed = false;
        if (maxTouchCount > 0) {
            if (touchCount >= 2) {
                // Calculate new distance between touch points, to scale and
                // pan relative to start values.
                vDistEnd = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1));
                vCenterEnd = new PointF((event.getX(0) + event.getX(1)) / 2,
                        (event.getY(0) + event.getY(1)) / 2);

                if (zoomEnabled && (distance(vCenterStart.x, vCenterEnd.x, vCenterStart.y, vCenterEnd.y) > 5
                        || Math.abs(vDistEnd - vDistStart) > 5 || isPanning)) {
                    isZooming = true;
                    isPanning = true;
                    consumed = true;

                    scale = Math.min(maxScale, (vDistEnd / vDistStart) * scaleStart);

                    if (scale <= minScale()) {
                        // Minimum scale reached so don't pan. Adjust start
                        // settings so any expand will zoom in.
                        vDistStart = vDistEnd;
                        scaleStart = minScale();
                        vCenterStart = vCenterEnd;
                        vTranslateStart = vTranslate;
                    } else if (panEnabled) {
                        // Translate to place the source image coordinate
                        // that was at the center of the pinch at the start
                        // at the center of the pinch now, to give
                        // simultaneous pan + zoom.
                        float vLeftStart = vCenterStart.x - vTranslateStart.x;
                        float vTopStart = vCenterStart.y - vTranslateStart.y;
                        float vLeftNow = vLeftStart * (scale / scaleStart);
                        float vTopNow = vTopStart * (scale / scaleStart);
                        vTranslate.x = vCenterEnd.x - vLeftNow;
                        vTranslate.y = vCenterEnd.y - vTopNow;
                    } else if (sRequestedCenter != null) {
                        // With a center specified from code, zoom around
                        // that point.
                        vTranslate.x = (getWidth() / 2) - (scale * sRequestedCenter.x);
                        vTranslate.y = (getHeight() / 2) - (scale * sRequestedCenter.y);
                    } else {
                        // With no requested center, scale around the image
                        // center.
                        vTranslate.x = (getWidth() / 2) - (scale * (sWidth() / 2));
                        vTranslate.y = (getHeight() / 2) - (scale * (sHeight() / 2));
                    }

                    fitToBounds(true);
                    refreshRequiredTiles(false);
                }
            } else if (!isZooming) {
                // One finger pan - translate the image. We do this
                // calculation even with pan disabled so click
                // and long click behaviour is preserved.
                float dx = Math.abs(event.getX() - vCenterStart.x);
                float dy = Math.abs(event.getY() - vCenterStart.y);
                if (dx > 5 || dy > 5 || isPanning) {
                    consumed = true;
                    vTranslate.x = vTranslateStart.x + (event.getX() - vCenterStart.x);
                    vTranslate.y = vTranslateStart.y + (event.getY() - vCenterStart.y);

                    float lastX = vTranslate.x;
                    float lastY = vTranslate.y;
                    fitToBounds(true);
                    if (lastX == vTranslate.x || (lastY == vTranslate.y && dy > 10) || isPanning) {
                        isPanning = true;
                    } else if (dx > 5) {
                        // Haven't panned the image, and we're at the left
                        // or right edge. Switch to page swipe.
                        maxTouchCount = 0;
                        handler.removeMessages(MESSAGE_LONG_CLICK);
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }

                    if (!panEnabled) {
                        vTranslate.x = vTranslateStart.x;
                        vTranslate.y = vTranslateStart.y;
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }

                    refreshRequiredTiles(false);
                }
            }
        }
        if (consumed) {
            handler.removeMessages(MESSAGE_LONG_CLICK);
            invalidate();
            return true;
        }
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_POINTER_UP:
    case MotionEvent.ACTION_POINTER_2_UP:
        handler.removeMessages(MESSAGE_LONG_CLICK);
        if (maxTouchCount > 0 && (isZooming || isPanning)) {
            if (isZooming && touchCount == 2) {
                // Convert from zoom to pan with remaining touch
                isPanning = true;
                vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
                if (event.getActionIndex() == 1) {
                    vCenterStart = new PointF(event.getX(0), event.getY(0));
                } else {
                    vCenterStart = new PointF(event.getX(1), event.getY(1));
                }
            }
            if (touchCount < 3) {
                // End zooming when only one touch point
                isZooming = false;
            }
            if (touchCount < 2) {
                // End panning when no touch points
                isPanning = false;
                maxTouchCount = 0;
            }
            // Trigger load of tiles now required
            refreshRequiredTiles(true);
            return true;
        }
        if (touchCount == 1) {
            isZooming = false;
            isPanning = false;
            maxTouchCount = 0;
        }
        return true;
    }
    return super.onTouchEvent(event);
}

From source file:me.ccrama.redditslide.Views.SubsamplingScaleImageView.java

private void setGestureDetector(final Context context) {
    this.detector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {

        @Override//from  ww w.j a v  a  2 s .  c  o m
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if (panEnabled && readySent && vTranslate != null && e1 != null && e2 != null
                    && (Math.abs(e1.getX() - e2.getX()) > 50 || Math.abs(e1.getY() - e2.getY()) > 50)
                    && (Math.abs(velocityX) > 500 || Math.abs(velocityY) > 500) && !isZooming) {
                PointF vTranslateEnd = new PointF(vTranslate.x + (velocityX * 0.25f),
                        vTranslate.y + (velocityY * 0.25f));
                float sCenterXEnd = ((getWidth() / 2) - vTranslateEnd.x) / scale;
                float sCenterYEnd = ((getHeight() / 2) - vTranslateEnd.y) / scale;
                new AnimationBuilder(new PointF(sCenterXEnd, sCenterYEnd)).withEasing(EASE_OUT_QUAD)
                        .withPanLimited(false).start();
                return true;
            }
            return super.onFling(e1, e2, velocityX, velocityY);
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            performClick();
            return true;
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            if (zoomEnabled && readySent && vTranslate != null) {
                // Hacky solution for #15 - after a double tap the GestureDetector gets in a state
                // where the next fling is ignored, so here we replace it with a new one.
                setGestureDetector(context);
                if (quickScaleEnabled) {
                    // Store quick scale params. This will become either a double tap zoom or a
                    // quick scale depending on whether the user swipes.
                    vCenterStart = new PointF(e.getX(), e.getY());
                    vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
                    scaleStart = scale;
                    isQuickScaling = true;
                    isZooming = true;
                    quickScaleCenter = viewToSourceCoord(vCenterStart);
                    quickScaleLastDistance = -1F;
                    quickScaleLastPoint = new PointF(quickScaleCenter.x, quickScaleCenter.y);
                    quickScaleMoved = false;
                    // We need to get events in onTouchEvent after this.
                    return false;
                } else {
                    // Start double tap zoom animation.
                    doubleTapZoom(viewToSourceCoord(new PointF(e.getX(), e.getY())),
                            new PointF(e.getX(), e.getY()));
                    return true;
                }
            }
            return super.onDoubleTapEvent(e);
        }
    });
}

From source file:ac.robinson.paperchains.PaperChainsActivity.java

public void audioSaveCompleted(final Rect audioRect, final long trackId) {
    // convert back to grid-based coordinates
    final PointF rectLeftTop = QRImageParser.getGridPosition(mImageParameters,
            new PointF(audioRect.left, audioRect.top));
    final PointF rectRightBottom = QRImageParser.getGridPosition(mImageParameters,
            new PointF(audioRect.right, audioRect.bottom));

    // account for image rotation/inversion by making sure to use the min/max values of each coordinate
    int left = Math.round(rectLeftTop.x);
    int top = Math.round(rectLeftTop.y);
    int right = Math.round(rectRightBottom.x);
    int bottom = Math.round(rectRightBottom.y);
    final int leftmost = Math.min(left, right);
    final int topmost = Math.min(top, bottom);
    final int rightmost = Math.max(left, right);
    final int bottommost = Math.max(top, bottom);

    RequestParams params = new RequestParams("newaudio", 1); // 1 reserved for possible future use as box ID
    params.put("left", leftmost);
    params.put("top", topmost);
    params.put("right", rightmost);
    params.put("bottom", bottommost);
    params.put("soundCloudId", trackId);
    params.put("pageId", mPageId);

    // update on the server
    new AsyncHttpClient().get(CODE_SERVER_URL, params, new JsonHttpResponseHandler() {
        @Override// ww  w.jav a  2 s . c  om
        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
            try {
                if ("ok".equals(response.getString("status"))) {
                    AudioAreaHolder holder = new AudioAreaHolder(trackId,
                            new Rect(leftmost, topmost, rightmost, bottommost));
                    holder.setImageRect(new Rect(audioRect));
                    mAudioAreas.add(holder);
                    mImageView.addAudioAreaRect(holder.imageRect);

                    mSaveButton.clearAnimation();
                    mSaveButton.setImageResource(R.drawable.ic_done_white_24dp);
                    delayedResetRecordingInterface();
                } else {
                    audioSaveFailed(R.string.hint_audio_save_failed);
                }
            } catch (JSONException e) {
                audioSaveFailed(R.string.hint_audio_save_failed);
            }
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
            audioSaveFailed(R.string.hint_audio_save_failed);
        }
    });
}

From source file:com.zenithed.core.widget.scaledimageview.ScaledImageView.java

private void scaleToHelper(float sx, float sy, float newScale, int duration) {
    if (newScale > mMaxScale)
        newScale = mMaxScale;//from w  w  w.ja v  a  2 s. c  o m

    if (newScale == mScale)
        return;

    // if the image is not ready we can't zoom.
    if (mScale <= 0)
        return;

    mScroller.forceFinished(true);

    mZoomerInitialScale = mScale;
    mZoomerInitialDestinationPoint = new PointF(sx, sy);

    mZoomer.startZoom(mScale, newScale, duration);
    ViewCompat.postInvalidateOnAnimation(ScaledImageView.this);
}

From source file:me.ccrama.redditslide.Views.SubsamplingScaleImageView.java

/**
 * Handle touch events. One finger pans, and two finger pinch and zoom plus panning.
 *///from  www.  j  a  v a 2s  .  co  m
@Override
@SuppressWarnings("deprecation")
public boolean onTouchEvent(@NonNull MotionEvent event) {
    // During non-interruptible anims, ignore all touch events
    if (anim != null && !anim.interruptible) {
        getParent().requestDisallowInterceptTouchEvent(true);
        return true;
    } else {
        if (anim != null && anim.listener != null) {
            try {
                anim.listener.onInterruptedByUser();
            } catch (Exception e) {
                Log.w(TAG, "Error thrown by animation listener", e);
            }
        }
        anim = null;
    }

    // Abort if not ready
    if (vTranslate == null) {
        return true;
    }
    // Detect flings, taps and double taps
    if (!isQuickScaling && (detector == null || detector.onTouchEvent(event))) {
        isZooming = false;
        isPanning = false;
        maxTouchCount = 0;
        return true;
    }

    if (vTranslateStart == null) {
        vTranslateStart = new PointF(0, 0);
    }
    if (vCenterStart == null) {
        vCenterStart = new PointF(0, 0);
    }

    int touchCount = event.getPointerCount();
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_POINTER_1_DOWN:
    case MotionEvent.ACTION_POINTER_2_DOWN:
        anim = null;
        getParent().requestDisallowInterceptTouchEvent(true);
        maxTouchCount = Math.max(maxTouchCount, touchCount);
        if (touchCount >= 2) {
            if (zoomEnabled) {
                // Start pinch to zoom. Calculate distance between touch points and center point of the pinch.
                float distance = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1));
                scaleStart = scale;
                vDistStart = distance;
                vTranslateStart.set(vTranslate.x, vTranslate.y);
                vCenterStart.set((event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2);
            } else {
                // Abort all gestures on second touch
                maxTouchCount = 0;
            }
            // Cancel long click timer
            handler.removeMessages(MESSAGE_LONG_CLICK);
        } else if (!isQuickScaling) {
            // Start one-finger pan
            vTranslateStart.set(vTranslate.x, vTranslate.y);
            vCenterStart.set(event.getX(), event.getY());

            // Start long click timer
            handler.sendEmptyMessageDelayed(MESSAGE_LONG_CLICK, 600);
        }
        return true;
    case MotionEvent.ACTION_MOVE:
        boolean consumed = false;
        if (maxTouchCount > 0) {
            if (touchCount >= 2) {
                // Calculate new distance between touch points, to scale and pan relative to start values.
                float vDistEnd = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1));
                float vCenterEndX = (event.getX(0) + event.getX(1)) / 2;
                float vCenterEndY = (event.getY(0) + event.getY(1)) / 2;

                if (zoomEnabled && (distance(vCenterStart.x, vCenterEndX, vCenterStart.y, vCenterEndY) > 5
                        || Math.abs(vDistEnd - vDistStart) > 5 || isPanning)) {
                    isZooming = true;
                    isPanning = true;
                    consumed = true;

                    setScale(Math.min(maxScale, (vDistEnd / vDistStart) * scaleStart));

                    if (scale <= minScale()) {
                        // Minimum scale reached so don't pan. Adjust start settings so any expand will zoom in.
                        vDistStart = vDistEnd;
                        scaleStart = minScale();
                        vCenterStart.set(vCenterEndX, vCenterEndY);
                        vTranslateStart.set(vTranslate);
                    } else if (panEnabled) {
                        // Translate to place the source image coordinate that was at the center of the pinch at the start
                        // at the center of the pinch now, to give simultaneous pan + zoom.
                        float vLeftStart = vCenterStart.x - vTranslateStart.x;
                        float vTopStart = vCenterStart.y - vTranslateStart.y;
                        float vLeftNow = vLeftStart * (scale / scaleStart);
                        float vTopNow = vTopStart * (scale / scaleStart);
                        vTranslate.x = vCenterEndX - vLeftNow;
                        vTranslate.y = vCenterEndY - vTopNow;
                    } else if (sRequestedCenter != null) {
                        // With a center specified from code, zoom around that point.
                        vTranslate.x = (getWidth() / 2) - (scale * sRequestedCenter.x);
                        vTranslate.y = (getHeight() / 2) - (scale * sRequestedCenter.y);
                    } else {
                        // With no requested center, scale around the image center.
                        vTranslate.x = (getWidth() / 2) - (scale * (sWidth() / 2));
                        vTranslate.y = (getHeight() / 2) - (scale * (sHeight() / 2));
                    }

                    fitToBounds(true);
                    refreshRequiredTiles(false);
                }
            } else if (isQuickScaling) {
                // One finger zoom
                // Stole Google's Magical Formula to make sure it feels the exact same
                float dist = Math.abs(vCenterStart.y - event.getY()) * 2 + quickScaleThreshold;

                if (quickScaleLastDistance == -1F)
                    quickScaleLastDistance = dist;
                boolean isUpwards = event.getY() > quickScaleLastPoint.y;
                quickScaleLastPoint.set(0, event.getY());

                float spanDiff = (Math.abs(1 - (dist / quickScaleLastDistance)) * 0.5F);

                if (spanDiff > 0.03f || quickScaleMoved) {
                    quickScaleMoved = true;

                    float multiplier = 1;
                    if (quickScaleLastDistance > 0) {
                        multiplier = isUpwards ? (1 + spanDiff) : (1 - spanDiff);
                    }

                    setScale(Math.max(minScale(), Math.min(maxScale, scale * multiplier)));

                    if (panEnabled) {
                        float vLeftStart = vCenterStart.x - vTranslateStart.x;
                        float vTopStart = vCenterStart.y - vTranslateStart.y;
                        float vLeftNow = vLeftStart * (scale / scaleStart);
                        float vTopNow = vTopStart * (scale / scaleStart);
                        vTranslate.x = vCenterStart.x - vLeftNow;
                        vTranslate.y = vCenterStart.y - vTopNow;
                    } else if (sRequestedCenter != null) {
                        // With a center specified from code, zoom around that point.
                        vTranslate.x = (getWidth() / 2) - (scale * sRequestedCenter.x);
                        vTranslate.y = (getHeight() / 2) - (scale * sRequestedCenter.y);
                    } else {
                        // With no requested center, scale around the image center.
                        vTranslate.x = (getWidth() / 2) - (scale * (sWidth() / 2));
                        vTranslate.y = (getHeight() / 2) - (scale * (sHeight() / 2));
                    }
                }

                quickScaleLastDistance = dist;

                fitToBounds(true);
                refreshRequiredTiles(false);

                consumed = true;
            } else if (!isZooming) {
                // One finger pan - translate the image. We do this calculation even with pan disabled so click
                // and long click behaviour is preserved.
                float dx = Math.abs(event.getX() - vCenterStart.x);
                float dy = Math.abs(event.getY() - vCenterStart.y);
                if (dx > 5 || dy > 5 || isPanning) {
                    consumed = true;
                    vTranslate.x = vTranslateStart.x + (event.getX() - vCenterStart.x);
                    vTranslate.y = vTranslateStart.y + (event.getY() - vCenterStart.y);

                    float lastX = vTranslate.x;
                    float lastY = vTranslate.y;
                    fitToBounds(true);
                    boolean atXEdge = lastX != vTranslate.x;
                    boolean edgeXSwipe = atXEdge && dx > dy && !isPanning;
                    boolean yPan = lastY == vTranslate.y && dy > 15;
                    if (!edgeXSwipe && (!atXEdge || yPan || isPanning)) {
                        isPanning = true;
                    } else if (dx > 5) {
                        // Haven't panned the image, and we're at the left or right edge. Switch to page swipe.
                        maxTouchCount = 0;
                        handler.removeMessages(MESSAGE_LONG_CLICK);
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }

                    if (!panEnabled) {
                        vTranslate.x = vTranslateStart.x;
                        vTranslate.y = vTranslateStart.y;
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }

                    refreshRequiredTiles(false);
                }
            }
        }
        if (consumed) {
            handler.removeMessages(MESSAGE_LONG_CLICK);
            invalidate();
            return true;
        }
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_POINTER_UP:
    case MotionEvent.ACTION_POINTER_2_UP:
        handler.removeMessages(MESSAGE_LONG_CLICK);
        if (isQuickScaling) {
            isQuickScaling = false;
            if (!quickScaleMoved) {
                doubleTapZoom(quickScaleCenter, vCenterStart);
            }
        }
        if (maxTouchCount > 0 && (isZooming || isPanning)) {
            if (isZooming && touchCount == 2) {
                // Convert from zoom to pan with remaining touch
                isPanning = true;
                vTranslateStart.set(vTranslate.x, vTranslate.y);
                if (event.getActionIndex() == 1) {
                    vCenterStart.set(event.getX(0), event.getY(0));
                } else {
                    vCenterStart.set(event.getX(1), event.getY(1));
                }
            }
            if (touchCount < 3) {
                // End zooming when only one touch point
                isZooming = false;
            }
            if (touchCount < 2) {
                // End panning when no touch points
                isPanning = false;
                maxTouchCount = 0;
            }
            // Trigger load of tiles now required
            refreshRequiredTiles(true);
            return true;
        }
        if (touchCount == 1) {
            isZooming = false;
            isPanning = false;
            maxTouchCount = 0;
        }
        return true;
    }
    return super.onTouchEvent(event);
}

From source file:com.zenithed.core.widget.scaledimageview.ScaledImageView.java

/**
 * Manages the scroller to scroll ahead the initial destination point with middling it between the focus point,
 * while the content's scale is changing..
 * @param initialDestinationPoint the initial point from the content source to be focused on while zooming (the destination point when zooming ends).
 * @param focusPoint of the view to middle the destination's source point between it.
 * @param initialScale the original scale of the content before scaling, not the current mScale value.
 */// ww w  .ja v  a  2s.  c  o m
private void zoomAndFocusOnPoint(PointF initialDestinationPoint, PointF focusPoint, float initialScale) {
    /*
     * Every point is related to the original selected on, the only differences
     * when moving with the scale motions is the tendency of drawing content scale - initialScale (original mScale).
     */
    PointF currentPoint = new PointF((initialDestinationPoint.x) * (mScale / initialScale),
            (initialDestinationPoint.y) * (mScale / initialScale));

    // gets the top and the left points of the viewport.
    final int pointX = (int) (currentPoint.x - focusPoint.x);
    final int pointY = (int) (currentPoint.y - focusPoint.y);

    mScroller.computeScrollOffset();
    final int startX = mScroller.getCurrX();
    final int startY = mScroller.getCurrY();

    mScroller.startScroll(startX, startY, pointX - startX, pointY - startY, 0);

    fitToBounds();
    refreshRequiredTiles(false);
    ViewCompat.postInvalidateOnAnimation(ScaledImageView.this);
}

From source file:ac.robinson.paperchains.PaperChainsActivity.java

private void animateRecordingInterface(int direction, View keyView) {
    mPlayButton.setVisibility(View.VISIBLE);
    mDeleteButton.setVisibility(View.VISIBLE);
    mSaveButton.setVisibility(View.VISIBLE);

    // animate the control buttons out to be equally spaced around the record button
    float buttonOffset = -mPlayButton.getWidth();
    PointF centre = new PointF(0, 0);
    PointF startingPoint = new PointF(0, buttonOffset);
    double radRot = Math.toRadians(-120);
    double cosRot = Math.cos(radRot);
    double sinRot = Math.sin(radRot);
    QRImageParser.rotatePoint(startingPoint, centre, cosRot, sinRot);
    float leftX = startingPoint.x;
    float leftY = startingPoint.y;
    QRImageParser.rotatePoint(startingPoint, centre, cosRot, sinRot);
    float rightX = startingPoint.x;
    float rightY = startingPoint.y;

    RelativeLayout parent;//from w w w .ja v a  2  s  .  c  om
    AnimatorSet buttonAnimator = new AnimatorSet();
    switch (direction) {
    case 1: // out
        // on an outward animation, we want the three minor buttons to have priority so the record button's
        // larger click area doesn't capture their clicks
        mPlayButton.bringToFront();
        mDeleteButton.bringToFront();
        mSaveButton.bringToFront();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            // need to manually re-layout before KitKat
            parent = (RelativeLayout) mPlayButton.getParent();
            parent.requestLayout();
            parent.invalidate();
        }

        buttonAnimator.playTogether(ObjectAnimator.ofFloat(mDeleteButton, "translationX", 0, leftX),
                ObjectAnimator.ofFloat(mDeleteButton, "translationY", 0, leftY),
                ObjectAnimator.ofFloat(mSaveButton, "translationX", 0, rightX),
                ObjectAnimator.ofFloat(mSaveButton, "translationY", 0, rightY),
                ObjectAnimator.ofFloat(mPlayButton, "translationY", 0, buttonOffset));
        buttonAnimator.setInterpolator(new OvershootInterpolator());
        break;
    case -1: // in
        // keyView is the view we want to be at the front after an inward animation
        if (keyView != null) {
            keyView.bringToFront();
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                // need to manually re-layout before KitKat
                parent = (RelativeLayout) keyView.getParent();
                parent.requestLayout();
                parent.invalidate();
            }
        }

        buttonAnimator.playTogether(ObjectAnimator.ofFloat(mDeleteButton, "translationX", leftX, 0),
                ObjectAnimator.ofFloat(mDeleteButton, "translationY", leftY, 0),
                ObjectAnimator.ofFloat(mSaveButton, "translationX", rightX, 0),
                ObjectAnimator.ofFloat(mSaveButton, "translationY", rightY, 0),
                ObjectAnimator.ofFloat(mPlayButton, "translationY", buttonOffset, 0));
        buttonAnimator.setInterpolator(new AnticipateInterpolator());
        break;
    }
    buttonAnimator.setDuration(BUTTON_ANIMATION_DURATION);
    buttonAnimator.start();
}

From source file:com.zenithed.core.widget.scaledimageview.ScaledImageView.java

/**
 * Convert screen coordinate to source coordinate.
 *//*from   w w  w .jav a  2  s  .  com*/
public PointF viewToSourceCoord(float vx, float vy) {
    if (mTranslate == null) {
        return null;
    }
    float sx = (vx - mTranslate.x) / mScale;
    float sy = (vy - mTranslate.y) / mScale;
    return new PointF(sx, sy);
}

From source file:com.zenithed.core.widget.scaledimageview.ScaledImageView.java

/**
 * Convert source coordinate to screen coordinate.
 *///from  www  .  j a va  2s.  c o  m
public PointF sourceToViewCoord(float sx, float sy) {
    float vx = (sx * mScale) + mTranslate.x;
    float vy = (sy * mScale) + mTranslate.y;
    return new PointF(vx, vy);
}

From source file:com.mylikes.likes.etchasketch.Slate.java

@SuppressLint("NewApi")
@Override/* ww w  .  jav a 2 s . com*/
public boolean onTouchEvent(MotionEvent event) {
    final int action = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) ? event.getActionMasked()
            : event.getAction();
    int N = event.getHistorySize();
    int P = event.getPointerCount();
    long time = event.getEventTime();

    mEmpty = false;

    // starting a new touch? commit the previous state of the canvas
    if (action == MotionEvent.ACTION_DOWN) {
        commitStroke();
    }

    if (mZoomMode) {
        return false;
    }

    int pointerIndex = MotionEventCompat.getActionIndex(event);
    int pointerId = event.getPointerId(pointerIndex);
    if (moveMode) {
        if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) {
            if (firstFinger != null) {
                MotionEvent.PointerCoords coords1 = new MotionEvent.PointerCoords();
                event.getPointerCoords(0, coords1);
                Log.d(TAG, "coords1: " + coords1.x + " " + coords1.y);
                MotionEvent.PointerCoords coords2 = new MotionEvent.PointerCoords();
                event.getPointerCoords(1, coords2);
                firstFinger.set(coords1.x, coords1.y);
                secondFinger = new PointF(coords2.x, coords2.y);
            } else {
                touchStartTime = System.currentTimeMillis();
                moveDrawingStartX = event.getX();
                moveDrawingStartY = event.getY();
                int i = 0;
                moveDrawingIndex = -1;
                resizeDrawingIndex = -1;
                resizeDrawingCorner = null;
                if (selectedDrawing != null) {
                    moveDrawingIndex = 0;
                }
                if (i >= overlays.size()) {
                    return true;
                }
                Log.d(TAG, "Start dragging overlay");
                firstFinger = new PointF(event.getX(), event.getY());
            }
            return true;
        } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {
            if (secondFinger != null) {
                secondFinger = null;
                MotionEvent.PointerCoords coords1 = new MotionEvent.PointerCoords();
                event.getPointerCoords(0, coords1);
                moveDrawingStartX = coords1.x;
                moveDrawingStartY = coords1.y;
                return true;
            }
            if (firstFinger != null) {
                firstFinger = null;
            }
            if (moveDrawingIndex == -1 && resizeDrawingIndex == -1
                    && System.currentTimeMillis() - touchStartTime < 400
                    && Math.abs(event.getX() - moveDrawingStartX)
                            + Math.abs(event.getY() - moveDrawingStartY) < 8) {
                if (resizeDrawingCorner != null && selectedDrawing != null) {
                    if (resizeDrawingCorner == "tl" && selectedDrawing instanceof TextDrawing) {
                        //promptForText((TextDrawing)selectedDrawing);
                    } else if (resizeDrawingCorner == "tr") {
                        //maybeRemoveDrawing(selectedDrawing);
                    }
                } else {
                    //promptForText((int) event.getX(), (int) event.getY());
                }
            }
            moveDrawingIndex = -1;
            Log.d(TAG, "Stop dragging overlay");
            // TODO: add to undo stack
            return true;
        } else if (firstFinger != null && secondFinger != null && action == MotionEvent.ACTION_MOVE) {
            MotionEvent.PointerCoords coords1 = new MotionEvent.PointerCoords();
            event.getPointerCoords(0, coords1);
            Log.d(TAG, "coords1: " + coords1.x + " " + coords1.y);
            MotionEvent.PointerCoords coords2 = new MotionEvent.PointerCoords();
            event.getPointerCoords(1, coords2);
            Log.d(TAG, "coords2: " + coords2.x + " " + coords2.y);
            float xDist = firstFinger.x - secondFinger.x, yDist = firstFinger.y - secondFinger.y;
            float origAngle = (float) Math.atan2(yDist, xDist);
            if (origAngle < 0)
                origAngle += Math.PI * 2;
            float lastDistance = (float) Math.sqrt(xDist * xDist + yDist * yDist);

            xDist = coords2.x - coords1.x;
            yDist = coords2.y - coords1.y;
            float newDistance = (float) Math.sqrt(xDist * xDist + yDist * yDist);
            float newAngle = (float) Math.atan2(yDist, xDist);
            if (newAngle < 0)
                newAngle += Math.PI * 2;
            if (newAngle - origAngle > Math.PI / 2) {
                origAngle += Math.PI;
            } else if (origAngle - newAngle > Math.PI / 2) {
                newAngle += Math.PI;
            }

            firstFinger.set(coords1.x, coords1.y);
            secondFinger = new PointF(coords2.x, coords2.y);
            if (selectedDrawing != null) {
                selectedDrawing.resizeBy(newDistance / lastDistance);
                selectedDrawing.rotateBy(newAngle - origAngle);
                invalidate();
            }
        } else if (moveDrawingIndex >= 0 && moveDrawingIndex < overlays.size()
                && action == MotionEvent.ACTION_MOVE) {
            float x = event.getX();
            float y = event.getY();
            overlays.get(moveDrawingIndex).moveBy((int) ((x - moveDrawingStartX) * getDrawingDensity()),
                    (int) ((y - moveDrawingStartY) * getDrawingDensity()));
            // TODO: only invalidate relevant Rect
            invalidate();
            moveDrawingStartX = x;
            moveDrawingStartY = y;
            return true;
        } else if (resizeDrawingIndex >= 0 && resizeDrawingIndex < overlays.size()
                && action == MotionEvent.ACTION_MOVE) {
            float x = event.getX();
            float y = event.getY();
            overlays.get(resizeDrawingIndex).resizeCorner(resizeDrawingCorner, (int) (x - moveDrawingStartX),
                    (int) (y - moveDrawingStartY));
            // TODO: only invalidate relevant Rect
            invalidate();
            moveDrawingStartX = x;
            moveDrawingStartY = y;
            return true;
        }
        return false;
    }

    if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN
            || action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {
        int j = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) ? event.getActionIndex() : 0;

        mTmpSpot.update(event.getX(j), event.getY(j), event.getSize(j), event.getPressure(j) + event.getSize(j),
                time, getToolTypeCompat(event, j));
        mStrokes[event.getPointerId(j)].add(mTmpSpot);
        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) {
            mStrokes[event.getPointerId(j)].finish(time);
        }
    } else if (action == MotionEvent.ACTION_MOVE) {
        if (dbgX >= 0) {
            dbgRect.set(dbgX - 1, dbgY - 1, dbgX + 1, dbgY + 1);
        }

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < P; j++) {
                mTmpSpot.update(event.getHistoricalX(j, i), event.getHistoricalY(j, i),
                        event.getHistoricalSize(j, i),
                        event.getHistoricalPressure(j, i) + event.getHistoricalSize(j, i),
                        event.getHistoricalEventTime(i), getToolTypeCompat(event, j));
                if ((mDebugFlags & FLAG_DEBUG_STROKES) != 0) {
                    if (dbgX >= 0) {
                        //mTiledCanvas.drawLine(dbgX, dbgY, mTmpSpot.x, mTmpSpot.y, mDebugPaints[3]);
                    }
                    dbgX = mTmpSpot.x;
                    dbgY = mTmpSpot.y;
                    dbgRect.union(dbgX - 1, dbgY - 1, dbgX + 1, dbgY + 1);
                }
                mStrokes[event.getPointerId(j)].add(mTmpSpot);
            }
        }
        for (int j = 0; j < P; j++) {
            mTmpSpot.update(event.getX(j), event.getY(j), event.getSize(j),
                    event.getPressure(j) + event.getSize(j), time, getToolTypeCompat(event, j));
            if ((mDebugFlags & FLAG_DEBUG_STROKES) != 0) {
                if (dbgX >= 0) {
                    //mTiledCanvas.drawLine(dbgX, dbgY, mTmpSpot.x, mTmpSpot.y, mDebugPaints[3]);
                }
                dbgX = mTmpSpot.x;
                dbgY = mTmpSpot.y;
                dbgRect.union(dbgX - 1, dbgY - 1, dbgX + 1, dbgY + 1);
            }
            mStrokes[event.getPointerId(j)].add(mTmpSpot);
        }

        if ((mDebugFlags & FLAG_DEBUG_STROKES) != 0) {
            Rect dirty = new Rect();
            dbgRect.roundOut(dirty);
            invalidate(dirty);
        }
    }

    if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
        for (int j = 0; j < P; j++) {
            mStrokes[event.getPointerId(j)].finish(time);
        }
        dbgX = dbgY = -1;
    }
    return true;
}