public void reloadTexture(int frontIndex, View frontView, int backIndex, View backView) { synchronized (this) { boolean frontChanged = frontCards.loadView(frontIndex, frontView, controller.getAnimationBitmapFormat()); boolean backChanged = backCards.loadView(backIndex, backView, controller.getAnimationBitmapFormat()); if (AphidLog.ENABLE_DEBUG) { AphidLog.d( "reloading texture: %s and %s; old views: %s, %s, front changed %s, back changed %s", frontView, backView, frontCards.getView(), backCards.getView(), frontChanged, backChanged); } if (AphidLog.ENABLE_DEBUG) { AphidLog.d( "reloadTexture: activeIndex %d, front %d, back %d, angle %.1f", getPageIndexFromAngle(accumulatedAngle), frontIndex, backIndex, accumulatedAngle); } } }
public void reloadTexture(int frontIndex, View frontView, int backIndex, View backView) { synchronized (this) { boolean frontChanged = frontCards.loadView(frontIndex, frontView, controller.getAnimationBitmapFormat()); boolean backChanged = backCards.loadView(backIndex, backView, controller.getAnimationBitmapFormat()); } }
synchronized void resetSelection(int selection, int maxIndex) { // stop flip animation when selection is manually changed this.maxIndex = maxIndex; setVisible(false); setState(STATE_INIT); accumulatedAngle = selection * 180; frontCards.resetWithIndex(selection); backCards.resetWithIndex(selection + 1 < maxIndex ? selection + 1 : -1); controller.postHideFlipAnimation(); }
boolean refreshPage(int pageIndex) { boolean match = false; if (frontCards.getIndex() == pageIndex) { frontCards.resetWithIndex(pageIndex); match = true; } if (backCards.getIndex() == pageIndex) { backCards.resetWithIndex(pageIndex); match = true; } return match; }
public void rotateBy(float delta) { angle += delta; if (backCards.getIndex() == -1) { if (angle >= MAX_TIP_ANGLE) angle = MAX_TIP_ANGLE; } if (angle > 180) angle = 180; else if (angle < 0) angle = 0; }
boolean refreshPageView(View view) { boolean match = false; if (frontCards.getView() == view) { frontCards.resetWithIndex(frontCards.getIndex()); match = true; } if (backCards.getView() == view) { backCards.resetWithIndex(backCards.getIndex()); match = true; } return match; }
public void reloadTexture(int frontIndex, View frontView, int backIndex, View backView) { synchronized (this) { if (frontView != null) { if (backCards.getView() == frontView) { frontCards.setView(-1, null); swapCards(); } } if (backView != null) { if (frontCards.getView() == backView) { backCards.setView(-1, null); swapCards(); } } boolean frontChanged = frontCards.setView(frontIndex, frontView); boolean backChanged = backCards.setView(backIndex, backView); if (AphidLog.ENABLE_DEBUG) AphidLog.d( "reloading texture: %s and %s; old views: %s, %s, front changed %s, back changed %s", frontView, backView, frontCards.getView(), backCards.getView(), frontChanged, backChanged); if (frontIndex == activeIndex) { if (angle >= 180) angle -= 180; else if (angle < 0) angle += 180; } else if (backIndex == activeIndex) { if (angle < 0) angle += 180; } // AphidLog.i("View changed: front (%d, %s), back (%d, %s), angle %s, activeIndex %d", // frontIndex, frontView, backIndex, backView, angle, activeIndex); } }
public synchronized boolean handleTouchEvent(MotionEvent event, boolean isOnTouchEvent) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // remember page we started on... lastPageIndex = getPageIndexFromAngle(accumulatedAngle); lastPosition = orientationVertical ? event.getY() : event.getX(); return isOnTouchEvent; case MotionEvent.ACTION_MOVE: float delta = orientationVertical ? (lastPosition - event.getY()) : (lastPosition - event.getX()); if (Math.abs(delta) > controller.getTouchSlop()) { setState(STATE_TOUCH); forward = delta > 0; } if (state == STATE_TOUCH) { if (Math.abs(delta) > MIN_MOVEMENT) // ignore small movements { forward = delta > 0; } controller.showFlipAnimation(); float angleDelta; if (orientationVertical) { angleDelta = 180 * delta / controller.getContentHeight() * MOVEMENT_RATE; } else { angleDelta = 180 * delta / controller.getContentWidth() * MOVEMENT_RATE; } if (Math.abs(angleDelta) > MAX_TOUCH_MOVE_ANGLE) // prevent large delta when moving too fast { angleDelta = Math.signum(angleDelta) * MAX_TOUCH_MOVE_ANGLE; } // do not flip more than one page with one touch... if (Math.abs(getPageIndexFromAngle(accumulatedAngle + angleDelta) - lastPageIndex) <= 1) { accumulatedAngle += angleDelta; } // Bounce the page for the first and the last page if (frontCards.getIndex() == maxIndex - 1) { // the last page if (accumulatedAngle > frontCards.getIndex() * 180) { accumulatedAngle = Math.min( accumulatedAngle, controller.isOverFlipEnabled() ? (frontCards.getIndex() * 180 + MAX_TIP_ANGLE) : (frontCards.getIndex() * 180)); } } if (accumulatedAngle < 0) { accumulatedAngle = Math.max(accumulatedAngle, controller.isOverFlipEnabled() ? -MAX_TIP_ANGLE : 0); } int anglePageIndex = getPageIndexFromAngle(accumulatedAngle); if (accumulatedAngle >= 0) { if (anglePageIndex != frontCards.getIndex()) { if (anglePageIndex == frontCards.getIndex() - 1) { // moved to previous page swapCards(); // frontCards becomes the backCards frontCards.resetWithIndex(backCards.getIndex() - 1); controller.flippedToView(anglePageIndex, false); } else if (anglePageIndex == frontCards.getIndex() + 1) { // moved to next page swapCards(); backCards.resetWithIndex(frontCards.getIndex() + 1); controller.flippedToView(anglePageIndex, false); } else { throw new RuntimeException( AphidLog.format( "Inconsistent states: anglePageIndex: %d, accumulatedAngle %.1f, frontCards %d, backCards %d", anglePageIndex, accumulatedAngle, frontCards.getIndex(), backCards.getIndex())); } } } lastPosition = orientationVertical ? event.getY() : event.getX(); controller.getSurfaceView().requestRender(); return true; } return isOnTouchEvent; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (state == STATE_TOUCH) { if (accumulatedAngle < 0) { forward = true; } else if (accumulatedAngle >= frontCards.getIndex() * 180 && frontCards.getIndex() == maxIndex - 1) { forward = false; } setState(STATE_AUTO_ROTATE); controller.getSurfaceView().requestRender(); } return isOnTouchEvent; } return false; }
public void invalidateTexture() { frontCards.abandonTexture(); backCards.abandonTexture(); }
public synchronized void draw(FlipRenderer renderer, GL10 gl) { frontCards.buildTexture(renderer, gl); backCards.buildTexture(renderer, gl); if (!TextureUtils.isValidTexture(frontCards.getTexture()) && !TextureUtils.isValidTexture(backCards.getTexture())) { return; } if (!visible) { return; } switch (state) { case STATE_INIT: case STATE_TOUCH: break; case STATE_AUTO_ROTATE: { animatedFrame++; float delta = (forward ? ACCELERATION : -ACCELERATION) * animatedFrame % 180; float oldAngle = accumulatedAngle; accumulatedAngle += delta; if (oldAngle < 0) { // bouncing back after flip backward and over the first page Assert.assertTrue(forward); if (accumulatedAngle >= 0) { accumulatedAngle = 0; setState(STATE_INIT); } } else { if (frontCards.getIndex() == maxIndex - 1 && oldAngle > frontCards.getIndex() * 180) { // bouncing back after flip forward and over the last page Assert.assertTrue(!forward); if (accumulatedAngle <= frontCards.getIndex() * 180) { setState(STATE_INIT); accumulatedAngle = frontCards.getIndex() * 180; } } else { if (forward) { Assert.assertTrue( "index of backCards should not be -1 when automatically flipping forward", backCards.getIndex() != -1); if (accumulatedAngle >= backCards.getIndex() * 180) { // moved to the next page accumulatedAngle = backCards.getIndex() * 180; setState(STATE_INIT); controller.postFlippedToView(backCards.getIndex()); swapCards(); backCards.resetWithIndex(frontCards.getIndex() + 1); } } else { // backward if (accumulatedAngle <= frontCards.getIndex() * 180) { // firstCards restored accumulatedAngle = frontCards.getIndex() * 180; setState(STATE_INIT); } } } } // ends of `if (oldAngle < 0) {} else {}` if (state == STATE_INIT) { controller.postHideFlipAnimation(); } else { controller.getSurfaceView().requestRender(); } } break; default: AphidLog.e("Invalid state: " + state); break; } float angle = getDisplayAngle(); if (angle < 0) { frontCards.getTopCard().setAxis(Card.AXIS_BOTTOM); frontCards.getTopCard().setAngle(-angle); frontCards.getTopCard().draw(gl); frontCards.getBottomCard().setAngle(0); frontCards.getBottomCard().draw(gl); // no need to draw backCards here } else { if (angle < 90) { // render front view over back view frontCards.getTopCard().setAngle(0); frontCards.getTopCard().draw(gl); backCards.getBottomCard().setAngle(0); backCards.getBottomCard().draw(gl); frontCards.getBottomCard().setAxis(Card.AXIS_TOP); frontCards.getBottomCard().setAngle(angle); frontCards.getBottomCard().draw(gl); } else { // render back view first frontCards.getTopCard().setAngle(0); frontCards.getTopCard().draw(gl); backCards.getTopCard().setAxis(Card.AXIS_BOTTOM); backCards.getTopCard().setAngle(180 - angle); backCards.getTopCard().draw(gl); backCards.getBottomCard().setAngle(0); backCards.getBottomCard().draw(gl); } } if ((frontCards.getView() == null || TextureUtils.isValidTexture(frontCards.getTexture())) && (backCards.getView() == null || TextureUtils.isValidTexture(backCards.getTexture()))) firstDrawFinished = true; }
public synchronized boolean handleTouchEvent(MotionEvent event, boolean isOnTouchEvent) { float delta; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastY = event.getY(); lastX = event.getX(); return isOnTouchEvent; case MotionEvent.ACTION_MOVE: if (orientationVertical) { delta = lastY - event.getY(); } else { delta = lastX - event.getX(); } if (Math.abs(delta) > controller.getTouchSlop()) setState(STATE_TOUCH); // XXX: initialize views? if (state == STATE_TOUCH) { forward = delta > 0; // We only want to know the direction of the last movement controller.showFlipAnimation(); final float angleDelta; if (orientationVertical) { angleDelta = 180 * delta / controller.getContentHeight() * MOVEMENT_RATE; } else { angleDelta = 180 * delta / controller.getContentWidth() * MOVEMENT_RATE; } angle += angleDelta; if (backCards.getIndex() == -1) { if (angle >= MAX_TIP_ANGLE) angle = MAX_TIP_ANGLE; } else if (backCards.getIndex() == 0) { if (angle <= 180 - MAX_TIP_ANGLE) angle = 180 - MAX_TIP_ANGLE; } if (angle < 0) { if (frontCards.getIndex() > 0) { activeIndex = frontCards.getIndex() - 1; // xxx controller.flippedToView(activeIndex); } else { swapCards(); frontCards.setView(-1, null); if (-angle >= MAX_TIP_ANGLE) angle = -MAX_TIP_ANGLE; angle += 180; } } if (orientationVertical) { lastY = event.getY(); } else { lastX = event.getX(); } controller.getSurfaceView().requestRender(); return true; } return isOnTouchEvent; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (state == STATE_TOUCH) { if (orientationVertical) { delta = lastY - event.getY(); rotateBy(180 * delta / controller.getContentHeight() * MOVEMENT_RATE); } else { delta = lastX - event.getX(); rotateBy(180 * delta / controller.getContentWidth() * MOVEMENT_RATE); } if (frontCards.getIndex() == -1) // If at the first or last card forward = true; else if (backCards.getIndex() == -1) forward = false; setState(STATE_AUTO_ROTATE); controller.getSurfaceView().requestRender(); } return isOnTouchEvent; } return false; }
void refreshAllPages() { frontCards.resetWithIndex(frontCards.getIndex()); backCards.resetWithIndex(backCards.getIndex()); }
private void resetAxises() { frontCards.getTopCard().setAxis(Card.AXIS_TOP); frontCards.getBottomCard().setAxis(Card.AXIS_TOP); backCards.getBottomCard().setAxis(Card.AXIS_TOP); backCards.getTopCard().setAxis(Card.AXIS_BOTTOM); }
synchronized boolean handleTouchEvent(MotionEvent event, boolean isOnTouchEvent) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // remember page we started on... lastPageIndex = getPageIndexFromAngle(accumulatedAngle); lastPosition = orientationVertical ? event.getY() : event.getX(); return isOnTouchEvent; case MotionEvent.ACTION_MOVE: float delta = orientationVertical ? (lastPosition - event.getY()) : (lastPosition - event.getX()); if (Math.abs(delta) > controller.getTouchSlop()) { setState(STATE_TOUCH); forward = delta > 0; } if (state == STATE_TOUCH) { if (Math.abs(delta) > minMovement) // ignore small movements forward = delta > 0; controller.showFlipAnimation(); float angleDelta; if (orientationVertical) angleDelta = 180 * delta / controller.getContentHeight() * movementRate; else angleDelta = 180 * delta / controller.getContentWidth() * movementRate; if (Math.abs(angleDelta) > maxTouchMoveAngle) // prevent // large // delta // when // moving // too fast angleDelta = Math.signum(angleDelta) * maxTouchMoveAngle; // do not flip more than one page with one touch... if (Math.abs(getPageIndexFromAngle(accumulatedAngle + angleDelta) - lastPageIndex) <= 1) { accumulatedAngle += angleDelta; } // Bounce the page for the first and the last page if (frontCards.getIndex() == maxIndex - 1) { // the last page if (accumulatedAngle > frontCards.getIndex() * 180 + maxTipAngle) accumulatedAngle = frontCards.getIndex() * 180 + maxTipAngle; } else if (accumulatedAngle < -maxTipAngle) accumulatedAngle = -maxTipAngle; int anglePageIndex = getPageIndexFromAngle(accumulatedAngle); if (accumulatedAngle >= 0) { if (anglePageIndex != frontCards.getIndex()) { if (anglePageIndex == frontCards.getIndex() - 1) { // moved // to // previous // page swapCards(); // frontCards becomes the backCards frontCards.resetWithIndex(backCards.getIndex() - 1); controller.flippedToView(anglePageIndex, false); } else if (anglePageIndex == frontCards.getIndex() + 1) { // moved // to // next // page swapCards(); backCards.resetWithIndex(frontCards.getIndex() + 1); controller.flippedToView(anglePageIndex, false); } else throw new RuntimeException( String.format( "Inconsistent states: anglePageIndex: %d, accumulatedAngle %.1f, frontCards %d, backCards %d", anglePageIndex, accumulatedAngle, frontCards.getIndex(), backCards.getIndex())); } } lastPosition = orientationVertical ? event.getY() : event.getX(); controller.getSurfaceView().requestRender(); return true; } return isOnTouchEvent; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (state == STATE_TOUCH) { if (accumulatedAngle < 0) forward = true; else if (accumulatedAngle > frontCards.getIndex() * 180 && frontCards.getIndex() == maxIndex - 1) forward = false; setState(STATE_AUTO_ROTATE); controller.getSurfaceView().requestRender(); } return isOnTouchEvent; } return false; }
public synchronized void draw(FlipRenderer renderer, GL10 gl) { applyTexture(renderer, gl); if (!TextureUtils.isValidTexture(frontCards.getTexture()) && !TextureUtils.isValidTexture(backCards.getTexture())) return; if (!visible) return; switch (state) { case STATE_INIT: { /*if (false) { //XXX: debug only if (angle >= 180) forward = false; else if (angle <= 0) forward = true; rotateBy((forward ? TIP_SPEED : -TIP_SPEED)); if (angle > 90 && angle <= 180 - MAX_TIP_ANGLE) { forward = true; } else if (angle < 90 && angle >= MAX_TIP_ANGLE) { forward = false; } }*/ } break; case STATE_TOUCH: break; case STATE_AUTO_ROTATE: { animatedFrame++; rotateBy((forward ? ACCELERATION : -ACCELERATION) * animatedFrame); if (angle >= 180 || angle <= 0) { setState(STATE_INIT); if (angle >= 180) { // flip to next page if (backCards.getIndex() != -1) { activeIndex = backCards.getIndex(); controller.postFlippedToView(activeIndex); } else angle = 180; } controller.postHideFlipAnimation(); } else controller.getSurfaceView().requestRender(); } break; default: AphidLog.e("Invalid state: " + state); break; } if (angle < 90) { // render front view over back view frontCards.getTopCard().setAngle(0); frontCards.getTopCard().draw(gl); backCards.getBottomCard().setAngle(0); backCards.getBottomCard().draw(gl); frontCards.getBottomCard().setAngle(angle); frontCards.getBottomCard().draw(gl); } else { // render back view first frontCards.getTopCard().setAngle(0); frontCards.getTopCard().draw(gl); backCards.getTopCard().setAngle(180 - angle); backCards.getTopCard().draw(gl); backCards.getBottomCard().setAngle(0); backCards.getBottomCard().draw(gl); } }
private void applyTexture(FlipRenderer renderer, GL10 gl) { frontCards.buildTexture(renderer, gl); backCards.buildTexture(renderer, gl); }
void refreshPage(int pageIndex) { if (frontCards.getIndex() == pageIndex) frontCards.markForceReload(); if (backCards.getIndex() == pageIndex) backCards.markForceReload(); }
void refreshPageView(View view) { if (frontCards.getView() == view) frontCards.markForceReload(); if (backCards.getView() == view) backCards.markForceReload(); }