blob: 1af26d0e70648c4776622e1ec526cbca2bb46141 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.documentsui.dirlist;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import com.android.documentsui.Events;
import com.android.documentsui.Events.MotionInputEvent;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* The gesture listener for items in the directly list, interprets gestures, and sends the
* events to the target DocumentHolder, whence they are routed to the appropriate listener.
*/
final class GestureListener extends GestureDetector.SimpleOnGestureListener {
// From the RecyclerView, we get two events sent to
// ListeningGestureDetector#onInterceptTouchEvent on a mouse click; we first get an
// ACTION_DOWN Event for clicking on the mouse, and then an ACTION_UP event from releasing
// the mouse click. ACTION_UP event doesn't have information regarding the button (primary
// vs. secondary), so we have to save that somewhere first from ACTION_DOWN, and then reuse
// it later. The ACTION_DOWN event doesn't get forwarded to GestureListener, so we have open
// up a public set method to set it.
private int mLastButtonState = -1;
private MultiSelectManager mSelectionMgr;
private RecyclerView mRecView;
private Function<MotionInputEvent, DocumentHolder> mDocFinder;
private Predicate<MotionInputEvent> mDoubleTapHandler;
private Predicate<MotionInputEvent> mRightClickHandler;
public GestureListener(
MultiSelectManager selectionMgr,
RecyclerView recView,
Function<MotionInputEvent, DocumentHolder> docFinder,
Predicate<MotionInputEvent> doubleTapHandler,
Predicate<MotionInputEvent> rightClickHandler) {
mSelectionMgr = selectionMgr;
mRecView = recView;
mDocFinder = docFinder;
mDoubleTapHandler = doubleTapHandler;
mRightClickHandler = rightClickHandler;
}
public void setLastButtonState(int state) {
mLastButtonState = state;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// Single tap logic:
// We first see if it's a mouse event, and if it was right click by checking on
// @{code ListeningGestureDetector#mLastButtonState}
// If the selection manager is active, it gets first whack at handling tap
// events. Otherwise, tap events are routed to the target DocumentHolder.
if (Events.isMouseEvent(e) && mLastButtonState == MotionEvent.BUTTON_SECONDARY) {
mLastButtonState = -1;
return onRightClick(e);
}
try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) {
boolean handled = mSelectionMgr.onSingleTapUp(event);
if (handled) {
return handled;
}
// Give the DocumentHolder a crack at the event.
DocumentHolder holder = mDocFinder.apply(event);
if (holder != null) {
handled = holder.onSingleTapUp(e);
}
return handled;
}
}
@Override
public void onLongPress(MotionEvent e) {
// Long-press events get routed directly to the selection manager. They can be
// changed to route through the DocumentHolder if necessary.
try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) {
mSelectionMgr.onLongPress(event);
}
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// Double-tap events are handled directly by the DirectoryFragment. They can be changed
// to route through the DocumentHolder if necessary.
try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) {
return mDoubleTapHandler.test(event);
}
}
public boolean onRightClick(MotionEvent e) {
try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) {
return mRightClickHandler.test(event);
}
}
}