summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/PagedViewWithDraggableItems.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/PagedViewWithDraggableItems.java')
-rw-r--r--src/com/android/launcher3/PagedViewWithDraggableItems.java178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/com/android/launcher3/PagedViewWithDraggableItems.java b/src/com/android/launcher3/PagedViewWithDraggableItems.java
new file mode 100644
index 000000000..8f10ecfa5
--- /dev/null
+++ b/src/com/android/launcher3/PagedViewWithDraggableItems.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+
+/* Class that does most of the work of enabling dragging items out of a PagedView by performing a
+ * vertical drag. Used by both CustomizePagedView and AllAppsPagedView.
+ * Subclasses must do the following:
+ * * call setDragSlopeThreshold after making an instance of the PagedViewWithDraggableItems
+ * * call child.setOnLongClickListener(this) and child.setOnTouchListener(this) on all children
+ * (good place to do it is in syncPageItems)
+ * * override beginDragging(View) (but be careful to call super.beginDragging(View)
+ *
+ */
+public abstract class PagedViewWithDraggableItems extends PagedView
+ implements View.OnLongClickListener, View.OnTouchListener {
+ private View mLastTouchedItem;
+ private boolean mIsDragging;
+ private boolean mIsDragEnabled;
+ private float mDragSlopeThreshold;
+ private Launcher mLauncher;
+
+ public PagedViewWithDraggableItems(Context context) {
+ this(context, null);
+ }
+
+ public PagedViewWithDraggableItems(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public PagedViewWithDraggableItems(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mLauncher = (Launcher) context;
+ }
+
+ protected boolean beginDragging(View v) {
+ boolean wasDragging = mIsDragging;
+ mIsDragging = true;
+ return !wasDragging;
+ }
+
+ protected void cancelDragging() {
+ mIsDragging = false;
+ mLastTouchedItem = null;
+ mIsDragEnabled = false;
+ }
+
+ private void handleTouchEvent(MotionEvent ev) {
+ final int action = ev.getAction();
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN:
+ cancelDragging();
+ mIsDragEnabled = true;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (mTouchState != TOUCH_STATE_SCROLLING && !mIsDragging && mIsDragEnabled) {
+ determineDraggingStart(ev);
+ }
+ break;
+ }
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ handleTouchEvent(ev);
+ return super.onInterceptTouchEvent(ev);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ handleTouchEvent(ev);
+ return super.onTouchEvent(ev);
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ mLastTouchedItem = v;
+ mIsDragEnabled = true;
+ return false;
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ // Return early if this is not initiated from a touch
+ if (!v.isInTouchMode()) return false;
+ // Return early if we are still animating the pages
+ if (mNextPage != INVALID_PAGE) return false;
+ // When we have exited all apps or are in transition, disregard long clicks
+ if (!mLauncher.isAllAppsVisible() ||
+ mLauncher.getWorkspace().isSwitchingState()) return false;
+ // Return if global dragging is not enabled
+ if (!mLauncher.isDraggingEnabled()) return false;
+
+ return beginDragging(v);
+ }
+
+ /*
+ * Determines if we should change the touch state to start scrolling after the
+ * user moves their touch point too far.
+ */
+ protected void determineScrollingStart(MotionEvent ev) {
+ if (!mIsDragging) super.determineScrollingStart(ev);
+ }
+
+ /*
+ * Determines if we should change the touch state to start dragging after the
+ * user moves their touch point far enough.
+ */
+ protected void determineDraggingStart(MotionEvent ev) {
+ /*
+ * Locally do absolute value. mLastMotionX is set to the y value
+ * of the down event.
+ */
+ final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ final float x = ev.getX(pointerIndex);
+ final float y = ev.getY(pointerIndex);
+ final int xDiff = (int) Math.abs(x - mLastMotionX);
+ final int yDiff = (int) Math.abs(y - mLastMotionY);
+
+ final int touchSlop = mTouchSlop;
+ boolean yMoved = yDiff > touchSlop;
+ boolean isUpwardMotion = (yDiff / (float) xDiff) > mDragSlopeThreshold;
+
+ if (isUpwardMotion && yMoved && mLastTouchedItem != null) {
+ // Drag if the user moved far enough along the Y axis
+ beginDragging(mLastTouchedItem);
+
+ // Cancel any pending long press
+ if (mAllowLongPress) {
+ mAllowLongPress = false;
+ // Try canceling the long press. It could also have been scheduled
+ // by a distant descendant, so use the mAllowLongPress flag to block
+ // everything
+ final View currentPage = getPageAt(mCurrentPage);
+ if (currentPage != null) {
+ currentPage.cancelLongPress();
+ }
+ }
+ }
+ }
+
+ public void setDragSlopeThreshold(float dragSlopeThreshold) {
+ mDragSlopeThreshold = dragSlopeThreshold;
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ cancelDragging();
+ super.onDetachedFromWindow();
+ }
+
+ /** Show the scrolling indicators when we move the page */
+ protected void onPageBeginMoving() {
+ showScrollingIndicator(false);
+ }
+ protected void onPageEndMoving() {
+ hideScrollingIndicator(false);
+ }
+}