diff options
author | Artur Dryomov <artur.dryomov@gmail.com> | 2013-07-29 04:09:29 +0300 |
---|---|---|
committer | Artur Dryomov <artur.dryomov@gmail.com> | 2013-07-29 04:13:11 +0300 |
commit | f1b77bf3715b7a28cf4a9afd5f47b3e20d50ca36 (patch) | |
tree | 9b31ef06824f682f6446991e9677899c72855325 /android | |
parent | 766b6f5b14b517e178c9b86611d0edb7582e1ede (diff) |
Add timer support.
Show the timer as a dialog, plus update all following information as it
should be.
Change-Id: Idae00b009ce098cfd482ec79629fc8f674502c9a
Diffstat (limited to 'android')
17 files changed, 481 insertions, 138 deletions
diff --git a/android/sdremote/res/drawable-hdpi/ic_action_timer.png b/android/sdremote/res/drawable-hdpi/ic_action_timer.png Binary files differnew file mode 100755 index 000000000000..314ec9319a07 --- /dev/null +++ b/android/sdremote/res/drawable-hdpi/ic_action_timer.png diff --git a/android/sdremote/res/drawable-mdpi/ic_action_timer.png b/android/sdremote/res/drawable-mdpi/ic_action_timer.png Binary files differnew file mode 100755 index 000000000000..a09df2b99c58 --- /dev/null +++ b/android/sdremote/res/drawable-mdpi/ic_action_timer.png diff --git a/android/sdremote/res/drawable-xhdpi/ic_action_timer.png b/android/sdremote/res/drawable-xhdpi/ic_action_timer.png Binary files differnew file mode 100755 index 000000000000..c8771db97158 --- /dev/null +++ b/android/sdremote/res/drawable-xhdpi/ic_action_timer.png diff --git a/android/sdremote/res/menu/menu_action_bar_slide_show.xml b/android/sdremote/res/menu/menu_action_bar_slide_show.xml new file mode 100644 index 000000000000..eaa2b3d0ea3c --- /dev/null +++ b/android/sdremote/res/menu/menu_action_bar_slide_show.xml @@ -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>
\ No newline at end of file diff --git a/android/sdremote/res/menu/menu_action_bar_slide_show_grid.xml b/android/sdremote/res/menu/menu_action_bar_slide_show_grid.xml deleted file mode 100644 index d65c782669e2..000000000000 --- a/android/sdremote/res/menu/menu_action_bar_slide_show_grid.xml +++ /dev/null @@ -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>
\ No newline at end of file diff --git a/android/sdremote/res/menu/menu_action_bar_slide_show_pager.xml b/android/sdremote/res/menu/menu_action_bar_slide_show_pager.xml deleted file mode 100644 index 023dcd5e3301..000000000000 --- a/android/sdremote/res/menu/menu_action_bar_slide_show_pager.xml +++ /dev/null @@ -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>
\ No newline at end of file diff --git a/android/sdremote/res/values/strings.xml b/android/sdremote/res/values/strings.xml index 16c1de821d6f..f315add6ce86 100644 --- a/android/sdremote/res/values/strings.xml +++ b/android/sdremote/res/values/strings.xml @@ -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> diff --git a/android/sdremote/res/values/themes.xml b/android/sdremote/res/values/themes.xml index da70aa8e5776..20a4b2226722 100644 --- a/android/sdremote/res/values/themes.xml +++ b/android/sdremote/res/values/themes.xml @@ -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> diff --git a/android/sdremote/src/org/libreoffice/impressremote/activity/ComputersActivity.java b/android/sdremote/src/org/libreoffice/impressremote/activity/ComputersActivity.java index 3fa617339b6d..2dd3b0b994b3 100644 --- a/android/sdremote/src/org/libreoffice/impressremote/activity/ComputersActivity.java +++ b/android/sdremote/src/org/libreoffice/impressremote/activity/ComputersActivity.java @@ -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 diff --git a/android/sdremote/src/org/libreoffice/impressremote/activity/SlideShowActivity.java b/android/sdremote/src/org/libreoffice/impressremote/activity/SlideShowActivity.java index 4b91a6af8f65..06967d1be6fd 100644 --- a/android/sdremote/src/org/libreoffice/impressremote/activity/SlideShowActivity.java +++ b/android/sdremote/src/org/libreoffice/impressremote/activity/SlideShowActivity.java @@ -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; diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java b/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java index 2977921f25a9..6041190f5857 100644 --- a/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java +++ b/android/sdremote/src/org/libreoffice/impressremote/communication/CommunicationService.java @@ -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(); @@ -279,6 +279,12 @@ public class CommunicationService extends Service implements Runnable, MessagesL } @Override + public void onTimerUpdated() { + Intent aIntent = Intents.buildTimerUpdatedIntent(); + LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent); + } + + @Override public void onDestroy() { stopSearch(); diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java b/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java index 0b9b1d6dc61a..f6aa6dd1b40e 100644 --- a/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java +++ b/android/sdremote/src/org/libreoffice/impressremote/communication/SlideShow.java @@ -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) { diff --git a/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java b/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java index 84a793253328..9efc42e66fa9 100644 --- a/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java +++ b/android/sdremote/src/org/libreoffice/impressremote/communication/Timer.java @@ -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; - - private boolean mIsRunning; - private boolean mIsCountdown; - - public Timer() { - mTime = 0; - mCountdownTime = 0; - - mIsRunning = false; - mIsCountdown = false; - } +import java.util.concurrent.TimeUnit; - /** - * 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; +import android.os.Handler; - if (mIsRunning) { - reset(); - } +public class Timer implements Runnable { + public interface TimerListener { + public void onTimerUpdated(); } - public boolean isCountdown() { - return mIsCountdown; - } + private static final long UPDATE_PERIOD_IN_MINUTES = 1; + + private final Handler mTimerHandler; + private final TimerListener mTimerListener; + + private int mTotalMinutes; + private int mPassedMinutes; - /** - * 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 Timer(TimerListener aTimerListener) { + mTimerHandler = new Handler(); + mTimerListener = aTimerListener; + + mTotalMinutes = 0; + mPassedMinutes = 0; } - public long getCountdownTime() { - return mCountdownTime; + public void setMinutesLength(int aLengthInMinutes) { + mTotalMinutes = aLengthInMinutes; } - public boolean isRunning() { - return mIsRunning; + public int getMinutesLength() { + return mTotalMinutes; } - /** - * 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)); } - public void stop() { - if (!mIsRunning) - return; + @Override + public void run() { + updatePassedMinutes(); - mTime = System.currentTimeMillis() - mTime; - mIsRunning = false; - } + mTimerListener.onTimerUpdated(); - /** - * 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(); - } + start(); + } - return calculateRunningTime(); + private void updatePassedMinutes() { + mPassedMinutes++; } - private long calculateCountdownRunningTime() { - long aRunningTime = mCountdownTime - calculateRunningTime(); + public void pause() { + stop(); + } - if (aRunningTime < 0) { - reset(); - } + public void resume() { + start(); + } - return aRunningTime; + public void stop() { + mTimerHandler.removeCallbacks(this); } - private long calculateRunningTime() { - if (mIsRunning) { - return System.currentTimeMillis() - mTime; - } + public boolean isTimeUp() { + return getMinutesLeft() <= 0; + } - return mTime; + public int getMinutesLeft() { + return mTotalMinutes - mPassedMinutes; } } diff --git a/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerEditingDialog.java b/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerEditingDialog.java new file mode 100644 index 000000000000..accfd8bdeaaf --- /dev/null +++ b/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerEditingDialog.java @@ -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); + } +} diff --git a/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerSettingDialog.java b/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerSettingDialog.java new file mode 100644 index 000000000000..99374f817bfe --- /dev/null +++ b/android/sdremote/src/org/libreoffice/impressremote/fragment/TimerSettingDialog.java @@ -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); + } +} diff --git a/android/sdremote/src/org/libreoffice/impressremote/util/FragmentOperator.java b/android/sdremote/src/org/libreoffice/impressremote/util/FragmentOperator.java index 3c6506307938..af7e47c5b700 100644 --- a/android/sdremote/src/org/libreoffice/impressremote/util/FragmentOperator.java +++ b/android/sdremote/src/org/libreoffice/impressremote/util/FragmentOperator.java @@ -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(); } diff --git a/android/sdremote/src/org/libreoffice/impressremote/util/Intents.java b/android/sdremote/src/org/libreoffice/impressremote/util/Intents.java index ad7cfc1324c9..eb85418ea14d 100644 --- a/android/sdremote/src/org/libreoffice/impressremote/util/Intents.java +++ b/android/sdremote/src/org/libreoffice/impressremote/util/Intents.java @@ -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: */ |