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
16764e09c1353fa987144a3acecbe94a091f6229a6Craig Stoutimport android.graphics.drawable.Drawable;
1770acb0c19be3831a2080e4f902324de16bfbf62eTor Norbyeimport android.support.annotation.ColorInt;
187ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.support.v17.leanback.R;
19cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stoutimport android.support.v17.leanback.widget.ControlBarPresenter.OnControlClickedListener;
20cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stoutimport android.support.v17.leanback.widget.ControlBarPresenter.OnControlSelectedListener;
217ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.content.Context;
227ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.graphics.Color;
237ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.util.TypedValue;
2460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stoutimport android.view.KeyEvent;
257ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.LayoutInflater;
267ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.View;
277ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.ViewGroup;
287ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.ViewGroup.LayoutParams;
297ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.view.ViewGroup.MarginLayoutParams;
307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutimport android.widget.ImageView;
31764e09c1353fa987144a3acecbe94a091f6229a6Craig Stoutimport android.widget.LinearLayout;
327ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout/**
347ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * A PlaybackControlsRowPresenter renders a {@link PlaybackControlsRow} to display a
357ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout * series of playback control buttons. Typically this row will be the first row in a fragment
36a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * such as the {@link android.support.v17.leanback.app.PlaybackOverlayFragment}.
37a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout *
38a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * <p>The detailed description is rendered using a {@link Presenter} passed in
39a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * {@link #PlaybackControlsRowPresenter(Presenter)}.  Typically this will be an instance of
40a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * {@link AbstractDetailsDescriptionPresenter}.  The application can access the
41a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * detailed description ViewHolder from {@link ViewHolder#mDescriptionViewHolder}.
42a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * </p>
437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout */
447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stoutpublic class PlaybackControlsRowPresenter extends RowPresenter {
457ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
46cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    static class BoundData extends PlaybackControlsPresenter.BoundData {
47cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        ViewHolder mRowViewHolder;
48cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    }
49cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * A ViewHolder for the PlaybackControlsRow.
527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
536dca725412977bb56b933bdec120e31909233cdbCraig Stout    public class ViewHolder extends RowPresenter.ViewHolder {
546b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        public final Presenter.ViewHolder mDescriptionViewHolder;
557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        final ViewGroup mCard;
565d3875ca7ca9294a00f9da0a92ad9055adeb9703Craig Stout        final ViewGroup mCardRightPanel;
577ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        final ImageView mImageView;
587ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        final ViewGroup mDescriptionDock;
597ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        final ViewGroup mControlsDock;
607ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        final ViewGroup mSecondaryControlsDock;
617ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        final View mSpacer;
62d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        final View mBottomSpacer;
63adf55abedd17eb9484d03da4b521209f15724f1fCraig Stout        View mBgView;
647ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        int mControlsDockMarginStart;
657ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        int mControlsDockMarginEnd;
666dca725412977bb56b933bdec120e31909233cdbCraig Stout        PlaybackControlsPresenter.ViewHolder mControlsVh;
677ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        Presenter.ViewHolder mSecondaryControlsVh;
68cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        BoundData mControlsBoundData = new BoundData();
69cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        BoundData mSecondaryBoundData = new BoundData();
70cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        Presenter.ViewHolder mSelectedViewHolder;
71cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        Object mSelectedItem;
724cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout        final PlaybackControlsRow.OnPlaybackStateChangedListener mListener =
736dca725412977bb56b933bdec120e31909233cdbCraig Stout                new PlaybackControlsRow.OnPlaybackStateChangedListener() {
744cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout            @Override
754cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout            public void onCurrentTimeChanged(int ms) {
764cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                mPlaybackControlsPresenter.setCurrentTime(mControlsVh, ms);
774cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout            }
784cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout            @Override
794cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout            public void onBufferedProgressChanged(int ms) {
804cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout                mPlaybackControlsPresenter.setSecondaryProgress(mControlsVh, ms);
814cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout            }
824cc255c1c9ce5f3a718970b6e0be2c3ae6abf9edCraig Stout        };
837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
846b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        ViewHolder(View rootView, Presenter descriptionPresenter) {
857ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            super(rootView);
867ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mCard = (ViewGroup) rootView.findViewById(R.id.controls_card);
875d3875ca7ca9294a00f9da0a92ad9055adeb9703Craig Stout            mCardRightPanel = (ViewGroup) rootView.findViewById(R.id.controls_card_right_panel);
887ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mImageView = (ImageView) rootView.findViewById(R.id.image);
897ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mDescriptionDock = (ViewGroup) rootView.findViewById(R.id.description_dock);
907ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mControlsDock = (ViewGroup) rootView.findViewById(R.id.controls_dock);
917ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mSecondaryControlsDock =
927ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    (ViewGroup) rootView.findViewById(R.id.secondary_controls_dock);
937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            mSpacer = rootView.findViewById(R.id.spacer);
94d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout            mBottomSpacer = rootView.findViewById(R.id.bottom_spacer);
956b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            mDescriptionViewHolder = descriptionPresenter == null ? null :
966b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                    descriptionPresenter.onCreateViewHolder(mDescriptionDock);
976b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            if (mDescriptionViewHolder != null) {
986b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionDock.addView(mDescriptionViewHolder.view);
996b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            }
1007ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
1017ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
102cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        void dispatchItemSelection() {
103cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            if (!isSelected()) {
104cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                return;
105cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
106cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            if (mSelectedViewHolder == null) {
107cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                if (getOnItemViewSelectedListener() != null) {
108cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    getOnItemViewSelectedListener().onItemSelected(null, null,
109cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                            ViewHolder.this, getRow());
110cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                }
111cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            } else {
112cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                if (getOnItemViewSelectedListener() != null) {
113cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                    getOnItemViewSelectedListener().onItemSelected(mSelectedViewHolder, mSelectedItem,
114cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                            ViewHolder.this, getRow());
115cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                }
116cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
117cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        };
118cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
119cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        Presenter getPresenter(boolean primary) {
1207ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            ObjectAdapter adapter = primary ?
1217ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    ((PlaybackControlsRow) getRow()).getPrimaryActionsAdapter() :
1227ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                            ((PlaybackControlsRow) getRow()).getSecondaryActionsAdapter();
1235dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            if (adapter == null) {
1245dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout                return null;
1255dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            }
1267ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            if (adapter.getPresenterSelector() instanceof ControlButtonPresenterSelector) {
1277ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                ControlButtonPresenterSelector selector =
1287ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                        (ControlButtonPresenterSelector) adapter.getPresenterSelector();
1297ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                return primary ? selector.getPrimaryPresenter() :
1307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                    selector.getSecondaryPresenter();
1317ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            }
132cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            return adapter.getPresenter(adapter.size() > 0 ? adapter.get(0) : null);
1337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
134adf55abedd17eb9484d03da4b521209f15724f1fCraig Stout
1356b447e693090017258eb48a51ae4119fb0f5119eCraig Stout        void setOutline(View view) {
136adf55abedd17eb9484d03da4b521209f15724f1fCraig Stout            if (mBgView != null) {
1376b447e693090017258eb48a51ae4119fb0f5119eCraig Stout                RoundedRectHelper.getInstance().setClipToRoundedOutline(mBgView, false);
138c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout                ShadowHelper.getInstance().setZ(mBgView, 0);
139adf55abedd17eb9484d03da4b521209f15724f1fCraig Stout            }
140adf55abedd17eb9484d03da4b521209f15724f1fCraig Stout            mBgView = view;
1416b447e693090017258eb48a51ae4119fb0f5119eCraig Stout            RoundedRectHelper.getInstance().setClipToRoundedOutline(view, true);
142c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout
143c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout            if (sShadowZ == 0) {
144c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout                sShadowZ = view.getResources().getDimensionPixelSize(
145c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout                        R.dimen.lb_playback_controls_z);
146c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout            }
147c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout            ShadowHelper.getInstance().setZ(view, sShadowZ);
148adf55abedd17eb9484d03da4b521209f15724f1fCraig Stout        }
1497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
1507ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1517ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private int mBackgroundColor = Color.TRANSPARENT;
1527ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private boolean mBackgroundColorSet;
1536dca725412977bb56b933bdec120e31909233cdbCraig Stout    private int mProgressColor = Color.TRANSPARENT;
1546dca725412977bb56b933bdec120e31909233cdbCraig Stout    private boolean mProgressColorSet;
1557ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private boolean mSecondaryActionsHidden;
1567ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private Presenter mDescriptionPresenter;
1577ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private PlaybackControlsPresenter mPlaybackControlsPresenter;
1587ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private ControlBarPresenter mSecondaryControlsPresenter;
159cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    private OnActionClickedListener mOnActionClickedListener;
160c62efa44831b1c60dcbdfd968735e27ac8294439Craig Stout    private static float sShadowZ;
161cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
162cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    private final OnControlSelectedListener mOnControlSelectedListener =
163cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            new OnControlSelectedListener() {
164cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        @Override
165cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        public void onControlSelected(Presenter.ViewHolder itemViewHolder, Object item,
166cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                ControlBarPresenter.BoundData data) {
167cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            ViewHolder vh = ((BoundData) data).mRowViewHolder;
168cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            if (vh.mSelectedViewHolder != itemViewHolder || vh.mSelectedItem != item) {
169cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                vh.mSelectedViewHolder = itemViewHolder;
170cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                vh.mSelectedItem = item;
171cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                vh.dispatchItemSelection();
172cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
173cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        }
174cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    };
175cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
176cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    private final OnControlClickedListener mOnControlClickedListener =
177cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            new OnControlClickedListener() {
178cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        @Override
179cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        public void onControlClicked(Presenter.ViewHolder itemViewHolder, Object item,
180cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                ControlBarPresenter.BoundData data) {
181cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            ViewHolder vh = ((BoundData) data).mRowViewHolder;
1823a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout            if (vh.getOnItemViewClickedListener() != null) {
1833a5038bd0fefa5628a31a21422bf2126c53472a9Craig Stout                vh.getOnItemViewClickedListener().onItemClicked(itemViewHolder, item,
184cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                        vh, vh.getRow());
185cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
186cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            if (mOnActionClickedListener != null && item instanceof Action) {
187cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout                mOnActionClickedListener.onActionClicked((Action) item);
188cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            }
189cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        }
190cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    };
1917ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
1927ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
1937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Constructor for a PlaybackControlsRowPresenter.
1947ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     *
1957ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * @param descriptionPresenter Presenter for displaying item details.
1967ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
1977ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public PlaybackControlsRowPresenter(Presenter descriptionPresenter) {
1987ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        setHeaderPresenter(null);
1997ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        setSelectEffectEnabled(false);
2007ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2017ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mDescriptionPresenter = descriptionPresenter;
2027ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mPlaybackControlsPresenter = new PlaybackControlsPresenter(R.layout.lb_playback_controls);
2037ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mSecondaryControlsPresenter = new ControlBarPresenter(R.layout.lb_control_bar);
204cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
205cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        mPlaybackControlsPresenter.setOnControlSelectedListener(mOnControlSelectedListener);
206cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        mSecondaryControlsPresenter.setOnControlSelectedListener(mOnControlSelectedListener);
207cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        mPlaybackControlsPresenter.setOnControlClickedListener(mOnControlClickedListener);
208cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        mSecondaryControlsPresenter.setOnControlClickedListener(mOnControlClickedListener);
2097ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2107ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2117ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2127ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Constructor for a PlaybackControlsRowPresenter.
2137ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
2147ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public PlaybackControlsRowPresenter() {
2157ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        this(null);
2167ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2177ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2187ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2197ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Sets the listener for {@link Action} click events.
2207ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
2217ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void setOnActionClickedListener(OnActionClickedListener listener) {
222cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        mOnActionClickedListener = listener;
2237ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2247ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2257ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
226a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * Returns the listener for {@link Action} click events.
2277ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
2287ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public OnActionClickedListener getOnActionClickedListener() {
229cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        return mOnActionClickedListener;
2307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2317ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2327ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2337ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Sets the background color.  If not set, a default from the theme will be used.
2347ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
23570acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    public void setBackgroundColor(@ColorInt int color) {
2367ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mBackgroundColor = color;
2377ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mBackgroundColorSet = true;
2387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2417ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Returns the background color.  If no background color was set, transparent
2427ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * is returned.
2437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
24470acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    @ColorInt
2457ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public int getBackgroundColor() {
2467ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        return mBackgroundColor;
2477ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2497ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2506dca725412977bb56b933bdec120e31909233cdbCraig Stout     * Sets the primary color for the progress bar.  If not set, a default from
2516dca725412977bb56b933bdec120e31909233cdbCraig Stout     * the theme will be used.
2526dca725412977bb56b933bdec120e31909233cdbCraig Stout     */
25370acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    public void setProgressColor(@ColorInt int color) {
2546dca725412977bb56b933bdec120e31909233cdbCraig Stout        mProgressColor = color;
2556dca725412977bb56b933bdec120e31909233cdbCraig Stout        mProgressColorSet = true;
2566dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2576dca725412977bb56b933bdec120e31909233cdbCraig Stout
2586dca725412977bb56b933bdec120e31909233cdbCraig Stout    /**
2596dca725412977bb56b933bdec120e31909233cdbCraig Stout     * Returns the primary color for the progress bar.  If no color was set, transparent
2606dca725412977bb56b933bdec120e31909233cdbCraig Stout     * is returned.
2616dca725412977bb56b933bdec120e31909233cdbCraig Stout     */
26270acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    @ColorInt
2636dca725412977bb56b933bdec120e31909233cdbCraig Stout    public int getProgressColor() {
2646dca725412977bb56b933bdec120e31909233cdbCraig Stout        return mProgressColor;
2656dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
2666dca725412977bb56b933bdec120e31909233cdbCraig Stout
2676dca725412977bb56b933bdec120e31909233cdbCraig Stout    /**
2687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Sets the secondary actions to be hidden behind a "more actions" button.
2697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * When "more actions" is selected, the primary actions are replaced with
2707ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * the secondary actions.
2717ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
2727ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public void setSecondaryActionsHidden(boolean hidden) {
2737ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mSecondaryActionsHidden = hidden;
2747ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2757ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
2767ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    /**
2777ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     * Returns true if secondary actions are hidden.
2787ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout     */
2797ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    public boolean areSecondaryActionsHidden() {
2807ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        return mSecondaryActionsHidden;
2817ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
2827ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
283d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    /**
284d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout     * Shows or hides space at the bottom of the playback controls row.
285d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout     * This allows the row to hug the bottom of the display when no
286d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout     * other rows are present.
287d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout     */
288d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    public void showBottomSpace(ViewHolder vh, boolean show) {
289d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout        vh.mBottomSpacer.setVisibility(show ? View.VISIBLE : View.GONE);
290d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout    }
291d20507e0f5ac7ad021f42ca87c294787246f0591Craig Stout
292aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    /**
293a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * Displays the primary actions.  This will override the user having selected "more actions"
294a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout     * to display the secondary actions; see {@link #setSecondaryActionsHidden(boolean)}.
295aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout     */
296aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    public void showPrimaryActions(ViewHolder vh) {
297aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout        mPlaybackControlsPresenter.showPrimaryActions(vh.mControlsVh);
298d30b6d18e1c6b988f75d76c50dbec7199386ce9bCraig Stout        mPlaybackControlsPresenter.resetFocus(vh.mControlsVh);
299aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout    }
300aa67105babce5fb14e1f39b57d4c84ce634afa62Craig Stout
3017ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    private int getDefaultBackgroundColor(Context context) {
3027ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        TypedValue outValue = new TypedValue();
30346443cb5b092f1d9156342645088eead9da026f6Dake Gu        if (context.getTheme().resolveAttribute(R.attr.defaultBrandColor, outValue, true)) {
30446443cb5b092f1d9156342645088eead9da026f6Dake Gu            return context.getResources().getColor(outValue.resourceId);
30546443cb5b092f1d9156342645088eead9da026f6Dake Gu        }
30646443cb5b092f1d9156342645088eead9da026f6Dake Gu        return context.getResources().getColor(R.color.lb_default_brand_color);
3077ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
3087ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3096dca725412977bb56b933bdec120e31909233cdbCraig Stout    private int getDefaultProgressColor(Context context) {
3106dca725412977bb56b933bdec120e31909233cdbCraig Stout        TypedValue outValue = new TypedValue();
31146443cb5b092f1d9156342645088eead9da026f6Dake Gu        if (context.getTheme()
31246443cb5b092f1d9156342645088eead9da026f6Dake Gu                .resolveAttribute(R.attr.playbackProgressPrimaryColor, outValue, true)) {
31346443cb5b092f1d9156342645088eead9da026f6Dake Gu            return context.getResources().getColor(outValue.resourceId);
31446443cb5b092f1d9156342645088eead9da026f6Dake Gu        }
31546443cb5b092f1d9156342645088eead9da026f6Dake Gu        return context.getResources().getColor(R.color.lb_playback_progress_color_no_theme);
3166dca725412977bb56b933bdec120e31909233cdbCraig Stout    }
3176dca725412977bb56b933bdec120e31909233cdbCraig Stout
3187ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
3197ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) {
3207ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        View v = LayoutInflater.from(parent.getContext())
3217ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            .inflate(R.layout.lb_playback_controls_row, parent, false);
3226b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        ViewHolder vh = new ViewHolder(v, mDescriptionPresenter);
3237ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        initRow(vh);
3247ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        return vh;
3257ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
3267ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
32760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout    private void initRow(final ViewHolder vh) {
3287ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        MarginLayoutParams lp = (MarginLayoutParams) vh.mControlsDock.getLayoutParams();
3297ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mControlsDockMarginStart = lp.getMarginStart();
3307ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mControlsDockMarginEnd = lp.getMarginEnd();
3317ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3326dca725412977bb56b933bdec120e31909233cdbCraig Stout        vh.mControlsVh = (PlaybackControlsPresenter.ViewHolder)
3336dca725412977bb56b933bdec120e31909233cdbCraig Stout                mPlaybackControlsPresenter.onCreateViewHolder(vh.mControlsDock);
3346b447e693090017258eb48a51ae4119fb0f5119eCraig Stout        mPlaybackControlsPresenter.setProgressColor(vh.mControlsVh, mProgressColorSet ?
3356b447e693090017258eb48a51ae4119fb0f5119eCraig Stout                mProgressColor : getDefaultProgressColor(vh.mControlsDock.getContext()));
3366b447e693090017258eb48a51ae4119fb0f5119eCraig Stout        mPlaybackControlsPresenter.setBackgroundColor(vh.mControlsVh, mBackgroundColorSet ?
3376b447e693090017258eb48a51ae4119fb0f5119eCraig Stout                mBackgroundColor : getDefaultBackgroundColor(vh.view.getContext()));
3387ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mControlsDock.addView(vh.mControlsVh.view);
3397ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3407ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mSecondaryControlsVh =
3417ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                mSecondaryControlsPresenter.onCreateViewHolder(vh.mSecondaryControlsDock);
3427ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        if (!mSecondaryActionsHidden) {
3437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mSecondaryControlsDock.addView(vh.mSecondaryControlsVh.view);
3447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
34560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        ((PlaybackControlsRowView) vh.view).setOnUnhandledKeyListener(
34660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                new PlaybackControlsRowView.OnUnhandledKeyListener() {
34760bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            @Override
34860bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            public boolean onUnhandledKey(KeyEvent event) {
34960bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                if (vh.getOnKeyListener() != null) {
35060bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                    if (vh.getOnKeyListener().onKey(vh.view, event.getKeyCode(), event)) {
35160bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                        return true;
35260bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                    }
35360bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                }
35460bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout                return false;
35560bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout            }
35660bb6af2e336072921f5d3c3861e86b3cc6241b3Craig Stout        });
3577ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
3587ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3597ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
3607ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) {
3617ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        super.onBindRowViewHolder(holder, item);
3627ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3637ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder vh = (ViewHolder) holder;
3647ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        PlaybackControlsRow row = (PlaybackControlsRow) vh.getRow();
3657ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3667ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mPlaybackControlsPresenter.enableSecondaryActions(mSecondaryActionsHidden);
3677ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3687ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        if (row.getItem() == null) {
3697ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mDescriptionDock.setVisibility(View.GONE);
3707ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mSpacer.setVisibility(View.GONE);
3717ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        } else {
3727ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mDescriptionDock.setVisibility(View.VISIBLE);
3736b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            if (vh.mDescriptionViewHolder != null) {
3746b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout                mDescriptionPresenter.onBindViewHolder(vh.mDescriptionViewHolder, row.getItem());
3757ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            }
3767ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mSpacer.setVisibility(View.VISIBLE);
3777ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
3787ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3797ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        if (row.getImageDrawable() == null || row.getItem() == null) {
3805dac2c723e1d50da356170a6f372dcbab1a7d83cCraig Stout            vh.mImageView.setImageDrawable(null);
381764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            updateCardLayout(vh, LayoutParams.WRAP_CONTENT);
3827ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        } else {
3837ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout            vh.mImageView.setImageDrawable(row.getImageDrawable());
384764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            updateCardLayout(vh, vh.mImageView.getLayoutParams().height);
3857ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
3867ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3877ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mControlsBoundData.adapter = row.getPrimaryActionsAdapter();
3887ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mControlsBoundData.secondaryActionsAdapter = row.getSecondaryActionsAdapter();
389cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        vh.mControlsBoundData.presenter = vh.getPresenter(true);
390cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        vh.mControlsBoundData.mRowViewHolder = vh;
3917ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mPlaybackControlsPresenter.onBindViewHolder(vh.mControlsVh, vh.mControlsBoundData);
3927ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
3937ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        vh.mSecondaryBoundData.adapter = row.getSecondaryActionsAdapter();
394cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        vh.mSecondaryBoundData.presenter = vh.getPresenter(false);
395cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        vh.mSecondaryBoundData.mRowViewHolder = vh;
3967ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mSecondaryControlsPresenter.onBindViewHolder(vh.mSecondaryControlsVh,
3977ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout                vh.mSecondaryBoundData);
3986dca725412977bb56b933bdec120e31909233cdbCraig Stout
3996dca725412977bb56b933bdec120e31909233cdbCraig Stout        mPlaybackControlsPresenter.setTotalTime(vh.mControlsVh, row.getTotalTime());
4006dca725412977bb56b933bdec120e31909233cdbCraig Stout        mPlaybackControlsPresenter.setCurrentTime(vh.mControlsVh, row.getCurrentTime());
4016dca725412977bb56b933bdec120e31909233cdbCraig Stout        mPlaybackControlsPresenter.setSecondaryProgress(vh.mControlsVh, row.getBufferedProgress());
4026dca725412977bb56b933bdec120e31909233cdbCraig Stout        row.setOnPlaybackStateChangedListener(vh.mListener);
4037ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
4047ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout
405764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout    private void updateCardLayout(ViewHolder vh, int height) {
4065d3875ca7ca9294a00f9da0a92ad9055adeb9703Craig Stout        LayoutParams lp = vh.mCardRightPanel.getLayoutParams();
407764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout        lp.height = height;
4085d3875ca7ca9294a00f9da0a92ad9055adeb9703Craig Stout        vh.mCardRightPanel.setLayoutParams(lp);
409764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout
410764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout        MarginLayoutParams mlp = (MarginLayoutParams) vh.mControlsDock.getLayoutParams();
411764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout        LinearLayout.LayoutParams llp =
412764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout                (LinearLayout.LayoutParams) vh.mDescriptionDock.getLayoutParams();
413764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout
414764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout        if (height == LayoutParams.WRAP_CONTENT) {
415764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            llp.height = LayoutParams.WRAP_CONTENT;
416764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            mlp.setMarginStart(0);
417764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            mlp.setMarginEnd(0);
4186b447e693090017258eb48a51ae4119fb0f5119eCraig Stout            vh.mCard.setBackground(null);
4196b447e693090017258eb48a51ae4119fb0f5119eCraig Stout            vh.setOutline(vh.mControlsDock);
420764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            mPlaybackControlsPresenter.enableTimeMargins(vh.mControlsVh, true);
421764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout        } else {
422764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            llp.height = 0;
423764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            llp.weight = 1;
424764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            mlp.setMarginStart(vh.mControlsDockMarginStart);
425764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            mlp.setMarginEnd(vh.mControlsDockMarginEnd);
4266b447e693090017258eb48a51ae4119fb0f5119eCraig Stout            vh.mCard.setBackgroundColor(mBackgroundColorSet ? mBackgroundColor :
4276b447e693090017258eb48a51ae4119fb0f5119eCraig Stout                    getDefaultBackgroundColor(vh.mCard.getContext()));
4286b447e693090017258eb48a51ae4119fb0f5119eCraig Stout            vh.setOutline(vh.mCard);
429764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout            mPlaybackControlsPresenter.enableTimeMargins(vh.mControlsVh, false);
430764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout        }
431764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout        vh.mDescriptionDock.setLayoutParams(llp);
432764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout        vh.mControlsDock.setLayoutParams(mlp);
433764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout    }
434764e09c1353fa987144a3acecbe94a091f6229a6Craig Stout
4357ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    @Override
4367ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    protected void onUnbindRowViewHolder(RowPresenter.ViewHolder holder) {
4377ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        ViewHolder vh = (ViewHolder) holder;
4386dca725412977bb56b933bdec120e31909233cdbCraig Stout        PlaybackControlsRow row = (PlaybackControlsRow) vh.getRow();
4396dca725412977bb56b933bdec120e31909233cdbCraig Stout
4406b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout        if (vh.mDescriptionViewHolder != null) {
4416b2e5b5117f1b8dfafbd81b995bb423ab0297564Craig Stout            mDescriptionPresenter.onUnbindViewHolder(vh.mDescriptionViewHolder);
4427ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        }
4437ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mPlaybackControlsPresenter.onUnbindViewHolder(vh.mControlsVh);
4447ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout        mSecondaryControlsPresenter.onUnbindViewHolder(vh.mSecondaryControlsVh);
4456dca725412977bb56b933bdec120e31909233cdbCraig Stout        row.setOnPlaybackStateChangedListener(null);
4466dca725412977bb56b933bdec120e31909233cdbCraig Stout
4476dca725412977bb56b933bdec120e31909233cdbCraig Stout        super.onUnbindRowViewHolder(holder);
4487ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout    }
449cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout
450a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout    @Override
451cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    protected void onRowViewSelected(RowPresenter.ViewHolder vh, boolean selected) {
452cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        super.onRowViewSelected(vh, selected);
453cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        if (selected) {
454cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout            ((ViewHolder) vh).dispatchItemSelection();
455cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout        }
456cf992de2d34abb8228dc6cb39fffe97346823a37Craig Stout    }
45726d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout
45826d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout    @Override
45926d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout    protected void onRowViewAttachedToWindow(RowPresenter.ViewHolder vh) {
46026d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout        super.onRowViewAttachedToWindow(vh);
46126d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout        if (mDescriptionPresenter != null) {
46226d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout            mDescriptionPresenter.onViewAttachedToWindow(
46326d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout                    ((ViewHolder) vh).mDescriptionViewHolder);
46426d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout        }
46526d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout    }
46626d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout
46726d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout    @Override
46826d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout    protected void onRowViewDetachedFromWindow(RowPresenter.ViewHolder vh) {
46926d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout        super.onRowViewDetachedFromWindow(vh);
47026d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout        if (mDescriptionPresenter != null) {
47126d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout            mDescriptionPresenter.onViewDetachedFromWindow(
47226d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout                    ((ViewHolder) vh).mDescriptionViewHolder);
47326d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout        }
47426d11212c4a66b075807888caacac5ee7fc10dc1Craig Stout    }
4757ab1edf2b49f3cdcb9db7a1c60d0dc1e17a9aef7Craig Stout}
476