Commit ea854a3a authored by Geoffrey Métais's avatar Geoffrey Métais

Databinding for video player controls

parent f9f1654d
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:vlc="http://schemas.android.com/apk/res-auto">
<data>
<import type="org.videolan.medialibrary.Tools" />
<variable
name="progress"
type="android.databinding.ObservableInt" />
<variable
name="length"
type="android.databinding.ObservableLong" />
</data>
<RelativeLayout
android:id="@+id/progress_overlay"
android:layout_width="800dp"
android:layout_height="wrap_content"
......@@ -22,7 +33,9 @@
android:progressDrawable="@drawable/po_seekbar"
android:thumb="@drawable/seekbar_thumb"
android:splitTrack="false"
android:focusable="true"/>
android:focusable="true"
android:progress="@{progress}"
vlc:mediamax="@{length}"/>
<TextView
android:id="@+id/player_overlay_time"
......@@ -30,12 +43,16 @@
android:layout_height="wrap_content"
android:layout_below="@id/player_overlay_seekbar"
android:layout_alignLeft="@+id/player_overlay_seekbar"
android:layout_alignStart="@+id/player_overlay_seekbar"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="@dimen/time_margin_sides"
android:gravity="left"
android:layout_marginStart="@dimen/time_margin_sides"
android:gravity="left|start"
android:textAppearance="@style/TextAppearance.AppCompat.SearchResult.Title"
android:textColor="@color/orange500"
android:textSize="16sp"/>
android:text="@{Tools.millisToString(progress)}"
android:textSize="16sp" />
<TextView
android:id="@+id/player_overlay_length"
......@@ -45,10 +62,15 @@
android:layout_alignParentRight="true"
android:layout_alignRight="@+id/player_overlay_seekbar"
android:layout_marginRight="@dimen/time_margin_sides"
android:gravity="right"
android:gravity="right|end"
android:text="--:--"
vlc:time="@{progress}"
vlc:length="@{length}"
android:textAppearance="@style/TextAppearance.AppCompat.SearchResult.Title"
android:textSize="16sp" />
android:textSize="16sp"
android:layout_alignParentEnd="true"
android:layout_alignEnd="@+id/player_overlay_seekbar"
android:layout_marginEnd="@dimen/time_margin_sides" />
<!-- Media control buttons -->
<LinearLayout
......@@ -155,4 +177,5 @@
android:scaleType="center"
android:focusable="true" />
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
</RelativeLayout>
</layout>
\ No newline at end of file
......@@ -36,6 +36,10 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.databinding.BindingAdapter;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableInt;
import android.databinding.ObservableLong;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.media.AudioManager;
......@@ -111,6 +115,7 @@ import org.videolan.vlc.BuildConfig;
import org.videolan.vlc.PlaybackService;
import org.videolan.vlc.R;
import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.databinding.PlayerHudBinding;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.gui.PlaybackServiceActivity;
import org.videolan.vlc.gui.audio.PlaylistAdapter;
......@@ -198,8 +203,6 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
private ImageView mPlaylistToggle;
private RecyclerView mPlaylist;
private PlaylistAdapter mPlaylistAdapter;
private ImageView mPlaylistNext;
private ImageView mPlaylistPrevious;
private static final int SURFACE_BEST_FIT = 0;
private static final int SURFACE_FIT_SCREEN = 1;
......@@ -219,9 +222,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
/** Overlay */
private ActionBar mActionBar;
private ViewGroup mActionBarView;
private View mOverlayProgress;
private View mOverlayBackground;
private View mOverlayButtons;
private static final int OVERLAY_TIMEOUT = 4000;
private static final int OVERLAY_INFINITE = -1;
private static final int FADE_OUT = 1;
......@@ -241,12 +242,9 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
private boolean mShowing;
private boolean mShowingDialog;
private DelayState mPlaybackSetting = DelayState.OFF;
private SeekBar mSeekbar;
private TextView mTitle;
private TextView mSysTime;
private TextView mBattery;
private TextView mTime;
private TextView mLength;
private TextView mInfo;
private View mOverlayInfo;
private View mVerticalBar;
......@@ -256,21 +254,14 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
private boolean mIsPlaying = false;
private ImageView mLoading;
private ImageView mTipsBackground;
private ImageView mPlayPause;
private ImageView mTracks;
private ImageView mNavMenu;
private ImageView mRewind;
private ImageView mForward;
private ImageView mAdvOptions;
private ImageView mPlaybackSettingPlus;
private ImageView mPlaybackSettingMinus;
protected boolean mEnableCloneMode;
private boolean mDisplayRemainingTime;
private static volatile boolean sDisplayRemainingTime;
private int mScreenOrientation;
private int mScreenOrientationLock;
private int mCurrentScreenOrientation;
private ImageView mLock;
private ImageView mSize;
private String KEY_REMAINING_TIME_DISPLAY = "remaining_time_display";
private String KEY_BLUETOOTH_DELAY = "key_bluetooth_delay";
private long mSpuDelay = 0L;
......@@ -447,7 +438,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
mSwitchingView = false;
mAskResume = mSettings.getBoolean("dialog_confirm_resume", false);
mDisplayRemainingTime = mSettings.getBoolean(KEY_REMAINING_TIME_DISPLAY, false);
sDisplayRemainingTime = mSettings.getBoolean(KEY_REMAINING_TIME_DISPLAY, false);
// Clear the resume time, since it is only used for resumes in external
// videos.
SharedPreferences.Editor editor = mSettings.edit();
......@@ -523,20 +514,17 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
}
private void setHudClickListeners(boolean enabled) {
if (mSeekbar != null)
mSeekbar.setOnSeekBarChangeListener(enabled ? mSeekListener : null);
if (mLock != null)
mLock.setOnClickListener(enabled ? this : null);
if (mPlayPause != null)
mPlayPause.setOnClickListener(enabled ? this : null);
if (mPlayPause != null)
mPlayPause.setOnLongClickListener(enabled ? this : null);
if (mLength != null)
mLength.setOnClickListener(enabled ? this : null);
if (mTime != null)
mTime.setOnClickListener(enabled ? this : null);
if (mSize != null)
mSize.setOnClickListener(enabled ? this : null);
if (mHudBinding != null) {
mHudBinding.playerOverlaySeekbar.setOnSeekBarChangeListener(enabled ? mSeekListener : null);
mHudBinding.lockOverlayButton.setOnClickListener(enabled ? this : null);
mHudBinding.playerOverlayPlay.setOnClickListener(enabled ? this : null);
mHudBinding.playerOverlayPlay.setOnLongClickListener(enabled ? this : null);
mHudBinding.playerOverlayLength.setOnClickListener(enabled ? this : null);
mHudBinding.playerOverlayTime.setOnClickListener(enabled ? this : null);
mHudBinding.playerOverlaySize.setOnClickListener(enabled ? this : null);
mHudBinding.playerOverlayTracks.setOnClickListener(enabled ? this : null);
mHudBinding.playerOverlayAdvFunction.setOnClickListener(enabled ? this : null);
}
if (mNavMenu != null)
mNavMenu.setOnClickListener(enabled ? this : null);
}
......@@ -566,11 +554,16 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
initUI();
setPlaybackParameters();
mForcedTime = mLastTime = -1;
setOverlayProgress();
updateTimeValues();
enableSubs();
}
}
private void updateTimeValues() {
mProgress.set((int) getTime());
mMediaLength.set(mService.getLength());
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onPause() {
......@@ -650,9 +643,9 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
}
public void resetHudLayout() {
if (mOverlayButtons == null)
if (mHudBinding == null)
return;
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)mOverlayButtons.getLayoutParams();
final RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)mHudBinding.playerOverlayButtons.getLayoutParams();
int orientation = getScreenOrientation(100);
boolean portrait = orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
orientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
......@@ -665,7 +658,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
layoutParams.addRule(RelativeLayout.RIGHT_OF, R.id.player_overlay_time);
layoutParams.addRule(RelativeLayout.LEFT_OF, R.id.player_overlay_length);
}
mOverlayButtons.setLayoutParams(layoutParams);
mHudBinding.playerOverlayButtons.setLayoutParams(layoutParams);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
......@@ -875,27 +868,22 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
private void initPlaylistUi() {
if (mService.hasPlaylist()) {
mPlaylistPrevious = (ImageView) findViewById(R.id.playlist_previous);
mPlaylistNext = (ImageView) findViewById(R.id.playlist_next);
mHasPlaylist = true;
mPlaylistAdapter = new PlaylistAdapter(this);
mPlaylistAdapter.setService(mService);
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mPlaylist.setLayoutManager(layoutManager);
mPlaylistToggle.setVisibility(View.VISIBLE);
mPlaylistPrevious.setVisibility(View.VISIBLE);
mPlaylistNext.setVisibility(View.VISIBLE);
mHudBinding.playlistPrevious.setVisibility(View.VISIBLE);
mHudBinding.playlistNext.setVisibility(View.VISIBLE);
mPlaylistToggle.setOnClickListener(VideoPlayerActivity.this);
mPlaylistPrevious.setOnClickListener(VideoPlayerActivity.this);
mPlaylistNext.setOnClickListener(VideoPlayerActivity.this);
mHudBinding.playlistPrevious.setOnClickListener(VideoPlayerActivity.this);
mHudBinding.playlistNext.setOnClickListener(VideoPlayerActivity.this);
ItemTouchHelper.Callback callback = new SwipeDragItemTouchHelperCallback(mPlaylistAdapter);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
final ItemTouchHelper.Callback callback = new SwipeDragItemTouchHelperCallback(mPlaylistAdapter);
final ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(mPlaylist);
if (mIsRtl) {
mPlaylistPrevious.setImageResource(R.drawable.ic_playlist_next_circle);
mPlaylistNext.setImageResource(R.drawable.ic_playlist_previous_circle);
}
}
}
......@@ -1221,135 +1209,135 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
if (mShowing || (mFov == 0f && keyCode == KeyEvent.KEYCODE_DPAD_DOWN))
showOverlayTimeout(OVERLAY_TIMEOUT);
switch (keyCode) {
case KeyEvent.KEYCODE_F:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
seekDelta(10000);
return true;
case KeyEvent.KEYCODE_R:
case KeyEvent.KEYCODE_MEDIA_REWIND:
seekDelta(-10000);
return true;
case KeyEvent.KEYCODE_BUTTON_R1:
seekDelta(60000);
return true;
case KeyEvent.KEYCODE_BUTTON_L1:
seekDelta(-60000);
return true;
case KeyEvent.KEYCODE_BUTTON_A:
if (mOverlayProgress != null && mOverlayProgress.getVisibility() == View.VISIBLE)
return false;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
case KeyEvent.KEYCODE_MEDIA_PLAY:
case KeyEvent.KEYCODE_MEDIA_PAUSE:
case KeyEvent.KEYCODE_SPACE:
if (mIsNavMenu)
return navigateDvdMenu(keyCode);
else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) //prevent conflict with remote control
return super.onKeyDown(keyCode, event);
else
doPlayPause();
return true;
case KeyEvent.KEYCODE_O:
case KeyEvent.KEYCODE_BUTTON_Y:
case KeyEvent.KEYCODE_MENU:
showAdvancedOptions();
return true;
case KeyEvent.KEYCODE_V:
case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
case KeyEvent.KEYCODE_BUTTON_X:
onAudioSubClick(mTracks);
return true;
case KeyEvent.KEYCODE_N:
showNavMenu();
return true;
case KeyEvent.KEYCODE_A:
resizeVideo();
return true;
case KeyEvent.KEYCODE_M:
case KeyEvent.KEYCODE_VOLUME_MUTE:
updateMute();
return true;
case KeyEvent.KEYCODE_S:
case KeyEvent.KEYCODE_MEDIA_STOP:
exitOK();
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
if (!mShowing) {
if (mFov == 0f)
seekDelta(-10000);
else
mService.updateViewpoint(-5f, 0f, 0f, 0f, false);
case KeyEvent.KEYCODE_F:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
seekDelta(10000);
return true;
}
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (!mShowing) {
if (mFov == 0f)
seekDelta(10000);
else
mService.updateViewpoint(5f, 0f, 0f, 0f, false);
case KeyEvent.KEYCODE_R:
case KeyEvent.KEYCODE_MEDIA_REWIND:
seekDelta(-10000);
return true;
}
case KeyEvent.KEYCODE_DPAD_UP:
if (!mShowing) {
if (mFov == 0f)
showAdvancedOptions();
case KeyEvent.KEYCODE_BUTTON_R1:
seekDelta(60000);
return true;
case KeyEvent.KEYCODE_BUTTON_L1:
seekDelta(-60000);
return true;
case KeyEvent.KEYCODE_BUTTON_A:
if (mHudBinding != null && mHudBinding.progressOverlay.getVisibility() == View.VISIBLE)
return false;
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
case KeyEvent.KEYCODE_MEDIA_PLAY:
case KeyEvent.KEYCODE_MEDIA_PAUSE:
case KeyEvent.KEYCODE_SPACE:
if (mIsNavMenu)
return navigateDvdMenu(keyCode);
else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) //prevent conflict with remote control
return super.onKeyDown(keyCode, event);
else
mService.updateViewpoint(0f, -5f, 0f, 0f, false);
doPlayPause();
return true;
}
case KeyEvent.KEYCODE_DPAD_DOWN:
if (!mShowing && mFov != 0f) {
mService.updateViewpoint(0f, 5f, 0f, 0f, false);
case KeyEvent.KEYCODE_O:
case KeyEvent.KEYCODE_BUTTON_Y:
case KeyEvent.KEYCODE_MENU:
showAdvancedOptions();
return true;
}
case KeyEvent.KEYCODE_DPAD_CENTER:
if (!mShowing) {
doPlayPause();
case KeyEvent.KEYCODE_V:
case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
case KeyEvent.KEYCODE_BUTTON_X:
onAudioSubClick(mHudBinding != null ? mHudBinding.playerOverlayTracks : null);
return true;
}
case KeyEvent.KEYCODE_ENTER:
if (mIsNavMenu)
return navigateDvdMenu(keyCode);
else
return super.onKeyDown(keyCode, event);
case KeyEvent.KEYCODE_J:
delayAudio(-50000l);
return true;
case KeyEvent.KEYCODE_K:
delayAudio(50000l);
return true;
case KeyEvent.KEYCODE_G:
delaySubs(-50000l);
return true;
case KeyEvent.KEYCODE_H:
delaySubs(50000l);
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
int vol;
if (mService.getVolume() > 100)
vol = Math.round(((float)mService.getVolume())*mAudioMax/100 - 1);
else
vol = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) - 1;
vol = Math.min(Math.max(vol, 0), mAudioMax * (audioBoostEnabled ? 2 : 1));
mOriginalVol = vol;
setAudioVolume(vol);
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
if (mMute) {
case KeyEvent.KEYCODE_N:
showNavMenu();
return true;
case KeyEvent.KEYCODE_A:
resizeVideo();
return true;
case KeyEvent.KEYCODE_M:
case KeyEvent.KEYCODE_VOLUME_MUTE:
updateMute();
} else {
int volume;
if (mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) < mAudioMax)
volume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) + 1;
return true;
case KeyEvent.KEYCODE_S:
case KeyEvent.KEYCODE_MEDIA_STOP:
exitOK();
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
if (!mShowing) {
if (mFov == 0f)
seekDelta(-10000);
else
mService.updateViewpoint(-5f, 0f, 0f, 0f, false);
return true;
}
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (!mShowing) {
if (mFov == 0f)
seekDelta(10000);
else
mService.updateViewpoint(5f, 0f, 0f, 0f, false);
return true;
}
case KeyEvent.KEYCODE_DPAD_UP:
if (!mShowing) {
if (mFov == 0f)
showAdvancedOptions();
else
mService.updateViewpoint(0f, -5f, 0f, 0f, false);
return true;
}
case KeyEvent.KEYCODE_DPAD_DOWN:
if (!mShowing && mFov != 0f) {
mService.updateViewpoint(0f, 5f, 0f, 0f, false);
return true;
}
case KeyEvent.KEYCODE_DPAD_CENTER:
if (!mShowing) {
doPlayPause();
return true;
}
case KeyEvent.KEYCODE_ENTER:
if (mIsNavMenu)
return navigateDvdMenu(keyCode);
else
volume = Math.round(((float)mService.getVolume())*mAudioMax/100 + 1);
volume = Math.min(Math.max(volume, 0), mAudioMax * (audioBoostEnabled ? 2 : 1));
setAudioVolume(volume);
}
return true;
case KeyEvent.KEYCODE_CAPTIONS:
selectSubtitles();
return true;
return super.onKeyDown(keyCode, event);
case KeyEvent.KEYCODE_J:
delayAudio(-50000l);
return true;
case KeyEvent.KEYCODE_K:
delayAudio(50000l);
return true;
case KeyEvent.KEYCODE_G:
delaySubs(-50000l);
return true;
case KeyEvent.KEYCODE_H:
delaySubs(50000l);
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
int vol;
if (mService.getVolume() > 100)
vol = Math.round(((float)mService.getVolume())*mAudioMax/100 - 1);
else
vol = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) - 1;
vol = Math.min(Math.max(vol, 0), mAudioMax * (audioBoostEnabled ? 2 : 1));
mOriginalVol = vol;
setAudioVolume(vol);
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
if (mMute) {
updateMute();
} else {
int volume;
if (mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) < mAudioMax)
volume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) + 1;
else
volume = Math.round(((float)mService.getVolume())*mAudioMax/100 + 1);
volume = Math.min(Math.max(volume, 0), mAudioMax * (audioBoostEnabled ? 2 : 1));
setAudioVolume(volume);
}
return true;
case KeyEvent.KEYCODE_CAPTIONS:
selectSubtitles();
return true;
}
return super.onKeyDown(keyCode, event);
}
......@@ -1454,8 +1442,8 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
}
UiTools.setViewVisibility(mOverlayInfo, View.INVISIBLE);
mInfo.setText("");
if (mPlayPause != null)
mPlayPause.requestFocus();
if (mHudBinding != null)
mHudBinding.playerOverlayPlay.requestFocus();
}
public void delayAudio(long delta) {
......@@ -1494,15 +1482,15 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
setRequestedOrientation(getScreenOrientation(100));
}
showInfo(R.string.locked, 1000);
mLock.setImageResource(R.drawable.ic_locked_circle);
mTime.setEnabled(false);
mSeekbar.setEnabled(false);
mLength.setEnabled(false);
mSize.setEnabled(false);
if (mPlaylistNext != null)
mPlaylistNext.setEnabled(false);
if (mPlaylistPrevious != null)
mPlaylistPrevious.setEnabled(false);
if (mHudBinding != null) {
mHudBinding.lockOverlayButton.setImageResource(R.drawable.ic_locked_circle);
mHudBinding.playerOverlayTime.setEnabled(false);
mHudBinding.playerOverlaySeekbar.setEnabled(false);
mHudBinding.playerOverlayLength.setEnabled(false);
mHudBinding.playerOverlaySize.setEnabled(false);
mHudBinding.playlistNext.setEnabled(false);
mHudBinding.playlistPrevious.setEnabled(false);
}
hideOverlay(true);
mLockBackButton = true;
mIsLocked = true;
......@@ -1515,15 +1503,15 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
if(mScreenOrientation != 100)
setRequestedOrientation(mScreenOrientationLock);
showInfo(R.string.unlocked, 1000);
mLock.setImageResource(R.drawable.ic_lock_circle);
mTime.setEnabled(true);
mSeekbar.setEnabled(mService == null || mService.isSeekable());
mLength.setEnabled(true);
mSize.setEnabled(true);
if (mPlaylistNext != null)
mPlaylistNext.setEnabled(true);
if (mPlaylistPrevious != null)
mPlaylistPrevious.setEnabled(true);
if (mHudBinding != null) {
mHudBinding.lockOverlayButton.setImageResource(R.drawable.ic_lock_circle);
mHudBinding.playerOverlayTime.setEnabled(true);
mHudBinding.playerOverlaySeekbar.setEnabled(mService == null || mService.isSeekable());