diff --git a/src/com/fsck/k9/activity/K9Activity.java b/src/com/fsck/k9/activity/K9Activity.java index 3fa72700b..b2c1827c6 100644 --- a/src/com/fsck/k9/activity/K9Activity.java +++ b/src/com/fsck/k9/activity/K9Activity.java @@ -14,15 +14,15 @@ import android.view.View; import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; -import android.widget.ScrollView; import com.fsck.k9.K9; import com.fsck.k9.helper.DateFormatter; +import com.fsck.k9.view.ToggleScrollView; public class K9Activity extends Activity { private GestureDetector gestureDetector; - protected ScrollView mTopView; + protected ToggleScrollView mTopView; @Override public void onCreate(Bundle icicle) { @@ -86,12 +86,26 @@ public class K9Activity extends Activity { public java.text.DateFormat getDateFormat() { return mDateFormat; } - protected void onNext() { - } - protected void onPrevious() { + /** + * Called when a swipe from right to left is handled by {@link MyGestureDetector}. See + * {@link android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float)} + * for more information on the {@link MotionEvent}s being passed. + * @param e1 First down motion event that started the fling. + * @param e2 The move motion event that triggered the current onFling. + */ + protected void onSwipeRightToLeft(final MotionEvent e1, final MotionEvent e2) { } + /** + * Called when a swipe from left to right is handled by {@link MyGestureDetector}. See + * {@link android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float)} + * for more information on the {@link MotionEvent}s being passed. + * @param e1 First down motion event that started the fling. + * @param e2 The move motion event that triggered the current onFling. + */ + protected void onSwipeLeftToRight(final MotionEvent e1, final MotionEvent e2) { + } protected Animation inFromRightAnimation() { return slideAnimation(0.0f, +1.0f); @@ -114,6 +128,25 @@ public class K9Activity extends Activity { } class MyGestureDetector extends SimpleOnGestureListener { + private boolean gesturesEnabled = false; + + /** + * Creates a new {@link android.view.GestureDetector.OnGestureListener}. Enabled/disabled based upon + * {@link com.fsck.k9.K9#gesturesEnabled()}}. + */ + public MyGestureDetector() { + super(); + } + + /** + * Create a new {@link android.view.GestureDetector.OnGestureListener}. + * @param gesturesEnabled Setting to true will enable gesture detection, + * regardless of the system-wide gesture setting. + */ + public MyGestureDetector(final boolean gesturesEnabled) { + super(); + this.gesturesEnabled = gesturesEnabled; + } private static final float SWIPE_MIN_DISTANCE_DIP = 130.0f; private static final float SWIPE_MAX_OFF_PATH_DIP = 250f; @@ -137,7 +170,8 @@ public class K9Activity extends Activity { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - if (K9.gesturesEnabled()) { + // Do fling-detection if gestures are force-enabled or we have system-wide gestures enabled. + if (gesturesEnabled || K9.gesturesEnabled()) { // Convert the dips to pixels final float mGestureScale = getResources().getDisplayMetrics().density; int min_distance = (int)(SWIPE_MIN_DISTANCE_DIP * mGestureScale + 0.5f); @@ -150,9 +184,9 @@ public class K9Activity extends Activity { return false; // right to left swipe if (e1.getX() - e2.getX() > min_distance && Math.abs(velocityX) > min_velocity) { - onNext(); + onSwipeRightToLeft(e1, e2); } else if (e2.getX() - e1.getX() > min_distance && Math.abs(velocityX) > min_velocity) { - onPrevious(); + onSwipeLeftToRight(e1, e2); } } catch (Exception e) { // nothing diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 5b41c8b28..50e911a87 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -818,7 +818,7 @@ public class MessageList mBatchDoneButton.setOnClickListener(this); // Gesture detection - gestureDetector = new GestureDetector(new MyGestureDetector()); + gestureDetector = new GestureDetector(new MyGestureDetector(true)); gestureListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { @@ -1660,35 +1660,34 @@ public class MessageList } } - class MyGestureDetector extends SimpleOnGestureListener { - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - if (e2 == null || e1 == null) - return true; + @Override + protected void onSwipeRightToLeft(final MotionEvent e1, final MotionEvent e2) { + // Handle right-to-left as an un-select + handleSwipe(e1, false); + } - float deltaX = e2.getX() - e1.getX(), - deltaY = e2.getY() - e1.getY(); + @Override + protected void onSwipeLeftToRight(final MotionEvent e1, final MotionEvent e2) { + // Handle left-to-right as a select. + handleSwipe(e1, true); + } - boolean movedAcross = (Math.abs(deltaX) > Math.abs(deltaY * 4)); - boolean steadyHand = (Math.abs(deltaX / deltaY) > 2); + /** + * Handle a select or unselect swipe event + * @param downMotion Event that started the swipe + * @param selected true if this was an attempt to select (i.e. left to right). + */ + private void handleSwipe(final MotionEvent downMotion, final boolean selected) { + int position = mListView.pointToPosition((int) downMotion.getX(), (int) downMotion.getY()); + if (position != AdapterView.INVALID_POSITION) { + MessageInfoHolder msgInfoHolder = (MessageInfoHolder) mAdapter.getItem(position); - if (movedAcross && steadyHand) { - boolean selected = (deltaX > 0); - int position = mListView.pointToPosition((int)e1.getX(), (int)e1.getY()); - - if (position != AdapterView.INVALID_POSITION) { - MessageInfoHolder msgInfoHolder = (MessageInfoHolder) mAdapter.getItem(position); - - if (msgInfoHolder != null && msgInfoHolder.selected != selected) { - msgInfoHolder.selected = selected; - mSelectedCount += (selected ? 1 : -1); - mAdapter.notifyDataSetChanged(); - toggleBatchButtons(); - } - } + if (msgInfoHolder != null && msgInfoHolder.selected != selected) { + msgInfoHolder.selected = selected; + mSelectedCount += (selected ? 1 : -1); + mAdapter.notifyDataSetChanged(); + toggleBatchButtons(); } - - return false; } } diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java index d10ee7186..66670ab3a 100644 --- a/src/com/fsck/k9/activity/MessageView.java +++ b/src/com/fsck/k9/activity/MessageView.java @@ -82,7 +82,6 @@ public class MessageView extends K9Activity implements OnClickListener { private View mArchive; private View mMove; private View mSpam; - private ToggleScrollView mToggleScrollView; private Account mAccount; private MessageReference mMessageReference; private ArrayList mMessageReferences; @@ -132,14 +131,14 @@ public class MessageView extends K9Activity implements OnClickListener { public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_UP) { // Text selection is finished. Allow scrolling again. - mToggleScrollView.setScrolling(true); + mTopView.setScrolling(true); } else if (K9.zoomControlsEnabled()) { // If we have system zoom controls enabled, disable scrolling so the screen isn't wiggling around while // trying to zoom. if (ev.getAction() == MotionEvent.ACTION_POINTER_2_DOWN) { - mToggleScrollView.setScrolling(false); + mTopView.setScrolling(false); } else if (ev.getAction() == MotionEvent.ACTION_POINTER_2_UP) { - mToggleScrollView.setScrolling(true); + mTopView.setScrolling(true); } } return super.dispatchTouchEvent(ev); @@ -187,7 +186,7 @@ public class MessageView extends K9Activity implements OnClickListener { * Selecting text started via shift key. Disable scrolling as * this causes problems when selecting text. */ - mToggleScrollView.setScrolling(false); + mTopView.setScrolling(false); break; } case KeyEvent.KEYCODE_DEL: { @@ -379,7 +378,7 @@ public class MessageView extends K9Activity implements OnClickListener { requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.message_view); - mTopView = mToggleScrollView = (ToggleScrollView) findViewById(R.id.top_view); + mTopView = (ToggleScrollView) findViewById(R.id.top_view); mMessageView = (SingleMessageView) findViewById(R.id.message_view); //set a callback for the attachment view. With this callback the attachmentview @@ -871,7 +870,22 @@ public class MessageView extends K9Activity implements OnClickListener { } } + /** + * Handle a right-to-left swipe as "move to next message." + */ @Override + protected void onSwipeRightToLeft(MotionEvent e1, MotionEvent e2) { + onNext(); + } + + /** + * Handle a left-to-right swipe as "move to previous message." + */ + @Override + protected void onSwipeLeftToRight(MotionEvent e1, MotionEvent e2) { + onPrevious(); + } + protected void onNext() { if (mNextMessage == null) { Toast.makeText(this, getString(R.string.end_of_folder), Toast.LENGTH_SHORT).show(); @@ -886,7 +900,6 @@ public class MessageView extends K9Activity implements OnClickListener { mNext.requestFocus(); } - @Override protected void onPrevious() { if (mPreviousMessage == null) { Toast.makeText(this, getString(R.string.end_of_folder), Toast.LENGTH_SHORT).show(); @@ -1019,7 +1032,7 @@ public class MessageView extends K9Activity implements OnClickListener { }); break; case R.id.select_text: - mToggleScrollView.setScrolling(false); + mTopView.setScrolling(false); mMessageView.beginSelectingText(); break; default: diff --git a/src/com/fsck/k9/activity/setup/AccountSetupBasics.java b/src/com/fsck/k9/activity/setup/AccountSetupBasics.java index 2c31e1920..81773b8ba 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupBasics.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupBasics.java @@ -240,7 +240,6 @@ public class AccountSetupBasics extends K9Activity } } - @Override protected void onNext() { String email = mEmailView.getText().toString(); String[] emailParts = splitEmail(email); diff --git a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java index 1cbd7410a..b842f1bf6 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupIncoming.java @@ -385,7 +385,6 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener } } - @Override protected void onNext() { try { int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; diff --git a/src/com/fsck/k9/activity/setup/AccountSetupNames.java b/src/com/fsck/k9/activity/setup/AccountSetupNames.java index 493633e99..6079f3825 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupNames.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupNames.java @@ -79,7 +79,6 @@ public class AccountSetupNames extends K9Activity implements OnClickListener { Utility.setCompoundDrawablesAlpha(mDoneButton, mDoneButton.isEnabled() ? 255 : 128); } - @Override protected void onNext() { if (Utility.requiredFieldValid(mDescription)) { mAccount.setDescription(mDescription.getText().toString()); diff --git a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java index 73738fe3f..5ae1f823b 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupOutgoing.java @@ -285,7 +285,6 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener, } } - @Override protected void onNext() { int securityType = (Integer)((SpinnerOption)mSecurityTypeView.getSelectedItem()).value; URI uri;