mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-02 17:06:49 +00:00
Add TaskbarView as a child of Hotseat
Instead of keeping the Taskbar window showing above the home screen, we now integrate a copy of TaskbarView directly into Launcher's view hierarchy. Most TaskbarController calls apply to both TaskbarViews (mTaskbarViewInApp and mTaskbarViewOnHome), except for calls related to Hotseat, which only apply to mTasbkarViewInApp given the real Hotseat will be showing with mTaskbarViewOnHome. More cleanup will follow this change. Test: All taskbar interactions (e.g. drag and drop) continue to work Bug: 182512211 Bug: 171917176 Change-Id: I0f0b124f652daa85f866e1df8f9e2981540331a0
This commit is contained in:
@@ -19,8 +19,6 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_TASKBAR;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_REPLACE_TASKBAR_WITH_HOTSEAT;
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
|
||||
@@ -43,7 +41,6 @@ import androidx.annotation.Nullable;
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Hotseat;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.QuickstepTransitionManager;
|
||||
import com.android.launcher3.R;
|
||||
@@ -54,6 +51,7 @@ import com.android.launcher3.model.data.FolderInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.touch.ItemClickHandler;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
@@ -70,7 +68,8 @@ public class TaskbarController {
|
||||
private static final String WINDOW_TITLE = "Taskbar";
|
||||
|
||||
private final TaskbarContainerView mTaskbarContainerView;
|
||||
private final TaskbarView mTaskbarView;
|
||||
private final TaskbarView mTaskbarViewInApp;
|
||||
private final TaskbarView mTaskbarViewOnHome;
|
||||
private final BaseQuickstepLauncher mLauncher;
|
||||
private final WindowManager mWindowManager;
|
||||
// Layout width and height of the Taskbar in the default state.
|
||||
@@ -91,14 +90,17 @@ public class TaskbarController {
|
||||
|
||||
private @Nullable Animator mAnimator;
|
||||
private boolean mIsAnimatingToLauncher;
|
||||
private boolean mIsAnimatingToApp;
|
||||
|
||||
public TaskbarController(BaseQuickstepLauncher launcher,
|
||||
TaskbarContainerView taskbarContainerView) {
|
||||
TaskbarContainerView taskbarContainerView, TaskbarView taskbarViewOnHome) {
|
||||
mLauncher = launcher;
|
||||
mTaskbarContainerView = taskbarContainerView;
|
||||
mTaskbarContainerView.construct(createTaskbarContainerViewCallbacks());
|
||||
mTaskbarView = mTaskbarContainerView.findViewById(R.id.taskbar_view);
|
||||
mTaskbarView.construct(createTaskbarViewCallbacks());
|
||||
mTaskbarViewInApp = mTaskbarContainerView.findViewById(R.id.taskbar_view);
|
||||
mTaskbarViewInApp.construct(createTaskbarViewCallbacks());
|
||||
mTaskbarViewOnHome = taskbarViewOnHome;
|
||||
mTaskbarViewOnHome.construct(createTaskbarViewCallbacks());
|
||||
mWindowManager = mLauncher.getWindowManager();
|
||||
mTaskbarSize = new Point(MATCH_PARENT, mLauncher.getDeviceProfile().taskbarSize);
|
||||
mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
|
||||
@@ -115,12 +117,13 @@ public class TaskbarController {
|
||||
return new TaskbarVisibilityControllerCallbacks() {
|
||||
@Override
|
||||
public void updateTaskbarBackgroundAlpha(float alpha) {
|
||||
mTaskbarView.setBackgroundAlpha(alpha);
|
||||
mTaskbarViewInApp.setBackgroundAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTaskbarVisibilityAlpha(float alpha) {
|
||||
mTaskbarContainerView.setAlpha(alpha);
|
||||
mTaskbarViewOnHome.setAlpha(alpha);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -196,7 +199,7 @@ public class TaskbarController {
|
||||
public View.OnLongClickListener getItemOnLongClickListener() {
|
||||
return view -> {
|
||||
if (mLauncher.hasBeenResumed() && view.getTag() instanceof ItemInfo) {
|
||||
alignRealHotseatWithTaskbar();
|
||||
// TODO: remove this path
|
||||
return mDragController.startWorkspaceDragOnLongClick(view);
|
||||
} else {
|
||||
return mDragController.startSystemDragOnLongClick(view);
|
||||
@@ -205,11 +208,24 @@ public class TaskbarController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmptyHotseatViewVisibility() {
|
||||
public int getEmptyHotseatViewVisibility(TaskbarView taskbarView) {
|
||||
// When on the home screen, we want the empty hotseat views to take up their full
|
||||
// space so that the others line up with the home screen hotseat.
|
||||
return mLauncher.hasBeenResumed() || mIsAnimatingToLauncher
|
||||
? View.INVISIBLE : View.GONE;
|
||||
boolean isOnHomeScreen = taskbarView == mTaskbarViewOnHome
|
||||
|| mLauncher.hasBeenResumed() || mIsAnimatingToLauncher;
|
||||
return isOnHomeScreen ? View.INVISIBLE : View.GONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getNonIconScale(TaskbarView taskbarView) {
|
||||
return taskbarView == mTaskbarViewOnHome ? getTaskbarScaleOnHome() : 1f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemPositionsChanged(TaskbarView taskbarView) {
|
||||
if (taskbarView == mTaskbarViewOnHome) {
|
||||
alignRealHotseatWithTaskbar();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -218,7 +234,7 @@ public class TaskbarController {
|
||||
return new TaskbarHotseatControllerCallbacks() {
|
||||
@Override
|
||||
public void updateHotseatItems(ItemInfo[] hotseatItemInfos) {
|
||||
mTaskbarView.updateHotseatItems(hotseatItemInfos);
|
||||
mTaskbarViewInApp.updateHotseatItems(hotseatItemInfos);
|
||||
mLatestLoadedHotseatItems = hotseatItemInfos;
|
||||
dedupeAndUpdateRecentItems();
|
||||
}
|
||||
@@ -235,7 +251,8 @@ public class TaskbarController {
|
||||
|
||||
@Override
|
||||
public void updateRecentTaskAtIndex(int taskIndex, Task task) {
|
||||
mTaskbarView.updateRecentTaskAtIndex(taskIndex, task);
|
||||
mTaskbarViewInApp.updateRecentTaskAtIndex(taskIndex, task);
|
||||
mTaskbarViewOnHome.updateRecentTaskAtIndex(taskIndex, task);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -244,16 +261,20 @@ public class TaskbarController {
|
||||
* Initializes the Taskbar, including adding it to the screen.
|
||||
*/
|
||||
public void init() {
|
||||
mTaskbarView.init(mHotseatController.getNumHotseatIcons(),
|
||||
mTaskbarViewInApp.init(mHotseatController.getNumHotseatIcons(),
|
||||
mRecentsController.getNumRecentIcons());
|
||||
mTaskbarContainerView.init(mTaskbarView);
|
||||
mTaskbarViewOnHome.init(mHotseatController.getNumHotseatIcons(),
|
||||
mRecentsController.getNumRecentIcons());
|
||||
mTaskbarContainerView.init(mTaskbarViewInApp);
|
||||
addToWindowManager();
|
||||
mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks());
|
||||
mTaskbarVisibilityController.init();
|
||||
mHotseatController.init();
|
||||
mRecentsController.init();
|
||||
|
||||
SCALE_PROPERTY.set(mTaskbarView, mLauncher.hasBeenResumed() ? getTaskbarScaleOnHome() : 1f);
|
||||
SCALE_PROPERTY.set(mTaskbarViewInApp, mLauncher.hasBeenResumed()
|
||||
? getTaskbarScaleOnHome() : 1f);
|
||||
updateWhichTaskbarViewIsVisible();
|
||||
}
|
||||
|
||||
private TaskbarStateHandlerCallbacks createTaskbarStateHandlerCallbacks() {
|
||||
@@ -274,7 +295,8 @@ public class TaskbarController {
|
||||
mAnimator.end();
|
||||
}
|
||||
|
||||
mTaskbarView.cleanup();
|
||||
mTaskbarViewInApp.cleanup();
|
||||
mTaskbarViewOnHome.cleanup();
|
||||
mTaskbarContainerView.cleanup();
|
||||
removeFromWindowManager();
|
||||
mTaskbarStateHandler.setTaskbarCallbacks(null);
|
||||
@@ -313,7 +335,7 @@ public class TaskbarController {
|
||||
TaskbarContainerView.LayoutParams taskbarLayoutParams =
|
||||
new TaskbarContainerView.LayoutParams(mTaskbarSize.x, mTaskbarSize.y);
|
||||
taskbarLayoutParams.gravity = gravity;
|
||||
mTaskbarView.setLayoutParams(taskbarLayoutParams);
|
||||
mTaskbarViewInApp.setLayoutParams(taskbarLayoutParams);
|
||||
|
||||
mWindowManager.addView(mTaskbarContainerView, mWindowLayoutParams);
|
||||
}
|
||||
@@ -330,7 +352,6 @@ public class TaskbarController {
|
||||
mAnimator = createAnimToLauncher(null, duration);
|
||||
} else {
|
||||
mAnimator = createAnimToApp(duration);
|
||||
replaceTaskbarWithHotseatOrViceVersa();
|
||||
}
|
||||
mAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
@@ -351,36 +372,41 @@ public class TaskbarController {
|
||||
if (toState != null) {
|
||||
mTaskbarStateHandler.setStateWithAnimation(toState, new StateAnimationConfig(), anim);
|
||||
}
|
||||
anim.addFloat(mTaskbarView, SCALE_PROPERTY, mTaskbarView.getScaleX(),
|
||||
anim.addFloat(mTaskbarViewInApp, SCALE_PROPERTY, mTaskbarViewInApp.getScaleX(),
|
||||
getTaskbarScaleOnHome(), LINEAR);
|
||||
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mIsAnimatingToLauncher = true;
|
||||
mTaskbarView.updateHotseatItemsVisibility();
|
||||
mTaskbarViewInApp.updateHotseatItemsVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mIsAnimatingToLauncher = false;
|
||||
updateWhichTaskbarViewIsVisible();
|
||||
}
|
||||
});
|
||||
|
||||
anim.addOnFrameCallback(this::alignRealHotseatWithTaskbar);
|
||||
|
||||
return anim.buildAnim();
|
||||
}
|
||||
|
||||
private Animator createAnimToApp(long duration) {
|
||||
PendingAnimation anim = new PendingAnimation(duration);
|
||||
anim.add(mTaskbarVisibilityController.createAnimToBackgroundAlpha(1, duration));
|
||||
anim.addFloat(mTaskbarView, SCALE_PROPERTY, mTaskbarView.getScaleX(), 1f, LINEAR);
|
||||
anim.addFloat(mTaskbarViewInApp, SCALE_PROPERTY, mTaskbarViewInApp.getScaleX(), 1f, LINEAR);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mTaskbarView.updateHotseatItemsVisibility();
|
||||
setReplaceTaskbarWithHotseat(false);
|
||||
mIsAnimatingToApp = true;
|
||||
mTaskbarViewInApp.updateHotseatItemsVisibility();
|
||||
updateWhichTaskbarViewIsVisible();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mIsAnimatingToApp = false;
|
||||
}
|
||||
});
|
||||
return anim.buildAnim();
|
||||
@@ -405,11 +431,11 @@ public class TaskbarController {
|
||||
* @return Whether any Taskbar item could handle the given MotionEvent if given the chance.
|
||||
*/
|
||||
public boolean isEventOverAnyTaskbarItem(MotionEvent ev) {
|
||||
return mTaskbarView.isEventOverAnyItem(ev);
|
||||
return mTaskbarViewInApp.isEventOverAnyItem(ev);
|
||||
}
|
||||
|
||||
public boolean isDraggingItem() {
|
||||
return mTaskbarView.isDraggingItem();
|
||||
return mTaskbarViewInApp.isDraggingItem() || mTaskbarViewOnHome.isDraggingItem();
|
||||
}
|
||||
|
||||
private void dedupeAndUpdateRecentItems() {
|
||||
@@ -454,7 +480,8 @@ public class TaskbarController {
|
||||
tasksArray[tasksArray.length - 1 - i] = task;
|
||||
}
|
||||
|
||||
mTaskbarView.updateRecentTasks(tasksArray);
|
||||
mTaskbarViewInApp.updateRecentTasks(tasksArray);
|
||||
mTaskbarViewOnHome.updateRecentTasks(tasksArray);
|
||||
mRecentsController.loadIconsForTasks(tasksArray);
|
||||
}
|
||||
|
||||
@@ -475,10 +502,11 @@ public class TaskbarController {
|
||||
int hotseatHeight = grid.workspacePadding.bottom + grid.taskbarSize;
|
||||
int hotseatTopDiff = hotseatHeight - grid.taskbarSize;
|
||||
|
||||
mTaskbarView.getHotseatBoundsAtScale(getTaskbarScaleOnHome()).roundOut(hotseatBounds);
|
||||
mLauncher.getHotseat().setPadding(hotseatBounds.left, hotseatBounds.top + hotseatTopDiff,
|
||||
mTaskbarView.getWidth() - hotseatBounds.right,
|
||||
mTaskbarView.getHeight() - hotseatBounds.bottom);
|
||||
mTaskbarViewOnHome.getHotseatBounds().roundOut(hotseatBounds);
|
||||
mLauncher.getHotseat().setPadding(hotseatBounds.left,
|
||||
hotseatBounds.top + hotseatTopDiff,
|
||||
mTaskbarViewOnHome.getWidth() - hotseatBounds.right,
|
||||
mTaskbarViewOnHome.getHeight() - hotseatBounds.bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -486,36 +514,32 @@ public class TaskbarController {
|
||||
* show the real one instead.
|
||||
*/
|
||||
public void onLauncherDragLayerHierarchyChanged() {
|
||||
replaceTaskbarWithHotseatOrViceVersa();
|
||||
// TODO: remove, as this is a no-op now
|
||||
}
|
||||
|
||||
private void replaceTaskbarWithHotseatOrViceVersa() {
|
||||
boolean replaceTaskbarWithHotseat = AbstractFloatingView.getTopOpenViewWithType(mLauncher,
|
||||
TYPE_REPLACE_TASKBAR_WITH_HOTSEAT) != null;
|
||||
if (!mLauncher.hasBeenResumed()) {
|
||||
replaceTaskbarWithHotseat = false;
|
||||
}
|
||||
setReplaceTaskbarWithHotseat(replaceTaskbarWithHotseat);
|
||||
|
||||
boolean hideTaskbar = AbstractFloatingView.getTopOpenViewWithType(mLauncher,
|
||||
TYPE_HIDE_TASKBAR) != null;
|
||||
mTaskbarVisibilityController.animateToVisibilityForFloatingView(hideTaskbar ? 0f : 1f);
|
||||
}
|
||||
|
||||
private void setReplaceTaskbarWithHotseat(boolean replaceTaskbarWithHotseat) {
|
||||
Hotseat hotseat = mLauncher.getHotseat();
|
||||
if (replaceTaskbarWithHotseat) {
|
||||
alignRealHotseatWithTaskbar();
|
||||
hotseat.getReplaceTaskbarAlpha().setValue(1f);
|
||||
mTaskbarView.setHotseatViewsHidden(true);
|
||||
private void updateWhichTaskbarViewIsVisible() {
|
||||
boolean isInApp = !mLauncher.hasBeenResumed() || mIsAnimatingToLauncher
|
||||
|| mIsAnimatingToApp;
|
||||
if (isInApp) {
|
||||
mTaskbarViewInApp.setVisibility(View.VISIBLE);
|
||||
mTaskbarViewOnHome.setVisibility(View.INVISIBLE);
|
||||
mLauncher.getHotseat().setIconsAlpha(0);
|
||||
} else {
|
||||
hotseat.getReplaceTaskbarAlpha().setValue(0f);
|
||||
mTaskbarView.setHotseatViewsHidden(false);
|
||||
mTaskbarViewInApp.setVisibility(View.INVISIBLE);
|
||||
mTaskbarViewOnHome.setVisibility(View.VISIBLE);
|
||||
mLauncher.getHotseat().setIconsAlpha(1);
|
||||
}
|
||||
}
|
||||
|
||||
private float getTaskbarScaleOnHome() {
|
||||
return 1f / mTaskbarContainerView.getTaskbarActivityContext().getTaskbarIconScale();
|
||||
/**
|
||||
* Returns the ratio of the taskbar icon size on home vs in an app.
|
||||
*/
|
||||
public float getTaskbarScaleOnHome() {
|
||||
DeviceProfile inAppDp = mTaskbarContainerView.getTaskbarActivityContext()
|
||||
.getDeviceProfile();
|
||||
DeviceProfile onHomeDp = ActivityContext.lookupContext(mTaskbarViewOnHome.getContext())
|
||||
.getDeviceProfile();
|
||||
return (float) onHomeDp.cellWidthPx / inAppDp.cellWidthPx;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -561,7 +585,10 @@ public class TaskbarController {
|
||||
protected interface TaskbarViewCallbacks {
|
||||
View.OnClickListener getItemOnClickListener();
|
||||
View.OnLongClickListener getItemOnLongClickListener();
|
||||
int getEmptyHotseatViewVisibility();
|
||||
int getEmptyHotseatViewVisibility(TaskbarView taskbarView);
|
||||
/** Returns how much to scale non-icon elements such as spacing and dividers. */
|
||||
float getNonIconScale(TaskbarView taskbarView);
|
||||
void onItemPositionsChanged(TaskbarView taskbarView);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user