use of com.android.launcher3.dragndrop.DragLayer in project Neo-Launcher by NeoApplications.
the class Folder method centerAboutIcon.
private void centerAboutIcon() {
DeviceProfile grid = mLauncher.getDeviceProfile();
DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
DragLayer parent = mLauncher.getDragLayer();
int width = getFolderWidth();
int height = getFolderHeight();
parent.getDescendantRectRelativeToSelf(mFolderIcon, sTempRect);
int centerX = sTempRect.centerX();
int centerY = sTempRect.centerY();
int centeredLeft = centerX - width / 2;
int centeredTop = centerY - height / 2;
// We need to bound the folder to the currently visible workspace area
if (mLauncher.getStateManager().getState().overviewUi) {
parent.getDescendantRectRelativeToSelf(mLauncher.getOverviewPanel(), sTempRect);
} else {
mLauncher.getWorkspace().getPageAreaRelativeToDragLayer(sTempRect);
}
int left = Math.min(Math.max(sTempRect.left, centeredLeft), sTempRect.right - width);
int top = Math.min(Math.max(sTempRect.top, centeredTop), sTempRect.bottom - height);
int distFromEdgeOfScreen = mLauncher.getWorkspace().getPaddingLeft() + getPaddingLeft();
if (grid.isPhone && (grid.availableWidthPx - width) < 4 * distFromEdgeOfScreen) {
// Center the folder if it is very close to being centered anyway, by virtue of
// filling the majority of the viewport. ie. remove it from the uncanny valley
// of centeredness.
left = (grid.availableWidthPx - width) / 2;
} else if (width >= sTempRect.width()) {
// If the folder doesn't fit within the bounds, center it about the desired bounds
left = sTempRect.left + (sTempRect.width() - width) / 2;
}
if (height >= sTempRect.height()) {
// Folder height is greater than page height, center on page
top = sTempRect.top + (sTempRect.height() - height) / 2;
} else {
// Folder height is less than page height, so bound it to the absolute open folder
// bounds if necessary
Rect folderBounds = grid.getAbsoluteOpenFolderBounds();
left = Math.max(folderBounds.left, Math.min(left, folderBounds.right - width));
top = Math.max(folderBounds.top, Math.min(top, folderBounds.bottom - height));
}
int folderPivotX = width / 2 + (centeredLeft - left);
int folderPivotY = height / 2 + (centeredTop - top);
setPivotX(folderPivotX);
setPivotY(folderPivotY);
lp.width = width;
lp.height = height;
lp.x = left;
lp.y = top;
}
use of com.android.launcher3.dragndrop.DragLayer in project Neo-Launcher by NeoApplications.
the class DragController method startDrag.
/**
* Starts a drag.
* When the drag is started, the UI automatically goes into spring loaded mode. On a successful
* drop, it is the responsibility of the {@link DropTarget} to exit out of the spring loaded
* mode. If the drop was cancelled for some reason, the UI will automatically exit out of this mode.
*
* @param b The bitmap to display as the drag image. It will be re-scaled to the
* enlarged size.
* @param dragLayerX The x position in the DragLayer of the left-top of the bitmap.
* @param dragLayerY The y position in the DragLayer of the left-top of the bitmap.
* @param source An object representing where the drag originated
* @param dragInfo The data associated with the object that is being dragged
* @param dragRegion Coordinates within the bitmap b for the position of item being dragged.
* Makes dragging feel more precise, e.g. you can clip out a transparent border
*/
public DragView startDrag(Bitmap b, int dragLayerX, int dragLayerY, DragSource source, ItemInfo dragInfo, Point dragOffset, Rect dragRegion, float initialDragViewScale, float dragViewScaleOnDrop, DragOptions options) {
if (PROFILE_DRAWING_DURING_DRAG) {
android.os.Debug.startMethodTracing("Launcher");
}
// Hide soft keyboard, if visible
UiThreadHelper.hideKeyboardAsync(mLauncher, mWindowToken);
AbstractFloatingView.closeOpenViews(mLauncher, false, TYPE_DISCOVERY_BOUNCE);
mOptions = options;
if (mOptions.systemDndStartPoint != null) {
mMotionDownX = mOptions.systemDndStartPoint.x;
mMotionDownY = mOptions.systemDndStartPoint.y;
}
final int registrationX = mMotionDownX - dragLayerX;
final int registrationY = mMotionDownY - dragLayerY;
final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left;
final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top;
mLastDropTarget = null;
mDragObject = new DropTarget.DragObject();
mIsInPreDrag = mOptions.preDragCondition != null && !mOptions.preDragCondition.shouldStartDrag(0);
final Resources res = mLauncher.getResources();
final float scaleDps = mIsInPreDrag ? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f;
final DragView dragView = mDragObject.dragView = new DragView(mLauncher, b, registrationX, registrationY, initialDragViewScale, dragViewScaleOnDrop, scaleDps);
dragView.setItemInfo(dragInfo);
mDragObject.dragComplete = false;
if (mOptions.isAccessibleDrag) {
// For an accessible drag, we assume the view is being dragged from the center.
mDragObject.xOffset = b.getWidth() / 2;
mDragObject.yOffset = b.getHeight() / 2;
mDragObject.accessibleDrag = true;
} else {
mDragObject.xOffset = mMotionDownX - (dragLayerX + dragRegionLeft);
mDragObject.yOffset = mMotionDownY - (dragLayerY + dragRegionTop);
mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
mDragDriver = DragDriver.create(mLauncher, this, mDragObject, mOptions);
}
mDragObject.dragSource = source;
mDragObject.dragInfo = dragInfo;
mDragObject.originalDragInfo = new ItemInfo();
mDragObject.originalDragInfo.copyFrom(dragInfo);
if (dragOffset != null) {
dragView.setDragVisualizeOffset(new Point(dragOffset));
}
if (dragRegion != null) {
dragView.setDragRegion(new Rect(dragRegion));
}
mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
dragView.show(mLastTouch[0], mLastTouch[1]);
mDistanceSinceScroll = 0;
if (!mIsInPreDrag) {
callOnDragStart();
} else if (mOptions.preDragCondition != null) {
mOptions.preDragCondition.onPreDragStart(mDragObject);
}
handleMoveEvent(mLastTouch[0], mLastTouch[1]);
mLauncher.getUserEventDispatcher().resetActionDurationMillis();
return dragView;
}
use of com.android.launcher3.dragndrop.DragLayer in project Neo-Launcher by NeoApplications.
the class ArrowPopup method orientAboutObject.
/**
* Orients this container above or below the given icon, aligning with the left or right.
*
* These are the preferred orientations, in order (RTL prefers right-aligned over left):
* - Above and left-aligned
* - Above and right-aligned
* - Below and left-aligned
* - Below and right-aligned
*
* So we always align left if there is enough horizontal space
* and align above if there is enough vertical space.
*/
protected void orientAboutObject() {
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
int width = getMeasuredWidth();
int extraVerticalSpace = mArrow.getLayoutParams().height + mArrowOffset + getResources().getDimensionPixelSize(R.dimen.popup_vertical_padding);
int height = getMeasuredHeight() + extraVerticalSpace;
getTargetObjectLocation(mTempRect);
InsettableFrameLayout dragLayer = getPopupContainer();
Rect insets = dragLayer.getInsets();
// Align left (right in RTL) if there is room.
int leftAlignedX = mTempRect.left;
int rightAlignedX = mTempRect.right - width;
int x = leftAlignedX;
boolean canBeLeftAligned = leftAlignedX + width + insets.left < dragLayer.getRight() - insets.right;
boolean canBeRightAligned = rightAlignedX > dragLayer.getLeft() + insets.left;
if (!canBeLeftAligned || (mIsRtl && canBeRightAligned)) {
x = rightAlignedX;
}
mIsLeftAligned = x == leftAlignedX;
// Offset x so that the arrow and shortcut icons are center-aligned with the original icon.
int iconWidth = mTempRect.width();
Resources resources = getResources();
int xOffset;
if (isAlignedWithStart()) {
// Aligning with the shortcut icon.
int shortcutIconWidth = resources.getDimensionPixelSize(R.dimen.deep_shortcut_icon_size);
int shortcutPaddingStart = resources.getDimensionPixelSize(R.dimen.popup_padding_start);
xOffset = iconWidth / 2 - shortcutIconWidth / 2 - shortcutPaddingStart;
} else {
// Aligning with the drag handle.
int shortcutDragHandleWidth = resources.getDimensionPixelSize(R.dimen.deep_shortcut_drag_handle_size);
int shortcutPaddingEnd = resources.getDimensionPixelSize(R.dimen.popup_padding_end);
xOffset = iconWidth / 2 - shortcutDragHandleWidth / 2 - shortcutPaddingEnd;
}
x += mIsLeftAligned ? xOffset : -xOffset;
// Open above icon if there is room.
int iconHeight = mTempRect.height();
int y = mTempRect.top - height;
mIsAboveIcon = y > dragLayer.getTop() + insets.top;
if (!mIsAboveIcon) {
y = mTempRect.top + iconHeight + extraVerticalSpace;
}
// Insets are added later, so subtract them now.
x -= insets.left;
y -= insets.top;
mGravity = 0;
if (y + height > dragLayer.getBottom() - insets.bottom) {
// The container is opening off the screen, so just center it in the drag layer instead.
mGravity = Gravity.CENTER_VERTICAL;
// Put the container next to the icon, preferring the right side in ltr (left in rtl).
int rightSide = leftAlignedX + iconWidth - insets.left;
int leftSide = rightAlignedX - iconWidth - insets.left;
if (!mIsRtl) {
if (rightSide + width < dragLayer.getRight()) {
x = rightSide;
mIsLeftAligned = true;
} else {
x = leftSide;
mIsLeftAligned = false;
}
} else {
if (leftSide > dragLayer.getLeft()) {
x = leftSide;
mIsLeftAligned = false;
} else {
x = rightSide;
mIsLeftAligned = true;
}
}
mIsAboveIcon = true;
}
setX(x);
if (Gravity.isVertical(mGravity)) {
return;
}
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
FrameLayout.LayoutParams arrowLp = (FrameLayout.LayoutParams) mArrow.getLayoutParams();
if (mIsAboveIcon) {
arrowLp.gravity = lp.gravity = Gravity.BOTTOM;
lp.bottomMargin = getPopupContainer().getHeight() - y - getMeasuredHeight() - insets.top;
arrowLp.bottomMargin = lp.bottomMargin - arrowLp.height - mArrowOffset - insets.bottom;
} else {
arrowLp.gravity = lp.gravity = Gravity.TOP;
lp.topMargin = y + insets.top;
arrowLp.topMargin = lp.topMargin - insets.top - arrowLp.height - mArrowOffset;
}
}
use of com.android.launcher3.dragndrop.DragLayer in project Neo-Launcher by NeoApplications.
the class WorkspaceTouchListener method onTouch.
@Override
public boolean onTouch(View view, MotionEvent ev) {
mGestureDetector.onTouchEvent(ev);
int action = ev.getActionMasked();
if (action == ACTION_DOWN) {
// Check if we can handle long press.
boolean handleLongPress = canHandleLongPress();
if (handleLongPress) {
// Check if the event is not near the edges
DeviceProfile dp = mLauncher.getDeviceProfile();
DragLayer dl = mLauncher.getDragLayer();
Rect insets = dp.getInsets();
mTempRect.set(insets.left, insets.top, dl.getWidth() - insets.right, dl.getHeight() - insets.bottom);
mTempRect.inset(dp.edgeMarginPx, dp.edgeMarginPx);
handleLongPress = mTempRect.contains((int) ev.getX(), (int) ev.getY());
}
if (handleLongPress) {
mLongPressState = STATE_REQUESTED;
mTouchDownPoint.set(ev.getX(), ev.getY());
mGestureController.setTouchDownPoint(mTouchDownPoint);
}
mWorkspace.onTouchEvent(ev);
// Return true to keep receiving touch events
return true;
}
if (mLongPressState == STATE_PENDING_PARENT_INFORM) {
// Inform the workspace to cancel touch handling
ev.setAction(ACTION_CANCEL);
mWorkspace.onTouchEvent(ev);
ev.setAction(action);
mLongPressState = STATE_COMPLETED;
}
final boolean result;
if (mLongPressState == STATE_COMPLETED) {
// We have handled the touch, so workspace does not need to know anything anymore.
result = true;
} else if (mLongPressState == STATE_REQUESTED) {
mWorkspace.onTouchEvent(ev);
if (mWorkspace.isHandlingTouch()) {
cancelLongPress();
} else if (action == ACTION_MOVE && PointF.length(mTouchDownPoint.x - ev.getX(), mTouchDownPoint.y - ev.getY()) > mTouchSlop) {
cancelLongPress();
}
result = true;
} else {
// We don't want to handle touch, let workspace handle it as usual.
result = false;
}
if (action == ACTION_UP || action == ACTION_POINTER_UP) {
if (!mWorkspace.isTouchActive()) {
final CellLayout currentPage = (CellLayout) mWorkspace.getChildAt(mWorkspace.getCurrentPage());
if (currentPage != null) {
mWorkspace.onWallpaperTap(ev);
}
}
}
if (action == ACTION_UP || action == ACTION_CANCEL) {
cancelLongPress();
}
return result;
}
use of com.android.launcher3.dragndrop.DragLayer in project Neo-Launcher by NeoApplications.
the class Snackbar method show.
public static void show(Launcher launcher, int labelStringResId, int actionStringResId, Runnable onDismissed, Runnable onActionClicked) {
closeOpenViews(launcher, true, TYPE_SNACKBAR);
Snackbar snackbar = new Snackbar(launcher, null);
// Set some properties here since inflated xml only contains the children.
snackbar.setOrientation(HORIZONTAL);
snackbar.setGravity(Gravity.CENTER_VERTICAL);
Resources res = launcher.getResources();
snackbar.setElevation(res.getDimension(R.dimen.snackbar_elevation));
int padding = res.getDimensionPixelSize(R.dimen.snackbar_padding);
snackbar.setPadding(padding, padding, padding, padding);
snackbar.setBackgroundResource(R.drawable.round_rect_primary);
snackbar.mIsOpen = true;
DragLayer dragLayer = launcher.getDragLayer();
dragLayer.addView(snackbar);
DragLayer.LayoutParams params = (DragLayer.LayoutParams) snackbar.getLayoutParams();
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
params.height = res.getDimensionPixelSize(R.dimen.snackbar_height);
int maxMarginLeftRight = res.getDimensionPixelSize(R.dimen.snackbar_max_margin_left_right);
int minMarginLeftRight = res.getDimensionPixelSize(R.dimen.snackbar_min_margin_left_right);
int marginBottom = res.getDimensionPixelSize(R.dimen.snackbar_margin_bottom);
Rect insets = launcher.getDeviceProfile().getInsets();
int maxWidth = dragLayer.getWidth() - minMarginLeftRight * 2 - insets.left - insets.right;
int minWidth = dragLayer.getWidth() - maxMarginLeftRight * 2 - insets.left - insets.right;
params.width = minWidth;
params.setMargins(0, 0, 0, marginBottom + insets.bottom);
TextView labelView = snackbar.findViewById(R.id.label);
TextView actionView = snackbar.findViewById(R.id.action);
String labelText = res.getString(labelStringResId);
String actionText = res.getString(actionStringResId);
int totalContentWidth = (int) (labelView.getPaint().measureText(labelText) + actionView.getPaint().measureText(actionText)) + labelView.getPaddingRight() + labelView.getPaddingLeft() + actionView.getPaddingRight() + actionView.getPaddingLeft() + padding * 2;
if (totalContentWidth > params.width) {
// The text doesn't fit in our standard width so update width to accommodate.
if (totalContentWidth <= maxWidth) {
params.width = totalContentWidth;
} else {
// One line will be cut off, fallback to 2 lines and smaller font. (This should only
// happen in some languages if system display and font size are set to largest.)
int textHeight = res.getDimensionPixelSize(R.dimen.snackbar_content_height);
float textSizePx = res.getDimension(R.dimen.snackbar_min_text_size);
labelView.setLines(2);
labelView.getLayoutParams().height = textHeight * 2;
actionView.getLayoutParams().height = textHeight * 2;
labelView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSizePx);
actionView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSizePx);
params.height += textHeight;
params.width = maxWidth;
}
}
labelView.setText(labelText);
actionView.setText(actionText);
actionView.setOnClickListener(v -> {
if (onActionClicked != null) {
onActionClicked.run();
}
snackbar.mOnDismissed = null;
snackbar.close(true);
});
snackbar.mOnDismissed = onDismissed;
snackbar.setAlpha(0);
snackbar.setScaleX(0.8f);
snackbar.setScaleY(0.8f);
snackbar.animate().alpha(1f).withLayer().scaleX(1).scaleY(1).setDuration(SHOW_DURATION_MS).setInterpolator(Interpolators.ACCEL_DEACCEL).start();
int timeout = AccessibilityManagerCompat.getRecommendedTimeoutMillis(launcher, TIMEOUT_DURATION_MS, FLAG_CONTENT_TEXT | FLAG_CONTENT_CONTROLS);
snackbar.postDelayed(() -> snackbar.close(true), timeout);
}
Aggregations