1package com.bumptech.glide;
2
3import android.graphics.Bitmap;
4import android.graphics.drawable.Drawable;
5import android.view.animation.Animation;
6
7import com.bumptech.glide.load.Encoder;
8import com.bumptech.glide.load.Key;
9import com.bumptech.glide.load.ResourceDecoder;
10import com.bumptech.glide.load.ResourceEncoder;
11import com.bumptech.glide.load.Transformation;
12import com.bumptech.glide.load.engine.DiskCacheStrategy;
13import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
14import com.bumptech.glide.load.resource.gif.GifDrawable;
15import com.bumptech.glide.load.resource.gif.GifDrawableTransformation;
16import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
17import com.bumptech.glide.provider.LoadProvider;
18import com.bumptech.glide.request.RequestListener;
19import com.bumptech.glide.request.animation.DrawableCrossFadeFactory;
20import com.bumptech.glide.request.animation.ViewPropertyAnimation;
21
22import java.io.File;
23import java.io.InputStream;
24
25/**
26 * A class for creating a request to load an animated gif.
27 *
28 * <p>
29 *     Warning - It is <em>not</em> safe to use this builder after calling <code>into()</code>, it may be pooled and
30 *     reused.
31 * </p>
32 *
33 * @param  The type of model that will be loaded into the target.
34 */
35public class GifRequestBuilder<ModelType>
36        extends GenericRequestBuilder<ModelType, InputStream, GifDrawable, GifDrawable>
37        implements BitmapOptions, DrawableOptions {
38
39    GifRequestBuilder(LoadProvider<ModelType, InputStream, GifDrawable, GifDrawable> loadProvider,
40            Class<GifDrawable> transcodeClass, GenericRequestBuilder<ModelType, ?, ?, ?> other) {
41        super(loadProvider, transcodeClass, other);
42    }
43
44    /**
45     * {@inheritDoc}
46     */
47    @Override
48    public GifRequestBuilder<ModelType> thumbnail(GenericRequestBuilder<?, ?, ?, GifDrawable> thumbnailRequest) {
49        super.thumbnail(thumbnailRequest);
50        return this;
51    }
52
53    /**
54     * Loads and displays the GIF retrieved by the given thumbnail request if it finishes before this
55     * request. Best used for loading thumbnail GIFs that are smaller and will be loaded more quickly
56     * than the fullsize GIF. There are no guarantees about the order in which the requests will actually
57     * finish. However, if the thumb request completes after the full request, the thumb GIF will never
58     * replace the full image.
59     *
60     * @see #thumbnail(float)
61     *
62     * <p>
63     *     Note - Any options on the main request will not be passed on to the thumbnail request. For example, if
64     *     you want an animation to occur when either the full GIF loads or the thumbnail loads,
65     *     you need to call {@link #animate(int)} on both the thumb and the full request. For a simpler thumbnail
66     *     option where these options are applied to the humbnail as well, see {@link #thumbnail(float)}.
67     * </p>
68     *
69     * <p>
70     *     Only the thumbnail call on the main request will be obeyed, recursive calls to this method are ignored.
71     * </p>
72     *
73     * @param thumbnailRequest The request to use to load the thumbnail.
74     * @return This builder object.
75     */
76    public GifRequestBuilder<ModelType> thumbnail(GifRequestBuilder<?> thumbnailRequest) {
77        super.thumbnail(thumbnailRequest);
78        return this;
79    }
80
81    /**
82     * {@inheritDoc}
83     */
84    @Override
85    public GifRequestBuilder<ModelType> thumbnail(float sizeMultiplier) {
86        super.thumbnail(sizeMultiplier);
87        return this;
88    }
89
90    /**
91     * {@inheritDoc}
92     */
93    @Override
94    public GifRequestBuilder<ModelType> sizeMultiplier(float sizeMultiplier) {
95        super.sizeMultiplier(sizeMultiplier);
96        return this;
97    }
98
99    /**
100     * {@inheritDoc}
101     */
102    @Override
103    public GifRequestBuilder<ModelType> decoder(
104            ResourceDecoder<InputStream, GifDrawable> decoder) {
105        super.decoder(decoder);
106        return this;
107    }
108
109    /**
110     * {@inheritDoc}
111     */
112    @Override
113    public GifRequestBuilder<ModelType> cacheDecoder(
114            ResourceDecoder<File, GifDrawable> cacheDecoder) {
115        super.cacheDecoder(cacheDecoder);
116        return this;
117    }
118
119    /**
120     * {@inheritDoc}
121     */
122    @Override
123    public GifRequestBuilder<ModelType> encoder(
124            ResourceEncoder<GifDrawable> encoder) {
125        super.encoder(encoder);
126        return this;
127    }
128
129    /**
130     * {@inheritDoc}
131     */
132    @Override
133    public GifRequestBuilder<ModelType> priority(Priority priority) {
134        super.priority(priority);
135        return this;
136    }
137
138    /**
139     * Transforms each frame of the GIF using {@link com.bumptech.glide.load.resource.bitmap.CenterCrop}.
140     *
141     * @see #fitCenter()
142     * @see #transformFrame(com.bumptech.glide.load.resource.bitmap.BitmapTransformation...)
143     * @see #transformFrame(com.bumptech.glide.load.Transformation[])
144     * @see #transform(com.bumptech.glide.load.Transformation[])
145     *
146     * @return This request builder.
147     */
148    public GifRequestBuilder<ModelType> centerCrop() {
149        return transformFrame(glide.getBitmapCenterCrop());
150    }
151
152    /**
153     * Transforms each frame of the GIF using {@link com.bumptech.glide.load.resource.bitmap.FitCenter}.
154     *
155     * @see #centerCrop()
156     * @see #transformFrame(com.bumptech.glide.load.resource.bitmap.BitmapTransformation...)
157     * @see #transformFrame(com.bumptech.glide.load.Transformation[])
158     * @see #transform(com.bumptech.glide.load.Transformation[])
159     *
160     * @return This request builder..
161     */
162    public GifRequestBuilder<ModelType> fitCenter() {
163        return transformFrame(glide.getBitmapFitCenter());
164    }
165
166    /**
167     * Transforms each frame of the GIF using the given transformations.
168     *
169     * @see #centerCrop()
170     * @see #fitCenter()
171     * @see #transformFrame(com.bumptech.glide.load.Transformation[])
172     * @see #transform(com.bumptech.glide.load.Transformation[])
173     *
174     * @param bitmapTransformations The transformations to apply in order to each frame.
175     * @return This request builder.
176     */
177    public GifRequestBuilder<ModelType> transformFrame(BitmapTransformation... bitmapTransformations) {
178        return transform(toGifTransformations(bitmapTransformations));
179    }
180
181    /**
182     * Transforms each frame of the GIF using the given transformations.
183     *
184     * @see #fitCenter()
185     * @see #centerCrop()
186     * @see #transformFrame(com.bumptech.glide.load.resource.bitmap.BitmapTransformation...)
187     * @see #transform(com.bumptech.glide.load.Transformation[])
188     *
189     * @param bitmapTransformations The transformations to apply in order to each frame.
190     * @return This request builder.
191     */
192    public GifRequestBuilder<ModelType> transformFrame(Transformation<Bitmap>... bitmapTransformations) {
193        return transform(toGifTransformations(bitmapTransformations));
194    }
195
196    private GifDrawableTransformation[] toGifTransformations(Transformation<Bitmap>[] bitmapTransformations) {
197        GifDrawableTransformation[] transformations = new GifDrawableTransformation[bitmapTransformations.length];
198        for (int i = 0; i < bitmapTransformations.length; i++) {
199            transformations[i] = new GifDrawableTransformation(bitmapTransformations[i], glide.getBitmapPool());
200        }
201        return transformations;
202    }
203
204    /**
205     * {@inheritDoc}
206     *
207     * @see #fitCenter()
208     * @see #centerCrop()
209     * @see #transformFrame(com.bumptech.glide.load.resource.bitmap.BitmapTransformation...)
210     * @see #transformFrame(com.bumptech.glide.load.Transformation[])
211     *
212     */
213    @Override
214    public GifRequestBuilder<ModelType> transform(Transformation<GifDrawable>... transformations) {
215        super.transform(transformations);
216        return this;
217    }
218
219    /**
220     * {@inheritDoc}
221     */
222    @Override
223    public GifRequestBuilder<ModelType> transcoder(ResourceTranscoder<GifDrawable, GifDrawable> transcoder) {
224        super.transcoder(transcoder);
225        return this;
226    }
227
228    /**
229     * {@inheritDoc}
230     */
231    @Override
232    public GifRequestBuilder<ModelType> crossFade() {
233        super.animate(new DrawableCrossFadeFactory<GifDrawable>());
234        return this;
235    }
236
237    /**
238     * {@inheritDoc}
239     */
240    @Override
241    public GifRequestBuilder<ModelType> crossFade(int duration) {
242        super.animate(new DrawableCrossFadeFactory<GifDrawable>(duration));
243        return this;
244    }
245
246    /**
247     * {@inheritDoc}
248     */
249    @Deprecated
250    @Override
251    public GifRequestBuilder<ModelType> crossFade(Animation animation, int duration) {
252        super.animate(new DrawableCrossFadeFactory<GifDrawable>(animation, duration));
253        return this;
254    }
255
256    /**
257     * {@inheritDoc}
258     */
259    @Override
260    public GifRequestBuilder<ModelType> crossFade(int animationId, int duration) {
261        super.animate(new DrawableCrossFadeFactory<GifDrawable>(context, animationId,
262                duration));
263        return this;
264    }
265
266    /**
267     * {@inheritDoc}
268     */
269    @Override
270    public GifRequestBuilder<ModelType> dontAnimate() {
271        super.dontAnimate();
272        return this;
273    }
274
275    /**
276     * {@inheritDoc}
277     */
278    @Override
279    public GifRequestBuilder<ModelType> animate(int animationId) {
280        super.animate(animationId);
281        return this;
282    }
283
284    /**
285     * {@inheritDoc}
286     */
287    @Deprecated
288    @SuppressWarnings("deprecation")
289    @Override
290    public GifRequestBuilder<ModelType> animate(Animation animation) {
291        super.animate(animation);
292        return this;
293    }
294
295    /**
296     * {@inheritDoc}
297     */
298    @Override
299    public GifRequestBuilder<ModelType> animate(ViewPropertyAnimation.Animator animator) {
300        super.animate(animator);
301        return this;
302    }
303
304    /**
305     * {@inheritDoc}
306     */
307    @Override
308    public GifRequestBuilder<ModelType> placeholder(int resourceId) {
309        super.placeholder(resourceId);
310        return this;
311    }
312
313    /**
314     * {@inheritDoc}
315     */
316    @Override
317    public GifRequestBuilder<ModelType> placeholder(Drawable drawable) {
318        super.placeholder(drawable);
319        return this;
320    }
321
322    /**
323     * {@inheritDoc}
324     */
325    @Override
326    public GifRequestBuilder<ModelType> error(int resourceId) {
327        super.error(resourceId);
328        return this;
329    }
330
331    /**
332     * {@inheritDoc}
333     */
334    @Override
335    public GifRequestBuilder<ModelType> error(Drawable drawable) {
336        super.error(drawable);
337        return this;
338    }
339
340    /**
341     * {@inheritDoc}
342     */
343    @Override
344    public GifRequestBuilder<ModelType> listener(
345            RequestListener<? super ModelType, GifDrawable> requestListener) {
346        super.listener(requestListener);
347        return this;
348    }
349
350    /**
351     * {@inheritDoc}
352     */
353    @Override
354    public GifRequestBuilder<ModelType> skipMemoryCache(boolean skip) {
355        super.skipMemoryCache(skip);
356        return this;
357    }
358
359    /**
360     * {@inheritDoc}
361     */
362    @Override
363    public GifRequestBuilder<ModelType> diskCacheStrategy(DiskCacheStrategy strategy) {
364        super.diskCacheStrategy(strategy);
365        return this;
366    }
367
368    /**
369     * {@inheritDoc}
370     */
371    @Override
372    public GifRequestBuilder<ModelType> override(int width, int height) {
373        super.override(width, height);
374        return this;
375    }
376
377    /**
378     * {@inheritDoc}
379     */
380    @Override
381    public GifRequestBuilder<ModelType> sourceEncoder(Encoder<InputStream> sourceEncoder) {
382        super.sourceEncoder(sourceEncoder);
383        return this;
384    }
385
386    /**
387     * {@inheritDoc}
388     */
389    @Override
390    public GifRequestBuilder<ModelType> dontTransform() {
391        super.dontTransform();
392        return this;
393    }
394
395    @Override
396    public GifRequestBuilder<ModelType> signature(Key signature) {
397        super.signature(signature);
398        return this;
399    }
400
401    @Override
402    public GifRequestBuilder<ModelType> load(ModelType model) {
403        super.load(model);
404        return this;
405    }
406
407    @Override
408    public GifRequestBuilder<ModelType> clone() {
409        return (GifRequestBuilder<ModelType>) super.clone();
410    }
411
412    @Override
413    void applyFitCenter() {
414        fitCenter();
415    }
416
417    @Override
418    void applyCenterCrop() {
419        centerCrop();
420    }
421}
422