diff --git a/java/com.sap.sailing.gwt.ui/RaceBoard.css b/java/com.sap.sailing.gwt.ui/RaceBoard.css index e043d8b18c3..8a338aa74d2 100644 --- a/java/com.sap.sailing.gwt.ui/RaceBoard.css +++ b/java/com.sap.sailing.gwt.ui/RaceBoard.css @@ -157,7 +157,7 @@ input.magnifier { -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; - padding: 10px; + padding: 10px 10px 0; border: 1px solid #a6a6a6; } @@ -261,7 +261,7 @@ input.magnifier { .collapsablePanel-toolbar a { display: block; - padding: 14px; + padding: 9px; } @@ -291,6 +291,7 @@ input.magnifier { } .timePanel-controls { + margin: 7px 0 0 0; } .timePanel-controls-play { diff --git a/java/com.sap.sailing.gwt.ui/RaceBoard.html b/java/com.sap.sailing.gwt.ui/RaceBoard.html index 7fc9059b35e..e5bdac1c9cd 100644 --- a/java/com.sap.sailing.gwt.ui/RaceBoard.html +++ b/java/com.sap.sailing.gwt.ui/RaceBoard.html @@ -4,7 +4,7 @@ SAP Sailing Analytics Race Board - + diff --git a/java/com.sap.sailing.gwt.ui/Spectator.css b/java/com.sap.sailing.gwt.ui/Spectator.css index 66fb66e9ac6..4a03e1e525f 100644 --- a/java/com.sap.sailing.gwt.ui/Spectator.css +++ b/java/com.sap.sailing.gwt.ui/Spectator.css @@ -215,7 +215,7 @@ input.magnifier { font-size: 24px; text-transform: uppercase; color: #a1a1a1; - font-weight: 200; + font-weight: 400; } .raceBoardNavigation { @@ -257,26 +257,30 @@ input.magnifier { .leaderboardGroupPanel-LeaderboardsTableLabel { margin: 0 13px 10px; font-size: 17px; - font-weight: 200; + font-weight: 500; } .leaderboardGroupPanel-ActiveRace, .leaderboardGroupPanel-ActiveLeaderboard { - padding: 3px 8px 5px; + padding: 5px 8px; display: block; float: left; margin: 5px 5px 5px 0; border-radius: 4px; - background: url("images/spectator-table-bg.png") repeat-x 0 0 #e7e7e7; + background: url("images/btn-cta-orangeleft.png") repeat-x -10px 0 #e7e7e7; text-decoration: none; - color: #3b3b3b; - border: 1px solid #a6a6a6; + color: #fff; + /*border: 1px solid #a6a6a6;*/ +} + +.leaderboardGroupPanel-ActiveRace:visited, .leaderboardGroupPanel-ActiveLeaderboard:visited{ + color: #fff; } .leaderboardGroupPanel-ActiveRace:hover, .leaderboardGroupPanel-ActiveLeaderboard:hover { text-decoration: none; color: #fff; - background: #f1af10; - border: 1px solid #f1af10; + background: url("images/btn-cta-orangeleft.png") repeat-x -10px -30px #e7e7e7; + /*border: 1px solid #f1af10;*/ } .leaderboardGroupPanel-ActiveRace { @@ -311,7 +315,6 @@ input.magnifier { .welcomeWidget-WelcomeText { font-weight: 400; line-height: 1.6; - text-shadow: 0 0 2px #a4a1a1; } .breadcrumbPanel-NextArrow { diff --git a/java/com.sap.sailing.gwt.ui/Spectator.html b/java/com.sap.sailing.gwt.ui/Spectator.html index 0915fc6d9bf..6aa2ad4f985 100644 --- a/java/com.sap.sailing.gwt.ui/Spectator.html +++ b/java/com.sap.sailing.gwt.ui/Spectator.html @@ -8,7 +8,8 @@ - + + diff --git a/java/com.sap.sailing.gwt.ui/images/btn-cta-orangeleft.png b/java/com.sap.sailing.gwt.ui/images/btn-cta-orangeleft.png new file mode 100644 index 00000000000..f92cbec65c9 Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/images/btn-cta-orangeleft.png differ diff --git a/java/com.sap.sailing.gwt.ui/images/sap-sailing-app-icon.png b/java/com.sap.sailing.gwt.ui/images/sap-sailing-app-icon.png index 6aee00964b3..9ad08955f9f 100644 Binary files a/java/com.sap.sailing.gwt.ui/images/sap-sailing-app-icon.png and b/java/com.sap.sailing.gwt.ui/images/sap-sailing-app-icon.png differ diff --git a/java/com.sap.sailing.gwt.ui/images/timeslider-bg.png b/java/com.sap.sailing.gwt.ui/images/timeslider-bg.png index 6d4aad8e122..c4474987a4a 100644 Binary files a/java/com.sap.sailing.gwt.ui/images/timeslider-bg.png and b/java/com.sap.sailing.gwt.ui/images/timeslider-bg.png differ diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LatLngBoundsCalculaterForSelected.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LatLngBoundsCalculaterForSelected.java new file mode 100644 index 00000000000..1a8317be4d6 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LatLngBoundsCalculaterForSelected.java @@ -0,0 +1,15 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +public abstract class LatLngBoundsCalculaterForSelected implements LatLngBoundsCalculator { + + private boolean zoomOnlyToSelectedCompetitors; + + public void setZoomOnlyToSelectedCompetitors(boolean zoomOnlyToSelectedCompetitors) { + this.zoomOnlyToSelectedCompetitors = zoomOnlyToSelectedCompetitors; + } + + public boolean isZoomOnlyToSelectedCompetitors() { + return zoomOnlyToSelectedCompetitors; + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LatLngBoundsCalculator.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LatLngBoundsCalculator.java new file mode 100644 index 00000000000..9873b9cb650 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LatLngBoundsCalculator.java @@ -0,0 +1,9 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +import com.google.gwt.maps.client.geom.LatLngBounds; + +public interface LatLngBoundsCalculator { + + public LatLngBounds calculateNewBounds(RaceMap forMap); + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMap.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMap.java index c7dd9580460..85a2181c873 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMap.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMap.java @@ -44,7 +44,7 @@ import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.Tack; import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util.Triple; -import com.sap.sailing.gwt.ui.adminconsole.RaceMapSettings.ZoomSettings; +import com.sap.sailing.gwt.ui.adminconsole.RaceMapZoomSettings.ZoomTypes; import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener; import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider; import com.sap.sailing.gwt.ui.client.ErrorReporter; @@ -286,14 +286,14 @@ public class RaceMap implements TimeListener, CompetitorSelectionChangeListener, showMarksOnMap(markData); //Rezoom the map - if (getSettings().getZoomSetting() != ZoomSettings.MANUAL) { //Auto zoom if setting is not manual - zoomMapToNewBounds(getNewMapBounds(getCompetitorsToShow(), buoyMarkers.keySet())); + if (!getSettings().getZoomSettings().contains(ZoomTypes.NONE)) { //Auto zoom if setting is not manual + zoomMapToNewBounds(getSettings().getZoomSettings().getNewBounds(RaceMap.this)); mapFirstZoomDone = true; } else if (!mapZoomedOrPannedSinceLastRaceSelectionChange) { //Zoom once to the boats - zoomMapToNewBounds(getBoundsForBoats(getCompetitorsToShow())); + zoomMapToNewBounds(new BoatsBoundsCalculater().calculateNewBounds(RaceMap.this)); mapFirstZoomDone = true; } else if (!mapZoomedOrPannedSinceLastRaceSelectionChange && !mapFirstZoomDone) { //Zoom once to the buoys - zoomMapToNewBounds(getBoundsForMarks(buoyMarkers.keySet())); + zoomMapToNewBounds(new BuoysBoundsCalculater().calculateNewBounds(RaceMap.this)); mapFirstZoomDone = true; /* * Reset the mapZoomedOrPannedSinceLastRaceSelection: In spite of the fact that the map was just zoomed @@ -473,79 +473,79 @@ public class RaceMap implements TimeListener, CompetitorSelectionChangeListener, } /** - * Calculates the new map bounds for the given data considering the current {@link ZoomSettings} of the map. + * Calculates the new map bounds for the given data considering the current {@link ZoomTypes} of the map. * @return The new map bounds */ - private LatLngBounds getNewMapBounds(Iterable competitorsToZoom, Iterable marksToZoom) { - LatLngBounds newBounds = null; - if (getSettings().getZoomSetting() != ZoomSettings.MANUAL) { - //Extend bounds for the boats - if (getSettings().getZoomSetting() == ZoomSettings.ZOOM_TO_BOATS - || getSettings().getZoomSetting() == ZoomSettings.ZOOM_TO_BOATS_AND_BUOYS) { - LatLngBounds boatBounds = getBoundsForBoats(competitorsToZoom); - if (boatBounds != null) { - newBounds = boatBounds; - } - } - //Extend bounds for the marks - if (getSettings().getZoomSetting() == ZoomSettings.ZOOM_TO_BUOYS - || getSettings().getZoomSetting() == ZoomSettings.ZOOM_TO_BOATS_AND_BUOYS) { - LatLngBounds markBounds = getBoundsForMarks(marksToZoom); - if (markBounds != null) { - if (newBounds == null) { - newBounds = markBounds; - } else { - newBounds.extend(markBounds.getNorthEast()); - newBounds.extend(markBounds.getSouthWest()); - } - } - } - } - return newBounds; - } +// private LatLngBounds getNewMapBounds(Iterable competitorsToZoom, Iterable marksToZoom) { +// LatLngBounds newBounds = null; +// if (getSettings().getZoomSetting() != ZoomTypes.MANUAL) { +// //Extend bounds for the boats +// if (getSettings().getZoomSetting() == ZoomTypes.ZOOM_TO_BOATS +// || getSettings().getZoomSetting() == ZoomTypes.ZOOM_TO_BOATS_AND_BUOYS) { +// LatLngBounds boatBounds = getBoundsForBoats(competitorsToZoom); +// if (boatBounds != null) { +// newBounds = boatBounds; +// } +// } +// //Extend bounds for the marks +// if (getSettings().getZoomSetting() == ZoomTypes.ZOOM_TO_BUOYS +// || getSettings().getZoomSetting() == ZoomTypes.ZOOM_TO_BOATS_AND_BUOYS) { +// LatLngBounds markBounds = getBoundsForMarks(marksToZoom); +// if (markBounds != null) { +// if (newBounds == null) { +// newBounds = markBounds; +// } else { +// newBounds.extend(markBounds.getNorthEast()); +// newBounds.extend(markBounds.getSouthWest()); +// } +// } +// } +// } +// return newBounds; +// } - private LatLngBounds getBoundsForBoats(Iterable competitorsToZoom) { - LatLngBounds newBounds = null; - for (CompetitorDTO competitorDTO : competitorsToZoom) { - LatLngBounds bounds = null; - if (getSettings().isIncludeTailsToAutoZoom()) { - Polyline tail = tails.get(competitorDTO); - bounds = tail != null ? tail.getBounds() : null; - } else { - List competitorFixes = fixes.get(competitorDTO); - GPSFixDTO competitorFix = competitorFixes != null ? competitorFixes.get(competitorFixes.size() - 1) : null; - PositionDTO competitorPosition = competitorFix != null ? competitorFix.position : null; - LatLng competitorLatLng = competitorPosition != null ? LatLng.newInstance(competitorPosition.latDeg, competitorPosition.lngDeg) : null; - bounds = competitorLatLng != null ? LatLngBounds.newInstance(competitorLatLng, competitorLatLng) : null; - } - if (bounds != null) { - if (newBounds == null) { - newBounds = bounds; - } else { - newBounds.extend(bounds.getNorthEast()); - newBounds.extend(bounds.getSouthWest()); - } - } - } - return newBounds; - } +// private LatLngBounds getBoundsForBoats(Iterable competitorsToZoom) { +// LatLngBounds newBounds = null; +// for (CompetitorDTO competitorDTO : competitorsToZoom) { +// LatLngBounds bounds = null; +// if (getSettings().isIncludeTailsToAutoZoom()) { +// Polyline tail = tails.get(competitorDTO); +// bounds = tail != null ? tail.getBounds() : null; +// } else { +// List competitorFixes = fixes.get(competitorDTO); +// GPSFixDTO competitorFix = competitorFixes != null ? competitorFixes.get(competitorFixes.size() - 1) : null; +// PositionDTO competitorPosition = competitorFix != null ? competitorFix.position : null; +// LatLng competitorLatLng = competitorPosition != null ? LatLng.newInstance(competitorPosition.latDeg, competitorPosition.lngDeg) : null; +// bounds = competitorLatLng != null ? LatLngBounds.newInstance(competitorLatLng, competitorLatLng) : null; +// } +// if (bounds != null) { +// if (newBounds == null) { +// newBounds = bounds; +// } else { +// newBounds.extend(bounds.getNorthEast()); +// newBounds.extend(bounds.getSouthWest()); +// } +// } +// } +// return newBounds; +// } - private LatLngBounds getBoundsForMarks(Iterable marksToZoom) { - LatLngBounds newBounds = null; - if (marksToZoom != null) { - for (MarkDTO markDTO : marksToZoom) { - LatLng markLatLng = LatLng.newInstance(markDTO.position.latDeg, markDTO.position.lngDeg); - LatLngBounds bounds = LatLngBounds.newInstance(markLatLng, markLatLng); - if (newBounds == null) { - newBounds = bounds; - } else { - newBounds.extend(bounds.getNorthEast()); - newBounds.extend(bounds.getSouthWest()); - } - } - } - return newBounds; - } +// private LatLngBounds getBoundsForMarks(Iterable marksToZoom) { +// LatLngBounds newBounds = null; +// if (marksToZoom != null) { +// for (MarkDTO markDTO : marksToZoom) { +// LatLng markLatLng = LatLng.newInstance(markDTO.position.latDeg, markDTO.position.lngDeg); +// LatLngBounds bounds = LatLngBounds.newInstance(markLatLng, markLatLng); +// if (newBounds == null) { +// newBounds = bounds; +// } else { +// newBounds.extend(bounds.getNorthEast()); +// newBounds.extend(bounds.getSouthWest()); +// } +// } +// } +// return newBounds; +// } private boolean updateMarkerForCompetitor(CompetitorDTO competitorDTO) { boolean usedExistingMarker = false; @@ -1100,11 +1100,89 @@ public class RaceMap implements TimeListener, CompetitorSelectionChangeListener, getSettings().setShowOnlySelectedCompetitors(newSettings.isShowOnlySelectedCompetitors()); redraw(); } - if (newSettings.getZoomSetting() != getSettings().getZoomSetting() - || newSettings.isIncludeTailsToAutoZoom() != getSettings().isIncludeTailsToAutoZoom()) { - getSettings().setZoomSetting(newSettings.getZoomSetting()); - getSettings().setIncludeTailsToAutoZoom(newSettings.isIncludeTailsToAutoZoom()); - zoomMapToNewBounds(getNewMapBounds(getCompetitorsToShow(), buoyMarkers.keySet())); + if (!newSettings.getZoomSettings().equals(getSettings().getZoomSettings())) { + getSettings().setZoomSettings(newSettings.getZoomSettings()); + zoomMapToNewBounds(getSettings().getZoomSettings().getNewBounds(this)); } } + + public static class BoatsBoundsCalculater extends LatLngBoundsCalculaterForSelected { + + @Override + public LatLngBounds calculateNewBounds(RaceMap forMap) { + LatLngBounds newBounds = null; + Iterable selectedCompetitors = forMap.competitorSelection.getSelectedCompetitors(); + Iterable competitors = new ArrayList(); + if (selectedCompetitors == null || !selectedCompetitors.iterator().hasNext()) { + competitors = forMap.getCompetitorsToShow(); + } else { + competitors = isZoomOnlyToSelectedCompetitors() ? selectedCompetitors : forMap.getCompetitorsToShow(); + } + for (CompetitorDTO competitor : competitors) { + List competitorFixes = forMap.fixes.get(competitor); + GPSFixDTO competitorFix = competitorFixes != null ? competitorFixes.get(competitorFixes.size() - 1) : null; + PositionDTO competitorPosition = competitorFix != null ? competitorFix.position : null; + LatLng competitorLatLng = competitorPosition != null ? LatLng.newInstance(competitorPosition.latDeg, + competitorPosition.lngDeg) : null; + LatLngBounds bounds = competitorLatLng != null ? LatLngBounds.newInstance(competitorLatLng, + competitorLatLng) : null; + if (bounds != null) { + if (newBounds == null) { + newBounds = bounds; + } else { + newBounds.extend(bounds.getNorthEast()); + newBounds.extend(bounds.getSouthWest()); + } + } + } + return newBounds; + } + + } + + public static class TailsBoundsCalculater extends LatLngBoundsCalculaterForSelected { + + @Override + public LatLngBounds calculateNewBounds(RaceMap forMap) { + LatLngBounds newBounds = null; + Iterable competitors = isZoomOnlyToSelectedCompetitors() ? forMap.competitorSelection.getSelectedCompetitors() : forMap.getCompetitorsToShow(); + for (CompetitorDTO competitor : competitors) { + Polyline tail = forMap.tails.get(competitor); + LatLngBounds bounds = tail != null ? tail.getBounds() : null; + if (bounds != null) { + if (newBounds == null) { + newBounds = bounds; + } else { + newBounds.extend(bounds.getNorthEast()); + newBounds.extend(bounds.getSouthWest()); + } + } + } + return newBounds; + } + + } + + public static class BuoysBoundsCalculater implements LatLngBoundsCalculator { + + @Override + public LatLngBounds calculateNewBounds(RaceMap forMap) { + LatLngBounds newBounds = null; + Iterable marksToZoom = forMap.buoyMarkers.keySet(); + if (marksToZoom != null) { + for (MarkDTO markDTO : marksToZoom) { + LatLng markLatLng = LatLng.newInstance(markDTO.position.latDeg, markDTO.position.lngDeg); + LatLngBounds bounds = LatLngBounds.newInstance(markLatLng, markLatLng); + if (newBounds == null) { + newBounds = bounds; + } else { + newBounds.extend(bounds.getNorthEast()); + newBounds.extend(bounds.getSouthWest()); + } + } + } + return newBounds; + } + + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapSettings.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapSettings.java index 33908de16b2..a3fa55838bd 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapSettings.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapSettings.java @@ -6,7 +6,6 @@ import java.util.Set; import com.sap.sailing.domain.common.ManeuverType; public class RaceMapSettings { - public enum ZoomSettings{MANUAL, ZOOM_TO_BOATS, ZOOM_TO_BUOYS, ZOOM_TO_BOATS_AND_BUOYS} private boolean showDouglasPeuckerPoints = false; @@ -14,8 +13,7 @@ public class RaceMapSettings { private boolean showOnlySelectedCompetitors = true; - private ZoomSettings zoomSetting = ZoomSettings.MANUAL; - private boolean includeTailsToAutoZoom = false; + private RaceMapZoomSettings zoomSettings; private long tailLengthInMilliseconds = 30000l; @@ -25,6 +23,8 @@ public class RaceMapSettings { maneuverTypesToShow.add(ManeuverType.JIBE); maneuverTypesToShow.add(ManeuverType.PENALTY_CIRCLE); maneuverTypesToShow.add(ManeuverType.MARK_PASSING); + + this.zoomSettings = new RaceMapZoomSettings(); } public long getTailLengthInMilliseconds() { @@ -63,30 +63,12 @@ public class RaceMapSettings { this.showOnlySelectedCompetitors = showOnlySelectedCompetitors; } - public ZoomSettings getZoomSetting() { - return zoomSetting; + public RaceMapZoomSettings getZoomSettings() { + return zoomSettings; } - /** - * Sets the zoom settings. If zoomSetting is a setting which doesn't include the boats (e.g. - * MANUAL_ZOOM or ZOOM_TO_BUOYS), is the includeTailsToAutoZoom value set to - * false. - * - * @param zoomSetting The new zoom settings - */ - public void setZoomSetting(ZoomSettings zoomSetting) { - this.zoomSetting = zoomSetting; - if (zoomSetting == ZoomSettings.MANUAL || zoomSetting == ZoomSettings.ZOOM_TO_BUOYS) { - setIncludeTailsToAutoZoom(false); - } - } - - public boolean isIncludeTailsToAutoZoom() { - return includeTailsToAutoZoom; - } - - public void setIncludeTailsToAutoZoom(boolean includeTailsToAutoZoom) { - this.includeTailsToAutoZoom = includeTailsToAutoZoom; + public void setZoomSettings(RaceMapZoomSettings zoomSettings) { + this.zoomSettings = zoomSettings; } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapSettingsDialogComponent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapSettingsDialogComponent.java index 2b0041bf48f..479607b6542 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapSettingsDialogComponent.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapSettingsDialogComponent.java @@ -1,23 +1,20 @@ package com.sap.sailing.gwt.ui.adminconsole; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import com.google.gwt.event.dom.client.ChangeEvent; -import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.FocusWidget; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.LongBox; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.domain.common.ManeuverType; import com.sap.sailing.domain.common.impl.Util.Pair; -import com.sap.sailing.gwt.ui.adminconsole.RaceMapSettings.ZoomSettings; +import com.sap.sailing.gwt.ui.adminconsole.RaceMapZoomSettings.ZoomTypes; import com.sap.sailing.gwt.ui.client.DataEntryDialog; import com.sap.sailing.gwt.ui.client.DataEntryDialog.Validator; import com.sap.sailing.gwt.ui.client.ManeuverTypeFormatter; @@ -25,25 +22,23 @@ import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent; public class RaceMapSettingsDialogComponent implements SettingsDialogComponent { - private List> checkboxAndType; - private ListBox zoomSettingsBox; - private CheckBox includeTailsToAutoZoom; - private CheckBox checkBoxDouglasPeuckerPoints; - private CheckBox showOnlySelectedCompetitors; - private LongBox tailLengthBox; + //Initializing the lists to prevent a null pointer exception in the first validation call + private List> checkboxAndManeuverType = new ArrayList>(); + private List> checkboxAndZoomType = new ArrayList>(); + private CheckBox zoomOnlyToSelectedCompetitors = new CheckBox(); + private CheckBox checkBoxDouglasPeuckerPoints = new CheckBox(); + private CheckBox showOnlySelectedCompetitors = new CheckBox(); + private LongBox tailLengthBox = new LongBox(); + private final StringMessages stringMessages; private final RaceMapSettings initialSettings; - - private Map zoomSettingsMap; + + private ArrayList disableOnlySelectedWhenAreFalse; + private CheckBox autoZoomOffBox; public RaceMapSettingsDialogComponent(RaceMapSettings settings, StringMessages stringMessages) { this.stringMessages = stringMessages; initialSettings = settings; - zoomSettingsMap = new HashMap(); - zoomSettingsMap.put(stringMessages.autoZoomManual(), ZoomSettings.MANUAL); - zoomSettingsMap.put(stringMessages.autoZoomToBoats(), ZoomSettings.ZOOM_TO_BOATS); - zoomSettingsMap.put(stringMessages.autoZoomToBuoys(), ZoomSettings.ZOOM_TO_BUOYS); - zoomSettingsMap.put(stringMessages.autoZoomToBoatsAndBuoys(), ZoomSettings.ZOOM_TO_BOATS_AND_BUOYS); } @Override @@ -54,39 +49,48 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent(); + for (ZoomTypes zoomType : ZoomTypes.values()) { + CheckBox cb = dialog.createCheckbox(ZoomTypeFormatter.format(zoomType, stringMessages)); + cb.setValue(initialSettings.getZoomSettings().getTypesToConsiderOnZoom().contains(zoomType), true); + checkboxAndZoomType.add(new Pair(cb, zoomType)); + zoomSettingsBoxesPanel.add(cb); + + //Save specific checkboxes for easier value change handling + if (zoomType == ZoomTypes.BOATS || zoomType == ZoomTypes.TAILS) { + disableOnlySelectedWhenAreFalse.add(cb); + } else if (zoomType == ZoomTypes.NONE) { + autoZoomOffBox = cb; + } + cb.addValueChangeHandler(new ValueChangeHandler() { + @Override + public void onValueChange(ValueChangeEvent event) { + zoomSettingsChanged(); + } + }); + } + labelAndZoomSettingsPanel.add(zoomSettingsBoxesPanel); + vp.add(labelAndZoomSettingsPanel); + vp.add(zoomOnlyToSelectedCompetitors); + //Run zoomSettingsChanged to set the checkboxes to their correct state + zoomSettingsChanged(); showOnlySelectedCompetitors = dialog.createCheckbox(stringMessages.showOnlySelected()); showOnlySelectedCompetitors.setValue(initialSettings.isShowOnlySelectedCompetitors()); vp.add(showOnlySelectedCompetitors); vp.add(new Label(stringMessages.maneuverTypes())); - checkboxAndType = new ArrayList>(); for (ManeuverType maneuverType : ManeuverType.values()) { CheckBox checkbox = dialog.createCheckbox(ManeuverTypeFormatter.format(maneuverType, stringMessages)); checkbox.setValue(initialSettings.isShowManeuverType(maneuverType)); - checkboxAndType.add(new Pair(checkbox, maneuverType)); + checkboxAndManeuverType.add(new Pair(checkbox, maneuverType)); vp.add(checkbox); } checkBoxDouglasPeuckerPoints = dialog.createCheckbox(stringMessages.douglasPeuckerPoints()); @@ -95,44 +99,56 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent pair : checkboxAndZoomType) { + if (pair.getB() != ZoomTypes.NONE) { + pair.getA().setEnabled(!autoZoomOffBox.getValue()); + pair.getA().setValue(false); + } + } + zoomOnlyToSelectedCompetitors.setEnabled(false); + zoomOnlyToSelectedCompetitors.setValue(false); } else { - includeTailsToAutoZoom.setEnabled(true); - } - } - - private ZoomSettings getSelectedZoomSetting() { - return zoomSettingsMap.get(zoomSettingsBox.getItemText(zoomSettingsBox.getSelectedIndex())); - } - - private int getIndexOfZoomSettingInBox(ZoomSettings zoomSetting) { - int index = -1; - for (int i = 0; i < zoomSettingsBox.getItemCount(); i++) { - if (zoomSettingsMap.get(zoomSettingsBox.getItemText(i)) == zoomSetting) { - index = i; - break; + boolean disableOnlySelected = true; + for (Pair pair : checkboxAndZoomType) { + pair.getA().setEnabled(true); + if (disableOnlySelectedWhenAreFalse.contains(pair.getA())) { + if (pair.getA().getValue()) { + disableOnlySelected = false; + } + } + } + + zoomOnlyToSelectedCompetitors.setEnabled(!disableOnlySelected); + if (disableOnlySelected) { + zoomOnlyToSelectedCompetitors.setValue(false); } } - return index; } @Override public RaceMapSettings getResult() { RaceMapSettings result = new RaceMapSettings(); - for (Pair p : checkboxAndType) { + for (Pair p : checkboxAndManeuverType) { result.showManeuverType(p.getB(), p.getA().getValue()); } - result.setZoomSetting(getSelectedZoomSetting()); - result.setIncludeTailsToAutoZoom(includeTailsToAutoZoom.getValue()); + result.setZoomSettings(getZoomSettings()); result.setShowDouglasPeuckerPoints(checkBoxDouglasPeuckerPoints.getValue()); result.setShowOnlySelectedCompetitors(showOnlySelectedCompetitors.getValue()); result.setTailLengthInMilliseconds(tailLengthBox.getValue() == null ? -1 : tailLengthBox.getValue()*1000l); return result; } + + private RaceMapZoomSettings getZoomSettings() { + ArrayList zoomTypes = new ArrayList(); + for (Pair pair : checkboxAndZoomType) { + if (pair.getA().getValue()) { + zoomTypes.add(pair.getB()); + } + } + return new RaceMapZoomSettings(zoomTypes, zoomOnlyToSelectedCompetitors.getValue()); + } @Override public Validator getValidator() { @@ -143,6 +159,12 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent zoomTypesToValidate = valueToValidate.getZoomSettings().getTypesToConsiderOnZoom(); + if (zoomTypesToValidate == null || zoomTypesToValidate.size() <= 0) { + errorMessage = stringMessages.selectOneZoomType() + "."; + } + return errorMessage; } }; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapZoomSettings.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapZoomSettings.java new file mode 100644 index 00000000000..85b86fa8d87 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceMapZoomSettings.java @@ -0,0 +1,117 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.maps.client.geom.LatLngBounds; + +public class RaceMapZoomSettings { + + public enum ZoomTypes { + NONE(null), BOATS(new RaceMap.BoatsBoundsCalculater()), TAILS(new RaceMap.TailsBoundsCalculater()), BUOYS( + new RaceMap.BuoysBoundsCalculater()); + + private LatLngBoundsCalculator calculater; + + private ZoomTypes(LatLngBoundsCalculator calculator) { + this.calculater = calculator; + } + + public LatLngBounds calculateNewBounds(RaceMap forMap) { + return calculater != null ? calculater.calculateNewBounds(forMap) : null; + } + }; + + private ArrayList typesToConsiderOnZoom; + private boolean zoomToSelectedCompetitors; + + public RaceMapZoomSettings() { + typesToConsiderOnZoom = new ArrayList(); + typesToConsiderOnZoom.add(ZoomTypes.NONE); + zoomToSelectedCompetitors = false; + } + + public RaceMapZoomSettings(ArrayList typesToConsiderOnZoom, boolean zoomToSelected) { + this.typesToConsiderOnZoom = typesToConsiderOnZoom; + this.zoomToSelectedCompetitors = zoomToSelected; + } + + public LatLngBounds getNewBounds(RaceMap forMap) { + LatLngBounds newBounds = null; + if (typesToConsiderOnZoom != null) { + for (ZoomTypes type : typesToConsiderOnZoom) { + //Skip the calculation of the boat bounds, if the list contains TAILS. + //That's because the tails already contain the boats + if (type == ZoomTypes.BOATS && typesToConsiderOnZoom.contains(ZoomTypes.TAILS)) { + continue; + } + //Set the for selected attribute for the corresponding calculaters + if (type.calculater instanceof LatLngBoundsCalculaterForSelected) { + ((LatLngBoundsCalculaterForSelected) type.calculater) + .setZoomOnlyToSelectedCompetitors(zoomToSelectedCompetitors); + } + + //Calculate the new bounds and extend the result + LatLngBounds calculatedBounds = type.calculateNewBounds(forMap); + if (calculatedBounds != null) { + if (newBounds == null) { + newBounds = calculatedBounds; + } else { + newBounds.extend(calculatedBounds.getNorthEast()); + newBounds.extend(calculatedBounds.getSouthWest()); + } + } + } + } + return newBounds; + } + + public List getTypesToConsiderOnZoom() { + return typesToConsiderOnZoom; + } + + public void setTypesToConsiderOnZoom(List typesToConsiderOnZoom) { + this.typesToConsiderOnZoom = new ArrayList(typesToConsiderOnZoom); + } + + public void setZoomToSelectedCompetitors(boolean zoomToSelectedCompetitors) { + this.zoomToSelectedCompetitors = zoomToSelectedCompetitors; + } + + public boolean isZoomToSelectedCompetitors() { + return zoomToSelectedCompetitors; + } + + public boolean contains(ZoomTypes zoomType) { + return typesToConsiderOnZoom.contains(zoomType); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((typesToConsiderOnZoom == null) ? 0 : typesToConsiderOnZoom.hashCode()); + result = prime * result + (zoomToSelectedCompetitors ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RaceMapZoomSettings other = (RaceMapZoomSettings) obj; + if (typesToConsiderOnZoom == null) { + if (other.typesToConsiderOnZoom != null) + return false; + } else if (!typesToConsiderOnZoom.equals(other.typesToConsiderOnZoom)) + return false; + if (zoomToSelectedCompetitors != other.zoomToSelectedCompetitors) + return false; + return true; + } + +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ZoomTypeFormatter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ZoomTypeFormatter.java new file mode 100644 index 00000000000..db3fc6eaf6f --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/ZoomTypeFormatter.java @@ -0,0 +1,20 @@ +package com.sap.sailing.gwt.ui.adminconsole; + +import com.sap.sailing.gwt.ui.adminconsole.RaceMapZoomSettings.ZoomTypes; +import com.sap.sailing.gwt.ui.client.StringMessages; + +public class ZoomTypeFormatter { + public static String format(ZoomTypes zoomType, StringMessages stringConstants) { + switch (zoomType) { + case NONE: + return stringConstants.autoZoomOff(); + case BOATS: + return stringConstants.autoZoomToBoats(); + case TAILS: + return stringConstants.autoZoomTails(); + case BUOYS: + return stringConstants.autoZoomToBuoys(); + } + return null; + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 98af9f9cf7d..93b55a98c4e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -246,7 +246,8 @@ public interface StringMessages extends Messages { String autoZoomTo(); String autoZoomToBoats(); String autoZoomToBuoys(); - String autoZoomManual(); - String autoZoomToBoatsAndBuoys(); - String includeTailsToAutoZoom(); + String autoZoomOff(); + String autoZoomTails(); + String autoZoomSelectedCompetitors(); + String selectOneZoomType(); } \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 805143a3592..a7594cd52fa 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -241,6 +241,7 @@ allTimesInUTC=All times in UTC autoZoomTo=Auto zoom to autoZoomToBoats=Boats autoZoomToBuoys=Buoys -autoZoomManual=Off -autoZoomToBoatsAndBuoys=Boats and buoys -includeTailsToAutoZoom=Consider tails when zooming \ No newline at end of file +autoZoomOff=Off +autoZoomTails=Tails +selectOneZoomType=Please select at least one zoom type +autoZoomSelectedCompetitors=Zoom only to selected competitors diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index ab29bc6f2cf..b32502f1bd3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -242,6 +242,7 @@ allTimesInUTC=Alle Zeiten in UTC autoZoomTo=Auto-Zoom nach autoZoomToBoats=Booten autoZoomToBuoys=Tonnen -autoZoomManual=Aus -autoZoomToBoatsAndBuoys=Booten und Tonnen -includeTailsToAutoZoom=Schweif beim auto-zoomen beachten \ No newline at end of file +autoZoomOff=Aus +autoZoomTails=Schweife +selectOneZoomType=Bitte mindestens eine Zoom-Art auswählen +autoZoomSelectedCompetitors=Nur zu ausgewählten Seglern zoomen diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupFullTable.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupFullTable.css index afef0ab04c4..08555411dde 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupFullTable.css +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupFullTable.css @@ -10,7 +10,7 @@ .cellTableHeader { background: url(images/spectator-table-bg.png) 0 0 repeat-x !important; - text-transform: uppercase; + font-weight: 600; padding: 10px 15px; border: 1px solid #aeaeaf !important;