Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
1 /*
2 * Copyright (C) 2013 Square, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.squareup.picasso;
18 import android.content.Context;
19 import android.content.res.Resources;
20 import android.graphics.Bitmap;
21 import android.graphics.Canvas;
22 import android.graphics.ColorFilter;
23 import android.graphics.Paint;
24 import android.graphics.Path;
25 import android.graphics.Point;
26 import android.graphics.Rect;
27 import android.graphics.drawable.AnimationDrawable;
28 import android.graphics.drawable.BitmapDrawable;
29 import android.graphics.drawable.Drawable;
30 import android.os.SystemClock;
31 import android.widget.ImageView;
33 import static android.graphics.Color.WHITE;
34 import static com.squareup.picasso.Picasso.LoadedFrom.MEMORY;
36 final class PicassoDrawable extends Drawable {
37 // Only accessed from main thread.
38 private static final Paint DEBUG_PAINT = new Paint();
40 private static final float FADE_DURATION = 200f; //ms
42 /**
43 * Create or update the drawable on the target {@link ImageView} to display the supplied bitmap
44 * image.
45 */
46 static void setBitmap(ImageView target, Context context, Bitmap bitmap,
47 Picasso.LoadedFrom loadedFrom, boolean noFade, boolean debugging) {
48 Drawable placeholder = target.getDrawable();
49 if (placeholder instanceof AnimationDrawable) {
50 ((AnimationDrawable) placeholder).stop();
51 }
52 PicassoDrawable drawable =
53 new PicassoDrawable(context, placeholder, bitmap, loadedFrom, noFade, debugging);
54 target.setImageDrawable(drawable);
55 }
57 /**
58 * Create or update the drawable on the target {@link ImageView} to display the supplied
59 * placeholder image.
60 */
61 static void setPlaceholder(ImageView target, int placeholderResId, Drawable placeholderDrawable) {
62 if (placeholderResId != 0) {
63 target.setImageResource(placeholderResId);
64 } else {
65 target.setImageDrawable(placeholderDrawable);
66 }
67 if (target.getDrawable() instanceof AnimationDrawable) {
68 ((AnimationDrawable) target.getDrawable()).start();
69 }
70 }
72 private final boolean debugging;
73 private final float density;
74 private final Picasso.LoadedFrom loadedFrom;
75 final BitmapDrawable image;
77 Drawable placeholder;
79 long startTimeMillis;
80 boolean animating;
81 int alpha = 0xFF;
83 PicassoDrawable(Context context, Drawable placeholder, Bitmap bitmap,
84 Picasso.LoadedFrom loadedFrom, boolean noFade, boolean debugging) {
85 Resources res = context.getResources();
87 this.debugging = debugging;
88 this.density = res.getDisplayMetrics().density;
90 this.loadedFrom = loadedFrom;
92 this.image = new BitmapDrawable(res, bitmap);
94 boolean fade = loadedFrom != MEMORY && !noFade;
95 if (fade) {
96 this.placeholder = placeholder;
97 animating = true;
98 startTimeMillis = SystemClock.uptimeMillis();
99 }
100 }
102 @Override public void draw(Canvas canvas) {
103 if (!animating) {
104 image.draw(canvas);
105 } else {
106 float normalized = (SystemClock.uptimeMillis() - startTimeMillis) / FADE_DURATION;
107 if (normalized >= 1f) {
108 animating = false;
109 placeholder = null;
110 image.draw(canvas);
111 } else {
112 if (placeholder != null) {
113 placeholder.draw(canvas);
114 }
116 int partialAlpha = (int) (alpha * normalized);
117 image.setAlpha(partialAlpha);
118 image.draw(canvas);
119 image.setAlpha(alpha);
120 invalidateSelf();
121 }
122 }
124 if (debugging) {
125 drawDebugIndicator(canvas);
126 }
127 }
129 @Override public int getIntrinsicWidth() {
130 return image.getIntrinsicWidth();
131 }
133 @Override public int getIntrinsicHeight() {
134 return image.getIntrinsicHeight();
135 }
137 @Override public void setAlpha(int alpha) {
138 this.alpha = alpha;
139 if (placeholder != null) {
140 placeholder.setAlpha(alpha);
141 }
142 image.setAlpha(alpha);
143 }
145 @Override public void setColorFilter(ColorFilter cf) {
146 if (placeholder != null) {
147 placeholder.setColorFilter(cf);
148 }
149 image.setColorFilter(cf);
150 }
152 @Override public int getOpacity() {
153 return image.getOpacity();
154 }
156 @Override protected void onBoundsChange(Rect bounds) {
157 super.onBoundsChange(bounds);
159 image.setBounds(bounds);
160 if (placeholder != null) {
161 placeholder.setBounds(bounds);
162 }
163 }
165 private void drawDebugIndicator(Canvas canvas) {
166 DEBUG_PAINT.setColor(WHITE);
167 Path path = getTrianglePath(new Point(0, 0), (int) (16 * density));
168 canvas.drawPath(path, DEBUG_PAINT);
170 DEBUG_PAINT.setColor(loadedFrom.debugColor);
171 path = getTrianglePath(new Point(0, 0), (int) (15 * density));
172 canvas.drawPath(path, DEBUG_PAINT);
173 }
175 private static Path getTrianglePath(Point p1, int width) {
176 Point p2 = new Point(p1.x + width, p1.y);
177 Point p3 = new Point(p1.x, p1.y + width);
179 Path path = new Path();
180 path.moveTo(p1.x, p1.y);
181 path.lineTo(p2.x, p2.y);
182 path.lineTo(p3.x, p3.y);
184 return path;
185 }
186 }