diff --git a/README.md b/README.md
index 6e94eda7..298a2a84 100644
--- a/README.md
+++ b/README.md
@@ -38,11 +38,11 @@ Tasklist:
* Volume bars implemented (done - December 17, 2013)
* Save & Load songs (done - December 18, 2013)
* Loop button loops the song (done - December 18, 2013)
-* End-of-File Behaviour fix (done - December 25, 2013)
* Release to a test group (v0.9 - **Alpha Release** - December 25, 2013)
* Measure line numbers (done - December 27, 2013)
* Tempo selector interface (done - December 27, 2013)
* Remove limit on song length (done - January 1, 2014)
+* End-of-File Behaviour fix (done - January 3, 2014)
* Options dialog
* Import MPC songs
* Arranger mode
diff --git a/src/smp/components/controls/ArrowButton.java b/src/smp/components/controls/ArrowButton.java
index 905e8390..32d154f6 100644
--- a/src/smp/components/controls/ArrowButton.java
+++ b/src/smp/components/controls/ArrowButton.java
@@ -1,10 +1,15 @@
package smp.components.controls;
+import java.util.Timer;
+import java.util.TimerTask;
+
import smp.ImageIndex;
import smp.components.Values;
+import smp.components.controls.TempoAdjustButton.clickHold;
import smp.components.general.ImagePushButton;
import smp.components.staff.sequences.StaffNoteLine;
import smp.components.staff.sequences.StaffSequence;
+import javafx.application.Platform;
import javafx.scene.control.Slider;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
@@ -31,6 +36,9 @@ public class ArrowButton extends ImagePushButton {
/** This is the slider that the scrollbar will affect. */
private Slider scrollbar;
+ /** This is a timer object for click-and-hold. */
+ private Timer t;
+
/**
* Default constructor.
* @param i The ImageView
object that we are
@@ -39,6 +47,7 @@ public class ArrowButton extends ImagePushButton {
public ArrowButton(ImageView i, Slider scr, ImageIndex pr,
ImageIndex notPr) {
super(i);
+ t = new Timer();
scrollbar = scr;
getImages(pr, notPr);
}
@@ -64,25 +73,55 @@ public double getSkipAmount() {
@Override
protected void reactPressed(MouseEvent event) {
super.reactPressed(event);
- scrollbar.adjustValue(scrollbar.getValue() + skipAmount);
- if (scrollbar.getMax() <= scrollbar.getValue() && endOfFile) {
- scrollbar.setMax(scrollbar.getMax()
- + Values.NOTELINES_IN_THE_WINDOW * 2);
- StaffSequence s = theStaff.getSequence();
- int start = (int) scrollbar.getMax();
- for(int i = start; i < start
- + Values.NOTELINES_IN_THE_WINDOW * 2; i++)
- s.addLine(new StaffNoteLine(i));
- }
- if (scrollbar.getMax() <= scrollbar.getValue())
- endOfFile = true;
- else
- endOfFile = false;
+ bumpStaff();
+ TimerTask tt = new clickHold();
+ t.schedule(tt, Values.HOLDTIME,
+ Values.REPEATTIME);
+ }
+
+ /** Bumps the staff by some amount. */
+ private void bumpStaff() {
+ Platform.runLater(new Runnable() {
+
+ @Override
+ public void run() {
+ scrollbar.adjustValue(scrollbar.getValue() + skipAmount);
+ if (scrollbar.getMax() <= scrollbar.getValue() && endOfFile) {
+ scrollbar.setMax(scrollbar.getMax()
+ + Values.NOTELINES_IN_THE_WINDOW * 2);
+ StaffSequence s = theStaff.getSequence();
+ int start = (int) scrollbar.getMax();
+ for(int i = start; i < start
+ + Values.NOTELINES_IN_THE_WINDOW * 2; i++)
+ s.addLine(new StaffNoteLine(i));
+ }
+ if (scrollbar.getMax() <= scrollbar.getValue())
+ endOfFile = true;
+ else
+ endOfFile = false;
+ }
+ });
}
@Override
protected void reactReleased(MouseEvent event) {
super.reactReleased(event);
+ t.cancel();
+ t = new Timer();
+ }
+
+ /**
+ * This is a timer task that increments the current line of the song.
+ * @author RehdBlob
+ * @since 2014.01.02
+ */
+ class clickHold extends TimerTask {
+
+ @Override
+ public void run() {
+ bumpStaff();
+ }
+
}
}
diff --git a/src/smp/components/controls/LoadButton.java b/src/smp/components/controls/LoadButton.java
index d66f2f22..c3310725 100644
--- a/src/smp/components/controls/LoadButton.java
+++ b/src/smp/components/controls/LoadButton.java
@@ -5,12 +5,14 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
+import java.util.ArrayList;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.stage.FileChooser;
import smp.components.Values;
import smp.components.general.ImagePushButton;
+import smp.components.staff.sequences.StaffNoteLine;
import smp.components.staff.sequences.StaffSequence;
import smp.fx.Dialog;
import smp.fx.SMPFXController;
@@ -47,7 +49,7 @@ private void load() {
boolean cont = true;
if (StateMachine.isModified())
cont = Dialog.showYesNoDialog("The current song has been modified!\n"
- + "Load the song anyway?");
+ + "Load anyway?");
if (cont) {
try {
FileChooser f = new FileChooser();
@@ -60,11 +62,13 @@ private void load() {
ObjectInputStream o_in = new
ObjectInputStream(f_in);
StaffSequence loaded = (StaffSequence) o_in.readObject();
+ normalize(loaded);
theStaff.setSequence(loaded);
StateMachine.setTempo(loaded.getTempo());
theStaff.getControlPanel().updateCurrTempo();
theStaff.getControlPanel().getScrollbar().setMax(
- loaded.getTheLines().size());
+ loaded.getTheLines().size()
+ - Values.NOTELINES_IN_THE_WINDOW);
theStaff.getNoteMatrix().redraw();
o_in.close();
f_in.close();
@@ -72,7 +76,7 @@ private void load() {
try {
fname = fname.substring(0, fname.indexOf("."));
} catch (IndexOutOfBoundsException e) {
-
+ // Do nothing
}
SMPFXController.getSongName().setText(fname);
StateMachine.setModified(false);
@@ -86,5 +90,18 @@ private void load() {
}
}
+ /**
+ * Makes a sequence fit on the screen.
+ * @param theSeq The sequence to normalize.
+ */
+ private void normalize(StaffSequence theSeq) {
+ ArrayList theLines = theSeq.getTheLines();
+ while (theLines.size() % 4 != 0 ||
+ theLines.size() % Values.NOTELINES_IN_THE_WINDOW != 0) {
+ theLines.add(new StaffNoteLine(theLines.size()));
+ }
+
+ }
+
}
diff --git a/src/smp/components/controls/OptionsButton.java b/src/smp/components/controls/OptionsButton.java
index 9b2c5c2b..0d9b292b 100644
--- a/src/smp/components/controls/OptionsButton.java
+++ b/src/smp/components/controls/OptionsButton.java
@@ -22,7 +22,9 @@
public class OptionsButton extends ImagePushButton {
/** This is the text that will be shown in the options dialog. */
- private String txt = "";
+ private String txt = "Not implemented yet";
+
+
/**
* Default constructor.
@@ -48,6 +50,7 @@ private void options() {
dialog.setHeight(150);
dialog.setWidth(250);
dialog.setResizable(false);
+ dialog.setTitle("Options");
dialog.initStyle(StageStyle.UTILITY);
Label label = new Label(txt);
Button okButton = new Button("OK");
diff --git a/src/smp/components/controls/SaveButton.java b/src/smp/components/controls/SaveButton.java
index 259718ea..63d115e9 100644
--- a/src/smp/components/controls/SaveButton.java
+++ b/src/smp/components/controls/SaveButton.java
@@ -72,7 +72,8 @@ private void saveObject() {
try {
FileChooser f = new FileChooser();
f.setInitialDirectory(new File(System.getProperty("user.dir")));
- f.setInitialFileName(SMPFXController.getSongName().getText());
+ f.setInitialFileName(SMPFXController.getSongName().getText()
+ + ".txt");
f.getExtensionFilters().addAll(
new ExtensionFilter("Text file", "*.txt"),
new ExtensionFilter("All files", "*"));
diff --git a/src/smp/components/staff/Staff.java b/src/smp/components/staff/Staff.java
index 19e312b1..63d1d202 100644
--- a/src/smp/components/staff/Staff.java
+++ b/src/smp/components/staff/Staff.java
@@ -133,11 +133,16 @@ public synchronized void redraw() {
/** Turns off all highlights in the play bars in the staff. */
private void highlightsOff() {
- ArrayList playBars = staffImages.getPlayBars();
- for(ImageView i : playBars) {
- i.setImage(ImageLoader.getSpriteFX(
- ImageIndex.NONE));
- }
+ Platform.runLater(new Runnable() {
+ @Override
+ public void run() {
+ ArrayList playBars = staffImages.getPlayBars();
+ for(ImageView i : playBars) {
+ i.setImage(ImageLoader.getSpriteFX(
+ ImageIndex.NONE));
+ }
+ }
+ });
}
@@ -147,7 +152,8 @@ private void highlightsOff() {
public void startSong() {
highlightsOff();
lastLine = findLastLine();
- if (lastLine == 0 && theSequence.getLine(0).isEmpty()) {
+ if ((lastLine == 0 && theSequence.getLine(0).isEmpty())
+ || (lastLine < StateMachine.getMeasureLineNum())) {
theControls.getStopButton().reactPressed(null);
return;
}
@@ -175,15 +181,6 @@ public void stopSong() {
songPlaying = false;
animationService.cancel();
animationService.reset();
- try {
- Thread.sleep(1);
- while (true) {
- if (!animationService.isRunning())
- break;
- }
- } catch (InterruptedException e) {
-
- }
highlightsOff();
}
@@ -324,7 +321,12 @@ protected Task createTask() {
*/
private void bumpHighlights(ArrayList playBars, int index,
boolean advance) {
- highlightsOff();
+ for (int i = 0; i < playBars.size(); i++)
+ if (i != index)
+ playBars.get(i).setImage(
+ ImageLoader.getSpriteFX(ImageIndex.NONE));
+
+
playBars.get(index).setImage(
ImageLoader.getSpriteFX(ImageIndex.PLAY_BAR1));
if (advance && !zero)
@@ -418,8 +420,8 @@ protected Staff call() throws Exception {
// Do nothing
}
} while (songPlaying);
- hitStop();
highlightsOff();
+ hitStop();
return theMatrix.getStaff();
}
diff --git a/src/smp/fx/Dialog.java b/src/smp/fx/Dialog.java
index 577a2702..ee809924 100644
--- a/src/smp/fx/Dialog.java
+++ b/src/smp/fx/Dialog.java
@@ -112,8 +112,8 @@ public void handle(ActionEvent event) {
*/
public static String showTextDialog(String txt) {
final Stage dialog = new Stage();
- dialog.setHeight(150);
- dialog.setWidth(250);
+ dialog.setHeight(125);
+ dialog.setWidth(150);
dialog.setResizable(false);
dialog.initStyle(StageStyle.UTILITY);
Label label = new Label(txt);