You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

303 lines
10 KiB

package seng302.Controllers;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import seng302.Mock.StreamedRace;
import seng302.Model.*;
import seng302.VisualiserInput;
import java.awt.Color;
import java.net.URL;
import java.util.*;
import java.util.List;
/**
* Created by fwy13 on 15/03/2017.
*/
public class RaceController extends Controller {
@FXML GridPane canvasBase;
//user saved data for annotation display
private ArrayList<Boolean> presetAnno;
private ArrayList<Boat> startBoats;
private Integer sparkLineNumber = 0;
private ResizableRaceCanvas raceMap;
private ResizableRaceMap raceBoundaries;
private ArrayList colours;
@FXML SplitPane race;
@FXML CheckBox showFPS;
@FXML CheckBox showBoatPath;
@FXML CheckBox showAnnotations;
@FXML Label timer;
@FXML Label FPS;
@FXML Label timeZone;
@FXML CheckBox showName;
@FXML CheckBox showAbbrev;
@FXML CheckBox showSpeed;
@FXML Button saveAnno;
@FXML Button showSetAnno;
@FXML TableView<Boat> boatInfoTable;
@FXML TableColumn<Boat, String> boatPlacingColumn;
@FXML TableColumn<Boat, String> boatTeamColumn;
@FXML TableColumn<Boat, String> boatMarkColumn;
@FXML TableColumn<Boat, String> boatSpeedColumn;
@FXML LineChart<Number, Number> sparklineChart;
@FXML NumberAxis xAxis;
@FXML NumberAxis yAxis;
/**
* Updates the ResizableRaceCanvas (raceMap) with most recent data
*
* @param boats boats that are to be displayed in the race
* @param boatMarkers Markers for boats
* @see ResizableRaceCanvas
*/
public void updateMap(ObservableList<Boat> boats, ObservableList<Marker> boatMarkers) {
raceMap.setBoats(boats);
raceMap.setBoatMarkers(boatMarkers);
raceMap.update();
raceBoundaries.draw();
//stop if the visualiser is no longer running
}
/**
* Updates the array listened by the TableView (boatInfoTable) that displays the boat information.
*
* @param race Race to listen to.
*/
public void setInfoTable(StreamedRace race) {
//boatInfoTable.getItems().clear();
ObservableList<Boat> startingBoats = race.getStartingBoats();
boatInfoTable.setItems(race.getStartingBoats());
boatTeamColumn.setCellValueFactory(cellData -> cellData.getValue().getName());
boatSpeedColumn.setCellValueFactory(cellData -> cellData.getValue().getVelocityProp());
boatMarkColumn.setCellValueFactory(cellData -> cellData.getValue().getCurrentLegName());
boatPlacingColumn.setCellValueFactory(cellData -> cellData.getValue().positionProperty());
}
@Override
public void initialize(URL location, ResourceBundle resources) {
//createSparkLine();
//listener for fps
startBoats = new ArrayList<>();
showFPS.selectedProperty().addListener((ov, old_val, new_val) -> {
if (showFPS.isSelected()) {
FPS.setVisible(true);
} else {
FPS.setVisible(false);
}
});
}
public void createSparkLine(ObservableList<Boat> boats){
// TODO replace for loop with boatsInRace
//int [] boats = {1, 2, 3, 4, 5, 6};
// set a line for each boat
makeColours();
System.out.println(colours.get(0));
for (Boat boat : boats){
startBoats.add(boat);
}
for (int i=0; i<startBoats.size(); i++){
XYChart.Series<Number, Number> series = new XYChart.Series();
series.getData().add(new XYChart.Data(0, i+1));
sparklineChart.getData().add(series);
}
// reverse Y axis order (0 at top) and set axis height/width
// TODO change lower bound to boatsInRace + 1
yAxis.setLowerBound(startBoats.size()+1);
yAxis.setUpperBound(0);
yAxis.setAutoRanging(false);
xAxis.setAutoRanging(false);
sparklineChart.setCreateSymbols(false);
sparklineChart.setStyle(".default-color0.chart-series-line { -fx-stroke: #e9967a; }");
// hide axis ticks and labels
sparklineChart.getXAxis().setTickLabelsVisible(false);
sparklineChart.getYAxis().setTickLabelsVisible(false);
sparklineChart.getXAxis().setTickMarkVisible(false);
sparklineChart.getYAxis().setTickMarkVisible(false);
sparklineChart.getXAxis().
lookup(".axis-minor-tick-mark").setVisible(false);
sparklineChart.getYAxis().
lookup(".axis-minor-tick-mark").setVisible(false);
}
/**
* Initializes and runs the race, based on the user's chosen scale factor
* Currently uses an example racecourse
*
* @param visualiserInput input from network
* @param raceClock The RaceClock to use for the race's countdown/elapsed duration + timezone.
*/
public void startRace(VisualiserInput visualiserInput, RaceClock raceClock) {
StreamedRace newRace = new StreamedRace(visualiserInput, this);
//newRace.initialiseBoats();
raceMap = new ResizableRaceCanvas(visualiserInput.getCourse());
raceMap.setMouseTransparent(true);
raceMap.widthProperty().bind(canvasBase.widthProperty());
raceMap.heightProperty().bind(canvasBase.heightProperty());
//raceMap.setBoats(newRace.getStartingBoats());
raceMap.draw();
raceMap.setVisible(true);
canvasBase.getChildren().add(0, raceMap);
raceBoundaries = new ResizableRaceMap(visualiserInput.getCourse());
raceBoundaries.setMouseTransparent(true);
raceBoundaries.widthProperty().bind(canvasBase.widthProperty());
raceBoundaries.heightProperty().bind(canvasBase.heightProperty());
raceBoundaries.draw();
raceBoundaries.setVisible(true);
canvasBase.getChildren().add(0, raceBoundaries);
race.setVisible(true);
//Initialize save annotation array, fps listener, and annotation listeners
timeZone.setText(raceClock.getTimeZone());
timer.textProperty().bind(raceClock.durationProperty());
initializeFPS();
initializeAnnotations();
new Thread((newRace)).start();
}
public void finishRace(ObservableList<Boat> boats){
race.setVisible(false);
parent.enterFinish(boats);
}
/**
* Set the value for the race clock label
*
* @param time time that the label will be updated to
*/
public void setTimer(String time) {
//timer.setText(time);
}
/**
* Set the value for the fps label
*
* @param fps fps that the label will be updated to
*/
public void setFrames(String fps) {
FPS.setText((fps));
}
/**
* Set up FPS display at bottom of screen
*/
private void initializeFPS() {
showFPS.setVisible(true);
showFPS.selectedProperty().addListener((ov, old_val, new_val) -> {
if (showFPS.isSelected()) {
FPS.setVisible(true);
} else {
FPS.setVisible(false);
}
});
}
public void updateSparkline(ObservableList<Boat> boatsInRace){
// TODO replace for loops with correct boats - Done
//int [] startingBoats = {1, 2, 3, 4, 5, 6};
//int [] boatsInRace = {1, 2, 3, 4, 5, 6};
int colourIndex = 0;
int placingVal = boatsInRace.size();
sparkLineNumber++;
for (int i=0; i<boatsInRace.size(); i++){
for (int j=0; j<startBoats.size(); j++){
if (boatsInRace.get(i)==startBoats.get(j)){
sparklineChart.getData().get(j).getData().add(new XYChart.Data<>
(sparkLineNumber, placingVal));
sparklineChart.getData().get(j).getNode().setStyle("-fx-stroke: "+colours.get(colourIndex)+";");
colourIndex+=1;
placingVal-=1;
}
}
}
xAxis.setUpperBound(sparkLineNumber);
}
private void makeColours() {
colours = new ArrayList<>(Arrays.asList(
"#8A2BE2",
"#000000",
"#FF0000",
"#FFA500",
"#556B2F",
"#32CD32",
"#800080",
"#A9A9A9",
"#FFFF00"
));
}
/**
* Set up boat annotations
*/
private void initializeAnnotations() {
presetAnno = new ArrayList<>();
//listener for annotation
showAnnotations.selectedProperty().addListener((ov, old_val, new_val) -> {
raceMap.toggleAnnotations();
raceMap.update();
});
//listener for show name in annotation
showName.selectedProperty().addListener((ov, old_val, new_val) -> {
raceMap.toggleAnnoName();
raceMap.update();
});
//listener for show abbreviation for annotation
showAbbrev.selectedProperty().addListener((ov, old_val, new_val) -> {
raceMap.toggleAnnoAbbrev();
raceMap.update();
});
//listener for show boat path for annotation
showBoatPath.selectedProperty().addListener((ov, old_val, new_val) -> {
raceMap.toggleBoatPath();
raceMap.update();
});
//listener to show speed for annotation
showSpeed.selectedProperty().addListener((ov, old_val, new_val) -> {
raceMap.toggleAnnoSpeed();
raceMap.update();
});
//listener to save currently selected annotation
saveAnno.setOnAction(event -> {
presetAnno.clear();
presetAnno.add(showName.isSelected());
presetAnno.add(showAbbrev.isSelected());
presetAnno.add(showSpeed.isSelected());
presetAnno.add(showBoatPath.isSelected());
});
//listener to show saved annotation
showSetAnno.setOnAction(event -> {
if (presetAnno.size() > 0) {
showName.setSelected(presetAnno.get(0));
showAbbrev.setSelected(presetAnno.get(1));
showSpeed.setSelected(presetAnno.get(2));
showBoatPath.setSelected(presetAnno.get(3));
raceMap.update();
}
});
}
}