Search in sources :

Example 46 with Touch

use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch in project android_packages_apps_Launcher3 by crdroidandroid.

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());
        }
        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.isHandlingTouch()) {
            final CellLayout currentPage = (CellLayout) mWorkspace.getChildAt(mWorkspace.getCurrentPage());
            if (currentPage != null) {
                mWorkspace.onWallpaperTap(ev);
            }
        }
    }
    if (action == ACTION_UP || action == ACTION_CANCEL) {
        cancelLongPress();
    }
    return result;
}
Also used : DeviceProfile(com.android.launcher3.DeviceProfile) DragLayer(com.android.launcher3.dragndrop.DragLayer) Rect(android.graphics.Rect) CellLayout(com.android.launcher3.CellLayout)

Example 47 with Touch

use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch in project Neo-Launcher by NeoApplications.

the class PortraitStatesTouchController method canInterceptTouch.

@Override
protected boolean canInterceptTouch(MotionEvent ev) {
    mStartedFromHotseat = isTouchOverHotseat(mLauncher, ev);
    mGoToOverview = false;
    if (mCurrentAnimation != null) {
        if (mFinishFastOnSecondTouch) {
            // TODO: Animate to finish instead.
            mCurrentAnimation.skipToEnd();
        }
        AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
        if (ev.getY() >= allAppsController.getShiftRange() * allAppsController.getProgress()) {
            // the touch is below the current all apps progress (to allow for double swipe).
            return true;
        }
        // recents, dismiss a task, etc.
        if (mAtomicAnim != null) {
            mAtomicAnim.end();
        }
        return false;
    }
    if (mLauncher.isInState(ALL_APPS)) {
        // In all-apps only listen if the container cannot scroll itself
        if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
            return false;
        }
    } else if (mLauncher.isInState(OVERVIEW)) {
        if (!mOverviewPortraitStateTouchHelper.canInterceptTouch(ev)) {
            return false;
        }
    } else {
        if ((ev.getEdgeFlags() & EDGE_NAV_BAR) != 0) {
            mGoToOverview = true;
        }
        // If we are swiping to all apps instead of overview, allow it from anywhere.
        // boolean interceptAnywhere = mLauncher.isInState(NORMAL) && !mAllowDragToOverview;
        boolean interceptAnywhere = mLauncher.isInState(NORMAL);
        // For all other states, only listen if the event originated below the hotseat height
        if (!interceptAnywhere && !isTouchOverHotseat(mLauncher, ev)) {
            return false;
        }
    }
    if (AbstractFloatingView.getTopOpenViewWithType(mLauncher, TYPE_ACCESSIBLE) != null) {
        return false;
    }
    return true;
}
Also used : AllAppsTransitionController(com.android.launcher3.allapps.AllAppsTransitionController)

Example 48 with Touch

use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch in project Neo-Launcher by NeoApplications.

the class ItemClickHandler method onClick.

private static void onClick(View v, String sourceContainer) {
    // view has detached (it's possible for this to happen if the view is removed mid touch).
    if (v.getWindowToken() == null)
        return;
    Launcher launcher = Launcher.getLauncher(v.getContext());
    if (!launcher.getWorkspace().isFinishedSwitchingState())
        return;
    Object tag = v.getTag();
    if (tag instanceof WorkspaceItemInfo) {
        onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);
    } else if (tag instanceof FolderInfo) {
        if (v instanceof FolderIcon) {
            onClickFolderIcon(v);
        }
    } else if (tag instanceof AppInfo) {
        startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher, sourceContainer == null ? CONTAINER_ALL_APPS : sourceContainer);
        if (Utilities.getOmegaPrefs(launcher).getSortMode() == Config.SORT_MOST_USED) {
            Utilities.getOmegaPrefs(launcher).updateSortApps();
            Log.d(TAG, "Sort Mode Most Used");
        }
    } else if (tag instanceof LauncherAppWidgetInfo) {
        if (v instanceof PendingAppWidgetHostView) {
            onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
        }
    }
}
Also used : FolderIcon(com.android.launcher3.folder.FolderIcon) Launcher(com.android.launcher3.Launcher) LauncherAppWidgetInfo(com.android.launcher3.LauncherAppWidgetInfo) PendingAppWidgetHostView(com.android.launcher3.widget.PendingAppWidgetHostView) FolderInfo(com.android.launcher3.FolderInfo) WorkspaceItemInfo(com.android.launcher3.WorkspaceItemInfo) AppInfo(com.android.launcher3.AppInfo) PromiseAppInfo(com.android.launcher3.PromiseAppInfo)

Example 49 with Touch

use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch in project Neo-Launcher by NeoApplications.

the class AppWidgetResizeFrame method snapToWidget.

private void snapToWidget(boolean animate) {
    getSnappedRectRelativeToDragLayer(sTmpRect);
    int newWidth = sTmpRect.width();
    int newHeight = sTmpRect.height();
    int newX = sTmpRect.left;
    int newY = sTmpRect.top;
    // down accordingly to provide a proper touch target.
    if (newY < 0) {
        // In this case we shift the touch region down to start at the top of the DragLayer
        mTopTouchRegionAdjustment = -newY;
    } else {
        mTopTouchRegionAdjustment = 0;
    }
    if (newY + newHeight > mDragLayer.getHeight()) {
        // In this case we shift the touch region up to end at the bottom of the DragLayer
        mBottomTouchRegionAdjustment = -(newY + newHeight - mDragLayer.getHeight());
    } else {
        mBottomTouchRegionAdjustment = 0;
    }
    final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
    if (!animate) {
        lp.width = newWidth;
        lp.height = newHeight;
        lp.x = newX;
        lp.y = newY;
        for (int i = 0; i < HANDLE_COUNT; i++) {
            mDragHandles[i].setAlpha(1.0f);
        }
        requestLayout();
    } else {
        ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, PropertyValuesHolder.ofInt(LAYOUT_WIDTH, lp.width, newWidth), PropertyValuesHolder.ofInt(LAYOUT_HEIGHT, lp.height, newHeight), PropertyValuesHolder.ofInt(LAYOUT_X, lp.x, newX), PropertyValuesHolder.ofInt(LAYOUT_Y, lp.y, newY));
        mFirstFrameAnimatorHelper.addTo(oa).addUpdateListener(a -> requestLayout());
        AnimatorSet set = new AnimatorSet();
        set.play(oa);
        for (int i = 0; i < HANDLE_COUNT; i++) {
            set.play(mFirstFrameAnimatorHelper.addTo(ObjectAnimator.ofFloat(mDragHandles[i], ALPHA, 1f)));
        }
        set.setDuration(SNAP_DURATION);
        set.start();
    }
    setFocusableInTouchMode(true);
    requestFocus();
}
Also used : DragLayer(com.android.launcher3.dragndrop.DragLayer) ObjectAnimator(android.animation.ObjectAnimator) AnimatorSet(android.animation.AnimatorSet) Point(android.graphics.Point)

Example 50 with Touch

use of com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch in project Neo-Launcher by NeoApplications.

the class GridSizeMigrationTask method migrateScreen.

/**
 * Migrate a particular screen id.
 * Strategy:
 *   1) For all possible combinations of row and column, pick the one which causes the least
 *      data loss: {@link #tryRemove(int, int, int, ArrayList, float[])}
 *   2) Maintain a list of all lost items before this screen, and add any new item lost from
 *      this screen to that list as well.
 *   3) If all those items from the above list can be placed on this screen, place them
 *      (otherwise they are placed on a new screen).
 */
protected void migrateScreen(int screenId) {
    // If we are migrating the first screen, do not touch the first row.
    int startY = (FeatureFlags.QSB_ON_FIRST_SCREEN && screenId == Workspace.FIRST_SCREEN_ID) ? 1 : 0;
    ArrayList<DbEntry> items = loadWorkspaceEntries(screenId);
    int removedCol = Integer.MAX_VALUE;
    int removedRow = Integer.MAX_VALUE;
    // removeWt represents the cost function for loss of items during migration, and moveWt
    // represents the cost function for repositioning the items. moveWt is only considered if
    // removeWt is same for two different configurations.
    // Start with Float.MAX_VALUE (assuming full data) and pick the configuration with least
    // cost.
    float removeWt = Float.MAX_VALUE;
    float moveWt = Float.MAX_VALUE;
    float[] outLoss = new float[2];
    ArrayList<DbEntry> finalItems = null;
    // Try removing all possible combinations
    for (int x = 0; x < mSrcX; x++) {
        // nicely aligned with hotseat.
        for (int y = mSrcY - 1; y >= startY; y--) {
            // Use a deep copy when trying out a particular combination as it can change
            // the underlying object.
            ArrayList<DbEntry> itemsOnScreen = tryRemove(x, y, startY, deepCopy(items), outLoss);
            if ((outLoss[0] < removeWt) || ((outLoss[0] == removeWt) && (outLoss[1] < moveWt))) {
                removeWt = outLoss[0];
                moveWt = outLoss[1];
                removedCol = mShouldRemoveX ? x : removedCol;
                removedRow = mShouldRemoveY ? y : removedRow;
                finalItems = itemsOnScreen;
            }
            // No need to loop over all rows, if a row removal is not needed.
            if (!mShouldRemoveY) {
                break;
            }
        }
        if (!mShouldRemoveX) {
            break;
        }
    }
    if (DEBUG) {
        Log.d(TAG, String.format("Removing row %d, column %d on screen %d", removedRow, removedCol, screenId));
    }
    IntSparseArrayMap<DbEntry> itemMap = new IntSparseArrayMap<>();
    for (DbEntry e : deepCopy(items)) {
        itemMap.put(e.id, e);
    }
    for (DbEntry item : finalItems) {
        DbEntry org = itemMap.get(item.id);
        itemMap.remove(item.id);
        // Check if update is required
        if (!item.columnsSame(org)) {
            update(item);
        }
    }
    // The remaining items in {@link #itemMap} are those which didn't get placed.
    for (DbEntry item : itemMap) {
        mCarryOver.add(item);
    }
    if (!mCarryOver.isEmpty() && removeWt == 0) {
        // No new items were removed in this step. Try placing all the items on this screen.
        GridOccupancy occupied = new GridOccupancy(mTrgX, mTrgY);
        occupied.markCells(0, 0, mTrgX, startY, true);
        for (DbEntry item : finalItems) {
            occupied.markCells(item, true);
        }
        OptimalPlacementSolution placement = new OptimalPlacementSolution(occupied, deepCopy(mCarryOver), startY, true);
        placement.find();
        if (placement.lowestWeightLoss == 0) {
            for (DbEntry item : placement.finalPlacedItems) {
                item.screenId = screenId;
                update(item);
            }
            mCarryOver.clear();
        }
    }
}
Also used : IntSparseArrayMap(com.android.launcher3.util.IntSparseArrayMap) GridOccupancy(com.android.launcher3.util.GridOccupancy) Utilities.parsePoint(com.android.launcher3.Utilities.parsePoint) Point(android.graphics.Point)

Aggregations

Point (android.graphics.Point)32 Rect (android.graphics.Rect)28 Intent (android.content.Intent)20 View (android.view.View)17 DragLayer (com.android.launcher3.dragndrop.DragLayer)14 DropTarget (com.android.launcher3.DropTarget)13 WorkspaceItemInfo (com.android.launcher3.model.data.WorkspaceItemInfo)13 ClipData (android.content.ClipData)12 ClipDescription (android.content.ClipDescription)12 Canvas (android.graphics.Canvas)12 DragView (com.android.launcher3.dragndrop.DragView)12 PendingAppWidgetHostView (com.android.launcher3.widget.PendingAppWidgetHostView)12 DraggableView (com.android.launcher3.dragndrop.DraggableView)10 DeviceProfile (com.android.launcher3.DeviceProfile)8 FolderIcon (com.android.launcher3.folder.FolderIcon)8 AnimatorSet (android.animation.AnimatorSet)7 ObjectAnimator (android.animation.ObjectAnimator)7 SuppressLint (android.annotation.SuppressLint)7 Drawable (android.graphics.drawable.Drawable)7 DragShadowBuilder (android.view.View.DragShadowBuilder)7