1f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette/* 2f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * Copyright (C) 2015 The Android Open Source Project 3f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * 4f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * Licensed under the Apache License, Version 2.0 (the "License"); 5f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * you may not use this file except in compliance with the License. 6f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * You may obtain a copy of the License at 7f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * 8f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * http://www.apache.org/licenses/LICENSE-2.0 9f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * 10f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * Unless required by applicable law or agreed to in writing, software 11f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * distributed under the License is distributed on an "AS IS" BASIS, 12f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * See the License for the specific language governing permissions and 14f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * limitations under the License. 15f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette */ 16f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 17f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverettepackage android.graphics.drawable; 18f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 19f872ee0057ed247aa93589347f1b53afc99517f8Alan Viveretteimport android.animation.Animator; 20f872ee0057ed247aa93589347f1b53afc99517f8Alan Viveretteimport android.graphics.Canvas; 21f872ee0057ed247aa93589347f1b53afc99517f8Alan Viveretteimport android.graphics.Paint; 22f872ee0057ed247aa93589347f1b53afc99517f8Alan Viveretteimport android.graphics.Rect; 23bd5294bcb857a48ad22ddd54b13208ec2903c3f6Alan Viveretteimport android.util.DisplayMetrics; 24f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craikimport android.view.DisplayListCanvas; 25f872ee0057ed247aa93589347f1b53afc99517f8Alan Viveretteimport android.view.RenderNodeAnimator; 26f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 27f872ee0057ed247aa93589347f1b53afc99517f8Alan Viveretteimport java.util.ArrayList; 28f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 29f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette/** 300c453ccb87e0b5a4f4b318df01700c9a9a0da545John Reck * Abstract class that handles size & positioning common to the ripple & focus states. 31f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette */ 32f872ee0057ed247aa93589347f1b53afc99517f8Alan Viveretteabstract class RippleComponent { 330c453ccb87e0b5a4f4b318df01700c9a9a0da545John Reck protected final RippleDrawable mOwner; 34f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 35f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette /** Bounds used for computing max radius. May be modified by the owner. */ 36f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette protected final Rect mBounds; 37f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 38f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette /** Whether we have an explicit maximum radius. */ 39f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette private boolean mHasMaxRadius; 40f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 41f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette /** How big this ripple should be when fully entered. */ 42f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette protected float mTargetRadius; 43f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 44f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette /** Screen density used to adjust pixel-based constants. */ 45bd5294bcb857a48ad22ddd54b13208ec2903c3f6Alan Viverette protected float mDensityScale; 46f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 470c453ccb87e0b5a4f4b318df01700c9a9a0da545John Reck public RippleComponent(RippleDrawable owner, Rect bounds) { 48f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette mOwner = owner; 49f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette mBounds = bounds; 50f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette } 51f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 525bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette public void onBoundsChange() { 535bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette if (!mHasMaxRadius) { 545bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette mTargetRadius = getTargetRadius(mBounds); 555bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette onTargetRadiusChanged(mTargetRadius); 565bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette } 575bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette } 585bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette 59bd5294bcb857a48ad22ddd54b13208ec2903c3f6Alan Viverette public final void setup(float maxRadius, int densityDpi) { 60f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette if (maxRadius >= 0) { 61f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette mHasMaxRadius = true; 62f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette mTargetRadius = maxRadius; 63f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette } else { 645bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette mTargetRadius = getTargetRadius(mBounds); 65f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette } 66f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 67bd5294bcb857a48ad22ddd54b13208ec2903c3f6Alan Viverette mDensityScale = densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; 68f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 69f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette onTargetRadiusChanged(mTargetRadius); 70f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette } 71f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 725bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette private static float getTargetRadius(Rect bounds) { 735bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette final float halfWidth = bounds.width() / 2.0f; 745bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette final float halfHeight = bounds.height() / 2.0f; 755bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette return (float) Math.sqrt(halfWidth * halfWidth + halfHeight * halfHeight); 765bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette } 775bc0144302bb378e5f007baa4bf6620ab9031879Alan Viverette 78f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette /** 79f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * Populates {@code bounds} with the maximum drawing bounds of the ripple 80f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * relative to its center. The resulting bounds should be translated into 81f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * parent drawable coordinates before use. 82f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * 83f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * @param bounds the rect to populate with drawing bounds 84f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette */ 85f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette public void getBounds(Rect bounds) { 86f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette final int r = (int) Math.ceil(mTargetRadius); 87f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette bounds.set(-r, -r, r, r); 88f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette } 89f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 90f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette protected final void invalidateSelf() { 9115ce834e52806378d6ab2b90f573bae14cb3fd4bAlan Viverette mOwner.invalidateSelf(false); 92f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette } 93f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 94f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette protected final void onHotspotBoundsChanged() { 95f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette if (!mHasMaxRadius) { 967bb9f374c07258039232711c49a743ea8dc982ffJohn Reck mTargetRadius = getTargetRadius(mBounds); 977bb9f374c07258039232711c49a743ea8dc982ffJohn Reck onTargetRadiusChanged(mTargetRadius); 98f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette } 99f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette } 100f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette 101f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette /** 102f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * Called when the target radius changes. 103f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * 104f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette * @param targetRadius the new target radius 105f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette */ 106f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette protected void onTargetRadiusChanged(float targetRadius) { 107f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette // Stub. 108f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette } 109f872ee0057ed247aa93589347f1b53afc99517f8Alan Viverette} 110