Skip to content

Commit

Permalink
implemented cut/copy/paste for PianoRoll for multiple notes, as well …
Browse files Browse the repository at this point in the history
…as shared copy buffer to allow pasting copy/pasting between PianoRolls [fixes #149]
  • Loading branch information
kunstmusik committed Aug 22, 2016
1 parent 2dd473f commit 5f993cf
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 59 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ UPDATED

* Updated included Clojure version to 1.8.0

* Issue #149 - implemented cut/copy/paste for PianoRoll for multiple notes, as
well as shared copy buffer to allow pasting copy/pasting between PianoRolls

FIX

* Adding new AudioLayerGroups did not properly handle change listening,
Expand Down
2 changes: 1 addition & 1 deletion blue-core/src/blue/blueConstants.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
blueReleaseDate=2016.xx.xx
blueVersion=2.6.1_test1
blueVersion=2.6.1_test2
2 changes: 1 addition & 1 deletion blue-core/src/blue/soundObject/pianoRoll/PianoNote.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public Element saveAsXML() {
}

@Override
public Object clone() {
public PianoNote clone() {
PianoNote note = new PianoNote();

note.octave = this.octave;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
/**
* @author steven
*/

public class NoteCanvasMouseListener implements MouseListener,
MouseMotionListener {

Expand Down Expand Up @@ -117,26 +116,52 @@ public void mousePressed(MouseEvent e) {
}

} else if (((e.getModifiers() & OS_CTRL_KEY) == OS_CTRL_KEY) && !e.isShiftDown()) {
if (canvas.bufferedNote == null) {
if (PianoRollCanvas.NOTE_COPY_BUFFER.isEmpty()) {
return;
}

int x = e.getX();
int y = e.getY();

float startTime = (float)x / canvas.p.getPixelSecond();

float startTime = (float) x / canvas.p.getPixelSecond();
int[] pchBase = canvas.getOctaveScaleDegreeForY(y);
float timeAdjust = Float.MAX_VALUE;
int topPitchNum = Integer.MIN_VALUE;
int bottomPitchNum = Integer.MAX_VALUE;
int scaleDegrees = canvas.p.getScale().getNumScaleDegrees();

if (canvas.p.isSnapEnabled()) {
float snapValue = canvas.p.getSnapValue();
startTime = ScoreUtilities.getSnapValueStart(startTime, snapValue);
}
PianoNote note = (PianoNote) canvas.bufferedNote.clone();
}

for (PianoNote note : PianoRollCanvas.NOTE_COPY_BUFFER) {
timeAdjust = Math.min(timeAdjust, note.getStart());
int pitchNum = note.getOctave() * scaleDegrees + note.getScaleDegree();
topPitchNum = Math.max(topPitchNum, pitchNum);
bottomPitchNum = Math.min(bottomPitchNum, pitchNum);
}

fireSelectionEvent(new SelectionEvent<>(null,
SelectionEvent.SELECTION_CLEAR));
start = null;

canvas.addNote(note, startTime, y, 0);
int basePitchNum = pchBase[0] * scaleDegrees + pchBase[1];
int pitchNumAdjust = basePitchNum - topPitchNum;

for (PianoNote note : PianoRollCanvas.NOTE_COPY_BUFFER) {
PianoNote copy = note.clone();
copy.setStart(startTime + (copy.getStart() - timeAdjust));

int pitchNum = copy.getOctave() * scaleDegrees + copy.getScaleDegree();
pitchNum += pitchNumAdjust;

copy.setOctave(pitchNum / scaleDegrees);
copy.setScaleDegree(pitchNum % scaleDegrees);

canvas.addNote(copy);
}

} else if (e.isShiftDown() && ((e.getModifiers() & OS_CTRL_KEY) != OS_CTRL_KEY)) {
fireSelectionEvent(new SelectionEvent<>(null,
SelectionEvent.SELECTION_CLEAR));
Expand All @@ -145,18 +170,17 @@ public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();

float startTime = (float)x / canvas.p.getPixelSecond();
float startTime = (float) x / canvas.p.getPixelSecond();
float duration = 5.0f / canvas.p.getPixelSecond();



if (canvas.p.isSnapEnabled()) {
float snapValue = canvas.p.getSnapValue();
startTime = ScoreUtilities.getSnapValueStart(startTime, snapValue);

duration = canvas.p.getSnapValue();
}
}

PianoNoteView noteView = canvas.addNote(startTime, y, 0);
PianoNoteView noteView = canvas.addNote(startTime, y);
SelectionEvent<PianoNoteView> selEvt = new SelectionEvent<>(noteView,
SelectionEvent.SELECTION_ADD);

Expand Down Expand Up @@ -187,7 +211,7 @@ public void mouseReleased(MouseEvent e) {
}

if (start != null) {
if(!canvas.p.isSnapEnabled()) {
if (!canvas.p.isSnapEnabled()) {
if (canvas.getCursor() == NORMAL_CURSOR) {
canvas.noteBuffer.endMove();
} else {
Expand Down Expand Up @@ -246,24 +270,23 @@ private void moveNotes(MouseEvent e) {

int noteHeight = canvas.getNoteHeight();
int layerDiff = (e.getPoint().y / noteHeight) - (start.y / noteHeight);

if (canvas.p.isSnapEnabled()) {
float timeAdjust = (float)diffX / canvas.p.getPixelSecond();


float timeAdjust = (float) diffX / canvas.p.getPixelSecond();

float initialStartTime = canvas.noteBuffer.initialStartTimes[0];

float tempStart = initialStartTime + timeAdjust;
if(tempStart < 0.0f) {

if (tempStart < 0.0f) {
timeAdjust = -initialStartTime;
} else {
float snappedStart = ScoreUtilities.getSnapValueMove(tempStart,
canvas.p.getSnapValue());
canvas.p.getSnapValue());

timeAdjust = snappedStart - initialStartTime;
}

canvas.noteBuffer.moveByTime(timeAdjust, layerDiff);
} else {
canvas.noteBuffer.move(diffX, layerDiff);
Expand All @@ -275,30 +298,28 @@ private void resizeNote(MouseEvent e) {
int mouseX = e.getPoint().x;

if (canvas.p.isSnapEnabled()) {

float snapValue = canvas.p.getSnapValue();
float endTime = ScoreUtilities.getSnapValueMove((float)mouseX / canvas.p.getPixelSecond(),

float endTime = ScoreUtilities.getSnapValueMove((float) mouseX / canvas.p.getPixelSecond(),
snapValue);



float minTime = ScoreUtilities.getSnapValueMove(
canvas.noteBuffer.initialStartTimes[0] + snapValue / 2,
canvas.noteBuffer.initialStartTimes[0] + snapValue / 2,
snapValue);

endTime = (endTime < minTime) ? minTime : endTime;

float newDuration = endTime - canvas.noteBuffer.initialStartTimes[0];

canvas.noteBuffer.setDuration(newDuration);

} else {
int diffX = mouseX - start.x;
int diffX = mouseX - start.x;

canvas.noteBuffer.resize(diffX);
canvas.noteBuffer.resize(diffX);
}


}

/*
Expand Down Expand Up @@ -355,7 +376,6 @@ public void endMarquee() {
}

// SELECTION EVENT CODE

public void fireSelectionEvent(SelectionEvent<PianoNoteView> se) {
for (SelectionListener<PianoNoteView> listener : listeners) {
listener.selectionPerformed(se);
Expand All @@ -369,4 +389,4 @@ public void addSelectionListener(SelectionListener<PianoNoteView> sl) {
public void removeSelectionListener(SelectionListener<PianoNoteView> sl) {
listeners.remove(sl);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
Expand All @@ -60,6 +61,9 @@
public class PianoRollCanvas extends JLayeredPane implements Scrollable,
PropertyChangeListener {

// TODO - This shouldn't be public, but it will be for now...
public static final List<PianoNote> NOTE_COPY_BUFFER = new ArrayList<>();

JPopupMenu popup = new JPopupMenu();

private static final int RIGHT_EXTRA_SPACE = 100;
Expand All @@ -78,8 +82,6 @@ public class PianoRollCanvas extends JLayeredPane implements Scrollable,

public NoteBuffer noteBuffer = new NoteBuffer();

public PianoNote bufferedNote = null;

ComponentListener cl;

private final NoteCanvasMouseListener nMouse;
Expand Down Expand Up @@ -166,19 +168,15 @@ public void actionPerformed(ActionEvent e) {

@Override
public void actionPerformed(ActionEvent e) {
if (noteBuffer.size() == 1) {
cut();
}
cut();
}
});

actionMap.put("copy", new AbstractAction() {

@Override
public void actionPerformed(ActionEvent e) {
if (noteBuffer.size() == 1) {
copy();
}
copy();
}
});

Expand Down Expand Up @@ -232,8 +230,10 @@ public void cut() {
}

public void copy() {
PianoNote noteInBuffer = noteBuffer.get(0).getPianoNote();
bufferedNote = (PianoNote) (noteInBuffer.clone());
NOTE_COPY_BUFFER.clear();
for(PianoNoteView pnv : noteBuffer) {
NOTE_COPY_BUFFER.add(pnv.getPianoNote().clone());
}
}

/**
Expand Down Expand Up @@ -390,27 +390,33 @@ public void editPianoRoll(PianoRoll p) {
* @param x
* @param y
*/
public PianoNoteView addNote(float startTime, int y, int dummy) {
public PianoNoteView addNote(float startTime, int y) {
PianoNote note = new PianoNote();
note.setNoteTemplate(p.getNoteTemplate());
note.setStart(startTime);

int[] pch = getOctaveScaleDegreeForY(y);
note.setOctave(pch[0]);
note.setScaleDegree(pch[1]);

return addNote(note, startTime, y, dummy);
return addNote(note);
}

public PianoNoteView addNote(PianoNote note, float startTime, int y, int dummy) {
note.setStart(startTime);
public int[] getOctaveScaleDegreeForY(int y) {
int[] retVal = new int[2];

int h = getHeight() - y;
int noteHeight = p.getNoteHeight();

h = h / noteHeight;
int numScaleDegrees = p.getScale().getNumScaleDegrees();
int octave = h / numScaleDegrees;
int scaleDegree = h % numScaleDegrees;
retVal[0] = h / numScaleDegrees;
retVal[1] = h % numScaleDegrees;

note.setOctave(octave);
note.setScaleDegree(scaleDegree);
return retVal;
}

public PianoNoteView addNote(PianoNote note) {
p.getNotes().add(note);
PianoNoteView n = addNoteView(note);

Expand Down

0 comments on commit 5f993cf

Please sign in to comment.