summaryrefslogtreecommitdiffstats
path: root/core/java/android/transition/MatrixClippedDrawable.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/transition/MatrixClippedDrawable.java')
-rw-r--r--core/java/android/transition/MatrixClippedDrawable.java300
1 files changed, 300 insertions, 0 deletions
diff --git a/core/java/android/transition/MatrixClippedDrawable.java b/core/java/android/transition/MatrixClippedDrawable.java
new file mode 100644
index 0000000..ebaad59
--- /dev/null
+++ b/core/java/android/transition/MatrixClippedDrawable.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.transition;
+
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.Property;
+
+/**
+ * Used in MoveImage to mock an ImageView as a Drawable to be scaled in the scene root Overlay.
+ * @hide
+ */
+class MatrixClippedDrawable extends Drawable implements Drawable.Callback {
+ private static final String TAG = "MatrixClippedDrawable";
+
+ private ClippedMatrixState mClippedMatrixState;
+
+ public static final Property<MatrixClippedDrawable, Rect> CLIP_PROPERTY
+ = new Property<MatrixClippedDrawable, Rect>(Rect.class, "clipRect") {
+
+ @Override
+ public Rect get(MatrixClippedDrawable object) {
+ return object.getClipRect();
+ }
+
+ @Override
+ public void set(MatrixClippedDrawable object, Rect value) {
+ object.setClipRect(value);
+ }
+ };
+
+ public static final Property<MatrixClippedDrawable, Matrix> MATRIX_PROPERTY
+ = new Property<MatrixClippedDrawable, Matrix>(Matrix.class, "matrix") {
+ @Override
+ public void set(MatrixClippedDrawable object, Matrix value) {
+ object.setMatrix(value);
+ }
+
+ @Override
+ public Matrix get(MatrixClippedDrawable object) {
+ return object.getMatrix();
+ }
+ };
+
+ public MatrixClippedDrawable(Drawable drawable) {
+ this(null, null);
+
+ mClippedMatrixState.mDrawable = drawable;
+
+ if (drawable != null) {
+ drawable.setCallback(this);
+ }
+ }
+
+ public void setMatrix(Matrix matrix) {
+ if (matrix == null) {
+ mClippedMatrixState.mMatrix = null;
+ } else {
+ if (mClippedMatrixState.mMatrix == null) {
+ mClippedMatrixState.mMatrix = new Matrix();
+ }
+ mClippedMatrixState.mMatrix.set(matrix);
+ }
+ invalidateSelf();
+ }
+
+ public Matrix getMatrix() {
+ return mClippedMatrixState.mMatrix;
+ }
+
+ public Rect getClipRect() {
+ return mClippedMatrixState.mClipRect;
+ }
+
+ public void setClipRect(Rect clipRect) {
+ if (clipRect == null) {
+ if (mClippedMatrixState.mClipRect != null) {
+ mClippedMatrixState.mClipRect = null;
+ invalidateSelf();
+ }
+ } else {
+ if (mClippedMatrixState.mClipRect == null) {
+ mClippedMatrixState.mClipRect = new Rect(clipRect);
+ } else {
+ mClippedMatrixState.mClipRect.set(clipRect);
+ }
+ invalidateSelf();
+ }
+ }
+
+ // overrides from Drawable.Callback
+
+ public void invalidateDrawable(Drawable who) {
+ final Drawable.Callback callback = getCallback();
+ if (callback != null) {
+ callback.invalidateDrawable(this);
+ }
+ }
+
+ public void scheduleDrawable(Drawable who, Runnable what, long when) {
+ final Drawable.Callback callback = getCallback();
+ if (callback != null) {
+ callback.scheduleDrawable(this, what, when);
+ }
+ }
+
+ public void unscheduleDrawable(Drawable who, Runnable what) {
+ final Drawable.Callback callback = getCallback();
+ if (callback != null) {
+ callback.unscheduleDrawable(this, what);
+ }
+ }
+
+ // overrides from Drawable
+
+ @Override
+ public int getChangingConfigurations() {
+ return super.getChangingConfigurations()
+ | mClippedMatrixState.mChangingConfigurations
+ | mClippedMatrixState.mDrawable.getChangingConfigurations();
+ }
+
+ @Override
+ public boolean getPadding(Rect padding) {
+ // XXX need to adjust padding!
+ return mClippedMatrixState.mDrawable.getPadding(padding);
+ }
+
+ @Override
+ public boolean setVisible(boolean visible, boolean restart) {
+ mClippedMatrixState.mDrawable.setVisible(visible, restart);
+ return super.setVisible(visible, restart);
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ mClippedMatrixState.mDrawable.setAlpha(alpha);
+ }
+
+ @Override
+ public int getAlpha() {
+ return mClippedMatrixState.mDrawable.getAlpha();
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ mClippedMatrixState.mDrawable.setColorFilter(cf);
+ }
+
+ @Override
+ public int getOpacity() {
+ return mClippedMatrixState.mDrawable.getOpacity();
+ }
+
+ @Override
+ public boolean isStateful() {
+ return mClippedMatrixState.mDrawable.isStateful();
+ }
+
+ @Override
+ protected boolean onStateChange(int[] state) {
+ return mClippedMatrixState.mDrawable.setState(state);
+ }
+
+ @Override
+ protected boolean onLevelChange(int level) {
+ mClippedMatrixState.mDrawable.setLevel(level);
+ invalidateSelf();
+ return true;
+ }
+
+ @Override
+ protected void onBoundsChange(Rect bounds) {
+ super.setBounds(bounds);
+ if (mClippedMatrixState.mMatrix == null) {
+ mClippedMatrixState.mDrawable.setBounds(bounds);
+ } else {
+ int drawableWidth = mClippedMatrixState.mDrawable.getIntrinsicWidth();
+ int drawableHeight = mClippedMatrixState.mDrawable.getIntrinsicHeight();
+ mClippedMatrixState.mDrawable.setBounds(bounds.left, bounds.top,
+ drawableWidth + bounds.left, drawableHeight + bounds.top);
+ }
+ invalidateSelf();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ Rect bounds = getBounds();
+ int left = bounds.left;
+ int top = bounds.top;
+ int saveCount = canvas.getSaveCount();
+ canvas.save();
+ if (mClippedMatrixState.mClipRect != null) {
+ canvas.clipRect(mClippedMatrixState.mClipRect);
+ } else {
+ canvas.clipRect(bounds);
+ }
+
+ if (mClippedMatrixState != null && !mClippedMatrixState.mMatrix.isIdentity()) {
+ canvas.translate(left, top);
+ canvas.concat(mClippedMatrixState.mMatrix);
+ canvas.translate(-left, -top);
+ }
+ mClippedMatrixState.mDrawable.draw(canvas);
+ canvas.restoreToCount(saveCount);
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mClippedMatrixState.mDrawable.getIntrinsicWidth();
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mClippedMatrixState.mDrawable.getIntrinsicHeight();
+ }
+
+ @Override
+ public Drawable.ConstantState getConstantState() {
+ if (mClippedMatrixState.canConstantState()) {
+ mClippedMatrixState.mChangingConfigurations = getChangingConfigurations();
+ return mClippedMatrixState;
+ }
+ return null;
+ }
+
+ final static class ClippedMatrixState extends Drawable.ConstantState {
+ Drawable mDrawable;
+ Matrix mMatrix;
+ Rect mClipRect;
+
+ private boolean mCheckedConstantState;
+ private boolean mCanConstantState;
+ int mChangingConfigurations;
+
+ ClippedMatrixState(ClippedMatrixState orig, MatrixClippedDrawable owner, Resources res) {
+ if (orig != null) {
+ if (res != null) {
+ mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
+ } else {
+ mDrawable = orig.mDrawable.getConstantState().newDrawable();
+ }
+ mDrawable.setCallback(owner);
+ mCheckedConstantState = mCanConstantState = true;
+ if (orig.mMatrix != null) {
+ mMatrix = new Matrix(orig.mMatrix);
+ }
+ if (orig.mClipRect != null) {
+ mClipRect = new Rect(orig.mClipRect);
+ }
+ }
+ }
+
+ @Override
+ public Drawable newDrawable() {
+ return new MatrixClippedDrawable(this, null);
+ }
+
+ @Override
+ public Drawable newDrawable(Resources res) {
+ return new MatrixClippedDrawable(this, res);
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return mChangingConfigurations;
+ }
+
+ boolean canConstantState() {
+ if (!mCheckedConstantState) {
+ mCanConstantState = mDrawable.getConstantState() != null;
+ mCheckedConstantState = true;
+ }
+
+ return mCanConstantState;
+ }
+ }
+
+ private MatrixClippedDrawable(ClippedMatrixState state, Resources res) {
+ mClippedMatrixState = new ClippedMatrixState(state, this, res);
+ }
+
+}