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 17 package com.android.documentsui.dirlist; 18 19 import static com.android.documentsui.base.Shared.DEBUG; 20 21 import android.app.Activity; 22 import android.content.ClipData; 23 import android.view.DragEvent; 24 import android.view.View; 25 import android.util.Log; 26 27 import com.android.documentsui.AbstractActionHandler; 28 import com.android.documentsui.AbstractDragHost; 29 import com.android.documentsui.ActionHandler; 30 import com.android.documentsui.DragAndDropManager; 31 import com.android.documentsui.base.DocumentInfo; 32 import com.android.documentsui.base.DocumentStack; 33 import com.android.documentsui.base.Lookup; 34 import com.android.documentsui.base.State; 35 import com.android.documentsui.selection.SelectionManager; 36 import com.android.documentsui.ui.DialogController; 37 38 import java.util.function.Predicate; 39 40 /** 41 * Drag host for items in {@link DirectoryFragment}. 42 */ 43 class DragHost<T extends Activity & AbstractActionHandler.CommonAddons> extends AbstractDragHost { 44 45 private static final String TAG = "dirlist.DragHost"; 46 47 private final T mActivity; 48 private final SelectionManager mSelectionMgr; 49 private final ActionHandler mActions; 50 private final State mState; 51 private final DialogController mDialogs; 52 private final Predicate<View> mIsDocumentView; 53 private final Lookup<View, DocumentHolder> mHolderLookup; 54 private final Lookup<View, DocumentInfo> mDestinationLookup; 55 56 DragHost( 57 T activity, 58 DragAndDropManager dragAndDropManager, 59 SelectionManager selectionMgr, 60 ActionHandler actions, 61 State state, 62 DialogController dialogs, 63 Predicate<View> isDocumentView, 64 Lookup<View, DocumentHolder> holderLookup, 65 Lookup<View, DocumentInfo> destinationLookup) { 66 super(dragAndDropManager); 67 68 mActivity = activity; 69 mSelectionMgr = selectionMgr; 70 mActions = actions; 71 mState = state; 72 mDialogs = dialogs; 73 mIsDocumentView = isDocumentView; 74 mHolderLookup = holderLookup; 75 mDestinationLookup = destinationLookup; 76 } 77 78 void dragStopped(boolean result) { 79 if (result) { 80 mSelectionMgr.clearSelection(); 81 } 82 } 83 84 @Override 85 public void runOnUiThread(Runnable runnable) { 86 mActivity.runOnUiThread(runnable); 87 } 88 89 @Override 90 public void setDropTargetHighlight(View v, boolean highlight) { 91 } 92 93 @Override 94 public void onViewHovered(View v) { 95 if (mIsDocumentView.test(v)) { 96 mActions.springOpenDirectory(mDestinationLookup.lookup(v)); 97 } 98 mActivity.setRootsDrawerOpen(false); 99 } 100 101 @Override 102 public void onDragEntered(View v) { 103 mActivity.setRootsDrawerOpen(false); 104 mDragAndDropManager.updateState(v, mState.stack.getRoot(), mDestinationLookup.lookup(v)); 105 } 106 107 boolean canSpringOpen(View v) { 108 DocumentInfo doc = mDestinationLookup.lookup(v); 109 return (doc != null) && mDragAndDropManager.canSpringOpen(mState.stack.getRoot(), doc); 110 } 111 112 boolean handleDropEvent(View v, DragEvent event) { 113 mActivity.setRootsDrawerOpen(false); 114 115 ClipData clipData = event.getClipData(); 116 assert (clipData != null); 117 118 DocumentInfo dst = mDestinationLookup.lookup(v); 119 if (dst == null) { 120 if (DEBUG) Log.d(TAG, "Invalid destination. Ignoring."); 121 return false; 122 } 123 124 // If destination is already at top of stack, no need to pass it in 125 DocumentStack dstStack = dst.equals(mState.stack.peek()) 126 ? mState.stack 127 : new DocumentStack(mState.stack, dst); 128 return mDragAndDropManager.drop(event.getClipData(), event.getLocalState(), dstStack, 129 mDialogs::showFileOperationStatus); 130 } 131 } 132