diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/SpeedWithConfidence.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/SpeedWithConfidence.java index 0ba42b2613e..f1a1ab5d8c9 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/SpeedWithConfidence.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/SpeedWithConfidence.java @@ -1,8 +1,7 @@ package com.sap.sailing.domain.base; import com.sap.sailing.domain.common.Speed; -import com.sap.sailing.domain.confidence.HasConfidence; +import com.sap.sailing.domain.confidence.HasConfidenceAndIsScalable; -public interface SpeedWithConfidence extends HasConfidence { - Speed getObject(); +public interface SpeedWithConfidence extends HasConfidenceAndIsScalable { } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SpeedWithConfidenceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SpeedWithConfidenceImpl.java new file mode 100755 index 00000000000..50d9a7609c1 --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/SpeedWithConfidenceImpl.java @@ -0,0 +1,48 @@ +package com.sap.sailing.domain.base.impl; + +import com.sap.sailing.domain.base.SpeedWithConfidence; +import com.sap.sailing.domain.common.Speed; +import com.sap.sailing.domain.confidence.ScalableValue; + +public class SpeedWithConfidenceImpl extends HasConfidenceImpl implements SpeedWithConfidence { + public SpeedWithConfidenceImpl(Speed object, double confidence, RelativeTo relativeTo) { + super(object, confidence, relativeTo); + } + + @Override + public ScalableValue getScalableValue() { + return new ScalableSpeed(getObject()); + } + + private static class ScalableSpeed implements ScalableValue { + private final double knots; + + public ScalableSpeed(Speed speed) { + this.knots = speed.getKnots(); + } + + private ScalableSpeed(double knots) { + this.knots = knots; + } + + @Override + public ScalableValue multiply(double factor) { + return new ScalableSpeed(factor*knots); + } + + @Override + public ScalableValue add(ScalableValue t) { + return new ScalableSpeed(knots+t.getValue()); + } + + @Override + public Speed divide(double divisor, double confidence) { + return new KnotSpeedImpl(knots / divisor); + } + + @Override + public Double getValue() { + return knots; + } + } +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/confidence/ConfidenceBasedAverager.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/confidence/ConfidenceBasedAverager.java index 6654f9a0f02..73e476d270f 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/confidence/ConfidenceBasedAverager.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/confidence/ConfidenceBasedAverager.java @@ -10,7 +10,8 @@ public interface ConfidenceBasedAverager { * null average with confidence is returned. Note, however, that the * {@link HasConfidence#getObject() object} in the {@link HasConfidence} result may be null, * e.g., if the combined confidence went to 0.0 and the averager was unable to determine a reasonable - * average value. + * average value. The result's confidence is the arithmetic average of the confidences of all values + * that contributed to the result. */ HasConfidence getAverage( Iterable> values, RelativeTo at); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/confidence/impl/ConfidenceBasedAveragerImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/confidence/impl/ConfidenceBasedAveragerImpl.java index bcced8a0332..262b437e028 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/confidence/impl/ConfidenceBasedAveragerImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/confidence/impl/ConfidenceBasedAveragerImpl.java @@ -61,7 +61,7 @@ public class ConfidenceBasedAveragerImpl implem } confidenceSum += relativeWeight; } - // TODO determine new confidence, e.g., based on the variance of estimates averaged + // TODO consider greater variance to reduce the confidence double newConfidence = confidenceSum / Util.size(values); BaseType result = numerator.divide(confidenceSum, newConfidence); return new HasConfidenceImpl(result, newConfidence, at); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/GPSFixTrack.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/GPSFixTrack.java index 69d1fab1c37..28031c44bb5 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/GPSFixTrack.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/GPSFixTrack.java @@ -1,11 +1,13 @@ package com.sap.sailing.domain.tracking; import com.sap.sailing.domain.base.SpeedWithBearing; +import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.impl.Util.Pair; +import com.sap.sailing.domain.confidence.Weigher; /** * A track records the {@link GPSFix}es received for an object of type @@ -74,6 +76,19 @@ public interface GPSFixTrack extends Trackat. */ SpeedWithBearing getEstimatedSpeed(TimePoint at); + + /** + * Estimates the tracked item's speed/bearing, returning the result as a value with confidence. The confidences of + * the individual fixes contributing to the estimation are computed using the weigher. The result's + * confidence is the average confidence of the fixes used. While this is probably not a mathematically meaningful + * confidence value, it helps in comparing confidences of different estimations relative to each other. + */ + SpeedWithBearingWithConfidence getEstimatedSpeed(TimePoint at, Weigher weigher); + + /** + * Same as {@link #getEstimatedSpeed(TimePoint, Weigher)}, but using the raw fixes. + */ + SpeedWithBearingWithConfidence getRawEstimatedSpeed(TimePoint at, Weigher weigher); long getMillisecondsOverWhichToAverageSpeed(); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java index 01ebcaf44c1..ff3eae4f398 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java @@ -1,5 +1,6 @@ package com.sap.sailing.domain.tracking.impl; +import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -7,15 +8,21 @@ import java.util.NavigableSet; import com.sap.sailing.domain.base.BearingWithConfidence; import com.sap.sailing.domain.base.SpeedWithBearing; +import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence; +import com.sap.sailing.domain.base.SpeedWithConfidence; import com.sap.sailing.domain.base.impl.BearingWithConfidenceImpl; import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl; import com.sap.sailing.domain.base.impl.MillisecondsTimePoint; +import com.sap.sailing.domain.base.impl.SpeedWithBearingWithConfidenceImpl; +import com.sap.sailing.domain.base.impl.SpeedWithConfidenceImpl; import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl; +import com.sap.sailing.domain.confidence.ConfidenceBasedAverager; import com.sap.sailing.domain.confidence.ConfidenceFactory; +import com.sap.sailing.domain.confidence.HasConfidence; import com.sap.sailing.domain.confidence.Weigher; import com.sap.sailing.domain.tracking.GPSFix; import com.sap.sailing.domain.tracking.GPSFixMoving; @@ -44,42 +51,47 @@ public class DynamicGPSFixMovingTrackImpl extends DynamicTrackImpl fixesToUseForSpeedEstimation) { + protected SpeedWithBearingWithConfidence getEstimatedSpeed(TimePoint at, + NavigableSet fixesToUseForSpeedEstimation, Weigher weigher) { List relevantFixes = getFixesRelevantForSpeedEstimation(at, fixesToUseForSpeedEstimation); - double knotSum = 0; - Weigher weigher = ConfidenceFactory.INSTANCE.createExponentialTimeDifferenceWeigher( - // use a minimum confidence to avoid the bearing to flip to 270deg in case all is zero - /* halfConfidenceAfterMilliseconds */ getMillisecondsOverWhichToAverageSpeed()); + List> speeds = new ArrayList>(); BearingWithConfidenceCluster bearingCluster = new BearingWithConfidenceCluster(weigher); - int count = 0; if (!relevantFixes.isEmpty()) { Iterator fixIter = relevantFixes.iterator(); GPSFixMoving last = fixIter.next(); - knotSum = last.getSpeed().getKnots(); + SpeedWithConfidenceImpl speedWithConfidence = new SpeedWithConfidenceImpl(last.getSpeed(), + /* original confidence */ 0.9, last.getTimePoint()); + speeds.add(speedWithConfidence); bearingCluster.add(new BearingWithConfidenceImpl(last.getSpeed().getBearing(), /* confidence */ 0.9, last.getTimePoint())); - count = 1; while (fixIter.hasNext()) { - // TODO bug #169: use confidence-based averager for speed, too, and not only for bearing // add to average the position and time difference GPSFixMoving next = fixIter.next(); - knotSum += last.getPosition().getDistance(next.getPosition()) - .inTime(next.getTimePoint().asMillis() - last.getTimePoint().asMillis()).getKnots(); + SpeedWithConfidenceImpl measuredSpeedWithConfidence = new SpeedWithConfidenceImpl( + last.getPosition().getDistance(next.getPosition()) + .inTime(next.getTimePoint().asMillis() - last.getTimePoint().asMillis()), + /* original confidence */0.9, new MillisecondsTimePoint((last.getTimePoint().asMillis()+next.getTimePoint().asMillis())/2)); + speeds.add(measuredSpeedWithConfidence); bearingCluster.add(new BearingWithConfidenceImpl(last.getPosition().getBearingGreatCircle(next.getPosition()), /* confidence */ weigher.getConfidence(last.getTimePoint(), next.getTimePoint()), new MillisecondsTimePoint((last.getTimePoint().asMillis()+next.getTimePoint().asMillis())/2))); - count++; // add to average the speed and bearing provided by the GPSFixMoving - knotSum += next.getSpeed().getKnots(); + SpeedWithConfidenceImpl computedSpeedWithConfidence = new SpeedWithConfidenceImpl( + next.getSpeed(), /* original confidence */0.9, next.getTimePoint()); + speeds.add(computedSpeedWithConfidence); bearingCluster.add(new BearingWithConfidenceImpl(next.getSpeed().getBearing(), /* confidence */ 0.9, next.getTimePoint())); - count++; last = next; } } - BearingWithConfidence average = bearingCluster.getAverage(at); - Bearing bearing = average == null ? null : average.getObject(); - SpeedWithBearing avgSpeed = (count == 0 || bearing == null) ? null : new KnotSpeedWithBearingImpl(knotSum / count, bearing); - return avgSpeed; + ConfidenceBasedAverager speedAverager = ConfidenceFactory.INSTANCE.createAverager(weigher); + HasConfidence speedWithConfidence = speedAverager.getAverage(speeds, at); + BearingWithConfidence bearingAverage = bearingCluster.getAverage(at); + Bearing bearing = bearingAverage == null ? null : bearingAverage.getObject(); + SpeedWithBearing avgSpeed = (speedWithConfidence == null || bearing == null) ? null : + new KnotSpeedWithBearingImpl(speedWithConfidence.getObject().getKnots(), bearing); + SpeedWithBearingWithConfidence result = new SpeedWithBearingWithConfidenceImpl(avgSpeed, + /* confidence */ (speedWithConfidence.getConfidence() + bearingAverage.getConfidence())/2., at); + return result; } private List getFixesRelevantForSpeedEstimation(TimePoint at, diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java index a1520bf2c85..75d079ea4c5 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java @@ -1,5 +1,6 @@ package com.sap.sailing.domain.tracking.impl; +import java.util.ArrayList; import java.util.ConcurrentModificationException; import java.util.HashSet; import java.util.Iterator; @@ -10,10 +11,14 @@ import java.util.Set; import com.sap.sailing.domain.base.BearingWithConfidence; import com.sap.sailing.domain.base.SpeedWithBearing; +import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence; +import com.sap.sailing.domain.base.SpeedWithConfidence; import com.sap.sailing.domain.base.impl.BearingWithConfidenceImpl; import com.sap.sailing.domain.base.impl.KnotSpeedImpl; import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl; import com.sap.sailing.domain.base.impl.MillisecondsTimePoint; +import com.sap.sailing.domain.base.impl.SpeedWithBearingWithConfidenceImpl; +import com.sap.sailing.domain.base.impl.SpeedWithConfidenceImpl; import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.Position; @@ -21,7 +26,10 @@ import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.impl.NauticalMileDistance; import com.sap.sailing.domain.common.impl.Util.Pair; +import com.sap.sailing.domain.confidence.ConfidenceBasedAverager; import com.sap.sailing.domain.confidence.ConfidenceFactory; +import com.sap.sailing.domain.confidence.HasConfidence; +import com.sap.sailing.domain.confidence.Weigher; import com.sap.sailing.domain.tracking.GPSFix; import com.sap.sailing.domain.tracking.GPSFixMoving; import com.sap.sailing.domain.tracking.GPSFixTrack; @@ -301,12 +309,26 @@ public class GPSFixTrackImpl extends TrackImpl */ @Override public synchronized SpeedWithBearing getEstimatedSpeed(TimePoint at) { - return getEstimatedSpeed(at, getInternalFixes()); + return getEstimatedSpeed(at, getInternalFixes(), ConfidenceFactory.INSTANCE.createExponentialTimeDifferenceWeigher( + // use a minimum confidence to avoid the bearing to flip to 270deg in case all is zero + getMillisecondsOverWhichToAverageSpeed())).getObject(); } @Override public synchronized SpeedWithBearing getRawEstimatedSpeed(TimePoint at) { - return getEstimatedSpeed(at, getRawFixes()); + return getEstimatedSpeed(at, getRawFixes(), ConfidenceFactory.INSTANCE.createExponentialTimeDifferenceWeigher( + // use a minimum confidence to avoid the bearing to flip to 270deg in case all is zero + getMillisecondsOverWhichToAverageSpeed())).getObject(); + } + + @Override + public SpeedWithBearingWithConfidence getEstimatedSpeed(TimePoint at, Weigher weigher) { + return getEstimatedSpeed(at, getInternalFixes(), weigher); + } + + @Override + public SpeedWithBearingWithConfidence getRawEstimatedSpeed(TimePoint at, Weigher weigher) { + return getEstimatedSpeed(at, getRawFixes(), weigher); } /** @@ -315,17 +337,20 @@ public class GPSFixTrackImpl extends TrackImpl * {@link #millisecondsOverWhichToAverage} milliseconds around at. Subclasses that know about the * particular fix type may redefine this to exploit a {@link SpeedWithBearing} attached, e.g., to a * {@link GPSFixMoving}. + * + * @param weigher + * If null, a confidence of 1.0 is assumed for all fixes used in the speed/bearing + * estimation. Otherwise, the confidence of each fix contributing to the estimation is computed using the + * weigher. + * @return a speed/bearing with the average confidence attributed to the fixes that contributed to the estimation */ - protected SpeedWithBearing getEstimatedSpeed(TimePoint at, NavigableSet fixesToUseForSpeedEstimation) { + protected SpeedWithBearingWithConfidence getEstimatedSpeed(TimePoint at, + NavigableSet fixesToUseForSpeedEstimation, Weigher weigher) { @SuppressWarnings("unchecked") NavigableSet gpsFixesToUseForSpeedEstimation = (NavigableSet) fixesToUseForSpeedEstimation; List relevantFixes = getFixesRelevantForSpeedEstimation(at, gpsFixesToUseForSpeedEstimation); - double knotSum = 0; - BearingWithConfidenceCluster bearingCluster = new BearingWithConfidenceCluster( - ConfidenceFactory.INSTANCE.createExponentialTimeDifferenceWeigher( - // use a minimum confidence to avoid the bearing to flip to 270deg in case all is zero - getMillisecondsOverWhichToAverageSpeed())); - int count = 0; + List> speeds = new ArrayList>(); + BearingWithConfidenceCluster bearingCluster = new BearingWithConfidenceCluster(weigher); if (!relevantFixes.isEmpty()) { Iterator fixIter = relevantFixes.iterator(); GPSFix last = fixIter.next(); @@ -333,20 +358,27 @@ public class GPSFixTrackImpl extends TrackImpl // TODO bug #169: consider time difference between next.getTimepoint() and at to compute a confidence GPSFix next = fixIter.next(); // TODO bug #169: use SpeedWithConfidence to aggregate confidence-tagged speed values - knotSum += last.getPosition().getDistance(next.getPosition()) - .inTime(next.getTimePoint().asMillis() - last.getTimePoint().asMillis()).getKnots(); + MillisecondsTimePoint relativeTo = new MillisecondsTimePoint((last.getTimePoint().asMillis() + next.getTimePoint().asMillis())/2); + Speed speed = last.getPosition().getDistance(next.getPosition()) + .inTime(next.getTimePoint().asMillis() - last.getTimePoint().asMillis()); + SpeedWithConfidenceImpl speedWithConfidence = new SpeedWithConfidenceImpl(speed, /* original confidence */ + 0.9, relativeTo); + speeds.add(speedWithConfidence); bearingCluster.add(new BearingWithConfidenceImpl(last.getPosition().getBearingGreatCircle(next.getPosition()), /* confidence */ 0.9, // TODO use number of tracked satellites to determine confidence of single fix - new MillisecondsTimePoint((last.getTimePoint().asMillis() + next.getTimePoint().asMillis())/2))); - count++; + relativeTo)); last = next; } } - // TODO bug #169: return SpeedWithBearingWithConfidence to reflect the confidence reduction incurred by the difference of the fix's time point and "at" - BearingWithConfidence average = bearingCluster.getAverage(at); - Bearing bearing = average == null ? null : average.getObject(); - SpeedWithBearing avgSpeed = (count == 0 || bearing == null) ? null : new KnotSpeedWithBearingImpl(knotSum / count, bearing); - return avgSpeed; + ConfidenceBasedAverager speedAverager = ConfidenceFactory.INSTANCE.createAverager(weigher); + HasConfidence speedWithConfidence = speedAverager.getAverage(speeds, at); + BearingWithConfidence bearingAverage = bearingCluster.getAverage(at); + Bearing bearing = bearingAverage == null ? null : bearingAverage.getObject(); + SpeedWithBearing avgSpeed = (speedWithConfidence == null || bearing == null) ? null : + new KnotSpeedWithBearingImpl(speedWithConfidence.getObject().getKnots(), bearing); + SpeedWithBearingWithConfidence result = avgSpeed == null ? null : + new SpeedWithBearingWithConfidenceImpl(avgSpeed, (bearingAverage.getConfidence() + speedWithConfidence.getConfidence())/2., at); + return result; } private List getFixesRelevantForSpeedEstimation(TimePoint at, diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index d14aa822853..49e91529a6e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -16,6 +16,7 @@ import java.util.logging.Logger; import org.json.simple.parser.ParseException; +import com.sap.sailing.domain.base.BearingWithConfidence; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Buoy; import com.sap.sailing.domain.base.Competitor; @@ -24,8 +25,10 @@ import com.sap.sailing.domain.base.CourseListener; import com.sap.sailing.domain.base.Leg; import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.SpeedWithBearing; +import com.sap.sailing.domain.base.SpeedWithBearingWithConfidence; import com.sap.sailing.domain.base.Timed; import com.sap.sailing.domain.base.Waypoint; +import com.sap.sailing.domain.base.impl.BearingWithConfidenceImpl; import com.sap.sailing.domain.base.impl.DouglasPeucker; import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl; import com.sap.sailing.domain.base.impl.MillisecondsTimePoint; @@ -47,6 +50,8 @@ import com.sap.sailing.domain.common.impl.RacePlaceOrderImpl; import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Triple; +import com.sap.sailing.domain.confidence.ConfidenceFactory; +import com.sap.sailing.domain.confidence.Weigher; import com.sap.sailing.domain.tracking.GPSFix; import com.sap.sailing.domain.tracking.GPSFixMoving; import com.sap.sailing.domain.tracking.GPSFixTrack; @@ -646,9 +651,12 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener { @Override public Wind getEstimatedWindDirection(Position position, TimePoint timePoint) { - Map bearings = new HashMap(); + Weigher weigher = ConfidenceFactory.INSTANCE.createExponentialTimeDifferenceWeigher( + // use a minimum confidence to avoid the bearing to flip to 270deg in case all is zero + getMillisecondsOverWhichToAverageSpeed()); + Map> bearings = new HashMap>(); for (LegType legType : LegType.values()) { - bearings.put(legType, new BearingCluster()); + bearings.put(legType, new BearingWithConfidenceCluster(weigher)); } for (Competitor competitor : getRace().getCompetitors()) { TrackedLegOfCompetitor leg = getTrackedLeg(competitor, timePoint); @@ -665,44 +673,58 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener { GPSFixTrack track = getTrack(competitor); // TODO bug #167 could be fixed here by excluding competitors that are x seconds before/after a mark passing if (!track.hasDirectionChange(timePoint, getManeuverDegreeAngleThreshold())) { - SpeedWithBearing estimatedSpeed = track.getEstimatedSpeed(timePoint); - if (estimatedSpeed != null) { - // TODO but #169: preserve confidence of estimatedSpeed relative to timePoint so as to feed into a BearingWithConfidenceCluster here - Bearing bearing = estimatedSpeed.getBearing(); - BearingCluster bearingClusterForLegType = bearings.get(legType); + SpeedWithBearingWithConfidence estimatedSpeedWithConfidence = track.getEstimatedSpeed(timePoint, + weigher); + if (estimatedSpeedWithConfidence != null) { + BearingWithConfidence bearing = new BearingWithConfidenceImpl( + estimatedSpeedWithConfidence.getObject().getBearing(), estimatedSpeedWithConfidence.getConfidence(), + estimatedSpeedWithConfidence.getRelativeTo()); + BearingWithConfidenceCluster bearingClusterForLegType = bearings.get(legType); bearingClusterForLegType.add(bearing); } } } } } - Bearing reversedUpwindAverage = null; - int upwindConfidence = 0; - BearingCluster[] bearingClustersUpwind = bearings.get(LegType.UPWIND).splitInTwo(getMinimumAngleBetweenDifferentTacksUpwind()); + // use the minimum confidence of the four "quadrants" as the result's confidence + BearingWithConfidenceImpl reversedUpwindAverage = null; + int upwindNumberOfRelevantBoats = 0; + double confidence = 0; + BearingWithConfidenceCluster[] bearingClustersUpwind = bearings.get(LegType.UPWIND).splitInTwo( + getMinimumAngleBetweenDifferentTacksUpwind(), timePoint); if (!bearingClustersUpwind[0].isEmpty() && !bearingClustersUpwind[1].isEmpty()) { - reversedUpwindAverage = bearingClustersUpwind[0].getAverage().middle(bearingClustersUpwind[1].getAverage()).reverse(); - upwindConfidence = Math.min(bearingClustersUpwind[0].size(), bearingClustersUpwind[1].size()); + BearingWithConfidence average0 = bearingClustersUpwind[0].getAverage(timePoint); + BearingWithConfidence average1 = bearingClustersUpwind[1].getAverage(timePoint); + confidence = Math.min(average0.getConfidence(), average1.getConfidence()); + reversedUpwindAverage = new BearingWithConfidenceImpl(average0.getObject().middle(average1.getObject()).reverse(), + confidence, timePoint); + upwindNumberOfRelevantBoats = Math.min(bearingClustersUpwind[0].size(), bearingClustersUpwind[1].size()); } - Bearing downwindAverage = null; - int downwindConfidence = 0; - BearingCluster[] bearingClustersDownwind = bearings.get(LegType.DOWNWIND).splitInTwo(getMinimumAngleBetweenDifferentTacksDownwind()); + BearingWithConfidenceImpl downwindAverage = null; + int downwindNumberOfRelevantBoats = 0; + BearingWithConfidenceCluster[] bearingClustersDownwind = bearings.get(LegType.DOWNWIND).splitInTwo( + getMinimumAngleBetweenDifferentTacksDownwind(), timePoint); if (!bearingClustersDownwind[0].isEmpty() && !bearingClustersDownwind[1].isEmpty()) { - downwindAverage = bearingClustersDownwind[0].getAverage().middle(bearingClustersDownwind[1].getAverage()); - downwindConfidence = Math.min(bearingClustersDownwind[0].size(), bearingClustersDownwind[1].size()); + BearingWithConfidence average0 = bearingClustersDownwind[0].getAverage(timePoint); + BearingWithConfidence average1 = bearingClustersDownwind[1].getAverage(timePoint); + double downwindConfidence = Math.min(average0.getConfidence(), average1.getConfidence()); + confidence = Math.min(confidence, downwindConfidence); + downwindAverage = new BearingWithConfidenceImpl(average0.getObject().middle(average1.getObject()), downwindConfidence, timePoint); + downwindNumberOfRelevantBoats = Math.min(bearingClustersDownwind[0].size(), bearingClustersDownwind[1].size()); } - int confidence = upwindConfidence + downwindConfidence; - BearingCluster resultCluster = new BearingCluster(); - assert upwindConfidence == 0 || reversedUpwindAverage != null; - for (int i=0; i resultCluster = new BearingWithConfidenceCluster(weigher); + assert upwindNumberOfRelevantBoats == 0 || reversedUpwindAverage != null; + if (upwindNumberOfRelevantBoats > 0) { resultCluster.add(reversedUpwindAverage); } - assert downwindConfidence == 0 || downwindAverage != null; - for (int i=0; i 0) { resultCluster.add(downwindAverage); } - Bearing resultBearing = resultCluster.getAverage(); + BearingWithConfidence resultBearing = resultCluster.getAverage(timePoint); return resultBearing == null ? null : new WindImpl(null, timePoint, - new KnotSpeedWithBearingImpl(/* speedInKnots */ confidence, resultBearing)); + new KnotSpeedWithBearingImpl(/* speedInKnots */ numberOfBoatsRelevantForEstimate, resultBearing.getObject())); } /** diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java index fb084a94bc7..8b516a7c755 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java @@ -134,8 +134,7 @@ public class WindTrackImpl extends TrackImpl implements WindTrack { Iterator afterIter = afterSet.iterator(); double knotSum = 0; // TODO bug #169: also measure speed with confidence; return confidence - Weigher weigher = ConfidenceFactory.INSTANCE.createLinearTimeDifferenceWeigher(millisecondsOverWhichToAverage); - // Weigher weigher = ConfidenceFactory.INSTANCE.createConstantWeigher(1.0); + Weigher weigher = ConfidenceFactory.INSTANCE.createLinearTimeDifferenceWeigher(millisecondsOverWhichToAverage/10); BearingWithConfidenceCluster bearingCluster = new BearingWithConfidenceCluster(weigher); int count = 0; long beforeDistanceToAt = 0; diff --git a/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs b/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs index 5c1dfe07e80..e6887c76391 100755 --- a/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs +++ b/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs @@ -1,5 +1,5 @@ -#Tue Jan 24 01:20:58 CET 2012 +#Thu Feb 02 12:04:27 CET 2012 eclipse.preferences.version=1 entryPointModules= filesCopiedToWebInfLib=gwt-servlet.jar -gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDUxMm1dXT48L3ZtLWFyZ3M+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLkFkbWluQ29uc29sZTwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5MZWFkZXJib2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5MZWFkZXJib2FyZEVkaXRpbmc8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuU3BlY3RhdG9yPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= +gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDUxMm1dXT48L3ZtLWFyZ3M+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= diff --git a/java/com.sap.sailing.gwt.ui/Spectator.css b/java/com.sap.sailing.gwt.ui/Spectator.css index 0dc5d423d97..45bc849c21a 100644 --- a/java/com.sap.sailing.gwt.ui/Spectator.css +++ b/java/com.sap.sailing.gwt.ui/Spectator.css @@ -236,3 +236,42 @@ input.magnifier { text-decoration: none; } +.leaderboardGroupPanel-GroupName { + float: left; +} + +.leaderboardGroupPanel-GroupDescription { + float: left; +} + +.leaderboardGroupPanel-LeaderboardsTableLabel { + +} + +.leaderboardGroupPanel-ActiveLeaderboard{ + +} + +.leaderboardGroupPanel-ActiveRace { + +} + +.leaderboardGroupPanel-InactiveRace { + +} + +.welcomeWidget-WelcomePanel{ + +} + +.welcomeWidget-CloseButton { + +} + +.welcomeWidget-Header { + +} + +.welcomeWidget-WelcomeText { + +} 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 new file mode 100644 index 00000000000..6aee00964b3 Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/images/sap-sailing-app-icon.png differ diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/HasWelcomeWidget.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/HasWelcomeWidget.java new file mode 100644 index 00000000000..7de178c715a --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/HasWelcomeWidget.java @@ -0,0 +1,22 @@ +package com.sap.sailing.gwt.ui.client; + +import com.sap.sailing.gwt.ui.shared.panels.ClosableWelcomeWidget; +import com.sap.sailing.gwt.ui.shared.panels.SimpleWelcomeWidget; +import com.sap.sailing.gwt.ui.shared.panels.WelcomeWidget; + +/** + * Classes which implement this interface have the ability to display a {@link WelcomeWidget}. + * + * @author Lennart Hensler (D054527) + */ +public interface HasWelcomeWidget { + + /** + * Sets the welcome widget of the component. + * @param welcome The new welcome widget + * @see {@link WelcomeWidget}, {@link SimpleWelcomeWidget}, {@link ClosableWelcomeWidget}, ... + */ + void setWelcomeWidget(WelcomeWidget welcome); + void setWelcomeWidgetVisible(boolean isVisible); + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimePanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimePanel.java index 363bc4ea176..3306dfa07cb 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimePanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimePanel.java @@ -26,7 +26,7 @@ import com.sap.sailing.gwt.ui.client.Timer.PlayModes; import com.sap.sailing.gwt.ui.shared.components.Component; import com.sap.sailing.gwt.ui.shared.components.SettingsDialog; import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent; -import com.sap.sailing.gwt.ui.shared.controls.SliderBar; +import com.sap.sailing.gwt.ui.shared.controls.slider.SliderBar; public class TimePanel extends FormPanel implements Component, TimeListener, PlayStateListener, RequiresResize { private final Timer timer; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java index f944fbcb029..f31b0b6475f 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java @@ -1060,6 +1060,13 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta Collections.sort(getData().getList(), getRankColumn().getComparator()); getLeaderboardTable().getColumnSortList().push(getRankColumn()); } + //Reselect the selected rows + leaderboardSelectionModel.clear(); + for (LeaderboardRowDTO row : data.getList()) { + if (competitorSelectionProvider.isSelected(row.competitor)) { + leaderboardSelectionModel.setSelected(row, true); + } + } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/HasWelcomeWidget.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/HasWelcomeWidget.java deleted file mode 100644 index 21c433032a1..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/HasWelcomeWidget.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.sap.sailing.gwt.ui.shared.components; - -import com.google.gwt.user.client.ui.Widget; - -public interface HasWelcomeWidget { - - /** - * Sets the welcome widget of the component. - * @param welcome The new welcome widget - * @see {@link WelcomeWidget}, {@link SimpleWelcomeWidget}, {@link ClosableWelcomeWidget}, ... - */ - void setWelcomeWidget(Widget welcome); - void setWelcomeWidgetVisible(boolean isVisible); - -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/WelcomeWidget.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/WelcomeWidget.java deleted file mode 100644 index aeafc846b68..00000000000 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/WelcomeWidget.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.sap.sailing.gwt.ui.shared.components; - -public interface WelcomeWidget { - - /** - * Sets the text of the header component. - * @param headerText The new header text - */ - void setWelcomeHeaderText(String headerText); - - /** - * Sets the text of the component under the header - * @param welcomeText The new welcome text - */ - void setWelcomeText(String welcomeText); - -} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/SliderBar.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/SliderBar.css similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/SliderBar.css rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/SliderBar.css diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/SliderBar.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/SliderBar.java similarity index 99% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/SliderBar.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/SliderBar.java index 5791ad7ccd6..bb6f5e951cf 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/SliderBar.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/SliderBar.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.ui.shared.controls; +package com.sap.sailing.gwt.ui.shared.controls.slider; /* * Copyright 2008 Google Inc. diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider.gif b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/slider.gif similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider.gif rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/slider.gif diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/sliderDisabled.gif b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/sliderDisabled.gif similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/sliderDisabled.gif rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/sliderDisabled.gif diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/sliderSliding.gif b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/sliderSliding.gif similarity index 100% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/sliderSliding.gif rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/controls/slider/sliderSliding.gif diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/BreadcrumbPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/BreadcrumbPanel.java new file mode 100644 index 00000000000..e74d6fb26e4 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/BreadcrumbPanel.java @@ -0,0 +1,51 @@ +package com.sap.sailing.gwt.ui.shared.panels; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style; +import com.google.gwt.safehtml.client.SafeHtmlTemplates; +import com.google.gwt.safehtml.shared.SafeHtml; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Label; +import com.sap.sailing.domain.common.impl.Util.Pair; + +public class BreadcrumbPanel extends FlowPanel { + + interface AnchorTemplates extends SafeHtmlTemplates { + @SafeHtmlTemplates.Template("{1}") + SafeHtml anchor(String url, String displayName); + } + + public static final AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class); + public static final String STYLE_NAME_PREFIX = "breadcrumbPanel-"; + + /** + * Creates a new BreadcrumbPanel with the breadcrumbLinks as active links and actualBreadcrumb as Label + * @param breadcrumbLinksData The data of the breadcrumbs which will be displayed as links. Part A of the pair is the URL and part B the displayed text. + * @param actualBreadcrumbName The text as Label. Should be the name of the component in which the BreadcrumbPanel is displayed. + */ + public BreadcrumbPanel(Iterable> breadcrumbLinksData, String actualBreadcrumbName) { + super(); + //Adding the active breadcrumbs + for (Pair breadcrumbData : breadcrumbLinksData) { + HTML breadcrumb = new HTML(ANCHORTEMPLATE.anchor(breadcrumbData.getA(), breadcrumbData.getB())); + breadcrumb.addStyleName(STYLE_NAME_PREFIX + "ActiveBreadcrumb"); + breadcrumb.getElement().getStyle().setFloat(Style.Float.LEFT); + breadcrumb.getElement().getStyle().setPadding(5, Style.Unit.PX); + add(breadcrumb); + + Label nextArrow = new Label(">"); + nextArrow.setStyleName(STYLE_NAME_PREFIX + "NextArrow"); + nextArrow.getElement().getStyle().setFloat(Style.Float.LEFT); + nextArrow.getElement().getStyle().setPadding(5, Style.Unit.PX); + add(nextArrow); + } + //Adding the actual breadcrumb + Label actualBreadcrumb = new Label(actualBreadcrumbName); + actualBreadcrumb.addStyleName(STYLE_NAME_PREFIX + "InactiveBreadcrumb"); + actualBreadcrumb.getElement().getStyle().setFloat(Style.Float.LEFT); + actualBreadcrumb.getElement().getStyle().setPadding(5, Style.Unit.PX); + add(actualBreadcrumb); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/ClosableWelcomeWidget.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/ClosableWelcomeWidget.java similarity index 80% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/ClosableWelcomeWidget.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/ClosableWelcomeWidget.java index e4880c88f1c..906f1819176 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/ClosableWelcomeWidget.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/ClosableWelcomeWidget.java @@ -1,4 +1,4 @@ -package com.sap.sailing.gwt.ui.shared.components; +package com.sap.sailing.gwt.ui.shared.panels; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; @@ -8,8 +8,8 @@ import com.sap.sailing.gwt.ui.client.StringMessages; public class ClosableWelcomeWidget extends SimpleWelcomeWidget { private StringMessages stringConstants; - private Button closeButton; private boolean closable; + private Button closeButton; /** * Creates a new closable welcome widget. It has the same components as the {@link SimpleWelcomeWidget} and a Button @@ -18,10 +18,9 @@ public class ClosableWelcomeWidget extends SimpleWelcomeWidget { * @param closable Sets the visibility of the close Button * @param headerText The text of the header component * @param welcomeText The text of the component under the header (welcome component) - * @param horizontalAlignment The alignment of the header and the welcomen component */ - public ClosableWelcomeWidget(boolean closable, String headerText, String welcomeText, HorizontalAlignmentConstant horizontalAlignment, StringMessages stringConstants) { - super(headerText, welcomeText, horizontalAlignment); + public ClosableWelcomeWidget(boolean closable, String headerText, String welcomeText, StringMessages stringConstants) { + super(headerText, welcomeText); this.stringConstants = stringConstants; this.closable = closable; @@ -33,8 +32,8 @@ public class ClosableWelcomeWidget extends SimpleWelcomeWidget { } }); closeButton.setVisible(this.closable); - setHorizontalAlignment(ALIGN_RIGHT); - insert(closeButton, 0); + closeButton.setStyleName(STYLE_NAME_PREFIX + "CloseButton"); + mainPanel.insert(closeButton, 0); } /** diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/SimpleWelcomeWidget.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/SimpleWelcomeWidget.java similarity index 59% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/SimpleWelcomeWidget.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/SimpleWelcomeWidget.java index 8543d466f64..30f352f22d7 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/components/SimpleWelcomeWidget.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/SimpleWelcomeWidget.java @@ -1,12 +1,13 @@ -package com.sap.sailing.gwt.ui.shared.components; +package com.sap.sailing.gwt.ui.shared.panels; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; +import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.VerticalPanel; -public class SimpleWelcomeWidget extends VerticalPanel implements WelcomeWidget { +public class SimpleWelcomeWidget extends WelcomeWidget { + protected FlowPanel mainPanel; private Label welcomeHeader; private HTML welcomeText; @@ -14,20 +15,25 @@ public class SimpleWelcomeWidget extends VerticalPanel implements WelcomeWidget * Creates a VerticalPanel as welcome widget with a header and a welcome message * @param headerText The text of the header component * @param welcomeText The text of the welcome message - * @param horizontalAlignment The alignment of the components in the VerticalPanel */ - public SimpleWelcomeWidget(String headerText, String welcomeText, HorizontalAlignmentConstant horizontalAlignment) { + public SimpleWelcomeWidget(String headerText, String welcomeText) { super(); - setHorizontalAlignment(horizontalAlignment); + mainPanel = new FlowPanel(); + mainPanel.setStyleName(STYLE_NAME_PREFIX + "WelcomePanel"); + add(mainPanel); + welcomeHeader = new Label(headerText); - add(welcomeHeader); + welcomeHeader.setStyleName(STYLE_NAME_PREFIX + "Header"); + mainPanel.add(welcomeHeader); this.welcomeText = new HTML(new SafeHtmlBuilder().appendEscapedLines(welcomeText).toSafeHtml()); - add(this.welcomeText); + this.welcomeText.setStyleName(STYLE_NAME_PREFIX + "WelcomeText"); + mainPanel.add(this.welcomeText); } @Override public void setWelcomeText(String welcomeText) { this.welcomeText = new HTML(new SafeHtmlBuilder().appendEscapedLines(welcomeText).toSafeHtml()); + this.welcomeText.setStyleName(STYLE_NAME_PREFIX + "WelcomeText"); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/WelcomeWidget.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/WelcomeWidget.java new file mode 100644 index 00000000000..b206e507d60 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/panels/WelcomeWidget.java @@ -0,0 +1,25 @@ +package com.sap.sailing.gwt.ui.shared.panels; + +import com.google.gwt.user.client.ui.SimplePanel; + +/** + * A WelcomeWidget displays a short message to the user to show him the functionality (or whatever) of the component on which it's displayed. + * @author Lennart Hensler (D054527) + */ +public abstract class WelcomeWidget extends SimplePanel { + + final static String STYLE_NAME_PREFIX = "welcomeWidget-"; + + /** + * Sets the text of the header component. + * @param headerText The new header text + */ + abstract void setWelcomeHeaderText(String headerText); + + /** + * Sets the text of the component under the header + * @param welcomeText The new welcome text + */ + abstract void setWelcomeText(String welcomeText); + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupCompactTable.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupCompactTable.css new file mode 100644 index 00000000000..5deab622b9c --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupCompactTable.css @@ -0,0 +1,134 @@ +@CHARSET "ISO-8859-1"; +.cellTableWidget { + border-left: 1px solid #c9caca; + border-top: 1px solid #c9caca; +} + +/** v-align images in the table header + * grey background for table header + */ +.cellTableHeader { + position: relative; + vertical-align: middle; + background-color: #e5e5e5; + border-right: 1px solid #ffffff !important; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 3px 12px; + text-align: center; +} + +.cellTableFirstColumnHeader { + position: relative; + vertical-align: middle; + background-color: #e5e5e5; + border-left: none !important; + border-right: 1px solid #ffffff !important; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 3px 12px; + text-align: center; +} + +.cellTableLastColumnHeader { + position: relative; + vertical-align: middle; + background-color: #e5e5e5; + border-right: 1px solid #c9caca !important; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 3px 12px; + text-align: center; +} + +.cellTableHeader > span > img:first-child { + position: relative; + vertical-align: middle; +} + +.cellTableEvenRow { + border-bottom: 1px solid #e5e5e5; + background-color: rgba(255,255,255,0.5); +} + +.cellTableEvenRowCell { + border-right: 1px solid #c9caca !important; + border-left: none; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 5px 17px 5px !important; + white-space: nowrap; +} + +.cellTableOddRow { + border-bottom: 1px solid #e5e5e5; + background-color: rgba(242,242,242,0.5); +} + +.cellTableOddRowCell { + border-left: none !important; + border-right: 1px solid #c9caca !important; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 5px 17px 5px !important; + white-space: nowrap; +} + +.cellTableHoveredRow { + background-color: rgba(229,242,249,0.5); + border-bottom: 1px solid #e5e5e5; +} + +.cellTableSelectedRow { + color: #000000; + background-color: rgba(229,242,249,0.5); + border-right: 2px solid #21a0e4 !important; + border-left: 2px solid #21a0e4 !important; + border: 2px solid #21a0e4; +} + +.cellTableSelectedRow > td:FIRST-CHILD { + border-left: 2px solid rgba(33,160,228,0.5) !important; +} + +.cellTableSelectedRow > td:LAST-CHILD { + border-right: 2px solid rgba(33,160,228,0.5) !important; +} + +.cellTableSelectedRowCell { + border-left: none; + border-right: 1px solid #e5e5e5; + border-top: 2px solid #21a0e4 !important; + border-bottom: 2px solid #21a0e4 !important; +} + +.cellTableRaceColumnHeader { + background-color: #e0e0e0; + padding: 3px 12px; +} + +.cellTableLegColumnHeader { + background-color: #efefef; + padding: 3px 12px; +} + +.cellTableLegDetailColumnHeader { + background-color: #f4f5f6; + padding: 3px 12px; +} + +.cellTableRaceColumn { + background-color: #e0e0e0 !important; +} + +.cellTableLegColumn { + background-color: #efefef !important; +} + +.cellTableLegDetailColumn { + background-color: #ffffff !important; +} + +.cellTableTotalColumn { + background-color: #e0e0e0 !important; +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupCompactTableResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupCompactTableResources.java new file mode 100644 index 00000000000..9aed999a0d3 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupCompactTableResources.java @@ -0,0 +1,12 @@ +package com.sap.sailing.gwt.ui.spectator; + +import com.google.gwt.user.cellview.client.CellTable; +import com.sap.sailing.gwt.ui.adminconsole.AdminConsoleTableResources.AdminConsoleTableStyle; + +public interface LeaderboardGroupCompactTableResources extends CellTable.Resources { + @Source({ CellTable.Style.DEFAULT_CSS, "LeaderboardGroupFullTable.css" }) + AdminConsoleTableStyle cellTableStyle(); + + interface LeaderboardGroupTableStyle extends CellTable.Style { + } +} 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 new file mode 100644 index 00000000000..5deab622b9c --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupFullTable.css @@ -0,0 +1,134 @@ +@CHARSET "ISO-8859-1"; +.cellTableWidget { + border-left: 1px solid #c9caca; + border-top: 1px solid #c9caca; +} + +/** v-align images in the table header + * grey background for table header + */ +.cellTableHeader { + position: relative; + vertical-align: middle; + background-color: #e5e5e5; + border-right: 1px solid #ffffff !important; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 3px 12px; + text-align: center; +} + +.cellTableFirstColumnHeader { + position: relative; + vertical-align: middle; + background-color: #e5e5e5; + border-left: none !important; + border-right: 1px solid #ffffff !important; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 3px 12px; + text-align: center; +} + +.cellTableLastColumnHeader { + position: relative; + vertical-align: middle; + background-color: #e5e5e5; + border-right: 1px solid #c9caca !important; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 3px 12px; + text-align: center; +} + +.cellTableHeader > span > img:first-child { + position: relative; + vertical-align: middle; +} + +.cellTableEvenRow { + border-bottom: 1px solid #e5e5e5; + background-color: rgba(255,255,255,0.5); +} + +.cellTableEvenRowCell { + border-right: 1px solid #c9caca !important; + border-left: none; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 5px 17px 5px !important; + white-space: nowrap; +} + +.cellTableOddRow { + border-bottom: 1px solid #e5e5e5; + background-color: rgba(242,242,242,0.5); +} + +.cellTableOddRowCell { + border-left: none !important; + border-right: 1px solid #c9caca !important; + border-top: none !important; + border-bottom: 1px solid #c9caca !important; + padding: 5px 17px 5px !important; + white-space: nowrap; +} + +.cellTableHoveredRow { + background-color: rgba(229,242,249,0.5); + border-bottom: 1px solid #e5e5e5; +} + +.cellTableSelectedRow { + color: #000000; + background-color: rgba(229,242,249,0.5); + border-right: 2px solid #21a0e4 !important; + border-left: 2px solid #21a0e4 !important; + border: 2px solid #21a0e4; +} + +.cellTableSelectedRow > td:FIRST-CHILD { + border-left: 2px solid rgba(33,160,228,0.5) !important; +} + +.cellTableSelectedRow > td:LAST-CHILD { + border-right: 2px solid rgba(33,160,228,0.5) !important; +} + +.cellTableSelectedRowCell { + border-left: none; + border-right: 1px solid #e5e5e5; + border-top: 2px solid #21a0e4 !important; + border-bottom: 2px solid #21a0e4 !important; +} + +.cellTableRaceColumnHeader { + background-color: #e0e0e0; + padding: 3px 12px; +} + +.cellTableLegColumnHeader { + background-color: #efefef; + padding: 3px 12px; +} + +.cellTableLegDetailColumnHeader { + background-color: #f4f5f6; + padding: 3px 12px; +} + +.cellTableRaceColumn { + background-color: #e0e0e0 !important; +} + +.cellTableLegColumn { + background-color: #efefef !important; +} + +.cellTableLegDetailColumn { + background-color: #ffffff !important; +} + +.cellTableTotalColumn { + background-color: #e0e0e0 !important; +} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupFullTableResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupFullTableResources.java new file mode 100644 index 00000000000..07a8677c30f --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupFullTableResources.java @@ -0,0 +1,12 @@ +package com.sap.sailing.gwt.ui.spectator; + +import com.google.gwt.user.cellview.client.CellTable; +import com.sap.sailing.gwt.ui.adminconsole.AdminConsoleTableResources.AdminConsoleTableStyle; + +public interface LeaderboardGroupFullTableResources extends CellTable.Resources { + @Source({ CellTable.Style.DEFAULT_CSS, "LeaderboardGroupCompactTable.css" }) + AdminConsoleTableStyle cellTableStyle(); + + interface LeaderboardGroupTableStyle extends CellTable.Style { + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupPanel.java index 9b0a145f218..6e51ea7a41c 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupPanel.java @@ -13,50 +13,61 @@ import com.google.gwt.user.cellview.client.CellTable; import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; -import com.google.gwt.user.client.ui.CaptionPanel; +import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.HTML; -import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.view.client.NoSelectionModel; import com.sap.sailing.domain.common.EventNameAndRaceName; import com.sap.sailing.gwt.ui.adminconsole.LeaderboardConfigPanel.AnchorCell; import com.sap.sailing.gwt.ui.client.ErrorReporter; +import com.sap.sailing.gwt.ui.client.HasWelcomeWidget; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.shared.LeaderboardDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; import com.sap.sailing.gwt.ui.shared.RaceInLeaderboardDTO; -import com.sap.sailing.gwt.ui.shared.components.HasWelcomeWidget; +import com.sap.sailing.gwt.ui.shared.panels.WelcomeWidget; public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget { interface AnchorTemplates extends SafeHtmlTemplates { - @SafeHtmlTemplates.Template("{1}") - SafeHtml anchor(String url, String displayName); + @SafeHtmlTemplates.Template("{1}") + SafeHtml anchor(String url, String displayName, String styleClass); + } + + interface TextWithClassTemplate extends SafeHtmlTemplates { + @SafeHtmlTemplates.Template("{0}") + SafeHtml textWithClass(String text, String styleClass); } private static final AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class); - private static final int MAX_COLUMNS_IN_ROW = 10; + private static final TextWithClassTemplate TEXTTEMPLATE = GWT.create(TextWithClassTemplate.class); + private static final int MAX_COLUMNS_IN_ROW = 10; + private static final String STYLE_NAME_PREFIX = "leaderboardGroupPanel-"; private SailingServiceAsync sailingService; private StringMessages stringConstants; private ErrorReporter errorReporter; private LeaderboardGroupDTO group; + private String root; - private VerticalPanel mainPanel; + private FlowPanel mainPanel; private Widget welcomeWidget = null; public LeaderboardGroupPanel(SailingServiceAsync sailingService, StringMessages stringConstants, - ErrorReporter errorReporter, final String groupName) { + ErrorReporter errorReporter, final String groupName, String root) { super(); this.sailingService = sailingService; this.stringConstants = stringConstants; this.errorReporter = errorReporter; + this.root = root; + if (this.root == null || this.root.length() == 0) { + this.root = "leaderboardGroupPanel"; + } - mainPanel = new VerticalPanel(); + mainPanel = new FlowPanel(); mainPanel.setWidth("95%"); add(mainPanel); final Runnable buildGUI = new Runnable() { @@ -90,23 +101,27 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget private void buildGUI() { //Create group details GUI - HorizontalPanel groupDetailsPanel = new HorizontalPanel(); - groupDetailsPanel.setSpacing(8); + FlowPanel groupDetailsPanel = new FlowPanel(); + groupDetailsPanel.setStyleName(STYLE_NAME_PREFIX + "GroupDetailsPanel"); mainPanel.add(groupDetailsPanel); - + Label groupNameLabel = new Label(group.name + ":"); + groupNameLabel.setStyleName(STYLE_NAME_PREFIX + "GroupName"); groupDetailsPanel.add(groupNameLabel); //Using HTML to display the line breaks in the description HTML groupDescriptionLabel = new HTML(new SafeHtmlBuilder().appendEscapedLines(group.description).toSafeHtml()); + groupDescriptionLabel.setStyleName(STYLE_NAME_PREFIX + "GroupDescription"); groupDetailsPanel.add(groupDescriptionLabel); //Create group leaderboards GUI - CaptionPanel leaderboardsCaptionPanel = new CaptionPanel(stringConstants.leaderboards()); - mainPanel.add(leaderboardsCaptionPanel); + Label leaderboardsTableLabel = new Label(stringConstants.leaderboards()); + leaderboardsTableLabel.setStyleName(STYLE_NAME_PREFIX + "LeaderboardsTableLabel"); + mainPanel.add(leaderboardsTableLabel); if (group.leaderboards.size() <= MAX_COLUMNS_IN_ROW) { - CellTable leaderboardsTable = new CellTable(); + LeaderboardGroupFullTableResources tableResources = GWT.create(LeaderboardGroupFullTableResources.class); + CellTable leaderboardsTable = new CellTable(200, tableResources); leaderboardsTable.setWidth("100%"); leaderboardsTable.setSelectionModel(new NoSelectionModel()); @@ -133,7 +148,7 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget } leaderboardsTable.setRowData(tableData); - leaderboardsCaptionPanel.add(leaderboardsTable); + mainPanel.add(leaderboardsTable); } else { AnchorCell nameAnchorCell = new AnchorCell(); Column nameColumn = new Column(nameAnchorCell) { @@ -141,9 +156,9 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget public SafeHtml getValue(LeaderboardDTO leaderboard) { String debugParam = Window.Location.getParameter("gwt.codesvr"); return ANCHORTEMPLATE.anchor("/gwt/Leaderboard.html?name=" + leaderboard.name - + "&leaderboardGroupName=" + group.name + + "&leaderboardGroupName=" + group.name + "&root=" + root + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""), - leaderboard.name); + leaderboard.name, STYLE_NAME_PREFIX + "ActiveLeaderboard"); } }; @@ -155,7 +170,8 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget } }; - CellTable leaderboardsTable = new CellTable(); + LeaderboardGroupCompactTableResources tableResources = GWT.create(LeaderboardGroupCompactTableResources.class); + CellTable leaderboardsTable = new CellTable(200, tableResources); leaderboardsTable.setWidth("100%"); leaderboardsTable.setSelectionModel(new NoSelectionModel()); @@ -165,7 +181,7 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget leaderboardsTable.setColumnWidth(racesColumn, "70%"); leaderboardsTable.setRowData(group.leaderboards); - leaderboardsCaptionPanel.add(leaderboardsTable); + mainPanel.add(leaderboardsTable); } } @@ -174,18 +190,19 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget SafeHtmlBuilder b = new SafeHtmlBuilder(); String displayName = race.getRaceColumnName(); if (race.getRaceColumnName().equals(stringConstants.overview())) { - String link = "/gwt/Leaderboard.html?name=" + leaderboard.name + "&leaderboardGroupName=" + group.name + - (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr="+debugParam : ""); - b.append(ANCHORTEMPLATE.anchor(link, displayName)); + String link = "/gwt/Leaderboard.html?name=" + leaderboard.name + "&leaderboardGroupName=" + group.name + + "&root=" + root + + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""); + b.append(ANCHORTEMPLATE.anchor(link, displayName, STYLE_NAME_PREFIX + "ActiveLeaderboard")); } else { if (race.getRaceIdentifier() != null) { EventNameAndRaceName raceId = (EventNameAndRaceName) race.getRaceIdentifier(); String link = "/gwt/RaceBoard.html?leaderboardName=" + leaderboard.name + "&raceName=" + raceId.getRaceName() - + "&eventName=" + raceId.getEventName() + "&leaderboardGroupName=" + group.name + + "&eventName=" + raceId.getEventName() + "&leaderboardGroupName=" + group.name + "&root=" + root + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""); - b.append(ANCHORTEMPLATE.anchor(link, displayName)); + b.append(ANCHORTEMPLATE.anchor(link, displayName, STYLE_NAME_PREFIX + "ActiveRace")); } else { - b.appendHtmlConstant(race.getRaceColumnName()); + b.append(TEXTTEMPLATE.textWithClass(race.getRaceColumnName(), STYLE_NAME_PREFIX + "InactiveRace")); } } return b.toSafeHtml(); @@ -201,12 +218,12 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget } if (race.getRaceIdentifier() != null) { EventNameAndRaceName raceId = (EventNameAndRaceName) race.getRaceIdentifier(); - String link = "/gwt/RaceBoard.html?leaderboardName=" + leaderboard.name + "&raceName=" + String link = "/gwt/RaceBoard.html?leaderboardName=" + leaderboard.name + "&raceName=" + "&root=" + root + raceId.getRaceName() + "&eventName=" + raceId.getEventName() + "&leaderboardGroupName=" + group.name + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""); - b.append(ANCHORTEMPLATE.anchor(link, race.getRaceColumnName())); + b.append(ANCHORTEMPLATE.anchor(link, race.getRaceColumnName(), STYLE_NAME_PREFIX + "ActiveRace")); } else { - b.appendHtmlConstant(race.getRaceColumnName()); + b.append(TEXTTEMPLATE.textWithClass(race.getRaceColumnName(), STYLE_NAME_PREFIX + "InactiveRace")); } first = false; } @@ -221,7 +238,7 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget } @Override - public void setWelcomeWidget(Widget welcome) { + public void setWelcomeWidget(WelcomeWidget welcome) { boolean needsToBeInserted = welcomeWidget == null; welcomeWidget = welcome; welcomeWidget.setWidth("100%"); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/SpectatorEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/SpectatorEntryPoint.java index c409b0c0c33..fb644226652 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/SpectatorEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/SpectatorEntryPoint.java @@ -8,8 +8,7 @@ import com.sap.sailing.gwt.ui.client.AbstractEntryPoint; import com.sap.sailing.gwt.ui.client.EventRefresher; import com.sap.sailing.gwt.ui.client.LogoAndTitlePanel; import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; -import com.sap.sailing.gwt.ui.shared.components.ClosableWelcomeWidget; -import com.sap.sailing.gwt.ui.shared.components.SimpleWelcomeWidget; +import com.sap.sailing.gwt.ui.shared.panels.ClosableWelcomeWidget; /** * @@ -22,9 +21,7 @@ public class SpectatorEntryPoint extends AbstractEntryPoint implements EventRefr public void onModuleLoad() { super.onModuleLoad(); - //Fill fixed leaderboard selection String groupParamValue = Window.Location.getParameter("leaderboardGroupName"); - final String groupName; if(groupParamValue == null || groupParamValue.isEmpty()) { groupName = null; @@ -40,6 +37,11 @@ public class SpectatorEntryPoint extends AbstractEntryPoint implements EventRefr }); } + String root = Window.Location.getParameter("root"); + //Check if the root contains an allowed value + if (root != null) { + root = (root.equals("leaderboardGroupPanel") || root.equals("overview")) ? root : null; + } RootPanel rootPanel = RootPanel.get(); rootPanel.setSize("100%", "100%"); @@ -52,10 +54,10 @@ public class SpectatorEntryPoint extends AbstractEntryPoint implements EventRefr if (groupName == null) { panelToDisplay = new OverviewEventPanel(sailingService, this, this, stringMessages); } else { - panelToDisplay = new LeaderboardGroupPanel(sailingService, stringMessages, this, groupName); + panelToDisplay = new LeaderboardGroupPanel(sailingService, stringMessages, this, groupName, root); LeaderboardGroupPanel groupPanel = (LeaderboardGroupPanel) panelToDisplay; groupPanel.setWelcomeWidget(new ClosableWelcomeWidget(true, stringMessages.welcomeToSailingAnalytics(), - "Ipsum lorum\nHello World!", SimpleWelcomeWidget.ALIGN_RIGHT, stringMessages)); + "Ipsum lorum\nHello World!", stringMessages)); } panelToDisplay.setSize("100%", "100%"); rootPanel.add(panelToDisplay); diff --git a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/Spectator.gwt.xml b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/Spectator.gwt.xml index 34ff6acbe67..151f75089c2 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/Spectator.gwt.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/Spectator.gwt.xml @@ -25,7 +25,6 @@ -