use of com.android.launcher3.tapl.Folder in project android_packages_apps_Launcher3 by AOSPA.
the class KeyboardDragAndDropView method getNextSelection.
/**
* Focus finding logic:
* Collect all virtual nodes in reading order (used for forward and backwards).
* Then find the closest view by comparing the distances spatially. Since it is a move
* operation. consider all cell sizes to be approximately of the same size.
*/
private VirtualNodeInfo getNextSelection(int direction) {
// Collect all virtual nodes
mDelegates.clear();
mNodes.clear();
Folder openFolder = Folder.getOpen(mLauncher);
PagedView pv = openFolder == null ? mLauncher.getWorkspace() : openFolder.getContent();
int count = pv.getPageCount();
for (int i = 0; i < count; i++) {
mDelegates.add(((CellLayout) pv.getChildAt(i)).getDragAndDropAccessibilityDelegate());
}
if (openFolder == null) {
mDelegates.add(pv.getNextPage() + 1, mLauncher.getHotseat().getDragAndDropAccessibilityDelegate());
}
mDelegates.forEach(delegate -> {
mIntList.clear();
delegate.getVisibleVirtualViews(mIntList);
mIntList.forEach(id -> mNodes.add(new VirtualNodeInfo(delegate, id)));
});
if (mNodes.isEmpty()) {
return null;
}
int index = mNodes.indexOf(mCurrentSelection);
if (mCurrentSelection == null || index < 0) {
return null;
}
int totalNodes = mNodes.size();
final ToIntBiFunction<Rect, Rect> majorAxis;
final ToIntFunction<Rect> minorAxis;
switch(direction) {
case View.FOCUS_RIGHT:
majorAxis = (source, dest) -> dest.left - source.left;
minorAxis = Rect::centerY;
break;
case View.FOCUS_LEFT:
majorAxis = (source, dest) -> source.left - dest.left;
minorAxis = Rect::centerY;
break;
case View.FOCUS_UP:
majorAxis = (source, dest) -> source.top - dest.top;
minorAxis = Rect::centerX;
break;
case View.FOCUS_DOWN:
majorAxis = (source, dest) -> dest.top - source.top;
minorAxis = Rect::centerX;
break;
case View.FOCUS_FORWARD:
return mNodes.get((index + 1) % totalNodes);
case View.FOCUS_BACKWARD:
return mNodes.get((index + totalNodes - 1) % totalNodes);
default:
// Unknown direction
return null;
}
mCurrentSelection.populate(mTempNodeInfo).getBoundsInScreen(mTempRect);
float minWeight = Float.MAX_VALUE;
VirtualNodeInfo match = null;
for (int i = 0; i < totalNodes; i++) {
VirtualNodeInfo node = mNodes.get(i);
node.populate(mTempNodeInfo).getBoundsInScreen(mTempRect2);
int majorAxisWeight = majorAxis.applyAsInt(mTempRect, mTempRect2);
if (majorAxisWeight <= 0) {
continue;
}
int minorAxisWeight = minorAxis.applyAsInt(mTempRect2) - minorAxis.applyAsInt(mTempRect);
float weight = majorAxisWeight * majorAxisWeight + minorAxisWeight * minorAxisWeight * MINOR_AXIS_WEIGHT;
if (weight < minWeight) {
minWeight = weight;
match = node;
}
}
return match;
}
use of com.android.launcher3.tapl.Folder in project android_packages_apps_Launcher3 by AOSPA.
the class DragLayer method onInterceptHoverEvent.
@Override
public boolean onInterceptHoverEvent(MotionEvent ev) {
if (mActivity == null || mActivity.getWorkspace() == null) {
return false;
}
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
if (!(topView instanceof Folder)) {
return false;
} else {
AccessibilityManager accessibilityManager = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
if (accessibilityManager.isTouchExplorationEnabled()) {
Folder currentFolder = (Folder) topView;
final int action = ev.getAction();
boolean isOverFolderOrSearchBar;
switch(action) {
case MotionEvent.ACTION_HOVER_ENTER:
isOverFolderOrSearchBar = isEventOverView(topView, ev) || isEventOverAccessibleDropTargetBar(ev);
if (!isOverFolderOrSearchBar) {
sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName());
mHoverPointClosesFolder = true;
return true;
}
mHoverPointClosesFolder = false;
break;
case MotionEvent.ACTION_HOVER_MOVE:
isOverFolderOrSearchBar = isEventOverView(topView, ev) || isEventOverAccessibleDropTargetBar(ev);
if (!isOverFolderOrSearchBar && !mHoverPointClosesFolder) {
sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName());
mHoverPointClosesFolder = true;
return true;
} else if (!isOverFolderOrSearchBar) {
return true;
}
mHoverPointClosesFolder = false;
}
}
}
return false;
}
use of com.android.launcher3.tapl.Folder in project android_packages_apps_Launcher3 by AOSPA.
the class DragView method setItemInfo.
/**
* Initialize {@code #mIconDrawable} if the item can be represented using
* an {@link AdaptiveIconDrawable} or {@link FolderAdaptiveIcon}.
*/
@TargetApi(Build.VERSION_CODES.O)
public void setItemInfo(final ItemInfo info) {
if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && info.itemType != LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION && info.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT && info.itemType != LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
return;
}
// Load the adaptive icon on a background thread and add the view in ui thread.
MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> {
Object[] outObj = new Object[1];
int w = mWidth;
int h = mHeight;
Drawable dr = Utilities.getFullDrawable(mActivity, info, w, h, outObj);
if (dr instanceof AdaptiveIconDrawable) {
int blurMargin = (int) mActivity.getResources().getDimension(R.dimen.blur_size_medium_outline) / 2;
Rect bounds = new Rect(0, 0, w, h);
bounds.inset(blurMargin, blurMargin);
// Badge is applied after icon normalization so the bounds for badge should not
// be scaled down due to icon normalization.
Rect badgeBounds = new Rect(bounds);
mBadge = getBadge(mActivity, info, outObj[0]);
mBadge.setBounds(badgeBounds);
// Do not draw the background in case of folder as its translucent
final boolean shouldDrawBackground = !(dr instanceof FolderAdaptiveIcon);
try (LauncherIcons li = LauncherIcons.obtain(mActivity)) {
// drawable to be normalized
Drawable nDr;
if (shouldDrawBackground) {
nDr = dr;
} else {
// Since we just want the scale, avoid heavy drawing operations
nDr = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null);
}
Utilities.scaleRectAboutCenter(bounds, li.getNormalizer().getScale(nDr, null, null, null));
}
AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr;
// Shrink very tiny bit so that the clip path is smaller than the original bitmap
// that has anti aliased edges and shadows.
Rect shrunkBounds = new Rect(bounds);
Utilities.scaleRectAboutCenter(shrunkBounds, 0.98f);
adaptiveIcon.setBounds(shrunkBounds);
final Path mask = adaptiveIcon.getIconMask();
mTranslateX = new SpringFloatValue(DragView.this, w * AdaptiveIconDrawable.getExtraInsetFraction());
mTranslateY = new SpringFloatValue(DragView.this, h * AdaptiveIconDrawable.getExtraInsetFraction());
bounds.inset((int) (-bounds.width() * AdaptiveIconDrawable.getExtraInsetFraction()), (int) (-bounds.height() * AdaptiveIconDrawable.getExtraInsetFraction()));
mBgSpringDrawable = adaptiveIcon.getBackground();
if (mBgSpringDrawable == null) {
mBgSpringDrawable = new ColorDrawable(Color.TRANSPARENT);
}
mBgSpringDrawable.setBounds(bounds);
mFgSpringDrawable = adaptiveIcon.getForeground();
if (mFgSpringDrawable == null) {
mFgSpringDrawable = new ColorDrawable(Color.TRANSPARENT);
}
mFgSpringDrawable.setBounds(bounds);
new Handler(Looper.getMainLooper()).post(() -> mOnDragStartCallback.add(() -> {
// TODO: Consider fade-in animation
// Assign the variable on the UI thread to avoid race conditions.
mScaledMaskPath = mask;
// Avoid relayout as we do not care about children affecting layout
removeAllViewsInLayout();
if (info.isDisabled()) {
FastBitmapDrawable d = new FastBitmapDrawable((Bitmap) null);
d.setIsDisabled(true);
mBgSpringDrawable.setColorFilter(d.getColorFilter());
mFgSpringDrawable.setColorFilter(d.getColorFilter());
mBadge.setColorFilter(d.getColorFilter());
}
invalidate();
}));
}
});
}
use of com.android.launcher3.tapl.Folder in project android_packages_apps_Launcher3 by AOSPA.
the class LauncherDelegate method replaceFolderWithFinalItem.
boolean replaceFolderWithFinalItem(Folder folder) {
// Add the last remaining child to the workspace in place of the folder
Runnable onCompleteRunnable = new Runnable() {
@Override
public void run() {
int itemCount = folder.getItemCount();
FolderInfo info = folder.mInfo;
if (itemCount <= 1) {
View newIcon = null;
WorkspaceItemInfo finalItem = null;
if (itemCount == 1) {
// Move the item from the folder to the workspace, in the position of the
// folder
CellLayout cellLayout = mLauncher.getCellLayout(info.container, info.screenId);
finalItem = info.contents.remove(0);
newIcon = mLauncher.createShortcut(cellLayout, finalItem);
mLauncher.getModelWriter().addOrMoveItemInDatabase(finalItem, info.container, info.screenId, info.cellX, info.cellY);
}
// Remove the folder
mLauncher.removeItem(folder.mFolderIcon, info, true);
if (folder.mFolderIcon instanceof DropTarget) {
folder.mDragController.removeDropTarget((DropTarget) folder.mFolderIcon);
}
if (newIcon != null) {
// We add the child after removing the folder to prevent both from existing
// at the same time in the CellLayout. We need to add the new item with
// addInScreenFromBind() to ensure that hotseat items are placed correctly.
mLauncher.getWorkspace().addInScreenFromBind(newIcon, info);
// Focus the newly created child
newIcon.requestFocus();
}
if (finalItem != null) {
StatsLogger logger = mLauncher.getStatsLogManager().logger().withItemInfo(finalItem);
((Optional<InstanceId>) folder.mDragController.getLogInstanceId()).map(logger::withInstanceId).orElse(logger).log(LAUNCHER_FOLDER_CONVERTED_TO_ICON);
}
}
}
};
View finalChild = folder.mContent.getLastItem();
if (finalChild != null) {
folder.mFolderIcon.performDestroyAnimation(onCompleteRunnable);
} else {
onCompleteRunnable.run();
}
return true;
}
use of com.android.launcher3.tapl.Folder in project android_packages_apps_Launcher3 by AOSPA.
the class PreviewItemManager method drawPreviewItem.
/**
* Draws each preview item.
*
* @param offset The offset needed to draw the preview items.
* @param shouldClipPath Iff true, clip path using {@param clipPath}.
* @param clipPath The clip path of the folder icon.
*/
private void drawPreviewItem(Canvas canvas, PreviewItemDrawingParams params, PointF offset, boolean shouldClipPath, Path clipPath) {
canvas.save();
if (shouldClipPath) {
canvas.clipPath(clipPath);
}
canvas.translate(offset.x + params.transX, offset.y + params.transY);
canvas.scale(params.scale, params.scale);
Drawable d = params.drawable;
if (d != null) {
Rect bounds = d.getBounds();
canvas.save();
canvas.translate(-bounds.left, -bounds.top);
canvas.scale(mIntrinsicIconSize / bounds.width(), mIntrinsicIconSize / bounds.height());
d.draw(canvas);
canvas.restore();
}
canvas.restore();
}
Aggregations