Home | History | Annotate | Download | only in list
      1 /*
      2  * Copyright (C) 2016 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.dialer.app.list;
     18 
     19 import android.os.Build.VERSION;
     20 import android.os.Build.VERSION_CODES;
     21 import android.view.View;
     22 import java.util.ArrayList;
     23 import java.util.List;
     24 
     25 /**
     26  * Class that handles and combines drag events generated from multiple views, and then fires off
     27  * events to any OnDragDropListeners that have registered for callbacks.
     28  */
     29 public class DragDropController {
     30 
     31   private final List<OnDragDropListener> mOnDragDropListeners = new ArrayList<OnDragDropListener>();
     32   private final DragItemContainer mDragItemContainer;
     33   private final int[] mLocationOnScreen = new int[2];
     34 
     35   public DragDropController(DragItemContainer dragItemContainer) {
     36     mDragItemContainer = dragItemContainer;
     37   }
     38 
     39   /** @return True if the drag is started, false if the drag is cancelled for some reason. */
     40   boolean handleDragStarted(View v, int x, int y) {
     41     int screenX = x;
     42     int screenY = y;
     43     // The coordinates in dragEvent of DragEvent.ACTION_DRAG_STARTED before NYC is window-related.
     44     // This is fixed in NYC.
     45     if (VERSION.SDK_INT >= VERSION_CODES.N) {
     46       v.getLocationOnScreen(mLocationOnScreen);
     47       screenX = x + mLocationOnScreen[0];
     48       screenY = y + mLocationOnScreen[1];
     49     }
     50     final PhoneFavoriteSquareTileView tileView =
     51         mDragItemContainer.getViewForLocation(screenX, screenY);
     52     if (tileView == null) {
     53       return false;
     54     }
     55     for (int i = 0; i < mOnDragDropListeners.size(); i++) {
     56       mOnDragDropListeners.get(i).onDragStarted(screenX, screenY, tileView);
     57     }
     58 
     59     return true;
     60   }
     61 
     62   public void handleDragHovered(View v, int x, int y) {
     63     v.getLocationOnScreen(mLocationOnScreen);
     64     final int screenX = x + mLocationOnScreen[0];
     65     final int screenY = y + mLocationOnScreen[1];
     66     final PhoneFavoriteSquareTileView view =
     67         mDragItemContainer.getViewForLocation(screenX, screenY);
     68     for (int i = 0; i < mOnDragDropListeners.size(); i++) {
     69       mOnDragDropListeners.get(i).onDragHovered(screenX, screenY, view);
     70     }
     71   }
     72 
     73   public void handleDragFinished(int x, int y, boolean isRemoveView) {
     74     if (isRemoveView) {
     75       for (int i = 0; i < mOnDragDropListeners.size(); i++) {
     76         mOnDragDropListeners.get(i).onDroppedOnRemove();
     77       }
     78     }
     79 
     80     for (int i = 0; i < mOnDragDropListeners.size(); i++) {
     81       mOnDragDropListeners.get(i).onDragFinished(x, y);
     82     }
     83   }
     84 
     85   public void addOnDragDropListener(OnDragDropListener listener) {
     86     if (!mOnDragDropListeners.contains(listener)) {
     87       mOnDragDropListeners.add(listener);
     88     }
     89   }
     90 
     91   public void removeOnDragDropListener(OnDragDropListener listener) {
     92     if (mOnDragDropListeners.contains(listener)) {
     93       mOnDragDropListeners.remove(listener);
     94     }
     95   }
     96 
     97   /**
     98    * Callback interface used to retrieve views based on the current touch coordinates of the drag
     99    * event. The {@link DragItemContainer} houses the draggable views that this {@link
    100    * DragDropController} controls.
    101    */
    102   public interface DragItemContainer {
    103 
    104     PhoneFavoriteSquareTileView getViewForLocation(int x, int y);
    105   }
    106 }
    107