Merge remote-tracking branch 'origin/master' into newhome

This commit is contained in:
fmittag committed 2014-08-13 19:16:40 +02:00
commit 9635c95551
11 files changed
+151 -84

No files matched your search

@@ -9,7 +9,6 @@ import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.client.shared.footer.Footer;
import com.sap.sailing.gwt.home.client.shared.header.Header;
import com.sap.sailing.gwt.home.client.shared.placeholder.Placeholder;
/**
* This is the top-level view of the application. Every time another presenter wants to reveal itself,
@@ -33,9 +32,6 @@ public class TabletAndDesktopApplicationView extends Composite implements Applic
public TabletAndDesktopApplicationView(PlaceNavigator navigator) {
headerPanel = new Header(navigator);
initWidget(uiBinder.createAndBindUi(this));
Placeholder placeHolder = new Placeholder();
mainContentPanel.setWidget(placeHolder);
}
@Override
@@ -84,7 +84,7 @@ public class EventRegattaRacesRace extends UIObject {
setElement(uiBinder.createAndBindUi(this));
allConditionalElements = new Element[] {raceWinnerDiv, raceLeaderDiv, watchRaceDiv, analyzeRaceDiv, raceNotTrackedDiv,
raceFeaturesDiv, legProgressDiv, raceFlagDiv, windStatusDiv, currentLegNo, totalLegsCount };
raceFeaturesDiv, legProgressDiv, raceFlagDiv, windStatusDiv };
if(fleet.getColor() != null) {
fleetColor.getStyle().setBackgroundColor(fleet.getColor().getAsHtml());
@@ -149,14 +149,15 @@ public class EventRegattaRacesRace extends UIObject {
break;
case TRACKED_AND_LIVE:
showElement(watchRaceDiv);
showElement(legProgressDiv);
showElement(currentLegNo);
showElement(totalLegsCount);
raceTime.setInnerText(raceTimeFormat.format(race.startOfRace));
currentLegNo.setInnerText(String.valueOf(race.trackedRaceStatistics.currentLegNo));
totalLegsCount.setInnerText(String.valueOf(race.trackedRaceStatistics.totalLegsCount));
if(race.startOfRace != null) {
raceTime.setInnerText(raceTimeFormat.format(race.startOfRace));
}
if(race.trackedRaceStatistics.hasLegProgressData) {
showElement(legProgressDiv);
currentLegNo.setInnerText(String.valueOf(race.trackedRaceStatistics.currentLegNo));
totalLegsCount.setInnerText(String.valueOf(race.trackedRaceStatistics.totalLegsCount));
}
if(race.trackedRaceStatistics.hasLeaderData && race.trackedRaceStatistics.leaderOrWinner != null) {
showElement(raceLeaderDiv);
updateWinnerOrLeader(raceLeader, race.trackedRaceStatistics.leaderOrWinner);
@@ -170,9 +171,10 @@ public class EventRegattaRacesRace extends UIObject {
showElement(raceWinnerDiv);
updateWinnerOrLeader(raceWinner, race.trackedRaceStatistics.leaderOrWinner);
}
if(race.startOfRace != null) {
raceTime.setInnerText(raceTimeFormat.format(race.startOfRace));
}
showElement(raceFeaturesDiv);
raceTime.setInnerText(raceTimeFormat.format(race.startOfRace));
updateRaceFeatures();
break;
@@ -27,7 +27,7 @@
<div ui:field="raceLeaderDiv" class="{local_res.css.eventregattarace_details} {local_res.css.eventregattarace_leader}">
<ui:text from="{i18n.eventRegattaRaceLeader}"/><br></br><span ui:field="raceLeader" class="{local_res.css.eventregattarace_leader_name}"></span>
</div>
<div ui:field="legProgressDiv" class="{local_res.css.eventregattarace_details} {local_res.css.eventregattarace_legs}"><ui:text from='{i18n.leg}'/>&nbps;<span ui:field="currentLegNo" />/<span ui:field="totalLegsCount" />
<div ui:field="legProgressDiv" class="{local_res.css.eventregattarace_details} {local_res.css.eventregattarace_legs}"><ui:text from='{i18n.leg}'/>&nbsp;<span ui:field="currentLegNo" />/<span ui:field="totalLegsCount" />
<div class="{local_res.css.eventregattarace_legs_list}">
<div data-status="r" class="{local_res.css.eventregattarace_legs_leg}"></div>
</div>
@@ -67,22 +67,23 @@ public class Stage extends Composite {
stageTeaserComposites.add(stageTeaser);
}
this.swiper = Swiper.createWithoutLoopOption(StageResources.INSTANCE.css().stage_teasers(),
StageResources.INSTANCE.css().swiperwrapper(),
StageResources.INSTANCE.css().swiperslide(), new Swiper.PageChangeListener() {
@Override
public void pageChanged(int newPageIndex, int pageCount) {
boolean isFirstSlide = newPageIndex == 0;
boolean isLastSlide = newPageIndex == pageCount - 1;
nextStageTeaserLink.setVisible(!isLastSlide);
prevStageTeaserLink.setVisible(!isFirstSlide);
}
});
if (featuredEvents.size() <= 1) {
prevStageTeaserLink.setVisible(false);
nextStageTeaserLink.setVisible(false);
} else {
swiper = Swiper.createWithoutLoopOption(StageResources.INSTANCE.css().stage_teasers(),
StageResources.INSTANCE.css().swiperwrapper(),
StageResources.INSTANCE.css().swiperslide(), new Swiper.PageChangeListener() {
@Override
public void pageChanged(int newPageIndex, int pageCount) {
boolean isFirstSlide = newPageIndex == 0;
boolean isLastSlide = newPageIndex == pageCount - 1;
nextStageTeaserLink.setVisible(!isLastSlide);
prevStageTeaserLink.setVisible(!isFirstSlide);
}
});
prevStageTeaserLink.setVisible(false);
}
}
@@ -278,13 +278,13 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
/**
* The map bounds as last received by map callbacks; used to determine whether to suppress the boat animation during zoom/pan
*/
private LatLngBounds currentMapBounds;
private LatLngBounds currentMapBounds; // bounds to which bounds-changed-handler compares
private int currentZoomLevel; // zoom-level to which bounds-changed-handler compares
private int currentZoomLevel;
private boolean autoZoomIn = false;
private boolean autoZoomOut = false;
private int autoZoomLevel;
LatLngBounds autoZoomLatLngBounds;
private boolean autoZoomIn = false; // flags auto-zoom-in in progress
private boolean autoZoomOut = false; // flags auto-zoom-out in progress
private int autoZoomLevel; // zoom-level to which auto-zoom-in/-out is zooming
LatLngBounds autoZoomLatLngBounds; // bounds to which auto-zoom-in/-out is panning&zooming
private WindStreamletsRaceboardOverlay streamletOverlay;
private final boolean showViewStreamlets;
@@ -385,6 +385,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
@Override
public void onEvent(DragEndMapEvent event) {
// stop automatic zoom after a manual drag event
autoZoomIn = false;
autoZoomOut = false;
final List<RaceMapZoomSettings.ZoomTypes> emptyList = Collections.emptyList();
settings.getZoomSettings().setTypesToConsiderOnZoom(emptyList);
}
@@ -392,11 +394,14 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
map.addIdleHandler(new IdleMapHandler() {
@Override
public void onEvent(IdleMapEvent event) {
// the "idle"-event is raised at the end of map-animations
if (autoZoomIn) {
// finalize zoom-in that was started with panTo() in zoomMapToNewBounds()
map.setZoom(autoZoomLevel);
autoZoomIn = false;
}
if (autoZoomOut) {
// finalize zoom-out that was started with setZoom() in zoomMapToNewBounds()
map.panTo(autoZoomLatLngBounds.getCenter());
autoZoomOut = false;
}
@@ -407,14 +412,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
public void onEvent(BoundsChangeMapEvent event) {
int newZoomLevel = map.getZoom();
if (!isAutoZoomInProgress() && (newZoomLevel != currentZoomLevel)) {
// remove the canvas animations for boats
for (BoatOverlay boatOverlay : RaceMap.this.getBoatOverlays().values()) {
boatOverlay.removeCanvasPositionAndRotationTransition();
}
// remove the canvas animations for the info overlays of the selected boats
for (CompetitorInfoOverlay infoOverlay : competitorInfoOverlays.values()) {
infoOverlay.removeCanvasPositionAndRotationTransition();
}
removeTransitions();
}
if ((streamletOverlay != null) && !map.getBounds().equals(currentMapBounds)) {
streamletOverlay.onBoundsChanged(newZoomLevel != currentZoomLevel);
@@ -444,7 +442,18 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
LoadApi.go(onLoad, loadLibraries, sensor, "key="+GoogleMapAPIKey.V3_APIKey);
}
private void removeTransitions() {
// remove the canvas animations for boats
for (BoatOverlay boatOverlay : RaceMap.this.getBoatOverlays().values()) {
boatOverlay.removeCanvasPositionAndRotationTransition();
}
// remove the canvas animations for the info overlays of the selected boats
for (CompetitorInfoOverlay infoOverlay : competitorInfoOverlays.values()) {
infoOverlay.removeCanvasPositionAndRotationTransition();
}
}
public void redraw() {
timeChanged(timer.getTime(), null);
}
@@ -1235,17 +1244,15 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
autoZoomLatLngBounds = BoundsUtil.getAsLatLngBounds(newBounds);
int newZoomLevel = getZoomLevel(autoZoomLatLngBounds);
if (newZoomLevel != map.getZoom()) {
// remove the canvas animations for boats
for (BoatOverlay boatOverlay : RaceMap.this.getBoatOverlays().values()) {
boatOverlay.removeCanvasPositionAndRotationTransition();
}
// remove the canvas animations for the info overlays of the selected boats
for(CompetitorInfoOverlay infoOverlay: competitorInfoOverlays.values()) {
infoOverlay.removeCanvasPositionAndRotationTransition();
}
// distinguish between zoom-in and zoom-out, because the sequence of panTo() and setZoom()
// appears different on the screen due to map-animations
// following sequences keep the selected boats allways visible:
// zoom-in : 1. panTo(), 2. setZoom()
// zoom-out: 1. setZoom(), 2. panTo()
autoZoomIn = newZoomLevel > map.getZoom();
autoZoomOut = !autoZoomIn;
autoZoomLevel = newZoomLevel;
removeTransitions();
if (autoZoomIn) {
map.panTo(autoZoomLatLngBounds.getCenter());
} else {
@@ -1847,8 +1854,9 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
requiredRedraw = true;
}
if (!newSettings.getZoomSettings().equals(settings.getZoomSettings())) {
settings.setZoomSettings(newSettings.getZoomSettings());
settings.setZoomSettings(newSettings.getZoomSettings());
if (!settings.getZoomSettings().containsZoomType(ZoomTypes.NONE)) {
removeTransitions();
zoomMapToNewBounds(settings.getZoomSettings().getNewBounds(this));
}
}
@@ -102,6 +102,7 @@ public class WindStreamletsRaceboardOverlay extends MovingCanvasOverlay {
setCanvasSettings();
this.swarm = new Swarm(this, map, timer, windField, new StreamletParameters());
}
initCanvasOrigin();
this.swarm.start(animationIntervalMillis);
}
@@ -16,8 +16,7 @@ import com.sap.sailing.gwt.ui.simulator.streamlets.Vector;
*/
public abstract class MovingCanvasOverlay extends FullCanvasOverlay {
private LatLng ne;
private LatLng sw;
private LatLng nw;
public MovingCanvasOverlay(MapWidget map, int zIndex) {
super(map, zIndex);
@@ -25,45 +24,57 @@ public abstract class MovingCanvasOverlay extends FullCanvasOverlay {
@Override
public void setCanvasSettings() {
// do nothing, if mapProjection is not available
if (mapProjection == null)
return;
int canvasWidth = getMap().getDiv().getClientWidth();
int canvasHeight = getMap().getDiv().getClientHeight();
// calculate pixel-positions of old and new canvas-bounds using the same, current mapProjection
// start from LatLng, as the canvas might have jumped to new bounds that do not intersect with the old bounds
Point nwOldPx;
if (nw == null) {
nwOldPx = null;
} else {
nwOldPx = mapProjection.fromLatLngToDivPixel(nw);
}
nw = LatLng.newInstance(getMap().getBounds().getNorthEast().getLatitude(), getMap().getBounds().getSouthWest().getLongitude());
Point nwNewPx = mapProjection.fromLatLngToDivPixel(nw);
widgetPosLeft = Math.round(nwNewPx.getX());
widgetPosTop = Math.round(nwNewPx.getY());
// calculate the translation-vector between old and new origin in pixels
if (nwOldPx == null) {
diffPx = new Vector(0, 0);
} else {
double oldPosLeft = Math.round(nwOldPx.getX());
double oldPosTop = Math.round(nwOldPx.getY());
diffPx = new Vector(oldPosLeft - widgetPosLeft, oldPosTop - widgetPosTop);
}
// store canvas-content, because setWidth() and setHeight() will clear canvas and change Context2d
Context2d ctxt = canvas.getContext2d();
ImageData canvasContent = ctxt.getImageData(0, 0, canvas.getElement().getClientWidth(), canvas.getElement().getClientHeight());
canvas.setWidth(String.valueOf(canvasWidth));
canvas.setHeight(String.valueOf(canvasHeight));
canvas.setCoordinateSpaceWidth(canvasWidth);
canvas.setCoordinateSpaceHeight(canvasHeight);
Point oldSWpx = mapProjection.fromLatLngToDivPixel(sw);
Point oldNEpx = mapProjection.fromLatLngToDivPixel(ne);
sw = getMap().getBounds().getSouthWest();
ne = getMap().getBounds().getNorthEast();
Point swPx = mapProjection.fromLatLngToDivPixel(sw);
Point nePx = mapProjection.fromLatLngToDivPixel(ne);
widgetPosLeft = Math.min(swPx.getX(), nePx.getX());
widgetPosTop = Math.min(swPx.getY(), nePx.getY());
double oldLeftpx;
double oldToppx;
if (oldSWpx == null) {
oldLeftpx = widgetPosLeft;
oldToppx = widgetPosTop;
} else {
oldLeftpx = Math.min(oldSWpx.getX(), oldNEpx.getX());
oldToppx = Math.min(oldSWpx.getY(), oldNEpx.getY());
}
diffPx = new Vector(oldLeftpx - widgetPosLeft, oldToppx - widgetPosTop);
// get updated Context2d and restore canvas-content moved by translation-vector
ctxt = canvas.getContext2d();
ctxt.putImageData(canvasContent, diffPx.x, diffPx.y);
setCanvasPosition(getWidgetPosLeft(), getWidgetPosTop());
// update canvas position
setCanvasPosition(widgetPosLeft, widgetPosTop);
}
@Override
protected void draw() {
// do nothing; setCanvasSettings() is called directly
}
public void initCanvasOrigin() {
nw = null;
}
}
@@ -66,18 +66,17 @@ public class Swarm implements TimeListener {
}
public void start(int animationIntervalMillis) {
fullcanvas.setCanvasSettings();
projection = new Mercator(fullcanvas, map);
projection.calibrate();
this.updateBounds();
Context2d ctxt = canvas.getContext2d();
ctxt.setFillStyle("red");
updateBounds();
particles = this.createParticles();
this.swarmContinue = true;
swarmContinue = true;
startLoop(animationIntervalMillis);
}
public void stop() {
this.swarmContinue = false;
swarmContinue = false;
}
private Particle createParticle() {
+21
View File
@@ -45,6 +45,27 @@
<h2 class='articleSubheadline'>Upcoming and Live</h2>
<br/>
<div class="timeBar">
<div class='raceSection'>
<h5 class='date'>
505 Worlds 2014
</h5>
<div class='raceTimepoint'></div>
<a href='http://505worlds2014.sapsailing.com' target='_blank'>
<ul class='racePanel'>
<li class='raceName'>
505 Worlds 2014
</li>
<li class='raceLocation'>
Kiel, Germany
</li>
</ul>
</a>
<div class='raceDescription'>
<p>505 Worlds 2014</p>
<a href='http://505worlds2014.sapsailing.com' target='_blank'>SAP Sailing Analytics</a><br/>
<a href='http://505worlds.com' target='_blank'>Official website</a>
</div>
</div>
<div class='raceSection'>
<h5 class='date'>
2014 Season
+27 -1
View File
@@ -1,4 +1,30 @@
# 505 worlds Kiel 2014
# 505 Worlds 2014, Kiel
## Server Landscape
We run two servers for the event, A and B, for fast and available switching. The DB they use is called 505WORLDS2014, and so is the replication channel. The git branch we use to merge the features we want to deploy to the event servers is called `505worlds2014` and the git tag used to build a release for it is called `505worlds2014-release`. See http://hudson.sapsailing.com/job/SAPSailingAnalytics-505worlds2014/ and http://hudson.sapsailing.com/job/SAPSailingAnalytics-505worlds2014-release/, respectively, for their Hudson jobs.
Regatta Overview: http://505worlds2014ro.sapsailing.com
Manage2Sail Event URL: http://manage2sail.com/api/public/links/event/d70bee3e-9f65-46f4-96a1-9fd467712ce0?accesstoken=bDAv8CwsTM94ujZ&mediaType=json
Event Page (newhome): http://505worlds2014.sapsailing.com/gwt/Home.html#EventPlace:eventId=94e1e240-8a3d-466b-9f39-419f311eaace
### A server
Admin Console at http://ec2-54-77-58-65.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
External IP: 54.77.58.65
Internal IP: 172.31.30.45
### B server
Admin Console at http://ec2-54-77-33-52.eu-west-1.compute.amazonaws.com:8888/gwt/AdminConsole.html
External IP: 54.77.33.52
Internal IP: 172.31.31.62
## TracTrac URL
http://secondary.traclive.dk/events/event_20140813_Worlds/jsonservice.php
### Touch Computer (Lenovo) Setup
+2
View File
@@ -2,6 +2,8 @@
This document describes the onboarding process for a new team member (developer)
First of all, make sure you've looked at http://www.amazon.de/Patterns-Elements-Reusable-Object-Oriented-Software/dp/0201633612. That's a great book, and knowing at least some of it will help you a great deal finding your way around our solution.
### Race Analysis Development Setup
#### Installations