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; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TypedValue; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>A Drawable that can rotate another Drawable based on the current level 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * value. The start and end angles of rotation can be controlled to map any 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * circular arc to the level values range.</p> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 38dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * <p>It can be defined in an XML file with the <code><rotate></code> element. For more 39dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * information, see the guide to <a 40dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p> 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_visible 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_fromDegrees 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_toDegrees 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_pivotX 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_pivotY 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#RotateDrawable_drawable 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RotateDrawable extends Drawable implements Drawable.Callback { 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float MAX_LEVEL = 10000.0f; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private RotateState mState; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mMutated; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new rotating drawable with an empty state.</p> 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public RotateDrawable() { 599db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru this(null, null); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Create a new rotating drawable with the specified state. A copy of 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this state is used as the internal state for the newly created 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * drawable.</p> 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rotateState the state for this drawable 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 699db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru private RotateDrawable(RotateState rotateState, Resources res) { 709db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru mState = new RotateState(rotateState, this, res); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int saveCount = canvas.save(); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect bounds = mState.mDrawable.getBounds(); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int w = bounds.right - bounds.left; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int h = bounds.bottom - bounds.top; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final RotateState st = mState; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 86a1b92c5e8b750d8f5b2dc5ca7e8b4edc97de5575Adam Powell canvas.rotate(st.mCurrentDegrees, px + bounds.left, py + bounds.top); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st.mDrawable.draw(canvas); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.restoreToCount(saveCount); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the drawable rotated by this RotateDrawable. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable getDrawable() { 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.getChangingConfigurations() 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | mState.mChangingConfigurations 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | mState.mDrawable.getChangingConfigurations(); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setAlpha(alpha); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColorFilter(ColorFilter cf) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setColorFilter(cf); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.getOpacity(); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void invalidateDrawable(Drawable who) { 120f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy final Callback callback = getCallback(); 121f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (callback != null) { 122f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy callback.invalidateDrawable(this); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void scheduleDrawable(Drawable who, Runnable what, long when) { 127f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy final Callback callback = getCallback(); 128f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (callback != null) { 129f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy callback.scheduleDrawable(this, what, when); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unscheduleDrawable(Drawable who, Runnable what) { 134f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy final Callback callback = getCallback(); 135f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy if (callback != null) { 136f2a47782f31b58d2d31bd00b50fe43604af8b9c2Romain Guy callback.unscheduleDrawable(this, what); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getPadding(Rect padding) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.getPadding(padding); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setVisible(boolean visible, boolean restart) { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setVisible(visible, restart); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.setVisible(visible, restart); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStateful() { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.isStateful(); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onStateChange(int[] state) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean changed = mState.mDrawable.setState(state); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project onBoundsChange(getBounds()); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return changed; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onLevelChange(int level) { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setLevel(level); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project onBoundsChange(getBounds()); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mCurrentDegrees = mState.mFromDegrees + 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mState.mToDegrees - mState.mFromDegrees) * 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((float) level / MAX_LEVEL); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateSelf(); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect bounds) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.setBounds(bounds.left, bounds.top, 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.right, bounds.bottom); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.getIntrinsicWidth(); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState.mDrawable.getIntrinsicHeight(); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState.canConstantState()) { 1956efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mState.mChangingConfigurations = getChangingConfigurations(); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = r.obtainAttributes(attrs, 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.inflateWithAttributes(r, parser, a, 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable_visible); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedValue tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotX); 212b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier boolean pivotXRel; 213b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier float pivotX; 214b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier if (tv == null) { 215b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotXRel = true; 216b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotX = 0.5f; 217b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier } else { 218b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotXRel = tv.type == TypedValue.TYPE_FRACTION; 219b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotX = pivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat(); 220b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotY); 223b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier boolean pivotYRel; 224b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier float pivotY; 225b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier if (tv == null) { 226b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotYRel = true; 227b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotY = 0.5f; 228b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier } else { 229b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotYRel = tv.type == TypedValue.TYPE_FRACTION; 230b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier pivotY = pivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat(); 231b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier } 232b81b1447d2cfa9dc5bcc02c8a1b7193400a97ab6Cyril Mottier 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float fromDegrees = a.getFloat( 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float toDegrees = a.getFloat( 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res = a.getResourceId( 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.RotateDrawable_drawable, 0); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable drawable = null; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res > 0) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawable = r.getDrawable(res); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int outerDepth = parser.getDepth(); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((drawable = Drawable.createFromXmlInner(r, parser, attrs)) == null) { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("drawable", "Bad element under <rotate>: " 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + parser .getName()); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (drawable == null) { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("drawable", "No drawable specified for <rotate>"); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable = drawable; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mPivotXRel = pivotXRel; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mPivotX = pivotX; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mPivotYRel = pivotYRel; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mPivotY = pivotY; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mFromDegrees = mState.mCurrentDegrees = fromDegrees; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mToDegrees = toDegrees; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (drawable != null) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawable.setCallback(this); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState.mDrawable.mutate(); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Represents the state of a rotation for a given drawable. The same 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rotate drawable can be invoked with different states to drive several 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rotations at the same time.</p> 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final static class RotateState extends Drawable.ConstantState { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Drawable mDrawable; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mChangingConfigurations; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mPivotXRel; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mPivotX; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mPivotYRel; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mPivotY; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mFromDegrees; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mToDegrees; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mCurrentDegrees; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mCanConstantState; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mCheckedConstantState; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3119db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru public RotateState(RotateState source, RotateDrawable owner, Resources res) { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (source != null) { 3139db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru if (res != null) { 3149db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru mDrawable = source.mDrawable.getConstantState().newDrawable(res); 3159db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru } else { 3169db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru mDrawable = source.mDrawable.getConstantState().newDrawable(); 3179db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDrawable.setCallback(owner); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPivotXRel = source.mPivotXRel; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPivotX = source.mPivotX; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPivotYRel = source.mPivotYRel; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPivotY = source.mPivotY; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFromDegrees = mCurrentDegrees = source.mFromDegrees; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mToDegrees = source.mToDegrees; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCanConstantState = mCheckedConstantState = true; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable newDrawable() { 3319db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru return new RotateDrawable(this, null); 3329db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru } 3339db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru 3349db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru @Override 3359db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru public Drawable newDrawable(Resources res) { 3369db3d07b9620b4269ab33f78604a36327e536ce1Jean-Baptiste Queru return new RotateDrawable(this, res); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChangingConfigurations; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean canConstantState() { 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mCheckedConstantState) { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCanConstantState = mDrawable.getConstantState() != null; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCheckedConstantState = true; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCanConstantState; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 354