diff --git a/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java b/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java new file mode 100644 index 00000000..84d82e91 --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java @@ -0,0 +1,247 @@ +package visualiser.Controllers; + +import javafx.application.Platform; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ListView; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.layout.AnchorPane; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.stage.WindowEvent; +import visualiser.gameController.Keys.ControlKey; +import visualiser.gameController.Keys.KeyFactory; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import static visualiser.app.App.keyFactory; + +/** + * Controller for the scene used to display and update current key bindings. + */ +public class KeyBindingsController { + private @FXML Button btnSave; + private @FXML Button btnCancel; + private @FXML Button btnReset; + private @FXML ListView lstControl; + private @FXML ListView lstKey; + private @FXML ListView lstDescription; + private @FXML AnchorPane anchor; + private KeyFactory newKeyFactory; + private Boolean changed = false; // keyBindings have been modified + private Button currentButton = null; // last button clicked + + public void initialize(){ + // create new key factory to modify, keeping the existing one safe + newKeyFactory = copyExistingFactory(); + initializeTable(); + populateTable(); + setKeyListener(); + } + + /** + * Sets up table before populating it. + * Set up includes headings, CSS styling and modifying default properties. + */ + public void initializeTable(){ + // set the headings for each column + lstKey.getItems().add("Key"); + lstControl.getItems().add("Command"); + lstDescription.getItems().add("Description"); + lstKey.getSelectionModel().select(0); + lstControl.getSelectionModel().select(0); + lstDescription.getSelectionModel().select(0); + + // add CSS stylesheet once the scene has been created + lstKey.sceneProperty().addListener((obs, oldScene, newScene) -> { + if (newScene != null) { + newScene.getStylesheets().add("/css/keyBindings.css"); + } + }); + + // stop the columns from being selectable, so only the buttons are + lstKey.getSelectionModel().selectedItemProperty() + .addListener((observable, oldvalue, newValue) -> + Platform.runLater(() -> + lstKey.getSelectionModel().select(0))); + lstDescription.getSelectionModel().selectedItemProperty() + .addListener((observable, oldvalue, newValue) -> + Platform.runLater(() -> + lstDescription.getSelectionModel().select(0))); + lstControl.getSelectionModel().selectedItemProperty() + .addListener((observable, oldvalue, newValue) -> + Platform.runLater(() -> + lstControl.getSelectionModel().select(0))); + } + + /** + * Populates the table with commands and their key binding details. + */ + public void populateTable(){ + // add each command to the table + for (Map.Entry entry : newKeyFactory.getKeyState().entrySet()) { + // create button for command + Button button = new Button(entry.getKey()); + button.setMinWidth(120); + button.setId(entry.getValue().toString()); + button.setOnAction(e -> currentButton = button); + // display details for command in table + lstControl.getItems().add(entry.getValue()); + lstKey.getItems().add(button); + lstDescription.getItems().add(entry.getValue().getProtocolCode()); + } + } + + /** + * Makes a copy of the {@link KeyFactory} that does not modify the original. + * @return new keyfactory to be modified + */ + public KeyFactory copyExistingFactory(){ + newKeyFactory = new KeyFactory(); + Map oldKeyState = keyFactory.getKeyState(); + Map newKeyState = new HashMap<>(); + + // copy over commands and their keys + for (Map.Entry entry : oldKeyState.entrySet()){ + newKeyState.put(entry.getKey(), entry.getValue()); + } + newKeyFactory.setKeyState(newKeyState); + return newKeyFactory; + } + + /** + * Creates a listener for the base anchorpane for key presses. + * It updates the current key bindings of the {@link KeyFactory} if + * required. + */ + public void setKeyListener(){ + anchor.addEventFilter(KeyEvent.KEY_PRESSED, event -> { + // if esc, cancel current button click + if (event.getCode() == KeyCode.ESCAPE){ + btnCancel.requestFocus(); + currentButton = null; + } + // if a button was clicked + else if (currentButton != null) { + // check if a button is already mapped to this key + for (int i = 1; i < lstKey.getItems().size(); i++) { + Button button = (Button)lstKey.getItems().get(i); + // update buttons text and remove key binding from command + if (button.getText().equals(event.getCode().toString())) { + button.setText(""); + newKeyFactory.updateKey(button.getId(), button.getId()); + } + } + // update text on the button + currentButton.setText(event.getCode().toString()); + // update the control key + newKeyFactory.updateKey(event.getCode().toString(), + currentButton.getId()); + // remove current button selection + currentButton = null; + changed = true; + btnCancel.requestFocus(); + } + event.consume(); + }); + } + + /** + * Cancel and exits the key bindings menu. Changes are not forced to be + * saved or fixed if invalid, and instead are defaulted back to the last + * successful saved state. + */ + public void cancel(){ + ((Stage)btnCancel.getScene().getWindow()).close(); + } + + /** + * Resets all key bindings to the built-in defaults. + */ + public void reset(){ + lstKey.getItems().clear(); + lstControl.getItems().clear(); + lstDescription.getItems().clear(); + newKeyFactory = new KeyFactory(); + initializeTable(); + populateTable(); + changed = true; + } + + /** + * Replace existing {@link KeyFactory} with the modified key bindings. + */ + public void save(){ + if (isFactoryValid()) { + keyFactory = newKeyFactory; + newKeyFactory = new KeyFactory(); + changed = false; + keyFactory.save(); // save persistently + loadNotification("Key bindings were successfully saved.", false); + } else { + loadNotification("One or more key bindings are missing. " + + "Failed to save.", true); + } + } + + /** + * Checks the {@link KeyFactory} being modified is valid and that no + * commands are missing a key binding. + * @return True if valid, false if invalid + */ + public Boolean isFactoryValid(){ + for (Map.Entry entry : newKeyFactory.getKeyState().entrySet + ()) { + if (entry.getKey().toString()==entry.getValue().toString()){ + return false; + } + } + return true; + } + + /** + * Method used to stop a user from exiting key bindings without saving + * their changes to the {@link KeyFactory}. + * @param we {@link WindowEvent} close request to be consumed if settings + * have not been successfully saved. + */ + public void onExit(WindowEvent we){ + // if modified KeyFactory hasn't been saved + if (changed){ + loadNotification("Please cancel or save your changes before exiting" + + ".", true); + we.consume(); + } + } + + /** + * Loads a popup window giving confirmation/warning of user activity. + * @param message the message to be displayed to the user + * @param warning true if the message to be displayed is due to user error + */ + public void loadNotification(String message, Boolean warning){ + Parent root = null; + FXMLLoader loader = new FXMLLoader(getClass().getResource + ("/visualiser/scenes/notification.fxml")); + try { + root = loader.load(); + } catch (IOException e) { + e.printStackTrace(); + } + NotificationController controller = loader.getController(); + Stage stage = new Stage(); + stage.setScene(new Scene(root)); + stage.centerOnScreen(); + stage.initModality(Modality.APPLICATION_MODAL); + stage.show(); + // displays given message in the window + controller.setMessage(message, warning); + } + +} diff --git a/racevisionGame/src/main/java/visualiser/Controllers/NotificationController.java b/racevisionGame/src/main/java/visualiser/Controllers/NotificationController.java new file mode 100644 index 00000000..d122ec80 --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/Controllers/NotificationController.java @@ -0,0 +1,35 @@ +package visualiser.Controllers; + +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.paint.Color; +import javafx.scene.text.Text; +import javafx.stage.Stage; + +/** + * Controller for a popup notification regarding user activity. + */ +public class NotificationController { + private @FXML Label lblDescription; + private @FXML Text txtMessage; + + /** + * Closes the popup window once clicked. + */ + public void ok(){ + ((Stage)lblDescription.getScene().getWindow()).close(); + } + + /** + * Displays the appropriate popup notification. + * @param message message for the user + * @param warning if true warning text shown, if false success text shown + */ + public void setMessage(String message, Boolean warning){ + lblDescription.setText(message); + if (!warning){ + txtMessage.setText("Success!"); + txtMessage.setFill(Color.GREEN); + } + } +} diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index b6a53f0b..043726f7 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -10,7 +10,6 @@ import javafx.collections.transformation.SortedList; import javafx.fxml.FXML; import javafx.scene.chart.LineChart; import javafx.scene.control.*; -import javafx.scene.control.Label; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; @@ -23,7 +22,6 @@ import shared.model.Leg; import visualiser.app.App; import visualiser.gameController.ControllerClient; import visualiser.gameController.Keys.ControlKey; -import visualiser.gameController.Keys.KeyFactory; import visualiser.model.*; import java.io.IOException; @@ -33,6 +31,7 @@ import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; +import static visualiser.app.App.keyFactory; /** @@ -113,7 +112,7 @@ public class RaceController extends Controller { @Override public void initialize(URL location, ResourceBundle resources) { - KeyFactory keyFactory = KeyFactory.getFactory(); +// KeyFactory keyFactory = KeyFactory.getFactory(); infoTableShow = true; // Initialise keyboard handler diff --git a/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java b/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java index 5617e3da..aa2edf13 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java @@ -1,5 +1,6 @@ package visualiser.Controllers; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; @@ -9,6 +10,7 @@ import javafx.scene.control.RadioButton; import javafx.scene.layout.AnchorPane; import javafx.stage.Modality; import javafx.stage.Stage; +import javafx.stage.WindowEvent; import visualiser.app.App; import java.io.IOException; @@ -87,18 +89,26 @@ public class TitleController extends Controller { * Called when control button is pressed. New pop up window displaying controls */ public void controlBtnPressed(){ - FXMLLoader loader = new FXMLLoader(); - loader.setLocation(getClass().getResource("/visualiser/scenes/controls.fxml")); - Parent layout; try { - layout = loader.load(); + FXMLLoader loader = new FXMLLoader(); + loader.setLocation(getClass().getResource("/visualiser/scenes/keyBindings.fxml")); + Parent layout = loader.load(); Scene scene = new Scene(layout); Stage popupStage = new Stage(); popupStage.setResizable(false); popupStage.setTitle("Game Controls"); popupStage.initModality(Modality.WINDOW_MODAL); + popupStage.centerOnScreen(); popupStage.setScene(scene); - popupStage.showAndWait(); + popupStage.show(); + KeyBindingsController controller = loader.getController(); + popupStage.setOnCloseRequest(new EventHandler() { + public void handle(WindowEvent we) { + if (we.getEventType() == WindowEvent.WINDOW_CLOSE_REQUEST) { + controller.onExit(we); + } + } + }); } catch (Exception e){ e.printStackTrace(); } diff --git a/racevisionGame/src/main/java/visualiser/app/App.java b/racevisionGame/src/main/java/visualiser/app/App.java index 31dcae24..e095e04e 100644 --- a/racevisionGame/src/main/java/visualiser/app/App.java +++ b/racevisionGame/src/main/java/visualiser/app/App.java @@ -3,7 +3,6 @@ package visualiser.app; import javafx.animation.FadeTransition; import javafx.application.Application; import javafx.application.Platform; -import javafx.beans.property.ReadOnlyObjectProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.concurrent.Task; @@ -15,7 +14,6 @@ import javafx.geometry.Rectangle2D; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Label; -import javafx.scene.control.ListView; import javafx.scene.control.ProgressBar; import javafx.scene.effect.DropShadow; import javafx.scene.image.Image; @@ -29,19 +27,17 @@ import javafx.stage.StageStyle; import javafx.stage.WindowEvent; import javafx.util.Duration; import visualiser.Controllers.MainController; - -import java.io.IOException; +import visualiser.gameController.Keys.KeyFactory; public class App extends Application { - private static Stage stage; private Pane splashLayout; private ProgressBar loadProgress; private Label progressText; private static final int SPLASH_WIDTH = 676; private static final int SPLASH_HEIGHT = 227; - + public static KeyFactory keyFactory = new KeyFactory(); public static App app; /** @@ -55,6 +51,9 @@ public class App extends Application { @Override public void init() { + // load the user's personalised key bindings + keyFactory.load(); + ImageView splash = new ImageView(new Image( getClass().getClassLoader().getResourceAsStream("images/splashScreen.png") )); diff --git a/racevisionGame/src/main/java/visualiser/gameController/InputChecker.java b/racevisionGame/src/main/java/visualiser/gameController/InputChecker.java index 057b5721..b4b3de9b 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/InputChecker.java +++ b/racevisionGame/src/main/java/visualiser/gameController/InputChecker.java @@ -3,10 +3,11 @@ package visualiser.gameController; import javafx.animation.AnimationTimer; import javafx.scene.Scene; import visualiser.gameController.Keys.ControlKey; -import visualiser.gameController.Keys.KeyFactory; import java.util.HashMap; +import static visualiser.app.App.keyFactory; + /** * Class for checking what keys are currently being used */ @@ -18,7 +19,7 @@ public class InputChecker { * @param scene Scene the controller is to run in parallel with. */ public void runWithScene(Scene scene){ - KeyFactory keyFactory = KeyFactory.getFactory(); +// KeyFactory keyFactory = KeyFactory.getFactory(); scene.setOnKeyPressed(event -> { String codeString = event.getCode().toString(); diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/DownWindKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/DownWindKey.java index e4b5455a..6c974972 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/Keys/DownWindKey.java +++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/DownWindKey.java @@ -9,11 +9,9 @@ public class DownWindKey extends ControlKey { /** * Constructor for Control - * @param name name of the key - * */ - public DownWindKey(String name) { - super(name, BoatActionEnum.DOWNWIND); + public DownWindKey() { + super("Downwind", BoatActionEnum.DOWNWIND); } @Override diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java index be95abd3..a783f268 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java +++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java @@ -1,5 +1,8 @@ package visualiser.gameController.Keys; +import java.beans.XMLDecoder; +import java.beans.XMLEncoder; +import java.io.*; import java.util.HashMap; import java.util.Map; @@ -13,39 +16,108 @@ public class KeyFactory { private Map keyState; /** - * Singleton instance to enforce consistent key state + * Constructor for key state, set up initial state of each action. */ - private static KeyFactory theFactory = new KeyFactory(); + public KeyFactory() { + this.keyState = new HashMap<>(); + keyState.put("Z", new ZoomInKey()); + keyState.put("X", new ZoomOutKey()); + keyState.put("SPACE", new VMGKey()); + keyState.put("SHIFT", new SailsToggleKey()); + keyState.put("ENTER", new TackGybeKey()); + keyState.put("UP", new UpWindKey()); + keyState.put("DOWN", new DownWindKey()); + } /** - * Singleton constructor for key state, set up initial state of each action. + * Get the Control Key in charge of a key press + * @param key key pressed (String value of KeyCode) + * @return the Control Key behaviour of the key pressed. */ - private KeyFactory() { - this.keyState = new HashMap<>(); - keyState.put("Z", new ZoomInKey("Zoom In")); - keyState.put("X", new ZoomOutKey("Zoom Out")); - keyState.put("SPACE", new VMGKey("VMG")); - keyState.put("SHIFT", new SailsToggleKey("Toggle Sails")); - keyState.put("ENTER", new TackGybeKey("Tack/Gybe")); - keyState.put("UP", new UpWindKey("Upwind")); - keyState.put("DOWN", new DownWindKey("Downwind")); + public ControlKey getKey(String key){ + return keyState.get(key); + } + + public Map getKeyState() { + return keyState; + } + + public void setKeyState(Map keyState) { + this.keyState = keyState; } /** - * Get singleton instance of KeyFactory to interact with key state - * @return automatically constructed KeyFactory + * Update the key bound to a particular command in the keystate. + * @param newKey the new key value for the command + * @param command the command to be updated */ - public static KeyFactory getFactory() { - return theFactory; + public void updateKey(String newKey, String command){ + ControlKey controlKey = null; + String oldKey = null; + for (Map.Entry entry : keyState.entrySet()) { + // if this is the correct command + if (entry.getValue().toString()==command){ + controlKey = entry.getValue(); + oldKey = entry.getKey(); + } + } + keyState.remove(oldKey, controlKey); + keyState.put(newKey, controlKey); } /** - * Get the Control Key in charge of a key press - * @param key key pressed (String value of KeyCode) - * @return the Control Key behaviour of the key pressed. + * Persistently saves the keybindings the user has set. */ - public ControlKey getKey(String key){ - return keyState.get(key); + public void save(){ + try { + // open the filestream and write to it + FileOutputStream fos = new FileOutputStream( + System.getProperty("user.dir")+ + "/settings/keyBindings.xml"); + XMLEncoder xmlEncoder = new XMLEncoder(fos); + xmlEncoder.writeObject(this.keyState); + xmlEncoder.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + /** + * Loads the persistently saved keybindings the user has set. + */ + public void load(){ + try { + // access settings folder, create if it doesn't exist + File settingsFolder = new File( + System.getProperty("user.dir")+"/settings"); + if (!settingsFolder.exists()){ + settingsFolder.mkdir(); + } + + // access keybindings xml file, create if it doesn't exist + File savedFile = new File( + settingsFolder+"/keyBindings.xml"); + if (!savedFile.exists()){ + savedFile.createNewFile(); + FileOutputStream fos = new FileOutputStream(savedFile); + XMLEncoder xmlEncoder = new XMLEncoder(fos); + xmlEncoder.writeObject(this.keyState); + xmlEncoder.close(); + } + + // load the saved settings into the game + InputStream is = new FileInputStream(savedFile); + XMLDecoder xmlDecoder = new XMLDecoder(is); + Map savedKeyState + = (Map)xmlDecoder.readObject(); + xmlDecoder.close(); + this.keyState = savedKeyState; + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } } } diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/SailsToggleKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/SailsToggleKey.java index f1e4d65b..a04b7d77 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/Keys/SailsToggleKey.java +++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/SailsToggleKey.java @@ -10,11 +10,9 @@ public class SailsToggleKey extends ControlKey { /** * Constructor for Control - * @param name name of the key - * */ - public SailsToggleKey(String name) { - super(name, BoatActionEnum.NOT_A_STATUS); + public SailsToggleKey() { + super("Toggle Sails", BoatActionEnum.NOT_A_STATUS); } /** diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/TackGybeKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/TackGybeKey.java index 80252e73..5c164443 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/Keys/TackGybeKey.java +++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/TackGybeKey.java @@ -9,11 +9,9 @@ public class TackGybeKey extends ControlKey { /** * Constructor for Control - * @param name name of the key - * */ - public TackGybeKey(String name) { - super(name, BoatActionEnum.TACK_GYBE); + public TackGybeKey() { + super("Tack/Gybe", BoatActionEnum.TACK_GYBE); } @Override diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/UpWindKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/UpWindKey.java index 333e5f1f..b4bbf489 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/Keys/UpWindKey.java +++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/UpWindKey.java @@ -9,11 +9,9 @@ public class UpWindKey extends ControlKey { /** * Constructor for Control - * @param name name of the key - * */ - public UpWindKey(String name) { - super(name, BoatActionEnum.UPWIND); + public UpWindKey() { + super("Upwind", BoatActionEnum.UPWIND); } @Override diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/VMGKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/VMGKey.java index c01658bb..2c7237f0 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/Keys/VMGKey.java +++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/VMGKey.java @@ -1,6 +1,5 @@ package visualiser.gameController.Keys; -import javafx.scene.input.KeyCode; import network.Messages.Enums.BoatActionEnum; /** @@ -10,11 +9,9 @@ public class VMGKey extends ControlKey{ /** * Constructor for Control - * - * @param name name of the key */ - public VMGKey(String name) { - super(name, BoatActionEnum.AUTO_PILOT); + public VMGKey() { + super("VMG", BoatActionEnum.AUTO_PILOT); } @Override diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomInKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomInKey.java index 51f98a58..e9a8ad7b 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomInKey.java +++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomInKey.java @@ -5,8 +5,8 @@ package visualiser.gameController.Keys; */ public class ZoomInKey extends ControlKey { - public ZoomInKey(String name) { - super(name); + public ZoomInKey() { + super("Zoom In"); } @Override diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomOutKey.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomOutKey.java index 6da2210c..cbba97fc 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomOutKey.java +++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/ZoomOutKey.java @@ -7,11 +7,9 @@ public class ZoomOutKey extends ControlKey{ /** * Constructor for Control - * @param name name of the key - * */ - public ZoomOutKey(String name) { - super(name); + public ZoomOutKey() { + super("Zoom Out"); } @Override diff --git a/racevisionGame/src/main/resources/css/keyBindings.css b/racevisionGame/src/main/resources/css/keyBindings.css new file mode 100644 index 00000000..a572116e --- /dev/null +++ b/racevisionGame/src/main/resources/css/keyBindings.css @@ -0,0 +1,45 @@ +.list-view .list-cell { + -fx-cell-size: 40; + -fx-font-family: "Tahoma"; + -fx-background-color: #fffff0; + -fx-alignment: center; +} + +.list-view .list-cell:even { + -fx-background-color: #ffffdc; +} + +.list-view .list-cell:selected { + -fx-background-color: #f9e5c3; + -fx-font-family: "Comic Sans MS"; + -fx-font-weight: bold; + -fx-font-size: 18; +} + +.button { + -fx-background-color: linear-gradient(#acdeff 50%, #a9c8ff 100%); + -fx-background-radius: 4px; + -fx-border-radius: 4px; + -fx-text-fill: #242d35; + -fx-font-size: 12px; + -fx-font-family: "Courier New"; + -fx-border-color: #a9c8ff; +} + +.button:focused { + -fx-background-color: white; + -fx-border-color: #0056bd; +} + +#anchor { + -fx-background-color: #fdfac3; +} +#menu{ + -fx-background-color: linear-gradient(#acdeff 50%, #a9c8ff 100%); + -fx-background-radius: 4px; + -fx-border-radius: 4px; + -fx-text-fill: #242d35; + -fx-font-size: 12px; + -fx-font-family: "Verdana"; + -fx-border-color: #a9c8ff; +} \ No newline at end of file diff --git a/racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml b/racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml new file mode 100644 index 00000000..40217567 --- /dev/null +++ b/racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml @@ -0,0 +1,24 @@ + + + + + + + + + + + +