1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.launcher3.views; 17 18 import android.annotation.TargetApi; 19 import android.content.Context; 20 import android.content.res.ColorStateList; 21 import android.content.res.TypedArray; 22 import android.graphics.Bitmap; 23 import android.graphics.BlendMode; 24 import android.graphics.BlendModeColorFilter; 25 import android.graphics.Canvas; 26 import android.graphics.Color; 27 import android.graphics.Rect; 28 import android.graphics.drawable.ColorDrawable; 29 import android.graphics.drawable.Drawable; 30 import android.os.Build; 31 import android.util.AttributeSet; 32 import android.view.accessibility.AccessibilityEvent; 33 34 import androidx.annotation.ColorInt; 35 import androidx.annotation.NonNull; 36 37 import com.android.launcher3.BubbleTextView; 38 import com.android.launcher3.icons.BaseIconFactory; 39 import com.android.launcher3.icons.FastBitmapDrawable; 40 import com.android.launcher3.icons.LauncherIcons; 41 import com.android.launcher3.util.MultiTranslateDelegate; 42 43 /** 44 * Button in Taskbar that shows a tinted background and foreground. 45 */ 46 public class IconButtonView extends BubbleTextView { 47 48 private static final int[] ATTRS = {android.R.attr.icon}; 49 50 private static final int INDEX_TASKBAR_ALL_APPS_ICON = MultiTranslateDelegate.COUNT; 51 private static final int MY_COUNT = MultiTranslateDelegate.COUNT + 1; 52 53 private final MultiTranslateDelegate mTranslateDelegate = 54 new MultiTranslateDelegate(this, MY_COUNT, MultiTranslateDelegate.COUNT); 55 IconButtonView(Context context)56 public IconButtonView(Context context) { 57 this(context, null); 58 } 59 IconButtonView(Context context, AttributeSet attrs)60 public IconButtonView(Context context, AttributeSet attrs) { 61 this(context, attrs, 0); 62 } 63 IconButtonView(Context context, AttributeSet attrs, int defStyle)64 public IconButtonView(Context context, AttributeSet attrs, int defStyle) { 65 super(context, attrs, defStyle); 66 67 TypedArray a = context.obtainStyledAttributes(attrs, ATTRS, defStyle, 0); 68 Drawable fg = a.getDrawable(0); 69 a.recycle(); 70 71 ColorStateList tintList = getBackgroundTintList(); 72 int tint = tintList == null ? Color.WHITE : tintList.getDefaultColor(); 73 74 if (fg == null) { 75 fg = new ColorDrawable(Color.TRANSPARENT); 76 } 77 try (BaseIconFactory factory = LauncherIcons.obtain(context)) { 78 setIcon(new IconDrawable(factory.getWhiteShadowLayer(), tint, fg)); 79 } 80 } 81 82 @Override onPopulateAccessibilityEvent(AccessibilityEvent event)83 public void onPopulateAccessibilityEvent(AccessibilityEvent event) { 84 super.onPopulateAccessibilityEvent(event); 85 event.getText().add(this.getContentDescription()); 86 } 87 88 /** Sets given Drawable as icon */ setIconDrawable(@onNull Drawable drawable)89 public void setIconDrawable(@NonNull Drawable drawable) { 90 ColorStateList tintList = getBackgroundTintList(); 91 int tint = tintList == null ? Color.WHITE : tintList.getDefaultColor(); 92 try (BaseIconFactory factory = LauncherIcons.obtain(getContext())) { 93 setIcon(new IconDrawable(factory.getWhiteShadowLayer(), tint, drawable)); 94 } 95 } 96 97 /** Updates the color of the icon's foreground layer. */ setForegroundTint(@olorInt int tintColor)98 public void setForegroundTint(@ColorInt int tintColor) { 99 FastBitmapDrawable icon = getIcon(); 100 if (icon instanceof IconDrawable) { 101 ((IconDrawable) icon).mFg.setTint(tintColor); 102 } 103 } 104 105 @Override getTranslateDelegate()106 public MultiTranslateDelegate getTranslateDelegate() { 107 return mTranslateDelegate; 108 } 109 110 /** 111 * Sets translationX for taskbar all apps icon 112 */ setTranslationXForTaskbarAllAppsIcon(float translationX)113 public void setTranslationXForTaskbarAllAppsIcon(float translationX) { 114 getTranslateDelegate().getTranslationX(INDEX_TASKBAR_ALL_APPS_ICON).setValue(translationX); 115 } 116 117 private static class IconDrawable extends FastBitmapDrawable { 118 119 private final Drawable mFg; 120 121 @TargetApi(Build.VERSION_CODES.TIRAMISU) IconDrawable(Bitmap b, int colorBg, Drawable fg)122 IconDrawable(Bitmap b, int colorBg, Drawable fg) { 123 super(b); 124 mPaint.setColorFilter(new BlendModeColorFilter(colorBg, BlendMode.SRC_IN)); 125 mFg = fg; 126 } 127 128 @Override drawInternal(Canvas canvas, Rect bounds)129 protected void drawInternal(Canvas canvas, Rect bounds) { 130 super.drawInternal(canvas, bounds); 131 mFg.draw(canvas); 132 } 133 134 @Override onBoundsChange(Rect bounds)135 protected void onBoundsChange(Rect bounds) { 136 super.onBoundsChange(bounds); 137 mFg.setBounds(bounds); 138 } 139 } 140 } 141