예제 #1
0
  /** Updates bitmaps for page meshes. */
  private void updatePages() {
    Log.d("artbook", ">>>>>update page(s): " + Thread.currentThread());
    if (mPageProvider == null || mPageBitmapWidth <= 0 || mPageBitmapHeight <= 0) {
      return;
    }

    // Remove meshes from renderer.
    mRenderer.removeCurlMesh(mPageLeft);
    mRenderer.removeCurlMesh(mPageRight);
    mRenderer.removeCurlMesh(mPageCurl);

    int leftIdx = mCurrentIndex - 1;
    int rightIdx = mCurrentIndex;
    int curlIdx = -1;
    if (mCurlState == CURL_LEFT) {
      curlIdx = leftIdx;
      --leftIdx;
    } else if (mCurlState == CURL_RIGHT) {
      curlIdx = rightIdx;
      ++rightIdx;
    }

    if (rightIdx >= 0 && rightIdx < mPageProvider.getPageCount()) {
      updatePage(mPageRight.getTexturePage(), rightIdx);
      mPageRight.setFlipTexture(false);
      mPageRight.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT));
      mPageRight.reset();
      mRenderer.addCurlMesh(mPageRight);
    }
    if (leftIdx >= 0 && leftIdx < mPageProvider.getPageCount()) {
      updatePage(mPageLeft.getTexturePage(), leftIdx);
      mPageLeft.setFlipTexture(true);
      mPageLeft.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT));
      mPageLeft.reset();
      if (mRenderLeftPage) {
        mRenderer.addCurlMesh(mPageLeft);
      }
    }
    if (curlIdx >= 0 && curlIdx < mPageProvider.getPageCount()) {
      updatePage(mPageCurl.getTexturePage(), curlIdx);

      if (mCurlState == CURL_RIGHT) {
        mPageCurl.setFlipTexture(true);
        mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT));
      } else {
        mPageCurl.setFlipTexture(false);
        mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT));
      }

      mPageCurl.reset();
      mRenderer.addCurlMesh(mPageCurl);
    }
  }
예제 #2
0
 /**
  * Set current page index. Page indices are zero based values presenting page being shown on right
  * side of the book. E.g if you set value to 4; right side front facing bitmap will be with index
  * 4, back facing 5 and for left side page index 3 is front facing, and index 2 back facing (once
  * page is on left side it's flipped over).
  *
  * <p>Current index is rounded to closest value divisible with 2.
  */
 public void setCurrentIndex(int index) {
   Log.d("artbook", ">>>>>set current index " + Thread.currentThread());
   if (mPageProvider == null || index < 0) {
     mCurrentIndex = 0;
   } else {
     if (mAllowLastPageCurl) {
       mCurrentIndex = Math.min(index, mPageProvider.getPageCount());
     } else {
       mCurrentIndex = Math.min(index, mPageProvider.getPageCount() - 1);
     }
   }
   updatePages();
   requestRender();
 }
예제 #3
0
  /** Switches meshes and loads new bitmaps if available. Updated to support 2 pages in landscape */
  private void startCurl(int page) {
    switch (page) {

        // Once right side page is curled, first right page is assigned into
        // curled page. And if there are more bitmaps available new bitmap is
        // loaded into right side mesh.
      case CURL_RIGHT:
        {
          // Remove meshes from renderer.
          mRenderer.removeCurlMesh(mPageLeft);
          mRenderer.removeCurlMesh(mPageRight);
          mRenderer.removeCurlMesh(mPageCurl);

          // We are curling right page.
          CurlMesh curl = mPageRight;
          mPageRight = mPageCurl;
          mPageCurl = curl;

          if (mCurrentIndex > 0) {
            mPageLeft.setFlipTexture(true);
            mPageLeft.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT));
            mPageLeft.reset();
            if (mRenderLeftPage) {
              mRenderer.addCurlMesh(mPageLeft);
            }
          }
          if (mCurrentIndex < mPageProvider.getPageCount() - 1) {
            updatePage(mPageRight.getTexturePage(), mCurrentIndex + 1);
            mPageRight.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT));
            mPageRight.setFlipTexture(false);
            mPageRight.reset();
            mRenderer.addCurlMesh(mPageRight);
          }

          // Add curled page to renderer.
          mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT));
          mPageCurl.setFlipTexture(false);
          mPageCurl.reset();
          mRenderer.addCurlMesh(mPageCurl);

          mCurlState = CURL_RIGHT;
          break;
        }

        // On left side curl, left page is assigned to curled page. And if
        // there are more bitmaps available before currentIndex, new bitmap
        // is loaded into left page.
      case CURL_LEFT:
        {
          // Remove meshes from renderer.
          mRenderer.removeCurlMesh(mPageLeft);
          mRenderer.removeCurlMesh(mPageRight);
          mRenderer.removeCurlMesh(mPageCurl);

          // We are curling left page.
          CurlMesh curl = mPageLeft;
          mPageLeft = mPageCurl;
          mPageCurl = curl;

          if (mCurrentIndex > 1) {
            updatePage(mPageLeft.getTexturePage(), mCurrentIndex - 2);
            mPageLeft.setFlipTexture(true);
            mPageLeft.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT));
            mPageLeft.reset();
            if (mRenderLeftPage) {
              mRenderer.addCurlMesh(mPageLeft);
            }
          }

          // If there is something to show on right page add it to renderer.
          if (mCurrentIndex < mPageProvider.getPageCount()) {
            mPageRight.setFlipTexture(false);
            mPageRight.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT));
            mPageRight.reset();
            mRenderer.addCurlMesh(mPageRight);
          }

          // How dragging previous page happens depends on view mode.
          if (mViewMode == SHOW_ONE_PAGE
              || (mCurlState == CURL_LEFT && mViewMode == SHOW_TWO_PAGES)) {
            mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT));
            mPageCurl.setFlipTexture(false);
          } else {
            mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT));
            mPageCurl.setFlipTexture(true);
          }
          mPageCurl.reset();
          mRenderer.addCurlMesh(mPageCurl);

          mCurlState = CURL_LEFT;
          break;
        }
    }
  }
예제 #4
0
  @Override
  public boolean onTouch(View view, MotionEvent me) {
    // No dragging during animation at the moment.
    // TODO: Stop animation on touch event and return to drag mode.
    if (mAnimate || mPageProvider == null) {
      return false;
    }

    // We need page rects quite extensively so get them for later use.
    RectF rightRect = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT);
    RectF leftRect = mRenderer.getPageRect(CurlRenderer.PAGE_LEFT);

    // Store pointer position.
    mPointerPos.mPos.set(me.getX(), me.getY());
    mRenderer.translate(mPointerPos.mPos);
    if (mEnableTouchPressure) {
      mPointerPos.mPressure = me.getPressure();
    } else {
      mPointerPos.mPressure = 0.8f;
    }

    switch (me.getAction()) {
      case MotionEvent.ACTION_DOWN:
        {

          // Once we receive pointer down event its position is mapped to
          // right or left edge of page and that'll be the position from where
          // user is holding the paper to make curl happen.
          mDragStartPos.set(mPointerPos.mPos);

          // First we make sure it's not over or below page. Pages are
          // supposed to be same height so it really doesn't matter do we use
          // left or right one.
          if (mDragStartPos.y > rightRect.top) {
            mDragStartPos.y = rightRect.top;
          } else if (mDragStartPos.y < rightRect.bottom) {
            mDragStartPos.y = rightRect.bottom;
          }

          // Then we have to make decisions for the user whether curl is going
          // to happen from left or right, and on which page.
          if (mViewMode == SHOW_TWO_PAGES) {
            // If we have an open book and pointer is on the left from right
            // page we'll mark drag position to left edge of left page.
            // Additionally checking mCurrentIndex is higher than zero tells
            // us there is a visible page at all.
            if (mDragStartPos.x < rightRect.left && mCurrentIndex > 0) {
              mDragStartPos.x = leftRect.left;
              startCurl(CURL_LEFT);
            }
            // Otherwise check pointer is on right page's side.
            else if (mDragStartPos.x >= rightRect.left
                && mCurrentIndex < mPageProvider.getPageCount()) {
              mDragStartPos.x = rightRect.right;
              if (!mAllowLastPageCurl && mCurrentIndex >= mPageProvider.getPageCount() - 1) {
                return false;
              }
              startCurl(CURL_RIGHT);
            }
          } else if (mViewMode == SHOW_ONE_PAGE) {
            float halfX = (rightRect.right + rightRect.left) / 2;
            if (mDragStartPos.x < halfX && mCurrentIndex > 0) {
              mDragStartPos.x = rightRect.left;
              startCurl(CURL_LEFT);
            } else if (mDragStartPos.x >= halfX && mCurrentIndex < mPageProvider.getPageCount()) {
              mDragStartPos.x = rightRect.right;
              if (!mAllowLastPageCurl && mCurrentIndex >= mPageProvider.getPageCount() - 1) {
                return false;
              }
              startCurl(CURL_RIGHT);
            }
          }
          // If we have are in curl state, let this case clause flow through
          // to next one. We have pointer position and drag position defined
          // and this will create first render request given these points.
          if (mCurlState == CURL_NONE) {
            return false;
          }
        }
      case MotionEvent.ACTION_MOVE:
        {
          updateCurlPos(mPointerPos);
          break;
        }
      case MotionEvent.ACTION_CANCEL:
      case MotionEvent.ACTION_UP:
        {
          if (mCurlState == CURL_LEFT || mCurlState == CURL_RIGHT) {
            // Animation source is the point from where animation starts.
            // Also it's handled in a way we actually simulate touch events
            // meaning the output is exactly the same as if user drags the
            // page to other side. While not producing the best looking
            // result (which is easier done by altering curl position and/or
            // direction directly), this is done in a hope it made code a
            // bit more readable and easier to maintain.
            mAnimationSource.set(mPointerPos.mPos);
            mAnimationStartTime = System.currentTimeMillis();

            // Given the explanation, here we decide whether to simulate
            // drag to left or right end.
            if ((mViewMode == SHOW_ONE_PAGE
                    && mPointerPos.mPos.x > (rightRect.left + rightRect.right) / 2)
                || mViewMode == SHOW_TWO_PAGES && mPointerPos.mPos.x > rightRect.left) {
              // On right side target is always right page's right border.
              mAnimationTarget.set(mDragStartPos);
              mAnimationTarget.x = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT).right;
              mAnimationTargetEvent = SET_CURL_TO_RIGHT;
            } else {
              // On left side target depends on visible pages.
              mAnimationTarget.set(mDragStartPos);
              if (mCurlState == CURL_RIGHT || mViewMode == SHOW_TWO_PAGES) {
                mAnimationTarget.x = leftRect.left;
              } else {
                mAnimationTarget.x = rightRect.left;
              }
              mAnimationTargetEvent = SET_CURL_TO_LEFT;
            }
            mAnimate = true;
            requestRender();
          }
          break;
        }
    }

    return true;
  }