# generic flag rendering for all flag views

# ability to register (base) RacingProcedureChangedListeners on procedures
This commit is contained in:
Lukas Niemeier
2013-11-14 22:33:48 +01:00
parent d86e793b81
commit 1423859f3d
15 changed files with 170 additions and 202 deletions
@@ -70,7 +70,7 @@ public abstract class BaseRacingProcedure extends BaseRaceState2ChangedListener
@Override
public void addChangedListener(RacingProcedureChangedListener listener) {
changedListeners.addListener(listener);
changedListeners.addBaseListener(listener);
}
public void removeChangedListener(RacingProcedureChangedListener listener) {
@@ -5,7 +5,5 @@ import com.sap.sailing.domain.racelog.state.racingprocedure.ESSChangedListener;
public class ESSChangedListeners extends RacingProcedureChangedListeners<ESSChangedListener> implements
ESSChangedListener {
private static final long serialVersionUID = 7331254480922861592L;
}
@@ -6,18 +6,16 @@ import com.sap.sailing.domain.racelog.state.racingprocedure.GateStartRacingProce
public class GateStartChangedListeners extends RacingProcedureChangedListeners<GateStartChangedListener> implements
GateStartChangedListener {
private static final long serialVersionUID = 9128555669971858138L;
@Override
public void onGateLineOpeningTimeChanged(GateStartRacingProcedure gateStartRacingProcedure) {
for (GateStartChangedListener listener : this) {
for (GateStartChangedListener listener : getListeners()) {
listener.onGateLineOpeningTimeChanged(gateStartRacingProcedure);
}
}
@Override
public void onPathfinderChanged(GateStartRacingProcedure procedure) {
for (GateStartChangedListener listener : this) {
for (GateStartChangedListener listener : getListeners()) {
listener.onPathfinderChanged(procedure);
}
}
@@ -6,11 +6,9 @@ import com.sap.sailing.domain.racelog.state.racingprocedure.RRS26RacingProcedure
public class RRS26ChangedListeners extends RacingProcedureChangedListeners<RRS26ChangedListener> implements
RRS26ChangedListener {
private static final long serialVersionUID = -2809742244111393186L;
@Override
public void onStartmodeChanged(RRS26RacingProcedure racingProcedure) {
for (RRS26ChangedListener listener : this) {
for (RRS26ChangedListener listener : getListeners()) {
listener.onStartmodeChanged(racingProcedure);
}
}
@@ -1,44 +1,55 @@
package com.sap.sailing.domain.racelog.state.racingprocedure.impl;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.domain.racelog.state.racingprocedure.RacingProcedure;
import com.sap.sailing.domain.racelog.state.racingprocedure.RacingProcedureChangedListener;
public class RacingProcedureChangedListeners<T extends RacingProcedureChangedListener> extends HashSet<T> implements
RacingProcedureChangedListener {
private static final long serialVersionUID = 3518707638312002482L;
public class RacingProcedureChangedListeners<T extends RacingProcedureChangedListener> implements RacingProcedureChangedListener {
/**
* Adds a {@link RacingProcedureChangedListener} to this set. The type is checked on runtime!
*/
@SuppressWarnings("unchecked")
public boolean addListener(Object listener) {
if (listener instanceof RacingProcedureChangedListener) {
return super.add((T)listener);
} else {
throw new IllegalArgumentException("listener");
}
private Set<T> specificListeners;
private Set<RacingProcedureChangedListener> allListeners;
public RacingProcedureChangedListeners() {
this.specificListeners = new HashSet<T>();
this.allListeners = new HashSet<RacingProcedureChangedListener>();
}
protected Set<T> getListeners() {
return specificListeners;
}
public boolean addBaseListener(RacingProcedureChangedListener listener) {
return allListeners.add(listener);
}
public boolean add(T specificListener) {
return specificListeners.add(specificListener) && allListeners.add(specificListener);
}
public void remove(RacingProcedureChangedListener listener) {
specificListeners.remove(listener);
allListeners.remove(listener);
}
@Override
public void onActiveFlagsChanged(RacingProcedure racingProcedure) {
for (RacingProcedureChangedListener listener : this) {
for (RacingProcedureChangedListener listener : allListeners) {
listener.onActiveFlagsChanged(racingProcedure);
}
}
@Override
public void onIndividualRecallDisplayed(RacingProcedure racingProcedure) {
for (RacingProcedureChangedListener listener : this) {
for (RacingProcedureChangedListener listener : allListeners) {
listener.onIndividualRecallDisplayed(racingProcedure);
}
}
@Override
public void onIndividualRecallRemoved(RacingProcedure racingProcedure) {
for (RacingProcedureChangedListener listener : this) {
for (RacingProcedureChangedListener listener : allListeners) {
listener.onIndividualRecallRemoved(racingProcedure);
}
}
@@ -1,8 +1,6 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import android.app.Activity;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.sap.sailing.domain.racelog.state.racingprocedure.RacingProcedure;
import com.sap.sailing.domain.racelog.state.racingprocedure.impl.BaseRacingProcedureChangedListener;
@@ -48,13 +46,6 @@ public abstract class BaseRaceInfoRaceFragment<ProcedureType extends RacingProce
return getRaceState().getTypedRacingProcedure();
}
protected ImageView createFlagImageView(int flagDrawableId) {
ImageView flagView = new ImageView(getActivity());
flagView.setLayoutParams(new LinearLayout.LayoutParams(200, 130));
flagView.setImageResource(flagDrawableId);
return flagView;
}
protected abstract void setupUi();
private class ChangeListener extends BaseRacingProcedureChangedListener {
@@ -0,0 +1,103 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import android.content.Context;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.sap.sailing.domain.common.racelog.FlagPole;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.racelog.state.racingprocedure.FlagPoleState;
import com.sap.sailing.racecommittee.app.R;
public class FlagPoleStateRenderer {
private final Context context;
private final LinearLayout upperFlagsViewGroup;
private final LinearLayout lowerFlagsViewGroup;
public FlagPoleStateRenderer(Context context, LinearLayout upperFlagsViewGroup, LinearLayout lowerFlagsViewGroup) {
this.context = context;
this.upperFlagsViewGroup = upperFlagsViewGroup;
this.lowerFlagsViewGroup = lowerFlagsViewGroup;
}
public void render(FlagPoleState state) {
upperFlagsViewGroup.removeAllViews();
lowerFlagsViewGroup.removeAllViews();
for (FlagPole pole : state.getCurrentState()) {
int upperFlagResourceId = getFlagResourceId(pole.getUpperFlag());
//int lowerFlagResourceId = getFlagResourceId(pole.getLowerFlag());
if (pole.isDisplayed()) {
upperFlagsViewGroup.addView(createFlagImageView(upperFlagResourceId));
} else {
lowerFlagsViewGroup.addView(createFlagImageView(upperFlagResourceId));
}
}
/*FlagPoleState activeFlags = getRacingProcedure().getActiveFlags(startTime, MillisecondsTimePoint.now());
Flags startModeFlag = getRacingProcedure().getStartModeFlag();
boolean isClassFlagUp = false;
boolean isStartModeFlagUp = false;
for (FlagPole pole : activeFlags.getCurrentState()) {
if (pole.isDisplayed()) {
if (pole.getUpperFlag().equals(Flags.CLASS)) {
isClassFlagUp = true;
} else if (pole.getUpperFlag().equals(startModeFlag)) {
isStartModeFlagUp = true;
}
}
}
if (isClassFlagUp) {
upperFlagsViewGroup.addView(classFlagImageView);
} else {
lowerFlagsViewGroup.addView(classFlagImageView);
}
if (isStartModeFlagUp) {
upperFlagsViewGroup.addView(startModeFlagImageView);
} else {
lowerFlagsViewGroup.addView(startModeFlagImageView);
}*/
}
private ImageView createFlagImageView(int flagDrawableId) {
ImageView flagView = new ImageView(context);
flagView.setLayoutParams(new LinearLayout.LayoutParams(200, 130));
flagView.setImageResource(flagDrawableId);
return flagView;
}
private int getFlagResourceId(Flags upperFlag) {
return R.drawable.india_flag_mini;
}
/*
private int getStartModeImageResourceId() {
switch (getRacingProcedure().getStartModeFlag()) {
case PAPA:
return R.drawable.papa_flag_mini;
case INDIA:
return R.drawable.india_flag_mini;
case BLACK:
return R.drawable.black_flag_mini;
case ZULU:
return R.drawable.zulu_flag_mini;
default:
return R.drawable.papa_flag_mini;
}
private int getClassmageResourceId() {
// TODO: check boat class for specific image
return R.drawable.generic_class;
}
private int getFleetColorId() {
Triple<Integer, Integer, Integer> rgb = getRace().getFleet().getColor().getAsRGB();
int color = Color.rgb(rgb.getA(), rgb.getB(), rgb.getC());
return color;
}
}*/
}
@@ -7,6 +7,7 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.sap.sailing.domain.common.TimePoint;
@@ -17,6 +18,7 @@ import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.AbortTypeSelectionDialog;
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.RaceDialogFragment;
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.BaseRaceInfoRaceFragment;
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.FlagPoleStateRenderer;
import com.sap.sailing.racecommittee.app.utils.TimeUtils;
public abstract class BaseRunningRaceFragment<ProcedureType extends RacingProcedure> extends BaseRaceInfoRaceFragment<ProcedureType> {
@@ -28,8 +30,7 @@ public abstract class BaseRunningRaceFragment<ProcedureType extends RacingProced
private TextView startCountUpTextView;
private TextView nextCountdownTextView;
protected ViewGroup upperFlagsViewGroup;
protected ViewGroup lowerFlagsViewGroup;
private FlagPoleStateRenderer flagRenderer;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -47,9 +48,6 @@ public abstract class BaseRunningRaceFragment<ProcedureType extends RacingProced
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
upperFlagsViewGroup = (ViewGroup) getView().findViewById(R.id.race_running_base_up_flags);
lowerFlagsViewGroup = (ViewGroup) getView().findViewById(R.id.race_running_base_down_flags);
startCountUpTextView = (TextView) getView().findViewById(R.id.race_running_base_start_countup);
nextCountdownTextView = (TextView) getView().findViewById(R.id.race_running_base_next_countdown);
abortButton = (ImageButton) getView().findViewById(R.id.race_running_base_abort);
@@ -98,6 +96,10 @@ public abstract class BaseRunningRaceFragment<ProcedureType extends RacingProced
fragment.show(getFragmentManager(), "dialogAPNovemberMode");
}
});
flagRenderer = new FlagPoleStateRenderer(getActivity(),
(LinearLayout) getView().findViewById(R.id.race_running_base_up_flags),
(LinearLayout) getView().findViewById(R.id.race_running_base_down_flags));
}
@Override
@@ -137,5 +139,13 @@ public abstract class BaseRunningRaceFragment<ProcedureType extends RacingProced
protected int getActionsLayoutId() {
return 0;
}
@Override
protected void setupUi() {
TimePoint startTime = getRaceState().getStartTime();
if (startTime != null) {
flagRenderer.render(getRacingProcedure().getActiveFlags(startTime, MillisecondsTimePoint.now()));
}
}
}
@@ -4,9 +4,4 @@ import com.sap.sailing.domain.racelog.state.racingprocedure.ESSRacingProcedure;
public class ESSRunningRaceFragment extends BaseRunningRaceFragment<ESSRacingProcedure> {
@Override
protected void setupUi() {
// nothing here
}
}
@@ -26,11 +26,6 @@ public class GateStartRunningRaceFragment extends BaseRunningRaceFragment<GateSt
super.onStop();
}
@Override
protected void setupUi() {
// TODO: display all the flags!
}
private class ChangeListener extends BaseRacingProcedureChangedListener implements GateStartChangedListener {
@Override
@@ -27,11 +27,6 @@ public class RRS26RunningRaceFragment extends BaseRunningRaceFragment<RRS26Racin
super.onStop();
}
@Override
protected void setupUi() {
// TODO: display all the flags!
}
private class ChangeListener extends BaseRacingProcedureChangedListener implements RRS26ChangedListener {
@Override
@@ -8,6 +8,7 @@ import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.sap.sailing.domain.common.TimePoint;
@@ -20,6 +21,7 @@ import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.AbortModeSelectionDialog;
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.RaceDialogFragment;
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.BaseRaceInfoRaceFragment;
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.FlagPoleStateRenderer;
import com.sap.sailing.racecommittee.app.utils.TimeUtils;
public abstract class BaseStartphaseRaceFragment<ProcedureType extends RacingProcedure> extends BaseRaceInfoRaceFragment<ProcedureType> {
@@ -29,8 +31,7 @@ public abstract class BaseStartphaseRaceFragment<ProcedureType extends RacingPro
private Button resetTimeButton;
private TextView nextCountdownTextView;
protected ViewGroup upperFlagsViewGroup;
protected ViewGroup lowerFlagsViewGroup;
private FlagPoleStateRenderer flagRenderer;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -70,8 +71,9 @@ public abstract class BaseStartphaseRaceFragment<ProcedureType extends RacingPro
}
});
upperFlagsViewGroup = (ViewGroup) getView().findViewById(R.id.race_startphase_base_up_flags);
lowerFlagsViewGroup = (ViewGroup) getView().findViewById(R.id.race_startphase_base_down_flags);
flagRenderer = new FlagPoleStateRenderer(getActivity(),
(LinearLayout) getView().findViewById(R.id.race_startphase_base_up_flags),
(LinearLayout) getView().findViewById(R.id.race_startphase_base_down_flags));
}
@Override
@@ -98,5 +100,13 @@ public abstract class BaseStartphaseRaceFragment<ProcedureType extends RacingPro
protected int getActionsLayoutId() {
return 0;
}
@Override
protected void setupUi() {
TimePoint startTime = getRaceState().getStartTime();
if (startTime != null) {
flagRenderer.render(getRacingProcedure().getActiveFlags(startTime, MillisecondsTimePoint.now()));
}
}
}
@@ -1,66 +1,7 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.startphase;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.racelog.FlagPole;
import com.sap.sailing.domain.racelog.state.racingprocedure.ESSRacingProcedure;
import com.sap.sailing.domain.racelog.state.racingprocedure.FlagPoleState;
import com.sap.sailing.racecommittee.app.R;
public class ESSStartphaseRaceFragment extends BaseStartphaseRaceFragment<ESSRacingProcedure> {
private ImageView apFlagImageView;
private ImageView threeFlagImageView;
private ImageView twoFlagImageView;
private ImageView oneFlagImageView;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
apFlagImageView = createFlagImageView(R.drawable.ap_flag);
threeFlagImageView = createFlagImageView(R.drawable.three_min_flag);
twoFlagImageView = createFlagImageView(R.drawable.two_min_flag);
oneFlagImageView = createFlagImageView(R.drawable.one_min_flag);
}
@Override
protected void setupUi() {
lowerFlagsViewGroup.removeAllViews();
upperFlagsViewGroup.removeAllViews();
TimePoint startTime = getRaceState().getStartTime();
if (startTime == null) {
return;
}
FlagPoleState activeFlags = getRacingProcedure().getActiveFlags(startTime, MillisecondsTimePoint.now());
for (FlagPole pole : activeFlags.getCurrentState()) {
addFlagViews(pole, pole.isDisplayed() ? upperFlagsViewGroup : lowerFlagsViewGroup);
}
}
private void addFlagViews(FlagPole pole, ViewGroup container) {
switch (pole.getUpperFlag()) {
case AP:
container.addView(apFlagImageView);;
break;
case ESSTHREE:
container.addView(threeFlagImageView);
break;
case ESSTWO:
container.addView(twoFlagImageView);
break;
case ESSONE:
container.addView(oneFlagImageView);
break;
default:
break;
}
}
}
@@ -57,10 +57,8 @@ public class GateStartStartphaseRaceFragment extends BaseStartphaseRaceFragment<
@Override
protected void setupUi() {
lowerFlagsViewGroup.removeAllViews();
upperFlagsViewGroup.removeAllViews();
// TODO: work to dooo!
// TODO: gate time and pathfinder ui update
super.setupUi();
}
private class ChangeListener extends BaseRacingProcedureChangedListener implements GateStartChangedListener {
@@ -1,19 +1,10 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.startphase;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.common.racelog.FlagPole;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.racelog.state.racingprocedure.FlagPoleState;
import com.sap.sailing.domain.racelog.state.racingprocedure.RRS26ChangedListener;
import com.sap.sailing.domain.racelog.state.racingprocedure.RRS26RacingProcedure;
import com.sap.sailing.domain.racelog.state.racingprocedure.impl.BaseRacingProcedureChangedListener;
@@ -26,9 +17,6 @@ public class RRS26StartphaseRaceFragment extends BaseStartphaseRaceFragment<RRS2
private ImageButton startModeButton;
private final ChangeListener changeListener;
private ImageView classFlagImageView;
private ImageView startModeFlagImageView;
public RRS26StartphaseRaceFragment() {
this.changeListener = new ChangeListener();
}
@@ -46,13 +34,11 @@ public class RRS26StartphaseRaceFragment extends BaseStartphaseRaceFragment<RRS2
}
});
classFlagImageView = new ImageView(getActivity());
/*classFlagImageView = new ImageView(getActivity());
classFlagImageView.setLayoutParams(new LinearLayout.LayoutParams(200, 130));
classFlagImageView.setImageResource(getClassmageResourceId());
classFlagImageView.setPadding(6, 6, 6, 6);
classFlagImageView.setBackgroundColor(getFleetColorId());
startModeFlagImageView = createFlagImageView(getStartModeImageResourceId());
classFlagImageView.setBackgroundColor(getFleetColorId());*/
}
@Override
@@ -75,69 +61,8 @@ public class RRS26StartphaseRaceFragment extends BaseStartphaseRaceFragment<RRS2
@Override
protected void setupUi() {
lowerFlagsViewGroup.removeAllViews();
upperFlagsViewGroup.removeAllViews();
TimePoint startTime = getRaceState().getStartTime();
if (startTime == null) {
return;
}
startModeFlagImageView.setImageResource(getStartModeImageResourceId());
FlagPoleState activeFlags = getRacingProcedure().getActiveFlags(startTime, MillisecondsTimePoint.now());
Flags startModeFlag = getRacingProcedure().getStartModeFlag();
boolean isClassFlagUp = false;
boolean isStartModeFlagUp = false;
for (FlagPole pole : activeFlags.getCurrentState()) {
if (pole.isDisplayed()) {
if (pole.getUpperFlag().equals(Flags.CLASS)) {
isClassFlagUp = true;
} else if (pole.getUpperFlag().equals(startModeFlag)) {
isStartModeFlagUp = true;
}
}
}
if (isClassFlagUp) {
upperFlagsViewGroup.addView(classFlagImageView);
} else {
lowerFlagsViewGroup.addView(classFlagImageView);
}
if (isStartModeFlagUp) {
upperFlagsViewGroup.addView(startModeFlagImageView);
} else {
lowerFlagsViewGroup.addView(startModeFlagImageView);
}
startModeButton.setEnabled(!isStartModeFlagUp);
}
private int getStartModeImageResourceId() {
switch (getRacingProcedure().getStartModeFlag()) {
case PAPA:
return R.drawable.papa_flag;
case INDIA:
return R.drawable.india_flag;
case BLACK:
return R.drawable.black_flag;
case ZULU:
return R.drawable.zulu_flag;
default:
return R.drawable.papa_flag;
}
}
private int getClassmageResourceId() {
// TODO: check boat class for specific image
return R.drawable.generic_class;
}
private int getFleetColorId() {
Triple<Integer, Integer, Integer> rgb = getRace().getFleet().getColor().getAsRGB();
int color = Color.rgb(rgb.getA(), rgb.getB(), rgb.getC());
return color;
// TODO: Maybe check for something like getRacingProcedure().isStartmodeFlagUp()
super.setupUi();
}
private class ChangeListener extends BaseRacingProcedureChangedListener implements RRS26ChangedListener {