18b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen/*
28b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * Copyright (C) 2015 The Android Open Source Project
38b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen *
48b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * Licensed under the Apache License, Version 2.0 (the "License");
58b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * you may not use this file except in compliance with the License.
68b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * You may obtain a copy of the License at
78b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen *
88b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen *      http://www.apache.org/licenses/LICENSE-2.0
98b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen *
108b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * Unless required by applicable law or agreed to in writing, software
118b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * distributed under the License is distributed on an "AS IS" BASIS,
128b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * See the License for the specific language governing permissions and
148b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * limitations under the License.
158b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen */
168b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenpackage android.support.car.ui;
178b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
188b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.content.res.Resources;
198b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.Bitmap;
208b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.Canvas;
218b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.ColorFilter;
228b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.PixelFormat;
238b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.Rect;
248b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.graphics.drawable.Drawable;
258b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.support.annotation.NonNull;
268b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.support.v4.graphics.drawable.RoundedBitmapDrawable;
278b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenimport android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
288b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
298b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
308b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen/**
318b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * A drawable for displaying a circular bitmap. This is a wrapper over RoundedBitmapDrawable,
328b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * since that implementation doesn't behave quite as desired.
338b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen *
348b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * Note that not all drawable functionality is passed to the RoundedBitmapDrawable at this
358b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen * time. Feel free to add more as necessary.
3657de61296cc8f29d8740fc7e6983af9553e7a410Jason Tholstrup * @hide
378b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen */
388b7af7188228ca88838e31e070f0fca0d1f90581Yao Chenpublic class CircleBitmapDrawable extends Drawable {
398b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    private final Resources mResources;
408b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
418b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    private Bitmap mBitmap;
428b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    private RoundedBitmapDrawable mDrawable;
438b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    private int mAlpha = -1;
448b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    private ColorFilter mCf = null;
458b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
468b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    public CircleBitmapDrawable(@NonNull Resources res, @NonNull Bitmap bitmap) {
478b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        mBitmap = bitmap;
488b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        mResources = res;
498b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    }
508b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
518b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    @Override
528b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    public void onBoundsChange(Rect bounds) {
538b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        super.onBoundsChange(bounds);
548b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        int width = bounds.right - bounds.left;
558b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        int height = bounds.bottom - bounds.top;
568b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
578b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        Bitmap processed = mBitmap;
588b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen       /* if (processed.getWidth() != width || processed.getHeight() != height) {
598b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            processed = BitmapUtils.scaleBitmap(processed, width, height);
608b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        }
618b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        // RoundedBitmapDrawable is actually just a rounded rectangle. So it can't turn
628b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        // rectangular images into circles.
638b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        if (processed.getWidth() != processed.getHeight()) {
648b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            int diam = Math.min(width, height);
658b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            Bitmap cropped = BitmapUtils.cropBitmap(processed, diam, diam);
668b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            if (processed != mBitmap) {
678b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen                processed.recycle();
688b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            }
698b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            processed = cropped;
708b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        }*/
718b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        mDrawable = RoundedBitmapDrawableFactory.create(mResources, processed);
728b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        mDrawable.setBounds(bounds);
738b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        mDrawable.setAntiAlias(true);
748b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        mDrawable.setCornerRadius(Math.min(width, height) / 2f);
758b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        if (mAlpha != -1) {
768b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            mDrawable.setAlpha(mAlpha);
778b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        }
788b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        if (mCf != null) {
798b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            mDrawable.setColorFilter(mCf);
808b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        }
818b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        invalidateSelf();
828b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    }
838b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
848b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    @Override
858b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    public void draw(Canvas canvas) {
868b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        if (mDrawable != null) {
878b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            mDrawable.draw(canvas);
888b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        }
898b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    }
908b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
918b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    @Override
928b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    public int getOpacity() {
938b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        return mDrawable != null ? mDrawable.getOpacity() : PixelFormat.TRANSLUCENT;
948b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    }
958b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
968b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    @Override
978b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    public void setAlpha(int alpha) {
988b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        mAlpha = alpha;
998b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        if (mDrawable != null) {
1008b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            mDrawable.setAlpha(alpha);
1018b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            invalidateSelf();
1028b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        }
1038b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    }
1048b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
1058b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    @Override
1068b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    public void setColorFilter(ColorFilter cf) {
1078b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        mCf = cf;
1088b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        if (mDrawable != null) {
1098b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            mDrawable.setColorFilter(cf);
1108b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen            invalidateSelf();
1118b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        }
1128b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    }
1138b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
1148b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    /**
1158b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen     * Convert the drawable to a bitmap.
1168b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen     * @param size The target size of the bitmap in pixels.
1178b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen     * @return A bitmap representation of the drawable.
1188b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen     */
1198b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    public Bitmap toBitmap(int size) {
1208b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        Bitmap largeIcon = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
1218b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        Canvas canvas = new Canvas(largeIcon);
1228b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        Rect bounds = getBounds();
1238b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
1248b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        draw(canvas);
1258b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        setBounds(bounds);
1268b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen        return largeIcon;
1278b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen    }
1288b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen}
1298b7af7188228ca88838e31e070f0fca0d1f90581Yao Chen
130