19314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal/*
29314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * Copyright (C) 2017 The Android Open Source Project
39314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal *
49314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * Licensed under the Apache License, Version 2.0 (the "License");
59314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * you may not use this file except in compliance with the License.
69314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * You may obtain a copy of the License at
79314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal *
89314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal *      http://www.apache.org/licenses/LICENSE-2.0
99314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal *
109314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * Unless required by applicable law or agreed to in writing, software
119314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * distributed under the License is distributed on an "AS IS" BASIS,
129314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * See the License for the specific language governing permissions and
149314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * limitations under the License.
159314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal */
169314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
179314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyalpackage com.android.launcher3.views;
189314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
199314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyalimport android.content.Context;
209314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyalimport android.content.res.TypedArray;
219314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyalimport android.graphics.Canvas;
221d9cc3247554d5b52534515af1a081716476097cJon Mirandaimport android.graphics.Color;
239314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyalimport android.graphics.Region;
241d9cc3247554d5b52534515af1a081716476097cJon Mirandaimport android.support.v4.graphics.ColorUtils;
259314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyalimport android.util.AttributeSet;
26bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschlerimport android.widget.TextView;
279314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
289314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyalimport com.android.launcher3.BubbleTextView;
299314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyalimport com.android.launcher3.R;
309314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
319314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal/**
329314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal * Extension of {@link BubbleTextView} which draws two shadows on the text (ambient and key shadows}
339314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal */
349314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyalpublic class DoubleShadowBubbleTextView extends BubbleTextView {
359314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
369314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    private final ShadowInfo mShadowInfo;
379314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
389314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    public DoubleShadowBubbleTextView(Context context) {
399314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        this(context, null);
409314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    }
419314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
429314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    public DoubleShadowBubbleTextView(Context context, AttributeSet attrs) {
439314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        this(context, attrs, 0);
449314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    }
459314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
469314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    public DoubleShadowBubbleTextView(Context context, AttributeSet attrs, int defStyle) {
479314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        super(context, attrs, defStyle);
489314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        mShadowInfo = new ShadowInfo(context, attrs, defStyle);
499314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0, mShadowInfo.ambientShadowColor);
509314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    }
511d9cc3247554d5b52534515af1a081716476097cJon Miranda
529314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    @Override
539314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    public void onDraw(Canvas canvas) {
54bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler        // If text is transparent or shadow alpha is 0, don't draw any shadow
55bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler        if (mShadowInfo.skipDoubleShadow(this)) {
569314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal            super.onDraw(canvas);
579314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal            return;
589314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        }
59bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler        int alpha = Color.alpha(getCurrentTextColor());
609314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
619314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        // We enhance the shadow by drawing the shadow twice
621d9cc3247554d5b52534515af1a081716476097cJon Miranda        getPaint().setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0,
631d9cc3247554d5b52534515af1a081716476097cJon Miranda                ColorUtils.setAlphaComponent(mShadowInfo.ambientShadowColor, alpha));
649314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
659314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        drawWithoutBadge(canvas);
669314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        canvas.save(Canvas.CLIP_SAVE_FLAG);
679314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
689314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal                getScrollX() + getWidth(),
699314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal                getScrollY() + getHeight(), Region.Op.INTERSECT);
709314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
711d9cc3247554d5b52534515af1a081716476097cJon Miranda        getPaint().setShadowLayer(mShadowInfo.keyShadowBlur, 0.0f, mShadowInfo.keyShadowOffset,
721d9cc3247554d5b52534515af1a081716476097cJon Miranda                ColorUtils.setAlphaComponent(mShadowInfo.keyShadowColor, alpha));
739314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        drawWithoutBadge(canvas);
749314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        canvas.restore();
759314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
769314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        drawBadgeIfNecessary(canvas);
779314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    }
789314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
799314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    public static class ShadowInfo {
809314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        public final float ambientShadowBlur;
819314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        public final int ambientShadowColor;
829314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
839314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        public final float keyShadowBlur;
849314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        public final float keyShadowOffset;
859314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        public final int keyShadowColor;
869314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
879314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        public ShadowInfo(Context c, AttributeSet attrs, int defStyle) {
889314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
899314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal            TypedArray a = c.obtainStyledAttributes(
909314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal                    attrs, R.styleable.ShadowInfo, defStyle, 0);
919314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
929314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal            ambientShadowBlur = a.getDimension(R.styleable.ShadowInfo_ambientShadowBlur, 0);
939314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal            ambientShadowColor = a.getColor(R.styleable.ShadowInfo_ambientShadowColor, 0);
949314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal
959314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal            keyShadowBlur = a.getDimension(R.styleable.ShadowInfo_keyShadowBlur, 0);
969314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal            keyShadowOffset = a.getDimension(R.styleable.ShadowInfo_keyShadowOffset, 0);
979314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal            keyShadowColor = a.getColor(R.styleable.ShadowInfo_keyShadowColor, 0);
989314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal            a.recycle();
999314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal        }
100bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler
101bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler        public boolean skipDoubleShadow(TextView textView) {
102bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler            int textAlpha = Color.alpha(textView.getCurrentTextColor());
103bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler            int keyShadowAlpha = Color.alpha(keyShadowColor);
104bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler            int ambientShadowAlpha = Color.alpha(ambientShadowColor);
105bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler            if (textAlpha == 0 || (keyShadowAlpha == 0 && ambientShadowAlpha == 0)) {
106bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler                textView.getPaint().clearShadowLayer();
107bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler                return true;
108bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler            } else if (ambientShadowAlpha > 0) {
109bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler                textView.getPaint().setShadowLayer(ambientShadowBlur, 0, 0,
110bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler                        ColorUtils.setAlphaComponent(ambientShadowColor, textAlpha));
111bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler                return true;
112bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler            } else if (keyShadowAlpha > 0) {
113bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler                textView.getPaint().setShadowLayer(keyShadowBlur, 0.0f, keyShadowOffset,
114bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler                        ColorUtils.setAlphaComponent(keyShadowColor, textAlpha));
115bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler                return true;
116bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler            } else {
117bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler                return false;
118bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler            }
119bbc139188a4ac90cb9371e2b823821063d96f273Mario Bertschler        }
1209314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal    }
1219314b7c01d932093c730dd39b9b9842d1a56efdbSunny Goyal}
122