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> onDragDropListeners = new ArrayList<OnDragDropListener>();
     32   private final DragItemContainer dragItemContainer;
     33   private final int[] locationOnScreen = new int[2];
     34 
     35   public DragDropController(DragItemContainer dragItemContainer) {
     36     this.dragItemContainer = 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(locationOnScreen);
     47       screenX = x + locationOnScreen[0];
     48       screenY = y + locationOnScreen[1];
     49     }
     50     final PhoneFavoriteSquareTileView tileView =
     51         dragItemContainer.getViewForLocation(screenX, screenY);
     52     if (tileView == null) {
     53       return false;
     54     }
     55     for (int i = 0; i < onDragDropListeners.size(); i++) {
     56       onDragDropListeners.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(locationOnScreen);
     64     final int screenX = x + locationOnScreen[0];
     65     final int screenY = y + locationOnScreen[1];
     66     final PhoneFavoriteSquareTileView view = dragItemContainer.getViewForLocation(screenX, screenY);
     67     for (int i = 0; i < onDragDropListeners.size(); i++) {
     68       onDragDropListeners.get(i).onDragHovered(screenX, screenY, view);
     69     }
     70   }
     71 
     72   public void handleDragFinished(int x, int y, boolean isRemoveView) {
     73     if (isRemoveView) {
     74       for (int i = 0; i < onDragDropListeners.size(); i++) {
     75         onDragDropListeners.get(i).onDroppedOnRemove();
     76       }
     77     }
     78 
     79     for (int i = 0; i < onDragDropListeners.size(); i++) {
     80       onDragDropListeners.get(i).onDragFinished(x, y);
     81     }
     82   }
     83 
     84   public void addOnDragDropListener(OnDragDropListener listener) {
     85     if (!onDragDropListeners.contains(listener)) {
     86       onDragDropListeners.add(listener);
     87     }
     88   }
     89 
     90   public void removeOnDragDropListener(OnDragDropListener listener) {
     91     if (onDragDropListeners.contains(listener)) {
     92       onDragDropListeners.remove(listener);
     93     }
     94   }
     95 
     96   /**
     97    * Callback interface used to retrieve views based on the current touch coordinates of the drag
     98    * event. The {@link DragItemContainer} houses the draggable views that this {@link
     99    * DragDropController} controls.
    100    */
    101   public interface DragItemContainer {
    102 
    103     PhoneFavoriteSquareTileView getViewForLocation(int x, int y);
    104   }
    105 }
    106