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);