mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-04 01:46:49 +00:00
Extend recents button hitbox on tablet
* Extends hitbox when recents is tapped when going from taskbar to overview. * Extended region lasts for 400ms after the animation ends. Fixes: 225885714 Test: Manual, added unit test Change-Id: I8766279c1a5bf6867f8d69ddd3af2aa3565deec2
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.TouchDelegate;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Extends the Recents touch area during the taskbar to overview animation
|
||||
* to give user some error room when trying to quickly double tap recents button since it moves.
|
||||
*
|
||||
* Listens for icon alignment as our indication for the animation.
|
||||
*/
|
||||
public class RecentsHitboxExtender implements TouchController {
|
||||
|
||||
private static final int RECENTS_HITBOX_TIMEOUT_MS = 500;
|
||||
|
||||
private View mRecentsButton;
|
||||
private View mRecentsParent;
|
||||
private DeviceProfile mDeviceProfile;
|
||||
private Supplier<float[]> mParentCoordSupplier;
|
||||
private TouchDelegate mRecentsTouchDelegate;
|
||||
/**
|
||||
* Will be true while the animation from taskbar to overview is occurring.
|
||||
* Lifecycle of this variable slightly extends past the animation by
|
||||
* {@link #RECENTS_HITBOX_TIMEOUT_MS}, so can use this variable as a proxy for if
|
||||
* the current hitbox is extended or not.
|
||||
*/
|
||||
private boolean mAnimatingFromTaskbarToOverview;
|
||||
private float mLastIconAlignment;
|
||||
private final Rect mRecentsHitBox = new Rect();
|
||||
private boolean mRecentsButtonClicked;
|
||||
private Handler mHandler;
|
||||
private final Runnable mRecentsHitboxResetRunnable = this::reset;
|
||||
|
||||
public void init(View recentsButton, View recentsParent, DeviceProfile deviceProfile,
|
||||
Supplier<float[]> parentCoordSupplier, Handler handler) {
|
||||
mRecentsButton = recentsButton;
|
||||
mRecentsParent = recentsParent;
|
||||
mDeviceProfile = deviceProfile;
|
||||
mParentCoordSupplier = parentCoordSupplier;
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
public void onRecentsButtonClicked() {
|
||||
mRecentsButtonClicked = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param progress 0 -> Taskbar, 1 -> Overview
|
||||
*/
|
||||
public void onAnimationProgressToOverview(float progress) {
|
||||
if (progress == 1 || progress == 0) {
|
||||
// Done w/ animation
|
||||
mLastIconAlignment = progress;
|
||||
if (mAnimatingFromTaskbarToOverview) {
|
||||
if (progress == 1) {
|
||||
// Finished animation to workspace, remove the touch delegate shortly
|
||||
mHandler.postDelayed(mRecentsHitboxResetRunnable, RECENTS_HITBOX_TIMEOUT_MS);
|
||||
return;
|
||||
} else {
|
||||
// Went back to taskbar, reset immediately
|
||||
mHandler.removeCallbacks(mRecentsHitboxResetRunnable);
|
||||
reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mAnimatingFromTaskbarToOverview) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (progress > 0 && mLastIconAlignment == 0 && mRecentsButtonClicked) {
|
||||
// Starting animation, previously we were showing taskbar
|
||||
mAnimatingFromTaskbarToOverview = true;
|
||||
float[] recentsCoords = mParentCoordSupplier.get();
|
||||
int x = (int) recentsCoords[0];
|
||||
int y = (int) (recentsCoords[1]);
|
||||
// Extend hitbox vertically by the offset amount from mDeviceProfile.getTaskbarOffsetY()
|
||||
mRecentsHitBox.set(x, y,
|
||||
x + mRecentsButton.getWidth(),
|
||||
y + mRecentsButton.getHeight() + mDeviceProfile.getTaskbarOffsetY()
|
||||
);
|
||||
mRecentsTouchDelegate = new TouchDelegate(mRecentsHitBox, mRecentsButton);
|
||||
mRecentsParent.setTouchDelegate(mRecentsTouchDelegate);
|
||||
}
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
mAnimatingFromTaskbarToOverview = false;
|
||||
mRecentsButton.setTouchDelegate(null);
|
||||
mRecentsHitBox.setEmpty();
|
||||
mRecentsButtonClicked = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the bounds for recents touches are currently extended
|
||||
*/
|
||||
public boolean extendedHitboxEnabled() {
|
||||
return mAnimatingFromTaskbarToOverview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onControllerTouchEvent(MotionEvent ev) {
|
||||
return mRecentsTouchDelegate.onTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
|
||||
return mRecentsHitBox.contains((int)ev.getX(), (int)ev.getY());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user