diff --git a/src/main/java/seng302/controllers/Controller.java b/src/main/java/seng302/controllers/Controller.java index 9d964243..faa67cc4 100644 --- a/src/main/java/seng302/controllers/Controller.java +++ b/src/main/java/seng302/controllers/Controller.java @@ -18,12 +18,8 @@ import seng302.models.Yacht; import seng302.models.parsers.StreamParser; import seng302.models.parsers.XMLParser; - import java.io.IOException; import java.net.URL; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; import java.util.ResourceBundle; import java.util.Timer; import java.util.TimerTask; @@ -56,6 +52,7 @@ public class Controller implements Initializable { try{ contentPane.getChildren().removeAll(); contentPane.getChildren().clear(); + contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); contentPane.getChildren().addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl))); } catch(javafx.fxml.LoadException e){ @@ -71,6 +68,8 @@ public class Controller implements Initializable { //DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); //format.setTimeZone(TimeZone.getTimeZone("GMT-8")); //realTime.setText(format.format(new Date())); + contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); + teamList.getStylesheets().add(getClass().getResource("/css/master.css").toString()); } /** @@ -138,7 +137,9 @@ public class Controller implements Initializable { private void updateTeamList() { ObservableList data = FXCollections.observableArrayList(); + teamList.setItems(data); + boatNameCol.setCellValueFactory( new PropertyValueFactory<>("boatName") ); diff --git a/src/main/java/seng302/controllers/ImportantAnnotationController.java b/src/main/java/seng302/controllers/ImportantAnnotationController.java new file mode 100644 index 00000000..e1a031cf --- /dev/null +++ b/src/main/java/seng302/controllers/ImportantAnnotationController.java @@ -0,0 +1,125 @@ +package seng302.controllers; + +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Stage; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.ResourceBundle; + +public class ImportantAnnotationController implements Initializable { + /* + * JavaFX Outlets + */ + @FXML + private CheckBox boatWakeSelect; + + @FXML + private CheckBox boatSpeedSelect; + + @FXML + private CheckBox boatTrackSelect; + + @FXML + private CheckBox boatNameSelect; + + @FXML + private AnchorPane annotationSelectWindow; + + @FXML + private Button closeButton; + + private RaceViewController parent; + private Map importantAnnotations; + private Stage stage; + + ImportantAnnotationController(RaceViewController parent, Stage stage){ + this.parent = parent; + importantAnnotations = new HashMap<>(); + this.stage = stage; + } + + /** + * Sets whether or not an annotation is considered important + * @param name The annotation name + * @param isSet True if annotation is important + */ + private void setAnnotation(String name, Boolean isSet){ + importantAnnotations.put(name, isSet); + } + + /** + * Sends an update to the parent controller when the important + * annotations have changed + */ + private void sendUpdate(){ + this.parent.importantAnnotationsChanged(this.importantAnnotations); + } + + /** + * Load the current state of the 'important annotations' + * @param currentState hashmap containing the states of each annotation + */ + void loadState(Map currentState){ + this.importantAnnotations = currentState; + + // Initialise checkboxes + for (String key : importantAnnotations.keySet()){ + switch (key){ + case "BoatWake": + boatWakeSelect.setSelected(importantAnnotations.get(key)); + break; + + case "BoatSpeed": + boatSpeedSelect.setSelected(importantAnnotations.get(key)); + break; + + case "BoatTrack": + boatTrackSelect.setSelected(importantAnnotations.get(key)); + break; + + case "BoatName": + boatNameSelect.setSelected(importantAnnotations.get(key)); + break; + + default: + break; + } + } + } + + /** + * View did load + * @param location . + * @param resources . + */ + @Override + public void initialize(URL location, ResourceBundle resources) { + boatWakeSelect.setOnAction(event -> { + setAnnotation("BoatWake", boatWakeSelect.isSelected()); + sendUpdate(); + }); + + boatSpeedSelect.setOnAction(event -> { + setAnnotation("BoatSpeed", boatSpeedSelect.isSelected()); + sendUpdate(); + }); + + boatTrackSelect.setOnAction(event -> { + setAnnotation("BoatTrack", boatTrackSelect.isSelected()); + sendUpdate(); + }); + + boatNameSelect.setOnAction(event -> { + setAnnotation("BoatName", boatNameSelect.isSelected()); + sendUpdate(); + }); + + closeButton.setOnAction(event -> stage.close()); + } +} diff --git a/src/main/java/seng302/controllers/RaceViewController.java b/src/main/java/seng302/controllers/RaceViewController.java index 12069084..433e47a2 100644 --- a/src/main/java/seng302/controllers/RaceViewController.java +++ b/src/main/java/seng302/controllers/RaceViewController.java @@ -1,26 +1,27 @@ package seng302.controllers; -import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; -import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.Slider; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; import javafx.scene.text.Text; import javafx.stage.Stage; +import javafx.stage.StageStyle; import javafx.util.Duration; import javafx.util.StringConverter; import seng302.models.*; -import seng302.models.parsers.ConfigParser; import seng302.models.parsers.StreamParser; import java.io.IOException; @@ -43,6 +44,8 @@ public class RaceViewController extends Thread{ @FXML private Slider annotationSlider; @FXML + private Button selectAnnotationBtn; + @FXML private CanvasController includedCanvasController; private ArrayList startingBoats = new ArrayList<>(); @@ -52,6 +55,8 @@ public class RaceViewController extends Thread{ private ArrayList boatOrder = new ArrayList<>(); private Race race; private Stage stage; + private Integer annotationLevel; + private Map importantAnnotations = new HashMap<>(); public void initialize() { @@ -79,9 +84,53 @@ public class RaceViewController extends Thread{ // windDirectionText.setText(String.format("%.1f°", windDirection)); // windArrowText.setRotate(windDirection); includedCanvasController.timer.start(); + + selectAnnotationBtn.setOnAction(event -> { + loadSelectAnnotationView(); + }); } + /** + * Important annotations have been changed, update this view + * @param newImportantAnnotations HashMap containing whether or not annotations + * are important + */ + void importantAnnotationsChanged(Map newImportantAnnotations){ + this.importantAnnotations = newImportantAnnotations; + setAnnotations((int)annotationSlider.getValue()); + } + /** + * Loads the "select annotations" view in a new window + */ + private void loadSelectAnnotationView() { + try { + FXMLLoader fxmlLoader = new FXMLLoader(); + Stage stage = new Stage(); + + // Set controller + ImportantAnnotationController controller = new ImportantAnnotationController(this, stage); + fxmlLoader.setController(controller); + + // Load FXML and set CSS + fxmlLoader.setLocation(getClass().getResource("/views/importantAnnotationSelectView.fxml")); + Scene scene = new Scene(fxmlLoader.load(), 469, 248); + scene.getStylesheets().add(getClass().getResource("/css/master.css").toString()); + stage.initStyle(StageStyle.UNDECORATED); + + stage.setScene(scene); + stage.show(); + + controller.loadState(importantAnnotations); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + Map getImportantAnnotations(){ + return importantAnnotations; + } private void initializeSettings() { displayFps = true; @@ -93,13 +142,13 @@ public class RaceViewController extends Thread{ } }); - //SLIFER STUFF BELOW + //SLIDER STUFF BELOW annotationSlider.setLabelFormatter(new StringConverter() { @Override public String toString(Double n) { if (n == 0) return "None"; if (n == 1) return "Low"; - if (n == 2) return "Medium"; + if (n == 2) return "Important"; if (n == 3) return "All"; return "All"; @@ -112,7 +161,7 @@ public class RaceViewController extends Thread{ return 0d; case "Low": return 1d; - case "Medium": + case "Important": return 2d; case "All": return 3d; @@ -303,6 +352,7 @@ public class RaceViewController extends Thread{ private void showOrder() { positionVbox.getChildren().clear(); positionVbox.getChildren().removeAll(); + positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString()); // for (Boat boat : boatOrder) { // positionVbox.getChildren().add(new Text(boat.getShortName() + " " + boat.getSpeedInKnots() + " Knots")); @@ -310,11 +360,17 @@ public class RaceViewController extends Thread{ for (Yacht boat : StreamParser.getBoatsPos().values()) { if (boat.getBoatStatus() == 3) { // 3 is finish status - positionVbox.getChildren().add(new Text(boat.getPosition() + ". " + - boat.getShortName() + " (Finished)")); + Text textToAdd = new Text(boat.getPosition() + ". " + + boat.getShortName() + " (Finished)"); + textToAdd.setFill(Paint.valueOf("#d3d3d3")); + positionVbox.getChildren().add(textToAdd); + } else { - positionVbox.getChildren().add(new Text(boat.getPosition() + ". " + - boat.getShortName() + " ")); + Text textToAdd = new Text(boat.getPosition() + ". " + + boat.getShortName() + " "); + textToAdd.setFill(Paint.valueOf("#d3d3d3")); + textToAdd.setStyle(""); + positionVbox.getChildren().add(textToAdd); } } @@ -401,14 +457,39 @@ public class RaceViewController extends Thread{ } } break; + // Important Annotations case 2: for (RaceObject ro : includedCanvasController.getRaceObjects()) { if(ro instanceof BoatGroup) { BoatGroup bg = (BoatGroup) ro; - bg.setTeamNameObjectVisible(true); - bg.setVelocityObjectVisible(false); - bg.setLineGroupVisible(true); - bg.setWakeVisible(false); + + if (importantAnnotations.containsKey("BoatName") && importantAnnotations.get("BoatName")){ + bg.setTeamNameObjectVisible(true); + } + else{ + bg.setTeamNameObjectVisible(false); + } + + if (importantAnnotations.containsKey("BoatSpeed") && importantAnnotations.get("BoatSpeed")){ + bg.setVelocityObjectVisible(true); + } + else{ + bg.setTeamNameObjectVisible(false); + } + + if (importantAnnotations.containsKey("BoatTrack") && importantAnnotations.get("BoatTrack")){ + bg.setLineGroupVisible(true); + } + else{ + bg.setLineGroupVisible(false); + } + + if (importantAnnotations.containsKey("BoatWake") && importantAnnotations.get("BoatWake")){ + bg.setWakeVisible(true); + } + else{ + bg.setWakeVisible(false); + } } } break; diff --git a/src/main/resources/css/master.css b/src/main/resources/css/master.css new file mode 100644 index 00000000..81661bfe --- /dev/null +++ b/src/main/resources/css/master.css @@ -0,0 +1,166 @@ +/** +Background colours + */ +.background-blue{ + -fx-background-color: #119796; +} + +.background-dark{ + -fx-background-color: #2C2c36; +} + +/** +Exit button with no background + */ +.clear-exit-btn{ + -fx-background-insets: 0; + -fx-background-color: #119796; + -fx-border-style: none; +} + +/** +Buttons + */ +.blue-ui-btn{ + -fx-background-color: #119796; + -fx-text-fill: #fff; +} + +.text-white { + -fx-text-fill: white !important; + -fx-fill:white !important; +} + +/** +Sliders + */ +.ui-slider .thumb { + -fx-background-color: rgb(60, 60, 60); + -fx-border-radius: 10; + -fx-border-color: darkgray; +} + +.ui-slider .track{ + -fx-background-color: #119796; +} + +.ui-slider .axis{ + -fx-tick-label-fill: white; +} + +.ui-slider .axis .axis-label{ + -fx-text-fill: white; +} + +/** +Checkbox + */ +.ui-checkbox .box{ + -fx-background-color: white; + -fx-graphic:none; + -fx-shape: none; +} + +.ui-checkbox .box .mark{ + -fx-background-image: none; + -fx-image: none; + -fx-graphic: none; + -fx-shape: none; +} + +.ui-checkbox:selected .box{ + -fx-background-color: #119796; + -fx-shape: none; +} + +.ui-checkbox:selected .box .mark{ + -fx-background-color: #119796; + -fx-shape: none; + -fx-graphic: none; +} + +/** +Table + */ +.ui-table{ + -fx-background-color: transparent; +} + +.ui-table:focused{ + -fx-background-color: transparent; +} + +.ui-table .column-header-background{ + -fx-background-color: white +} + +.ui-table .column-header-background .label{ + -fx-background-color: transparent; + -fx-text-fill: black; +} + +.ui-table .column-header { + -fx-background-color: transparent; +} + +.ui-table .table-cell{ + -fx-text-fill: white; + -fx-border-style: none; +} + +.table-row-cell{ + -fx-background-color: #119796; + -fx-background-insets: 0, 0 0 1 0; + -fx-padding: 0.0em; /* 0 */ + -fx-border-style: none; +} + +.table-row-cell:odd{ + -fx-background-color: #0e6d6c; + -fx-background-insets: 0, 0 0 1 0; + -fx-padding: 0.0em; /* 0 */ + -fx-border-style: none; +} + +.table-row-cell:selected { + -fx-background-color: #005797; + -fx-background-insets: 0; + -fx-border-style: none; +} + +/** +Remove scroll bars + */ +.ui-table *.scroll-bar:horizontal *.increment-button, +.ui-table *.scroll-bar:horizontal *.decrement-button { + -fx-background-color: null; + -fx-background-radius: 0; + -fx-background-insets: 0; + -fx-padding: 0; +} + +.ui-table *.scroll-bar:horizontal *.increment-arrow, +.ui-table *.scroll-bar:horizontal *.decrement-arrow { + -fx-background-color: null; + -fx-background-radius: 0; + -fx-background-insets: 0; + -fx-padding: 0; + -fx-shape: null; +} + +.ui-table *.scroll-bar:vertical *.increment-arrow, +.ui-table *.scroll-bar:vertical *.decrement-arrow { + -fx-background-color: null; + -fx-background-radius: 0; + -fx-background-insets: 0; + -fx-padding: 0; + -fx-shape: null; +} + +.ui-table *.scroll-bar:vertical *.increment-button, +.ui-table *.scroll-bar:vertical *.decrement-button { + -fx-background-color: null; + -fx-background-radius: 0; + -fx-background-insets: 0; + -fx-padding: 0; +} \ No newline at end of file diff --git a/src/main/resources/views/MainView.fxml b/src/main/resources/views/MainView.fxml index ac72bd8c..65e7ee7b 100644 --- a/src/main/resources/views/MainView.fxml +++ b/src/main/resources/views/MainView.fxml @@ -9,7 +9,7 @@ - + @@ -18,23 +18,23 @@ - - + + - +