14fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal/*
24fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal * Copyright (C) 2014 The Android Open Source Project
34fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal *
44fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal * Licensed under the Apache License, Version 2.0 (the "License");
54fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal * you may not use this file except in compliance with the License.
64fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal * You may obtain a copy of the License at
74fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal *
84fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal *      http://www.apache.org/licenses/LICENSE-2.0
94fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal *
104fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal * Unless required by applicable law or agreed to in writing, software
114fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal * distributed under the License is distributed on an "AS IS" BASIS,
124fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal * See the License for the specific language governing permissions and
144fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal * limitations under the License.
154fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal */
164fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
174fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyalpackage com.android.launcher3;
184fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
194fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyalimport android.content.Context;
204fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyalimport android.graphics.Bitmap;
214fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyalimport android.graphics.Canvas;
224fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyalimport android.graphics.Color;
234fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyalimport android.graphics.Paint;
244fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyalimport android.view.View;
254fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyalimport android.view.ViewGroup;
264fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
274fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyalpublic class ClickShadowView extends View {
284fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
294fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    private static final int SHADOW_SIZE_FACTOR = 3;
304fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    private static final int SHADOW_LOW_ALPHA = 30;
314fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    private static final int SHADOW_HIGH_ALPHA = 60;
324fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
334fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    private final Paint mPaint;
344fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
354fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    private final float mShadowOffset;
364fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    private final float mShadowPadding;
374fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
384fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    private Bitmap mBitmap;
394fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
404fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    public ClickShadowView(Context context) {
414fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        super(context);
424fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
434fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        mPaint.setColor(Color.BLACK);
444fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
454fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        mShadowPadding = getResources().getDimension(R.dimen.blur_size_click_shadow);
464fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        mShadowOffset = getResources().getDimension(R.dimen.click_shadow_high_shift);
474fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    }
484fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
494fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    /**
504fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal     * @return extra space required by the view to show the shadow.
514fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal     */
524fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    public int getExtraSize() {
534fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        return (int) (SHADOW_SIZE_FACTOR * mShadowPadding);
544fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    }
554fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
564fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    /**
574fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal     * Applies the new bitmap.
584fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal     * @return true if the view was invalidated.
594fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal     */
604fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    public boolean setBitmap(Bitmap b) {
614fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        if (b != mBitmap){
624fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            mBitmap = b;
634fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            invalidate();
644fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            return true;
654fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        }
664fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        return false;
674fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    }
684fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
694fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    @Override
704fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    protected void onDraw(Canvas canvas) {
714fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        if (mBitmap != null) {
724fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            mPaint.setAlpha(SHADOW_LOW_ALPHA);
734fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            canvas.drawBitmap(mBitmap, 0, 0, mPaint);
744fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            mPaint.setAlpha(SHADOW_HIGH_ALPHA);
754fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            canvas.drawBitmap(mBitmap, 0, mShadowOffset, mPaint);
764fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        }
774fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    }
784fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
794fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    public void animateShadow() {
804fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        setAlpha(0);
814fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        animate().alpha(1)
824fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            .setDuration(FastBitmapDrawable.CLICK_FEEDBACK_DURATION)
834fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            .setInterpolator(FastBitmapDrawable.CLICK_FEEDBACK_INTERPOLATOR)
844fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal            .start();
854fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    }
864fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
874fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    /**
884fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal     * Aligns the shadow with {@param view}
894fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal     * @param viewParent immediate parent of {@param view}. It must be a sibling of this view.
904fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal     */
914fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    public void alignWithIconView(BubbleTextView view, ViewGroup viewParent) {
924fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        float leftShift = view.getLeft() + viewParent.getLeft() - getLeft();
934fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        float topShift = view.getTop() + viewParent.getTop() - getTop();
944fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        int iconWidth = view.getRight() - view.getLeft();
954fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        int iconHSpace = iconWidth - view.getCompoundPaddingRight() - view.getCompoundPaddingLeft();
964fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        float drawableWidth = view.getIcon().getBounds().width();
974fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal
984fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        setTranslationX(leftShift
994eda8048c1705a716e8f2b9ddaf026a8a8b03863Winson Chung                + viewParent.getTranslationX()
1004fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal                + view.getCompoundPaddingLeft() * view.getScaleX()
1014fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal                + (iconHSpace - drawableWidth) * view.getScaleX() / 2  /* drawable gap */
1024fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal                + iconWidth * (1 - view.getScaleX()) / 2  /* gap due to scale */
1034fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal                - mShadowPadding  /* extra shadow size */
1044fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal                );
1054fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal        setTranslationY(topShift
1064eda8048c1705a716e8f2b9ddaf026a8a8b03863Winson Chung                + viewParent.getTranslationY()
1074fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal                + view.getPaddingTop() * view.getScaleY()  /* drawable gap */
1084fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal                + view.getHeight() * (1 - view.getScaleY()) / 2  /* gap due to scale */
1094fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal                - mShadowPadding  /* extra shadow size */
1104fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal                );
1114fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal    }
1124fe5a37dda8eb1869f9328d94236eb2c23f8109cSunny Goyal}
113