Using same layout for drop-target bar in landscape and portrait

> Adding a tooltip on drag over when the text is not visible

Bug: 71709920
Change-Id: I1897a8dacd191fb1aeaec37f5d5c73c49517192a
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index cfb55cc..a9cf8cc 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -16,27 +16,28 @@
 
 package com.android.launcher3;
 
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+
 import static com.android.launcher3.LauncherState.NORMAL;
 
 import android.animation.AnimatorSet;
 import android.animation.FloatArrayEvaluator;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
-import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
+import android.widget.PopupWindow;
 import android.widget.TextView;
 
 import com.android.launcher3.anim.Interpolators;
@@ -56,7 +57,10 @@
     private static final int[] sTempCords = new int[2];
     private static final int DRAG_VIEW_DROP_DURATION = 285;
 
-    private final boolean mHideParentOnDisable;
+    public static final int TOOLTIP_DEFAULT = 0;
+    public static final int TOOLTIP_LEFT = 1;
+    public static final int TOOLTIP_RIGHT = 2;
+
     protected final Launcher mLauncher;
 
     private int mBottomDragPadding;
@@ -75,6 +79,10 @@
     protected CharSequence mText;
     protected ColorStateList mOriginalTextColor;
     protected Drawable mDrawable;
+    private boolean mTextVisible = true;
+
+    private PopupWindow mToolTip;
+    private int mToolTipLocation;
 
     private AnimatorSet mCurrentColorAnim;
     @Thunk ColorMatrix mSrcFilter, mDstFilter, mCurrentFilter;
@@ -89,11 +97,6 @@
 
         Resources resources = getResources();
         mBottomDragPadding = resources.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
-
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.ButtonDropTarget, defStyle, 0);
-        mHideParentOnDisable = a.getBoolean(R.styleable.ButtonDropTarget_hideParentOnDisable, false);
-        a.recycle();
         mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
     }
 
@@ -102,21 +105,56 @@
         super.onFinishInflate();
         mText = getText();
         mOriginalTextColor = getTextColors();
+        setContentDescription(mText);
     }
 
     protected void setDrawable(int resId) {
         // We do not set the drawable in the xml as that inflates two drawables corresponding to
         // drawableLeft and drawableStart.
-        setCompoundDrawablesRelativeWithIntrinsicBounds(resId, 0, 0, 0);
-        mDrawable = getCompoundDrawablesRelative()[0];
+        if (mTextVisible) {
+            setCompoundDrawablesRelativeWithIntrinsicBounds(resId, 0, 0, 0);
+            mDrawable = getCompoundDrawablesRelative()[0];
+        } else {
+            setCompoundDrawablesRelativeWithIntrinsicBounds(0, resId, 0, 0);
+            mDrawable = getCompoundDrawablesRelative()[1];
+        }
     }
 
     public void setDropTargetBar(DropTargetBar dropTargetBar) {
         mDropTargetBar = dropTargetBar;
     }
 
+    private void hideTooltip() {
+        if (mToolTip != null) {
+            mToolTip.dismiss();
+            mToolTip = null;
+        }
+    }
+
     @Override
     public final void onDragEnter(DragObject d) {
+        if (!d.accessibleDrag && !mTextVisible) {
+            // Show tooltip
+            hideTooltip();
+
+            TextView message = (TextView) LayoutInflater.from(getContext()).inflate(
+                    R.layout.drop_target_tool_tip, null);
+            message.setText(mText);
+
+            mToolTip = new PopupWindow(message, WRAP_CONTENT, WRAP_CONTENT);
+            int x = 0, y = 0;
+            if (mToolTipLocation != TOOLTIP_DEFAULT) {
+                y = -getMeasuredHeight();
+                message.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+                if (mToolTipLocation == TOOLTIP_LEFT) {
+                    x = - getMeasuredWidth() - message.getMeasuredWidth() / 2;
+                } else {
+                    x = getMeasuredWidth() / 2 + message.getMeasuredWidth() / 2;
+                }
+            }
+            mToolTip.showAsDropDown(this, x, y);
+        }
+
         d.dragView.setColor(mHoverColor);
         animateTextColor(mHoverColor);
         if (d.stateAnnouncer != null) {
@@ -153,13 +191,9 @@
         ValueAnimator anim1 = ValueAnimator.ofObject(
                 new FloatArrayEvaluator(mCurrentFilter.getArray()),
                 mSrcFilter.getArray(), mDstFilter.getArray());
-        anim1.addUpdateListener(new AnimatorUpdateListener() {
-
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                mDrawable.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter));
-                invalidate();
-            }
+        anim1.addUpdateListener((anim) -> {
+            mDrawable.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter));
+            invalidate();
         });
 
         mCurrentColorAnim.play(anim1);
@@ -169,6 +203,8 @@
 
     @Override
     public final void onDragExit(DragObject d) {
+        hideTooltip();
+
         if (!d.dragComplete) {
             d.dragView.setColor(0);
             resetHoverColor();
@@ -187,8 +223,7 @@
             mCurrentColorAnim = null;
         }
         setTextColor(mOriginalTextColor);
-        (mHideParentOnDisable ? ((ViewGroup) getParent()) : this)
-                .setVisibility(mActive ? View.VISIBLE : View.GONE);
+        setVisibility(mActive ? View.VISIBLE : View.GONE);
 
         mAccessibleDrag = options.isAccessibleDrag;
         setOnClickListener(mAccessibleDrag ? this : null);
@@ -230,14 +265,12 @@
         final float scale = (float) to.width() / from.width();
         mDropTargetBar.deferOnDragEnd();
 
-        Runnable onAnimationEndRunnable = new Runnable() {
-            @Override
-            public void run() {
-                completeDrop(d);
-                mDropTargetBar.onDragEnd();
-                mLauncher.getStateManager().goToState(NORMAL);
-            }
+        Runnable onAnimationEndRunnable = () -> {
+            completeDrop(d);
+            mDropTargetBar.onDragEnd();
+            mLauncher.getStateManager().goToState(NORMAL);
         };
+
         dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
                 DRAG_VIEW_DROP_DURATION,
                 Interpolators.DEACCEL_2, Interpolators.LINEAR, onAnimationEndRunnable,
@@ -294,8 +327,8 @@
         to.set(left, top, right, bottom);
 
         // Center the destination rect about the trash icon
-        final int xOffset = (int) -(viewWidth - width) / 2;
-        final int yOffset = (int) -(viewHeight - height) / 2;
+        final int xOffset = -(viewWidth - width) / 2;
+        final int yOffset = -(viewHeight - height) / 2;
         to.offset(xOffset, yOffset);
 
         return to;
@@ -310,25 +343,24 @@
         return getTextColors().getDefaultColor();
     }
 
-    /**
-     * Returns True if any update was made.
-     */
-    public boolean updateText(boolean hide) {
-        if ((hide && getText().toString().isEmpty()) || (!hide && mText.equals(getText()))) {
-            return false;
+    public void setTextVisible(boolean isVisible) {
+        if (mTextVisible != isVisible) {
+            mTextVisible = isVisible;
+            setText(isVisible ? mText : "");
+            if (mTextVisible) {
+                setCompoundDrawablesRelativeWithIntrinsicBounds(mDrawable, null, null, null);
+            } else {
+                setCompoundDrawablesRelativeWithIntrinsicBounds(null, mDrawable, null, null);
+            }
         }
-
-        setText(hide ? "" : mText);
-        return true;
     }
 
-    public boolean isTextTruncated() {
-        int availableWidth = getMeasuredWidth();
-        if (mHideParentOnDisable) {
-            ViewGroup parent = (ViewGroup) getParent();
-            availableWidth = parent.getMeasuredWidth() - parent.getPaddingLeft()
-                    - parent.getPaddingRight();
-        }
+    public void setToolTipLocation(int location) {
+        mToolTipLocation = location;
+        hideTooltip();
+    }
+
+    public boolean isTextTruncated(int availableWidth) {
         availableWidth -= (getPaddingLeft() + getPaddingRight() + mDrawable.getIntrinsicWidth()
                 + getCompoundDrawablePadding());
         CharSequence displayedText = TextUtils.ellipsize(mText, getPaint(), availableWidth,