1 /* 2 * Copyright (C) 2015 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.dragndrop; 18 19 import android.content.Context; 20 import android.view.DragEvent; 21 import android.view.MotionEvent; 22 23 import com.android.launcher3.DropTarget.DragObject; 24 import com.android.launcher3.Utilities; 25 26 /** 27 * Base class for driving a drag/drop operation. 28 */ 29 public abstract class DragDriver { 30 protected final EventListener mEventListener; 31 32 public interface EventListener { onDriverDragMove(float x, float y)33 void onDriverDragMove(float x, float y); onDriverDragExitWindow()34 void onDriverDragExitWindow(); onDriverDragEnd(float x, float y)35 void onDriverDragEnd(float x, float y); onDriverDragCancel()36 void onDriverDragCancel(); 37 } 38 DragDriver(EventListener eventListener)39 public DragDriver(EventListener eventListener) { 40 mEventListener = eventListener; 41 } 42 43 /** 44 * Handles ending of the DragView animation. 45 */ onDragViewAnimationEnd()46 public void onDragViewAnimationEnd() { } 47 onTouchEvent(MotionEvent ev)48 public boolean onTouchEvent(MotionEvent ev) { 49 final int action = ev.getAction(); 50 51 switch (action) { 52 case MotionEvent.ACTION_MOVE: 53 mEventListener.onDriverDragMove(ev.getX(), ev.getY()); 54 break; 55 case MotionEvent.ACTION_UP: 56 mEventListener.onDriverDragMove(ev.getX(), ev.getY()); 57 mEventListener.onDriverDragEnd(ev.getX(), ev.getY()); 58 break; 59 case MotionEvent.ACTION_CANCEL: 60 mEventListener.onDriverDragCancel(); 61 break; 62 } 63 64 return true; 65 } 66 onDragEvent(DragEvent event)67 public abstract boolean onDragEvent (DragEvent event); 68 69 onInterceptTouchEvent(MotionEvent ev)70 public boolean onInterceptTouchEvent(MotionEvent ev) { 71 final int action = ev.getAction(); 72 73 switch (action) { 74 case MotionEvent.ACTION_UP: 75 mEventListener.onDriverDragEnd(ev.getX(), ev.getY()); 76 break; 77 case MotionEvent.ACTION_CANCEL: 78 mEventListener.onDriverDragCancel(); 79 break; 80 } 81 82 return true; 83 } 84 create(Context context, DragController dragController, DragObject dragObject, DragOptions options)85 public static DragDriver create(Context context, DragController dragController, 86 DragObject dragObject, DragOptions options) { 87 if (Utilities.ATLEAST_NOUGAT && options.systemDndStartPoint != null) { 88 return new SystemDragDriver(dragController, context, dragObject); 89 } else { 90 return new InternalDragDriver(dragController); 91 } 92 } 93 } 94 95 /** 96 * Class for driving a system (i.e. framework) drag/drop operation. 97 */ 98 class SystemDragDriver extends DragDriver { 99 100 private final DragObject mDragObject; 101 private final Context mContext; 102 103 float mLastX = 0; 104 float mLastY = 0; 105 SystemDragDriver(DragController dragController, Context context, DragObject dragObject)106 public SystemDragDriver(DragController dragController, Context context, DragObject dragObject) { 107 super(dragController); 108 mDragObject = dragObject; 109 mContext = context; 110 } 111 112 @Override onTouchEvent(MotionEvent ev)113 public boolean onTouchEvent(MotionEvent ev) { 114 return false; 115 } 116 117 @Override onInterceptTouchEvent(MotionEvent ev)118 public boolean onInterceptTouchEvent(MotionEvent ev) { 119 return false; 120 } 121 122 @Override onDragEvent(DragEvent event)123 public boolean onDragEvent (DragEvent event) { 124 final int action = event.getAction(); 125 126 switch (action) { 127 case DragEvent.ACTION_DRAG_STARTED: 128 mLastX = event.getX(); 129 mLastY = event.getY(); 130 return true; 131 132 case DragEvent.ACTION_DRAG_ENTERED: 133 return true; 134 135 case DragEvent.ACTION_DRAG_LOCATION: 136 mLastX = event.getX(); 137 mLastY = event.getY(); 138 mEventListener.onDriverDragMove(event.getX(), event.getY()); 139 return true; 140 141 case DragEvent.ACTION_DROP: 142 mLastX = event.getX(); 143 mLastY = event.getY(); 144 mEventListener.onDriverDragMove(event.getX(), event.getY()); 145 mEventListener.onDriverDragEnd(mLastX, mLastY); 146 return true; 147 case DragEvent.ACTION_DRAG_EXITED: 148 mEventListener.onDriverDragExitWindow(); 149 return true; 150 151 case DragEvent.ACTION_DRAG_ENDED: 152 mEventListener.onDriverDragCancel(); 153 return true; 154 155 default: 156 return false; 157 } 158 } 159 } 160 161 /** 162 * Class for driving an internal (i.e. not using framework) drag/drop operation. 163 */ 164 class InternalDragDriver extends DragDriver { InternalDragDriver(DragController dragController)165 public InternalDragDriver(DragController dragController) { 166 super(dragController); 167 } 168 169 @Override onDragEvent(DragEvent event)170 public boolean onDragEvent (DragEvent event) { return false; } 171 }; 172