diff options
Diffstat (limited to 'android/src/com')
-rw-r--r-- | android/src/com/artifex/mupdfdemo/MuPDFActivity.java | 8 | ||||
-rw-r--r-- | android/src/com/artifex/mupdfdemo/ReaderView.java | 151 |
2 files changed, 157 insertions, 2 deletions
diff --git a/android/src/com/artifex/mupdfdemo/MuPDFActivity.java b/android/src/com/artifex/mupdfdemo/MuPDFActivity.java index bfe0e135..f41b6178 100644 --- a/android/src/com/artifex/mupdfdemo/MuPDFActivity.java +++ b/android/src/com/artifex/mupdfdemo/MuPDFActivity.java @@ -393,9 +393,13 @@ public class MuPDFActivity extends Activity } }); } else if (e.getX() < tapPageMargin) { - super.moveToPrevious(); + super.smartMoveBackwards(); } else if (e.getX() > super.getWidth()-tapPageMargin) { - super.moveToNext(); + super.smartMoveForwards(); + } else if (e.getY() < tapPageMargin) { + super.smartMoveBackwards(); + } else if (e.getY() > super.getHeight()-tapPageMargin) { + super.smartMoveForwards(); } else if (!mButtonsVisible) { showButtons(); } else { diff --git a/android/src/com/artifex/mupdfdemo/ReaderView.java b/android/src/com/artifex/mupdfdemo/ReaderView.java index 16ac1129..6a01e288 100644 --- a/android/src/com/artifex/mupdfdemo/ReaderView.java +++ b/android/src/com/artifex/mupdfdemo/ReaderView.java @@ -105,6 +105,157 @@ public class ReaderView extends AdapterView<Adapter> slideViewOntoScreen(v); } + public void smartMoveForwards() { + View v = mChildViews.get(mCurrent); + if (v == null) + return; + + // The following code works in terms of where the screen is on the views; + // so for example, if the currentView is at (-100,-100), the visible + // region would be at (100,100). If the previous page was (2000, 3000) in + // size, the visible region of the previous page might be (2100 + GAP, 100) + // (i.e. off the previous page). This is different to the way the rest of + // the code in this file is written, but it's easier for me to think about. + // At some point we may refactor this to fit better with the rest of the + // code. + + // screenWidth/Height are the actual width/height of the screen. e.g. 480/800 + int screenWidth = getWidth(); + int screenHeight = getHeight(); + // We might be mid scroll; we want to calculate where we scroll to based on + // where this scroll would end, not where we are now (to allow for people + // bashing 'forwards' very fast. + int remainingX = mScroller.getFinalX() - mScroller.getCurrX(); + int remainingY = mScroller.getFinalY() - mScroller.getCurrY(); + // right/bottom is in terms of pixels within the scaled document; e.g. 1000 + int top = -(v.getTop() + mYScroll + remainingY); + int right = screenWidth -(v.getLeft() + mXScroll + remainingX); + int bottom = screenHeight+top; + // docWidth/Height are the width/height of the scaled document e.g. 2000x3000 + int docWidth = v.getMeasuredWidth(); + int docHeight = v.getMeasuredHeight(); + + int xOffset, yOffset; + if (bottom >= docHeight) { + // We are flush with the bottom. Advance to next column. + if (right + screenWidth > docWidth) { + // No room for another column - go to next page + View nv = mChildViews.get(mCurrent+1); + if (nv == null) // No page to advance to + return; + int nextTop = -(nv.getTop() + mYScroll + remainingY); + int nextLeft = -(nv.getLeft() + mXScroll + remainingX); + int nextDocWidth = nv.getMeasuredWidth(); + int nextDocHeight = nv.getMeasuredHeight(); + + // Allow for the next page maybe being shorter than the screen is high + yOffset = (nextDocHeight < screenHeight ? ((nextDocHeight - screenHeight)>>1) : 0); + + if (nextDocWidth < screenWidth) { + // Next page is too narrow to fill the screen. Scroll to the top, centred. + xOffset = (nextDocWidth - screenWidth)>>1; + } else { + // Reset X back to the left hand column + xOffset = right % screenWidth; + // Adjust in case the previous page is less wide + if (xOffset + screenWidth > nextDocWidth) + xOffset = nextDocWidth - screenWidth; + } + xOffset -= nextLeft; + yOffset -= nextTop; + } else { + // Move to top of next column + xOffset = screenWidth; + yOffset = screenHeight - bottom; + } + } else { + // Advance by 90% of the screen height downwards (in case lines are partially cut off) + xOffset = 0; + yOffset = (int)(screenHeight * 0.9 + 0.5); + if (yOffset + bottom > docHeight) + yOffset = docHeight - bottom; + } + mScrollerLastX = mScrollerLastY = 0; + mScroller.startScroll(0, 0, remainingX - xOffset, remainingY - yOffset, 400); + post(this); + } + + public void smartMoveBackwards() { + View v = mChildViews.get(mCurrent); + if (v == null) + return; + + // The following code works in terms of where the screen is on the views; + // so for example, if the currentView is at (-100,-100), the visible + // region would be at (100,100). If the previous page was (2000, 3000) in + // size, the visible region of the previous page might be (2100 + GAP, 100) + // (i.e. off the previous page). This is different to the way the rest of + // the code in this file is written, but it's easier for me to think about. + // At some point we may refactor this to fit better with the rest of the + // code. + + // screenWidth/Height are the actual width/height of the screen. e.g. 480/800 + int screenWidth = getWidth(); + int screenHeight = getHeight(); + // We might be mid scroll; we want to calculate where we scroll to based on + // where this scroll would end, not where we are now (to allow for people + // bashing 'forwards' very fast. + int remainingX = mScroller.getFinalX() - mScroller.getCurrX(); + int remainingY = mScroller.getFinalY() - mScroller.getCurrY(); + // left/top is in terms of pixels within the scaled document; e.g. 1000 + int left = -(v.getLeft() + mXScroll + remainingX); + int top = -(v.getTop() + mYScroll + remainingY); + // docWidth/Height are the width/height of the scaled document e.g. 2000x3000 + int docWidth = v.getMeasuredWidth(); + int docHeight = v.getMeasuredHeight(); + + int xOffset, yOffset; + if (top <= 0) { + // We are flush with the top. Step back to previous column. + if (left < screenWidth) { + /* No room for previous column - go to previous page */ + View pv = mChildViews.get(mCurrent-1); + if (pv == null) /* No page to advance to */ + return; + int prevDocWidth = pv.getMeasuredWidth(); + int prevDocHeight = pv.getMeasuredHeight(); + + // Allow for the next page maybe being shorter than the screen is high + yOffset = (prevDocHeight < screenHeight ? ((prevDocHeight - screenHeight)>>1) : 0); + + int prevLeft = -(pv.getLeft() + mXScroll); + int prevTop = -(pv.getTop() + mYScroll); + if (prevDocWidth < screenWidth) { + // Previous page is too narrow to fill the screen. Scroll to the bottom, centred. + xOffset = (prevDocWidth - screenWidth)>>1; + } else { + // Reset X back to the right hand column + xOffset = (left > 0 ? left % screenWidth : 0); + if (xOffset + screenWidth > prevDocWidth) + xOffset = prevDocWidth - screenWidth; + while (xOffset + screenWidth*2 < prevDocWidth) + xOffset += screenWidth; + yOffset -= screenHeight-prevDocHeight; + } + xOffset -= prevLeft; + yOffset -= prevTop; + } else { + // Move to bottom of previous column + xOffset = -screenWidth; + yOffset = docHeight - screenHeight + top; + } + } else { + // Retreat by 90% of the screen height downwards (in case lines are partially cut off) + xOffset = 0; + yOffset = - (int)(screenHeight * 0.9 + 0.5); + if (yOffset < -top) + yOffset = -top; + } + mScrollerLastX = mScrollerLastY = 0; + mScroller.startScroll(0, 0, remainingX - xOffset, remainingY - yOffset, 400); + post(this); + } + public void resetupChildren() { for (int i = 0; i < mChildViews.size(); i++) onChildSetup(mChildViews.keyAt(i), mChildViews.valueAt(i)); |