aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/net/sowgro/npehero/editor
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/net/sowgro/npehero/editor')
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/DiffEditor.java165
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/DiffList.java162
-rw-r--r--src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java85
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/LevelEditor.java195
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/LevelList.java135
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/NotesEditor.java132
-rw-r--r--src/main/java/net/sowgro/npehero/editor/NotesEditor2.java444
7 files changed, 1318 insertions, 0 deletions
diff --git a/src/main/java/net/sowgro/npehero/editor/DiffEditor.java b/src/main/java/net/sowgro/npehero/editor/DiffEditor.java
new file mode 100755
index 0000000..f98ff46
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/editor/DiffEditor.java
@@ -0,0 +1,165 @@
+package net.sowgro.npehero.editor;
+
+import javafx.beans.binding.DoubleBinding;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import net.sowgro.npehero.Driver;
+import net.sowgro.npehero.gameplay.Block;
+import net.sowgro.npehero.gui.LevelSurround;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Text;
+import net.sowgro.npehero.main.*;
+
+public class DiffEditor extends Page
+{
+ Difficulty diff;
+ ScrollPane scroll;
+
+ HBox content = new HBox();
+
+ public Page prev;
+
+ public DiffEditor(Difficulty diff, Page prev) {
+ this.diff = diff;
+ this.prev = prev;
+
+ Text folderNameLabel = new Text("Folder name");
+ TextField folderName = new TextField(diff.thisDir.getName());
+ folderName.setDisable(true);
+
+ Text titleLabel = new Text("Title");
+ TextField title = new TextField(diff.title);
+
+ Button editNotes = new Button("Edit notes");
+ editNotes.setOnAction(_ -> {
+ if (diff.level.song == null) {
+ Driver.setMenu(new ErrorDisplay("You must import a song file before editing the notes!", this));
+ }
+ if (diff.bpm != 0.0) {
+ Driver.setMenu(new ErrorDisplay(
+ "Note:\nThe new notes editor does not support bpm and beat based songs. If you continue the beats will be converted to seconds.",
+ this,
+ new NotesEditor2(diff, this)
+ ));
+ }
+ Driver.setMenu(new NotesEditor2(diff, this));
+ });
+
+ Button oldEditNotes = new Button("Edit notes (legacy)");
+ oldEditNotes.setOnAction(_ -> Driver.setMenu(new ErrorDisplay(
+ "Warning: \nThe legacy editor will overwrite all existing notes!",
+ this,
+ new NotesEditor(diff, this))
+ ));
+
+ Label scoresLable = new Label("Scores");
+ Button editScores = new Button("Clear leaderboard");
+ editScores.setOnAction(_ -> diff.leaderboard.entries.clear());
+
+ Button playLevel = new Button("Play level");
+ playLevel.setOnAction(_ -> {
+ if (diff.isValid && diff.level.isValid) {
+ Driver.setMenu(new LevelSurround(diff.level, diff, this));
+ }
+ else {
+ Driver.setMenu(new ErrorDisplay("This Level is not valid!\nCheck that all required fields\nare populated.", this));
+ }
+ });
+
+ Button save = new Button("Save");
+ save.setOnAction(_ -> { //assigns text fields to values
+ diff.title = title.getText();
+// diff.bpm = Double.parseDouble(bpm.getText());
+// diff.numBeats = Integer.parseInt(numBeats.getText());
+ diff.write();
+ });
+
+ HBox scrollContent = new HBox();
+ scroll = new ScrollPane(scrollContent);
+ scroll.setFitToWidth(true);
+ scroll.getStyleClass().remove("scroll-pane");
+ scroll.getStyleClass().add("box");
+// scroll.setPrefHeight(400);
+ scroll.prefWidthProperty().bind(scroll.heightProperty().multiply(0.66));
+
+ Pane[] lanes = new Pane[5];
+ for (int i = 0; i < lanes.length; i++) {
+ lanes[i] = new Pane();
+ }
+
+ scrollContent.getChildren().addAll(lanes);
+ scrollContent.setSpacing(5);
+ scrollContent.setAlignment(Pos.CENTER);
+
+ diff.notes.list.forEach(n -> lanes[n.lane].getChildren().add(drawNote(n)));
+
+ VBox notePreview = new VBox();
+
+ ValidIndicator validNotes = new ValidIndicator();
+ if (diff.notes.list.isEmpty()) {
+ validNotes.setInvalid("This difficulty does not contain any notes!");
+ }
+ HBox notesLabel = new HBox(new Label("Notes"), validNotes);
+ Pane scrollHolder = new Pane(scroll);
+ scroll.prefHeightProperty().bind(scrollHolder.heightProperty());
+ scrollHolder.setPrefHeight(400);
+ notePreview.getChildren().addAll(notesLabel, scrollHolder, editNotes, oldEditNotes);
+ notePreview.setSpacing(10);
+
+ VBox left = new VBox();
+ left.getChildren().addAll(folderNameLabel,folderName,titleLabel,title,scoresLable,editScores,playLevel);
+ left.setSpacing(10);
+
+ HBox main = new HBox();
+ main.getChildren().addAll(left, notePreview);
+ main.setSpacing(30);
+
+ Button exit = new Button();
+ exit.setText("Back");
+ exit.setOnAction(e -> {
+ Sound.playSfx(Sound.BACKWARD);
+ Driver.setMenu(prev);
+ });
+
+ HBox bottom = new HBox(exit,save);
+ bottom.setSpacing(10);
+ bottom.setAlignment(Pos.CENTER);
+
+ VBox centerBox = new VBox();
+ centerBox.getChildren().addAll(main, bottom);
+ centerBox.setSpacing(10);
+ centerBox.setAlignment(Pos.CENTER);
+
+ content.getChildren().add(centerBox);
+ content.setAlignment(Pos.CENTER);
+ }
+
+ @Override
+ public Pane getContent() {
+ return content;
+ }
+
+ // Duplicates of NotesEditor2 methods, should be made generic and combined
+ private Block drawNote(Note n) {
+ Color color = diff.level.colors[n.lane];
+ Block b = new Block(color,20, 20, 5, false, n);
+ b.heightProperty().bind(scroll.widthProperty().divide(8));
+ b.widthProperty().bind(scroll.widthProperty().divide(8));
+ b.arcHeightProperty().bind(scroll.widthProperty().divide(25));
+ b.arcWidthProperty().bind(scroll.widthProperty().divide(25));
+ b.strokeWidthProperty().bind(scroll.widthProperty().divide(120));
+ b.layoutYProperty().bind(secondToScreenPos(n.time.add(0)));
+ return b;
+ }
+
+ private DoubleBinding secondToScreenPos(double second) {
+ return scroll.heightProperty().multiply(second * 0.9);
+ }
+
+ private DoubleBinding secondToScreenPos(DoubleBinding second) {
+ return scroll.heightProperty().multiply(second).multiply(0.9);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/sowgro/npehero/editor/DiffList.java b/src/main/java/net/sowgro/npehero/editor/DiffList.java
new file mode 100755
index 0000000..13e4795
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/editor/DiffList.java
@@ -0,0 +1,162 @@
+package net.sowgro.npehero.editor;
+
+import javafx.beans.property.ReadOnlyStringWrapper;
+import javafx.collections.ObservableList;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import net.sowgro.npehero.Driver;
+import net.sowgro.npehero.main.Difficulty;
+import net.sowgro.npehero.main.Level;
+import net.sowgro.npehero.main.Page;
+import net.sowgro.npehero.main.Sound;
+
+import java.util.Collections;
+
+public class DiffList extends Page
+{
+ private HBox content = new HBox();
+
+ public DiffList(Level level, Page prev)
+ {
+ //sets up table view: requires special getters, setters and constructors to work
+ TableView<Difficulty> diffs = new TableView<>();
+
+ TableColumn<Difficulty,String> titleCol = new TableColumn<>("Name");
+ TableColumn<Difficulty,String> validCol = new TableColumn<>("Valid?");
+
+ diffs.getColumns().add(titleCol);
+ diffs.getColumns().add(validCol);
+
+ titleCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().title));
+ validCol.setCellValueFactory(data -> {
+ if (data.getValue().isValid) {
+ return new ReadOnlyStringWrapper("Yes");
+ }
+ else {
+ return new ReadOnlyStringWrapper("No");
+ }
+ });
+
+ diffs.setItems(level.difficulties.list);
+
+ diffs.setRowFactory( _ -> {
+ TableRow<Difficulty> row = new TableRow<>();
+ row.setOnMouseClicked(event -> {
+ if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
+ Difficulty rowData = row.getItem();
+ Driver.setMenu(new DiffEditor(rowData, this));
+ }
+ });
+ return row ;
+ });
+
+ diffs.setPrefWidth(400);
+ diffs.prefHeightProperty().bind(content.prefHeightProperty().multiply(0.67));
+
+ Button edit = new Button("Edit");
+ edit.setOnAction(e -> Driver.setMenu(new DiffEditor(diffs.getSelectionModel().getSelectedItem(), this)));
+ edit.setDisable(true);
+ edit.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull());
+
+ Button remove = new Button("Delete");
+ remove.setOnAction(e -> level.difficulties.remove(diffs.getSelectionModel().getSelectedItem()));
+ remove.setDisable(true);
+ remove.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull());
+
+ Button refresh = new Button("Refresh");
+ refresh.setOnAction(e -> {
+// level.readData();
+// diffs.setItems(level.difficulties.list.sorted());
+ diffs.refresh();
+ });
+
+ ToggleButton create = new ToggleButton("Create");
+
+ Button moveUp = new Button("Move Up");
+ moveUp.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull());
+ moveUp.setOnAction(_ -> {
+ Difficulty diff = diffs.getSelectionModel().selectedItemProperty().get();
+ ObservableList<Difficulty> diffList = level.difficulties.list;
+ int oldIndex = diffList.indexOf(diff);
+ if (oldIndex <= 0) {
+ return;
+ }
+ Collections.swap(diffList, oldIndex, oldIndex-1);
+ level.difficulties.saveOrder();
+ });
+
+ Button moveDown = new Button("Move Down");
+ moveDown.disableProperty().bind(diffs.getSelectionModel().selectedItemProperty().isNull());
+ moveDown.setOnAction(_ -> {
+ Difficulty diff = diffs.getSelectionModel().selectedItemProperty().get();
+ ObservableList<Difficulty> diffList = level.difficulties.list;
+ int oldIndex = diffList.indexOf(diff);
+ if (oldIndex >= diffList.size()-1) {
+ return;
+ }
+ Collections.swap(diffList, oldIndex, oldIndex+1);
+ level.difficulties.saveOrder();
+ });
+
+ VBox buttons = new VBox();
+ buttons.getChildren().addAll(create, edit, remove, moveUp, moveDown, refresh);
+ buttons.setSpacing(10);
+
+ TextField newLevelEntry = new TextField();
+ Button newLevelButton = new Button("add");
+
+ HBox newLevel = new HBox(newLevelEntry,newLevelButton);
+ Label newLevelLabel = new Label("Name of new difficulty");
+ VBox newLevelBox = new VBox(newLevelLabel, newLevel);
+ newLevelBox.setSpacing(10);
+ newLevelBox.getStyleClass().add("box");
+ newLevelBox.setPadding(new Insets(10));
+
+ Pane sidebar = new Pane();
+
+ HBox main = new HBox();
+ main.getChildren().addAll(diffs,buttons, sidebar);
+ main.setSpacing(10);
+
+ Button exit = new Button();
+ exit.setText("Back");
+ exit.setOnAction(e -> {
+ Sound.playSfx(Sound.BACKWARD);
+ Driver.setMenu(prev);
+ });
+
+ create.setOnAction(_ -> {
+ if (create.isSelected()) {
+ sidebar.getChildren().add(newLevelBox);
+ }
+ else {
+ sidebar.getChildren().remove(newLevelBox);
+ }
+ });
+
+ newLevelButton.setOnAction(_ -> {
+ level.difficulties.add(newLevelEntry.getText());
+ newLevelEntry.clear();
+ refresh.fire();
+ sidebar.getChildren().clear();
+ create.setSelected(false);
+ });
+
+ VBox centerBox = new VBox();
+ centerBox.getChildren().addAll(main, exit);
+ centerBox.setSpacing(10);
+ centerBox.setAlignment(Pos.CENTER);
+
+ content.getChildren().add(centerBox);
+ content.setAlignment(Pos.CENTER);
+ }
+
+ @Override
+ public Pane getContent() {
+ return content;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java b/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java
new file mode 100644
index 0000000..b3ec751
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java
@@ -0,0 +1,85 @@
+package net.sowgro.npehero.editor;
+
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import net.sowgro.npehero.Driver;
+import net.sowgro.npehero.main.Page;
+import net.sowgro.npehero.main.Sound;
+
+public class ErrorDisplay extends Page {
+
+ private HBox content = new HBox();
+
+ /**
+ * Error display with a message and Back button
+ * @param message The message to display
+ * @param prev The destination of the close button
+ */
+ public ErrorDisplay(String message, Page prev) {
+ Label main = new Label(message);
+ main.getStyleClass().add("box");
+
+ Button exit = new Button();
+ exit.setText("Back");
+ exit.setOnAction(e -> {
+ Sound.playSfx(Sound.BACKWARD);
+ Driver.setMenu(prev);
+ });
+
+ VBox centerBox = new VBox();
+ centerBox.getChildren().addAll(main, exit);
+ centerBox.setSpacing(10);
+ centerBox.setAlignment(Pos.CENTER);
+
+ content.getChildren().add(centerBox);
+ content.setAlignment(Pos.CENTER);
+ }
+
+ /**
+ * Error display with a message and Cancel and Proceed buttons
+ * @param message The message to display
+ * @param prev The destination of the Cancel button
+ * @param next The destination of the Proceed button
+ */
+ public ErrorDisplay(String message, Page prev, Page next) {
+ Label main = new Label(message);
+ main.getStyleClass().add("box");
+ main.setPadding(new Insets(10));
+
+ Button exit = new Button();
+ exit.setText("Cancel");
+ exit.setOnAction(_ -> {
+ Sound.playSfx(Sound.BACKWARD);
+ Driver.setMenu(prev);
+ });
+
+ Button nextButton = new Button();
+ nextButton.setText("Proceed");
+ nextButton.setOnAction(_ -> {
+ Sound.playSfx(Sound.FORWARD);
+ Driver.setMenu(next);
+ });
+
+ HBox bottom = new HBox(exit, nextButton);
+ bottom.setAlignment(Pos.CENTER);
+ bottom.setSpacing(10);
+
+ VBox centerBox = new VBox();
+ centerBox.getChildren().addAll(main, bottom);
+ centerBox.setSpacing(10);
+ centerBox.setAlignment(Pos.CENTER);
+
+ content.getChildren().add(centerBox);
+ content.setAlignment(Pos.CENTER);
+ }
+
+ @Override
+ public Pane getContent() {
+ return content;
+ }
+}
diff --git a/src/main/java/net/sowgro/npehero/editor/LevelEditor.java b/src/main/java/net/sowgro/npehero/editor/LevelEditor.java
new file mode 100755
index 0000000..56a2924
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/editor/LevelEditor.java
@@ -0,0 +1,195 @@
+package net.sowgro.npehero.editor;
+
+import java.io.File;
+
+import javafx.beans.property.ReadOnlyStringWrapper;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.layout.*;
+import javafx.scene.text.Text;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import net.sowgro.npehero.Driver;
+import net.sowgro.npehero.main.*;
+
+public class LevelEditor extends Page
+{
+ private HBox content = new HBox();
+
+ private File selectedSong = null;
+ private File selectedPreview = null;
+ private File selectedBackground = null;
+
+ public LevelEditor(Level level, Page prev)
+ {
+ Text folderNameLabel = new Text("Folder name");
+ TextField folderName = new TextField();
+ if (level.dir != null) {
+ folderName.setText(level.dir.getName());
+ folderName.setDisable(true);
+ }
+
+ Text titleLabel = new Text("Title");
+ TextField title = new TextField(level.title);
+
+ Text artistLabel = new Text("Artist");
+ TextField artist = new TextField(level.artist);
+
+ Text descLabel = new Text("Description");
+ TextField desc = new TextField(level.desc);
+
+ Text colorsLabel = new Text("Colors");
+
+ ColorPicker[] colorsPickers = new ColorPicker[] {
+ new ColorPicker(level.colors[0]),
+ new ColorPicker(level.colors[1]),
+ new ColorPicker(level.colors[2]),
+ new ColorPicker(level.colors[3]),
+ new ColorPicker(level.colors[4])
+ };
+
+ for (ColorPicker cp : colorsPickers) {
+ cp.getStyleClass().add("button");
+ }
+
+ HBox colorPickerBox = new HBox();
+ colorPickerBox.getChildren().addAll(colorsPickers);
+
+ ValidIndicator songValid = new ValidIndicator();
+ if (level.song == null) {
+ songValid.setInvalid("Missing song file!");
+ }
+ HBox filesLabel = new HBox(new Text("Files"), songValid);
+
+ FileChooser backgroundChooser = new FileChooser();
+ backgroundChooser.getExtensionFilters().add(new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif"));
+ Button backgroundButton = new Button("Background Image");
+ backgroundButton.setOnAction(_ -> selectedBackground = backgroundChooser.showOpenDialog(Driver.primaryStage));
+
+ FileChooser previewChooser = new FileChooser();
+ previewChooser.getExtensionFilters().add(new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif"));
+ Button previewButton = new Button("Preview Image");
+ previewButton.setOnAction(_ -> selectedPreview = previewChooser.showOpenDialog(Driver.primaryStage));
+
+ FileChooser songChooser = new FileChooser();
+ songChooser.getExtensionFilters().add(new ExtensionFilter("Audio Files", "*.wav", "*.mp3", "*.aac"));
+ Button songButton = new Button("Song file");
+ songButton.setOnAction(_ -> selectedSong = songChooser.showOpenDialog(Driver.primaryStage));
+
+
+ ValidIndicator diffsInvalid = new ValidIndicator();
+ if (level.difficulties.validList.isEmpty()) {
+ diffsInvalid.setInvalid("This level contains no valid difficulties!");
+ }
+ HBox diffLabel = new HBox(new Text("Difficulties"), diffsInvalid);
+ diffLabel.setSpacing(5);
+
+
+ TableView<Difficulty> diffList = new TableView<>();
+
+ TableColumn<Difficulty,String> diffCol = new TableColumn<>("Difficulty");
+ TableColumn<Difficulty,String> validCol = new TableColumn<>("Valid?");
+
+ diffList.getColumns().add(diffCol);
+ diffList.getColumns().add(validCol);
+
+ diffCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().title));
+ validCol.setCellValueFactory(data -> {
+ if (data.getValue().isValid) {
+ return new ReadOnlyStringWrapper("Yes");
+ }
+ else {
+ return new ReadOnlyStringWrapper("No");
+ }
+ });
+
+ diffList.setItems(level.difficulties.list);
+
+ diffList.setRowFactory( _ -> {
+ TableRow<Difficulty> row = new TableRow<>();
+ row.setOnMouseClicked(event -> {
+ if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
+ Difficulty rowData = row.getItem();
+ Driver.setMenu(new DiffEditor(rowData, this));
+ }
+ });
+ return row ;
+ });
+
+ Button newDiffs = new Button("Edit difficulties");
+ newDiffs.setOnAction(_ -> Driver.setMenu(new DiffList(level, this)));
+
+ diffList.setSelectionModel(null);
+
+ Button save = new Button("Save");
+ save.setOnAction(e -> { //assigns fields to values
+ level.title = title.getText();
+ level.artist = artist.getText();
+ level.desc = desc.getText();
+ level.colors[0] = colorsPickers[0].getValue();
+ level.colors[1] = colorsPickers[1].getValue();
+ level.colors[2] = colorsPickers[2].getValue();
+ level.colors[3] = colorsPickers[3].getValue();
+ level.colors[4] = colorsPickers[4].getValue();
+ if (selectedBackground != null && selectedBackground.exists()) {
+ level.addFile(selectedBackground,"background." + getFileExtension(selectedBackground));
+ }
+ if (selectedPreview != null && selectedPreview.exists()) {
+ level.addFile(selectedPreview,"preview." + getFileExtension(selectedPreview));
+ }
+ if (selectedSong != null) {
+ level.addFile(selectedSong,"song." + getFileExtension(selectedSong));
+ }
+ level.writeMetadata();
+ });
+
+ VBox left = new VBox(filesLabel, songButton, previewButton, backgroundButton, colorsLabel, colorPickerBox);
+ left.setSpacing(10);
+ left.setPrefWidth(300);
+
+ VBox center = new VBox(folderNameLabel,folderName,titleLabel,title,artistLabel,artist,descLabel,desc);
+ center.setSpacing(10);
+ center.setPrefWidth(300);
+
+ VBox right = new VBox(diffLabel,diffList,newDiffs);
+ right.setSpacing(10);
+ center.setPrefWidth(300);
+
+ HBox mainBox = new HBox();
+ mainBox.getChildren().addAll(left, center, right);
+ mainBox.setSpacing(30);
+
+ Button exit = new Button();
+ exit.setText("Back");
+ exit.setOnAction(e -> {
+ Sound.playSfx(Sound.BACKWARD);
+ Driver.setMenu(prev);
+ });
+
+ HBox bottom = new HBox(save, exit);
+ bottom.setAlignment(Pos.CENTER);
+ bottom.setSpacing(10);
+
+ VBox centerBox = new VBox();
+ centerBox.getChildren().addAll(mainBox, bottom);
+ centerBox.setSpacing(10);
+ centerBox.setAlignment(Pos.CENTER);
+
+ content.getChildren().add(centerBox);
+ content.setAlignment(Pos.CENTER);
+ }
+
+ @Override
+ public Pane getContent() {
+ return content;
+ }
+
+ /**
+ * Get the extension of a file.
+ * @param file The file to return the extension of
+ * @return The extension of the file in the format "*.ext"
+ */
+ public String getFileExtension(File file) {
+ return file.getName().substring(file.getName().lastIndexOf('.') + 1);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/sowgro/npehero/editor/LevelList.java b/src/main/java/net/sowgro/npehero/editor/LevelList.java
new file mode 100755
index 0000000..b479f49
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/editor/LevelList.java
@@ -0,0 +1,135 @@
+package net.sowgro.npehero.editor;
+
+import javafx.beans.property.ReadOnlyStringWrapper;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.layout.Pane;
+import net.sowgro.npehero.Driver;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import net.sowgro.npehero.gui.MainMenu;
+import net.sowgro.npehero.main.Level;
+import net.sowgro.npehero.main.Levels;
+import net.sowgro.npehero.main.Page;
+import net.sowgro.npehero.main.Sound;
+
+public class LevelList extends Page
+{
+ private HBox content = new HBox();
+
+ public LevelList()
+ {
+ //sets up table view: requires special getters, setters and constructors to work
+ TableView<Level> levels = new TableView<>();
+
+ TableColumn<Level,String> titleCol = new TableColumn<>("Title");
+ TableColumn<Level,String> artistCol = new TableColumn<>("Artist");
+ TableColumn<Level,String> validCol = new TableColumn<>("Valid?");
+
+ levels.getColumns().add(titleCol);
+ levels.getColumns().add(artistCol);
+ levels.getColumns().add(validCol);
+
+ titleCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().title));
+ artistCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().artist));
+ validCol.setCellValueFactory(data -> {
+ if (data.getValue().isValid) {
+ return new ReadOnlyStringWrapper("Yes");
+ }
+ else {
+ return new ReadOnlyStringWrapper("No");
+ }
+ });
+
+ levels.setItems(Levels.list);
+
+ levels.setRowFactory( _ -> {
+ TableRow<Level> row = new TableRow<>();
+ row.setOnMouseClicked(event -> {
+ if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
+ Level rowData = row.getItem();
+ Driver.setMenu(new LevelEditor(rowData, this));
+ }
+ });
+ return row ;
+ });
+ levels.setPrefWidth(600);
+ levels.prefHeightProperty().bind(content.prefHeightProperty().multiply(0.75));
+
+ Button edit = new Button("Edit");
+ edit.setOnAction(e -> Driver.setMenu(new LevelEditor(levels.getSelectionModel().getSelectedItem(), this)));
+ edit.setDisable(true);
+ edit.disableProperty().bind(levels.getSelectionModel().selectedItemProperty().isNull());
+
+ Button remove = new Button("Delete");
+ remove.setOnAction(e -> Levels.remove(levels.getSelectionModel().getSelectedItem()));
+ remove.setDisable(true);
+ remove.disableProperty().bind(levels.getSelectionModel().selectedItemProperty().isNull());
+
+ Button refresh = new Button("Refresh");
+ refresh.setOnAction(e -> {
+ Levels.readData();
+ levels.setItems(Levels.list);
+ });
+
+ ToggleButton create = new ToggleButton("Create");
+
+ VBox buttons = new VBox();
+ buttons.getChildren().addAll(create, edit, remove, refresh);
+ buttons.setSpacing(10);
+
+ TextField newLevelEntry = new TextField();
+ Button newLevelButton = new Button("add");
+
+ HBox newLevel = new HBox(newLevelEntry,newLevelButton);
+ Label newLevelLabel = new Label("Name of new level");
+ VBox newLevelBox = new VBox(newLevelLabel, newLevel);
+ newLevelBox.setSpacing(10);
+ newLevelBox.getStyleClass().add("box");
+ newLevelBox.setPadding(new Insets(10));
+
+ Pane sidebar = new Pane();
+
+ HBox main = new HBox();
+ main.getChildren().addAll(levels,buttons,sidebar);
+ main.setSpacing(10);
+
+ Button exit = new Button();
+ exit.setText("Back");
+ exit.setOnAction(e -> {
+ Sound.playSfx(Sound.BACKWARD);
+ Driver.setMenu(new MainMenu());
+ });
+
+ VBox centerBox = new VBox();
+ centerBox.getChildren().addAll(main, exit);
+ centerBox.setSpacing(10);
+ centerBox.setAlignment(Pos.CENTER);
+
+ content.getChildren().add(centerBox);
+ content.setAlignment(Pos.CENTER);
+
+ create.setOnAction(_ -> {
+ if (create.isSelected()) {
+ sidebar.getChildren().add(newLevelBox);
+ }
+ else {
+ sidebar.getChildren().remove(newLevelBox);
+ }
+ });
+
+ newLevelButton.setOnAction(_ -> {
+ Levels.add(newLevelEntry.getText());
+ newLevelEntry.clear();
+ refresh.fire();
+ sidebar.getChildren().clear();
+ create.setSelected(false);
+ });
+ }
+
+ @Override
+ public Pane getContent() {
+ return content;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/sowgro/npehero/editor/NotesEditor.java b/src/main/java/net/sowgro/npehero/editor/NotesEditor.java
new file mode 100755
index 0000000..133330f
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/editor/NotesEditor.java
@@ -0,0 +1,132 @@
+package net.sowgro.npehero.editor;
+
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+
+import javafx.geometry.Pos;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.media.Media;
+import net.sowgro.npehero.gameplay.Timer;
+import net.sowgro.npehero.Driver;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Text;
+import net.sowgro.npehero.main.Control;
+import net.sowgro.npehero.main.Difficulty;
+import net.sowgro.npehero.main.Page;
+import net.sowgro.npehero.main.Sound;
+
+public class NotesEditor extends Page
+{
+ Text help;
+ String t1 = "Press Start to begin recording. Use the same keys. Note: existing notes will be overwritten.";
+ String t2 = "Now recording. Press Stop or " + Control.LEGACY_STOP.getKey().toString() + " to finish";
+ Difficulty diff;
+ Timer timer;
+ PrintWriter writer;
+
+ private HBox content = new HBox();
+
+ public NotesEditor(Difficulty diff, Page prev)
+ {
+ this.diff = diff;
+
+ help = new Text(t1);
+ Text cur = new Text("-----");
+
+ Button start = new Button("Start");
+ start.setOnAction(e -> start());
+ start.setFocusTraversable(false);
+
+ Button stop = new Button("Stop");
+ stop.setOnAction(e -> stop());
+ stop.setFocusTraversable(false);
+
+ VBox main = new VBox();
+ main.getChildren().addAll(help,cur,start,stop);
+
+ Button exit = new Button();
+ exit.setText("Back");
+ exit.setOnAction(e -> {
+ Sound.playSfx(Sound.BACKWARD);
+ Driver.setMenu(prev);
+ });
+
+ VBox centerBox = new VBox();
+ centerBox.getChildren().addAll(main, exit);
+ centerBox.setSpacing(10);
+ centerBox.setAlignment(Pos.CENTER);
+
+ content.getChildren().add(centerBox);
+ content.setAlignment(Pos.CENTER);
+
+ try {
+ writer = new PrintWriter(diff.notes.getFile(), "UTF-8");
+ } catch (FileNotFoundException | UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ Scene scene = Driver.primaryStage.getScene();
+ scene.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
+ if (e.getCode() == Control.LANE0.getKey()) {
+ writer.println("d"+timer);
+ cur.setText("d"+timer);
+ }
+ if (e.getCode() == Control.LANE1.getKey()) {
+ writer.println("f"+timer);
+ cur.setText("f"+timer);
+ }
+ if (e.getCode() == Control.LANE2.getKey()) {
+ writer.println("s"+timer);
+ cur.setText("s"+timer);
+ }
+ if (e.getCode() == Control.LANE3.getKey()) {
+ writer.println("j"+timer);
+ cur.setText("j"+timer);
+ }
+ if (e.getCode() == Control.LANE4.getKey()) {
+ writer.println("k"+timer);
+ cur.setText("k"+timer);
+ }
+ if (e.getCode() == Control.LEGACY_STOP.getKey())
+ {
+ stop();
+ }
+ e.consume();
+ });
+
+ Driver.primaryStage.setOnCloseRequest(e -> stop());
+ }
+
+ @Override
+ public Pane getContent() {
+ return content;
+ }
+
+ private void start()
+ {
+ Sound.playSong(new Media(diff.level.song.toString()));
+ timer = new Timer(diff.bpm);
+ help.setText(t2);
+ }
+
+ private void stop()
+ {
+ try
+ {
+ Sound.stopSong();
+// diff.numBeats = (int)Double.parseDouble(timer.toString());
+ timer = null;
+ writer.close();
+ help.setText(t1);
+ }
+ catch (Exception e)
+ {
+ //System.err.println("tried to stop but already stopped");
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java b/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java
new file mode 100644
index 0000000..38ad234
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java
@@ -0,0 +1,444 @@
+package net.sowgro.npehero.editor;
+
+import javafx.beans.binding.DoubleBinding;
+import javafx.beans.property.DoubleProperty;
+import javafx.beans.property.ListProperty;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.property.SimpleListProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+import javafx.scene.media.Media;
+import javafx.scene.media.MediaPlayer;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Line;
+import javafx.scene.shape.Polygon;
+import javafx.util.Duration;
+import net.sowgro.npehero.Driver;
+import net.sowgro.npehero.gameplay.Block;
+import net.sowgro.npehero.gameplay.Target;
+import net.sowgro.npehero.main.*;
+import net.sowgro.npehero.main.Control;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class NotesEditor2 extends Page {
+ Difficulty diff;
+ ScrollPane scroll = new ScrollPane();
+ Pane[] lanes;
+ MediaPlayer m;
+ Polygon playhead;
+ ListProperty<Block> activeNotes = new SimpleListProperty<>(FXCollections.observableArrayList());
+ ListProperty<Note> noteList;
+ DiffEditor prev;
+ DoubleProperty newEndTime = new SimpleDoubleProperty(0);
+
+ private HBox content = new HBox();
+
+ public NotesEditor2(Difficulty diff, DiffEditor prev) {
+ this.diff = diff;
+ noteList = diff.notes.deepCopyList();
+ m = new MediaPlayer(diff.level.song);
+ this.prev = prev;
+
+ // Buttons
+ VBox actionBox = new VBox();
+ actionBox.setSpacing(10);
+
+ Label noteLabel = new Label("Notes");
+ ToggleButton addNote = new ToggleButton("Add");
+ Button delNote = new Button("Delete");
+ ToggleButton moveNote = new ToggleButton("Move");
+ actionBox.getChildren().addAll(noteLabel, addNote, delNote, moveNote);
+
+ Label selectionLabel = new Label("Selection");
+ Button selectAll = new Button("Select All");
+ Button clearSelect = new Button("Clear");
+ actionBox.getChildren().addAll(selectionLabel, selectAll, clearSelect);
+
+ Label playbackLabel = new Label("Playback");
+ ToggleButton play = new ToggleButton("Play");
+ Button reset = new Button("Reset");
+ ToggleButton scrollLock = new ToggleButton("Scroll Lock");
+ Button setEnd = new Button("End Here");
+ actionBox.getChildren().addAll(playbackLabel, play, reset, scrollLock, setEnd);
+
+ delNote.disableProperty().bind(activeNotes.emptyProperty());
+ moveNote.disableProperty().bind(activeNotes.emptyProperty());
+ clearSelect.disableProperty().bind(activeNotes.emptyProperty());
+
+ ToggleGroup tg = new ToggleGroup();
+ addNote.setToggleGroup(tg);
+ moveNote.setToggleGroup(tg);
+
+ // Lanes
+ this.lanes = new Pane[5];
+ for (int i = 0; i < lanes.length; i++) {
+ lanes[i] = new Pane();
+ }
+ Block sizer = drawBlock(new Note(0, 0));
+ for (Pane lane : lanes) {
+ lane.prefWidthProperty().bind(sizer.widthProperty());
+ }
+ Pane rulerLane = new Pane();
+// rulerLane.setManaged(false);
+
+ Pane playheadLane = new Pane();
+ playheadLane.setOnMouseClicked(e -> {
+ m.seek(new Duration(screenPosToSecond(e.getY()) * 1000));
+ });
+
+ this.playhead = new Polygon();
+ playhead.getPoints().addAll(
+ 0.0, -10.0,
+ 20.0, -10.0,
+ 30.0, 0.0,
+ 20.0, 10.0,
+ 0.0, 10.0
+ );
+ playhead.setFill(Color.WHITE);
+ playheadLane.getChildren().add(playhead);
+// playhead.setOnMouseDragged(e -> {
+// scroll.get
+// playhead.layoutYProperty().bind(secondToScreenPos());
+// });
+
+ HBox scrollContent = new HBox();
+ scrollContent.setAlignment(Pos.CENTER);
+ scrollContent.setSpacing(10);
+ scrollContent.getChildren().addAll(playheadLane, rulerLane);
+ scrollContent.getChildren().addAll(lanes);
+
+ Line playheadLine = new Line();
+ playheadLine.setStartX(0);
+ playheadLine.endXProperty().bind(scroll.widthProperty().subtract(80));
+ playheadLine.setStartY(0);
+ playheadLine.setEndY(0);
+ playheadLine.setStroke(Color.WHITE);
+ playheadLine.layoutYProperty().bind(playhead.layoutYProperty());
+
+ Line endLine = new Line();
+ endLine.setStartX(0);
+ endLine.endXProperty().bind(scroll.widthProperty().subtract(80));
+ endLine.setStartY(0);
+ endLine.setEndY(0);
+ endLine.setStroke(Color.RED);
+
+ Pane contentOverlay = new Pane(playheadLine, endLine);
+ contentOverlay.setPickOnBounds(false);
+
+ StackPane stackPane = new StackPane();
+ stackPane.getChildren().addAll(scrollContent, contentOverlay);
+
+ scroll.setContent(stackPane);
+// scroll.prefWidthProperty().bind(super.prefWidthProperty().multiply(0.35));
+// scroll.setMinWidth(400);
+ scroll.prefHeightProperty().bind(content.heightProperty().multiply(0.75));
+ scroll.prefWidthProperty().bind(scroll.prefHeightProperty().multiply(0.70));
+ scroll.getStyleClass().remove("scroll-pane");
+ scroll.getStyleClass().add("box");
+ scroll.setPadding(new Insets(5));
+
+ Pane helpBox = new Pane();
+
+ HBox main = new HBox();
+ main.getChildren().addAll(scroll, actionBox, helpBox);
+ main.setSpacing(10);
+
+ Button exit = new Button();
+ exit.setText("Cancel");
+ exit.setOnAction(_ -> {
+ Sound.playSfx(Sound.BACKWARD);
+ Driver.setMenu(prev);
+ });
+
+ Button save = new Button();
+ save.setText("Save");
+ save.setOnAction(_ -> {
+ diff.notes.list = noteList;
+ diff.notes.writeFile();
+ diff.endTime = newEndTime.get();
+ Sound.playSfx(Sound.BACKWARD);
+ Driver.setMenu(new DiffEditor(diff, prev.prev));
+ });
+
+ HBox buttons = new HBox(save, exit);
+ buttons.setSpacing(10);
+ buttons.setAlignment(Pos.CENTER);
+
+ Runnable updateEndLine = () -> {
+ System.out.println("LISTENER CALLED");
+ if (newEndTime.get() != 0) {
+ endLine.layoutYProperty().bind(secondToScreenPos(newEndTime.get()));
+ }
+ else {
+ endLine.layoutYProperty().bind(secondToScreenPos(m.getTotalDuration().toSeconds()));
+ }
+ };
+
+ newEndTime.addListener((_, _, _) -> updateEndLine.run());
+ newEndTime.set(diff.endTime);
+ updateEndLine.run();
+
+ // Draw notes
+ noteList.forEach(n -> lanes[n.lane].getChildren().add(drawBlock(n)));
+ noteList.addListener((ListChangeListener<? super Note>) _ -> {
+ // TODO
+ for (Pane lane : lanes) {
+ lane.getChildren().clear();
+ }
+ noteList.forEach(n -> lanes[n.lane].getChildren().add(drawBlock(n)));
+ });
+
+ // Draw and update ruler
+ AtomicInteger lastRuler = new AtomicInteger(-1);
+ scrollContent.heightProperty().addListener(_ -> {
+ int ruler1 = (int) screenPosToSecond(scrollContent.getHeight());
+ for (int i = lastRuler.get() + 1; i <= ruler1; i++) {
+ Label l = new Label(toMinAndSec(i)+" -");
+ l.layoutYProperty().bind(secondToScreenPos(i));
+ l.setTextFill(Color.WHITE);
+ rulerLane.getChildren().add(l);
+ }
+ lastRuler.set(ruler1);
+ });
+
+ VBox centerBox = new VBox();
+ centerBox.getChildren().addAll(main, buttons);
+ centerBox.setSpacing(10);
+ centerBox.setAlignment(Pos.CENTER);
+
+ content.getChildren().add(centerBox);
+ content.setAlignment(Pos.CENTER);
+
+ // write notes on key press
+ content.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
+ KeyCode k = e.getCode();
+ if (k == Control.LANE0.getKey()) { WriteNote(0); }
+ if (k == Control.LANE1.getKey()) { WriteNote(1); }
+ if (k == Control.LANE2.getKey()) { WriteNote(2); }
+ if (k == Control.LANE3.getKey()) { WriteNote(3); }
+ if (k == Control.LANE4.getKey()) { WriteNote(4); }
+ if (k == Control.NOTE_DOWN.getKey()) { MoveNoteDown(); }
+ if (k == Control.NOTE_UP.getKey()) { MoveNoteUp(); }
+ if (k == Control.DELETE_NOTE.getKey()) { delNote.fire(); }
+ if (k == Control.CLEAR_SELECTION.getKey()) { clearSelect.fire(); }
+ if (k == Control.SCROLL_LOCK.getKey()) { scrollLock.fire(); }
+ if (k == Control.PLAY_PAUSE.getKey()) { play.fire(); }
+ if (k == Control.SELECT_ALL.getKey()) { selectAll.fire(); }
+ e.consume();
+ });
+
+ m.currentTimeProperty().addListener(_ -> {
+ // TODO
+ playhead.layoutYProperty().bind(secondToScreenPos(m.getCurrentTime().toSeconds()));
+ });
+
+ play.setOnAction(_ -> {
+ if (play.isSelected()) {
+ m.play();
+ }
+ else {
+ m.pause();
+ }
+
+ });
+
+ scrollLock.setOnAction(_ -> {
+ if (scrollLock.isSelected()) {
+ // vvalue takes in a value between 0 and 1 NOT a pixel value
+ scroll.vvalueProperty().bind(playhead.layoutYProperty().subtract(scroll.heightProperty().divide(2)).divide(scrollContent.heightProperty().subtract(scroll.heightProperty())));
+ }
+ else {
+ scroll.vvalueProperty().unbind();
+ }
+
+
+ });
+
+ reset.setOnAction(_ -> {
+ m.seek(new Duration(0));
+ });
+
+ delNote.setOnAction(_ -> {
+ activeNotes.forEach(e -> {
+ noteList.remove(e.note);
+ });
+ activeNotes.clear();
+ });
+
+ clearSelect.setOnAction(_ -> {
+ activeNotes.forEach(e -> e.setFill(e.color));
+ activeNotes.clear();
+ });
+
+ selectAll.setOnAction(_ -> {
+ activeNotes.clear();
+ for (Pane lane : lanes) {
+ lane.getChildren().forEach(e -> activeNotes.add((Block) e));
+ }
+ activeNotes.forEach(e -> e.setFill(Color.WHITE));
+ });
+
+ Pane addHelp = addHelp();
+ Pane moveHelp = moveHelp();
+ addNote.setOnAction(_ -> {
+ if (addNote.isSelected()) {
+ helpBox.getChildren().clear();
+ helpBox.getChildren().add(addHelp);
+ }
+ else {
+ helpBox.getChildren().clear();
+ }
+ });
+
+ moveNote.setOnAction(_ -> {
+ if (moveNote.isSelected()) {
+ helpBox.getChildren().clear();
+ helpBox.getChildren().add(moveHelp);
+ }
+ else {
+ helpBox.getChildren().clear();
+ }
+ });
+
+ moveNote.disabledProperty().addListener(_ -> {
+ if (moveNote.isDisabled() && moveNote.isSelected()) {
+ moveNote.setSelected(false);
+ helpBox.getChildren().clear();
+ }
+ });
+
+ setEnd.setOnAction(_ -> {
+ double tmp = screenPosToSecond(playhead.getLayoutY());
+ if (Math.round(tmp*10)/10 == Math.round(m.getTotalDuration().toSeconds() * 10)/10) {
+ newEndTime.set(0);
+ }
+ else {
+ newEndTime.set(tmp);
+ }
+ });
+ }
+
+ @Override
+ public Pane getContent() {
+ return content;
+ }
+
+ @Override
+ public void onView() {
+ Sound.stopSong();
+ m.play();
+ m.pause();
+ m.seek(Duration.ZERO);
+ }
+
+ @Override
+ public void onLeave() {
+ m.stop();
+ Sound.playSong(Sound.MENU_SONG);
+ }
+
+ private Block drawBlock(Note n) {
+ Color color = diff.level.colors[n.lane];
+ Block b = new Block(color,20, 20, 5, false, n);
+ b.heightProperty().bind(scroll.widthProperty().divide(8));
+ b.widthProperty().bind(scroll.widthProperty().divide(8));
+ b.arcHeightProperty().bind(scroll.widthProperty().divide(25));
+ b.arcWidthProperty().bind(scroll.widthProperty().divide(25));
+ b.strokeWidthProperty().bind(scroll.widthProperty().divide(120));
+ b.layoutYProperty().bind(secondToScreenPos(n.time.add(0)));
+ b.setOnMouseClicked(_ -> {
+ if (activeNotes.contains(b)) {
+ activeNotes.remove(b);
+ b.setFill(b.color);
+ }
+ else {
+ activeNotes.add(b);
+ b.setFill(Color.WHITE);
+ }
+ });
+ return b;
+ }
+
+ private String toMinAndSec(int t) {
+ int min = t / 60;
+ int sec = t % 60;
+
+ String min2 = min + "";
+ if (min2.length() == 1) {
+ min2 = "0" + min2;
+ }
+ String sec2 = sec + "";
+ if (sec2.length() == 1) {
+ sec2 = "0" + sec2;
+ }
+ return min2 + ":" + sec2;
+ }
+
+ private double screenPosToSecond(double screenYPos) {
+ return screenYPos / (scroll.getHeight() * 0.9);
+ }
+
+ private DoubleBinding secondToScreenPos(DoubleBinding second) {
+ return scroll.heightProperty().multiply(second).multiply(0.9);
+ }
+
+ private DoubleBinding secondToScreenPos(double second) {
+ return scroll.heightProperty().multiply(second).multiply(0.9);
+ }
+
+ private void WriteNote(int col) {
+ Note tmp = new Note(screenPosToSecond(playhead.getLayoutY()), col);
+ noteList.add(tmp);
+ }
+
+ private void MoveNoteUp() {
+ activeNotes.forEach(n -> n.note.time.setValue(n.note.time.get() - 0.01));
+ }
+
+ private void MoveNoteDown() {
+ activeNotes.forEach(n -> n.note.time.setValue(n.note.time.get() + 0.01));
+ }
+
+ private Pane addHelp() {
+ Label l1 = new Label("Use the following keys");
+ HBox hb = new HBox(
+ new Target(diff.level.colors[0], 40, 40, 10, Control.LANE0.targetString()),
+ new Target(diff.level.colors[1], 40, 40, 10, Control.LANE1.targetString()),
+ new Target(diff.level.colors[2], 40, 40, 10, Control.LANE2.targetString()),
+ new Target(diff.level.colors[3], 40, 40, 10, Control.LANE3.targetString()),
+ new Target(diff.level.colors[4], 40, 40, 10, Control.LANE4.targetString())
+ );
+ hb.setSpacing(10);
+ hb.setAlignment(Pos.CENTER_LEFT);
+ Label l2 = new Label("to write a new note at \nthe play head's position.");
+
+ VBox ret = new VBox(l1, hb, l2);
+ ret.setPadding(new Insets(10));
+ ret.getStyleClass().add("box");
+ return ret;
+ }
+
+ private Pane moveHelp() {
+ Label l1 = new Label("Use the");
+ HBox hb = new HBox(new Target(Color.BLACK, 40, 40, 10, Control.NOTE_UP.targetString()), new Label("and"), new Target(Color.BLACK, 40, 40, 10, Control.NOTE_DOWN.targetString()), new Label("keys"));
+ hb.setSpacing(10);
+ hb.setAlignment(Pos.CENTER_LEFT);
+ Label l2 = new Label("to move the selected \nnote(s) up and down.");
+
+ VBox ret = new VBox(l1, hb, l2);
+ ret.setPadding(new Insets(10));
+ ret.getStyleClass().add("box");
+ ret.setLayoutY(120);
+ return ret;
+ }
+}