1 /* 2 * Copyright (C) 2023 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.car.portraitlauncher.panel; 18 19 import android.annotation.NonNull; 20 import android.content.Context; 21 import android.graphics.Point; 22 import android.view.GestureDetector; 23 import android.view.MotionEvent; 24 import android.view.View; 25 26 /** An OnTouchListener to control the drag events of a TaskViewPanel */ 27 abstract class OnPanelDragListener implements View.OnTouchListener { 28 private class SingleTapListener extends GestureDetector.SimpleOnGestureListener { 29 @Override onSingleTapUp(@onNull MotionEvent e)30 public boolean onSingleTapUp(@NonNull MotionEvent e) { 31 onClick(); 32 return true; 33 } 34 } 35 36 private final GestureDetector mGestureDetector; 37 private final Point mDragBeginPoint = new Point(); 38 private final Point mDragCurrentPoint = new Point(); 39 private final Point mDragDeltaPoint = new Point(); 40 private final Point mLastDragDeltaPoint = new Point(); 41 OnPanelDragListener(Context context)42 OnPanelDragListener(Context context) { 43 mGestureDetector = new GestureDetector(context, new SingleTapListener()); 44 } 45 46 @Override onTouch(View view, MotionEvent event)47 public boolean onTouch(View view, MotionEvent event) { 48 // Abandon the rest if gesture detector already detected a gesture. 49 if (mGestureDetector.onTouchEvent(event)) { 50 return true; 51 } 52 53 mDragCurrentPoint.set((int) event.getRawX(), (int) event.getRawY()); 54 55 switch (event.getAction()) { 56 case MotionEvent.ACTION_DOWN: 57 mDragBeginPoint.set(mDragCurrentPoint); 58 mDragDeltaPoint.set(0, 0); 59 mLastDragDeltaPoint.set(0, 0); 60 onDragBegin(); 61 break; 62 case MotionEvent.ACTION_MOVE: 63 mDragDeltaPoint.set(mDragCurrentPoint); 64 mDragDeltaPoint.offset(-mDragBeginPoint.x, -mDragBeginPoint.y); 65 if (mLastDragDeltaPoint.equals(mDragDeltaPoint)) { 66 return true; 67 } 68 mLastDragDeltaPoint.set(mDragDeltaPoint); 69 onDrag(mDragDeltaPoint.x, mDragDeltaPoint.y); 70 break; 71 case MotionEvent.ACTION_UP: 72 mDragDeltaPoint.set(mDragCurrentPoint); 73 mDragDeltaPoint.offset(-mDragBeginPoint.x, -mDragBeginPoint.y); 74 onDragEnd(mDragDeltaPoint.x, mDragDeltaPoint.y); 75 break; 76 default: 77 return false; 78 } 79 return true; 80 } 81 onClick()82 abstract void onClick(); onDragBegin()83 abstract void onDragBegin(); onDrag(int deltaX, int deltaY)84 abstract void onDrag(int deltaX, int deltaY); onDragEnd(int deltaX, int deltaY)85 abstract void onDragEnd(int deltaX, int deltaY); 86 } 87