Merge remote-tracking branch 'origin/sprint4_master' into Story877

# Conflicts:
#	mock/src/main/java/seng302/DataInput/BoatXMLReader.java
#	mock/src/main/java/seng302/DataInput/XMLReader.java
#	mock/src/main/java/seng302/Model/Boat.java
#	mock/src/main/java/seng302/Model/CompoundMark.java
#	mock/src/main/java/seng302/Model/Leg.java
#	mock/src/main/java/seng302/Model/Mark.java
#	mock/src/main/java/seng302/Model/Marker.java
#	mock/src/main/java/seng302/Model/Race.java
#	mock/src/test/java/seng302/Model/LegTest.java
#	visualiser/src/main/java/seng302/Controllers/RaceController.java
#	visualiser/src/main/java/seng302/Mock/StreamedRace.java
#	visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java
#	visualiser/src/main/resources/scenes/race.fxml
This commit is contained in:
Fan-Wu Yang
2017-05-24 22:57:31 +12:00
54 changed files with 3763 additions and 830 deletions
@@ -1,6 +1,8 @@
package seng302.Model;
import javafx.scene.Node;
import javafx.scene.layout.Pane;
import javafx.collections.ObservableList;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
@@ -10,9 +12,11 @@ import seng302.Mock.StreamedCourse;
import seng302.RaceDataSource;
import seng302.RaceMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
/**
* This creates a JavaFX Canvas that is fills it's parent.
@@ -27,9 +31,14 @@ public class ResizableRaceCanvas extends ResizableCanvas {
private boolean annoAbbrev = true;
private boolean annoSpeed = true;
private boolean annoPath = true;
private boolean annoTimeSinceLastMark = true;
private List<Color> colours;
private final List<Marker> markers;
private final RaceDataSource raceData;
private Map<Integer, Color> boatColours = new HashMap<>();
private Node arrow;
private RaceClock raceClock;
public ResizableRaceCanvas(RaceDataSource raceData) {
super();
@@ -53,6 +62,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
*/
public void setBoats(List<Boat> boats) {
this.boats = boats;
mapBoatColours();
}
@@ -139,6 +149,13 @@ public class ResizableRaceCanvas extends ResizableCanvas {
gc.restore();
}
private void displayFancyArrow(GraphCoordinate coordinate, double angle) {
angle = angle % 360;
if (arrow != null && arrow.getRotate() != angle) {
arrow.setRotate(angle);
}
}
/**
* Rotates things on the canvas Note: this must be called in between gc.save() and gc.restore() else they will rotate everything
*
@@ -158,8 +175,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
* @param abbrev abbreviation of the boat name
* @param speed speed of the boat
* @param coordinate coordinate the text appears
* @param timeSinceLastMark time since the last mark was passed
*/
private void displayText(String name, String abbrev, double speed, GraphCoordinate coordinate) {
private void displayText(String name, String abbrev, double speed, GraphCoordinate coordinate, ZonedDateTime timeSinceLastMark) {
String text = "";
//Check name toggle value
if (annoName){
@@ -171,7 +189,12 @@ public class ResizableRaceCanvas extends ResizableCanvas {
}
//Check speed toggle value
if (annoSpeed){
text += String.format("%.2fkn", speed);
text += String.format("%.2fkn ", speed);
}
//Check time since last mark toggle value
if(annoTimeSinceLastMark){
Duration timeSince = Duration.between(timeSinceLastMark, raceClock.getTime());
text += String.format("%d", timeSince.getSeconds());
}
//String text = String.format("%s, %2$.2fkn", name, speed);
long xCoord = coordinate.getX() + 20;
@@ -233,9 +256,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
//display wind direction arrow - specify origin point and angle - angle now set to random angle
if (raceData instanceof StreamedCourse) {
displayArrow(new GraphCoordinate((int) getWidth() - 40, 40), ((StreamedCourse) raceData).getWindDirection());
displayFancyArrow(new GraphCoordinate((int) getWidth() - 40, 40), ((StreamedCourse) raceData).getWindDirection());
} else {
displayArrow(new GraphCoordinate((int) getWidth() - 40, 40), 150);
displayFancyArrow(new GraphCoordinate((int) getWidth() - 40, 40), 150);
}
}
@@ -248,12 +271,17 @@ public class ResizableRaceCanvas extends ResizableCanvas {
}
/**
* Toggles the path of the boat
* Toggle boat path display in annotation
*/
public void toggleBoatPath() {
annoPath = !annoPath;
}
/**
* Toggle boat time display in annotation
*/
public void toggleAnnoTime() { annoTimeSinceLastMark = !annoTimeSinceLastMark;}
/**
* Toggle abbreviation display in annotation
*/
@@ -272,26 +300,29 @@ public class ResizableRaceCanvas extends ResizableCanvas {
* Draws boats while race in progress, when leg heading is set.
*/
private void updateBoats() {
int currentColour = 0;
if (boats != null) {
if (boatColours.size() < boats.size()) mapBoatColours();
for (Boat boat : boats) {
boolean finished = boat.getCurrentLeg().getName().equals("Finish") || boat.getCurrentLeg().getName().equals("DNF");
boolean isStart = boat.isStarted();
int sourceID = boat.getSourceID();
if (!finished && isStart) {
displayBoat(boat, boat.getHeading(), colours.get(currentColour));
displayBoat(boat, boat.getHeading(), boatColours.get(sourceID));
GraphCoordinate wakeFrom = this.map.convertGPS(boat.getCurrentPosition());
GraphCoordinate wakeTo = this.map.convertGPS(boat.getWake());
displayLine(wakeFrom, wakeTo, colours.get(currentColour));
displayLine(wakeFrom, wakeTo, boatColours.get(sourceID));
} else if (!isStart) {
displayBoat(boat, boat.getHeading(), colours.get(currentColour));
displayBoat(boat, boat.getHeading(), boatColours.get(sourceID));
} else {
displayBoat(boat, 0, colours.get(currentColour));
displayBoat(boat, 0, boatColours.get(sourceID));
}
displayText(boat.toString(), boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition()));
if (Duration.between(boat.getTimeSinceLastMark(), raceClock.getTime()).getSeconds() < 0) {
boat.setTimeSinceLastMark(raceClock.getTime());
}
displayText(boat.toString(), boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition()), boat.getTimeSinceLastMark());
//TODO this needs to be fixed.
drawTrack(boat, colours.get(currentColour));
currentColour = (currentColour + 1) % colours.size();
drawTrack(boat, boatColours.get(sourceID));
}
}
}
@@ -299,6 +330,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
/**
* Draws all track points for a given boat. Colour is set by boat, opacity by track point.
* @param boat whose track is displayed
* @param colour The color to use for the track.
* @see seng302.Model.TrackPoint
*/
private void drawTrack(Boat boat, Color colour) {
@@ -328,4 +360,22 @@ public class ResizableRaceCanvas extends ResizableCanvas {
));
}
}
public void setArrow(Node arrow) {
this.arrow = arrow;
}
public void setRaceClock(RaceClock raceClock) {
this.raceClock = raceClock;
}
private void mapBoatColours() {
int currentColour = 0;
for (Boat boat : boats) {
if (!boatColours.containsKey(boat.getSourceID())) {
boatColours.put(boat.getSourceID(), colours.get(currentColour));
}
currentColour = (currentColour + 1) % colours.size();
}
}
}