use of com.android.launcher3.WorkspaceItemInfo in project android_packages_apps_Trebuchet by LineageOS.
the class Workspace method onDropExternal.
/**
* Drop an item that didn't originate on one of the workspace screens.
* It may have come from Launcher (e.g. from all apps or customize), or it may have
* come from another app altogether.
*
* NOTE: This can also be called when we are outside of a drag event, when we want
* to add an item to one of the workspace screens.
*/
private void onDropExternal(final int[] touchXY, final CellLayout cellLayout, DragObject d) {
if (d.dragInfo instanceof PendingAddShortcutInfo) {
WorkspaceItemInfo si = ((PendingAddShortcutInfo) d.dragInfo).activityInfo.createWorkspaceItemInfo();
if (si != null) {
d.dragInfo = si;
}
}
ItemInfo info = d.dragInfo;
int spanX = info.spanX;
int spanY = info.spanY;
if (mDragInfo != null) {
spanX = mDragInfo.spanX;
spanY = mDragInfo.spanY;
}
final int container = mLauncher.isHotseatLayout(cellLayout) ? LauncherSettings.Favorites.CONTAINER_HOTSEAT : LauncherSettings.Favorites.CONTAINER_DESKTOP;
final int screenId = getIdForScreen(cellLayout);
if (!mLauncher.isHotseatLayout(cellLayout) && screenId != getScreenIdForPageIndex(mCurrentPage) && !mLauncher.isInState(SPRING_LOADED)) {
snapToPage(getPageIndexForScreenId(screenId));
}
if (info instanceof PendingAddItemInfo) {
final PendingAddItemInfo pendingInfo = (PendingAddItemInfo) info;
boolean findNearestVacantCell = true;
if (pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY, cellLayout, mTargetCell);
float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
if (willCreateUserFolder(d.dragInfo, cellLayout, mTargetCell, distance, true) || willAddToExistingUserFolder(d.dragInfo, cellLayout, mTargetCell, distance)) {
findNearestVacantCell = false;
}
}
final ItemInfo item = d.dragInfo;
boolean updateWidgetSize = false;
if (findNearestVacantCell) {
int minSpanX = item.spanX;
int minSpanY = item.spanY;
if (item.minSpanX > 0 && item.minSpanY > 0) {
minSpanX = item.minSpanX;
minSpanY = item.minSpanY;
}
int[] resultSpan = new int[2];
mTargetCell = cellLayout.performReorder((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], minSpanX, minSpanY, info.spanX, info.spanY, null, mTargetCell, resultSpan, CellLayout.MODE_ON_DROP_EXTERNAL);
if (resultSpan[0] != item.spanX || resultSpan[1] != item.spanY) {
updateWidgetSize = true;
}
item.spanX = resultSpan[0];
item.spanY = resultSpan[1];
}
Runnable onAnimationCompleteRunnable = new Runnable() {
@Override
public void run() {
// Normally removeExtraEmptyScreen is called in Workspace#onDragEnd, but when
// adding an item that may not be dropped right away (due to a config activity)
// we defer the removal until the activity returns.
deferRemoveExtraEmptyScreen();
// When dragging and dropping from customization tray, we deal with creating
// widgets/shortcuts/folders in a slightly different way
mLauncher.addPendingItem(pendingInfo, container, screenId, mTargetCell, item.spanX, item.spanY);
mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId).log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED);
}
};
boolean isWidget = pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET || pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
AppWidgetHostView finalView = isWidget ? ((PendingAddWidgetInfo) pendingInfo).boundWidget : null;
if (finalView != null && updateWidgetSize) {
AppWidgetResizeFrame.updateWidgetSizeRanges(finalView, mLauncher, item.spanX, item.spanY);
}
int animationStyle = ANIMATE_INTO_POSITION_AND_DISAPPEAR;
if (isWidget && ((PendingAddWidgetInfo) pendingInfo).info != null && ((PendingAddWidgetInfo) pendingInfo).getHandler().needsConfigure()) {
animationStyle = ANIMATE_INTO_POSITION_AND_REMAIN;
}
animateWidgetDrop(info, cellLayout, d.dragView, onAnimationCompleteRunnable, animationStyle, finalView, true);
} else {
// This is for other drag/drop cases, like dragging from All Apps
mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY);
View view;
switch(info.itemType) {
case ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
if (info instanceof AppInfo) {
// Came from all apps -- make a copy
info = ((AppInfo) info).makeWorkspaceItem();
d.dragInfo = info;
}
view = mLauncher.createShortcut(cellLayout, (WorkspaceItemInfo) info);
break;
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
view = FolderIcon.inflateFolderAndIcon(R.layout.folder_icon, mLauncher, cellLayout, (FolderInfo) info);
break;
default:
throw new IllegalStateException("Unknown item type: " + info.itemType);
}
// dropped, without any consideration to whether there is an item there.
if (touchXY != null) {
mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY, cellLayout, mTargetCell);
float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
if (createUserFolderIfNecessary(view, container, cellLayout, mTargetCell, distance, true, d)) {
return;
}
if (addToExistingFolderIfNecessary(view, cellLayout, mTargetCell, distance, d, true)) {
return;
}
}
if (touchXY != null) {
// when dragging and dropping, just find the closest free spot
mTargetCell = cellLayout.performReorder((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], 1, 1, 1, 1, null, mTargetCell, null, CellLayout.MODE_ON_DROP_EXTERNAL);
} else {
cellLayout.findCellForSpan(mTargetCell, 1, 1);
}
// Add the item to DB before adding to screen ensures that the container and other
// values of the info is properly updated.
mLauncher.getModelWriter().addOrMoveItemInDatabase(info, container, screenId, mTargetCell[0], mTargetCell[1]);
addInScreen(view, container, screenId, mTargetCell[0], mTargetCell[1], info.spanX, info.spanY);
cellLayout.onDropChild(view);
cellLayout.getShortcutsAndWidgets().measureChild(view);
if (d.dragView != null) {
// We wrap the animation call in the temporary set and reset of the current
// cellLayout to its final transform -- this means we animate the drag view to
// the correct final location.
setFinalTransitionTransform();
mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, view, this);
resetTransitionTransform();
}
mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId).log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED);
}
}
use of com.android.launcher3.WorkspaceItemInfo in project android_packages_apps_Trebuchet by LineageOS.
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 (final CellLayout layoutParent : getWorkspaceAndHotseatCellLayouts()) {
final ViewGroup layout = layoutParent.getShortcutsAndWidgets();
IntSparseArrayMap<View> idToViewMap = new IntSparseArrayMap<>();
ArrayList<ItemInfo> items = new ArrayList<>();
for (int j = 0; j < layout.getChildCount(); j++) {
final View view = layout.getChildAt(j);
if (view.getTag() instanceof ItemInfo) {
ItemInfo item = (ItemInfo) view.getTag();
items.add(item);
idToViewMap.put(item.id, view);
}
}
for (ItemInfo itemToRemove : matcher.filterItemInfos(items)) {
View child = idToViewMap.get(itemToRemove.id);
if (child != null) {
// Note: We can not remove the view directly from CellLayoutChildren as this
// does not re-mark the spaces as unoccupied.
layoutParent.removeViewInLayout(child);
if (child instanceof DropTarget) {
mDragController.removeDropTarget((DropTarget) child);
}
} else if (itemToRemove.container >= 0) {
// The item may belong to a folder.
View parent = idToViewMap.get(itemToRemove.container);
if (parent instanceof FolderIcon) {
FolderInfo folderInfo = (FolderInfo) parent.getTag();
folderInfo.remove((WorkspaceItemInfo) itemToRemove, false);
if (((FolderIcon) parent).getFolder().isOpen()) {
((FolderIcon) parent).getFolder().close(false);
}
}
}
}
}
// Strip all the empty screens
stripEmptyScreens();
}
use of com.android.launcher3.WorkspaceItemInfo in project android_packages_apps_Trebuchet by LineageOS.
the class Workspace method updateShortcuts.
void updateShortcuts(ArrayList<WorkspaceItemInfo> shortcuts) {
final HashSet<WorkspaceItemInfo> updates = new HashSet<>(shortcuts);
ItemOperator op = (info, v) -> {
if (v instanceof BubbleTextView && updates.contains(info)) {
WorkspaceItemInfo si = (WorkspaceItemInfo) info;
BubbleTextView shortcut = (BubbleTextView) v;
Drawable oldIcon = shortcut.getIcon();
boolean oldPromiseState = (oldIcon instanceof PreloadIconDrawable) && ((PreloadIconDrawable) oldIcon).hasNotCompleted();
shortcut.applyFromWorkspaceItem(si, si.isPromise() != oldPromiseState);
} else if (info instanceof FolderInfo && v instanceof FolderIcon) {
((FolderIcon) v).updatePreviewItems(updates::contains);
}
// Iterate all items
return false;
};
mapOverItems(op);
Folder openFolder = Folder.getOpen(mLauncher);
if (openFolder != null) {
openFolder.iterateOverItems(op);
}
}
use of com.android.launcher3.WorkspaceItemInfo in project android_packages_apps_Trebuchet by LineageOS.
the class Workspace method createUserFolderIfNecessary.
boolean createUserFolderIfNecessary(View newView, int container, CellLayout target, int[] targetCell, float distance, boolean external, DragObject d) {
if (distance > mMaxDistanceForFolderCreation)
return false;
View v = target.getChildAt(targetCell[0], targetCell[1]);
boolean hasntMoved = false;
if (mDragInfo != null) {
CellLayout cellParent = getParentCellLayoutForView(mDragInfo.cell);
hasntMoved = (mDragInfo.cellX == targetCell[0] && mDragInfo.cellY == targetCell[1]) && (cellParent == target);
}
if (v == null || hasntMoved || !mCreateUserFolderOnDrop)
return false;
mCreateUserFolderOnDrop = false;
final int screenId = getIdForScreen(target);
boolean aboveShortcut = (v.getTag() instanceof WorkspaceItemInfo);
boolean willBecomeShortcut = (newView.getTag() instanceof WorkspaceItemInfo);
if (aboveShortcut && willBecomeShortcut) {
WorkspaceItemInfo sourceInfo = (WorkspaceItemInfo) newView.getTag();
WorkspaceItemInfo destInfo = (WorkspaceItemInfo) v.getTag();
// if the drag started here, we need to remove it from the workspace
if (!external) {
getParentCellLayoutForView(mDragInfo.cell).removeView(mDragInfo.cell);
}
Rect folderLocation = new Rect();
float scale = mLauncher.getDragLayer().getDescendantRectRelativeToSelf(v, folderLocation);
target.removeView(v);
mStatsLogManager.logger().withItemInfo(destInfo).withInstanceId(d.logInstanceId).log(LauncherEvent.LAUNCHER_ITEM_DROP_FOLDER_CREATED);
FolderIcon fi = mLauncher.addFolder(target, container, screenId, targetCell[0], targetCell[1]);
destInfo.cellX = -1;
destInfo.cellY = -1;
sourceInfo.cellX = -1;
sourceInfo.cellY = -1;
// If the dragView is null, we can't animate
boolean animate = d != null;
if (animate) {
// In order to keep everything continuous, we hand off the currently rendered
// folder background to the newly created icon. This preserves animation state.
fi.setFolderBackground(mFolderCreateBg);
mFolderCreateBg = new PreviewBackground();
fi.performCreateAnimation(destInfo, v, sourceInfo, d, folderLocation, scale);
} else {
fi.prepareCreateAnimation(v);
fi.addItem(destInfo);
fi.addItem(sourceInfo);
}
mLauncher.folderCreatedFromItem(fi.getFolder(), destInfo);
return true;
}
return false;
}
use of com.android.launcher3.WorkspaceItemInfo in project android_packages_apps_Trebuchet by LineageOS.
the class LauncherAccessibilityDelegate method performAction.
public boolean performAction(final View host, final ItemInfo item, int action) {
if (action == ACTION_LONG_CLICK) {
if (PopupContainerWithArrow.canShow(host, item)) {
// Long press should be consumed for workspace items, and it should invoke the
// Shortcuts / Notifications / Actions pop-up menu, and not start a drag as the
// standard long press path does.
PopupContainerWithArrow.showForIcon((BubbleTextView) host);
return true;
} else {
CustomActionsPopup popup = new CustomActionsPopup(mLauncher, host);
if (popup.canShow()) {
popup.show();
return true;
}
}
}
if (host instanceof AccessibilityActionHandler && ((AccessibilityActionHandler) host).performAccessibilityAction(action, item)) {
return true;
}
if (action == MOVE) {
beginAccessibleDrag(host, item);
} else if (action == ADD_TO_WORKSPACE) {
final int[] coordinates = new int[2];
final int screenId = findSpaceOnWorkspace(item, coordinates);
mLauncher.getStateManager().goToState(NORMAL, true, new Runnable() {
@Override
public void run() {
if (item instanceof AppInfo) {
WorkspaceItemInfo info = ((AppInfo) item).makeWorkspaceItem();
mLauncher.getModelWriter().addItemToDatabase(info, Favorites.CONTAINER_DESKTOP, screenId, coordinates[0], coordinates[1]);
ArrayList<ItemInfo> itemList = new ArrayList<>();
itemList.add(info);
mLauncher.bindItems(itemList, true);
announceConfirmation(R.string.item_added_to_workspace);
} else if (item instanceof PendingAddItemInfo) {
PendingAddItemInfo info = (PendingAddItemInfo) item;
Workspace workspace = mLauncher.getWorkspace();
workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
mLauncher.addPendingItem(info, Favorites.CONTAINER_DESKTOP, screenId, coordinates, info.spanX, info.spanY);
}
}
});
return true;
} else if (action == MOVE_TO_WORKSPACE) {
Folder folder = Folder.getOpen(mLauncher);
folder.close(true);
WorkspaceItemInfo info = (WorkspaceItemInfo) item;
folder.getInfo().remove(info, false);
final int[] coordinates = new int[2];
final int screenId = findSpaceOnWorkspace(item, coordinates);
mLauncher.getModelWriter().moveItemInDatabase(info, LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId, coordinates[0], coordinates[1]);
// Bind the item in next frame so that if a new workspace page was created,
// it will get laid out.
new Handler().post(new Runnable() {
@Override
public void run() {
ArrayList<ItemInfo> itemList = new ArrayList<>();
itemList.add(item);
mLauncher.bindItems(itemList, true);
announceConfirmation(R.string.item_moved);
}
});
} else if (action == RESIZE) {
final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
final IntArray actions = getSupportedResizeActions(host, info);
CharSequence[] labels = new CharSequence[actions.size()];
for (int i = 0; i < actions.size(); i++) {
labels[i] = mLauncher.getText(actions.get(i));
}
new AlertDialog.Builder(mLauncher).setTitle(R.string.action_resize).setItems(labels, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
performResizeAction(actions.get(which), host, info);
dialog.dismiss();
}
}).show();
return true;
} else if (action == DEEP_SHORTCUTS) {
return PopupContainerWithArrow.showForIcon((BubbleTextView) host) != null;
} else {
for (ButtonDropTarget dropTarget : mLauncher.getDropTargetBar().getDropTargets()) {
if (dropTarget.supportsAccessibilityDrop(item, host) && action == dropTarget.getAccessibilityAction()) {
dropTarget.onAccessibilityDrop(host, item);
return true;
}
}
}
return false;
}
Aggregations