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