From 0f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1b Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 2 Dec 2015 17:55:07 -0800 Subject: [PATCH] Added config_springLoadWorkspace to enable/disable spring-loaded workspace. - Added side hints back - Only scale down icons if spring-loaded - Only show App Info drop target if spring-loaded Change-Id: I4b0dddccbe0e80b7ceb6b7266fc527f757744148 --- res/drawable-hdpi/page_hover_left.9.png | Bin 0 -> 102 bytes .../page_hover_left_active.9.png | Bin 0 -> 102 bytes res/drawable-hdpi/page_hover_right.9.png | Bin 0 -> 100 bytes .../page_hover_right_active.9.png | Bin 0 -> 100 bytes res/drawable-mdpi/page_hover_left.9.png | Bin 0 -> 99 bytes .../page_hover_left_active.9.png | Bin 0 -> 99 bytes res/drawable-mdpi/page_hover_right.9.png | Bin 0 -> 97 bytes .../page_hover_right_active.9.png | Bin 0 -> 98 bytes res/drawable-xhdpi/page_hover_left.9.png | Bin 0 -> 104 bytes .../page_hover_left_active.9.png | Bin 0 -> 104 bytes res/drawable-xhdpi/page_hover_right.9.png | Bin 0 -> 108 bytes .../page_hover_right_active.9.png | Bin 0 -> 108 bytes res/drawable-xxhdpi/page_hover_left.9.png | Bin 0 -> 116 bytes .../page_hover_left_active.9.png | Bin 0 -> 116 bytes res/drawable-xxhdpi/page_hover_right.9.png | Bin 0 -> 122 bytes .../page_hover_right_active.9.png | Bin 0 -> 122 bytes res/values-sw720dp-land/dimens.xml | 21 +++++ res/values-sw720dp-port/dimens.xml | 22 ++++++ res/values/dimens.xml | 4 + src/com/android/launcher3/CellLayout.java | 8 ++ src/com/android/launcher3/Folder.java | 3 +- src/com/android/launcher3/Launcher.java | 5 +- src/com/android/launcher3/Workspace.java | 25 ++++-- .../allapps/AllAppsContainerView.java | 2 + .../launcher3/dragndrop/DragController.java | 73 ++++++++++++++++- .../launcher3/dragndrop/DragLayer.java | 74 +++++++++++++++++- 26 files changed, 223 insertions(+), 14 deletions(-) create mode 100644 res/drawable-hdpi/page_hover_left.9.png create mode 100644 res/drawable-hdpi/page_hover_left_active.9.png create mode 100644 res/drawable-hdpi/page_hover_right.9.png create mode 100644 res/drawable-hdpi/page_hover_right_active.9.png create mode 100644 res/drawable-mdpi/page_hover_left.9.png create mode 100644 res/drawable-mdpi/page_hover_left_active.9.png create mode 100644 res/drawable-mdpi/page_hover_right.9.png create mode 100644 res/drawable-mdpi/page_hover_right_active.9.png create mode 100644 res/drawable-xhdpi/page_hover_left.9.png create mode 100644 res/drawable-xhdpi/page_hover_left_active.9.png create mode 100644 res/drawable-xhdpi/page_hover_right.9.png create mode 100644 res/drawable-xhdpi/page_hover_right_active.9.png create mode 100644 res/drawable-xxhdpi/page_hover_left.9.png create mode 100644 res/drawable-xxhdpi/page_hover_left_active.9.png create mode 100644 res/drawable-xxhdpi/page_hover_right.9.png create mode 100644 res/drawable-xxhdpi/page_hover_right_active.9.png create mode 100644 res/values-sw720dp-land/dimens.xml create mode 100644 res/values-sw720dp-port/dimens.xml diff --git a/res/drawable-hdpi/page_hover_left.9.png b/res/drawable-hdpi/page_hover_left.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3f11d0b33dd91dcea948106329ccb8964027ee63 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!2%@X47W}MQo5cljv*C{$qY^ZJtk;;kY_fy z!TdF8YQaHeMxlNehdDxvg`TwN&FfI&37E{naNw=uMh4*@d_av1p00i_>zopr0KCr| A?f?J) literal 0 HcmV?d00001 diff --git a/res/drawable-hdpi/page_hover_left_active.9.png b/res/drawable-hdpi/page_hover_left_active.9.png new file mode 100644 index 0000000000000000000000000000000000000000..abe4c31a97611d422a31bc8f32e21b52816d3d44 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!2%@X47W}MQo5cljv*C{$qY^ZJtk;;kY_fy z!TdF8YQaHeMxp!t4Hl|yswX&OZ3JB<7N~JD{4k44oL=#&52%sB)78&qol`;+0Iz%- AzyJUM literal 0 HcmV?d00001 diff --git a/res/drawable-hdpi/page_hover_right.9.png b/res/drawable-hdpi/page_hover_right.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3bcf191958abeea6a7bfd8fd12a00b96714b37bc GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!2%@X47W}MQrey_jv*C{$qr2aCo0q>{Fj$? y__|}F#z%QQ!OjK=p~XT^TJ+v^9OB-f%ETak+3{kiT0$dG8-u5-pUXO@geCx-;v4J$ literal 0 HcmV?d00001 diff --git a/res/drawable-hdpi/page_hover_right_active.9.png b/res/drawable-hdpi/page_hover_right_active.9.png new file mode 100644 index 0000000000000000000000000000000000000000..101e4dc0f69fd7ba51ecb4fda4389205196e7f92 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eQ!2%@X47W}MQrey_jv*C{$qr2aCo0q>{Fj$? y__|}F#z%R*jq;3!DsHMLIAiY!wu&csvoK`##x<61KJE|H#^CAd=d#Wzp$PzY0UGrH literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/page_hover_left.9.png b/res/drawable-mdpi/page_hover_left.9.png new file mode 100644 index 0000000000000000000000000000000000000000..2b6094cf65491623d9208b874f73c9f9cc44b4d4 GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^oIotV!2%@n9Os?@Qd*uajv*C{$qY^Z13JY2xHIwa xIb6+f(sNK;;Gx38r>E$%Jn6H5Tmy#!LrT(&eUWdzTnFl6@O1TaS?83{1OO=C8U+9V literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/page_hover_left_active.9.png b/res/drawable-mdpi/page_hover_left_active.9.png new file mode 100644 index 0000000000000000000000000000000000000000..9eb00a28205b45ae9c0794b0f78e4858be2f036d GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^oIotV!2%@n9Os?@Qd*uajv*C{$qY^Z13JY2xHIwa wIb6+f(sNK;aH5VwCdO%o-_d7^HVlFe3}U;M)@{D+12Tfa)78&qol`;+07cds3jhEB literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/page_hover_right.9.png b/res/drawable-mdpi/page_hover_right.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c2e598351b7498188b4673763b8a2b23af4082d1 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^oIotV!2%@n9Os?@QW~Bvjv*C{$qmi_13I`Z{<$-( vure=M_&;Ew2ZxM~(+t0(&lF`COd}XxX3V&vv{+>uP!EHrtDnm{r-UW|SWg>3 literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/page_hover_right_active.9.png b/res/drawable-mdpi/page_hover_right_active.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d2771a1a54e75c6585d49322ad454a8791f82ca0 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^oIotV!2%@n9Os?@QktGFjv*C{$qmi_13I`Z{<$-( wure=M_&;FbUjd7V7K6E6XPqq=vNkX<_&Y3}vg@08A5as6r>mdKI;Vst0GNdwrvLx| literal 0 HcmV?d00001 diff --git a/res/drawable-xhdpi/page_hover_left.9.png b/res/drawable-xhdpi/page_hover_left.9.png new file mode 100644 index 0000000000000000000000000000000000000000..dbcc0abd2d2bddd7f6c3b0d23c4c784943674afd GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+r!2%@jAN&^xr1U*q978G?lNp-+XH1y&z@G0w z!r2e<^S5v>y`*r{Bg7(Ssr%B*IWss^Q-m1O;+Pr2ebvA5FU_z7YGv?r^>bP0l+XkK Ds+S)e literal 0 HcmV?d00001 diff --git a/res/drawable-xhdpi/page_hover_left_active.9.png b/res/drawable-xhdpi/page_hover_left_active.9.png new file mode 100644 index 0000000000000000000000000000000000000000..3233efe281c4ae0b037eddd77a9e1ffb07f99bc9 GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+r!2%@jAN&^xr1U*q978G?lNp-+XH1y&z@G0w z!r2e<^S5v>y`*sS?}~yOUj1H|Eer*{PN*=P*~7-L{aMsE&W3%{fm#_nUHx3vIVCg! E01<>E8UO$Q literal 0 HcmV?d00001 diff --git a/res/drawable-xhdpi/page_hover_right.9.png b/res/drawable-xhdpi/page_hover_right.9.png new file mode 100644 index 0000000000000000000000000000000000000000..d82f809bfdc67a31e711e57b54f7fef06631013c GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+r!2%@jAN&^xq>MdX978G?lN}iUUsMonI9vaQ zA#0CzU8XtLlK;w{?u!m3YS?P|T5O##SAbP0 Hl+XkK@`fM~ literal 0 HcmV?d00001 diff --git a/res/drawable-xhdpi/page_hover_right_active.9.png b/res/drawable-xhdpi/page_hover_right_active.9.png new file mode 100644 index 0000000000000000000000000000000000000000..819ea195ce9999129d57e97a09489ee3f94c37db GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+r!2%@jAN&^xq>MdX978G?lN}iUUsMonI9vaQ zA#0CzU8XtLlK;w{@7-Gu2ULa3D#%i_))ewN(Zcv{4l9F)Q?$}%o;8br+8I1u{an^L HB{Ts54QC*c literal 0 HcmV?d00001 diff --git a/res/drawable-xxhdpi/page_hover_left.9.png b/res/drawable-xxhdpi/page_hover_left.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c81f86c023ba177be8357e4aea23b206fe5e00c7 GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^VnD3T!2%?&MQ%6@q^vz%978G?lNp-+TPV~XtXE=a z)^8R$T%RPm+)#tx_o%|wi53dW9t9p<+~qFXuO-LGs+@WC$O6_K+0hIRhFhgSO=>m( P8pGh}>gTe~DWM4f#NHxR literal 0 HcmV?d00001 diff --git a/res/drawable-xxhdpi/page_hover_left_active.9.png b/res/drawable-xxhdpi/page_hover_left_active.9.png new file mode 100644 index 0000000000000000000000000000000000000000..858a3b2ab0820fb0416301d1872f4f078c0ca273 GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^VnD3T!2%?&MQ%6@q^vz%978G?lNp-+TPV~XtXE=a z)^8R$T%RPm+)#tx_o%|w--Ql7M;CXwi}q{Dh1xK2xm{Y->BwDheH%k%llm)9A>JuK PV;DSL{an^LB{Ts5!QmnP literal 0 HcmV?d00001 diff --git a/res/drawable-xxhdpi/page_hover_right.9.png b/res/drawable-xxhdpi/page_hover_right.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c5297703e06abe68a15b8e1c00c9a4250b894b8f GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^VnD3T!2%?&MQ%6@q#Qk6978G?lMgWcd)#2cX2i4a zKPU4F=MafY9pP(EO|Uy6^8a{%Os8z07Tck~ql>%TMfrbi>icwP&X%mC0LDjIAqBCFK4%0P#^CAd=d#Wzp$PzcAt^Ng literal 0 HcmV?d00001 diff --git a/res/drawable-xxhdpi/page_hover_right_active.9.png b/res/drawable-xxhdpi/page_hover_right_active.9.png new file mode 100644 index 0000000000000000000000000000000000000000..99005536b2c44ca1f216452d605077db59f7beff GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^VnD3T!2%?&MQ%6@q#Qk6978G?lMgWcd)#2cX2i4a zKPU4F=MafY9pP(EO|Uy6^8a|i9(ik-P@a~>UGAd&T5?}fWuLZMW?ntAfa%E96$~2! WH3Hh2w{idtWAJqKb6Mw<&;$Th6ev&t literal 0 HcmV?d00001 diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml new file mode 100644 index 0000000000..514980fe0b --- /dev/null +++ b/res/values-sw720dp-land/dimens.xml @@ -0,0 +1,21 @@ + + + + + + 100dip + diff --git a/res/values-sw720dp-port/dimens.xml b/res/values-sw720dp-port/dimens.xml new file mode 100644 index 0000000000..6f594d5188 --- /dev/null +++ b/res/values-sw720dp-port/dimens.xml @@ -0,0 +1,22 @@ + + + + + + + 40dp + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 90083c09ce..041b82bf86 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -104,6 +104,10 @@ 14dp 14sp + + 20dp + 12dp diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index 3d3d57dbd5..b09723de5d 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -399,6 +399,10 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { mIsDragTarget = false; } + public boolean isDragTarget() { + return mIsDragTarget; + } + void setIsDragOverlapping(boolean isDragOverlapping) { if (mIsDragOverlapping != isDragOverlapping) { mIsDragOverlapping = isDragOverlapping; @@ -441,6 +445,10 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { (ParcelableSparseArray) parcelable : new ParcelableSparseArray(); } + public boolean getIsDragOverlapping() { + return mIsDragOverlapping; + } + @Override protected void onDraw(Canvas canvas) { if (!mIsDragTarget) { diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java index 1df12084c4..ee9e4f2110 100644 --- a/src/com/android/launcher3/Folder.java +++ b/src/com/android/launcher3/Folder.java @@ -42,7 +42,6 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.animation.AccelerateInterpolator; @@ -950,7 +949,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList @Override public boolean supportsAppInfoDropTarget() { - return true; + return Workspace.IS_SPRING_LOADED; } @Override diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 1eda66df2a..1af2c4fbe2 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1384,6 +1384,7 @@ public class Launcher extends Activity // Setup the drag controller (drop targets have to be added in reverse order in priority) dragController.setDragScoller(mWorkspace); + dragController.setScrollView(mDragLayer); dragController.setMoveTarget(mWorkspace); dragController.addDropTarget(mWorkspace); if (mSearchDropTargetBar != null) { @@ -3488,8 +3489,10 @@ public class Launcher extends Activity mState = State.APPS_SPRING_LOADED; } else if (isWidgetsViewVisible()) { mState = State.WIDGETS_SPRING_LOADED; - } else { + } else if (Workspace.IS_SPRING_LOADED) { mState = State.WORKSPACE_SPRING_LOADED; + } else { + mState = State.WORKSPACE; } } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 0d5bbc11d7..e86758a9e6 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -46,13 +46,10 @@ import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.util.SparseArray; -import android.view.Choreographer; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; import android.widget.TextView; import com.android.launcher3.FolderIcon.FolderRingAnimator; @@ -93,6 +90,7 @@ public class Workspace extends PagedView Insettable, UninstallSource, AccessibilityDragSource, Stats.LaunchSourceProvider { private static final String TAG = "Launcher.Workspace"; + public static final boolean IS_SPRING_LOADED = true; private static boolean ENFORCE_DRAG_EVENT_ORDER = false; private static final int SNAP_OFF_EMPTY_SCREEN_DURATION = 400; @@ -404,8 +402,9 @@ public class Workspace extends PagedView mLauncher.onInteractionEnd(); } - public float getSpringLoadedShrinkFactor() { - return mSpringLoadedShrinkFactor; + /** Returns a scale factor to apply to workspace icons when dragging them from the workspace. */ + public float getDragShrinkFactor() { + return IS_SPRING_LOADED ? mSpringLoadedShrinkFactor : 1f; } /** @@ -2146,7 +2145,9 @@ public class Workspace extends PagedView b.recycle(); - mLauncher.enterSpringLoadedDragMode(); + if (IS_SPRING_LOADED) { + mLauncher.enterSpringLoadedDragMode(); + } } public void beginExternalDragShared(View child, DragSource source) { @@ -2196,7 +2197,9 @@ public class Workspace extends PagedView // Recycle temporary bitmaps tmpB.recycle(); - mLauncher.enterSpringLoadedDragMode(); + if (IS_SPRING_LOADED) { + mLauncher.enterSpringLoadedDragMode(); + } } public boolean transitionStateShouldAllowDrop() { @@ -2635,6 +2638,10 @@ public class Workspace extends PagedView CellLayout layout = getCurrentDropLayout(); setCurrentDropLayout(layout); setCurrentDragOverlappingLayout(layout); + + if (!workspaceInModalState() && !IS_SPRING_LOADED) { + mLauncher.getDragLayer().showPageHints(); + } } @Override @@ -2669,6 +2676,8 @@ public class Workspace extends PagedView setCurrentDragOverlappingLayout(null); mSpringLoadedDragController.cancel(); + + mLauncher.getDragLayer().hidePageHints(); } private void enfoceDragParity(String event, int update, int expectedValue) { @@ -3552,7 +3561,7 @@ public class Workspace extends PagedView @Override public boolean supportsAppInfoDropTarget() { - return true; + return IS_SPRING_LOADED; } @Override diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 13f83a7437..84807cb39c 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -494,6 +494,8 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc // Start the drag mLauncher.getWorkspace().beginDragShared(v, mIconLastTouchPos, this, false); + // Enter spring loaded mode + mLauncher.enterSpringLoadedDragMode(); return false; } diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index d61117c0d8..07775b615b 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -35,7 +35,6 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.inputmethod.InputMethodManager; -import com.android.launcher3.DeleteDropTarget; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget; import com.android.launcher3.ItemInfo; @@ -43,6 +42,7 @@ import com.android.launcher3.Launcher; import com.android.launcher3.PagedView; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; +import com.android.launcher3.Utilities; import com.android.launcher3.accessibility.DragViewStateAnnouncer; import com.android.launcher3.util.Thunk; @@ -81,6 +81,7 @@ public class DragController implements DragDriver.EventListener { // temporaries to avoid gc thrash private Rect mRectTemp = new Rect(); private final int[] mCoordinatesTemp = new int[2]; + private final boolean mIsRtl; /** * Drag driver for the current drag/drop operation, or null if there is no active DND operation. @@ -97,6 +98,11 @@ public class DragController implements DragDriver.EventListener { /** Y coordinate of the down event. */ private int mMotionDownY; + /** the area at the edge of the screen that makes the workspace go left + * or right while you're dragging. + */ + private final int mScrollZone; + private DropTarget.DragObject mDragObject; /** Who can receive drop events */ @@ -107,6 +113,9 @@ public class DragController implements DragDriver.EventListener { /** The window token used as the parent for the DragView. */ private IBinder mWindowToken; + /** The view that will be scrolled when dragging to the left and right edges of the screen. */ + private View mScrollView; + private View mMoveTarget; @Thunk DragScroller mDragScroller; @@ -119,6 +128,7 @@ public class DragController implements DragDriver.EventListener { @Thunk int mLastTouch[] = new int[2]; @Thunk long mLastTouchUpTime = -1; + @Thunk int mDistanceSinceScroll = 0; private int mTmpPoint[] = new int[2]; private Rect mDragLayerRect = new Rect(); @@ -148,15 +158,19 @@ public class DragController implements DragDriver.EventListener { /** * Used to create a new DragLayer from XML. + * + * @param context The application's context. */ public DragController(Launcher launcher) { Resources r = launcher.getResources(); mLauncher = launcher; mHandler = new Handler(); + mScrollZone = r.getDimensionPixelSize(R.dimen.scroll_zone); mVelocityTracker = VelocityTracker.obtain(); mFlingToDeleteThresholdVelocity = r.getDimensionPixelSize(R.dimen.drag_flingToDeleteMinVelocity); + mIsRtl = Utilities.isRtl(r); } /** @@ -231,7 +245,7 @@ public class DragController implements DragDriver.EventListener { mDragObject = new DropTarget.DragObject(); - float finalDragViewScale = mLauncher.getWorkspace().getSpringLoadedShrinkFactor(); + float finalDragViewScale = mLauncher.getWorkspace().getDragShrinkFactor(); final DragView dragView = mDragObject.dragView = new DragView(mLauncher, b, registrationX, registrationY, 0, 0, b.getWidth(), b.getHeight(), initialDragViewScale, finalDragViewScale); @@ -502,6 +516,7 @@ public class DragController implements DragDriver.EventListener { mScrollState = SCROLL_OUTSIDE_ZONE; mScrollRunnable.setDirection(SCROLL_RIGHT); mDragScroller.onExitScrollArea(); + mLauncher.getDragLayer().onExitScrollArea(); } } @@ -515,8 +530,11 @@ public class DragController implements DragDriver.EventListener { mDragObject.y = coordinates[1]; checkTouchMove(dropTarget); + // Check if we are hovering over the scroll areas + mDistanceSinceScroll += Math.hypot(mLastTouch[0] - x, mLastTouch[1] - y); mLastTouch[0] = x; mLastTouch[1] = y; + checkScrollState(x, y); } public void forceTouchMove() { @@ -544,6 +562,36 @@ public class DragController implements DragDriver.EventListener { mLastDropTarget = dropTarget; } + @Thunk void checkScrollState(int x, int y) { + final int slop = ViewConfiguration.get(mLauncher).getScaledWindowTouchSlop(); + final int delay = mDistanceSinceScroll < slop ? RESCROLL_DELAY : SCROLL_DELAY; + final DragLayer dragLayer = mLauncher.getDragLayer(); + final int forwardDirection = mIsRtl ? SCROLL_RIGHT : SCROLL_LEFT; + final int backwardsDirection = mIsRtl ? SCROLL_LEFT : SCROLL_RIGHT; + + if (x < mScrollZone) { + if (mScrollState == SCROLL_OUTSIDE_ZONE) { + mScrollState = SCROLL_WAITING_IN_ZONE; + if (mDragScroller.onEnterScrollArea(x, y, forwardDirection)) { + dragLayer.onEnterScrollArea(forwardDirection); + mScrollRunnable.setDirection(forwardDirection); + mHandler.postDelayed(mScrollRunnable, delay); + } + } + } else if (x > mScrollView.getWidth() - mScrollZone) { + if (mScrollState == SCROLL_OUTSIDE_ZONE) { + mScrollState = SCROLL_WAITING_IN_ZONE; + if (mDragScroller.onEnterScrollArea(x, y, backwardsDirection)) { + dragLayer.onEnterScrollArea(backwardsDirection); + mScrollRunnable.setDirection(backwardsDirection); + mHandler.postDelayed(mScrollRunnable, delay); + } + } + } else { + clearScrollRunnable(); + } + } + /** * Call this from a drag source view. */ @@ -565,6 +613,13 @@ public class DragController implements DragDriver.EventListener { // Remember where the motion event started mMotionDownX = dragLayerX; mMotionDownY = dragLayerY; + + if ((dragLayerX < mScrollZone) || (dragLayerX > mScrollView.getWidth() - mScrollZone)) { + mScrollState = SCROLL_WAITING_IN_ZONE; + mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY); + } else { + mScrollState = SCROLL_OUTSIDE_ZONE; + } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: @@ -757,6 +812,13 @@ public class DragController implements DragDriver.EventListener { } } + /** + * Set which view scrolls for touch events near the edge of the screen. + */ + public void setScrollView(View v) { + mScrollView = v; + } + private class ScrollRunnable implements Runnable { private int mDirection; @@ -771,7 +833,14 @@ public class DragController implements DragDriver.EventListener { mDragScroller.scrollRight(); } mScrollState = SCROLL_OUTSIDE_ZONE; + mDistanceSinceScroll = 0; mDragScroller.onExitScrollArea(); + mLauncher.getDragLayer().onExitScrollArea(); + + if (isDragging()) { + // Check the scroll again so that we can requeue the scroller if necessary + checkScrollState(mLastTouch[0], mLastTouch[1]); + } } } diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 1fcb5234e1..ded7fae379 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -102,6 +102,15 @@ public class DragLayer extends InsettableFrameLayout { // Darkening scrim private float mBackgroundAlpha = 0; + // Related to adjacent page hints + private final Rect mScrollChildPosition = new Rect(); + private boolean mInScrollArea; + private boolean mShowPageHints; + private Drawable mLeftHoverDrawable; + private Drawable mRightHoverDrawable; + private Drawable mLeftHoverDrawableActive; + private Drawable mRightHoverDrawableActive; + private boolean mBlockTouches = false; /** @@ -117,7 +126,12 @@ public class DragLayer extends InsettableFrameLayout { setMotionEventSplittingEnabled(false); setChildrenDrawingOrderEnabled(true); - mIsRtl = Utilities.isRtl(getResources()); + final Resources res = getResources(); + mLeftHoverDrawable = res.getDrawable(R.drawable.page_hover_left); + mRightHoverDrawable = res.getDrawable(R.drawable.page_hover_right); + mLeftHoverDrawableActive = res.getDrawable(R.drawable.page_hover_left_active); + mRightHoverDrawableActive = res.getDrawable(R.drawable.page_hover_right_active); + mIsRtl = Utilities.isRtl(res); } public void setup(Launcher launcher, DragController controller) { @@ -883,6 +897,29 @@ public class DragLayer extends InsettableFrameLayout { } } + void onEnterScrollArea(int direction) { + mInScrollArea = true; + invalidate(); + } + + void onExitScrollArea() { + mInScrollArea = false; + invalidate(); + } + + public void showPageHints() { + mShowPageHints = true; + Workspace workspace = mLauncher.getWorkspace(); + getDescendantRectRelativeToSelf(workspace.getChildAt(workspace.numCustomPages()), + mScrollChildPosition); + invalidate(); + } + + public void hidePageHints() { + mShowPageHints = false; + invalidate(); + } + @Override protected void dispatchDraw(Canvas canvas) { // Draw the background below children. @@ -894,6 +931,41 @@ public class DragLayer extends InsettableFrameLayout { super.dispatchDraw(canvas); } + private void drawPageHints(Canvas canvas) { + if (mShowPageHints) { + Workspace workspace = mLauncher.getWorkspace(); + int width = getMeasuredWidth(); + int page = workspace.getNextPage(); + CellLayout leftPage = (CellLayout) workspace.getChildAt(mIsRtl ? page + 1 : page - 1); + CellLayout rightPage = (CellLayout) workspace.getChildAt(mIsRtl ? page - 1 : page + 1); + + if (leftPage != null && leftPage.isDragTarget()) { + Drawable left = mInScrollArea && leftPage.getIsDragOverlapping() ? + mLeftHoverDrawableActive : mLeftHoverDrawable; + left.setBounds(0, mScrollChildPosition.top, + left.getIntrinsicWidth(), mScrollChildPosition.bottom); + left.draw(canvas); + } + if (rightPage != null && rightPage.isDragTarget()) { + Drawable right = mInScrollArea && rightPage.getIsDragOverlapping() ? + mRightHoverDrawableActive : mRightHoverDrawable; + right.setBounds(width - right.getIntrinsicWidth(), + mScrollChildPosition.top, width, mScrollChildPosition.bottom); + right.draw(canvas); + } + } + } + + protected boolean drawChild(Canvas canvas, View child, long drawingTime) { + boolean ret = super.drawChild(canvas, child, drawingTime); + + // We want to draw the page hints above the workspace, but below the drag view. + if (child instanceof Workspace) { + drawPageHints(canvas); + } + return ret; + } + public void setBackgroundAlpha(float alpha) { if (alpha != mBackgroundAlpha) { mBackgroundAlpha = alpha;