use of com.android.launcher3.CellLayout in project android_packages_apps_Launcher3 by AOSPA.
the class Workspace method animateWidgetDrop.
public void animateWidgetDrop(ItemInfo info, CellLayout cellLayout, final DragView dragView, final Runnable onCompleteRunnable, int animationType, final View finalView, boolean external) {
int[] finalPos = new int[2];
float[] scaleXY = new float[2];
boolean scalePreview = !(info instanceof PendingAddShortcutInfo);
getFinalPositionForDropAnimation(finalPos, scaleXY, dragView, cellLayout, info, mTargetCell, scalePreview);
Resources res = mLauncher.getResources();
final int duration = res.getInteger(R.integer.config_dropAnimMaxDuration) - 200;
boolean isWidget = info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
if ((animationType == ANIMATE_INTO_POSITION_AND_RESIZE || external) && finalView != null && dragView.getContentView() != finalView) {
Drawable crossFadeDrawable = createWidgetDrawable(info, finalView);
dragView.crossFadeContent(crossFadeDrawable, (int) (duration * 0.8f));
} else if (isWidget && external) {
scaleXY[0] = scaleXY[1] = Math.min(scaleXY[0], scaleXY[1]);
}
DragLayer dragLayer = mLauncher.getDragLayer();
if (animationType == CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION) {
mLauncher.getDragLayer().animateViewIntoPosition(dragView, finalPos, 0f, 0.1f, 0.1f, DragLayer.ANIMATION_END_DISAPPEAR, onCompleteRunnable, duration);
} else {
int endStyle;
if (animationType == ANIMATE_INTO_POSITION_AND_REMAIN) {
endStyle = DragLayer.ANIMATION_END_REMAIN_VISIBLE;
} else {
endStyle = DragLayer.ANIMATION_END_DISAPPEAR;
}
Runnable onComplete = new Runnable() {
@Override
public void run() {
if (finalView != null) {
finalView.setVisibility(VISIBLE);
}
if (onCompleteRunnable != null) {
onCompleteRunnable.run();
}
}
};
dragLayer.animateViewIntoPosition(dragView, finalPos[0], finalPos[1], 1, scaleXY[0], scaleXY[1], onComplete, endStyle, duration, this);
}
}
use of com.android.launcher3.CellLayout in project android_packages_apps_Launcher3 by AOSPA.
the class Workspace method acceptDrop.
/**
* {@inheritDoc}
*/
@Override
public boolean acceptDrop(DragObject d) {
// If it's an external drop (e.g. from All Apps), check if it should be accepted
CellLayout dropTargetLayout = mDropToLayout;
if (d.dragSource != this) {
// Don't accept the drop if we're not over a screen at time of drop
if (dropTargetLayout == null) {
return false;
}
if (!transitionStateShouldAllowDrop())
return false;
mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);
// We want the point to be mapped to the dragTarget.
mapPointFromDropLayout(dropTargetLayout, mDragViewVisualCenter);
int spanX;
int spanY;
if (mDragInfo != null) {
final CellLayout.CellInfo dragCellInfo = mDragInfo;
spanX = dragCellInfo.spanX;
spanY = dragCellInfo.spanY;
} else {
spanX = d.dragInfo.spanX;
spanY = d.dragInfo.spanY;
}
int minSpanX = spanX;
int minSpanY = spanY;
if (d.dragInfo instanceof PendingAddWidgetInfo) {
minSpanX = ((PendingAddWidgetInfo) d.dragInfo).minSpanX;
minSpanY = ((PendingAddWidgetInfo) d.dragInfo).minSpanY;
}
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], minSpanX, minSpanY, dropTargetLayout, mTargetCell);
float distance = dropTargetLayout.getDistanceFromWorkspaceCellVisualCenter(mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
if (mCreateUserFolderOnDrop && willCreateUserFolder(d.dragInfo, dropTargetLayout, mTargetCell, distance, true)) {
return true;
}
if (mAddToExistingFolderOnDrop && willAddToExistingUserFolder(d.dragInfo, dropTargetLayout, mTargetCell, distance)) {
return true;
}
int[] resultSpan = new int[2];
mTargetCell = dropTargetLayout.performReorder((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY, null, mTargetCell, resultSpan, CellLayout.MODE_ACCEPT_DROP);
boolean foundCell = mTargetCell[0] >= 0 && mTargetCell[1] >= 0;
// Don't accept the drop if there's no room for the item
if (!foundCell) {
onNoCellFound(dropTargetLayout, d.dragInfo, d.logInstanceId);
return false;
}
}
int screenId = getIdForScreen(dropTargetLayout);
if (Workspace.EXTRA_EMPTY_SCREEN_IDS.contains(screenId)) {
commitExtraEmptyScreens();
}
return true;
}
use of com.android.launcher3.CellLayout in project android_packages_apps_Launcher3 by AOSPA.
the class Workspace method onDrop.
@Override
public void onDrop(final DragObject d, DragOptions options) {
mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);
CellLayout dropTargetLayout = mDropToLayout;
// We want the point to be mapped to the dragTarget.
if (dropTargetLayout != null) {
mapPointFromDropLayout(dropTargetLayout, mDragViewVisualCenter);
}
boolean droppedOnOriginalCell = false;
boolean snappedToNewPage = false;
boolean resizeOnDrop = false;
Runnable onCompleteRunnable = null;
if (d.dragSource != this || mDragInfo == null) {
final int[] touchXY = new int[] { (int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1] };
onDropExternal(touchXY, dropTargetLayout, d);
} else {
final View cell = mDragInfo.cell;
boolean droppedOnOriginalCellDuringTransition = false;
if (dropTargetLayout != null && !d.cancelled) {
// Move internally
boolean hasMovedLayouts = (getParentCellLayoutForView(cell) != dropTargetLayout);
boolean hasMovedIntoHotseat = mLauncher.isHotseatLayout(dropTargetLayout);
int container = hasMovedIntoHotseat ? LauncherSettings.Favorites.CONTAINER_HOTSEAT : LauncherSettings.Favorites.CONTAINER_DESKTOP;
int screenId = (mTargetCell[0] < 0) ? mDragInfo.screenId : getIdForScreen(dropTargetLayout);
int spanX = mDragInfo != null ? mDragInfo.spanX : 1;
int spanY = mDragInfo != null ? mDragInfo.spanY : 1;
// First we find the cell nearest to point at which the item is
// dropped, without any consideration to whether there is an item there.
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], spanX, spanY, dropTargetLayout, mTargetCell);
float distance = dropTargetLayout.getDistanceFromWorkspaceCellVisualCenter(mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
// cell also contains a shortcut, then create a folder with the two shortcuts.
if (createUserFolderIfNecessary(cell, container, dropTargetLayout, mTargetCell, distance, false, d) || addToExistingFolderIfNecessary(cell, dropTargetLayout, mTargetCell, distance, d, false)) {
mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY);
return;
}
// Aside from the special case where we're dropping a shortcut onto a shortcut,
// we need to find the nearest cell location that is vacant
ItemInfo item = d.dragInfo;
int minSpanX = item.spanX;
int minSpanY = item.spanY;
if (item.minSpanX > 0 && item.minSpanY > 0) {
minSpanX = item.minSpanX;
minSpanY = item.minSpanY;
}
droppedOnOriginalCell = item.screenId == screenId && item.container == container && item.cellX == mTargetCell[0] && item.cellY == mTargetCell[1];
droppedOnOriginalCellDuringTransition = droppedOnOriginalCell && mIsSwitchingState;
// When quickly moving an item, a user may accidentally rearrange their
// workspace. So instead we move the icon back safely to its original position.
boolean returnToOriginalCellToPreventShuffling = !isFinishedSwitchingState() && !droppedOnOriginalCellDuringTransition && !dropTargetLayout.isRegionVacant(mTargetCell[0], mTargetCell[1], spanX, spanY);
int[] resultSpan = new int[2];
if (returnToOriginalCellToPreventShuffling) {
mTargetCell[0] = mTargetCell[1] = -1;
} else {
mTargetCell = dropTargetLayout.performReorder((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY, cell, mTargetCell, resultSpan, CellLayout.MODE_ON_DROP);
}
boolean foundCell = mTargetCell[0] >= 0 && mTargetCell[1] >= 0;
// if the widget resizes on drop
if (foundCell && (cell instanceof AppWidgetHostView) && (resultSpan[0] != item.spanX || resultSpan[1] != item.spanY)) {
resizeOnDrop = true;
item.spanX = resultSpan[0];
item.spanY = resultSpan[1];
AppWidgetHostView awhv = (AppWidgetHostView) cell;
WidgetSizes.updateWidgetSizeRanges(awhv, mLauncher, resultSpan[0], resultSpan[1]);
}
if (foundCell) {
int targetScreenIndex = getPageIndexForScreenId(screenId);
int snapScreen = getLeftmostVisiblePageForIndex(targetScreenIndex);
// isn't needed if the source and target screens appear at the same time
if (snapScreen != mCurrentPage && !hasMovedIntoHotseat) {
snapToPage(snapScreen);
snappedToNewPage = true;
}
final ItemInfo info = (ItemInfo) cell.getTag();
if (hasMovedLayouts) {
// Reparent the view
CellLayout parentCell = getParentCellLayoutForView(cell);
if (parentCell != null) {
parentCell.removeView(cell);
} else if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
d.dragView.detachContentView(/* reattachToPreviousParent= */
false);
} else if (FeatureFlags.IS_STUDIO_BUILD) {
throw new NullPointerException("mDragInfo.cell has null parent");
}
addInScreen(cell, container, screenId, mTargetCell[0], mTargetCell[1], info.spanX, info.spanY);
}
// update the item's position after drop
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
lp.cellX = lp.tmpCellX = mTargetCell[0];
lp.cellY = lp.tmpCellY = mTargetCell[1];
lp.cellHSpan = item.spanX;
lp.cellVSpan = item.spanY;
lp.isLockedToGrid = true;
if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT && cell instanceof LauncherAppWidgetHostView) {
final CellLayout cellLayout = dropTargetLayout;
// We post this call so that the widget has a chance to be placed
// in its final location
final LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) cell;
AppWidgetProviderInfo pInfo = hostView.getAppWidgetInfo();
if (pInfo != null && !options.isAccessibleDrag) {
onCompleteRunnable = () -> {
if (!isPageInTransition()) {
AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
}
};
}
}
mLauncher.getModelWriter().modifyItemInDatabase(info, container, screenId, lp.cellX, lp.cellY, item.spanX, item.spanY);
} else {
if (!returnToOriginalCellToPreventShuffling) {
onNoCellFound(dropTargetLayout, d.dragInfo, d.logInstanceId);
}
if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
d.dragView.detachContentView(/* reattachToPreviousParent= */
true);
}
// If we can't find a drop location, we return the item to its original position
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
mTargetCell[0] = lp.cellX;
mTargetCell[1] = lp.cellY;
CellLayout layout = (CellLayout) cell.getParent().getParent();
layout.markCellsAsOccupiedForView(cell);
}
} else {
// When drag is cancelled, reattach content view back to its original parent.
if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
d.dragView.detachContentView(/* reattachToPreviousParent= */
true);
}
}
final CellLayout parent = (CellLayout) cell.getParent().getParent();
if (d.dragView.hasDrawn()) {
if (droppedOnOriginalCellDuringTransition) {
// Animate the item to its original position, while simultaneously exiting
// spring-loaded mode so the page meets the icon where it was picked up.
final RunnableList callbackList = new RunnableList();
final Runnable onCompleteCallback = onCompleteRunnable;
mLauncher.getDragController().animateDragViewToOriginalPosition(/* onComplete= */
callbackList::executeAllAndDestroy, cell, SPRING_LOADED.getTransitionDuration(mLauncher));
mLauncher.getStateManager().goToState(NORMAL, /* delay= */
0, onCompleteCallback == null ? null : forSuccessCallback(() -> callbackList.add(onCompleteCallback)));
mLauncher.getDropTargetBar().onDragEnd();
parent.onDropChild(cell);
return;
}
final ItemInfo info = (ItemInfo) cell.getTag();
boolean isWidget = info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
if (isWidget) {
int animationType = resizeOnDrop ? ANIMATE_INTO_POSITION_AND_RESIZE : ANIMATE_INTO_POSITION_AND_DISAPPEAR;
animateWidgetDrop(info, parent, d.dragView, null, animationType, cell, false);
} else {
int duration = snappedToNewPage ? ADJACENT_SCREEN_DROP_DURATION : -1;
mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, cell, duration, this);
}
} else {
d.deferDragViewCleanupPostAnimation = false;
cell.setVisibility(VISIBLE);
}
parent.onDropChild(cell);
mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable == null ? null : forSuccessCallback(onCompleteRunnable));
mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId).log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED);
}
if (d.stateAnnouncer != null && !droppedOnOriginalCell) {
d.stateAnnouncer.completeAction(R.string.item_moved);
}
}
use of com.android.launcher3.CellLayout in project android_packages_apps_Launcher3 by AOSPA.
the class Workspace method removeItemsByMatcher.
/**
* Removes items that match the {@param matcher}. When applications are removed
* as a part of an update, this is called to ensure that other widgets and application
* shortcuts are not removed.
*/
public void removeItemsByMatcher(final ItemInfoMatcher matcher) {
for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) {
ShortcutAndWidgetContainer container = layout.getShortcutsAndWidgets();
// Iterate in reverse order as we are removing items
for (int i = container.getChildCount() - 1; i >= 0; i--) {
View child = container.getChildAt(i);
ItemInfo info = (ItemInfo) child.getTag();
if (matcher.matchesInfo(info)) {
layout.removeViewInLayout(child);
if (child instanceof DropTarget) {
mDragController.removeDropTarget((DropTarget) child);
}
} else if (child instanceof FolderIcon) {
FolderInfo folderInfo = (FolderInfo) info;
List<WorkspaceItemInfo> matches = folderInfo.contents.stream().filter(matcher::matchesInfo).collect(Collectors.toList());
if (!matches.isEmpty()) {
folderInfo.removeAll(matches, false);
if (((FolderIcon) child).getFolder().isOpen()) {
((FolderIcon) child).getFolder().close(false);
}
}
}
}
}
// Strip all the empty screens
stripEmptyScreens();
}
use of com.android.launcher3.CellLayout in project android_packages_apps_Launcher3 by AOSPA.
the class WorkspaceStateTransitionAnimation method setWorkspaceProperty.
/**
* Starts a transition animation for the workspace.
*/
private void setWorkspaceProperty(LauncherState state, PropertySetter propertySetter, StateAnimationConfig config) {
ScaleAndTranslation scaleAndTranslation = state.getWorkspaceScaleAndTranslation(mLauncher);
ScaleAndTranslation hotseatScaleAndTranslation = state.getHotseatScaleAndTranslation(mLauncher);
mNewScale = scaleAndTranslation.scale;
PageAlphaProvider pageAlphaProvider = state.getWorkspacePageAlphaProvider(mLauncher);
final int childCount = mWorkspace.getChildCount();
for (int i = 0; i < childCount; i++) {
applyChildState(state, (CellLayout) mWorkspace.getChildAt(i), i, pageAlphaProvider, propertySetter, config);
}
int elements = state.getVisibleElements(mLauncher);
Interpolator fadeInterpolator = config.getInterpolator(ANIM_WORKSPACE_FADE, pageAlphaProvider.interpolator);
Hotseat hotseat = mWorkspace.getHotseat();
Interpolator scaleInterpolator = config.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT);
LauncherState fromState = mLauncher.getStateManager().getState();
boolean shouldSpring = propertySetter instanceof PendingAnimation && fromState == HINT_STATE && state == NORMAL;
if (shouldSpring) {
((PendingAnimation) propertySetter).add(getSpringScaleAnimator(mLauncher, mWorkspace, mNewScale));
} else {
propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator);
}
mWorkspace.setPivotToScaleWithSelf(hotseat);
float hotseatScale = hotseatScaleAndTranslation.scale;
if (shouldSpring) {
PendingAnimation pa = (PendingAnimation) propertySetter;
pa.add(getSpringScaleAnimator(mLauncher, hotseat, hotseatScale));
} else {
Interpolator hotseatScaleInterpolator = config.getInterpolator(ANIM_HOTSEAT_SCALE, scaleInterpolator);
propertySetter.setFloat(hotseat, SCALE_PROPERTY, hotseatScale, hotseatScaleInterpolator);
}
float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha, fadeInterpolator);
float workspacePageIndicatorAlpha = (elements & WORKSPACE_PAGE_INDICATOR) != 0 ? 1 : 0;
propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(), workspacePageIndicatorAlpha, fadeInterpolator);
Interpolator translationInterpolator = config.getInterpolator(ANIM_WORKSPACE_TRANSLATE, ZOOM_OUT);
propertySetter.setFloat(mWorkspace, VIEW_TRANSLATE_X, scaleAndTranslation.translationX, translationInterpolator);
propertySetter.setFloat(mWorkspace, VIEW_TRANSLATE_Y, scaleAndTranslation.translationY, translationInterpolator);
Interpolator hotseatTranslationInterpolator = config.getInterpolator(ANIM_HOTSEAT_TRANSLATE, translationInterpolator);
propertySetter.setFloat(hotseat, VIEW_TRANSLATE_Y, hotseatScaleAndTranslation.translationY, hotseatTranslationInterpolator);
propertySetter.setFloat(mWorkspace.getPageIndicator(), VIEW_TRANSLATE_Y, hotseatScaleAndTranslation.translationY, hotseatTranslationInterpolator);
if (!config.hasAnimationFlag(SKIP_SCRIM)) {
setScrim(propertySetter, state, config);
}
}
Aggregations