17ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/*
27ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * Copyright (C) 2014 The Android Open Source Project
37ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout *
47ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
57ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * in compliance with the License. You may obtain a copy of the License at
67ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout *
77ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * http://www.apache.org/licenses/LICENSE-2.0
87ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout *
97ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License
107ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
117ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * or implied. See the License for the specific language governing permissions and limitations under
127ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * the License.
137ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */
147ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutpackage android.support.v17.leanback.widget;
157ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
166dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.animation.ValueAnimator;
17aa93f6777233b789feb14d95d900b158d0ac4841Craig Stoutimport android.content.Context;
18aa93f6777233b789feb14d95d900b158d0ac4841Craig Stoutimport android.content.res.Resources;
196dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.graphics.drawable.ClipDrawable;
206dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.graphics.drawable.ColorDrawable;
216dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.graphics.drawable.Drawable;
226dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.graphics.drawable.LayerDrawable;
2370acb0c19be3831a2080e4f902324de16bfbf62eTor Norbyeimport android.support.annotation.ColorInt;
247ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.R;
256dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.view.Gravity;
267ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.LayoutInflater;
277ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.View;
287ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.ViewGroup;
29e5b67be786d519377ae275ef76f3ad72187183d5Craig Stoutimport android.view.ViewGroup.MarginLayoutParams;
306dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.view.animation.LinearInterpolator;
317ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.widget.FrameLayout;
326dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.widget.ProgressBar;
336dca725412977bb56b933bdec120e31909233cdbCraig Stoutimport android.widget.TextView;
347ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
357ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/**
367ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * A presenter for a control bar that supports "more actions",
377ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * and toggling the set of controls between primary and secondary
387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * sets of {@link Actions}.
397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */
407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutclass PlaybackControlsPresenter extends ControlBarPresenter {
417ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
427ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * The data type expected by this presenter.
447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
457ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    static class BoundData extends ControlBarPresenter.BoundData {
467ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        /**
477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         * The adapter containing secondary actions.
487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout         */
497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter secondaryActionsAdapter;
507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    class ViewHolder extends ControlBarPresenter.ViewHolder {
537ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter mMoreActionsAdapter;
547ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ObjectAdapter.DataObserver mMoreActionsObserver;
556dca725412977bb56b933bdec120e31909233cdbCraig Stout        final FrameLayout mMoreActionsDock;
567ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        Presenter.ViewHolder mMoreActionsViewHolder;
577ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        boolean mMoreActionsShowing;
586dca725412977bb56b933bdec120e31909233cdbCraig Stout        final TextView mCurrentTime;
596dca725412977bb56b933bdec120e31909233cdbCraig Stout        final TextView mTotalTime;
606dca725412977bb56b933bdec120e31909233cdbCraig Stout        final ProgressBar mProgressBar;
616dca725412977bb56b933bdec120e31909233cdbCraig Stout        int mCurrentTimeInSeconds;
626dca725412977bb56b933bdec120e31909233cdbCraig Stout        StringBuilder mTotalTimeStringBuilder = new StringBuilder();
636dca725412977bb56b933bdec120e31909233cdbCraig Stout        StringBuilder mCurrentTimeStringBuilder = new StringBuilder();
64e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout        int mCurrentTimeMarginStart;
65e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout        int mTotalTimeMarginEnd;
66d30b6d18e1c6b988f75d76c50dbec7199386ce9bCraig Stout        final PersistentFocusWrapper mControlsFocusWrapper;
677ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder(View rootView) {
697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            super(rootView);
707ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mMoreActionsDock = (FrameLayout) rootView.findViewById(R.id.more_actions_dock);
716dca725412977bb56b933bdec120e31909233cdbCraig Stout            mCurrentTime = (TextView) rootView.findViewById(R.id.current_time);
726dca725412977bb56b933bdec120e31909233cdbCraig Stout            mTotalTime = (TextView) rootView.findViewById(R.id.total_time);
736dca725412977bb56b933bdec120e31909233cdbCraig Stout            mProgressBar = (ProgressBar) rootView.findViewById(R.id.playback_progress);
747ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mMoreActionsObserver = new ObjectAdapter.DataObserver() {
757ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                @Override
767ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                public void onChanged() {
777ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    if (mMoreActionsShowing) {
78aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                        showControls(mPresenter);
797ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    }
807ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                }
817ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                @Override
827ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                public void onItemRangeChanged(int positionStart, int itemCount) {
837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    if (mMoreActionsShowing) {
847ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                        for (int i = 0; i < itemCount; i++) {
85aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                            bindControlToAction(positionStart + i, mPresenter);
867ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                        }
877ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    }
887ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                }
897ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            };
90e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout            mCurrentTimeMarginStart =
91e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout                    ((MarginLayoutParams) mCurrentTime.getLayoutParams()).getMarginStart();
92e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout            mTotalTimeMarginEnd =
93e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout                    ((MarginLayoutParams) mTotalTime.getLayoutParams()).getMarginEnd();
94d30b6d18e1c6b988f75d76c50dbec7199386ce9bCraig Stout            mControlsFocusWrapper = (PersistentFocusWrapper) mControlBar.getParent();
957ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
967ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
97aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        void showMoreActions(boolean show) {
98aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            if (show) {
99aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                if (mMoreActionsViewHolder == null) {
100aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    Action action = new PlaybackControlsRow.MoreActions(mMoreActionsDock.getContext());
101aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    mMoreActionsViewHolder = mPresenter.onCreateViewHolder(mMoreActionsDock);
102aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    mPresenter.onBindViewHolder(mMoreActionsViewHolder, action);
103aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    mPresenter.setOnClickListener(mMoreActionsViewHolder, new View.OnClickListener() {
104aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                        @Override
105aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                        public void onClick(View v) {
106aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                            toggleMoreActions();
107aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                        }
108aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    });
109aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                }
110aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                if (mMoreActionsViewHolder.view.getParent() == null) {
111aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    mMoreActionsDock.addView(mMoreActionsViewHolder.view);
112aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                }
113aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            } else if (mMoreActionsViewHolder != null &&
114aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                    mMoreActionsViewHolder.view.getParent() != null) {
115aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout                mMoreActionsDock.removeView(mMoreActionsViewHolder.view);
1167ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            }
1177ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1187ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1197ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        void toggleMoreActions() {
1207ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mMoreActionsShowing = !mMoreActionsShowing;
121aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            showControls(mPresenter);
1227ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1237ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1247ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        @Override
125aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        ObjectAdapter getDisplayedAdapter() {
1267ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            return mMoreActionsShowing ? mMoreActionsAdapter : mAdapter;
1277ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1286dca725412977bb56b933bdec120e31909233cdbCraig Stout
129aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        @Override
130aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        int getChildMarginFromCenter(Context context, int numControls) {
131aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            int margin = getControlIconWidth(context);
132aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            if (numControls < 4) {
133aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout                margin += getChildMarginBiggest(context);
134aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            } else if (numControls < 6) {
135aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout                margin += getChildMarginBigger(context);
136aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            } else {
137aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout                margin += getChildMarginDefault(context);
138aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            }
139aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            return margin;
140aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        }
141aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout
1426dca725412977bb56b933bdec120e31909233cdbCraig Stout        void setTotalTime(int totalTimeMs) {
1436dca725412977bb56b933bdec120e31909233cdbCraig Stout            if (totalTimeMs <= 0) {
1446dca725412977bb56b933bdec120e31909233cdbCraig Stout                mTotalTime.setVisibility(View.GONE);
1456dca725412977bb56b933bdec120e31909233cdbCraig Stout                mProgressBar.setVisibility(View.GONE);
1466dca725412977bb56b933bdec120e31909233cdbCraig Stout            } else {
1476dca725412977bb56b933bdec120e31909233cdbCraig Stout                mTotalTime.setVisibility(View.VISIBLE);
1486dca725412977bb56b933bdec120e31909233cdbCraig Stout                mProgressBar.setVisibility(View.VISIBLE);
1496dca725412977bb56b933bdec120e31909233cdbCraig Stout                formatTime(totalTimeMs / 1000, mTotalTimeStringBuilder);
1506dca725412977bb56b933bdec120e31909233cdbCraig Stout                mTotalTime.setText(mTotalTimeStringBuilder.toString());
1516dca725412977bb56b933bdec120e31909233cdbCraig Stout                mProgressBar.setMax(totalTimeMs);
1526dca725412977bb56b933bdec120e31909233cdbCraig Stout            }
1536dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1546dca725412977bb56b933bdec120e31909233cdbCraig Stout
1556dca725412977bb56b933bdec120e31909233cdbCraig Stout        int getTotalTime() {
1566dca725412977bb56b933bdec120e31909233cdbCraig Stout            return mProgressBar.getMax();
1576dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1586dca725412977bb56b933bdec120e31909233cdbCraig Stout
1596dca725412977bb56b933bdec120e31909233cdbCraig Stout        void setCurrentTime(int currentTimeMs) {
1606dca725412977bb56b933bdec120e31909233cdbCraig Stout            int seconds = currentTimeMs / 1000;
1616dca725412977bb56b933bdec120e31909233cdbCraig Stout            if (seconds != mCurrentTimeInSeconds) {
1626dca725412977bb56b933bdec120e31909233cdbCraig Stout                mCurrentTimeInSeconds = seconds;
1636dca725412977bb56b933bdec120e31909233cdbCraig Stout                formatTime(mCurrentTimeInSeconds, mCurrentTimeStringBuilder);
1646dca725412977bb56b933bdec120e31909233cdbCraig Stout                mCurrentTime.setText(mCurrentTimeStringBuilder.toString());
1656dca725412977bb56b933bdec120e31909233cdbCraig Stout            }
1666dca725412977bb56b933bdec120e31909233cdbCraig Stout            mProgressBar.setProgress(currentTimeMs);
1676dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1686dca725412977bb56b933bdec120e31909233cdbCraig Stout
1696dca725412977bb56b933bdec120e31909233cdbCraig Stout        int getCurrentTime() {
1706dca725412977bb56b933bdec120e31909233cdbCraig Stout            return mProgressBar.getProgress();
1716dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1726dca725412977bb56b933bdec120e31909233cdbCraig Stout
1736dca725412977bb56b933bdec120e31909233cdbCraig Stout        void setSecondaryProgress(int progressMs) {
1746dca725412977bb56b933bdec120e31909233cdbCraig Stout            mProgressBar.setSecondaryProgress(progressMs);
1756dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1766dca725412977bb56b933bdec120e31909233cdbCraig Stout
1776dca725412977bb56b933bdec120e31909233cdbCraig Stout        int getSecondaryProgress() {
1786dca725412977bb56b933bdec120e31909233cdbCraig Stout            return mProgressBar.getSecondaryProgress();
1796dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1806dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
1816dca725412977bb56b933bdec120e31909233cdbCraig Stout
1826dca725412977bb56b933bdec120e31909233cdbCraig Stout    private static void formatTime(int seconds, StringBuilder sb) {
1836dca725412977bb56b933bdec120e31909233cdbCraig Stout        int minutes = seconds / 60;
1846dca725412977bb56b933bdec120e31909233cdbCraig Stout        int hours = minutes / 60;
1856dca725412977bb56b933bdec120e31909233cdbCraig Stout        seconds -= minutes * 60;
1866dca725412977bb56b933bdec120e31909233cdbCraig Stout        minutes -= hours * 60;
1876dca725412977bb56b933bdec120e31909233cdbCraig Stout
1886dca725412977bb56b933bdec120e31909233cdbCraig Stout        sb.setLength(0);
1896dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (hours > 0) {
1906dca725412977bb56b933bdec120e31909233cdbCraig Stout            sb.append(hours).append(':');
1916dca725412977bb56b933bdec120e31909233cdbCraig Stout            if (minutes < 10) {
1926dca725412977bb56b933bdec120e31909233cdbCraig Stout                sb.append('0');
1936dca725412977bb56b933bdec120e31909233cdbCraig Stout            }
1946dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1956dca725412977bb56b933bdec120e31909233cdbCraig Stout        sb.append(minutes).append(':');
1966dca725412977bb56b933bdec120e31909233cdbCraig Stout        if (seconds < 10) {
1976dca725412977bb56b933bdec120e31909233cdbCraig Stout            sb.append('0');
1986dca725412977bb56b933bdec120e31909233cdbCraig Stout        }
1996dca725412977bb56b933bdec120e31909233cdbCraig Stout        sb.append(seconds);
2007ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2017ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2027ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private boolean mMoreActionsEnabled = true;
203aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    private static int sChildMarginBigger;
204aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    private static int sChildMarginBiggest;
2057ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2067ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2077ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Constructor for a PlaybackControlsRowPresenter.
2087ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     *
2097ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * @param layoutResourceId The resource id of the layout for this presenter.
2107ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
2117ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public PlaybackControlsPresenter(int layoutResourceId) {
2127ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super(layoutResourceId);
2137ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2147ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2157ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2167ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Enables the display of secondary actions.
2177ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * A "more actions" button will be displayed.  When "more actions" is selected,
2187ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * the primary actions are replaced with the secondary actions.
2197ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
2207ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void enableSecondaryActions(boolean enable) {
2217ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mMoreActionsEnabled = enable;
2227ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2237ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2247ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2257ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Returns true if secondary actions are enabled.
2267ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
2277ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public boolean areMoreActionsEnabled() {
2287ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        return mMoreActionsEnabled;
2297ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
23170acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    public void setProgressColor(ViewHolder vh, @ColorInt int color) {
2326dca725412977bb56b933bdec120e31909233cdbCraig Stout        Drawable drawable = new ClipDrawable(new ColorDrawable(color),
2336dca725412977bb56b933bdec120e31909233cdbCraig Stout                Gravity.LEFT, ClipDrawable.HORIZONTAL);
2346dca725412977bb56b933bdec120e31909233cdbCraig Stout        ((LayerDrawable) vh.mProgressBar.getProgressDrawable())
2356dca725412977bb56b933bdec120e31909233cdbCraig Stout                .setDrawableByLayerId(android.R.id.progress, drawable);
2366dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2376dca725412977bb56b933bdec120e31909233cdbCraig Stout
2386dca725412977bb56b933bdec120e31909233cdbCraig Stout    public void setTotalTime(ViewHolder vh, int ms) {
2396dca725412977bb56b933bdec120e31909233cdbCraig Stout        vh.setTotalTime(ms);
2406dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2416dca725412977bb56b933bdec120e31909233cdbCraig Stout
2426dca725412977bb56b933bdec120e31909233cdbCraig Stout    public int getTotalTime(ViewHolder vh) {
2436dca725412977bb56b933bdec120e31909233cdbCraig Stout        return vh.getTotalTime();
2446dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2456dca725412977bb56b933bdec120e31909233cdbCraig Stout
2466dca725412977bb56b933bdec120e31909233cdbCraig Stout    public void setCurrentTime(ViewHolder vh, int ms) {
2476dca725412977bb56b933bdec120e31909233cdbCraig Stout        vh.setCurrentTime(ms);
2486dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2496dca725412977bb56b933bdec120e31909233cdbCraig Stout
2506dca725412977bb56b933bdec120e31909233cdbCraig Stout    public int getCurrentTime(ViewHolder vh) {
2516dca725412977bb56b933bdec120e31909233cdbCraig Stout        return vh.getCurrentTime();
2526dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2536dca725412977bb56b933bdec120e31909233cdbCraig Stout
2546dca725412977bb56b933bdec120e31909233cdbCraig Stout    public void setSecondaryProgress(ViewHolder vh, int progressMs) {
2556dca725412977bb56b933bdec120e31909233cdbCraig Stout        vh.setSecondaryProgress(progressMs);
2566dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2576dca725412977bb56b933bdec120e31909233cdbCraig Stout
2586dca725412977bb56b933bdec120e31909233cdbCraig Stout    public int getSecondaryProgress(ViewHolder vh) {
2596dca725412977bb56b933bdec120e31909233cdbCraig Stout        return vh.getSecondaryProgress();
2606dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2616dca725412977bb56b933bdec120e31909233cdbCraig Stout
262aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    public void showPrimaryActions(ViewHolder vh) {
263aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        if (vh.mMoreActionsShowing) {
264aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            vh.toggleMoreActions();
265aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        }
266aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    }
267aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
268d30b6d18e1c6b988f75d76c50dbec7199386ce9bCraig Stout    public void resetFocus(ViewHolder vh) {
269d30b6d18e1c6b988f75d76c50dbec7199386ce9bCraig Stout        vh.mControlsFocusWrapper.clearSelection();
270d30b6d18e1c6b988f75d76c50dbec7199386ce9bCraig Stout        vh.mControlBar.requestFocus();
271d30b6d18e1c6b988f75d76c50dbec7199386ce9bCraig Stout    }
272d30b6d18e1c6b988f75d76c50dbec7199386ce9bCraig Stout
273e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout    public void enableTimeMargins(ViewHolder vh, boolean enable) {
274e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout        MarginLayoutParams lp;
275e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout        lp = (MarginLayoutParams) vh.mCurrentTime.getLayoutParams();
276e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout        lp.setMarginStart(enable ? vh.mCurrentTimeMarginStart : 0);
277e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout        vh.mCurrentTime.setLayoutParams(lp);
278e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout
279e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout        lp = (MarginLayoutParams) vh.mTotalTime.getLayoutParams();
280e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout        lp.setMarginEnd(enable ? vh.mTotalTimeMarginEnd : 0);
281e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout        vh.mTotalTime.setLayoutParams(lp);
282e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout    }
283e5b67be786d519377ae275ef76f3ad72187183d5Craig Stout
2847ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
2857ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
2867ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        View v = LayoutInflater.from(parent.getContext())
2877ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            .inflate(getLayoutResourceId(), parent, false);
2887ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        return new ViewHolder(v);
2897ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2907ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2917ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
2927ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void onBindViewHolder(Presenter.ViewHolder holder, Object item) {
2937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder vh = (ViewHolder) holder;
2947ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        BoundData data = (BoundData) item;
295aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
296aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        // If binding to a new adapter, display primary actions.
2977ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        if (vh.mMoreActionsAdapter != data.secondaryActionsAdapter) {
2987ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mMoreActionsAdapter = data.secondaryActionsAdapter;
2997ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mMoreActionsAdapter.registerObserver(vh.mMoreActionsObserver);
300aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout            vh.mMoreActionsShowing = false;
3017ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
302aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
303aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        super.onBindViewHolder(holder, item);
304aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        vh.showMoreActions(mMoreActionsEnabled);
3057ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
3067ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3077ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
3087ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void onUnbindViewHolder(Presenter.ViewHolder holder) {
3097ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.onUnbindViewHolder(holder);
3107ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder vh = (ViewHolder) holder;
3115d3875ca7ca9294a00f9da0a92ad9055adeb9703Craig Stout        if (vh.mMoreActionsAdapter != null) {
3125d3875ca7ca9294a00f9da0a92ad9055adeb9703Craig Stout            vh.mMoreActionsAdapter.unregisterObserver(vh.mMoreActionsObserver);
3135d3875ca7ca9294a00f9da0a92ad9055adeb9703Craig Stout            vh.mMoreActionsAdapter = null;
3145d3875ca7ca9294a00f9da0a92ad9055adeb9703Craig Stout        }
3157ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
316aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout
317aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    int getChildMarginBigger(Context context) {
318aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        if (sChildMarginBigger == 0) {
319aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            sChildMarginBigger = context.getResources().getDimensionPixelSize(
320aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout                    R.dimen.lb_playback_controls_child_margin_bigger);
321aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        }
322aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        return sChildMarginBigger;
323aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    }
324aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout
325aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    int getChildMarginBiggest(Context context) {
326aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        if (sChildMarginBiggest == 0) {
327aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout            sChildMarginBiggest = context.getResources().getDimensionPixelSize(
328aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout                    R.dimen.lb_playback_controls_child_margin_biggest);
329aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        }
330aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout        return sChildMarginBiggest;
331aa93f6777233b789feb14d95d900b158d0ac4841Craig Stout    }
3327ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout}
333