1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.documentsui.selection; 17 18 import static android.support.v4.util.Preconditions.checkArgument; 19 20 import android.view.GestureDetector.SimpleOnGestureListener; 21 import android.view.MotionEvent; 22 23 import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails; 24 25 /** 26 * Base class for handlers that can be registered w/ {@link GestureRouter}. 27 */ 28 public abstract class MotionInputHandler extends SimpleOnGestureListener { 29 30 protected final SelectionHelper mSelectionHelper; 31 protected final ItemDetailsLookup mDetailsLookup; 32 33 private final Callbacks mCallbacks; 34 MotionInputHandler( SelectionHelper selectionHelper, ItemDetailsLookup detailsLookup, Callbacks callbacks)35 public MotionInputHandler( 36 SelectionHelper selectionHelper, 37 ItemDetailsLookup detailsLookup, 38 Callbacks callbacks) { 39 40 checkArgument(selectionHelper != null); 41 checkArgument(detailsLookup != null); 42 checkArgument(callbacks != null); 43 44 mSelectionHelper = selectionHelper; 45 mDetailsLookup = detailsLookup; 46 mCallbacks = callbacks; 47 } 48 selectItem(ItemDetails details)49 protected final boolean selectItem(ItemDetails details) { 50 checkArgument(details != null); 51 checkArgument(details.hasPosition()); 52 checkArgument(details.hasStableId()); 53 54 if (mSelectionHelper.select(details.getStableId())) { 55 mSelectionHelper.anchorRange(details.getPosition()); 56 } 57 58 // we set the focus on this doc so it will be the origin for keyboard events or shift+clicks 59 // if there is only a single item selected, otherwise clear focus 60 if (mSelectionHelper.getSelection().size() == 1) { 61 mCallbacks.focusItem(details); 62 } else { 63 mCallbacks.clearFocus(); 64 } 65 return true; 66 } 67 focusItem(ItemDetails details)68 protected final boolean focusItem(ItemDetails details) { 69 checkArgument(details != null); 70 checkArgument(details.hasStableId()); 71 72 mSelectionHelper.clearSelection(); 73 mCallbacks.focusItem(details); 74 return true; 75 } 76 extendSelectionRange(ItemDetails details)77 protected final void extendSelectionRange(ItemDetails details) { 78 checkArgument(details.hasPosition()); 79 checkArgument(details.hasStableId()); 80 81 mSelectionHelper.extendRange(details.getPosition()); 82 mCallbacks.focusItem(details); 83 } 84 isRangeExtension(MotionEvent e)85 protected final boolean isRangeExtension(MotionEvent e) { 86 return MotionEvents.isShiftKeyPressed(e) && mSelectionHelper.isRangeActive(); 87 } 88 shouldClearSelection(MotionEvent e, ItemDetails item)89 protected boolean shouldClearSelection(MotionEvent e, ItemDetails item) { 90 return !MotionEvents.isCtrlKeyPressed(e) 91 && !item.inSelectionHotspot(e) 92 && !mSelectionHelper.isSelected(item.getStableId()); 93 } 94 95 public static abstract class Callbacks { onPerformHapticFeedback()96 public abstract void onPerformHapticFeedback(); focusItem(ItemDetails item)97 public void focusItem(ItemDetails item) {} clearFocus()98 public void clearFocus() {} 99 } 100 } 101