diff options
author | Tony Wickham <twickham@google.com> | 2017-02-27 16:30:47 -0800 |
---|---|---|
committer | Tony Wickham <twickham@google.com> | 2017-03-01 10:16:16 -0800 |
commit | 51889b0be83dc34c9752fc066d0d6e75ab4f5e26 (patch) | |
tree | b3c466ce4742e561fc19dce1a1a028a65f28801b /src/com/android/launcher3/shortcuts | |
parent | 7f3526a1a4d5d3578d4648abb1422646d23c6080 (diff) | |
download | android_packages_apps_Trebuchet-51889b0be83dc34c9752fc066d0d6e75ab4f5e26.tar.gz android_packages_apps_Trebuchet-51889b0be83dc34c9752fc066d0d6e75ab4f5e26.tar.bz2 android_packages_apps_Trebuchet-51889b0be83dc34c9752fc066d0d6e75ab4f5e26.zip |
Merge deep shortcuts in rounded rect
- DeepShortcutViews are added to ShortcutsItemView, which
is in PopupContainerWithArrow
- Moved some shortcut-specific logic to ShortcutsItemView
(namely, touch/long-click handling for draggin shortcuts)
- Moved round-rect clipping to PopupItemView
- Removed collapseToIcon() logic, including
PillWidthRevealOutlineProvider, which was only used for
that purpose. It isn't necessary now that the deep
shortcuts have no background themselves.
- Replaced focus pill drawable with ripple effect on
shortcuts and notification view.
Bug: 35766387
Change-Id: I6bc09f1851cfbb806df4bf75a6e435b0f1900c9c
Diffstat (limited to 'src/com/android/launcher3/shortcuts')
-rw-r--r-- | src/com/android/launcher3/shortcuts/DeepShortcutView.java | 24 | ||||
-rw-r--r-- | src/com/android/launcher3/shortcuts/ShortcutsItemView.java | 180 |
2 files changed, 200 insertions, 4 deletions
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java index 2f07c9ac9..47a023e25 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java @@ -17,26 +17,30 @@ package com.android.launcher3.shortcuts; import android.content.Context; +import android.graphics.Point; import android.graphics.Rect; import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; +import android.widget.FrameLayout; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; -import com.android.launcher3.popup.PopupContainerWithArrow; -import com.android.launcher3.popup.PopupItemView; +import com.android.launcher3.Utilities; /** * A {@link android.widget.FrameLayout} that contains a {@link DeepShortcutView}. * This lets us animate the DeepShortcutView (icon and text) separately from the background. */ -public class DeepShortcutView extends PopupItemView { +public class DeepShortcutView extends FrameLayout { + + private static final Point sTempPoint = new Point(); private final Rect mPillRect; private DeepShortcutTextView mBubbleText; + private View mIconView; private ShortcutInfo mInfo; private ShortcutInfoCompat mDetail; @@ -59,6 +63,7 @@ public class DeepShortcutView extends PopupItemView { protected void onFinishInflate() { super.onFinishInflate(); mBubbleText = (DeepShortcutTextView) findViewById(R.id.deep_shortcut); + mIconView = findViewById(R.id.icon); } public DeepShortcutTextView getBubbleText() { @@ -73,6 +78,17 @@ public class DeepShortcutView extends PopupItemView { return mIconView.getVisibility() == View.VISIBLE; } + /** + * Returns the position of the center of the icon relative to the container. + */ + public Point getIconCenter() { + sTempPoint.y = sTempPoint.x = getMeasuredHeight() / 2; + if (Utilities.isRtl(getResources())) { + sTempPoint.x = getMeasuredWidth() - sTempPoint.x; + } + return sTempPoint; + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); @@ -81,7 +97,7 @@ public class DeepShortcutView extends PopupItemView { /** package private **/ public void applyShortcutInfo(ShortcutInfo info, ShortcutInfoCompat detail, - PopupContainerWithArrow container) { + ShortcutsItemView container) { mInfo = info; mDetail = detail; mBubbleText.applyFromShortcutInfo(info); diff --git a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java new file mode 100644 index 000000000..349c4c946 --- /dev/null +++ b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2017 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.shortcuts; + +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.content.Context; +import android.graphics.Point; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.widget.LinearLayout; + +import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.ItemInfo; +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAnimUtils; +import com.android.launcher3.R; +import com.android.launcher3.anim.PropertyListBuilder; +import com.android.launcher3.dragndrop.DragOptions; +import com.android.launcher3.dragndrop.DragView; +import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; +import com.android.launcher3.popup.PopupContainerWithArrow; +import com.android.launcher3.popup.PopupItemView; +import com.android.launcher3.userevent.nano.LauncherLogProto; + +import java.util.ArrayList; +import java.util.List; + +/** + * A {@link PopupItemView} that contains all of the {@link DeepShortcutView}s for an app. + */ +public class ShortcutsItemView extends PopupItemView implements View.OnLongClickListener, + View.OnTouchListener, LogContainerProvider { + + private Launcher mLauncher; + private LinearLayout mDeepShortcutsLayout; + private final Point mIconShift = new Point(); + private final Point mIconLastTouchPos = new Point(); + + public ShortcutsItemView(Context context) { + this(context, null, 0); + } + + public ShortcutsItemView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ShortcutsItemView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + mLauncher = Launcher.getLauncher(context); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mDeepShortcutsLayout = (LinearLayout) findViewById(R.id.deep_shortcuts); + } + + @Override + public boolean onTouch(View v, MotionEvent ev) { + // Touched a shortcut, update where it was touched so we can drag from there on long click. + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_MOVE: + mIconLastTouchPos.set((int) ev.getX(), (int) ev.getY()); + break; + } + return false; + } + + @Override + public boolean onLongClick(View v) { + // Return early if this is not initiated from a touch or not the correct view + if (!v.isInTouchMode() || !(v.getParent() instanceof DeepShortcutView)) return false; + // Return early if global dragging is not enabled + if (!mLauncher.isDraggingEnabled()) return false; + // Return early if an item is already being dragged (e.g. when long-pressing two shortcuts) + if (mLauncher.getDragController().isDragging()) return false; + + // Long clicked on a shortcut. + DeepShortcutView sv = (DeepShortcutView) v.getParent(); + sv.setWillDrawIcon(false); + + // Move the icon to align with the center-top of the touch point + mIconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x; + mIconShift.y = mIconLastTouchPos.y - mLauncher.getDeviceProfile().iconSizePx; + + DragView dv = mLauncher.getWorkspace().beginDragShared(sv.getBubbleText(), + (PopupContainerWithArrow) getParent(), sv.getFinalInfo(), + new ShortcutDragPreviewProvider(sv.getIconView(), mIconShift), new DragOptions()); + dv.animateShift(-mIconShift.x, -mIconShift.y); + + // TODO: support dragging from within folder without having to close it + AbstractFloatingView.closeOpenContainer(mLauncher, AbstractFloatingView.TYPE_FOLDER); + return false; + } + + public void addDeepShortcutView(DeepShortcutView deepShortcutView) { + if (getNumDeepShortcuts() > 0) { + getDeepShortcutAt(getNumDeepShortcuts() - 1).findViewById(R.id.divider) + .setVisibility(VISIBLE); + } + mDeepShortcutsLayout.addView(deepShortcutView); + } + + private DeepShortcutView getDeepShortcutAt(int index) { + return (DeepShortcutView) mDeepShortcutsLayout.getChildAt(index); + } + + private int getNumDeepShortcuts() { + return mDeepShortcutsLayout.getChildCount(); + } + + public List<DeepShortcutView> getDeepShortcutViews(boolean reverseOrder) { + int numDeepShortcuts = getNumDeepShortcuts(); + List<DeepShortcutView> deepShortcutViews = new ArrayList<>(numDeepShortcuts); + for (int i = 0; i < numDeepShortcuts; i++) { + DeepShortcutView deepShortcut = getDeepShortcutAt(i); + if (reverseOrder) { + deepShortcutViews.add(0, deepShortcut); + } else { + deepShortcutViews.add(deepShortcut); + } + } + return deepShortcutViews; + } + + @Override + public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) { + AnimatorSet openAnimation = LauncherAnimUtils.createAnimatorSet(); + openAnimation.play(super.createOpenAnimation(isContainerAboveIcon, pivotLeft)); + for (int i = 0; i < getNumDeepShortcuts(); i++) { + View deepShortcutIcon = getDeepShortcutAt(i).getIconView(); + deepShortcutIcon.setScaleX(0); + deepShortcutIcon.setScaleY(0); + openAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder( + deepShortcutIcon, new PropertyListBuilder().scale(1).build())); + } + return openAnimation; + } + + @Override + public Animator createCloseAnimation(boolean isContainerAboveIcon, boolean pivotLeft, + long duration) { + AnimatorSet closeAnimation = LauncherAnimUtils.createAnimatorSet(); + closeAnimation.play(super.createCloseAnimation(isContainerAboveIcon, pivotLeft, duration)); + for (int i = 0; i < getNumDeepShortcuts(); i++) { + View deepShortcutIcon = getDeepShortcutAt(i).getIconView(); + deepShortcutIcon.setScaleX(1); + deepShortcutIcon.setScaleY(1); + closeAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder( + deepShortcutIcon, new PropertyListBuilder().scale(0).build())); + } + return closeAnimation; + } + + @Override + public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target, + LauncherLogProto.Target targetParent) { + target.itemType = LauncherLogProto.ItemType.DEEPSHORTCUT; + target.rank = info.rank; + targetParent.containerType = LauncherLogProto.ContainerType.DEEPSHORTCUTS; + } +} |