183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar/*
283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Copyright (C) 2014 The Android Open Source Project
383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar *
483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * you may not use this file except in compliance with the License.
683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * You may obtain a copy of the License at
783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar *
883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar *
1083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Unless required by applicable law or agreed to in writing, software
1183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
1283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * See the License for the specific language governing permissions and
1483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * limitations under the License.
1583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar */
1683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarpackage android.support.v7.widget;
1783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
1883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.Canvas;
1983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.ColorFilter;
2083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.Outline;
2183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.Paint;
2283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.PixelFormat;
2383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.Rect;
2483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.RectF;
2583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.drawable.Drawable;
2683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
27bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyarimport static android.support.v7.widget.RoundRectDrawableWithShadow.calculateVerticalPadding;
28bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyarimport static android.support.v7.widget.RoundRectDrawableWithShadow.calculateHorizontalPadding;
29bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
3083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar/**
3183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Very simple drawable that draws a rounded rectangle background with arbitrary corners and also
3283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * reports proper outline for L.
3383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * <p>
3483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Simpler and uses less resources compared to GradientDrawable or ShapeDrawable.
3583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar */
3683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarclass RoundRectDrawable extends Drawable {
37bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    private float mRadius;
38bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    private final Paint mPaint;
39bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    private final RectF mBoundsF;
40bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    private final Rect mBoundsI;
41bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    private float mPadding;
42bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    private boolean mInsetForPadding = false;
43c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar    private boolean mInsetForRadius = true;
4483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
45c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar    public RoundRectDrawable(int backgroundColor, float radius) {
4683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        mRadius = radius;
4783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
4883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        mPaint.setColor(backgroundColor);
49bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mBoundsF = new RectF();
50bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mBoundsI = new Rect();
51bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
52bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
53c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar    void setPadding(float padding, boolean insetForPadding, boolean insetForRadius) {
54c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar        if (padding == mPadding && mInsetForPadding == insetForPadding &&
55c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar                mInsetForRadius == insetForRadius) {
56bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar            return;
57bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        }
58bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mPadding = padding;
59bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mInsetForPadding = insetForPadding;
60c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar        mInsetForRadius = insetForRadius;
61bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        updateBounds(null);
62bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        invalidateSelf();
63bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
64bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
65bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    float getPadding() {
66bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        return mPadding;
6783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
6883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
6983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    @Override
7083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public void draw(Canvas canvas) {
71bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        canvas.drawRoundRect(mBoundsF, mRadius, mRadius, mPaint);
72bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
73bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
74bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    private void updateBounds(Rect bounds) {
75bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        if (bounds == null) {
76bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar            bounds = getBounds();
77bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        }
78bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mBoundsF.set(bounds.left, bounds.top, bounds.right, bounds.bottom);
79bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mBoundsI.set(bounds);
80bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        if (mInsetForPadding) {
81c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar            float vInset = calculateVerticalPadding(mPadding, mRadius, mInsetForRadius);
82c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar            float hInset = calculateHorizontalPadding(mPadding, mRadius, mInsetForRadius);
83bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar            mBoundsI.inset((int) Math.ceil(hInset), (int) Math.ceil(vInset));
84c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar            // to make sure they have same bounds.
85c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar            mBoundsF.set(mBoundsI);
86bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        }
8783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
8883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
8983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    @Override
9083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    protected void onBoundsChange(Rect bounds) {
9183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        super.onBoundsChange(bounds);
92bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        updateBounds(bounds);
9383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
9483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
9583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    @Override
96bf43be6ab14db8489f924d1673951f0c49014605Chris Craik    public void getOutline(Outline outline) {
97bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        outline.setRoundRect(mBoundsI, mRadius);
9883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
9983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
100bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    void setRadius(float radius) {
10183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        if (radius == mRadius) {
10283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar            return;
10383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        }
10483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        mRadius = radius;
105bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        updateBounds(null);
10683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        invalidateSelf();
10783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
10883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
10983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    @Override
11083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public void setAlpha(int alpha) {
11183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        // not supported because older versions do not support
11283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
11383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
11483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    @Override
11583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public void setColorFilter(ColorFilter cf) {
11683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        // not supported because older versions do not support
11783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
11883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
11983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    @Override
12083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public int getOpacity() {
121ad124ea5fa71f1b675c9c42b858adfbc42093d37Yigit Boyar        return PixelFormat.TRANSLUCENT;
12283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
12383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
12483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public float getRadius() {
12583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        return mRadius;
12683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
1274eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar
1284eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar    public void setColor(int color) {
1294eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar        mPaint.setColor(color);
1304eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar        invalidateSelf();
1314eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar    }
13283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar}
133