Merge branch 'ubilabs--rcapp--bug-3525' into ubilabs--rcapp--master

This commit is contained in:
Bennet Brunsen committed 2016-06-09 11:48:08 +02:00
commit 72ad93dfd4
13 files changed
+271 -226

No files matched your search

@@ -22,7 +22,7 @@ public class DurationTest {
TimePoint t2 = t1.plus(d);
assertEquals(123+234, t2.asMillis());
}
@Test
public void testDurationMinus() {
TimePoint t1 = new MillisecondsTimePoint(234);
@@ -1,10 +1,14 @@
package com.sap.sailing.domain.common.test;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.junit.Test;
import com.sap.sse.common.TimePoint;
@@ -54,4 +58,29 @@ public class TimePointTest {
assertFalse(t.equals("s"));
}
@Test
public void nearestFullMinute() {
Calendar cal = new GregorianCalendar();
cal.set(Calendar.MILLISECOND, 0);
cal.set(2016, 5, 15, 10, 12, 33); // 10:12:33 on June 15, 2016 in the local time zone
final TimePoint start = new MillisecondsTimePoint(cal.getTime());
cal.set(2016, 5, 15, 10, 8, 35); // 10:08:35 on June 15, 2016 in the local time zone
final TimePoint t1 = new MillisecondsTimePoint(cal.getTime());
cal.set(2016, 5, 15, 10, 8, 31); // 10:08:31 on June 15, 2016 in the local time zone
final TimePoint t2 = new MillisecondsTimePoint(cal.getTime());
cal.set(2016, 5, 15, 10, 15, 31); // 10:15:31 on June 15, 2016 in the local time zone
final TimePoint t3 = new MillisecondsTimePoint(cal.getTime());
cal.set(2016, 5, 15, 10, 15, 37); // 10:15:31 on June 15, 2016 in the local time zone
final TimePoint t4 = new MillisecondsTimePoint(cal.getTime());
assertEquals(new MillisecondsTimePoint(new GregorianCalendar(2016, 5, 15, 10, 12, 35).getTime()), start.getNearestModuloOneMinute(t1));
assertEquals(new MillisecondsTimePoint(new GregorianCalendar(2016, 5, 15, 10, 12, 31).getTime()), start.getNearestModuloOneMinute(t2));
assertEquals(new MillisecondsTimePoint(new GregorianCalendar(2016, 5, 15, 10, 12, 31).getTime()), start.getNearestModuloOneMinute(t3));
assertEquals(new MillisecondsTimePoint(new GregorianCalendar(2016, 5, 15, 10, 12, 37).getTime()), start.getNearestModuloOneMinute(t4));
// and now at least on milliseconds example
cal.set(Calendar.MILLISECOND, 123);
final TimePoint t5 = new MillisecondsTimePoint(cal.getTime());
final Calendar t5Compare = new GregorianCalendar(2016, 5, 15, 10, 12, 37);
t5Compare.set(Calendar.MILLISECOND, 123);
assertEquals(new MillisecondsTimePoint(t5Compare.getTime()), start.getNearestModuloOneMinute(t5));
}
}
@@ -4,6 +4,14 @@
<div id="mainContent">
<h4 class="articleHeadline">What's New - SAP Sailing Race Manager</h4>
<div class="innerContent">
<h5 class="articleSubheadline">June 2016</h5>
<ul class="bulletList">
<li>The start time editing screen has now a "Sync to minute" button, which replaces
the both buttons beside the countdown. This button sets the countdown to the nearest
minute and after "Set time" the new start time will be sent to the server.</li>
</ul>
<h5 class="articleSubheadline">May 2016</h5>
<ul class="bulletList">
@@ -47,4 +47,10 @@ public interface Duration extends Serializable, Comparable<Duration> {
Duration plus(long milliseconds);
Duration plus(Duration duration);
/**
* The "modulo" operation; imagine the operation implemented as this duration's milliseconds
* modulo {@code d}'s milliseconds
*/
Duration mod(Duration d);
}
@@ -32,4 +32,11 @@ public interface TimePoint extends Comparable<TimePoint>, Serializable {
boolean after(TimePoint other);
boolean before(TimePoint other);
/**
* @return a {@link TimePoint} such that when used to set the time of a calendar, the seconds and milliseconds will
* match that of {@code syncToClosestSecondsAndMillisOf} and the time difference to {@code this} time point is
* minimal. In particular, the time difference will always be less than or equal to 30s.
*/
TimePoint getNearestModuloOneMinute(TimePoint syncToClosestSecondsAndMillisOf);
}
@@ -116,4 +116,21 @@ public abstract class AbstractTimePoint implements TimePoint {
* as {@link #getDate()}.
*/
protected void cacheDate(Date date) {}
@Override
public TimePoint getNearestModuloOneMinute(final TimePoint syncToClosestSecondsAndMillisOf) {
final Duration diffModOneMinute = this.until(syncToClosestSecondsAndMillisOf).mod(Duration.ONE_MINUTE);
final Duration diffToAdd;
if (diffModOneMinute.compareTo(Duration.ONE_SECOND.times(30l)) > 0) {
diffToAdd = Duration.ONE_MINUTE.minus(diffModOneMinute).times(-1l);
} else if (diffModOneMinute.compareTo(Duration.ONE_SECOND.times(-30l)) < 0) {
diffToAdd = Duration.ONE_MINUTE.minus(diffModOneMinute.times(-1l));
} else {
diffToAdd = diffModOneMinute;
}
final TimePoint result = this.plus(diffToAdd);
assert this.until(result).abs().compareTo(Duration.ONE_SECOND.times(30)) <= 0;
assert syncToClosestSecondsAndMillisOf.asMillis() % 60000 == result.asMillis() % 60000;
return result;
}
}
@@ -117,4 +117,9 @@ public class MillisecondsDurationImpl implements Duration {
}
}
@Override
public Duration mod(Duration d) {
return new MillisecondsDurationImpl(asMillis() % d.asMillis());
}
}
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/header"
@@ -25,13 +25,13 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="?attr/chevron_left_24dp"
android:visibility="gone" />
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/set_time"
android:textAppearance="?attr/textHeader" />
android:textAppearance="?attr/textHeader"/>
</LinearLayout>
<View
@@ -39,7 +39,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/thin_line"
android:layout_alignParentBottom="true"
android:background="?attr/black" />
android:background="?attr/black"/>
</RelativeLayout>
<LinearLayout
@@ -63,7 +63,7 @@
android:text="@string/dependent_races_absolute"
android:textAllCaps="true"
android:textColor="?attr/sap_yellow_1"
android:textSize="@dimen/textSize_20" />
android:textSize="@dimen/textSize_20"/>
<Button
android:id="@+id/relative"
@@ -76,7 +76,7 @@
android:text="@string/dependent_races_relative"
android:textAllCaps="true"
android:textColor="?attr/sap_light_gray"
android:textSize="@dimen/textSize_20" />
android:textSize="@dimen/textSize_20"/>
</LinearLayout>
<FrameLayout
@@ -103,21 +103,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="@dimen/default_margin_half"
android:orientation="horizontal">
<Button
android:id="@+id/minute_inc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?attr/button_filled_bordered"
android:drawableLeft="?attr/chevron_left"
android:paddingRight="@dimen/default_padding_half"
android:textColor="?attr/white"
android:textSize="@dimen/textSize_20"
tools:text="1:00:00" />
<TextView
android:id="@+id/start_countdown"
android:layout_width="wrap_content"
@@ -126,21 +113,9 @@
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
android:textColor="?attr/white"
android:textSize="@dimen/textSize_20"
android:textSize="@dimen/textSize_72"
android:visibility="visible"
tools:text="1:01:00" />
<Button
android:id="@+id/minute_dec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?attr/button_filled_bordered"
android:drawableRight="?attr/chevron_right"
android:paddingLeft="@dimen/default_padding_half"
android:textColor="?attr/white"
android:textSize="@dimen/textSize_20"
tools:text="1:02:00" />
tools:text="1:01:00"/>
</LinearLayout>
</RelativeLayout>
@@ -162,14 +137,21 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants" />
android:descendantFocusability="blocksDescendants"/>
<include
android:id="@+id/start_time_picker"
layout="@layout/time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
android:layout_gravity="center_vertical"/>
<NumberPicker
android:id="@+id/start_time_seconds"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants"/>
</LinearLayout>
</RelativeLayout>
@@ -178,14 +160,29 @@
android:id="@+id/set_start_time_absolute"
style="?attr/button"
android:layout_width="@dimen/default_button_width"
android:layout_height="wrap_content"
android:layout_height="@dimen/default_button_height"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_marginBottom="@dimen/side_padding"
android:layout_marginTop="@dimen/side_padding"
android:maxWidth="400dp"
android:text="@string/race_set_time"
android:textSize="@dimen/textSize_18" />
android:textSize="@dimen/textSize_18"/>
<Button
android:id="@+id/sync_to_minute"
android:layout_width="@dimen/default_button_width"
android:layout_height="@dimen/default_button_height"
android:layout_above="@id/set_start_time_absolute"
android:layout_centerHorizontal="true"
android:background="?attr/button_filled_bordered"
android:paddingLeft="@dimen/default_padding_half"
android:paddingRight="@dimen/default_padding_half"
android:text="@string/sync_to_minute"
android:textColor="?attr/white"
android:textSize="@dimen/textSize_18"
android:visibility="gone"
tools:visibility="visible"/>
<TextView
android:id="@+id/debug_time"
@@ -195,8 +192,7 @@
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:visibility="gone"
tools:text="12:12:12" />
tools:text="12:12:12"/>
</RelativeLayout>
<RelativeLayout
@@ -227,7 +223,7 @@
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginTop="@dimen/default_margin"
android:scaleX="@integer/picker_scale"
android:scaleY="@integer/picker_scale" />
android:scaleY="@integer/picker_scale"/>
<LinearLayout
android:id="@+id/relative_spinner_area"
@@ -246,7 +242,7 @@
android:layout_marginTop="@dimen/default_margin_half"
android:background="?attr/spinner_background"
android:dropDownWidth="wrap_content"
android:spinnerMode="dropdown" />
android:spinnerMode="dropdown"/>
<Spinner
android:id="@+id/dependent_fleet"
@@ -257,7 +253,7 @@
android:dropDownWidth="wrap_content"
android:spinnerMode="dropdown"
android:visibility="gone"
tools:visibility="visible" />
tools:visibility="visible"/>
<Spinner
android:id="@+id/dependent_racegroup"
@@ -266,7 +262,7 @@
android:layout_marginTop="@dimen/default_margin_half"
android:background="?attr/spinner_background"
android:dropDownWidth="wrap_content"
android:spinnerMode="dropdown" />
android:spinnerMode="dropdown"/>
</LinearLayout>
<TextView
@@ -277,7 +273,7 @@
android:layout_alignParentTop="true"
android:paddingLeft="@dimen/spinner_padding"
android:text="@string/minutes_after"
android:textAppearance="?attr/textSmall" />
android:textAppearance="?attr/textSmall"/>
</RelativeLayout>
</RelativeLayout>
@@ -285,14 +281,14 @@
android:id="@+id/set_start_time_relative"
style="?attr/button"
android:layout_width="@dimen/default_button_width"
android:layout_height="wrap_content"
android:layout_height="@dimen/default_button_height"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_marginBottom="@dimen/side_padding"
android:layout_marginTop="@dimen/side_padding"
android:maxWidth="400dp"
android:text="@string/race_set_time"
android:textSize="@dimen/textSize_18" />
android:textSize="@dimen/textSize_18"/>
</RelativeLayout>
</FrameLayout>
</RelativeLayout>
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/header"
@@ -25,13 +25,13 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="?attr/chevron_left_24dp"
android:visibility="gone" />
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/set_time"
android:textAppearance="?attr/textHeader" />
android:textAppearance="?attr/textHeader"/>
</LinearLayout>
<View
@@ -39,7 +39,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/thick_line"
android:layout_alignParentBottom="true"
android:background="?attr/black" />
android:background="?attr/black"/>
</RelativeLayout>
<LinearLayout
@@ -61,7 +61,7 @@
android:text="@string/dependent_races_absolute"
android:textAllCaps="true"
android:textColor="?attr/sap_yellow_1"
android:textSize="@dimen/textSize_26" />
android:textSize="@dimen/textSize_26"/>
<Button
android:id="@+id/relative"
@@ -72,7 +72,7 @@
android:text="@string/dependent_races_relative"
android:textAllCaps="true"
android:textColor="?attr/sap_light_gray"
android:textSize="@dimen/textSize_26" />
android:textSize="@dimen/textSize_26"/>
</LinearLayout>
<FrameLayout
@@ -87,7 +87,7 @@
android:layout_height="match_parent"
android:background="?attr/sap_gray_black_30"
android:visibility="gone"
tools:visibility="gone">
tools:visibility="visible">
<RelativeLayout
android:id="@+id/buttonBar"
@@ -102,18 +102,6 @@
android:layout_marginTop="@dimen/default_margin_half"
android:orientation="horizontal">
<Button
android:id="@+id/minute_inc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?attr/button_filled_bordered"
android:drawableLeft="?attr/chevron_left"
android:paddingRight="@dimen/default_padding_half"
android:textAppearance="?attr/textLarge"
android:textColor="?attr/white"
tools:text="1:00:00" />
<TextView
android:id="@+id/start_countdown"
android:layout_width="wrap_content"
@@ -123,19 +111,7 @@
android:layout_marginRight="@dimen/default_margin"
android:textAppearance="?attr/textXLarge"
android:visibility="visible"
tools:text="1:01:00" />
<Button
android:id="@+id/minute_dec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?attr/button_filled_bordered"
android:drawableRight="?attr/chevron_right"
android:paddingLeft="@dimen/default_padding_half"
android:textAppearance="?attr/textLarge"
android:textColor="?attr/white"
tools:text="1:02:00" />
tools:text="1:01:00"/>
</LinearLayout>
</RelativeLayout>
@@ -145,14 +121,33 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
android:id="@+id/set_start_time_absolute"
style="?attr/buttonSolidSmall"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="@dimen/default_margin_twice"
android:text="@string/race_set_time" />
android:layout_margin="@dimen/default_margin"
android:orientation="horizontal">
<Button
android:id="@+id/sync_to_minute"
style="?attr/buttonSolidSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin"
android:background="?attr/button_filled_bordered"
android:text="@string/sync_to_minute"
android:textColor="?attr/white"
android:visibility="gone"
tools:visibility="visible"/>
<Button
android:id="@+id/set_start_time_absolute"
style="?attr/buttonSolidSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin"
android:text="@string/race_set_time"/>
</LinearLayout>
</RelativeLayout>
<RelativeLayout
@@ -174,14 +169,21 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants" />
android:descendantFocusability="blocksDescendants"/>
<include
android:id="@+id/start_time_picker"
layout="@layout/time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
android:layout_gravity="center_vertical"/>
<NumberPicker
android:id="@+id/start_time_seconds"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants"/>
</LinearLayout>
</RelativeLayout>
@@ -194,7 +196,7 @@
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:visibility="gone"
tools:text="12:12:12" />
tools:text="12:12:12"/>
</RelativeLayout>
<RelativeLayout
@@ -203,7 +205,7 @@
android:layout_height="match_parent"
android:background="?attr/sap_gray_black_30"
android:visibility="gone"
tools:visibility="visible">
tools:visibility="gone">
<RelativeLayout
android:id="@+id/set_start_time_2"
@@ -218,13 +220,13 @@
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="@dimen/default_margin_twice"
android:text="@string/race_set_time" />
android:text="@string/race_set_time"/>
</RelativeLayout>
<RelativeLayout
android:layout_above="@id/set_start_time_2"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:layout_above="@id/set_start_time_2">
<LinearLayout
android:id="@+id/relative_input"
@@ -239,7 +241,7 @@
android:layout_gravity="center_vertical"
android:layout_margin="@dimen/default_margin"
android:scaleX="@integer/picker_scale"
android:scaleY="@integer/picker_scale" />
android:scaleY="@integer/picker_scale"/>
<TextView
android:layout_width="wrap_content"
@@ -247,7 +249,7 @@
android:layout_gravity="center_vertical"
android:padding="@dimen/default_padding_half"
android:text="@string/minutes_after"
android:textAppearance="?attr/textLarge" />
android:textAppearance="?attr/textLarge"/>
<LinearLayout
android:layout_width="@dimen/unscheduled_spinner_width"
@@ -261,7 +263,7 @@
android:layout_height="wrap_content"
android:background="?attr/spinner_background"
android:dropDownWidth="wrap_content"
android:spinnerMode="dropdown" />
android:spinnerMode="dropdown"/>
<Spinner
android:id="@+id/dependent_fleet"
@@ -272,7 +274,7 @@
android:dropDownWidth="wrap_content"
android:spinnerMode="dropdown"
android:visibility="gone"
tools:visibility="visible" />
tools:visibility="visible"/>
<Spinner
android:id="@+id/dependent_racegroup"
@@ -281,7 +283,7 @@
android:layout_marginTop="@dimen/default_margin_half"
android:background="?attr/spinner_background"
android:dropDownWidth="wrap_content"
android:spinnerMode="dropdown" />
android:spinnerMode="dropdown"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
@@ -512,5 +512,6 @@
<string name="abort_dismiss">Verwerfen</string>
<string name="set_column_factor">Setze Faktor</string>
<string name="set_factor_error">Beim Setzen des Faktors ist ein Fehler aufgetreten: %s</string>
<string name="sync_to_minute">Sync zur Minute</string>
</resources>
@@ -540,5 +540,6 @@
<string name="race_factor_format" translatable="false">x #.####</string>
<string name="set_column_factor">Set Factor</string>
<string name="set_factor_error">There was an error while setting the factor: %s</string>
<string name="sync_to_minute">Sync to minute</string>
</resources>
@@ -1,5 +1,6 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
@@ -9,21 +10,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import android.app.FragmentTransaction;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.NumberPicker;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import com.sap.sailing.android.shared.util.AppUtils;
import com.sap.sailing.android.shared.util.BitmapHelper;
import com.sap.sailing.android.shared.util.ViewHelper;
@@ -53,6 +39,21 @@ import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.util.NaturalComparator;
import android.app.FragmentTransaction;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.NumberPicker;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
public class StartTimeFragment extends BaseFragment
implements View.OnClickListener, NumberPicker.OnValueChangeListener, TimePicker.OnTimeChangedListener {
@@ -61,7 +62,6 @@ public class StartTimeFragment extends BaseFragment
private static final int FUTURE_DAYS = 25;
private static final int PAST_DAYS = 3;
private static final int MAX_DIFF_MIN = 60;
private static final String ZERO_TIME = "-00:00:00";
private static final int ABSOLUTE = 0;
private static final int RELATIVE = 1;
@@ -77,14 +77,10 @@ public class StartTimeFragment extends BaseFragment
private Spinner mFleet;
private Spinner mRace;
private TimePicker mTimePicker;
private NumberPicker mStartSeconds;
private TextView mCountdown;
private TextView mDebugTime;
private Button mMinuteInc;
private Button mMinuteDec;
private TimePoint mStartTime;
private Calendar mTimeLeft;
private Calendar mTimeRight;
private Calendar mCalendar;
private SimpleRaceLogIdentifier mRaceId;
private Duration mStartTimeOffset;
private boolean mListenerIgnore = true;
@@ -99,10 +95,6 @@ public class StartTimeFragment extends BaseFragment
*/
private RaceStateChangedListener raceStateChangedListener;
public StartTimeFragment() {
mCalendar = Calendar.getInstance();
}
public static StartTimeFragment newInstance(int startMode) {
StartTimeFragment fragment = new StartTimeFragment();
Bundle args = new Bundle();
@@ -155,14 +147,10 @@ public class StartTimeFragment extends BaseFragment
}
mCountdown = ViewHelper.get(layout, R.id.start_countdown);
mMinuteInc = ViewHelper.get(layout, R.id.minute_inc);
if (mMinuteInc != null) {
mMinuteInc.setOnClickListener(this);
}
mMinuteDec = ViewHelper.get(layout, R.id.minute_dec);
if (mMinuteDec != null) {
mMinuteDec.setOnClickListener(this);
Button syncMinute = ViewHelper.get(layout, R.id.sync_to_minute);
if (syncMinute != null) {
syncMinute.setOnClickListener(this);
}
View setStartAbsolute = ViewHelper.get(layout, R.id.set_start_time_absolute);
@@ -179,20 +167,6 @@ public class StartTimeFragment extends BaseFragment
return layout;
}
@Override
public void onPause() {
super.onPause();
getRaceState().removeChangedListener(raceStateChangedListener);
}
@Override
public void onResume() {
super.onResume();
getRaceState().addChangedListener(raceStateChangedListener);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -209,6 +183,7 @@ public class StartTimeFragment extends BaseFragment
View header = ViewHelper.get(getView(), R.id.header);
View back = ViewHelper.get(getView(), R.id.header_back);
View text = ViewHelper.get(getView(), R.id.header_text);
View sync = ViewHelper.get(getView(), R.id.sync_to_minute);
switch (getArguments().getInt(START_MODE, START_MODE_PRESETUP)) {
case START_MODE_PLANNED:
if (back != null) {
@@ -238,6 +213,9 @@ public class StartTimeFragment extends BaseFragment
text.setOnClickListener(this);
}
}
if (sync != null) {
sync.setVisibility(View.VISIBLE);
}
StartTimeFinderResult result = getRaceState().getStartTimeFinderResult();
if (result != null && result.isDependentStartTime()) {
@@ -258,6 +236,11 @@ public class StartTimeFragment extends BaseFragment
if (syncButtons != null) {
syncButtons.setVisibility(View.GONE);
}
View startSeconds = ViewHelper.get(getView(), R.id.start_time_seconds);
if (startSeconds != null) {
startSeconds.setVisibility(View.GONE);
}
break;
}
}
@@ -272,6 +255,20 @@ public class StartTimeFragment extends BaseFragment
initViewsRelative();
}
@Override
public void onPause() {
super.onPause();
getRaceState().removeChangedListener(raceStateChangedListener);
}
@Override
public void onResume() {
super.onResume();
getRaceState().addChangedListener(raceStateChangedListener);
}
private void initViewsRelative() {
mTimeOffset = ViewHelper.get(getView(), R.id.time_offset);
if (mTimeOffset != null) {
@@ -461,7 +458,7 @@ public class StartTimeFragment extends BaseFragment
for (RaceGroupSeriesFleet races : mGroupHeaders.keySet()) {
Util.Pair<String, String> leaderBoard = mLeaderBoardAdapter.getItem(mLeaderBoard.getSelectedItemPosition());
if (races.getRaceGroup().getName().equals(leaderBoard.getA())) {
if(races.getFleet().getName().equals(fleet)) {
if (races.getFleet().getName().equals(fleet)) {
for (ManagedRace race : mGroupHeaders.get(races)) {
if (!getRace().equals(race) && race.getStatus() != RaceLogRaceStatus.FINISHED) {
return true;
@@ -506,6 +503,15 @@ public class StartTimeFragment extends BaseFragment
mTimePicker.setCurrentMinute(minutes);
mTimePicker.setTag(time.get(Calendar.SECOND));
}
mStartSeconds = ViewHelper.get(getView(), R.id.start_time_seconds);
if (mStartSeconds != null) {
ThemeHelper.setPickerColor(getActivity(), mStartSeconds, ThemeHelper.getColor(getActivity(), R.attr.sap_light_gray), ThemeHelper
.getColor(getActivity(), R.attr.sap_light_gray));
ThemeHelper.setPickerTextSize(getActivity(), mStartSeconds, R.dimen.textSize_14);
mStartSeconds.setEnabled(false);
setSeconds();
}
}
@Override
@@ -516,33 +522,17 @@ public class StartTimeFragment extends BaseFragment
int resId;
TimePoint timePoint;
String time;
String timeLeft;
String timeRight;
if (mStartTime == null) {
mStartTime = getPickerTime();
}
if (mStartTime.after(now)) {
resId = R.string.race_start_time_in;
timePoint = mStartTime.minus(now.asMillis());
setButtonTime(timePoint, false);
time = TimeUtils.formatDurationUntil(timePoint.asMillis());
timeLeft = TimeUtils.formatDurationUntil(mTimeLeft.getTimeInMillis());
timeRight = TimeUtils.formatDurationUntil(mTimeRight.getTimeInMillis());
if (timeRight.equals(time)) {
mTimeRight.add(Calendar.MINUTE, 1);
timeRight = TimeUtils.formatDurationUntil(mTimeRight.getTimeInMillis());
}
} else {
resId = R.string.race_start_time_ago;
timePoint = now.minus(mStartTime.asMillis());
setButtonTime(timePoint, true);
time = TimeUtils.formatDurationSince(timePoint.asMillis());
timeLeft = TimeUtils.formatDurationSince(mTimeLeft.getTimeInMillis());
timeRight = TimeUtils.formatDurationSince(mTimeRight.getTimeInMillis());
if (timeRight.equals(time)) {
mTimeRight.add(Calendar.MINUTE, -1);
timeRight = TimeUtils.formatDurationSince(mTimeRight.getTimeInMillis());
}
}
if (mCountdown != null) {
@@ -551,22 +541,6 @@ public class StartTimeFragment extends BaseFragment
mCountdown.setTag(resId);
}
if (mMinuteDec != null) {
String countdown = getString(resId, timeLeft);
if (ZERO_TIME.equals(countdown)) {
countdown = countdown.substring(1);
}
mMinuteDec.setText(countdown);
}
if (mMinuteInc != null) {
String countdown = getString(resId, timeRight);
if (ZERO_TIME.equals(countdown)) {
countdown = countdown.substring(1);
}
mMinuteInc.setText(countdown);
}
if (mDebugTime != null) {
mDebugTime.setText(mStartTime.asDate().toString());
}
@@ -622,56 +596,9 @@ public class StartTimeFragment extends BaseFragment
}
}
private void setButtonTime(TimePoint timePoint, boolean reverse) {
mCalendar.setTime(timePoint.asDate());
mTimeLeft = getNewTime(mCalendar, (reverse) ? 1 : 0);
mTimeRight = getNewTime(mCalendar, (reverse) ? 0 : 1);
}
private Calendar getNewTime(Calendar calendar, int upDown) {
Calendar newCalendar = (Calendar) calendar.clone();
newCalendar.add(Calendar.MINUTE, upDown);
newCalendar.set(Calendar.SECOND, 0);
newCalendar.set(Calendar.MILLISECOND, 0);
return newCalendar;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.minute_inc:
case R.id.minute_dec:
mCalendar = Calendar.getInstance();
int msec = mCalendar.get(Calendar.MILLISECOND);
mCalendar.set(Calendar.MILLISECOND, msec);
String button = ((TextView) view).getText().toString();
boolean down = button.substring(0, 1).equals("-");
String[] values = button.split(":");
int hour = Integer.parseInt(values[0]);
int min = Integer.parseInt(values[1]);
if (view.getId() == R.id.minute_dec) { // button right
if (!down) { // time is positive
mCalendar.add(Calendar.HOUR_OF_DAY, -1 * hour);
mCalendar.add(Calendar.MINUTE, -1 * min);
} else {
mCalendar.add(Calendar.HOUR_OF_DAY, -1 * hour);
mCalendar.add(Calendar.MINUTE, min);
}
} else { // button left
if (!down) { // time is positive
mCalendar.add(Calendar.HOUR_OF_DAY, -1 * hour);
mCalendar.add(Calendar.MINUTE, -1 * min);
} else {
mCalendar.add(Calendar.HOUR_OF_DAY, -1 * hour);
mCalendar.add(Calendar.MINUTE, min);
}
}
mStartTime = new MillisecondsTimePoint(mCalendar.getTimeInMillis());
mListenerIgnore = true;
setPickerTime();
break;
case R.id.set_start_time_absolute:
changeFragment(mStartTime);
break;
@@ -680,6 +607,10 @@ public class StartTimeFragment extends BaseFragment
changeFragment(MillisecondsTimePoint.now(), new MillisecondsDurationImpl(mTimeOffset.getValue() * 60 * 1000), identifier);
break;
case R.id.sync_to_minute:
syncToMinute();
break;
case R.id.header_text:
if (getArguments() != null && getArguments().getInt(START_MODE, START_MODE_PRESETUP) == START_MODE_PRESETUP) {
changeFragment();
@@ -694,10 +625,18 @@ public class StartTimeFragment extends BaseFragment
}
}
private void syncToMinute() {
final TimePoint now = MillisecondsTimePoint.now();
mStartTime = mStartTime.getNearestModuloOneMinute(now);
mListenerIgnore = true;
setPickerTime();
}
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
if (!mListenerIgnore) {
mStartTime = new MillisecondsTimePoint(getPickerTime().asMillis());
setSeconds();
}
mListenerIgnore = false;
}
@@ -706,10 +645,26 @@ public class StartTimeFragment extends BaseFragment
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
if (!mListenerIgnore) {
mStartTime = new MillisecondsTimePoint(getPickerTime().asMillis());
setSeconds();
}
mListenerIgnore = false;
}
private void setSeconds() {
setSeconds(0, 0);
}
private void setSeconds(int sec, int msec) {
if (mStartSeconds != null) {
double seconds = sec + msec / (double) 1000;
DecimalFormat format = new DecimalFormat("0.000");
mStartSeconds.setDisplayedValues(new String[] { format.format(seconds) });
}
}
/**
* sets the time displayed in the time picker to the value of {@link #mStartTime}
*/
private void setPickerTime() {
Calendar today = Calendar.getInstance();
Calendar newTime = (Calendar) today.clone();
@@ -724,6 +679,8 @@ public class StartTimeFragment extends BaseFragment
mTimePicker.setCurrentHour(newTime.get(Calendar.HOUR_OF_DAY));
mTimePicker.setCurrentMinute(newTime.get(Calendar.MINUTE));
}
setSeconds(newTime.get(Calendar.SECOND), newTime.get(Calendar.MILLISECOND));
}
private TimePoint getPickerTime() {
@@ -9,6 +9,7 @@ import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.support.annotation.AttrRes;
import android.support.annotation.ColorInt;
import android.support.annotation.DimenRes;
import android.util.TypedValue;
import android.view.View;
import android.widget.EditText;
@@ -105,6 +106,21 @@ public class ThemeHelper {
setPickerDividerColor(context, numberPicker, dividerColor);
}
public static void setPickerTextSize(Context context, NumberPicker numberPicker, @DimenRes int dimen) {
final int count = numberPicker.getChildCount();
for (int i = 0; i < count; i++) {
View child = numberPicker.getChildAt(i);
if (child instanceof EditText) {
try {
((EditText) child).setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(dimen));
numberPicker.invalidate();
} catch (IllegalArgumentException e) {
ExLog.w(context, TAG, "IllegalArgumentException - " + e.getMessage());
}
}
}
}
public static @ColorInt int getColor(Context context, @AttrRes int colorId) {
int color = 0;
TypedValue typedValue = new TypedValue();