| package com.cooliris.media; |
| |
| import android.content.Context; |
| import android.hardware.Sensor; |
| import android.hardware.SensorEvent; |
| import android.os.SystemClock; |
| import android.view.GestureDetector; |
| import android.view.KeyEvent; |
| import android.view.MotionEvent; |
| |
| public final class GridInputProcessor implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener, |
| ScaleGestureDetector.OnScaleGestureListener { |
| private int mCurrentFocusSlot; |
| private boolean mCurrentFocusIsPressed; |
| private int mCurrentSelectedSlot; |
| |
| private float mPrevTiltValueLowPass; |
| private float mPrevShakeValueHighPass; |
| private float mShakeValue; |
| private int mTouchPosX; |
| private int mTouchPosY; |
| private int mActionCode; |
| private long mPrevTouchTime; |
| private float mFirstTouchPosX; |
| private float mFirstTouchPosY; |
| private float mPrevTouchPosX; |
| private float mPrevTouchPosY; |
| private float mTouchVelX; |
| private float mTouchVelY; |
| private boolean mProcessTouch; |
| private boolean mTouchMoved; |
| private float mDpadIgnoreTime = 0.0f; |
| private GridCamera mCamera; |
| private GridLayer mLayer; |
| private Context mContext; |
| private Pool<Vector3f> mPool; |
| private DisplayItem[] mDisplayItems; |
| private boolean mPrevHitEdge; |
| private boolean mTouchFeedbackDelivered; |
| private GestureDetector mGestureDetector; |
| private ScaleGestureDetector mScaleGestureDetector; |
| private boolean mZoomGesture; |
| |
| public GridInputProcessor(Context context, GridCamera camera, GridLayer layer, RenderView view, Pool<Vector3f> pool, |
| DisplayItem[] displayItems) { |
| mPool = pool; |
| mCamera = camera; |
| mLayer = layer; |
| mCurrentFocusSlot = Shared.INVALID; |
| mCurrentSelectedSlot = Shared.INVALID; |
| mContext = context; |
| mDisplayItems = displayItems; |
| mGestureDetector = new GestureDetector(context, this); |
| mScaleGestureDetector = new ScaleGestureDetector(context, this); |
| mGestureDetector.setIsLongpressEnabled(true); |
| mZoomGesture = false; |
| } |
| |
| public int getCurrentFocusSlot() { |
| return mCurrentFocusSlot; |
| } |
| |
| public int getCurrentSelectedSlot() { |
| return mCurrentSelectedSlot; |
| } |
| |
| public void setCurrentSelectedSlot(int slot) { |
| mCurrentSelectedSlot = slot; |
| GridLayer layer = mLayer; |
| layer.setState(GridLayer.STATE_FULL_SCREEN); |
| mCamera.mConvergenceSpeed = 2.0f; |
| DisplayItem displayItem = layer.getDisplayItemForSlotId(slot); |
| MediaItem item = null; |
| if (displayItem != null) |
| item = displayItem.mItemRef; |
| layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1); |
| } |
| |
| public void onSensorChanged(RenderView view, SensorEvent event, int state) { |
| switch (event.sensor.getType()) { |
| case Sensor.TYPE_ACCELEROMETER: |
| case Sensor.TYPE_ORIENTATION: |
| float[] values = event.values; |
| float valueToUse = (mCamera.mWidth < mCamera.mHeight) ? values[0] : -values[1]; |
| float tiltValue = 0.8f * mPrevTiltValueLowPass + 0.2f * valueToUse; |
| if (Math.abs(tiltValue) < 0.5f) |
| tiltValue = 0.0f; |
| if (state == GridLayer.STATE_FULL_SCREEN) |
| tiltValue = 0.0f; |
| if (tiltValue != 0.0f) |
| view.requestRender(); |
| mCamera.mEyeOffsetX = -3.0f * tiltValue; |
| float shakeValue = values[1] * values[1] + values[2] * values[2]; |
| mShakeValue = shakeValue - mPrevShakeValueHighPass; |
| mPrevShakeValueHighPass = shakeValue; |
| if (mShakeValue < 16.0f) { |
| mShakeValue = 0; |
| } else { |
| mShakeValue = mShakeValue * 4.0f; |
| if (mShakeValue > 200) { |
| mShakeValue = 200; |
| } |
| } |
| break; |
| } |
| } |
| |
| public boolean onTouchEvent(MotionEvent event) { |
| mTouchPosX = (int) (event.getX()); |
| mTouchPosY = (int) (event.getY()); |
| mActionCode = event.getAction(); |
| long timestamp = SystemClock.elapsedRealtime(); |
| long delta = timestamp - mPrevTouchTime; |
| mPrevTouchTime = timestamp; |
| float timeElapsed = (float) delta; |
| timeElapsed = timeElapsed * 0.001f; // division by 1000 for seconds |
| switch (mActionCode) { |
| case MotionEvent.ACTION_UP: |
| if (mProcessTouch == false) { |
| touchBegan(mTouchPosX, mTouchPosY); |
| } |
| touchEnded(mTouchPosX, mTouchPosY, timeElapsed); |
| break; |
| case MotionEvent.ACTION_DOWN: |
| mPrevTouchTime = timestamp; |
| touchBegan(mTouchPosX, mTouchPosY); |
| break; |
| case MotionEvent.ACTION_MOVE: |
| touchMoved(mTouchPosX, mTouchPosY, timeElapsed); |
| break; |
| } |
| mGestureDetector.onTouchEvent(event); |
| mScaleGestureDetector.onTouchEvent(event); |
| return true; |
| } |
| |
| public boolean onKeyDown(int keyCode, KeyEvent event, int state) { |
| GridLayer layer = mLayer; |
| if (keyCode == KeyEvent.KEYCODE_BACK) { |
| if (layer.getViewIntent()) |
| return false; |
| if (layer.getHud().getMode() == HudLayer.MODE_SELECT) { |
| layer.deselectAll(); |
| return true; |
| } |
| if (layer.inSlideShowMode()) { |
| layer.endSlideshow(); |
| layer.getHud().setAlpha(1.0f); |
| return true; |
| } |
| float zoomValue = layer.getZoomValue(); |
| if (zoomValue != 1.0f) { |
| layer.setZoomValue(1.0f); |
| layer.centerCameraForSlot(mCurrentSelectedSlot, 1.0f); |
| return true; |
| } |
| layer.goBack(); |
| if (state == GridLayer.STATE_MEDIA_SETS) |
| return false; |
| return true; |
| } |
| if (mDpadIgnoreTime < 0.1f) |
| return true; |
| mDpadIgnoreTime = 0.0f; |
| IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange(); |
| int firstBufferedVisibleSlot = bufferedVisibleRange.begin; |
| int lastBufferedVisibleSlot = bufferedVisibleRange.end; |
| int anchorSlot = layer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER); |
| if (state == GridLayer.STATE_FULL_SCREEN) { |
| if (keyCode != KeyEvent.KEYCODE_VOLUME_UP && keyCode != KeyEvent.KEYCODE_VOLUME_DOWN |
| && keyCode != KeyEvent.KEYCODE_MUTE && keyCode != KeyEvent.KEYCODE_HEADSETHOOK |
| && keyCode != KeyEvent.KEYCODE_NOTIFICATION) { |
| layer.endSlideshow(); |
| } |
| boolean needsVibrate = false; |
| if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { |
| needsVibrate = !layer.changeFocusToNextSlot(1.0f); |
| } |
| if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { |
| needsVibrate = !layer.changeFocusToPreviousSlot(1.0f); |
| } |
| if (needsVibrate) { |
| vibrateShort(); |
| } |
| if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && !mCamera.isAnimating()) { |
| if (layer.getZoomValue() == 1.0f) |
| layer.zoomInToSelectedItem(); |
| else |
| layer.setZoomValue(1.0f); |
| } |
| if (keyCode == KeyEvent.KEYCODE_MENU) { |
| if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) { |
| return true; |
| } |
| if (layer.getHud().getMode() == HudLayer.MODE_NORMAL) |
| layer.enterSelectionMode(); |
| else |
| layer.deselectAll(); |
| } |
| } else { |
| mCurrentFocusIsPressed = false; |
| int numRows = ((GridLayoutInterface) layer.getLayoutInterface()).mNumRows; |
| if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && mCurrentFocusSlot != Shared.INVALID) { |
| if (layer.getHud().getMode() != HudLayer.MODE_SELECT) { |
| boolean centerCamera = layer.tapGesture(mCurrentFocusSlot, false); |
| if (centerCamera) { |
| int slotId = mCurrentFocusSlot; |
| selectSlot(slotId); |
| } |
| mCurrentFocusSlot = Shared.INVALID; |
| return true; |
| } else { |
| layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true); |
| } |
| mCurrentFocusIsPressed = true; |
| } else if (keyCode == KeyEvent.KEYCODE_MENU && mCurrentFocusSlot != Shared.INVALID) { |
| if (layer.getHud().getMode() == HudLayer.MODE_NORMAL) |
| layer.enterSelectionMode(); |
| else |
| layer.deselectAll(); |
| } else if (mCurrentFocusSlot == Shared.INVALID) { |
| mCurrentFocusSlot = anchorSlot; |
| } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { |
| mCurrentFocusSlot += numRows; |
| } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { |
| mCurrentFocusSlot -= numRows; |
| } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { |
| --mCurrentFocusSlot; |
| } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { |
| ++mCurrentFocusSlot; |
| } |
| if (mCurrentFocusSlot > lastBufferedVisibleSlot) { |
| mCurrentFocusSlot = lastBufferedVisibleSlot; |
| } |
| if (mCurrentFocusSlot < firstBufferedVisibleSlot) |
| mCurrentFocusSlot = firstBufferedVisibleSlot; |
| if (mCurrentFocusSlot != Shared.INVALID) { |
| layer.centerCameraForSlot(mCurrentFocusSlot, 1.0f); |
| } |
| } |
| return false; |
| } |
| |
| private void touchBegan(int posX, int posY) { |
| mPrevTouchPosX = posX; |
| mPrevTouchPosY = posY; |
| mFirstTouchPosX = posX; |
| mFirstTouchPosY = posY; |
| mTouchVelX = 0; |
| mTouchVelY = 0; |
| mProcessTouch = true; |
| mTouchMoved = false; |
| mCamera.stopMovementInX(); |
| GridLayer layer = mLayer; |
| mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY); |
| mCurrentFocusIsPressed = true; |
| mTouchFeedbackDelivered = false; |
| HudLayer hud = layer.getHud(); |
| if (hud.getMode() == HudLayer.MODE_SELECT) |
| hud.closeSelectionMenu(); |
| if (layer.getState() == GridLayer.STATE_FULL_SCREEN && hud.getMode() == HudLayer.MODE_SELECT) { |
| layer.deselectAll(); |
| hud.setAlpha(1.0f); |
| } |
| int slotId = layer.getSlotIndexForScreenPosition(posX, posY); |
| if (slotId != Shared.INVALID && layer.getState() != GridLayer.STATE_FULL_SCREEN) { |
| vibrateShort(); |
| } |
| } |
| |
| private void touchMoved(int posX, int posY, float timeElapsedx) { |
| if (mProcessTouch && !mZoomGesture) { |
| GridLayer layer = mLayer; |
| GridCamera camera = mCamera; |
| float deltaX = -(posX - mPrevTouchPosX); // negation since the wall |
| // moves in a direction |
| // opposite to that of |
| // the touch |
| float deltaY = -(posY - mPrevTouchPosY); |
| if (Math.abs(deltaX) >= 10.0f || Math.abs(deltaY) >= 10.0f) { |
| mTouchMoved = true; |
| } |
| Pool<Vector3f> pool = mPool; |
| Vector3f firstPosition = pool.create(); |
| Vector3f lastPosition = pool.create(); |
| Vector3f deltaAnchorPosition = pool.create(); |
| Vector3f worldPosDelta = pool.create(); |
| try { |
| deltaAnchorPosition.set(layer.getDeltaAnchorPosition()); |
| LayoutInterface layout = layer.getLayoutInterface(); |
| GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition); |
| int lastSlotIndex = 0; |
| IndexRange completeRange = layer.getCompleteRange(); |
| synchronized (completeRange) { |
| lastSlotIndex = completeRange.end; |
| } |
| GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition); |
| |
| camera.convertToRelativeCameraSpace(deltaX, deltaY, 0, worldPosDelta); |
| deltaX = worldPosDelta.x; |
| deltaY = worldPosDelta.y; |
| camera.moveBy(deltaX, (layer.getZoomValue() == 1.0f) ? 0 : deltaY, 0); |
| deltaX *= camera.mScale; |
| deltaY *= camera.mScale; |
| } finally { |
| pool.delete(firstPosition); |
| pool.delete(lastPosition); |
| pool.delete(deltaAnchorPosition); |
| pool.delete(worldPosDelta); |
| } |
| if (layer.getZoomValue() == 1.0f) { |
| if (camera |
| .computeConstraints(false, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition)) { |
| deltaX = 0.0f; |
| // vibrate |
| if (!mTouchFeedbackDelivered) { |
| mTouchFeedbackDelivered = true; |
| vibrateLong(); |
| } |
| } |
| } |
| mTouchVelX = deltaX * timeElapsedx; |
| mTouchVelY = deltaY * timeElapsedx; |
| float maxVelXx = (mCamera.mWidth * 0.5f); |
| float maxVelYx = (mCamera.mHeight); |
| mTouchVelX = FloatUtils.clamp(mTouchVelX, -maxVelXx, maxVelXx); |
| mTouchVelY = FloatUtils.clamp(mTouchVelY, -maxVelYx, maxVelYx); |
| mPrevTouchPosX = posX; |
| mPrevTouchPosY = posY; |
| // you want the movement to track the finger immediately |
| if (mTouchMoved == false) |
| mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY); |
| else |
| mCurrentFocusSlot = Shared.INVALID; |
| if (!mCamera.isZAnimating()) { |
| mCamera.commitMoveInX(); |
| mCamera.commitMoveInY(); |
| } |
| int anchorSlotIndex = layer.getAnchorSlotIndex(GridLayer.ANCHOR_LEFT); |
| DisplayItem[] displayItems = mDisplayItems; |
| IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange(); |
| int firstBufferedVisibleSlot = bufferedVisibleRange.begin; |
| int lastBufferedVisibleSlot = bufferedVisibleRange.end; |
| synchronized (displayItems) { |
| if (anchorSlotIndex >= firstBufferedVisibleSlot && anchorSlotIndex <= lastBufferedVisibleSlot) { |
| DisplayItem item = displayItems[(anchorSlotIndex - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT]; |
| if (item != null) { |
| layer.getHud().setTimeBarTime(item.mItemRef.mDateTakenInMs); |
| } |
| } |
| } |
| } |
| } |
| |
| private void touchEnded(int posX, int posY, float timeElapsedx) { |
| if (mProcessTouch == false) { |
| mZoomGesture = false; |
| return; |
| } |
| int maxPixelsBeforeSwitch = mCamera.mWidth / 8; |
| mCamera.mConvergenceSpeed = 2.0f; |
| GridLayer layer = mLayer; |
| if (layer.getExpandedSlot() == Shared.INVALID && !layer.feedAboutToChange() && !mZoomGesture) { |
| if (mCurrentSelectedSlot != Shared.INVALID) { |
| if (layer.getState() == GridLayer.STATE_FULL_SCREEN) { |
| if (!mTouchMoved) { |
| // tap gesture for fullscreen |
| if (layer.getZoomValue() == 1.0f) |
| layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f); |
| } else if (layer.getZoomValue() == 1.0f) { |
| // we want to snap to a new slotIndex based on where the |
| // current position is |
| if (layer.inSlideShowMode()) { |
| layer.endSlideshow(); |
| } |
| float deltaX = posX - mFirstTouchPosX; |
| float deltaY = posY - mFirstTouchPosY; |
| if (deltaY != 0) { |
| // it has moved vertically |
| } |
| layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f); |
| HudLayer hud = layer.getHud(); |
| if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) { |
| layer.changeFocusToPreviousSlot(1.0f); |
| } else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) { |
| layer.changeFocusToNextSlot(1.0f); |
| } |
| } else { |
| // in zoomed state |
| // we do nothing for now, but we should clamp to the |
| // image bounds |
| boolean hitEdge = layer.constrainCameraForSlot(mCurrentSelectedSlot); |
| // mPrevHitEdge = false; |
| if (hitEdge && mPrevHitEdge) { |
| float deltaX = posX - mFirstTouchPosX; |
| float deltaY = posY - mFirstTouchPosY; |
| maxPixelsBeforeSwitch *= 4; |
| if (deltaY != 0) { |
| // it has moved vertically |
| } |
| mPrevHitEdge = false; |
| HudLayer hud = layer.getHud(); |
| if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) { |
| layer.changeFocusToPreviousSlot(1.0f); |
| } else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) { |
| layer.changeFocusToNextSlot(1.0f); |
| } else { |
| mPrevHitEdge = hitEdge; |
| } |
| } else { |
| mPrevHitEdge = hitEdge; |
| } |
| } |
| } |
| } else { |
| if (!layer.feedAboutToChange() && layer.getZoomValue() == 1.0f) { |
| constrainCamera(true); |
| } |
| } |
| } |
| mCurrentFocusSlot = Shared.INVALID; |
| mCurrentFocusIsPressed = false; |
| mPrevTouchPosX = posX; |
| mPrevTouchPosY = posY; |
| mProcessTouch = false; |
| mZoomGesture = false; |
| } |
| |
| private void constrainCamera(boolean b) { |
| Pool<Vector3f> pool = mPool; |
| GridLayer layer = mLayer; |
| Vector3f firstPosition = pool.create(); |
| Vector3f lastPosition = pool.create(); |
| Vector3f deltaAnchorPosition = pool.create(); |
| try { |
| deltaAnchorPosition.set(layer.getDeltaAnchorPosition()); |
| GridCamera camera = mCamera; |
| LayoutInterface layout = layer.getLayoutInterface(); |
| GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition); |
| int lastSlotIndex = 0; |
| IndexRange completeRange = layer.getCompleteRange(); |
| synchronized (completeRange) { |
| lastSlotIndex = completeRange.end; |
| } |
| GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition); |
| camera.computeConstraints(true, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition); |
| } finally { |
| pool.delete(firstPosition); |
| pool.delete(lastPosition); |
| pool.delete(deltaAnchorPosition); |
| } |
| } |
| |
| public void clearSelection() { |
| mCurrentSelectedSlot = Shared.INVALID; |
| } |
| |
| public void clearFocus() { |
| mCurrentFocusSlot = Shared.INVALID; |
| } |
| |
| public boolean isFocusItemPressed() { |
| return mCurrentFocusIsPressed; |
| } |
| |
| public void update(float timeElapsed) { |
| mDpadIgnoreTime += timeElapsed; |
| } |
| |
| public void setCurrentFocusSlot(int slotId) { |
| mCurrentSelectedSlot = slotId; |
| } |
| |
| public boolean onDown(MotionEvent e) { |
| // TODO Auto-generated method stub |
| return true; |
| } |
| |
| public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { |
| if (mCurrentSelectedSlot == Shared.INVALID) { |
| mCamera.moveYTo(0); |
| mCamera.moveZTo(0); |
| mCamera.mConvergenceSpeed = 1.0f; |
| float normalizedVelocity = velocityX * mCamera.mOneByScale; |
| // mCamera.moveBy(-velocityX * mCamera.mOneByScale * 0.25f, 0, 0); |
| // constrainCamera(true); |
| IndexRange visibleRange = mLayer.getVisibleRange(); |
| int numVisibleSlots = visibleRange.end - visibleRange.begin; |
| if (numVisibleSlots > 0) { |
| float fastFlingVelocity = 20.0f; |
| int slotsToSkip = (int) (numVisibleSlots * (-normalizedVelocity / fastFlingVelocity)); |
| int maxSlots = numVisibleSlots; |
| if (slotsToSkip > maxSlots) |
| slotsToSkip = maxSlots; |
| if (slotsToSkip < -maxSlots) |
| slotsToSkip = -maxSlots; |
| if (Math.abs(slotsToSkip) <= 1) { |
| if (velocityX > 0) |
| slotsToSkip = -2; |
| else if (velocityX < 0) |
| slotsToSkip = 2; |
| } |
| int slotToGetTo = mLayer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER) + slotsToSkip; |
| if (slotToGetTo < 0) |
| slotToGetTo = 0; |
| int lastSlot = mLayer.getCompleteRange().end; |
| if (slotToGetTo > lastSlot) |
| slotToGetTo = lastSlot; |
| mLayer.centerCameraForSlot(slotToGetTo, 1.0f); |
| } |
| constrainCamera(true); |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| public void onLongPress(MotionEvent e) { |
| if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) { |
| HudLayer hud = mLayer.getHud(); |
| hud.getPathBar().setHidden(true); |
| hud.getMenuBar().setHidden(true); |
| if (hud.getMode() != HudLayer.MODE_NORMAL) |
| hud.setMode(HudLayer.MODE_NORMAL); |
| } |
| if (mCurrentFocusSlot != Shared.INVALID) { |
| vibrateLong(); |
| GridLayer layer = mLayer; |
| if (layer.getState() == GridLayer.STATE_FULL_SCREEN) { |
| layer.deselectAll(); |
| } |
| HudLayer hud = layer.getHud(); |
| hud.enterSelectionMode(); |
| layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true); |
| } |
| } |
| |
| public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| public void onShowPress(MotionEvent e) { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| public boolean onSingleTapUp(MotionEvent e) { |
| GridLayer layer = mLayer; |
| int posX = (int) e.getX(); |
| int posY = (int) e.getY(); |
| if (mCurrentSelectedSlot != Shared.INVALID) { |
| // Fullscreen mode. |
| mCamera.mConvergenceSpeed = 2.0f; |
| int slotId = mCurrentSelectedSlot; |
| if (layer.getZoomValue() == 1.0f) { |
| layer.centerCameraForSlot(slotId, 1.0f); |
| } else { |
| layer.constrainCameraForSlot(slotId); |
| } |
| DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId); |
| if (displayItem != null) { |
| final MediaItem item = displayItem.mItemRef; |
| int heightBy2 = mCamera.mHeight / 2; |
| boolean posYInBounds = (Math.abs(posY - heightBy2) < 64); |
| if (posX < 32 && posYInBounds) { |
| layer.changeFocusToPreviousSlot(1.0f); |
| } else if (posX > mCamera.mWidth - 32 && posYInBounds) { |
| layer.changeFocusToNextSlot(1.0f); |
| } else if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) { |
| Utils.playVideo(mContext, item); |
| } else { |
| // We stop any slideshow. |
| HudLayer hud = layer.getHud(); |
| if (layer.inSlideShowMode()) { |
| layer.endSlideshow(); |
| } else { |
| hud.setAlpha(1.0f - hud.getAlpha()); |
| } |
| if (hud.getMode() == HudLayer.MODE_SELECT) { |
| hud.setAlpha(1.0f); |
| } |
| } |
| } |
| } else { |
| int slotId = layer.getSlotIndexForScreenPosition(posX, posY); |
| if (slotId != Shared.INVALID) { |
| HudLayer hud = layer.getHud(); |
| if (hud.getMode() == HudLayer.MODE_SELECT) { |
| layer.addSlotToSelectedItems(slotId, true, true); |
| } else { |
| boolean centerCamera = (mCurrentSelectedSlot == Shared.INVALID) ? layer.tapGesture(slotId, false) : true; |
| if (centerCamera) { |
| // We check if this item is a video or not. |
| selectSlot(slotId); |
| } |
| } |
| } else { |
| int state = layer.getState(); |
| if (state != GridLayer.STATE_FULL_SCREEN && state != GridLayer.STATE_GRID_VIEW |
| && layer.getHud().getMode() != HudLayer.MODE_SELECT) { |
| slotId = layer.getMetadataSlotIndexForScreenPosition(posX, posY); |
| if (slotId != Shared.INVALID) { |
| layer.tapGesture(slotId, true); |
| } |
| } |
| } |
| } |
| return true; |
| } |
| |
| private void selectSlot(int slotId) { |
| GridLayer layer = mLayer; |
| if (layer.getState() == GridLayer.STATE_GRID_VIEW) { |
| DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId); |
| if (displayItem != null) { |
| final MediaItem item = displayItem.mItemRef; |
| if (layer.getPickIntent()) { |
| // we need to return this item |
| ((Gallery) mContext).getHandler().post(new Runnable() { |
| public void run() { |
| ((Gallery) mContext).launchCropperOrFinish(item); |
| } |
| }); |
| return; |
| } |
| if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) { |
| Utils.playVideo(mContext, item); |
| } else { |
| mCurrentSelectedSlot = slotId; |
| layer.endSlideshow(); |
| layer.setState(GridLayer.STATE_FULL_SCREEN); |
| mCamera.mConvergenceSpeed = 2.0f; |
| layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1); |
| } |
| } |
| } |
| } |
| |
| public boolean onDoubleTap(MotionEvent e) { |
| final GridLayer layer = mLayer; |
| if (layer.getState() == GridLayer.STATE_FULL_SCREEN && !mCamera.isZAnimating()) { |
| float posX = e.getX(); |
| float posY = e.getY(); |
| final Vector3f retVal = new Vector3f(); |
| posX -= (mCamera.mWidth / 2); |
| posY -= (mCamera.mHeight / 2); |
| mCamera.convertToRelativeCameraSpace(posX, posY, 0, retVal); |
| if (layer.getZoomValue() == 1.0f) { |
| layer.setZoomValue(3f); |
| mCamera.update(0.001f); |
| mCamera.moveBy(retVal.x, retVal.y, 0); |
| layer.constrainCameraForSlot(mCurrentSelectedSlot); |
| } else { |
| layer.setZoomValue(1.0f); |
| } |
| mCamera.mConvergenceSpeed = 2.0f; |
| } else { |
| return onSingleTapConfirmed(e); |
| } |
| return true; |
| } |
| |
| public boolean onDoubleTapEvent(MotionEvent e) { |
| return false; |
| } |
| |
| public boolean onSingleTapConfirmed(MotionEvent e) { |
| return false; |
| } |
| |
| public boolean touchPressed() { |
| return mProcessTouch; |
| } |
| |
| private void vibrateShort() { |
| // As per request by Google, this line disables vibration. |
| // mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); |
| } |
| |
| private void vibrateLong() { |
| // mView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); |
| } |
| |
| public boolean onScale(ScaleGestureDetector detector) { |
| final GridLayer layer = mLayer; |
| if (layer.getState() == GridLayer.STATE_FULL_SCREEN) { |
| float scale = detector.getScaleFactor(); |
| float currentScale = layer.getZoomValue(); |
| if (currentScale < 0.7f && scale < 1.0f) { |
| scale = 1.0f; |
| } |
| if (currentScale > 8.0f && scale > 1.0f) { |
| scale = 1.0f; |
| } |
| layer.setZoomValue(currentScale * scale); |
| } |
| return true; |
| } |
| |
| public boolean onScaleBegin(ScaleGestureDetector detector) { |
| mZoomGesture = true; |
| mLayer.getHud().hideZoomButtons(true); |
| return true; |
| } |
| |
| public void onScaleEnd(ScaleGestureDetector detector) { |
| final GridLayer layer = mLayer; |
| if (layer.getState() == GridLayer.STATE_FULL_SCREEN) { |
| float currentScale = layer.getZoomValue(); |
| if (currentScale < 1.0f) { |
| currentScale = 1.0f; |
| } else if (currentScale > 6.0f) { |
| currentScale = 6.0f; |
| } |
| if (currentScale != layer.getZoomValue()) { |
| layer.setZoomValue(currentScale); |
| } |
| layer.constrainCameraForSlot(mCurrentSelectedSlot); |
| mLayer.getHud().hideZoomButtons(false); |
| } |
| } |
| } |