blob: 1154515b261c864e86f0198f5240526edbbc48b8 [file] [log] [blame]
Mady Mellor3f2efdb2018-11-21 11:30:45 -08001/*
2 * Copyright (C) 2018 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 */
16package com.android.systemui.bubbles;
17
18import android.content.Context;
Joshua Tsuji580c0bf2019-01-28 13:28:21 -050019import android.content.res.TypedArray;
Mady Mellor3f2efdb2018-11-21 11:30:45 -080020import android.graphics.Canvas;
Joshua Tsuji580c0bf2019-01-28 13:28:21 -050021import android.graphics.Color;
Mady Mellor3f2efdb2018-11-21 11:30:45 -080022import android.graphics.Path;
23import android.graphics.Point;
24import android.graphics.Rect;
25import android.util.AttributeSet;
26import android.widget.ImageView;
27
28import com.android.systemui.R;
29
30/**
31 * View that circle crops its contents and supports displaying a coloured dot on a top corner.
32 */
33public class BadgedImageView extends ImageView {
34
35 private BadgeRenderer mDotRenderer;
36 private int mIconSize;
37 private Rect mTempBounds = new Rect();
38 private Point mTempPoint = new Point();
39 private Path mClipPath = new Path();
40
41 private float mDotScale = 0f;
42 private int mUpdateDotColor;
Joshua Tsuji580c0bf2019-01-28 13:28:21 -050043 private int mBubbleDefaultBgColor;
Mady Mellor3f2efdb2018-11-21 11:30:45 -080044 private boolean mShowUpdateDot;
45 private boolean mOnLeft;
46
47 public BadgedImageView(Context context) {
48 this(context, null);
49 }
50
51 public BadgedImageView(Context context, AttributeSet attrs) {
52 this(context, attrs, 0);
53 }
54
55 public BadgedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
56 this(context, attrs, defStyleAttr, 0);
57 }
58
59 public BadgedImageView(Context context, AttributeSet attrs, int defStyleAttr,
60 int defStyleRes) {
61 super(context, attrs, defStyleAttr, defStyleRes);
62 setScaleType(ScaleType.CENTER_CROP);
Joshua Tsujib1a796b2019-01-16 15:43:12 -080063 mIconSize = getResources().getDimensionPixelSize(R.dimen.individual_bubble_size);
Mady Mellor3f2efdb2018-11-21 11:30:45 -080064 mDotRenderer = new BadgeRenderer(mIconSize);
Joshua Tsuji580c0bf2019-01-28 13:28:21 -050065
66 TypedArray ta = context.obtainStyledAttributes(
67 new int[] {android.R.attr.colorBackgroundFloating});
68 mBubbleDefaultBgColor = ta.getColor(0, Color.WHITE);
69 ta.recycle();
Mady Mellor3f2efdb2018-11-21 11:30:45 -080070 }
71
72 // TODO: Clipping oval path isn't great: rerender image into a separate, rounded bitmap and
73 // then draw would be better
74 @Override
75 public void onDraw(Canvas canvas) {
76 canvas.save();
77 // Circle crop
78 mClipPath.addOval(getPaddingStart(), getPaddingTop(),
79 getWidth() - getPaddingEnd(), getHeight() - getPaddingBottom(), Path.Direction.CW);
80 canvas.clipPath(mClipPath);
Joshua Tsuji580c0bf2019-01-28 13:28:21 -050081 canvas.drawColor(mBubbleDefaultBgColor);
Mady Mellor3f2efdb2018-11-21 11:30:45 -080082 super.onDraw(canvas);
83
84 // After we've circle cropped what we're showing, restore so we don't clip the badge
85 canvas.restore();
86
87 // Draw the badge
88 if (mShowUpdateDot) {
89 getDrawingRect(mTempBounds);
90 mTempPoint.set((getWidth() - mIconSize) / 2, getPaddingTop());
91 mDotRenderer.draw(canvas, mUpdateDotColor, mTempBounds, mDotScale, mTempPoint,
92 mOnLeft);
93 }
94 }
95
96 /**
97 * Set whether the dot should appear on left or right side of the view.
98 */
99 public void setDotPosition(boolean onLeft) {
100 mOnLeft = onLeft;
101 invalidate();
102 }
103
104 /**
105 * Set whether the dot should show or not.
106 */
107 public void setShowDot(boolean showBadge) {
108 mShowUpdateDot = showBadge;
109 invalidate();
110 }
111
112 /**
113 * @return whether the dot is being displayed.
114 */
115 public boolean isShowingDot() {
116 return mShowUpdateDot;
117 }
118
119 /**
120 * The colour to use for the dot.
121 */
122 public void setDotColor(int color) {
123 mUpdateDotColor = color;
124 invalidate();
125 }
126
127 /**
128 * How big the dot should be, fraction from 0 to 1.
129 */
130 public void setDotScale(float fraction) {
131 mDotScale = fraction;
132 invalidate();
133 }
134
135 public float getDotScale() {
136 return mDotScale;
137 }
138}