Merge "Refactor arrow popups to allow easier code overriding and sharing." into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
03be53443d
@@ -23,9 +23,11 @@ import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
|
||||
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
|
||||
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_FOLDER;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_ICON_SURFACE;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_SNACKBAR;
|
||||
import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
|
||||
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.FLAG_CLOSE_POPUPS;
|
||||
@@ -2901,13 +2903,26 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
* Shows the default options popup
|
||||
*/
|
||||
public void showDefaultOptions(float x, float y) {
|
||||
OptionsPopupView.show(this, getPopupTarget(x, y), OptionsPopupView.getOptions(this),
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns target rectangle for anchoring a popup menu.
|
||||
*/
|
||||
protected RectF getPopupTarget(float x, float y) {
|
||||
float halfSize = getResources().getDimension(R.dimen.options_menu_thumb_size) / 2;
|
||||
if (x < 0 || y < 0) {
|
||||
x = mDragLayer.getWidth() / 2;
|
||||
y = mDragLayer.getHeight() / 2;
|
||||
}
|
||||
RectF target = new RectF(x - halfSize, y - halfSize, x + halfSize, y + halfSize);
|
||||
OptionsPopupView.show(this, target, OptionsPopupView.getOptions(this), false);
|
||||
return new RectF(x - halfSize, y - halfSize, x + halfSize, y + halfSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUseColorExtractionForPopup() {
|
||||
return getTopOpenViewWithType(this, TYPE_FOLDER) == null
|
||||
&& getStateManager().getState() != LauncherState.ALL_APPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,21 +51,20 @@ import android.widget.FrameLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.InsettableFrameLayout;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutView;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.launcher3.widget.LocalColorExtractor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -74,7 +73,7 @@ import java.util.List;
|
||||
*
|
||||
* @param <T> The activity on with the popup shows
|
||||
*/
|
||||
public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
public abstract class ArrowPopup<T extends Context & ActivityContext>
|
||||
extends AbstractFloatingView {
|
||||
|
||||
// Duration values (ms) for popup open and close animations.
|
||||
@@ -98,7 +97,7 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
|
||||
protected final LayoutInflater mInflater;
|
||||
private final float mOutlineRadius;
|
||||
protected final T mLauncher;
|
||||
protected final T mActivityContext;
|
||||
protected final boolean mIsRtl;
|
||||
|
||||
private final int mArrowOffsetVertical;
|
||||
@@ -131,13 +130,13 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
|
||||
private final String mIterateChildrenTag;
|
||||
|
||||
private final int[] mColors;
|
||||
private final int[] mColorIds;
|
||||
|
||||
public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mOutlineRadius = Themes.getDialogCornerRadius(context);
|
||||
mLauncher = BaseDraggingActivity.fromContext(context);
|
||||
mActivityContext = ActivityContext.lookupContext(context);
|
||||
mIsRtl = Utilities.isRtl(getResources());
|
||||
|
||||
mBackgroundColor = Themes.getAttrColor(context, R.attr.popupColorPrimary);
|
||||
@@ -169,22 +168,18 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
|
||||
mIterateChildrenTag = getContext().getString(R.string.popup_container_iterate_children);
|
||||
|
||||
boolean isAboveAnotherSurface = getTopOpenViewWithType(mLauncher, TYPE_FOLDER) != null
|
||||
|| mLauncher.getStateManager().getState() == LauncherState.ALL_APPS;
|
||||
if (!isAboveAnotherSurface && Utilities.ATLEAST_S && ENABLE_LOCAL_COLOR_POPUPS.get()) {
|
||||
boolean shouldUseColorExtraction = mActivityContext.shouldUseColorExtractionForPopup();
|
||||
if (shouldUseColorExtraction && Utilities.ATLEAST_S && ENABLE_LOCAL_COLOR_POPUPS.get()) {
|
||||
mColorExtractors = new ArrayList<>();
|
||||
} else {
|
||||
mColorExtractors = null;
|
||||
}
|
||||
|
||||
if (isAboveAnotherSurface) {
|
||||
mColors = new int[] {
|
||||
getColorStateList(context, R.color.popup_shade_first).getDefaultColor()};
|
||||
if (shouldUseColorExtraction) {
|
||||
mColorIds = new int[]{R.color.popup_shade_first, R.color.popup_shade_second,
|
||||
R.color.popup_shade_third};
|
||||
} else {
|
||||
mColors = new int[] {
|
||||
getColorStateList(context, R.color.popup_shade_first).getDefaultColor(),
|
||||
getColorStateList(context, R.color.popup_shade_second).getDefaultColor(),
|
||||
getColorStateList(context, R.color.popup_shade_third).getDefaultColor()};
|
||||
mColorIds = new int[]{R.color.popup_shade_first};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,17 +231,22 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
}
|
||||
|
||||
/**
|
||||
* @param backgroundColor When Color.TRANSPARENT, we get color from {@link #mColors}.
|
||||
* @param backgroundColor When Color.TRANSPARENT, we get color from {@link #mColorIds}.
|
||||
* Otherwise, we will use this color for all child views.
|
||||
*/
|
||||
private void assignMarginsAndBackgrounds(ViewGroup viewGroup, int backgroundColor) {
|
||||
final boolean getColorFromColorArray = backgroundColor == Color.TRANSPARENT;
|
||||
int[] colors = null;
|
||||
if (backgroundColor == Color.TRANSPARENT) {
|
||||
// Lazily get the colors so they match the current wallpaper colors.
|
||||
colors = Arrays.stream(mColorIds).map(
|
||||
r -> getColorStateList(getContext(), r).getDefaultColor()).toArray();
|
||||
}
|
||||
|
||||
int count = viewGroup.getChildCount();
|
||||
int totalVisibleShortcuts = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
View view = viewGroup.getChildAt(i);
|
||||
if (view.getVisibility() == VISIBLE && view instanceof DeepShortcutView) {
|
||||
if (view.getVisibility() == VISIBLE && isShortcutOrWrapper(view)) {
|
||||
totalVisibleShortcuts++;
|
||||
}
|
||||
}
|
||||
@@ -266,9 +266,8 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
MarginLayoutParams mlp = (MarginLayoutParams) lastView.getLayoutParams();
|
||||
mlp.bottomMargin = 0;
|
||||
|
||||
|
||||
if (getColorFromColorArray) {
|
||||
backgroundColor = mColors[numVisibleChild % mColors.length];
|
||||
if (colors != null) {
|
||||
backgroundColor = colors[numVisibleChild % colors.length];
|
||||
}
|
||||
|
||||
if (view instanceof ViewGroup && mIterateChildrenTag.equals(view.getTag())) {
|
||||
@@ -277,7 +276,7 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
continue;
|
||||
}
|
||||
|
||||
if (view instanceof DeepShortcutView) {
|
||||
if (isShortcutOrWrapper(view)) {
|
||||
if (totalVisibleShortcuts == 1) {
|
||||
view.setBackgroundResource(R.drawable.single_item_primary);
|
||||
} else if (totalVisibleShortcuts > 1) {
|
||||
@@ -310,6 +309,12 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the child is a shortcut or wraps a shortcut.
|
||||
*/
|
||||
protected boolean isShortcutOrWrapper(View view) {
|
||||
return view instanceof DeepShortcutView;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.S)
|
||||
private int getExtractedColor(SparseIntArray colors) {
|
||||
@@ -427,7 +432,7 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
/**
|
||||
* Shows the popup at the desired location.
|
||||
*/
|
||||
protected void show() {
|
||||
public void show() {
|
||||
setupForDisplay();
|
||||
onInflationComplete(false);
|
||||
assignMarginsAndBackgrounds(this);
|
||||
@@ -807,6 +812,6 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
|
||||
}
|
||||
|
||||
protected BaseDragLayer getPopupContainer() {
|
||||
return mLauncher.getDragLayer();
|
||||
return mActivityContext.getDragLayer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public class PopupContainerWithArrow<T extends StatefulActivity<LauncherState>>
|
||||
|
||||
public OnClickListener getItemClickListener() {
|
||||
return (view) -> {
|
||||
mLauncher.getItemOnClickListener().onClick(view);
|
||||
mActivityContext.getItemOnClickListener().onClick(view);
|
||||
close(true);
|
||||
};
|
||||
}
|
||||
@@ -326,7 +326,7 @@ public class PopupContainerWithArrow<T extends StatefulActivity<LauncherState>>
|
||||
|
||||
// Load the shortcuts on a background thread and update the container as it animates.
|
||||
MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(PopupPopulator.createUpdateRunnable(
|
||||
mLauncher, originalItemInfo, new Handler(Looper.getMainLooper()),
|
||||
mActivityContext, originalItemInfo, new Handler(Looper.getMainLooper()),
|
||||
this, mShortcuts, notificationKeys));
|
||||
}
|
||||
|
||||
@@ -439,7 +439,7 @@ public class PopupContainerWithArrow<T extends StatefulActivity<LauncherState>>
|
||||
|
||||
private void updateNotificationHeader() {
|
||||
ItemInfoWithIcon itemInfo = (ItemInfoWithIcon) mOriginalIcon.getTag();
|
||||
DotInfo dotInfo = mLauncher.getDotInfoForItem(itemInfo);
|
||||
DotInfo dotInfo = mActivityContext.getDotInfoForItem(itemInfo);
|
||||
if (mNotificationContainer != null && dotInfo != null) {
|
||||
mNotificationContainer.updateHeader(dotInfo.getNotificationCount());
|
||||
}
|
||||
@@ -481,7 +481,7 @@ public class PopupContainerWithArrow<T extends StatefulActivity<LauncherState>>
|
||||
@Override
|
||||
protected void closeComplete() {
|
||||
super.closeComplete();
|
||||
PopupContainerWithArrow openPopup = getOpen(mLauncher);
|
||||
PopupContainerWithArrow openPopup = getOpen(mActivityContext);
|
||||
if (openPopup == null || openPopup.mOriginalIcon != mOriginalIcon) {
|
||||
mOriginalIcon.setTextVisibility(mOriginalIcon.shouldTextBeVisible());
|
||||
mOriginalIcon.setForceHideDot(false);
|
||||
|
||||
@@ -115,6 +115,13 @@ public interface ActivityContext {
|
||||
return StatsLogManager.newInstance((Context) this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if popups should use color extraction.
|
||||
*/
|
||||
default boolean shouldUseColorExtractionForPopup() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether we can show the IME for elements hosted by this ActivityContext.
|
||||
*/
|
||||
|
||||
@@ -59,7 +59,7 @@ import java.util.List;
|
||||
/**
|
||||
* Popup shown on long pressing an empty space in launcher
|
||||
*/
|
||||
public class OptionsPopupView extends ArrowPopup
|
||||
public class OptionsPopupView extends ArrowPopup<Launcher>
|
||||
implements OnClickListener, OnLongClickListener {
|
||||
|
||||
private final ArrayMap<View, OptionItem> mItemMap = new ArrayMap<>();
|
||||
@@ -74,6 +74,10 @@ public class OptionsPopupView extends ArrowPopup
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public void setTargetRect(RectF targetRect) {
|
||||
mTargetRect = targetRect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
handleViewClick(view);
|
||||
@@ -90,7 +94,7 @@ public class OptionsPopupView extends ArrowPopup
|
||||
return false;
|
||||
}
|
||||
if (item.eventId.getId() > 0) {
|
||||
mLauncher.getStatsLogManager().logger().log(item.eventId);
|
||||
mActivityContext.getStatsLogManager().logger().log(item.eventId);
|
||||
}
|
||||
if (item.clickListener.onLongClick(view)) {
|
||||
close(true);
|
||||
|
||||
Reference in New Issue
Block a user