Add timer support.
Show the timer as a dialog, plus update all following information as it should be. Change-Id: Idae00b009ce098cfd482ec79629fc8f674502c9a
This commit is contained in:
parent
766b6f5b14
commit
f1b77bf371
17 changed files with 486 additions and 143 deletions
BIN
android/sdremote/res/drawable-hdpi/ic_action_timer.png
Executable file
BIN
android/sdremote/res/drawable-hdpi/ic_action_timer.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
android/sdremote/res/drawable-mdpi/ic_action_timer.png
Executable file
BIN
android/sdremote/res/drawable-mdpi/ic_action_timer.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
android/sdremote/res/drawable-xhdpi/ic_action_timer.png
Executable file
BIN
android/sdremote/res/drawable-xhdpi/ic_action_timer.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
27
android/sdremote/res/menu/menu_action_bar_slide_show.xml
Normal file
27
android/sdremote/res/menu/menu_action_bar_slide_show.xml
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_slides_pager"
|
||||
android:title="@string/menu_slides_pager"
|
||||
android:icon="@drawable/ic_action_pager"
|
||||
android:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_slides_grid"
|
||||
android:title="@string/menu_slides_grid"
|
||||
android:icon="@drawable/ic_action_grid"
|
||||
android:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_timer"
|
||||
android:title="@string/menu_timer"
|
||||
android:icon="@drawable/ic_action_timer"
|
||||
android:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_stop_slide_show"
|
||||
android:title="@string/menu_stop_slide_show"
|
||||
android:showAsAction="never"/>
|
||||
|
||||
</menu>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_slides_pager"
|
||||
android:title="@string/menu_slides_pager"
|
||||
android:icon="@drawable/ic_action_pager"
|
||||
android:showAsAction="always"/>
|
||||
|
||||
</menu>
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_slides_grid"
|
||||
android:title="@string/menu_slides_grid"
|
||||
android:icon="@drawable/ic_action_grid"
|
||||
android:showAsAction="always"/>
|
||||
|
||||
</menu>
|
|
@ -10,6 +10,7 @@
|
|||
<string name="title_connection">Connection</string>
|
||||
<string name="title_creation">Creation</string>
|
||||
<string name="title_slide_show">Slide Show</string>
|
||||
<string name="title_timer">Timer</string>
|
||||
|
||||
<string name="menu_licenses">Open source licenses</string>
|
||||
<string name="menu_reconnect">Reconnect</string>
|
||||
|
@ -17,9 +18,13 @@
|
|||
<string name="menu_remove_computer">Remove</string>
|
||||
<string name="menu_slides_grid">Slides grid</string>
|
||||
<string name="menu_slides_pager">Slides pager</string>
|
||||
<string name="menu_timer">Timer</string>
|
||||
<string name="menu_stop_slide_show">Stop slide show</string>
|
||||
|
||||
<string name="button_cancel">Cancel</string>
|
||||
<string name="button_save">Save</string>
|
||||
<string name="button_start">Start</string>
|
||||
<string name="button_reset">Reset</string>
|
||||
|
||||
<string name="message_impress_pin_validation">Go to “Slide Show → Impress Remote” in LibreOffice Impress and enter the code.</string>
|
||||
<string name="message_connection_failed_title">Connection failed</string>
|
||||
|
@ -28,6 +33,7 @@
|
|||
<string name="message_impress_pairing_check">If you have Bluetooth pairing issues check instructions related to your desktop OS.</string>
|
||||
<string name="message_ip_address_validation">You should type a valid IP address.</string>
|
||||
<string name="message_name_notice">Name is optional — IP address would be used instead if you wish.</string>
|
||||
<string name="message_time_is_up">Time is up</string>
|
||||
|
||||
<string name="hint_ip_address">IP address</string>
|
||||
<string name="hint_name">Name</string>
|
||||
|
@ -35,5 +41,9 @@
|
|||
<string name="header_notes">Notes</string>
|
||||
|
||||
<string name="mask_slide_show_progress">Slide %1$d from %2$d</string>
|
||||
<plurals name="mask_timer_progress">
|
||||
<item quantity="one">One minute left</item>
|
||||
<item quantity="other">%d minutes left</item>
|
||||
</plurals>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<style name="Theme.ImpressRemote" parent="Theme.Sherlock.Light.DarkActionBar">
|
||||
<style name="Theme.ImpressRemote" parent="Theme.Sherlock.Light.DarkActionBar.ForceOverflow">
|
||||
<item name="android:actionBarStyle">@style/Theme.ImpressRemote.ActionBar</item>
|
||||
<item name="actionBarStyle">@style/Theme.ImpressRemote.ActionBar</item>
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ public class ComputersActivity extends SherlockFragmentActivity implements Actio
|
|||
private void setUpComputersList() {
|
||||
Fragment aComputersFragment = ComputersFragment.newInstance(ComputersFragment.Type.WIFI);
|
||||
|
||||
FragmentOperator.setUpFragment(this, aComputersFragment);
|
||||
FragmentOperator.addFragment(this, aComputersFragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,8 +16,8 @@ import android.content.IntentFilter;
|
|||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
|
@ -26,8 +26,12 @@ import com.actionbarsherlock.view.MenuItem;
|
|||
import org.libreoffice.impressremote.R;
|
||||
import org.libreoffice.impressremote.communication.CommunicationService;
|
||||
import org.libreoffice.impressremote.communication.SlideShow;
|
||||
import org.libreoffice.impressremote.communication.Timer;
|
||||
import org.libreoffice.impressremote.fragment.SlidesGridFragment;
|
||||
import org.libreoffice.impressremote.fragment.SlidesPagerFragment;
|
||||
import org.libreoffice.impressremote.fragment.TimerEditingDialog;
|
||||
import org.libreoffice.impressremote.fragment.TimerSettingDialog;
|
||||
import org.libreoffice.impressremote.util.FragmentOperator;
|
||||
import org.libreoffice.impressremote.util.Intents;
|
||||
|
||||
public class SlideShowActivity extends SherlockFragmentActivity implements ServiceConnection {
|
||||
|
@ -57,7 +61,7 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
}
|
||||
|
||||
private void setUpFragment() {
|
||||
setUpFragment(buildFragment());
|
||||
FragmentOperator.replaceFragmentAnimated(this, buildFragment());
|
||||
}
|
||||
|
||||
private Fragment buildFragment() {
|
||||
|
@ -73,15 +77,6 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
}
|
||||
}
|
||||
|
||||
private void setUpFragment(Fragment aFragment) {
|
||||
FragmentTransaction aTransaction = getSupportFragmentManager().beginTransaction();
|
||||
aTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
|
||||
aTransaction.replace(android.R.id.content, aFragment);
|
||||
|
||||
aTransaction.commit();
|
||||
}
|
||||
|
||||
private void bindService() {
|
||||
Intent aIntent = Intents.buildCommunicationServiceIntent(this);
|
||||
bindService(aIntent, this, Context.BIND_AUTO_CREATE);
|
||||
|
@ -124,6 +119,30 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
public void onReceive(Context aContext, Intent aIntent) {
|
||||
if (Intents.Actions.SLIDE_CHANGED.equals(aIntent.getAction())) {
|
||||
mSlideShowActivity.setUpSlideShowInformation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Intents.Actions.TIMER_UPDATED.equals(aIntent.getAction())) {
|
||||
mSlideShowActivity.setUpSlideShowInformation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Intents.Actions.TIMER_STARTED.equals(aIntent.getAction())) {
|
||||
int aMinutesLength = aIntent.getIntExtra(Intents.Extras.MINUTES, 0);
|
||||
mSlideShowActivity.startTimer(aMinutesLength);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Intents.Actions.TIMER_RESUMED.equals(aIntent.getAction())) {
|
||||
mSlideShowActivity.resumeTimer();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Intents.Actions.TIMER_CHANGED.equals(aIntent.getAction())) {
|
||||
int aMinutesLength = aIntent.getIntExtra(Intents.Extras.MINUTES, 0);
|
||||
mSlideShowActivity.changeTimer(aMinutesLength);
|
||||
mSlideShowActivity.resumeTimer();
|
||||
mSlideShowActivity.setUpSlideShowInformation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +150,10 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
private IntentFilter buildIntentsReceiverFilter() {
|
||||
IntentFilter aIntentFilter = new IntentFilter();
|
||||
aIntentFilter.addAction(Intents.Actions.SLIDE_CHANGED);
|
||||
aIntentFilter.addAction(Intents.Actions.TIMER_UPDATED);
|
||||
aIntentFilter.addAction(Intents.Actions.TIMER_STARTED);
|
||||
aIntentFilter.addAction(Intents.Actions.TIMER_RESUMED);
|
||||
aIntentFilter.addAction(Intents.Actions.TIMER_CHANGED);
|
||||
|
||||
return aIntentFilter;
|
||||
}
|
||||
|
@ -148,6 +171,10 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
getSupportActionBar().setSubtitle(buildSlideShowTimerProgress());
|
||||
}
|
||||
|
||||
private boolean isServiceBound() {
|
||||
return mCommunicationService != null;
|
||||
}
|
||||
|
||||
private String buildSlideShowProgress() {
|
||||
SlideShow aSlideShow = mCommunicationService.getSlideShow();
|
||||
|
||||
|
@ -158,7 +185,38 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
}
|
||||
|
||||
private String buildSlideShowTimerProgress() {
|
||||
return null;
|
||||
Timer aTimer = mCommunicationService.getSlideShow().getTimer();
|
||||
|
||||
if (!aTimer.isSet()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (aTimer.isTimeUp()) {
|
||||
return getString(R.string.message_time_is_up);
|
||||
}
|
||||
|
||||
int aMinutesLeft = aTimer.getMinutesLeft();
|
||||
|
||||
return getResources().getQuantityString(R.plurals.mask_timer_progress, aMinutesLeft, aMinutesLeft);
|
||||
}
|
||||
|
||||
private void startTimer(int aMinutesLength) {
|
||||
Timer aTimer = mCommunicationService.getSlideShow().getTimer();
|
||||
|
||||
aTimer.setMinutesLength(aMinutesLength);
|
||||
aTimer.start();
|
||||
|
||||
setUpSlideShowInformation();
|
||||
}
|
||||
|
||||
private void resumeTimer() {
|
||||
mCommunicationService.getSlideShow().getTimer().resume();
|
||||
}
|
||||
|
||||
private void changeTimer(int aMinutesLength) {
|
||||
Timer aTimer = mCommunicationService.getSlideShow().getTimer();
|
||||
|
||||
aTimer.setMinutesLength(aMinutesLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -170,27 +228,42 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu aMenu) {
|
||||
getSupportMenuInflater().inflate(getActionBarMenuResourceId(), aMenu);
|
||||
getSupportMenuInflater().inflate(R.menu.menu_action_bar_slide_show, aMenu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getActionBarMenuResourceId() {
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu aMenu) {
|
||||
MenuItem aSlidesPagerMenuItem = aMenu.findItem(R.id.menu_slides_pager);
|
||||
MenuItem aSlidesGridMenuItem = aMenu.findItem(R.id.menu_slides_grid);
|
||||
|
||||
switch (mMode) {
|
||||
case PAGER:
|
||||
return R.menu.menu_action_bar_slide_show_pager;
|
||||
aSlidesPagerMenuItem.setVisible(false);
|
||||
aSlidesGridMenuItem.setVisible(true);
|
||||
break;
|
||||
|
||||
case GRID:
|
||||
return R.menu.menu_action_bar_slide_show_grid;
|
||||
aSlidesPagerMenuItem.setVisible(true);
|
||||
aSlidesGridMenuItem.setVisible(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
return R.menu.menu_action_bar_slide_show_pager;
|
||||
break;
|
||||
}
|
||||
|
||||
return super.onPrepareOptionsMenu(aMenu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem aMenuItem) {
|
||||
switch (aMenuItem.getItemId()) {
|
||||
case android.R.id.home:
|
||||
navigateUp();
|
||||
|
||||
return true;
|
||||
|
||||
case R.id.menu_slides_grid:
|
||||
mMode = Mode.GRID;
|
||||
|
||||
|
@ -207,8 +280,13 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
|
||||
return true;
|
||||
|
||||
case android.R.id.home:
|
||||
navigateUp();
|
||||
case R.id.menu_timer:
|
||||
callTimer();
|
||||
|
||||
return true;
|
||||
|
||||
case R.id.menu_stop_slide_show:
|
||||
stopSlideShow();
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -217,11 +295,38 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
}
|
||||
}
|
||||
|
||||
private void navigateUp() {
|
||||
finish();
|
||||
}
|
||||
|
||||
private void refreshActionBarMenu() {
|
||||
supportInvalidateOptionsMenu();
|
||||
}
|
||||
|
||||
private void navigateUp() {
|
||||
private void callTimer() {
|
||||
Timer aTimer = mCommunicationService.getSlideShow().getTimer();
|
||||
|
||||
if (aTimer.isSet()) {
|
||||
int aTimerLength = aTimer.getMinutesLeft();
|
||||
|
||||
DialogFragment aFragment = TimerEditingDialog.newInstance(aTimerLength);
|
||||
aFragment.show(getSupportFragmentManager(), TimerEditingDialog.TAG);
|
||||
|
||||
pauseTimer();
|
||||
}
|
||||
else {
|
||||
DialogFragment aFragment = TimerSettingDialog.newInstance();
|
||||
aFragment.show(getSupportFragmentManager(), TimerSettingDialog.TAG);
|
||||
}
|
||||
}
|
||||
|
||||
private void pauseTimer() {
|
||||
mCommunicationService.getSlideShow().getTimer().pause();
|
||||
}
|
||||
|
||||
private void stopSlideShow() {
|
||||
mCommunicationService.getTransmitter().stopPresentation();
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
|
@ -245,11 +350,17 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
stopTimer();
|
||||
|
||||
disconnectComputer();
|
||||
|
||||
unbindService();
|
||||
}
|
||||
|
||||
private void stopTimer() {
|
||||
mCommunicationService.getSlideShow().getTimer().stop();
|
||||
}
|
||||
|
||||
private void disconnectComputer() {
|
||||
if (!isServiceBound()) {
|
||||
return;
|
||||
|
@ -258,10 +369,6 @@ public class SlideShowActivity extends SherlockFragmentActivity implements Servi
|
|||
mCommunicationService.disconnect();
|
||||
}
|
||||
|
||||
private boolean isServiceBound() {
|
||||
return mCommunicationService != null;
|
||||
}
|
||||
|
||||
private void unbindService() {
|
||||
if (!isServiceBound()) {
|
||||
return;
|
||||
|
|
|
@ -19,7 +19,7 @@ import android.support.v4.content.LocalBroadcastManager;
|
|||
|
||||
import org.libreoffice.impressremote.util.Intents;
|
||||
|
||||
public class CommunicationService extends Service implements Runnable, MessagesListener {
|
||||
public class CommunicationService extends Service implements Runnable, MessagesListener, Timer.TimerListener {
|
||||
public static enum State {
|
||||
DISCONNECTED, SEARCHING, CONNECTING, CONNECTED
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class CommunicationService extends Service implements Runnable, MessagesL
|
|||
|
||||
mServersManager = new ServersManager(this);
|
||||
|
||||
mSlideShow = new SlideShow();
|
||||
mSlideShow = new SlideShow(new Timer(this));
|
||||
|
||||
mThread = new Thread(this);
|
||||
mThread.start();
|
||||
|
@ -278,6 +278,12 @@ public class CommunicationService extends Service implements Runnable, MessagesL
|
|||
LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerUpdated() {
|
||||
Intent aIntent = Intents.buildTimerUpdatedIntent();
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
stopSearch();
|
||||
|
|
|
@ -20,14 +20,14 @@ public class SlideShow {
|
|||
|
||||
private final Timer mTimer;
|
||||
|
||||
public SlideShow() {
|
||||
public SlideShow(Timer aTimer) {
|
||||
this.mSlidesCount = 0;
|
||||
this.mCurrentSlideIndex = 0;
|
||||
|
||||
this.mSlidePreviewsBytes = new SparseArray<byte[]>();
|
||||
this.mSlideNotes = new SparseArray<String>();
|
||||
|
||||
this.mTimer = new Timer();
|
||||
this.mTimer = aTimer;
|
||||
}
|
||||
|
||||
public void setSlidesCount(int aSlidesCount) {
|
||||
|
|
|
@ -8,116 +8,82 @@
|
|||
*/
|
||||
package org.libreoffice.impressremote.communication;
|
||||
|
||||
public class Timer {
|
||||
/**
|
||||
* This stores the starting time of the timer if running.
|
||||
* <p/>
|
||||
* If paused this stores how long the timer was previously running.
|
||||
*/
|
||||
private long mTime;
|
||||
private long mCountdownTime;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
private boolean mIsRunning;
|
||||
private boolean mIsCountdown;
|
||||
import android.os.Handler;
|
||||
|
||||
public Timer() {
|
||||
mTime = 0;
|
||||
mCountdownTime = 0;
|
||||
|
||||
mIsRunning = false;
|
||||
mIsCountdown = false;
|
||||
public class Timer implements Runnable {
|
||||
public interface TimerListener {
|
||||
public void onTimerUpdated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this timer should be a normal or a countdown timer.
|
||||
*
|
||||
* @param aIsCountdown Whether this should be a countdown timer.
|
||||
*/
|
||||
public void setCountdown(boolean aIsCountdown) {
|
||||
mIsCountdown = aIsCountdown;
|
||||
private static final long UPDATE_PERIOD_IN_MINUTES = 1;
|
||||
|
||||
if (mIsRunning) {
|
||||
reset();
|
||||
}
|
||||
private final Handler mTimerHandler;
|
||||
private final TimerListener mTimerListener;
|
||||
|
||||
private int mTotalMinutes;
|
||||
private int mPassedMinutes;
|
||||
|
||||
public Timer(TimerListener aTimerListener) {
|
||||
mTimerHandler = new Handler();
|
||||
mTimerListener = aTimerListener;
|
||||
|
||||
mTotalMinutes = 0;
|
||||
mPassedMinutes = 0;
|
||||
}
|
||||
|
||||
public boolean isCountdown() {
|
||||
return mIsCountdown;
|
||||
public void setMinutesLength(int aLengthInMinutes) {
|
||||
mTotalMinutes = aLengthInMinutes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the countdown time. Can be set, and isn't lost, whatever mode
|
||||
* the timer is running in.
|
||||
*
|
||||
* @param aCountdownTime The countdown time.
|
||||
*/
|
||||
public void setCountdownTime(long aCountdownTime) {
|
||||
mCountdownTime = aCountdownTime;
|
||||
public int getMinutesLength() {
|
||||
return mTotalMinutes;
|
||||
}
|
||||
|
||||
public long getCountdownTime() {
|
||||
return mCountdownTime;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return mIsRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the timer, and stop it it was running.
|
||||
*/
|
||||
public void reset() {
|
||||
mIsRunning = false;
|
||||
mTime = 0;
|
||||
public boolean isSet() {
|
||||
return mTotalMinutes != 0;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (mIsRunning) {
|
||||
if (!isSet()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTime = System.currentTimeMillis() - mTime;
|
||||
mIsRunning = true;
|
||||
mTimerHandler.postDelayed(this, TimeUnit.MINUTES.toMillis(UPDATE_PERIOD_IN_MINUTES));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
updatePassedMinutes();
|
||||
|
||||
mTimerListener.onTimerUpdated();
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
private void updatePassedMinutes() {
|
||||
mPassedMinutes++;
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
stop();
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
start();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (!mIsRunning)
|
||||
return;
|
||||
|
||||
mTime = System.currentTimeMillis() - mTime;
|
||||
mIsRunning = false;
|
||||
mTimerHandler.removeCallbacks(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get either how long this timer has been running, or how long the
|
||||
* timer still has left to run.
|
||||
*
|
||||
* @return running time in millis.
|
||||
*/
|
||||
public long getTimeMillis() {
|
||||
if (mIsCountdown) {
|
||||
return calculateCountdownRunningTime();
|
||||
}
|
||||
|
||||
return calculateRunningTime();
|
||||
public boolean isTimeUp() {
|
||||
return getMinutesLeft() <= 0;
|
||||
}
|
||||
|
||||
private long calculateCountdownRunningTime() {
|
||||
long aRunningTime = mCountdownTime - calculateRunningTime();
|
||||
|
||||
if (aRunningTime < 0) {
|
||||
reset();
|
||||
}
|
||||
|
||||
return aRunningTime;
|
||||
}
|
||||
|
||||
private long calculateRunningTime() {
|
||||
if (mIsRunning) {
|
||||
return System.currentTimeMillis() - mTime;
|
||||
}
|
||||
|
||||
return mTime;
|
||||
public int getMinutesLeft() {
|
||||
return mTotalMinutes - mPassedMinutes;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
package org.libreoffice.impressremote.fragment;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.TimePickerDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.view.View;
|
||||
import android.widget.TimePicker;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||
import org.libreoffice.impressremote.R;
|
||||
import org.libreoffice.impressremote.util.Intents;
|
||||
|
||||
public class TimerEditingDialog extends SherlockDialogFragment implements TimePickerDialog.OnTimeSetListener, DialogInterface.OnClickListener, DialogInterface.OnShowListener, View.OnClickListener {
|
||||
public static final String TAG = "TIMER_EDITING";
|
||||
|
||||
private static final boolean IS_24_HOUR_VIEW = true;
|
||||
|
||||
private int mMinutes;
|
||||
|
||||
public static TimerEditingDialog newInstance(int aMinutes) {
|
||||
TimerEditingDialog aDialog = new TimerEditingDialog();
|
||||
|
||||
aDialog.setArguments(buildArguments(aMinutes));
|
||||
|
||||
return aDialog;
|
||||
}
|
||||
|
||||
private static Bundle buildArguments(int aMinutes) {
|
||||
Bundle aArguments = new Bundle();
|
||||
|
||||
aArguments.putInt("MINUTES", aMinutes);
|
||||
|
||||
return aArguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mMinutes = getArguments().getInt("MINUTES");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle aSavedInstanceState) {
|
||||
TimePickerDialog aDialog = new TimePickerDialog(getActivity(), this,
|
||||
getHours(mMinutes), getMinutes(mMinutes), IS_24_HOUR_VIEW);
|
||||
|
||||
aDialog.setTitle(R.string.title_timer);
|
||||
|
||||
aDialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.button_save), this);
|
||||
aDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.button_cancel), this);
|
||||
aDialog.setButton(DialogInterface.BUTTON_NEUTRAL, getString(R.string.button_reset), this);
|
||||
|
||||
aDialog.setOnShowListener(this);
|
||||
|
||||
return aDialog;
|
||||
}
|
||||
|
||||
private int getMinutes(int aMinutes) {
|
||||
return (int) (aMinutes - getHours(aMinutes) * TimeUnit.HOURS.toMinutes(1));
|
||||
}
|
||||
|
||||
private int getHours(int aMinutes) {
|
||||
return (int) (aMinutes / TimeUnit.HOURS.toMinutes(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeSet(TimePicker aTimePicker, int aHour, int aMinute) {
|
||||
mMinutes = getMinutes(aHour, aMinute);
|
||||
}
|
||||
|
||||
private int getMinutes(int aHours, int aMinutes) {
|
||||
return (int) (TimeUnit.HOURS.toMinutes(aHours) + aMinutes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface aDialogInterface, int aButtonId) {
|
||||
getTimePickerDialog().onClick(aDialogInterface, aButtonId);
|
||||
|
||||
switch (aButtonId) {
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
resumeTimer();
|
||||
break;
|
||||
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
changeTimer();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private TimePickerDialog getTimePickerDialog() {
|
||||
return (TimePickerDialog) getDialog();
|
||||
}
|
||||
|
||||
private void resumeTimer() {
|
||||
Intent aIntent = Intents.buildTimerResumedIntent();
|
||||
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(aIntent);
|
||||
}
|
||||
|
||||
private void changeTimer() {
|
||||
Intent aIntent = Intents.buildTimerChangedIntent(mMinutes);
|
||||
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(aIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow(DialogInterface dialogInterface) {
|
||||
setUpNeutralButton();
|
||||
}
|
||||
|
||||
private void setUpNeutralButton() {
|
||||
TimePickerDialog aDialog = (TimePickerDialog) getDialog();
|
||||
|
||||
aDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View aView) {
|
||||
// Requires the additional listener to not close the dialog.
|
||||
|
||||
resetTime();
|
||||
}
|
||||
|
||||
private void resetTime() {
|
||||
TimePickerDialog aDialog = (TimePickerDialog) getDialog();
|
||||
|
||||
aDialog.updateTime(0, 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package org.libreoffice.impressremote.fragment;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.TimePickerDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.widget.TimePicker;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||
import org.libreoffice.impressremote.R;
|
||||
import org.libreoffice.impressremote.util.Intents;
|
||||
|
||||
public class TimerSettingDialog extends SherlockDialogFragment implements TimePickerDialog.OnTimeSetListener, DialogInterface.OnClickListener {
|
||||
public static final String TAG = "TIMER_SETTING";
|
||||
|
||||
private static final int INITIAL_HOUR = 0;
|
||||
private static final int INITIAL_MINUTE = 15;
|
||||
|
||||
private static final boolean IS_24_HOUR_VIEW = true;
|
||||
|
||||
private int mMinutes;
|
||||
|
||||
public static TimerSettingDialog newInstance() {
|
||||
return new TimerSettingDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle aSavedInstanceState) {
|
||||
TimePickerDialog aDialog = new TimePickerDialog(getActivity(), this,
|
||||
INITIAL_HOUR, INITIAL_MINUTE, IS_24_HOUR_VIEW);
|
||||
|
||||
aDialog.setTitle(R.string.title_timer);
|
||||
|
||||
aDialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.button_start), this);
|
||||
aDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.button_cancel), this);
|
||||
|
||||
return aDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeSet(TimePicker aTimePicker, int aHour, int aMinute) {
|
||||
mMinutes = getMinutes(aHour, aMinute);
|
||||
}
|
||||
|
||||
private int getMinutes(int aHours, int aMinutes) {
|
||||
return (int) (TimeUnit.HOURS.toMinutes(aHours) + aMinutes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface aDialogInterface, int aButtonId) {
|
||||
getTimePickerDialog().onClick(aDialogInterface, aButtonId);
|
||||
|
||||
if (aButtonId != DialogInterface.BUTTON_POSITIVE) {
|
||||
return;
|
||||
}
|
||||
|
||||
startTimer();
|
||||
}
|
||||
|
||||
private TimePickerDialog getTimePickerDialog() {
|
||||
return (TimePickerDialog) getDialog();
|
||||
}
|
||||
|
||||
private void startTimer() {
|
||||
Intent aIntent = Intents.buildTimerStartedIntent(mMinutes);
|
||||
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(aIntent);
|
||||
}
|
||||
}
|
|
@ -17,25 +17,35 @@ public final class FragmentOperator {
|
|||
private FragmentOperator() {
|
||||
}
|
||||
|
||||
public static void setUpFragment(FragmentActivity aActivity, Fragment aFragment) {
|
||||
if (isFragmentSetUp(aActivity)) {
|
||||
public static void addFragment(FragmentActivity aActivity, Fragment aFragment) {
|
||||
if (isFragmentAdded(aActivity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
installFragment(aActivity, aFragment);
|
||||
FragmentTransaction aFragmentTransaction = beginFragmentTransaction(aActivity);
|
||||
|
||||
aFragmentTransaction.add(android.R.id.content, aFragment);
|
||||
|
||||
aFragmentTransaction.commit();
|
||||
}
|
||||
|
||||
private static boolean isFragmentSetUp(FragmentActivity aActivity) {
|
||||
private static boolean isFragmentAdded(FragmentActivity aActivity) {
|
||||
FragmentManager aFragmentManager = aActivity.getSupportFragmentManager();
|
||||
|
||||
return aFragmentManager.findFragmentById(android.R.id.content) != null;
|
||||
}
|
||||
|
||||
private static void installFragment(FragmentActivity aActivity, Fragment aFragment) {
|
||||
private static FragmentTransaction beginFragmentTransaction(FragmentActivity aActivity) {
|
||||
FragmentManager aFragmentManager = aActivity.getSupportFragmentManager();
|
||||
FragmentTransaction aFragmentTransaction = aFragmentManager.beginTransaction();
|
||||
|
||||
aFragmentTransaction.add(android.R.id.content, aFragment);
|
||||
return aFragmentManager.beginTransaction();
|
||||
}
|
||||
|
||||
public static void replaceFragmentAnimated(FragmentActivity aActivity, Fragment aFragment) {
|
||||
FragmentTransaction aFragmentTransaction = beginFragmentTransaction(aActivity);
|
||||
aFragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
|
||||
aFragmentTransaction.replace(android.R.id.content, aFragment);
|
||||
|
||||
aFragmentTransaction.commit();
|
||||
}
|
||||
|
|
|
@ -39,6 +39,11 @@ public final class Intents {
|
|||
public static final String SLIDE_CHANGED = "SLIDE_CHANGED";
|
||||
public static final String SLIDE_PREVIEW = "SLIDE_PREVIEW";
|
||||
public static final String SLIDE_NOTES = "SLIDE_NOTES";
|
||||
|
||||
public static final String TIMER_UPDATED = "TIMER_UPDATED";
|
||||
public static final String TIMER_STARTED = "TIMER_STARTED";
|
||||
public static final String TIMER_RESUMED = "TIMER_RESUMED";
|
||||
public static final String TIMER_CHANGED = "TIMER_CHANGED";
|
||||
}
|
||||
|
||||
public static final class Extras {
|
||||
|
@ -52,6 +57,8 @@ public final class Intents {
|
|||
public static final String SERVER_NAME = "SERVER_NAME";
|
||||
|
||||
public static final String SLIDE_INDEX = "SLIDE_INDEX";
|
||||
|
||||
public static final String MINUTES = "MINUTES";
|
||||
}
|
||||
|
||||
public static final class RequestCodes {
|
||||
|
@ -139,6 +146,28 @@ public final class Intents {
|
|||
public static Intent buildCommunicationServiceIntent(Context aContext) {
|
||||
return new Intent(aContext, CommunicationService.class);
|
||||
}
|
||||
|
||||
public static Intent buildTimerUpdatedIntent() {
|
||||
return new Intent(Actions.TIMER_UPDATED);
|
||||
}
|
||||
|
||||
public static Intent buildTimerStartedIntent(int aMinutesLength) {
|
||||
Intent aIntent = new Intent(Actions.TIMER_STARTED);
|
||||
aIntent.putExtra(Extras.MINUTES, aMinutesLength);
|
||||
|
||||
return aIntent;
|
||||
}
|
||||
|
||||
public static Intent buildTimerResumedIntent() {
|
||||
return new Intent(Actions.TIMER_RESUMED);
|
||||
}
|
||||
|
||||
public static Intent buildTimerChangedIntent(int aMinutesLength) {
|
||||
Intent aIntent = new Intent(Actions.TIMER_CHANGED);
|
||||
aIntent.putExtra(Extras.MINUTES, aMinutesLength);
|
||||
|
||||
return aIntent;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
Loading…
Reference in a new issue