RotateDrawable.java revision b3c56086d802ae28888dd97ba1f49bd6cee0b673
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics.drawable; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.ColorFilter; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 25b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.graphics.PorterDuff.Mode; 26b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viveretteimport android.content.res.ColorStateList; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 2952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TypedValue; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 37a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * <p> 38a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * A Drawable that can rotate another Drawable based on the current level value. 39a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * The start and end angles of rotation can be controlled to map any circular 40a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * arc to the level values range. 41a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * <p> 42a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * It can be defined in an XML file with the <code><rotate></code> element. 43a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * For more information, see the guide to 44a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * <a href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_visible 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_fromDegrees 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_toDegrees 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_pivotX 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_pivotY 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_drawable 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RotateDrawable extends Drawable implements Drawable.Callback { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float MAX_LEVEL = 10000.0f; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette private final RotateState mState; 57a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mMutated; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 61a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Create a new rotating drawable with an empty state. 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public RotateDrawable() { 649db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru this(null, null); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 68a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Create a new rotating drawable with the specified state. A copy of 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this state is used as the internal state for the newly created 70a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * drawable. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rotateState the state for this drawable 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru private RotateDrawable(RotateState rotateState, Resources res) { 759db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru mState = new RotateState(rotateState, this, res); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette @Override 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas) { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final RotateState st = mState; 81a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final Drawable d = st.mDrawable; 82a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final Rect bounds = d.getBounds(); 83a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final int w = bounds.right - bounds.left; 84a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final int h = bounds.bottom - bounds.top; 85a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX; 86a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY; 87a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 88a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final int saveCount = canvas.save(); 89a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell canvas.rotate(st.mCurrentDegrees, px + bounds.left, py + bounds.top); 90a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette d.draw(canvas); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.restoreToCount(saveCount); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 95a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Sets the drawable rotated by this RotateDrawable. 96a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * 97a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @param drawable The drawable to rotate 98a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 99a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public void setDrawable(Drawable drawable) { 100a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final Drawable oldDrawable = mState.mDrawable; 101a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette if (oldDrawable != drawable) { 102a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette if (oldDrawable != null) { 103a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette oldDrawable.setCallback(null); 104a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 105a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette mState.mDrawable = drawable; 106a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette if (drawable != null) { 107a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette drawable.setCallback(this); 108a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 109a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 110a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 111a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 112a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 113a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @return The drawable rotated by this RotateDrawable 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getDrawable() { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.getChangingConfigurations() 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | mState.mChangingConfigurations 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | mState.mDrawable.getChangingConfigurations(); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 125a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 126a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette @Override 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setAlpha(alpha); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 131b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 132b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase public int getAlpha() { 133b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase return mState.mDrawable.getAlpha(); 134b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase } 135b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase 136a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette @Override 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColorFilter(ColorFilter cf) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setColorFilter(cf); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 141a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette @Override 142b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette public void setTint(ColorStateList tint, Mode tintMode) { 143b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette mState.mDrawable.setTint(tint, tintMode); 144b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette } 145b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette 146b3c56086d802ae28888dd97ba1f49bd6cee0b673Alan Viverette @Override 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.getOpacity(); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 151a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 152a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Sets the start angle for rotation. 153a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * 154a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @param fromDegrees Starting angle in degrees 155e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 156e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @see #getFromDegrees() 157e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @attr ref android.R.styleable#RotateDrawable_fromDegrees 158a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 159a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public void setFromDegrees(float fromDegrees) { 160a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette if (mState.mFromDegrees != fromDegrees) { 161a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette mState.mFromDegrees = fromDegrees; 162a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette invalidateSelf(); 163a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 164a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 165a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 166a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 167a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @return The starting angle for rotation in degrees 168e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 169e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @see #setFromDegrees(float) 170e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @attr ref android.R.styleable#RotateDrawable_fromDegrees 171a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 172a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public float getFromDegrees() { 173a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette return mState.mFromDegrees; 174a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 175a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 176a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 177a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Sets the end angle for rotation. 178a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * 179a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @param toDegrees Ending angle in degrees 180e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 181e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @see #getToDegrees() 182e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @attr ref android.R.styleable#RotateDrawable_toDegrees 183a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 184a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public void setToDegrees(float toDegrees) { 185a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette if (mState.mToDegrees != toDegrees) { 186a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette mState.mToDegrees = toDegrees; 187a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette invalidateSelf(); 188a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 189a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 190a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 191a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 192a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @return The ending angle for rotation in degrees 193e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 194e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @see #setToDegrees(float) 195e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @attr ref android.R.styleable#RotateDrawable_toDegrees 196a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 197a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public float getToDegrees() { 198a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette return mState.mToDegrees; 199a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 200a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 201a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 202a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Sets the X position around which the drawable is rotated. 203a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * 204a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @param pivotX X position around which to rotate. If the X pivot is 205a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * relative, the position represents a fraction of the drawable 206a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * width. Otherwise, the position represents an absolute value in 207a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * pixels. 208e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 209a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @see #setPivotXRelative(boolean) 210e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @attr ref android.R.styleable#RotateDrawable_pivotX 211a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 212a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public void setPivotX(float pivotX) { 213a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette if (mState.mPivotX == pivotX) { 214a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette mState.mPivotX = pivotX; 215a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette invalidateSelf(); 216a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 217a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 218a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 219a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 220a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @return X position around which to rotate 221e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 222a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @see #setPivotX(float) 223e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @attr ref android.R.styleable#RotateDrawable_pivotX 224a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 225a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public float getPivotX() { 226a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette return mState.mPivotX; 227a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 228a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 229a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 230a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Sets whether the X pivot value represents a fraction of the drawable 231a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * width or an absolute value in pixels. 232a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * 233a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @param relative True if the X pivot represents a fraction of the drawable 234a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * width, or false if it represents an absolute value in pixels 235e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 236e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @see #isPivotXRelative() 237a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 238a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public void setPivotXRelative(boolean relative) { 239a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette if (mState.mPivotXRel == relative) { 240a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette mState.mPivotXRel = relative; 241a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette invalidateSelf(); 242a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 243a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 244a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 245a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 246a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @return True if the X pivot represents a fraction of the drawable width, 247a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * or false if it represents an absolute value in pixels 248e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 249a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @see #setPivotXRelative(boolean) 250a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 251a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public boolean isPivotXRelative() { 252a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette return mState.mPivotXRel; 253a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 254a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 255a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 256a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Sets the Y position around which the drawable is rotated. 257a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * 258a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @param pivotY Y position around which to rotate. If the Y pivot is 259a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * relative, the position represents a fraction of the drawable 260a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * height. Otherwise, the position represents an absolute value 261a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * in pixels. 262e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 263e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @see #getPivotY() 264e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @attr ref android.R.styleable#RotateDrawable_pivotY 265a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 266a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public void setPivotY(float pivotY) { 267a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette if (mState.mPivotY == pivotY) { 268a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette mState.mPivotY = pivotY; 269a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette invalidateSelf(); 270a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 271a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 272a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 273a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 274a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @return Y position around which to rotate 275e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 276a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @see #setPivotY(float) 277e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @attr ref android.R.styleable#RotateDrawable_pivotY 278a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 279a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public float getPivotY() { 280a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette return mState.mPivotY; 281a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 282a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 283a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 284a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Sets whether the Y pivot value represents a fraction of the drawable 285a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * height or an absolute value in pixels. 286a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * 287a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @param relative True if the Y pivot represents a fraction of the drawable 288a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * height, or false if it represents an absolute value in pixels 289e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 290e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * @see #isPivotYRelative() 291a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 292a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public void setPivotYRelative(boolean relative) { 293a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette if (mState.mPivotYRel == relative) { 294a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette mState.mPivotYRel = relative; 295a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette invalidateSelf(); 296a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 297a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 298a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 299a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette /** 300a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @return True if the Y pivot represents a fraction of the drawable height, 301a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * or false if it represents an absolute value in pixels 302e5b082d6eb0489e7dbe3159338f8c94c0af61deeAlan Viverette * 303a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * @see #setPivotYRelative(boolean) 304a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette */ 305a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette public boolean isPivotYRelative() { 306a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette return mState.mPivotYRel; 307a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette } 308a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 309a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette @Override 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void invalidateDrawable(Drawable who) { 311f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy final Callback callback = getCallback(); 312f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (callback != null) { 313f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy callback.invalidateDrawable(this); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 317a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette @Override 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleDrawable(Drawable who, Runnable what, long when) { 319f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy final Callback callback = getCallback(); 320f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (callback != null) { 321f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy callback.scheduleDrawable(this, what, when); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 325a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette @Override 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unscheduleDrawable(Drawable who, Runnable what) { 327f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy final Callback callback = getCallback(); 328f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (callback != null) { 329f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy callback.unscheduleDrawable(this, what); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getPadding(Rect padding) { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.getPadding(padding); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setVisible(boolean visible, boolean restart) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setVisible(visible, restart); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.setVisible(visible, restart); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStateful() { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.isStateful(); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 348a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onStateChange(int[] state) { 351a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final boolean changed = mState.mDrawable.setState(state); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project onBoundsChange(getBounds()); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return changed; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onLevelChange(int level) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setLevel(level); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project onBoundsChange(getBounds()); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mCurrentDegrees = mState.mFromDegrees + 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mState.mToDegrees - mState.mFromDegrees) * 363a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette (level / MAX_LEVEL); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateSelf(); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect bounds) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setBounds(bounds.left, bounds.top, 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.right, bounds.bottom); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.getIntrinsicWidth(); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.getIntrinsicHeight(); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState.canConstantState()) { 3886efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mState.mChangingConfigurations = getChangingConfigurations(); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 39552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 397a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final TypedArray a = r.obtainAttributes(attrs, 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.inflateWithAttributes(r, parser, a, 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable_visible); 402a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedValue tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotX); 404a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final boolean pivotXRel; 405a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final float pivotX; 406b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier if (tv == null) { 407b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotXRel = true; 408b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotX = 0.5f; 409b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier } else { 410b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotXRel = tv.type == TypedValue.TYPE_FRACTION; 411b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotX = pivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat(); 412b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier } 413a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotY); 415a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final boolean pivotYRel; 416a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final float pivotY; 417b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier if (tv == null) { 418b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotYRel = true; 419b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotY = 0.5f; 420b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier } else { 421b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotYRel = tv.type == TypedValue.TYPE_FRACTION; 422b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotY = pivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat(); 423b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier } 424b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier 425a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final float fromDegrees = a.getFloat( 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f); 427a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final float toDegrees = a.getFloat( 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 430a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final int res = a.getResourceId( 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable_drawable, 0); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable drawable = null; 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res > 0) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawable = r.getDrawable(res); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 438a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 439a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final int outerDepth = parser.getDepth(); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4486dbe51b50e82057af4d29882889444d22ac19c9cAlan Viverette if ((drawable = Drawable.createFromXmlInner(r, parser, attrs, theme)) == null) { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("drawable", "Bad element under <rotate>: " 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + parser .getName()); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (drawable == null) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("drawable", "No drawable specified for <rotate>"); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 458a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette final RotateState st = mState; 459a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette st.mDrawable = drawable; 460a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette st.mPivotXRel = pivotXRel; 461a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette st.mPivotX = pivotX; 462a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette st.mPivotYRel = pivotYRel; 463a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette st.mPivotY = pivotY; 464a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette st.mFromDegrees = fromDegrees; 465a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette st.mCurrentDegrees = fromDegrees; 466a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette st.mToDegrees = toDegrees; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (drawable != null) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawable.setCallback(this); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.mutate(); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 483a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * Represents the state of a rotation for a given drawable. The same 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rotate drawable can be invoked with different states to drive several 485a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette * rotations at the same time. 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final static class RotateState extends Drawable.ConstantState { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable mDrawable; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mChangingConfigurations; 491a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mPivotXRel; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mPivotX; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mPivotYRel; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mPivotY; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mFromDegrees; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mToDegrees; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mCurrentDegrees; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mCanConstantState; 503a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette private boolean mCheckedConstantState; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5059db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru public RotateState(RotateState source, RotateDrawable owner, Resources res) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (source != null) { 5079db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru if (res != null) { 5089db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru mDrawable = source.mDrawable.getConstantState().newDrawable(res); 5099db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru } else { 5109db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru mDrawable = source.mDrawable.getConstantState().newDrawable(); 5119db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru } 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawable.setCallback(owner); 513731ba6649a40529657aa68f93e6febe7d98b4f3bFabrice Di Meglio mDrawable.setLayoutDirection(source.mDrawable.getLayoutDirection()); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPivotXRel = source.mPivotXRel; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPivotX = source.mPivotX; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPivotYRel = source.mPivotYRel; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPivotY = source.mPivotY; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFromDegrees = mCurrentDegrees = source.mFromDegrees; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mToDegrees = source.mToDegrees; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCanConstantState = mCheckedConstantState = true; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable newDrawable() { 5269db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru return new RotateDrawable(this, null); 5279db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru } 528a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 5299db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru @Override 5309db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru public Drawable newDrawable(Resources res) { 5319db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru return new RotateDrawable(this, res); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 533a8b2edec93beeaa76b3cfc93bb9cb3e19fc34addAlan Viverette 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChangingConfigurations; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean canConstantState() { 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mCheckedConstantState) { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCanConstantState = mDrawable.getConstantState() != null; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCheckedConstantState = true; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCanConstantState; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 549