From b46a440cbd1c69403d09500343159740b57a90cb Mon Sep 17 00:00:00 2001 From: Nikolay Pultsin Date: Sat, 1 Jan 2011 19:20:04 +0000 Subject: [PATCH] single/double tap support has been implemented; navigation window by douple tap --- TODO.dictionary | 3 +- .../fbreader/fbreader/FBView.java | 78 +++++++++++++------ .../zlibrary/core/view/ZLView.java | 12 +++ .../ui/android/view/ZLAndroidWidget.java | 43 ++++++++-- 4 files changed, 102 insertions(+), 34 deletions(-) diff --git a/TODO.dictionary b/TODO.dictionary index c7295195c..964bee3a4 100644 --- a/TODO.dictionary +++ b/TODO.dictionary @@ -4,9 +4,8 @@ DONE Synchronize resources DONE Option for opening ColorDict immediately by finger tap DONE Synchronize resources DONE 3-mode tapping behaviour -* long tapping processing instead of short one? +DONE long tapping processing instead of short one After 0.99: -* More convenient mode changing * Installation from the site if AM is not available * Integration with other dictionaries diff --git a/src/org/geometerplus/fbreader/fbreader/FBView.java b/src/org/geometerplus/fbreader/fbreader/FBView.java index 29c3e4207..49f414025 100644 --- a/src/org/geometerplus/fbreader/fbreader/FBView.java +++ b/src/org/geometerplus/fbreader/fbreader/FBView.java @@ -76,6 +76,59 @@ public final class FBView extends ZLTextView { private boolean myIsBrightnessAdjustmentInProgress; private int myStartBrightness; + public boolean onFingerSingleTap(int x, int y) { + if (super.onFingerSingleTap(x, y)) { + return true; + } + + if (isScrollingActive()) { + return false; + } + + if (myReader.FooterIsSensitiveOption.getValue()) { + Footer footer = getFooterArea(); + if (footer != null && y > myContext.getHeight() - footer.getTapHeight()) { + footer.setProgress(x); + return true; + } + } + + final ZLTextElementRegion region = findRegion(x, y, 10, ZLTextHyperlinkRegion.Filter); + if (region != null) { + selectRegion(region); + myReader.repaintView(); + myReader.doAction(ActionCode.PROCESS_HYPERLINK); + return true; + } + + final ScrollingPreferences preferences = ScrollingPreferences.Instance(); + if (!preferences.FlickOption.getValue()) { + if (preferences.HorizontalOption.getValue()) { + if (x <= myContext.getWidth() / 3) { + doScrollPage(false); + } else if (x >= myContext.getWidth() * 2 / 3) { + doScrollPage(true); + } + } else { + if (y <= myContext.getHeight() / 3) { + doScrollPage(false); + } else if (y >= myContext.getHeight() * 2 / 3) { + doScrollPage(true); + } + } + } + + return true; + } + + public boolean onFingerDoubleTap() { + if (super.onFingerDoubleTap()) { + return true; + } + myReader.doAction(ActionCode.SHOW_NAVIGATION); + return true; + } + public boolean onFingerPress(int x, int y) { if (super.onFingerPress(x, y)) { return true; @@ -100,37 +153,14 @@ public final class FBView extends ZLTextView { return true; } - final ZLTextElementRegion region = findRegion(x, y, 10, ZLTextHyperlinkRegion.Filter); - if (region != null) { - selectRegion(region); - myReader.repaintView(); - myReader.doAction(ActionCode.PROCESS_HYPERLINK); - return true; - } - final ScrollingPreferences preferences = ScrollingPreferences.Instance(); if (preferences.FlickOption.getValue()) { myStartX = x; myStartY = y; setScrollingActive(true); myIsManualScrollingActive = true; - } else { - if (preferences.HorizontalOption.getValue()) { - if (x <= myContext.getWidth() / 3) { - doScrollPage(false); - } else if (x >= myContext.getWidth() * 2 / 3) { - doScrollPage(true); - } - } else { - if (y <= myContext.getHeight() / 3) { - doScrollPage(false); - } else if (y >= myContext.getHeight() * 2 / 3) { - doScrollPage(true); - } - } } - //activateSelection(x, y); return true; } @@ -245,8 +275,6 @@ public final class FBView extends ZLTextView { } } - //myReader.doAction(ActionCode.SHOW_NAVIGATION); - //return true; return false; } diff --git a/src/org/geometerplus/zlibrary/core/view/ZLView.java b/src/org/geometerplus/zlibrary/core/view/ZLView.java index 40105bd47..d74283478 100644 --- a/src/org/geometerplus/zlibrary/core/view/ZLView.java +++ b/src/org/geometerplus/zlibrary/core/view/ZLView.java @@ -66,6 +66,18 @@ abstract public class ZLView { return false; } + public boolean onFingerSingleTap(int x, int y) { + return false; + } + + public boolean onFingerDoubleTap() { + return false; + } + + public boolean isDoubleTapSupported() { + return false; + } + public boolean onTrackballRotated(int diffX, int diffY) { return false; } diff --git a/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java b/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java index bf9d3b2bf..ec2d3b8ef 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java @@ -329,19 +329,29 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { } } } - - private LongClickRunnable myPendingLongClickRunnable; - private boolean myLongClickPerformed; + private volatile LongClickRunnable myPendingLongClickRunnable; + private volatile boolean myLongClickPerformed; private void postLongClickRunnable() { myLongClickPerformed = false; + myPendingPress = false; if (myPendingLongClickRunnable == null) { myPendingLongClickRunnable = new LongClickRunnable(); } postDelayed(myPendingLongClickRunnable, 2 * ViewConfiguration.getLongPressTimeout()); } - private boolean myPendingPress; + private class ShortClickRunnable implements Runnable { + public void run() { + final ZLView view = ZLApplication.Instance().getCurrentView(); + view.onFingerSingleTap(myPressedX, myPressedY); + myPendingPress = false; + myPendingShortClickRunnable = null; + } + } + private volatile ShortClickRunnable myPendingShortClickRunnable; + + private volatile boolean myPendingPress; private int myPressedX, myPressedY; private boolean myScreenIsTouched; @Override @@ -357,17 +367,32 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { } else { if (myPendingLongClickRunnable != null) { removeCallbacks(myPendingLongClickRunnable); + myPendingLongClickRunnable = null; } if (myPendingPress) { - view.onFingerPress(myPressedX, myPressedY); + if (view.isDoubleTapSupported()) { + if (myPendingShortClickRunnable == null) { + myPendingShortClickRunnable = new ShortClickRunnable(); + } + postDelayed(myPendingShortClickRunnable, ViewConfiguration.getDoubleTapTimeout()); + } else { + view.onFingerSingleTap(x, y); + } + } else { + view.onFingerRelease(x, y); } - view.onFingerRelease(x, y); } myPendingPress = false; myScreenIsTouched = false; break; case MotionEvent.ACTION_DOWN: - postLongClickRunnable(); + if (myPendingShortClickRunnable != null) { + removeCallbacks(myPendingShortClickRunnable); + myPendingShortClickRunnable = null; + view.onFingerDoubleTap(); + } else { + postLongClickRunnable(); + } myScreenIsTouched = true; myPendingPress = true; myPressedX = x; @@ -378,6 +403,10 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { view.onFingerMoveAfterLongPress(x, y); } else { if (myPendingPress) { + if (myPendingShortClickRunnable != null) { + removeCallbacks(myPendingShortClickRunnable); + myPendingShortClickRunnable = null; + } final int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); if (Math.abs(myPressedX - x) > slop || Math.abs(myPressedY - y) > slop) { if (myPendingLongClickRunnable != null) {