mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-18 18:28:20 +00:00
Merge "Allow split with an existing split task" into tm-dev
This commit is contained in:
@@ -469,13 +469,19 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
|
||||
}
|
||||
});
|
||||
mReturnAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
private boolean mCanceled = false;
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
cleanUpSurface();
|
||||
mCanceled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mCanceled) {
|
||||
return;
|
||||
}
|
||||
cleanUpSurface();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,8 +48,6 @@ public class FloatingTaskView extends FrameLayout {
|
||||
|
||||
private SplitPlaceholderView mSplitPlaceholderView;
|
||||
private RectF mStartingPosition;
|
||||
@Nullable
|
||||
private Consumer<RectF> mAdditionalOffsetter;
|
||||
private final StatefulActivity mActivity;
|
||||
private final boolean mIsRtl;
|
||||
private final Rect mOutline = new Rect();
|
||||
@@ -81,9 +79,8 @@ public class FloatingTaskView extends FrameLayout {
|
||||
}
|
||||
|
||||
private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail,
|
||||
Drawable icon, RectF positionOut, Consumer<RectF> additionalOffsetter) {
|
||||
Drawable icon, RectF positionOut) {
|
||||
mStartingPosition = positionOut;
|
||||
mAdditionalOffsetter = additionalOffsetter;
|
||||
updateInitialPositionForView(originalView);
|
||||
final InsettableFrameLayout.LayoutParams lp =
|
||||
(InsettableFrameLayout.LayoutParams) getLayoutParams();
|
||||
@@ -113,15 +110,13 @@ public class FloatingTaskView extends FrameLayout {
|
||||
* translation values from originalView will be used
|
||||
*/
|
||||
public static FloatingTaskView getFloatingTaskView(StatefulActivity launcher,
|
||||
View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut,
|
||||
@Nullable Consumer<RectF> additionalOffsetter) {
|
||||
View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut) {
|
||||
final BaseDragLayer dragLayer = launcher.getDragLayer();
|
||||
ViewGroup parent = (ViewGroup) dragLayer.getParent();
|
||||
final FloatingTaskView floatingView = (FloatingTaskView) launcher.getLayoutInflater()
|
||||
.inflate(R.layout.floating_split_select_view, parent, false);
|
||||
|
||||
floatingView.init(launcher, originalView, thumbnail, icon, positionOut,
|
||||
additionalOffsetter);
|
||||
floatingView.init(launcher, originalView, thumbnail, icon, positionOut);
|
||||
parent.addView(floatingView);
|
||||
return floatingView;
|
||||
}
|
||||
@@ -129,14 +124,8 @@ public class FloatingTaskView extends FrameLayout {
|
||||
public void updateInitialPositionForView(View originalView) {
|
||||
Rect viewBounds = new Rect(0, 0, originalView.getWidth(), originalView.getHeight());
|
||||
Utilities.getBoundsForViewInDragLayer(mActivity.getDragLayer(), originalView, viewBounds,
|
||||
true /* ignoreTransform */, null /* recycle */,
|
||||
false /* ignoreTransform */, null /* recycle */,
|
||||
mStartingPosition);
|
||||
if (mAdditionalOffsetter != null) {
|
||||
mAdditionalOffsetter.accept(mStartingPosition);
|
||||
} else {
|
||||
mStartingPosition.offset(originalView.getTranslationX(),
|
||||
originalView.getTranslationY());
|
||||
}
|
||||
final InsettableFrameLayout.LayoutParams lp = new InsettableFrameLayout.LayoutParams(
|
||||
Math.round(mStartingPosition.width()),
|
||||
Math.round(mStartingPosition.height()));
|
||||
|
||||
@@ -5,14 +5,17 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
|
||||
import com.android.launcher3.util.TransformingTouchDelegate;
|
||||
@@ -52,7 +55,6 @@ public class GroupedTaskView extends TaskView {
|
||||
@Nullable private StagedSplitBounds mSplitBoundsConfig;
|
||||
private final DigitalWellBeingToast mDigitalWellBeingToast2;
|
||||
|
||||
|
||||
public GroupedTaskView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -204,6 +206,20 @@ public class GroupedTaskView extends TaskView {
|
||||
return new TaskThumbnailView[]{mSnapshotView, mSnapshotView2};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getChildTaskIndexAtPosition(PointF position) {
|
||||
if (isCoordInView(mIconView2, position) || isCoordInView(mSnapshotView2, position)) {
|
||||
return 1;
|
||||
}
|
||||
return super.getChildTaskIndexAtPosition(position);
|
||||
}
|
||||
|
||||
private boolean isCoordInView(View v, PointF position) {
|
||||
float[] localPos = new float[]{position.x, position.y};
|
||||
Utilities.mapCoordInSelfToDescendant(v, this, localPos);
|
||||
return Utilities.pointInView(v, localPos[0], localPos[1], 0f /* slop */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecycle() {
|
||||
super.onRecycle();
|
||||
|
||||
@@ -619,7 +619,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
@Nullable
|
||||
private TaskView mSplitHiddenTaskView;
|
||||
@Nullable
|
||||
private TaskView mSecondSplitHiddenTaskView;
|
||||
private View mSecondSplitHiddenView;
|
||||
@Nullable
|
||||
private StagedSplitBounds mSplitBoundsConfig;
|
||||
private final Toast mSplitToast = Toast.makeText(getContext(),
|
||||
@@ -2729,11 +2729,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
|
||||
mSplitHiddenTaskView.getThumbnail(),
|
||||
mSplitHiddenTaskView.getThumbnail().getThumbnail(),
|
||||
mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect,
|
||||
floatingTaskViewStartingPosition -> floatingTaskViewStartingPosition.offset(
|
||||
mSplitHiddenTaskView.getTranslationX(),
|
||||
mSplitHiddenTaskView.getTranslationY()
|
||||
));
|
||||
mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect);
|
||||
mFirstFloatingTaskView.setAlpha(1);
|
||||
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
|
||||
mTempRect, true /*fadeWithThumbnail*/);
|
||||
@@ -2741,7 +2737,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mSplitSelectSource.view.setVisibility(INVISIBLE);
|
||||
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
|
||||
mSplitSelectSource.view, null,
|
||||
mSplitSelectSource.drawable, startingTaskRect, null /*additionalOffsetter*/);
|
||||
mSplitSelectSource.drawable, startingTaskRect);
|
||||
mFirstFloatingTaskView.setAlpha(1);
|
||||
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
|
||||
mTempRect, true /*fadeWithThumbnail*/);
|
||||
@@ -4004,9 +4000,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
}
|
||||
|
||||
public void confirmSplitSelect(TaskView taskView) {
|
||||
/**
|
||||
* Confirms the selection of the next split task. The extra data is passed through because the
|
||||
* user may be selecting a subtask in a group.
|
||||
*/
|
||||
public void confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
|
||||
TaskThumbnailView thumbnailView) {
|
||||
mSplitToast.cancel();
|
||||
if (!taskView.getTask().isDockable) {
|
||||
if (!task.isDockable) {
|
||||
// Task not split screen supported
|
||||
mSplitUnsupportedToast.show();
|
||||
return;
|
||||
@@ -4032,20 +4033,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
false /*fadeWithThumbnail*/);
|
||||
|
||||
mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
|
||||
taskView.getThumbnail(), taskView.getThumbnail().getThumbnail(),
|
||||
taskView.getIconView().getDrawable(), secondTaskStartingBounds,
|
||||
floatingTaskViewStartingPosition -> floatingTaskViewStartingPosition.offset(
|
||||
taskView.getTranslationX(),
|
||||
taskView.getTranslationY()
|
||||
));
|
||||
thumbnailView, thumbnailView.getThumbnail(),
|
||||
iconView.getDrawable(), secondTaskStartingBounds);
|
||||
mSecondFloatingTaskView.setAlpha(1);
|
||||
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
|
||||
secondTaskEndingBounds, true /*fadeWithThumbnail*/);
|
||||
secondTaskEndingBounds, true /* fadeWithThumbnail */);
|
||||
pendingAnimation.addEndListener(aBoolean ->
|
||||
mSplitSelectStateController.setSecondTaskId(taskView.getTask().key.id,
|
||||
mSplitSelectStateController.setSecondTaskId(task.key.id,
|
||||
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
|
||||
mSecondSplitHiddenTaskView = taskView;
|
||||
taskView.setVisibility(INVISIBLE);
|
||||
if (containerTaskView.containsMultipleTasks()) {
|
||||
// If we are launching from a child task, then only hide the thumbnail itself
|
||||
mSecondSplitHiddenView = thumbnailView;
|
||||
} else {
|
||||
mSecondSplitHiddenView = containerTaskView;
|
||||
}
|
||||
mSecondSplitHiddenView.setVisibility(INVISIBLE);
|
||||
pendingAnimation.buildAnim().start();
|
||||
}
|
||||
|
||||
@@ -4059,8 +4061,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (mSecondFloatingTaskView != null) {
|
||||
mActivity.getRootView().removeView(mSecondFloatingTaskView);
|
||||
mSecondFloatingTaskView = null;
|
||||
mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
|
||||
mSecondSplitHiddenTaskView = null;
|
||||
mSecondSplitHiddenView.setVisibility(VISIBLE);
|
||||
mSecondSplitHiddenView = null;
|
||||
}
|
||||
mSplitSelectSource = null;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import android.app.ActivityOptions;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -426,8 +427,11 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
private final float[] mIconCenterCoords = new float[2];
|
||||
|
||||
private final PointF mLastTouchDownPosition = new PointF();
|
||||
|
||||
private boolean mIsClickableAsLiveTile = true;
|
||||
|
||||
|
||||
public TaskView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -600,6 +604,14 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
return mIconView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
mLastTouchDownPosition.set(ev.getX(), ev.getY());
|
||||
}
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
private void onClick(View view) {
|
||||
if (getTask() == null) {
|
||||
return;
|
||||
@@ -688,11 +700,21 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
private boolean confirmSecondSplitSelectApp() {
|
||||
boolean isSelectingSecondSplitApp = getRecentsView().isSplitSelectionActive();
|
||||
if (isSelectingSecondSplitApp) {
|
||||
getRecentsView().confirmSplitSelect(this);
|
||||
int index = getChildTaskIndexAtPosition(mLastTouchDownPosition);
|
||||
TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
|
||||
getRecentsView().confirmSplitSelect(this, container.getTask(), container.getIconView(),
|
||||
container.getThumbnailView());
|
||||
}
|
||||
return isSelectingSecondSplitApp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the task under the given position in the local coordinates of this task view.
|
||||
*/
|
||||
protected int getChildTaskIndexAtPosition(PointF position) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the task associated with this view and animates the startup.
|
||||
* @return CompletionStage to indicate the animation completion or null if the launch failed.
|
||||
|
||||
Reference in New Issue
Block a user