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.content.Context; 19d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikasimport android.content.res.ColorStateList; 2083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.Canvas; 2183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.Paint; 2218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyarimport android.graphics.Rect; 2383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.graphics.RectF; 24e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikasimport android.support.annotation.ColorInt; 25d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikasimport android.support.annotation.Nullable; 2683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 2783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarclass CardViewEclairMr1 implements CardViewImpl { 2883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 2983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar final RectF sCornerRect = new RectF(); 3083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 3183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar @Override 3283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar public void initStatic() { 3383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar // Draws a round rect using 7 draw operations. This is faster than using 3483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar // canvas.drawRoundRect before JBMR1 because API 11-16 used alpha mask textures to draw 3583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar // shapes. 368578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas RoundRectDrawableWithShadow.sRoundRectHelper = 378578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas new RoundRectDrawableWithShadow.RoundRectHelper() { 3883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar @Override 3983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, 4083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar Paint paint) { 4183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar final float twoRadius = cornerRadius * 2; 42db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar final float innerWidth = bounds.width() - twoRadius - 1; 43db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar final float innerHeight = bounds.height() - twoRadius - 1; 44db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar if (cornerRadius >= 1f) { 458578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas // increment corner radius to account for half pixels. 468578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas float roundedCornerRadius = cornerRadius + .5f; 478578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas sCornerRect.set(-roundedCornerRadius, -roundedCornerRadius, roundedCornerRadius, 488578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas roundedCornerRadius); 49db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar int saved = canvas.save(); 508578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas canvas.translate(bounds.left + roundedCornerRadius, 518578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas bounds.top + roundedCornerRadius); 52db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.drawArc(sCornerRect, 180, 90, true, paint); 53db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.translate(innerWidth, 0); 54db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.rotate(90); 55db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.drawArc(sCornerRect, 180, 90, true, paint); 56db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.translate(innerHeight, 0); 57db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.rotate(90); 58db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.drawArc(sCornerRect, 180, 90, true, paint); 59db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.translate(innerWidth, 0); 60db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.rotate(90); 61db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.drawArc(sCornerRect, 180, 90, true, paint); 62db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar canvas.restoreToCount(saved); 63db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar //draw top and bottom pieces 648578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas canvas.drawRect(bounds.left + roundedCornerRadius - 1f, bounds.top, 658578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas bounds.right - roundedCornerRadius + 1f, 668578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas bounds.top + roundedCornerRadius, paint); 67378f43e4b46983d21915b37ff483b1725f144daeAurimas Liutikas 688578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas canvas.drawRect(bounds.left + roundedCornerRadius - 1f, 69378f43e4b46983d21915b37ff483b1725f144daeAurimas Liutikas bounds.bottom - roundedCornerRadius, 708578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas bounds.right - roundedCornerRadius + 1f, bounds.bottom, paint); 71db27cfc95b2f12aefacdd4d656910650a7fd4663Yigit Boyar } 728578605a165ca215bab90ee548cd305abadfa893Aurimas Liutikas // center 73378f43e4b46983d21915b37ff483b1725f144daeAurimas Liutikas canvas.drawRect(bounds.left, bounds.top + cornerRadius, 74378f43e4b46983d21915b37ff483b1725f144daeAurimas Liutikas bounds.right, bounds.bottom - cornerRadius , paint); 7583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 7683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar }; 7783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 7883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 7983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar @Override 80d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas public void initialize(CardViewDelegate cardView, Context context, 81d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas ColorStateList backgroundColor, float radius, float elevation, float maxElevation) { 8218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar RoundRectDrawableWithShadow background = createBackground(context, backgroundColor, radius, 8318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar elevation, maxElevation); 84c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar background.setAddPaddingForCorners(cardView.getPreventCornerOverlap()); 85ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes cardView.setCardBackground(background); 8618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar updatePadding(cardView); 8718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 8818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 8986223c8f397daa57fff72d6bd5cf10ceeb74d40eChris Banes private RoundRectDrawableWithShadow createBackground(Context context, 9086223c8f397daa57fff72d6bd5cf10ceeb74d40eChris Banes ColorStateList backgroundColor, float radius, float elevation, 9186223c8f397daa57fff72d6bd5cf10ceeb74d40eChris Banes float maxElevation) { 9218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar return new RoundRectDrawableWithShadow(context.getResources(), backgroundColor, radius, 9318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar elevation, maxElevation); 9418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 9518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 96bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar @Override 97bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public void updatePadding(CardViewDelegate cardView) { 9818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar Rect shadowPadding = new Rect(); 9918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar getShadowBackground(cardView).getMaxShadowAndCornerPadding(shadowPadding); 10072aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar cardView.setMinWidthHeightInternal((int) Math.ceil(getMinWidth(cardView)), 10172aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar (int) Math.ceil(getMinHeight(cardView))); 102bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar cardView.setShadowPadding(shadowPadding.left, shadowPadding.top, 103bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar shadowPadding.right, shadowPadding.bottom); 104bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 105bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 106bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar @Override 107bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public void onCompatPaddingChanged(CardViewDelegate cardView) { 108bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar // NO OP 10983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 11083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 11183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar @Override 112c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar public void onPreventCornerOverlapChanged(CardViewDelegate cardView) { 113c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar getShadowBackground(cardView).setAddPaddingForCorners(cardView.getPreventCornerOverlap()); 114c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar updatePadding(cardView); 115c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar } 116c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar 117c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar @Override 118d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas public void setBackgroundColor(CardViewDelegate cardView, @Nullable ColorStateList color) { 1194eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar getShadowBackground(cardView).setColor(color); 1204eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar } 1214eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar 122e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas public ColorStateList getBackgroundColor(CardViewDelegate cardView) { 123e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas return getShadowBackground(cardView).getColor(); 124e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas } 125e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas 1264eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar @Override 12783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar public void setRadius(CardViewDelegate cardView, float radius) { 12818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar getShadowBackground(cardView).setCornerRadius(radius); 12918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar updatePadding(cardView); 13083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 13183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 13283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar @Override 13383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar public float getRadius(CardViewDelegate cardView) { 13418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar return getShadowBackground(cardView).getCornerRadius(); 13518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 13618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 13718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar @Override 13818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public void setElevation(CardViewDelegate cardView, float elevation) { 13918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar getShadowBackground(cardView).setShadowSize(elevation); 14018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 14118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 14218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar @Override 14318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public float getElevation(CardViewDelegate cardView) { 14418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar return getShadowBackground(cardView).getShadowSize(); 14518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 14618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 14718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar @Override 14818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public void setMaxElevation(CardViewDelegate cardView, float maxElevation) { 14918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar getShadowBackground(cardView).setMaxShadowSize(maxElevation); 15018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar updatePadding(cardView); 15118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 15218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 15318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar @Override 15418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public float getMaxElevation(CardViewDelegate cardView) { 15518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar return getShadowBackground(cardView).getMaxShadowSize(); 15618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 15718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 15818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar @Override 15918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public float getMinWidth(CardViewDelegate cardView) { 16018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar return getShadowBackground(cardView).getMinWidth(); 16118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 16218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 16318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar @Override 16418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public float getMinHeight(CardViewDelegate cardView) { 16518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar return getShadowBackground(cardView).getMinHeight(); 16618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 16718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 16818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar private RoundRectDrawableWithShadow getShadowBackground(CardViewDelegate cardView) { 169ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes return ((RoundRectDrawableWithShadow) cardView.getCardBackground()); 17083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 171aa1de96894cfef188ac84b721812551d8f79a69dYigit Boyar} 172