mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
basic configurable story title gestures (#496)
This commit is contained in:
parent
8abd460d18
commit
0063742689
6 changed files with 159 additions and 18 deletions
|
@ -258,6 +258,8 @@
|
|||
</string-array>
|
||||
<string name="default_theme_value">light</string>
|
||||
|
||||
<string name="settings_gestures">Gestures</string>
|
||||
|
||||
<string name="sync_status_housekeeping">Tidying up...</string>
|
||||
<string name="sync_status_actions">Catching up %d reading actions...</string>
|
||||
<string name="sync_status_recounts">Catching up reading actions...</string>
|
||||
|
@ -300,4 +302,33 @@
|
|||
<item>NONE</item>
|
||||
</string-array>
|
||||
<string name="confirm_mark_all_read_value">FOLDER_ONLY</string>
|
||||
|
||||
<string name="settings_ltr_gesture_action">Rightward Swipe on Story Title</string>
|
||||
<string name="gest_action_none">No Action</string>
|
||||
<string name="gest_action_markread">Mark Story Read</string>
|
||||
<string name="gest_action_markunread">Mark Story Unread</string>
|
||||
<string-array name="ltr_gesture_action_entries">
|
||||
<item>@string/gest_action_none</item>
|
||||
<item>@string/gest_action_markread</item>
|
||||
<item>@string/gest_action_markunread</item>
|
||||
</string-array>
|
||||
<string-array name="ltr_gesture_action_values">
|
||||
<item>GEST_ACTION_NONE</item>
|
||||
<item>GEST_ACTION_MARKREAD</item>
|
||||
<item>GEST_ACTION_MARKUNREAD</item>
|
||||
</string-array>
|
||||
<string name="ltr_gesture_action_value">GEST_ACTION_MARKREAD</string>
|
||||
|
||||
<string name="settings_rtl_gesture_action">Leftward Swipe on Story Title</string>
|
||||
<string-array name="rtl_gesture_action_entries">
|
||||
<item>@string/gest_action_none</item>
|
||||
<item>@string/gest_action_markread</item>
|
||||
<item>@string/gest_action_markunread</item>
|
||||
</string-array>
|
||||
<string-array name="rtl_gesture_action_values">
|
||||
<item>GEST_ACTION_NONE</item>
|
||||
<item>GEST_ACTION_MARKREAD</item>
|
||||
<item>GEST_ACTION_MARKUNREAD</item>
|
||||
</string-array>
|
||||
<string name="rtl_gesture_action_value">GEST_ACTION_MARKUNREAD</string>
|
||||
</resources>
|
||||
|
|
|
@ -103,4 +103,22 @@
|
|||
android:defaultValue="@string/default_theme_value" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/settings_gestures">
|
||||
<ListPreference
|
||||
android:key="ltr_gesture_action"
|
||||
android:title="@string/settings_ltr_gesture_action"
|
||||
android:dialogTitle="@string/settings_ltr_gesture_action"
|
||||
android:entries="@array/ltr_gesture_action_entries"
|
||||
android:entryValues="@array/ltr_gesture_action_values"
|
||||
android:defaultValue="@string/ltr_gesture_action_value" />
|
||||
<ListPreference
|
||||
android:key="rtl_gesture_action"
|
||||
android:title="@string/settings_rtl_gesture_action"
|
||||
android:dialogTitle="@string/settings_rtl_gesture_action"
|
||||
android:entries="@array/rtl_gesture_action_entries"
|
||||
android:entryValues="@array/rtl_gesture_action_values"
|
||||
android:defaultValue="@string/rtl_gesture_action_value" />
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.newsblur.service.NBSyncService;
|
|||
import com.newsblur.util.DefaultFeedView;
|
||||
import com.newsblur.util.FeedSet;
|
||||
import com.newsblur.util.FeedUtils;
|
||||
import com.newsblur.util.GestureAction;
|
||||
import com.newsblur.util.PrefsUtils;
|
||||
import com.newsblur.util.ReadFilter;
|
||||
import com.newsblur.util.StoryOrder;
|
||||
|
@ -64,6 +65,13 @@ public abstract class ItemListFragment extends NbFragment implements OnScrollLis
|
|||
|
||||
private View fleuronFooter;
|
||||
|
||||
// row index of the last story to get a LTR gesture or -1 if none
|
||||
private int gestureLeftToRightFlag = -1;
|
||||
// row index of the last story to get a RTL gesture or -1 if none
|
||||
private int gestureRightToLeftFlag = -1;
|
||||
// flag indicating a gesture just occurred so we can ignore spurious story taps right after
|
||||
private boolean gestureDebounce = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -109,7 +117,7 @@ public abstract class ItemListFragment extends NbFragment implements OnScrollLis
|
|||
itemList.addFooterView(fleuronFooter, null, false);
|
||||
|
||||
itemList.setEmptyView(v.findViewById(R.id.empty_view));
|
||||
setupBezelSwipeDetector(itemList);
|
||||
setupGestureDetector(itemList);
|
||||
itemList.setOnScrollListener(this);
|
||||
itemList.setOnItemClickListener(this);
|
||||
itemList.setOnCreateContextMenuListener(this);
|
||||
|
@ -280,6 +288,10 @@ public abstract class ItemListFragment extends NbFragment implements OnScrollLis
|
|||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||
// context menu like to get accidentally triggered by the ListView event handler right after
|
||||
// we detect a gesure. if so, let the gesture happen rather than popping up the menu
|
||||
if ((gestureLeftToRightFlag > -1) || (gestureRightToLeftFlag > -1)) return;
|
||||
|
||||
MenuInflater inflater = getActivity().getMenuInflater();
|
||||
if (PrefsUtils.getStoryOrder(activity, getFeedSet()) == StoryOrder.NEWEST) {
|
||||
inflater.inflate(R.menu.context_story_newest, menu);
|
||||
|
@ -353,6 +365,14 @@ public abstract class ItemListFragment extends NbFragment implements OnScrollLis
|
|||
|
||||
@Override
|
||||
public synchronized void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
// clicks like to get accidentally triggered by the ListView event handler right after we detect
|
||||
// a gesture. if so, let the gesture happen rather than popping up the menu
|
||||
if (gestureDebounce){
|
||||
gestureDebounce = false;
|
||||
return;
|
||||
}
|
||||
if ((gestureLeftToRightFlag > -1) || (gestureRightToLeftFlag > -1)) return;
|
||||
|
||||
int truePosition = position - 1;
|
||||
Story story = adapter.getStory(truePosition);
|
||||
if (getActivity().isFinishing()) return;
|
||||
|
@ -364,36 +384,86 @@ public abstract class ItemListFragment extends NbFragment implements OnScrollLis
|
|||
adapter.setTextSize(size);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void setupBezelSwipeDetector(View v) {
|
||||
final GestureDetector gestureDetector = new GestureDetector(getActivity(), new BezelSwipeDetector());
|
||||
protected void setupGestureDetector(View v) {
|
||||
final GestureDetector gestureDetector = new GestureDetector(getActivity(), new ItemListGestureDetector());
|
||||
v.setOnTouchListener(new OnTouchListener() {
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
return gestureDetector.onTouchEvent(event);
|
||||
boolean result = gestureDetector.onTouchEvent(event);
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
|
||||
ItemListFragment.this.flushGesture();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A gesture detector that captures bezel swipes and finishes the activity,
|
||||
* to simulate a 'back' gesture.
|
||||
*
|
||||
* NB: pretty much all Views still try to process on-tap events despite
|
||||
* returning true, so be sure to check isFinishing() on all other
|
||||
* tap handlers.
|
||||
*/
|
||||
class BezelSwipeDetector extends GestureDetector.SimpleOnGestureListener {
|
||||
protected void gestureLeftToRight(float x, float y) {
|
||||
int index = itemList.pointToPosition((int) x, (int) y);
|
||||
gestureLeftToRightFlag = index;
|
||||
}
|
||||
|
||||
protected void gestureRightToLeft(float x, float y) {
|
||||
int index = itemList.pointToPosition((int) x, (int) y);
|
||||
gestureRightToLeftFlag = index;
|
||||
}
|
||||
|
||||
// the above gesture* methods will trigger more than once while being performed. it is not until
|
||||
// the up-event that we look to see if any happened, and if so, take action and flush.
|
||||
protected void flushGesture() {
|
||||
int index = -1;
|
||||
GestureAction action = GestureAction.GEST_ACTION_NONE;
|
||||
if (gestureLeftToRightFlag > -1) {
|
||||
index = gestureLeftToRightFlag;
|
||||
action = PrefsUtils.getLeftToRightGestureAction(getActivity());
|
||||
gestureLeftToRightFlag = -1;
|
||||
gestureDebounce = true;
|
||||
}
|
||||
if (gestureRightToLeftFlag > -1) {
|
||||
index = gestureRightToLeftFlag;
|
||||
action = PrefsUtils.getRightToLeftGestureAction(getActivity());
|
||||
gestureRightToLeftFlag = -1;
|
||||
gestureDebounce = true;
|
||||
}
|
||||
if (index <= -1) return;
|
||||
Story story = adapter.getStory(index-1);
|
||||
switch (action) {
|
||||
case GEST_ACTION_MARKREAD:
|
||||
FeedUtils.markStoryAsRead(story, getActivity());;
|
||||
break;
|
||||
case GEST_ACTION_MARKUNREAD:
|
||||
FeedUtils.markStoryUnread(story, getActivity());;
|
||||
break;
|
||||
case GEST_ACTION_NONE:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
class ItemListGestureDetector extends GestureDetector.SimpleOnGestureListener {
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
if((e1.getX() < 75f) && // the gesture should start from the left bezel and
|
||||
((e2.getX()-e1.getX()) > 90f) && // move horizontally to the right and
|
||||
(Math.abs(e1.getY()-e2.getY()) < 40f) // have minimal vertical travel, so we don't capture scrolling gestures
|
||||
) {
|
||||
if ((e1.getX() < 75f) && // the gesture should start from the left bezel and
|
||||
((e2.getX()-e1.getX()) > 90f) && // move horizontally to the right and
|
||||
(Math.abs(e1.getY()-e2.getY()) < 40f) // have minimal vertical travel, so we don't capture scrolling gestures
|
||||
) {
|
||||
ItemListFragment.this.getActivity().finish();
|
||||
return true;
|
||||
}
|
||||
if ((e1.getX() > 75f) && // the gesture should not start from the left bezel and
|
||||
((e2.getX()-e1.getX()) > 120f) && // move horizontally to the right and
|
||||
(Math.abs(e1.getY()-e2.getY()) < 40f) // have minimal vertical travel, so we don't capture scrolling gestures
|
||||
) {
|
||||
ItemListFragment.this.gestureLeftToRight(e1.getX(), e1.getY());
|
||||
return true;
|
||||
}
|
||||
if ((e1.getX() > 75f) && // the gesture should not start from the left bezel and
|
||||
((e1.getX()-e2.getX()) > 120f) && // move horizontally to the left and
|
||||
(Math.abs(e1.getY()-e2.getY()) < 40f) // have minimal vertical travel, so we don't capture scrolling gestures
|
||||
) {
|
||||
ItemListFragment.this.gestureRightToLeft(e1.getX(), e1.getY());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package com.newsblur.util;
|
||||
|
||||
public enum GestureAction {
|
||||
|
||||
GEST_ACTION_NONE,
|
||||
GEST_ACTION_MARKREAD,
|
||||
GEST_ACTION_MARKUNREAD;
|
||||
|
||||
}
|
|
@ -72,4 +72,7 @@ public class PrefConstants {
|
|||
|
||||
public static final String VOLUME_KEY_NAVIGATION = "volume_key_navigation";
|
||||
public static final String MARK_ALL_READ_CONFIRMATION = "pref_confirm_mark_all_read";
|
||||
|
||||
public static final String LTR_GESTURE_ACTION = "ltr_gesture_action";
|
||||
public static final String RTL_GESTURE_ACTION = "rtl_gesture_action";
|
||||
}
|
||||
|
|
|
@ -599,4 +599,14 @@ public class PrefsUtils {
|
|||
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||
return MarkAllReadConfirmation.valueOf(prefs.getString(PrefConstants.MARK_ALL_READ_CONFIRMATION, MarkAllReadConfirmation.FOLDER_ONLY.toString()));
|
||||
}
|
||||
|
||||
public static GestureAction getLeftToRightGestureAction(Context context) {
|
||||
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||
return GestureAction.valueOf(prefs.getString(PrefConstants.LTR_GESTURE_ACTION, GestureAction.GEST_ACTION_MARKREAD.toString()));
|
||||
}
|
||||
|
||||
public static GestureAction getRightToLeftGestureAction(Context context) {
|
||||
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||
return GestureAction.valueOf(prefs.getString(PrefConstants.RTL_GESTURE_ACTION, GestureAction.GEST_ACTION_MARKUNREAD.toString()));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue