Taskbar drag starts internal pre-drag before system drag

- TaskbarDragController now extends DragController.
- Currently there is no pre-drag condition, so we immediately get onDragStart(), which starts the system global drag (which cancels the original internal drag).
- Make the original view invisible during the drag and drop operation, across both internal and system drag events.
- No longer handle onDragEvent() in TaskbarView, as TaskbarDragController handles all of it now.

Test: Drag and drop from taskbar still works (bonus: starts from the correct registration point that you touched down on). Locally added a PreDragCondition and verified a seamless handoff to system drag and drop when the pre drag end condition was met.
Bug: 182981908
Change-Id: I6bf48141a5eedfc6db6f461258e880ef8146e733
This commit is contained in:
Tony Wickham
2021-05-25 15:35:58 -07:00
parent c7cbf254f3
commit 8ac277ebd8
10 changed files with 381 additions and 118 deletions
@@ -222,7 +222,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
}
public boolean isDraggingItem() {
return mTaskbarView.isDraggingItem();
return mContext.getDragController().isDragging();
}
/**
@@ -28,9 +28,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Process;
import android.os.SystemProperties;
import android.util.Log;
@@ -43,22 +41,14 @@ import android.view.WindowManager;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
import com.android.launcher3.touch.ItemClickHandler;
@@ -89,10 +79,13 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
private final LayoutInflater mLayoutInflater;
private final TaskbarDragLayer mDragLayer;
private final TaskbarIconController mIconController;
private final MyDragController mDragController;
private final TaskbarDragController mDragController;
private final WindowManager mWindowManager;
private WindowManager.LayoutParams mWindowLayoutParams;
private boolean mIsFullscreen;
// The size we should return to when we call setTaskbarWindowFullscreen(false)
private int mLastRequestedNonFullscreenHeight;
private final SysUINavigationMode.Mode mNavMode;
private final TaskbarNavButtonController mNavButtonController;
@@ -114,8 +107,8 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
() -> getPackageManager().isSafeMode());
mOnTaskbarIconLongClickListener =
new TaskbarDragController(this)::startSystemDragOnLongClick;
mDragController = new TaskbarDragController(this);
mOnTaskbarIconLongClickListener = mDragController::startDragOnLongClick;
mOnTaskbarIconClickListener = this::onTaskbarIconClicked;
float taskbarIconSize = getResources().getDimension(R.dimen.taskbar_icon_size);
@@ -126,7 +119,6 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
mDragLayer = (TaskbarDragLayer) mLayoutInflater
.inflate(R.layout.taskbar, null, false);
mIconController = new TaskbarIconController(this, mDragLayer);
mDragController = new MyDragController(this);
Display display = windowContext.getDisplay();
Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
@@ -136,9 +128,10 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
}
public void init() {
mLastRequestedNonFullscreenHeight = mDeviceProfile.taskbarSize;
mWindowLayoutParams = new WindowManager.LayoutParams(
MATCH_PARENT,
mDeviceProfile.taskbarSize,
mLastRequestedNonFullscreenHeight,
TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
@@ -160,17 +153,6 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
mWindowManager.addView(mDragLayer, mWindowLayoutParams);
}
/**
* Updates the TaskbarContainer height (pass deviceProfile.taskbarSize to reset).
*/
public void setTaskbarWindowHeight(int height) {
if (mWindowLayoutParams.height == height) {
return;
}
mWindowLayoutParams.height = height;
mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
}
public boolean canShowNavButtons() {
return ENABLE_THREE_BUTTON_TASKBAR && mNavMode == Mode.THREE_BUTTONS;
}
@@ -196,7 +178,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
}
@Override
public DragController getDragController() {
public TaskbarDragController getDragController() {
return mDragController;
}
@@ -243,8 +225,30 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
/**
* Updates the TaskbarContainer to MATCH_PARENT vs original Taskbar size.
*/
protected void setTaskbarWindowFullscreen(boolean fullscreen) {
setTaskbarWindowHeight(fullscreen ? MATCH_PARENT : getDeviceProfile().taskbarSize);
public void setTaskbarWindowFullscreen(boolean fullscreen) {
mIsFullscreen = fullscreen;
setTaskbarWindowHeight(fullscreen ? MATCH_PARENT : mLastRequestedNonFullscreenHeight);
}
/**
* Updates the TaskbarContainer height (pass deviceProfile.taskbarSize to reset).
*/
public void setTaskbarWindowHeight(int height) {
if (mWindowLayoutParams.height == height) {
return;
}
if (height != MATCH_PARENT) {
mLastRequestedNonFullscreenHeight = height;
if (mIsFullscreen) {
// We still need to be fullscreen, so defer any change to our height until we call
// setTaskbarWindowFullscreen(false). For example, this could happen when dragging
// from the gesture region, as the drag will cancel the gesture and reset launcher's
// state, which in turn normally would reset the taskbar window height as well.
return;
}
}
mWindowLayoutParams.height = height;
mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
}
protected void onTaskbarIconClicked(View view) {
@@ -309,27 +313,4 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
AbstractFloatingView.closeAllOpenViews(this);
}
private static class MyDragController extends DragController<TaskbarActivityContext> {
MyDragController(TaskbarActivityContext activity) {
super(activity);
}
@Override
protected DragView startDrag(@Nullable Drawable drawable, @Nullable View view,
DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source,
ItemInfo dragInfo, Point dragOffset, Rect dragRegion, float initialDragViewScale,
float dragViewScaleOnDrop, DragOptions options) {
return null;
}
@Override
protected void exitDrag() {
}
@Override
protected DropTarget getDefaultDropTarget(int[] dropCoordinates) {
return null;
}
}
}
@@ -20,19 +20,35 @@ import static android.view.View.VISIBLE;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragDriver;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ClipDescriptionCompat;
@@ -41,14 +57,20 @@ import com.android.systemui.shared.system.LauncherAppsCompat;
/**
* Handles long click on Taskbar items to start a system drag and drop operation.
*/
public class TaskbarDragController {
public class TaskbarDragController extends DragController<TaskbarActivityContext> {
private final Context mContext;
private final int mDragIconSize;
private final int[] mTempXY = new int[2];
public TaskbarDragController(Context context) {
mContext = context;
Resources resources = mContext.getResources();
// Where the initial touch was relative to the dragged icon.
private int mRegistrationX;
private int mRegistrationY;
private boolean mIsSystemDragInProgress;
public TaskbarDragController(TaskbarActivityContext activity) {
super(activity);
Resources resources = mActivity.getResources();
mDragIconSize = resources.getDimensionPixelSize(R.dimen.taskbar_icon_drag_icon_size);
}
@@ -57,18 +79,146 @@ public class TaskbarDragController {
* generate the ClipDescription and Intent.
* @return Whether {@link View#startDragAndDrop} started successfully.
*/
protected boolean startSystemDragOnLongClick(View view) {
protected boolean startDragOnLongClick(View view) {
if (!(view instanceof BubbleTextView)) {
return false;
}
BubbleTextView btv = (BubbleTextView) view;
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view) {
mActivity.setTaskbarWindowFullscreen(true);
view.post(() -> {
startInternalDrag(btv);
btv.setVisibility(INVISIBLE);
});
return true;
}
private void startInternalDrag(BubbleTextView btv) {
float iconScale = 1f;
Drawable icon = btv.getIcon();
if (icon instanceof FastBitmapDrawable) {
iconScale = ((FastBitmapDrawable) icon).getAnimatedScale();
}
// Clear the pressed state if necessary
btv.clearFocus();
btv.setPressed(false);
btv.clearPressedBackground();
final DragPreviewProvider previewProvider = new DragPreviewProvider(btv);
final Drawable drawable = previewProvider.createDrawable();
final float scale = previewProvider.getScaleAndPosition(drawable, mTempXY);
int dragLayerX = mTempXY[0];
int dragLayerY = mTempXY[1];
Rect dragRect = new Rect();
btv.getSourceVisualDragBounds(dragRect);
dragLayerY += dragRect.top;
DragOptions dragOptions = new DragOptions();
// TODO: open popup/pre-drag
// PopupContainerWithArrow popupContainer = PopupContainerWithArrow.showForIcon(view);
// if (popupContainer != null) {
// dragOptions.preDragCondition = popupContainer.createPreDragCondition();
// }
startDrag(
drawable,
/* view = */ null,
/* originalView = */ btv,
dragLayerX,
dragLayerY,
(View target, DropTarget.DragObject d, boolean success) -> {} /* DragSource */,
(WorkspaceItemInfo) btv.getTag(),
/* dragVisualizeOffset = */ null,
dragRect,
scale * iconScale,
scale,
dragOptions);
}
@Override
protected DragView startDrag(@Nullable Drawable drawable, @Nullable View view,
DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source,
ItemInfo dragInfo, Point dragOffset, Rect dragRegion, float initialDragViewScale,
float dragViewScaleOnDrop, DragOptions options) {
mOptions = options;
mRegistrationX = mMotionDown.x - dragLayerX;
mRegistrationY = mMotionDown.y - dragLayerY;
final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left;
final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top;
mLastDropTarget = null;
mDragObject = new DropTarget.DragObject(mActivity.getApplicationContext());
mDragObject.originalView = originalView;
mIsInPreDrag = mOptions.preDragCondition != null
&& !mOptions.preDragCondition.shouldStartDrag(0);
float scalePx = mDragIconSize - dragRegion.width();
final DragView dragView = mDragObject.dragView = new TaskbarDragView(
mActivity,
drawable,
mRegistrationX,
mRegistrationY,
initialDragViewScale,
dragViewScaleOnDrop,
scalePx);
dragView.setItemInfo(dragInfo);
mDragObject.dragComplete = false;
mDragObject.xOffset = mMotionDown.x - (dragLayerX + dragRegionLeft);
mDragObject.yOffset = mMotionDown.y - (dragLayerY + dragRegionTop);
mDragDriver = DragDriver.create(this, mOptions, /* secondaryEventConsumer = */ ev -> {});
if (!mOptions.isAccessibleDrag) {
mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
}
mDragObject.dragSource = source;
mDragObject.dragInfo = dragInfo;
mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy();
if (dragRegion != null) {
dragView.setDragRegion(new Rect(dragRegion));
}
dragView.show(mLastTouch.x, mLastTouch.y);
mDistanceSinceScroll = 0;
if (!mIsInPreDrag) {
callOnDragStart();
} else if (mOptions.preDragCondition != null) {
mOptions.preDragCondition.onPreDragStart(mDragObject);
}
handleMoveEvent(mLastTouch.x, mLastTouch.y);
return dragView;
}
@Override
protected void callOnDragStart() {
super.callOnDragStart();
// Pre-drag has ended, start the global system drag.
AbstractFloatingView.closeAllOpenViews(mActivity);
startSystemDrag((BubbleTextView) mDragObject.originalView);
}
private void startSystemDrag(BubbleTextView btv) {
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(btv) {
@Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
shadowSize.set(mDragIconSize, mDragIconSize);
// TODO: should be based on last touch point on the icon.
shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
// The registration point was taken before the icon scaled to mDragIconSize, so
// offset the registration to where the touch is on the new size.
int offset = (mDragIconSize - btv.getIconSize()) / 2;
shadowTouchPoint.set(mRegistrationX + offset, mRegistrationY + offset);
}
@Override
@@ -81,12 +231,12 @@ public class TaskbarDragController {
}
};
Object tag = view.getTag();
Object tag = btv.getTag();
ClipDescription clipDescription = null;
Intent intent = null;
if (tag instanceof WorkspaceItemInfo) {
WorkspaceItemInfo item = (WorkspaceItemInfo) tag;
LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
LauncherApps launcherApps = mActivity.getSystemService(LauncherApps.class);
clipDescription = new ClipDescription(item.title,
new String[] {
item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
@@ -116,28 +266,89 @@ public class TaskbarDragController {
if (clipDescription != null && intent != null) {
ClipData clipData = new ClipData(clipDescription, new ClipData.Item(intent));
view.setOnDragListener(getDraggedViewDragListener());
return view.startDragAndDrop(clipData, shadowBuilder, null /* localState */,
View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_OPAQUE);
if (btv.startDragAndDrop(clipData, shadowBuilder, null /* localState */,
View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_OPAQUE)) {
onSystemDragStarted();
}
}
return false;
}
/**
* Hide the original Taskbar item while it is being dragged.
*/
private View.OnDragListener getDraggedViewDragListener() {
return (view, dragEvent) -> {
private void onSystemDragStarted() {
mIsSystemDragInProgress = true;
mActivity.getDragLayer().setOnDragListener((view, dragEvent) -> {
switch (dragEvent.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
view.setVisibility(INVISIBLE);
// Return true to tell system we are interested in events, so we get DRAG_ENDED.
return true;
case DragEvent.ACTION_DRAG_ENDED:
view.setVisibility(VISIBLE);
view.setOnDragListener(null);
mIsSystemDragInProgress = false;
maybeOnDragEnd();
return true;
}
return false;
};
});
}
@Override
public boolean isDragging() {
return super.isDragging() || mIsSystemDragInProgress;
}
/**
* Whether we started dragging the given view and the drag is still in progress.
*/
public boolean isDraggingView(View child) {
return isDragging() && mDragObject != null && mDragObject.originalView == child;
}
private void maybeOnDragEnd() {
if (!isDragging()) {
((View) mDragObject.originalView).setVisibility(VISIBLE);
}
}
@Override
protected void callOnDragEnd() {
super.callOnDragEnd();
maybeOnDragEnd();
}
@Override
protected float getX(MotionEvent ev) {
// We will resize to fill the screen while dragging, so use screen coordinates. This ensures
// we start at the correct position even though touch down is on the smaller DragLayer size.
return ev.getRawX();
}
@Override
protected float getY(MotionEvent ev) {
// We will resize to fill the screen while dragging, so use screen coordinates. This ensures
// we start at the correct position even though touch down is on the smaller DragLayer size.
return ev.getRawY();
}
@Override
protected Point getClampedDragLayerPos(float x, float y) {
// No need to clamp, as we will take up the entire screen.
mTmpPoint.set(Math.round(x), Math.round(y));
return mTmpPoint;
}
@Override
protected void exitDrag() {
if (mDragObject != null) {
mActivity.getDragLayer().removeView(mDragObject.dragView);
}
}
@Override
public void addDropTarget(DropTarget target) {
// No-op as Taskbar currently doesn't support any drop targets internally.
// Note: if we do add internal DropTargets, we'll still need to ignore Folder.
}
@Override
protected DropTarget getDefaultDropTarget(int[] dropCoordinates) {
return null;
}
}
@@ -40,7 +40,7 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
private final int mFolderMargin;
private final Paint mTaskbarBackgroundPaint;
private TaskbarIconController.Callbacks mControllerCallbacks;
private TaskbarIconController.TaskbarDragLayerCallbacks mControllerCallbacks;
private TaskbarView mTaskbarView;
private final OnComputeInsetsListener mTaskbarInsetsComputer = this::onComputeTaskbarInsets;
@@ -69,10 +69,11 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
@Override
public void recreateControllers() {
mControllers = new TouchController[0];
mControllers = new TouchController[] {mActivity.getDragController()};
}
public void init(TaskbarIconController.Callbacks callbacks, TaskbarView taskbarView) {
public void init(TaskbarIconController.TaskbarDragLayerCallbacks callbacks,
TaskbarView taskbarView) {
mControllerCallbacks = callbacks;
mTaskbarView = taskbarView;
}
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2021 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.taskbar;
import android.graphics.drawable.Drawable;
import com.android.launcher3.R;
import com.android.launcher3.dragndrop.DragView;
/**
* A DragView drawn/used by the Taskbar. Note that this is only for the internal drag-and-drop,
* while the pre-drag is still in progress (i.e. when the long press popup is still open). After
* that ends, we switch to a system drag and drop view instead.
*/
public class TaskbarDragView extends DragView<TaskbarActivityContext> {
public TaskbarDragView(TaskbarActivityContext launcher, Drawable drawable, int registrationX,
int registrationY, float initialScale, float scaleOnDrop, float finalScaleDps) {
super(launcher, drawable, registrationX, registrationY, initialScale, scaleOnDrop,
finalScaleDps);
}
@Override
public void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable, int duration) {
Runnable onAnimationEnd = () -> {
if (onCompleteRunnable != null) {
onCompleteRunnable.run();
}
mActivity.getDragLayer().removeView(this);
};
duration = Math.max(duration,
getResources().getInteger(R.integer.config_dropAnimMinDuration));
animate()
.translationX(toTouchX - mRegistrationX)
.translationY(toTouchY - mRegistrationY)
.scaleX(mScaleOnDrop)
.scaleY(mScaleOnDrop)
.withEndAction(onAnimationEnd)
.setDuration(duration)
.start();
}
}
@@ -62,10 +62,11 @@ public class TaskbarIconController {
ButtonProvider buttonProvider = new ButtonProvider(mActivity);
mImeBarView.init(buttonProvider);
mTaskbarView.construct(clickListener, longClickListener, buttonProvider);
mTaskbarView.init(new TaskbarViewCallbacks(), clickListener, longClickListener,
buttonProvider);
mTaskbarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
mDragLayer.init(new Callbacks(), mTaskbarView);
mDragLayer.init(new TaskbarDragLayerCallbacks(), mTaskbarView);
}
public void onDestroy() {
@@ -102,7 +103,7 @@ public class TaskbarIconController {
/**
* Callbacks for {@link TaskbarDragLayer} to interact with the icon controller
*/
public class Callbacks {
public class TaskbarDragLayerCallbacks {
/**
* Called to update the touchable insets
@@ -160,4 +161,16 @@ public class TaskbarIconController {
mImeBarView.setVisibility(alpha == 0 ? GONE : VISIBLE);
}
}
/**
* Callbacks for {@link TaskbarView} to interact with the icon controller
*/
public class TaskbarViewCallbacks {
/**
* Returns whether no other controller is currently handling the given View's visibility.
*/
public boolean canUpdateViewVisibility(View child) {
return !mActivity.getDragController().isDraggingView(child);
}
}
}
@@ -24,7 +24,6 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.DragEvent;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@@ -35,7 +34,6 @@ import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
@@ -62,7 +60,8 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa
private final TaskbarActivityContext mActivityContext;
// Initialized in TaskbarController constructor.
// Initialized in init.
private TaskbarIconController.TaskbarViewCallbacks mControllerCallbacks;
private View.OnClickListener mIconClickListener;
private View.OnLongClickListener mIconLongClickListener;
@@ -75,7 +74,6 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa
// Prevents dispatching touches to children if true
private boolean mTouchEnabled = true;
private boolean mIsDraggingItem;
// Only non-null when the corresponding Folder is open.
private @Nullable FolderIcon mLeaveBehindFolderIcon;
@@ -118,8 +116,10 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa
mHotseatIconsContainer = findViewById(R.id.hotseat_icons_layout);
}
protected void construct(OnClickListener clickListener, OnLongClickListener longClickListener,
ButtonProvider buttonProvider) {
protected void init(TaskbarIconController.TaskbarViewCallbacks callbacks,
OnClickListener clickListener, OnLongClickListener longClickListener,
ButtonProvider buttonProvider) {
mControllerCallbacks = callbacks;
mIconClickListener = clickListener;
mIconLongClickListener = longClickListener;
mButtonProvider = buttonProvider;
@@ -225,6 +225,9 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa
}
private void updateHotseatItemVisibility(View hotseatView) {
if (!mControllerCallbacks.canUpdateViewVisibility(hotseatView)) {
return;
}
hotseatView.setVisibility(
hotseatView.getTag() != null ? VISIBLE : (mAreHolesAllowed ? INVISIBLE : GONE));
}
@@ -349,24 +352,6 @@ public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconPa
mSystemButtonContainer.addView(mButtonProvider.getRecents(), buttonParams);
}
@Override
public boolean onDragEvent(DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
mIsDraggingItem = true;
AbstractFloatingView.closeAllOpenViews(mActivityContext);
return true;
case DragEvent.ACTION_DRAG_ENDED:
mIsDraggingItem = false;
break;
}
return super.onDragEvent(event);
}
public boolean isDraggingItem() {
return mIsDraggingItem;
}
/**
* @return The bounding box of where the hotseat elements are relative to this TaskbarView.
*/
@@ -413,7 +413,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
}
void clearPressedBackground() {
public void clearPressedBackground() {
setPressed(false);
setStayPressed(false);
}
@@ -859,8 +859,9 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
switch (display) {
case DISPLAY_ALL_APPS:
return grid.allAppsIconSizePx;
case DISPLAY_WORKSPACE:
case DISPLAY_FOLDER:
return grid.folderChildIconSizePx;
case DISPLAY_WORKSPACE:
default:
return grid.iconSizePx;
}
@@ -74,7 +74,7 @@ public abstract class DragController<T extends ActivityContext>
/** Coordinate for last touch event **/
protected final Point mLastTouch = new Point();
private final Point mTmpPoint = new Point();
protected final Point mTmpPoint = new Point();
protected DropTarget.DragObject mDragObject;
@@ -317,7 +317,7 @@ public abstract class DragController<T extends ActivityContext>
mDragObject.dragView.animateTo(mMotionDown.x, mMotionDown.y, onCompleteRunnable, duration);
}
private void callOnDragEnd() {
protected void callOnDragEnd() {
if (mIsInPreDrag && mOptions.preDragCondition != null) {
mOptions.preDragCondition.onPreDragEnd(mDragObject, false /* dragStarted*/);
}
@@ -343,7 +343,7 @@ public abstract class DragController<T extends ActivityContext>
/**
* Clamps the position to the drag layer bounds.
*/
private Point getClampedDragLayerPos(float x, float y) {
protected Point getClampedDragLayerPos(float x, float y) {
mActivity.getDragLayer().getLocalVisibleRect(mRectTemp);
mTmpPoint.x = (int) Math.max(mRectTemp.left, Math.min(x, mRectTemp.right - 1));
mTmpPoint.y = (int) Math.max(mRectTemp.top, Math.min(y, mRectTemp.bottom - 1));
@@ -390,7 +390,7 @@ public abstract class DragController<T extends ActivityContext>
return false;
}
Point dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY());
Point dragLayerPos = getClampedDragLayerPos(getX(ev), getY(ev));
mLastTouch.set(dragLayerPos.x, dragLayerPos.y);
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
// Remember location of down touch
@@ -403,6 +403,14 @@ public abstract class DragController<T extends ActivityContext>
return mDragDriver != null && mDragDriver.onInterceptTouchEvent(ev);
}
protected float getX(MotionEvent ev) {
return ev.getX();
}
protected float getY(MotionEvent ev) {
return ev.getY();
}
/**
* Call this from a drag source view.
*/
@@ -165,8 +165,11 @@ public abstract class DragDriver {
* Class for driving an internal (i.e. not using framework) drag/drop operation.
*/
static class InternalDragDriver extends DragDriver {
private final DragController mDragController;
InternalDragDriver(DragController dragController, Consumer<MotionEvent> sec) {
super(dragController, sec);
mDragController = dragController;
}
@Override
@@ -176,11 +179,14 @@ public abstract class DragDriver {
switch (action) {
case MotionEvent.ACTION_MOVE:
mEventListener.onDriverDragMove(ev.getX(), ev.getY());
mEventListener.onDriverDragMove(mDragController.getX(ev),
mDragController.getY(ev));
break;
case MotionEvent.ACTION_UP:
mEventListener.onDriverDragMove(ev.getX(), ev.getY());
mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
mEventListener.onDriverDragMove(mDragController.getX(ev),
mDragController.getY(ev));
mEventListener.onDriverDragEnd(mDragController.getX(ev),
mDragController.getY(ev));
break;
case MotionEvent.ACTION_CANCEL:
mEventListener.onDriverDragCancel();
@@ -197,7 +203,8 @@ public abstract class DragDriver {
switch (action) {
case MotionEvent.ACTION_UP:
mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
mEventListener.onDriverDragEnd(mDragController.getX(ev),
mDragController.getY(ev));
break;
case MotionEvent.ACTION_CANCEL:
mEventListener.onDriverDragCancel();