mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 19:38:21 +00:00
* 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
135 lines
4.9 KiB
Java
135 lines
4.9 KiB
Java
/*
|
|
* 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());
|
|
}
|
|
}
|