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