blob: fe2033ba9170e4d9ed3f9046aff11633955bb227 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.tv.dvr.ui.list;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v17.leanback.widget.RowPresenter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.TextView;
import com.android.tv.R;
import com.android.tv.TvApplication;
import com.android.tv.dvr.data.SeriesRecording;
import com.android.tv.dvr.ui.DvrUiHelper;
import com.android.tv.dvr.ui.list.SchedulesHeaderRow.SeriesRecordingHeaderRow;
/**
* A base class for RowPresenter for {@link SchedulesHeaderRow}
*/
abstract class SchedulesHeaderRowPresenter extends RowPresenter {
private Context mContext;
public SchedulesHeaderRowPresenter(Context context) {
setHeaderPresenter(null);
setSelectEffectEnabled(false);
mContext = context;
}
/**
* Returns the context.
*/
Context getContext() {
return mContext;
}
/**
* A ViewHolder for {@link SchedulesHeaderRow}.
*/
public static class SchedulesHeaderRowViewHolder extends RowPresenter.ViewHolder {
private TextView mTitle;
private TextView mDescription;
public SchedulesHeaderRowViewHolder(Context context, ViewGroup parent) {
super(LayoutInflater.from(context).inflate(R.layout.dvr_schedules_header, parent,
false));
mTitle = (TextView) view.findViewById(R.id.header_title);
mDescription = (TextView) view.findViewById(R.id.header_description);
}
}
@Override
protected void onBindRowViewHolder(RowPresenter.ViewHolder viewHolder, Object item) {
super.onBindRowViewHolder(viewHolder, item);
SchedulesHeaderRowViewHolder headerViewHolder = (SchedulesHeaderRowViewHolder) viewHolder;
SchedulesHeaderRow header = (SchedulesHeaderRow) item;
headerViewHolder.mTitle.setText(header.getTitle());
headerViewHolder.mDescription.setText(header.getDescription());
}
/**
* A presenter for {@link SchedulesHeaderRow.DateHeaderRow}.
*/
public static class DateHeaderRowPresenter extends SchedulesHeaderRowPresenter {
public DateHeaderRowPresenter(Context context) {
super(context);
}
@Override
protected ViewHolder createRowViewHolder(ViewGroup parent) {
return new DateHeaderRowViewHolder(getContext(), parent);
}
/**
* A ViewHolder for
* {@link SchedulesHeaderRow.DateHeaderRow}.
*/
public static class DateHeaderRowViewHolder extends SchedulesHeaderRowViewHolder {
public DateHeaderRowViewHolder(Context context, ViewGroup parent) {
super(context, parent);
}
}
}
/**
* A presenter for {@link SeriesRecordingHeaderRow}.
*/
public static class SeriesRecordingHeaderRowPresenter extends SchedulesHeaderRowPresenter {
private final boolean mLtr;
private final Drawable mSettingsDrawable;
private final Drawable mCancelDrawable;
private final Drawable mResumeDrawable;
private final String mSettingsInfo;
private final String mCancelAllInfo;
private final String mResumeInfo;
public SeriesRecordingHeaderRowPresenter(Context context) {
super(context);
mLtr = context.getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_LTR;
mSettingsDrawable = context.getDrawable(R.drawable.ic_settings);
mCancelDrawable = context.getDrawable(R.drawable.ic_dvr_cancel_large);
mResumeDrawable = context.getDrawable(R.drawable.ic_record_start);
mSettingsInfo = context.getString(R.string.dvr_series_schedules_settings);
mCancelAllInfo = context.getString(R.string.dvr_series_schedules_stop);
mResumeInfo = context.getString(R.string.dvr_series_schedules_start);
}
@Override
protected ViewHolder createRowViewHolder(ViewGroup parent) {
return new SeriesHeaderRowViewHolder(getContext(), parent);
}
@Override
protected void onBindRowViewHolder(RowPresenter.ViewHolder viewHolder, Object item) {
super.onBindRowViewHolder(viewHolder, item);
SeriesHeaderRowViewHolder headerViewHolder =
(SeriesHeaderRowViewHolder) viewHolder;
SeriesRecordingHeaderRow header = (SeriesRecordingHeaderRow) item;
headerViewHolder.mSeriesSettingsButton.setVisibility(
header.getSeriesRecording().isStopped() ? View.INVISIBLE : View.VISIBLE);
headerViewHolder.mSeriesSettingsButton.setText(mSettingsInfo);
setTextDrawable(headerViewHolder.mSeriesSettingsButton, mSettingsDrawable);
if (header.getSeriesRecording().isStopped()) {
headerViewHolder.mToggleStartStopButton.setText(mResumeInfo);
setTextDrawable(headerViewHolder.mToggleStartStopButton, mResumeDrawable);
} else {
headerViewHolder.mToggleStartStopButton.setText(mCancelAllInfo);
setTextDrawable(headerViewHolder.mToggleStartStopButton, mCancelDrawable);
}
headerViewHolder.mSeriesSettingsButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
DvrUiHelper.startSeriesSettingsActivity(getContext(),
header.getSeriesRecording().getId(),
header.getPrograms(), false, false, false, null);
}
});
headerViewHolder.mToggleStartStopButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (header.getSeriesRecording().isStopped()) {
// Reset priority to the highest.
SeriesRecording seriesRecording = SeriesRecording
.buildFrom(header.getSeriesRecording())
.setPriority(TvApplication.getSingletons(getContext())
.getDvrScheduleManager().suggestNewSeriesPriority())
.build();
TvApplication.getSingletons(getContext()).getDvrManager()
.updateSeriesRecording(seriesRecording);
DvrUiHelper.startSeriesSettingsActivity(getContext(),
header.getSeriesRecording().getId(),
header.getPrograms(), false, false, false, null);
} else {
DvrUiHelper.showCancelAllSeriesRecordingDialog(
(DvrSchedulesActivity) view.getContext(),
header.getSeriesRecording());
}
}
});
}
private void setTextDrawable(TextView textView, Drawable drawableStart) {
textView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStart, null, null,
null);
}
/**
* A ViewHolder for {@link SeriesRecordingHeaderRow}.
*/
public static class SeriesHeaderRowViewHolder extends SchedulesHeaderRowViewHolder {
private final TextView mSeriesSettingsButton;
private final TextView mToggleStartStopButton;
private final boolean mLtr;
private final View mSelector;
private View mLastFocusedView;
public SeriesHeaderRowViewHolder(Context context, ViewGroup parent) {
super(context, parent);
mLtr = context.getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_LTR;
view.findViewById(R.id.button_container).setVisibility(View.VISIBLE);
mSeriesSettingsButton = (TextView) view.findViewById(R.id.series_settings);
mToggleStartStopButton =
(TextView) view.findViewById(R.id.series_toggle_start_stop);
mSelector = view.findViewById(R.id.selector);
OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean focused) {
view.post(new Runnable() {
@Override
public void run() {
updateSelector(view);
}
});
}
};
mSeriesSettingsButton.setOnFocusChangeListener(onFocusChangeListener);
mToggleStartStopButton.setOnFocusChangeListener(onFocusChangeListener);
}
private void updateSelector(View focusedView) {
int animationDuration = mSelector.getContext().getResources()
.getInteger(android.R.integer.config_shortAnimTime);
DecelerateInterpolator interpolator = new DecelerateInterpolator();
if (focusedView.hasFocus()) {
ViewGroup.LayoutParams lp = mSelector.getLayoutParams();
final int targetWidth = focusedView.getWidth();
float targetTranslationX;
if (mLtr) {
targetTranslationX = focusedView.getLeft() - mSelector.getLeft();
} else {
targetTranslationX = focusedView.getRight() - mSelector.getRight();
}
// if the selector is invisible, set the width and translation X directly -
// don't animate.
if (mSelector.getAlpha() == 0) {
mSelector.setTranslationX(targetTranslationX);
lp.width = targetWidth;
mSelector.requestLayout();
}
// animate the selector in and to the proper width and translation X.
final float deltaWidth = lp.width - targetWidth;
mSelector.animate().cancel();
mSelector.animate().translationX(targetTranslationX).alpha(1f)
.setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
// Set width to the proper width for this animation step.
lp.width = targetWidth + Math.round(
deltaWidth * (1f - animation.getAnimatedFraction()));
mSelector.requestLayout();
}
}).setDuration(animationDuration).setInterpolator(interpolator).start();
mLastFocusedView = focusedView;
} else if (mLastFocusedView == focusedView) {
mSelector.animate().setUpdateListener(null).cancel();
mSelector.animate().alpha(0f).setDuration(animationDuration)
.setInterpolator(interpolator).start();
mLastFocusedView = null;
}
}
}
}
}