PlaybackControlsRow.java revision 6dca725412977bb56b933bdec120e31909233cdb
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14package android.support.v17.leanback.widget;
15
16import android.support.v17.leanback.R;
17import android.content.Context;
18import android.graphics.Bitmap;
19import android.graphics.BitmapFactory;
20import android.graphics.Canvas;
21import android.graphics.Color;
22import android.graphics.Paint;
23import android.graphics.PorterDuff;
24import android.graphics.PorterDuffColorFilter;
25import android.graphics.drawable.BitmapDrawable;
26import android.graphics.drawable.Drawable;
27
28/**
29 * A row of playback controls to be displayed by a {@link PlaybackControlsRowPresenter}.
30 *
31 * This row consists of some optional item detail, a series of primary actions,
32 * and an optional series of secondary actions.
33 *
34 * Controls are specified via an {@link ObjectAdapter} containing one or more
35 * {@link Action}s.
36 *
37 * Adapters should have their {@link PresenterSelector} set to an instance of
38 * {@link ControlButtonPresenterSelector}.
39 *
40 */
41public class PlaybackControlsRow extends Row {
42
43    /**
44     * An action displaying icons for play and pause.
45     */
46    public static class PlayPauseAction extends Action {
47        Drawable mPlayIcon;
48        Drawable mPauseIcon;
49
50        /**
51         * Constructor
52         * @param context Context used for loading resources.
53         */
54        public PlayPauseAction(Context context) {
55            super(R.id.lb_control_play_pause);
56            mPlayIcon = context.getResources().getDrawable(R.drawable.lb_ic_play);
57            mPauseIcon = context.getResources().getDrawable(R.drawable.lb_ic_pause);
58            play();
59        }
60
61        /**
62         * Display the play icon.
63         */
64        public void play() {
65            setIcon(mPlayIcon);
66        }
67
68        /**
69         * Display the pause icon.
70         */
71        public void pause() {
72            setIcon(mPauseIcon);
73        }
74
75        /**
76         * Toggle between the play and pause icon.
77         */
78        public void toggle() {
79            setIcon(getIcon() == mPlayIcon ? mPauseIcon : mPlayIcon);
80        }
81
82        /**
83         * Returns true if the current icon is play.
84         */
85        public boolean isPlayIconShown() {
86            return getIcon() == mPlayIcon;
87        }
88    }
89
90    /**
91     * An action displaying an icon for fast forward.
92     */
93    public static class FastForwardAction extends Action {
94        /**
95         * Constructor
96         * @param context Context used for loading resources.
97         */
98        public FastForwardAction(Context context) {
99            super(R.id.lb_control_fast_forward);
100            setIcon(context.getResources().getDrawable(R.drawable.lb_ic_fast_forward));
101        }
102    }
103
104    /**
105     * An action displaying an icon for rewind.
106     */
107    public static class RewindAction extends Action {
108        /**
109         * Constructor
110         * @param context Context used for loading resources.
111         */
112        public RewindAction(Context context) {
113            super(R.id.lb_control_fast_rewind);
114            setIcon(context.getResources().getDrawable(R.drawable.lb_ic_fast_rewind));
115        }
116    }
117
118    /**
119     * An action displaying an icon for skip next.
120     */
121    public static class SkipNextAction extends Action {
122        /**
123         * Constructor
124         * @param context Context used for loading resources.
125         */
126        public SkipNextAction(Context context) {
127            super(R.id.lb_control_skip_next);
128            setIcon(context.getResources().getDrawable(R.drawable.lb_ic_skip_next));
129        }
130    }
131
132    /**
133     * An action displaying an icon for skip previous.
134     */
135    public static class SkipPreviousAction extends Action {
136        /**
137         * Constructor
138         * @param context Context used for loading resources.
139         */
140        public SkipPreviousAction(Context context) {
141            super(R.id.lb_control_skip_previous);
142            setIcon(context.getResources().getDrawable(R.drawable.lb_ic_skip_previous));
143        }
144    }
145
146    /**
147     * An action displaying an icon for "more actions".
148     */
149    public static class MoreActions extends Action {
150        /**
151         * Constructor
152         * @param context Context used for loading resources.
153         */
154        public MoreActions(Context context) {
155            super(R.id.lb_control_more_actions);
156            setIcon(context.getResources().getDrawable(R.drawable.lb_ic_more));
157        }
158    }
159
160    /**
161     * An action displaying an icon for thumbs up.
162     */
163    public static class ThumbsUpAction extends Action {
164        /**
165         * Constructor
166         * @param context Context used for loading resources.
167         */
168        public ThumbsUpAction(Context context) {
169            super(R.id.lb_control_thumbs_up);
170            setIcon(context.getResources().getDrawable(R.drawable.lb_ic_thumb_up));
171        }
172    }
173
174    /**
175     * An action displaying an icon for thumbs down.
176     */
177    public static class ThumbsDownAction extends Action {
178        /**
179         * Constructor
180         * @param context Context used for loading resources.
181         */
182        public ThumbsDownAction(Context context) {
183            super(R.id.lb_control_thumbs_down);
184            setIcon(context.getResources().getDrawable(R.drawable.lb_ic_thumb_down));
185        }
186    }
187
188    /**
189     * An action for displaying three repeat states: none, one, or all.
190     */
191    public static class RepeatAction extends Action {
192        public static int NONE = 0;
193        public static int ONE = 1;
194        public static int ALL = 2;
195        private Drawable[] mRepeatIcon = new Drawable[3];
196        private int mState;
197
198        /**
199         * Constructor
200         * @param context Context used for loading resources.
201         */
202        public RepeatAction(Context context) {
203            super(R.id.lb_control_repeat);
204            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
205                    R.drawable.lb_ic_loop);
206            mRepeatIcon[NONE] = new BitmapDrawable(context.getResources(),
207                    bitmap);
208            mRepeatIcon[ONE] = new BitmapDrawable(context.getResources(),
209                    createBitmap(bitmap, Color.CYAN));
210            mRepeatIcon[ALL] = new BitmapDrawable(context.getResources(),
211                    createBitmap(bitmap, Color.GREEN));
212            repeatNone();
213        }
214
215        /**
216         * Display the icon for repeat-none.
217         */
218        public void repeatNone() {
219            setIcon(mRepeatIcon[mState = NONE]);
220        }
221
222        /**
223         * Display the icon for repeat-one.
224         */
225        public void repeatOne() {
226            setIcon(mRepeatIcon[mState = ONE]);
227        }
228
229        /**
230         * Display the icon for repeat-all.
231         */
232        public void repeatAll() {
233            setIcon(mRepeatIcon[mState = ALL]);
234        }
235
236        /**
237         * Display the next icon in the series.
238         */
239        public void next() {
240            mState = mState == ALL ? NONE : mState + 1;
241            setIcon(mRepeatIcon[mState]);
242        }
243
244        /**
245         * Returns the current state (NONE, ALL, or ONE).
246         */
247        public int getState() {
248            return mState;
249        }
250    }
251
252    /**
253     * An action for displaying a shuffle icon.
254     */
255    public static class ShuffleAction extends Action {
256        /**
257         * Constructor
258         * @param context Context used for loading resources.
259         */
260        public ShuffleAction(Context context) {
261            super(R.id.lb_control_shuffle);
262            setIcon(context.getResources().getDrawable(R.drawable.lb_ic_shuffle));
263        }
264    }
265
266    private static Bitmap createBitmap(Bitmap bitmap, int color) {
267        Bitmap dst = bitmap.copy(bitmap.getConfig(), true);
268        Canvas canvas = new Canvas(dst);
269        Paint paint = new Paint();
270        paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
271        canvas.drawBitmap(bitmap, 0, 0, paint);
272        return dst;
273    }
274
275    private Object mItem;
276    private Drawable mImageDrawable;
277    private ObjectAdapter mPrimaryActionsAdapter;
278    private ObjectAdapter mSecondaryActionsAdapter;
279    private int mTotalTimeMs;
280    private int mCurrentTimeMs;
281    private int mBufferedProgressMs;
282    private OnPlaybackStateChangedListener mListener;
283
284    /**
285     * Constructor for a PlaybackControlsRow that displays some details from
286     * the given item.
287     *
288     * @param item The main item for the row.
289     */
290    public PlaybackControlsRow(Object item) {
291        mItem = item;
292    }
293
294    /**
295     * Constructor for a PlaybackControlsRow that has no item details.
296     */
297    public PlaybackControlsRow() {
298    }
299
300    /**
301     * Gets the main item for the details page.
302     */
303    public final Object getItem() {
304        return mItem;
305    }
306
307    /**
308     * Sets a {link @Drawable} image for this row.
309     *
310     * @param drawable The drawable to set.
311     */
312    public final void setImageDrawable(Drawable drawable) {
313        mImageDrawable = drawable;
314    }
315
316    /**
317     * Sets a {@link Bitmap} for this row.
318     *
319     * @param context The context to retrieve display metrics from.
320     * @param bm The bitmap to set.
321     */
322    public final void setImageBitmap(Context context, Bitmap bm) {
323        mImageDrawable = new BitmapDrawable(context.getResources(), bm);
324    }
325
326    /**
327     * Gets the image {@link Drawable} of this row.
328     *
329     * @return The overview's image drawable, or null if no drawable has been
330     *         assigned.
331     */
332    public final Drawable getImageDrawable() {
333        return mImageDrawable;
334    }
335
336    /**
337     * Sets the primary actions {@link ObjectAdapter}.
338     */
339    public final void setPrimaryActionsAdapter(ObjectAdapter adapter) {
340        mPrimaryActionsAdapter = adapter;
341    }
342
343    /**
344     * Sets the secondary actions {@link ObjectAdapter}.
345     */
346    public final void setSecondaryActionsAdapter(ObjectAdapter adapter) {
347        mSecondaryActionsAdapter = adapter;
348    }
349
350    /**
351     * Returns the primary actions {@link ObjectAdapter}.
352     */
353    public final ObjectAdapter getPrimaryActionsAdapter() {
354        return mPrimaryActionsAdapter;
355    }
356
357    /**
358     * Returns the secondary actions {@link ObjectAdapter}.
359     */
360    public final ObjectAdapter getSecondaryActionsAdapter() {
361        return mSecondaryActionsAdapter;
362    }
363
364    /**
365     * Sets the total time in milliseconds for the playback controls row.
366     */
367    public void setTotalTime(int ms) {
368        mTotalTimeMs = ms;
369    }
370
371    /**
372     * Returns the total time in milliseconds for the playback controls row.
373     */
374    public int getTotalTime() {
375        return mTotalTimeMs;
376    }
377
378    /**
379     * Sets the current time in milliseconds for the playback controls row.
380     */
381    public void setCurrentTime(int ms) {
382        if (mCurrentTimeMs != ms) {
383            mCurrentTimeMs = ms;
384            currentTimeChanged();
385        }
386    }
387
388    /**
389     * Returns the current time in milliseconds for the playback controls row.
390     */
391    public int getCurrentTime() {
392        return mCurrentTimeMs;
393    }
394
395    /**
396     * Sets the buffered progress for the playback controls row.
397     */
398    public void setBufferedProgress(int ms) {
399        if (mBufferedProgressMs != ms) {
400            mBufferedProgressMs = ms;
401            bufferedProgressChanged();
402        }
403    }
404
405    /**
406     * Returns the buffered progress for the playback controls row.
407     */
408    public int getBufferedProgress() {
409        return mBufferedProgressMs;
410    }
411
412    interface OnPlaybackStateChangedListener {
413        public void onCurrentTimeChanged(int currentTimeMs);
414        public void onBufferedProgressChanged(int bufferedProgressMs);
415    }
416
417    /**
418     * Sets a listener to be called when the playback state changes.
419     */
420    public void setOnPlaybackStateChangedListener(OnPlaybackStateChangedListener listener) {
421        mListener = listener;
422    }
423
424    /**
425     * Returns the playback state listener.
426     */
427    public OnPlaybackStateChangedListener getOnPlaybackStateChangedListener() {
428        return mListener;
429    }
430
431    private void currentTimeChanged() {
432        if (mListener != null) {
433            mListener.onCurrentTimeChanged(mCurrentTimeMs);
434        }
435    }
436
437    private void bufferedProgressChanged() {
438        if (mListener != null) {
439            mListener.onBufferedProgressChanged(mBufferedProgressMs);
440        }
441    }
442}
443