1 /* 2 * Copyright (C) 2008 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.launcher3; 18 19 import android.content.Context; 20 import android.graphics.Rect; 21 22 import com.android.launcher3.accessibility.DragViewStateAnnouncer; 23 import com.android.launcher3.config.FeatureFlags; 24 import com.android.launcher3.dragndrop.DragOptions; 25 import com.android.launcher3.dragndrop.DragView; 26 import com.android.launcher3.dragndrop.DraggableView; 27 import com.android.launcher3.folder.FolderNameProvider; 28 import com.android.launcher3.logging.InstanceId; 29 import com.android.launcher3.logging.InstanceIdSequence; 30 import com.android.launcher3.model.data.ItemInfo; 31 import com.android.launcher3.util.Executors; 32 33 /** 34 * Interface defining an object that can receive a drag. 35 * 36 */ 37 public interface DropTarget { 38 39 class DragObject { 40 public int x = -1; 41 public int y = -1; 42 43 /** X offset from the upper-left corner of the cell to where we touched. */ 44 public int xOffset = -1; 45 46 /** Y offset from the upper-left corner of the cell to where we touched. */ 47 public int yOffset = -1; 48 49 /** This indicates whether a drag is in final stages, either drop or cancel. It 50 * differentiates onDragExit, since this is called when the drag is ending, above 51 * the current drag target, or when the drag moves off the current drag object. 52 */ 53 public boolean dragComplete = false; 54 55 /** The view that moves around while you drag. */ 56 public DragView dragView = null; 57 58 /** The data associated with the object, after item is dropped. */ 59 public ItemInfo dragInfo = null; 60 61 /** The data associated with the object being dragged */ 62 public ItemInfo originalDragInfo = null; 63 64 /** Where the drag originated */ 65 public DragSource dragSource = null; 66 67 /** Indicates that the drag operation was cancelled */ 68 public boolean cancelled = false; 69 70 /** Defers removing the DragView from the DragLayer until after the drop animation. */ 71 public boolean deferDragViewCleanupPostAnimation = true; 72 73 public DragViewStateAnnouncer stateAnnouncer; 74 75 public FolderNameProvider folderNameProvider; 76 77 /** The source view (ie. icon, widget etc.) that is being dragged and which the 78 * DragView represents. May be an actual View class or a virtual stand-in */ 79 public DraggableView originalView = null; 80 81 /** Used for matching DROP event with its corresponding DRAG event on the server side. */ 82 public final InstanceId logInstanceId = 83 new InstanceIdSequence(1 << 20 /*InstanceId.INSTANCE_ID_MAX*/) 84 .newInstanceId(); 85 DragObject(Context context)86 public DragObject(Context context) { 87 if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { 88 Executors.MODEL_EXECUTOR.post(() -> { 89 folderNameProvider = FolderNameProvider.newInstance(context); 90 }); 91 } 92 } 93 94 /** 95 * This is used to compute the visual center of the dragView. This point is then 96 * used to visualize drop locations and determine where to drop an item. The idea is that 97 * the visual center represents the user's interpretation of where the item is, and hence 98 * is the appropriate point to use when determining drop location. 99 */ getVisualCenter(float[] recycle)100 public final float[] getVisualCenter(float[] recycle) { 101 final float res[] = (recycle == null) ? new float[2] : recycle; 102 Rect dragRegion = dragView.getDragRegion(); 103 104 // These represent the visual top and left of drag view if a dragRect was provided. 105 // If a dragRect was not provided, then they correspond to the actual view left and 106 // top, as the dragRect is in that case taken to be the entire dragView. 107 int left = x - xOffset - dragRegion.left; 108 int top = y - yOffset - dragRegion.top; 109 110 // In order to find the visual center, we shift by half the dragRect 111 res[0] = left + dragRegion.width() / 2; 112 res[1] = top + dragRegion.height() / 2; 113 114 return res; 115 } 116 117 118 /** 119 * This is used to determine if an object is dropped at a different location than it was 120 * dragged from 121 */ isMoved()122 public boolean isMoved() { 123 return dragInfo.cellX != originalDragInfo.cellX 124 || dragInfo.cellY != originalDragInfo.cellY 125 || dragInfo.screenId != originalDragInfo.screenId 126 || dragInfo.container != originalDragInfo.container; 127 } 128 } 129 130 /** 131 * Used to temporarily disable certain drop targets 132 * 133 * @return boolean specifying whether this drop target is currently enabled 134 */ isDropEnabled()135 boolean isDropEnabled(); 136 137 /** 138 * Handle an object being dropped on the DropTarget. 139 * 140 * This will be called only if this target previously returned true for {@link #acceptDrop}. It 141 * is the responsibility of this target to exit out of the spring loaded mode (either 142 * immediately or after any pending animations). 143 * 144 * If the drop was cancelled for some reason, onDrop will never get called, the UI will 145 * automatically exit out of this mode. 146 */ onDrop(DragObject dragObject, DragOptions options)147 void onDrop(DragObject dragObject, DragOptions options); 148 onDragEnter(DragObject dragObject)149 void onDragEnter(DragObject dragObject); 150 onDragOver(DragObject dragObject)151 void onDragOver(DragObject dragObject); 152 onDragExit(DragObject dragObject)153 void onDragExit(DragObject dragObject); 154 155 /** 156 * Check if a drop action can occur at, or near, the requested location. 157 * This will be called just before onDrop. 158 * @return True if the drop will be accepted, false otherwise. 159 */ acceptDrop(DragObject dragObject)160 boolean acceptDrop(DragObject dragObject); 161 prepareAccessibilityDrop()162 void prepareAccessibilityDrop(); 163 164 // These methods are implemented in Views getHitRectRelativeToDragLayer(Rect outRect)165 void getHitRectRelativeToDragLayer(Rect outRect); 166 } 167