Commit 7b81f762 authored by Geoffrey Métais's avatar Geoffrey Métais

Refactor Time Pickers

- split dialogs in children classes
- handle sign for delay
- work in µSeconds
parent f35f22f7
...@@ -14,26 +14,37 @@ ...@@ -14,26 +14,37 @@
<RelativeLayout <RelativeLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/jump_dialog_title"> android:layout_below="@+id/jump_dialog_title"
android:layout_centerHorizontal="true">
<Button
android:id="@+id/jump_sign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:nextFocusRight="@+id/jump_hours"
android:text="+"
android:visibility="gone"/>
<LinearLayout <LinearLayout
android:id="@+id/jump_hours_container" android:id="@+id/jump_hours_container"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="@+id/jump_sign"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView
android:id="@+id/jump_hours_up" android:id="@+id/jump_hours_up"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@android:drawable/arrow_up_float"/> android:src="@android:drawable/arrow_up_float"/>
<EditText <TextView
android:id="@+id/jump_hours" android:id="@+id/jump_hours"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:inputType="number" android:layout_margin="5dp"
android:maxLength="2" android:maxLength="2"
android:text="00" android:text="00"
android:focusable="true" android:focusable="true"
android:nextFocusRight="@+id/jump_minutes"/> android:nextFocusRight="@+id/jump_minutes"
android:nextFocusLeft="@+id/jump_sign"/>
<ImageView <ImageView
android:id="@+id/jump_hours_down" android:id="@+id/jump_hours_down"
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -62,13 +73,13 @@ ...@@ -62,13 +73,13 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusable="true" android:focusable="true"
android:src="@android:drawable/arrow_up_float"/> android:src="@android:drawable/arrow_up_float"/>
<EditText <TextView
android:id="@+id/jump_minutes" android:id="@+id/jump_minutes"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="5dp"
android:nextFocusLeft="@+id/jump_hours" android:nextFocusLeft="@+id/jump_hours"
android:nextFocusRight="@+id/jump_seconds" android:nextFocusRight="@+id/jump_seconds"
android:inputType="number"
android:maxLength="2" android:maxLength="2"
android:text="00" android:text="00"
android:focusable="true"/> android:focusable="true"/>
...@@ -100,18 +111,19 @@ ...@@ -100,18 +111,19 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusable="true" android:focusable="true"
android:src="@android:drawable/arrow_up_float"/> android:src="@android:drawable/arrow_up_float"/>
<EditText <TextView
android:id="@+id/jump_seconds" android:id="@+id/jump_seconds"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="5dp"
android:nextFocusLeft="@+id/jump_minutes" android:nextFocusLeft="@+id/jump_minutes"
android:nextFocusRight="@+id/jump_go" android:nextFocusRight="@+id/jump_millis"
android:inputType="number"
android:maxLength="2" android:maxLength="2"
android:text="00" android:text="00"
android:textColor="@color/darkorange"
android:focusable="true"> android:focusable="true">
<requestFocus /> <requestFocus />
</EditText> </TextView>
<ImageView <ImageView
android:id="@+id/jump_seconds_down" android:id="@+id/jump_seconds_down"
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -119,13 +131,62 @@ ...@@ -119,13 +131,62 @@
android:focusable="true" android:focusable="true"
android:src="@android:drawable/arrow_down_float"/> android:src="@android:drawable/arrow_down_float"/>
</LinearLayout> </LinearLayout>
<TextView
android:id="@+id/jump_seconds_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/jump_seconds_container"
android:layout_alignTop="@+id/jump_seconds_container"
android:layout_alignBottom="@+id/jump_seconds_container"
android:gravity="center_vertical"
android:text="s"/>
<LinearLayout
android:id="@+id/jump_millis_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/jump_seconds_text"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="@+id/jump_millis_up"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:src="@android:drawable/arrow_up_float"/>
<TextView
android:id="@+id/jump_millis"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:nextFocusLeft="@+id/jump_seconds"
android:nextFocusRight="@+id/jump_go"
android:maxLength="3"
android:text="000"
android:focusable="true"/>
<ImageView
android:id="@+id/jump_millis_down"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:src="@android:drawable/arrow_down_float"/>
</LinearLayout>
<TextView
android:id="@+id/jump_millis_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/jump_millis_container"
android:layout_alignTop="@+id/jump_millis_container"
android:layout_alignBottom="@+id/jump_millis_container"
android:gravity="center_vertical"
android:text="ms"
android:visibility="gone"/>
<Button <Button
android:id="@+id/jump_go" android:id="@+id/jump_go"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:nextFocusLeft="@+id/jump_seconds" android:nextFocusLeft="@+id/jump_seconds"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_toRightOf="@+id/jump_seconds_container" android:layout_toRightOf="@+id/jump_millis_text"
android:text="@android:string/ok"/> android:text="@android:string/ok"/>
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
/*
* *************************************************************************
* AudioDelayDialog.java
* **************************************************************************
* Copyright © 2015 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* ***************************************************************************
*/
package org.videolan.vlc.gui.dialogs;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.videolan.vlc.R;
public class AudioDelayDialog extends PickTimeFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
view.findViewById(R.id.jump_millis_container).setVisibility(View.VISIBLE);
view.findViewById(R.id.jump_millis_text).setVisibility(View.VISIBLE);
view.findViewById(R.id.jump_hours_text).setVisibility(View.GONE);
view.findViewById(R.id.jump_hours_container).setVisibility(View.GONE);
mMillis.setOnFocusChangeListener(this);
mMillis.setOnEditorActionListener(this);
mMinutes.setNextFocusLeftId(R.id.jump_sign);
mActionButton.setNextFocusLeftId(R.id.jump_millis);
mSign.setNextFocusRightId(R.id.jump_minutes);
mSign.setVisibility(View.VISIBLE);
mSign.setOnClickListener(this);
mActionButton.setText(android.R.string.cancel);
long delay = mLibVLC.getAudioDelay();
initTime(delay);
return view;
}
@Override
protected void executeAction(){
long minutes = Long.parseLong(mMinutes.getText().toString());
long seconds = Long.parseLong(mSeconds.getText().toString());
long millis = Long.parseLong(mMillis.getText().toString());
long delay = minutes * MINUTES_IN_MICROS + seconds * SECONDS_IN_MICROS + millis * MILLIS_IN_MICROS;
if (mSign.getText().equals("-"))
delay = -delay;
mLibVLC.setAudioDelay(delay);
Log.d(TAG, "setting audio delay to: " + delay);
}
@Override
protected void buttonAction() {
initTime(0l);
executeAction();
}
@Override
protected int getTitle() {
return R.string.audio_delay;
}
}
/*
* *************************************************************************
* JumpToTimeDIalog.java
* **************************************************************************
* Copyright © 2015 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* ***************************************************************************
*/
package org.videolan.vlc.gui.dialogs;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.videolan.libvlc.LibVLC;
import org.videolan.vlc.R;
public class JumpToTimeDialog extends PickTimeFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
if (mLibVLC.getLength() > HOURS_IN_MICROS) {
mHours.setOnFocusChangeListener(this);
mHours.setOnEditorActionListener(this);
view.findViewById(R.id.jump_hours_up).setOnClickListener(this);
view.findViewById(R.id.jump_hours_down).setOnClickListener(this);
} else {
view.findViewById(R.id.jump_hours_text).setVisibility(View.GONE);
view.findViewById(R.id.jump_hours_container).setVisibility(View.GONE);
}
mMinutes.setNextFocusLeftId(R.id.jump_minutes);
mSeconds.setNextFocusRightId(R.id.jump_go);
return view;
}
protected void executeAction() {
long hours = mHours != null ? Long.parseLong(mHours.getText().toString()) * HOURS_IN_MICROS : 0l;
long minutes = Long.parseLong(mMinutes.getText().toString()) * MINUTES_IN_MICROS ;
long seconds = Long.parseLong(mSeconds.getText().toString()) * SECONDS_IN_MICROS;
LibVLC.getExistingInstance().setTime((hours + minutes + seconds)/1000l); //Time in ms
dismiss();
}
@Override
protected void buttonAction() {
executeAction();
}
@Override
protected int getTitle() {
return R.string.jump_to_time;
}
}
...@@ -19,40 +19,40 @@ ...@@ -19,40 +19,40 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* *************************************************************************** * ***************************************************************************
*/ */
package org.videolan.vlc.gui; package org.videolan.vlc.gui.dialogs;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.widget.EditText; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import org.videolan.libvlc.LibVLC; import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.LibVlcException; import org.videolan.libvlc.LibVlcException;
import org.videolan.vlc.R; import org.videolan.vlc.R;
public class PickTimeFragment extends DialogFragment implements DialogInterface.OnKeyListener, View.OnClickListener, View.OnFocusChangeListener, TextView.OnEditorActionListener { public abstract class PickTimeFragment extends DialogFragment implements DialogInterface.OnKeyListener, View.OnClickListener, View.OnFocusChangeListener, TextView.OnEditorActionListener {
public final static String TAG = "VLC/PickTimeFragment"; public final static String TAG = "VLC/PickTimeFragment";
public static String ACTION = "action"; public static final int ACTION_JUMP_TO_TIME = 0;
public static int ACTION_JUMP_TO_TIME = 0; public static final int ACTION_SPU_DELAY = 1;
public static int ACTION_SPU_DELAY = 1; public static final int ACTION_AUDIO_DELAY = 2;
public static int ACTION_AUDIO_DELAY = 2; protected int mTextColor;
private int mAction = -1;
private static long SECONDS_IN_MICROS = 1000000; protected static long MILLIS_IN_MICROS = 1000;
private static long MINUTES_IN_MICROS = 60*SECONDS_IN_MICROS; protected static long SECONDS_IN_MICROS = 1000 * MILLIS_IN_MICROS;
private static long HOURS_IN_MICROS = 60*MINUTES_IN_MICROS; protected static long MINUTES_IN_MICROS = 60*SECONDS_IN_MICROS;
protected static long HOURS_IN_MICROS = 60*MINUTES_IN_MICROS;
LibVLC mLibVLC = null; protected LibVLC mLibVLC = null;
EditText mHours, mMinutes, mSeconds; protected TextView mHours, mMinutes, mSeconds, mMillis;
protected Button mActionButton, mSign;
public PickTimeFragment(){} public PickTimeFragment(){}
...@@ -64,11 +64,14 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface. ...@@ -64,11 +64,14 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface.
} catch (LibVlcException e) { } catch (LibVlcException e) {
getDialog().dismiss(); getDialog().dismiss();
} }
mAction = getArguments().getInt(ACTION);
View view = inflater.inflate(R.layout.jump_to_time, container); View view = inflater.inflate(R.layout.jump_to_time, container);
((TextView)view.findViewById(R.id.jump_dialog_title)).setText(getTitle()); ((TextView)view.findViewById(R.id.jump_dialog_title)).setText(getTitle());
mMinutes = (EditText) view.findViewById(R.id.jump_minutes); mHours = (TextView) view.findViewById(R.id.jump_hours);
mSeconds = (EditText) view.findViewById(R.id.jump_seconds); mMinutes = (TextView) view.findViewById(R.id.jump_minutes);
mSeconds = (TextView) view.findViewById(R.id.jump_seconds);
mMillis = (TextView) view.findViewById(R.id.jump_millis);
mActionButton = (Button) view.findViewById(R.id.jump_go);
mSign = (Button) view.findViewById(R.id.jump_sign);
mMinutes.setOnFocusChangeListener(this); mMinutes.setOnFocusChangeListener(this);
mSeconds.setOnFocusChangeListener(this); mSeconds.setOnFocusChangeListener(this);
...@@ -76,30 +79,9 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface. ...@@ -76,30 +79,9 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface.
mMinutes.setOnEditorActionListener(this); mMinutes.setOnEditorActionListener(this);
mSeconds.setOnEditorActionListener(this); mSeconds.setOnEditorActionListener(this);
if (mAction == ACTION_JUMP_TO_TIME) { mActionButton.setOnClickListener(this);
if (mLibVLC.getLength() > HOURS_IN_MICROS) {
mHours = (EditText) view.findViewById(R.id.jump_hours); mTextColor = mMinutes.getCurrentTextColor();
mHours.setOnFocusChangeListener(this);
mHours.setOnEditorActionListener(this);
view.findViewById(R.id.jump_hours_up).setOnClickListener(this);
view.findViewById(R.id.jump_hours_down).setOnClickListener(this);
} else {
view.findViewById(R.id.jump_hours_text).setVisibility(View.GONE);
view.findViewById(R.id.jump_hours_container).setVisibility(View.GONE);
}
view.findViewById(R.id.jump_go).setOnClickListener(this);
} else {
view.findViewById(R.id.jump_hours_text).setVisibility(View.GONE);
view.findViewById(R.id.jump_hours_container).setVisibility(View.GONE);
view.findViewById(R.id.jump_go).setVisibility(View.GONE);
long delay = 0l;
if (mAction == ACTION_AUDIO_DELAY)
delay = mLibVLC.getAudioDelay();
else if (mAction == ACTION_SPU_DELAY)
delay = mLibVLC.getSpuDelay();
if (delay != 0f)
initTime(delay);
}
view.findViewById(R.id.jump_minutes_up).setOnClickListener(this); view.findViewById(R.id.jump_minutes_up).setOnClickListener(this);
view.findViewById(R.id.jump_minutes_down).setOnClickListener(this); view.findViewById(R.id.jump_minutes_down).setOnClickListener(this);
...@@ -115,7 +97,7 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface. ...@@ -115,7 +97,7 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface.
@Override @Override
public void onFocusChange(View v, boolean hasFocus) { public void onFocusChange(View v, boolean hasFocus) {
((EditText)v).setSelection(((EditText)v).getText().length()); ((TextView)v).setTextColor(hasFocus ? getResources().getColor(R.color.darkorange) : mTextColor);
} }
@Override @Override
...@@ -127,10 +109,10 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface. ...@@ -127,10 +109,10 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface.
case KeyEvent.KEYCODE_DPAD_DOWN: case KeyEvent.KEYCODE_DPAD_DOWN:
updateViews(keyCode); updateViews(keyCode);
return true; return true;
case KeyEvent.KEYCODE_DPAD_CENTER: // case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER: // case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_NUMPAD_ENTER: // case KeyEvent.KEYCODE_NUMPAD_ENTER:
dismiss(); // executeAction();
} }
return false; return false;
} }
...@@ -156,28 +138,49 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface. ...@@ -156,28 +138,49 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface.
case R.id.jump_seconds_down: case R.id.jump_seconds_down:
updateValue(-1, R.id.jump_seconds); updateValue(-1, R.id.jump_seconds);
break; break;
case R.id.jump_millis_up:
updateValue(50, R.id.jump_millis);
break;
case R.id.jump_millis_down:
updateValue(-50, R.id.jump_millis);
break;
case R.id.jump_go: case R.id.jump_go:
jumpToTime(); buttonAction();
break;
case R.id.jump_sign:
toggleSign();
executeAction();
break; break;
} }
} }
private void toggleSign() {
if (mSign.getText().equals("+"))
mSign.setText("-");
else
mSign.setText("+");
}
private void updateViews(int keyCode){ private void updateViews(int keyCode){
int delta = keyCode == KeyEvent.KEYCODE_DPAD_UP ? 1 : -1; int delta = keyCode == KeyEvent.KEYCODE_DPAD_UP ? 1 : -1;
int id = 0; int id = 0;
if (mSeconds.hasFocus()) if (mMillis.hasFocus()) {
id = mMillis.getId();
delta = keyCode == KeyEvent.KEYCODE_DPAD_UP ? 50 : -50;
} else if (mSeconds.hasFocus())
id = mSeconds.getId(); id = mSeconds.getId();
else if (mMinutes.hasFocus()) else if (mMinutes.hasFocus())
id = mMinutes.getId(); id = mMinutes.getId();
else if (mHours != null && mHours.hasFocus()) else if (mHours.hasFocus())
id = mHours.getId(); id = mHours.getId();
updateValue(delta, id); updateValue(delta, id);
} }
private void updateValue(int delta, int resId) { private void updateValue(int delta, int resId) {
int max = 59, min = -59; int max = 59;
long length = mLibVLC.getLength(); String format = "%02d";
EditText edit = null; long length = mLibVLC.getLength() * 1000; //work in µSeconds
TextView edit = null;
switch(resId){ switch(resId){
case R.id.jump_hours: case R.id.jump_hours:
edit = mHours; edit = mHours;
...@@ -186,83 +189,68 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface. ...@@ -186,83 +189,68 @@ public class PickTimeFragment extends DialogFragment implements DialogInterface.
break; break;
case R.id.jump_minutes: case R.id.jump_minutes:
edit = mMinutes; edit = mMinutes;
if (mAction == ACTION_JUMP_TO_TIME) { if (this instanceof JumpToTimeDialog) {
if (mHours != null) if (mHours != null)
length -= Long.decode(mHours.getText().toString()).longValue() * HOURS_IN_MICROS; length -= Long.decode(mHours.getText().toString()).longValue() * HOURS_IN_MICROS;
if (length < 59 * MINUTES_IN_MICROS) if (length < 59 * MINUTES_IN_MICROS)
max = (int) (length / MINUTES_IN_MICROS); max = (int) (length / MINUTES_IN_MICROS);
min = 0;
} }
break; break;
case R.id.jump_seconds: case R.id.jump_seconds:
if (mAction == ACTION_JUMP_TO_TIME) { edit = mSeconds;
if (this instanceof JumpToTimeDialog) {
if (mHours != null) if (mHours != null)
length -= Long.decode(mHours.getText().toString()).longValue() * HOURS_IN_MICROS; length -= Long.decode(mHours.getText().toString()).longValue() * HOURS_IN_MICROS;
length -= Long.decode(mMinutes.getText().toString()).longValue() * MINUTES_IN_MICROS; length -= Long.decode(mMinutes.getText().toString()).longValue() * MINUTES_IN_MICROS;
if (length < 59000)