+ public String getLabel() {
+ return name;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public boolean isSelected() {
+ return enabled;
+ }
+
+ public void onMousePressed() {
+ setEnabled(!enabled);
+ }
+
+ public SCMidiInput setEnabled(boolean enabled) {
+ if (enabled != this.enabled) {
+ this.enabled = enabled;
+ for (SCMidiInputListener l : listeners) {
+ l.onEnabled(this, enabled);
+ }
+ }
+ return this;
+ }
+
+ private boolean logMidi() {
+ return (uiMidi != null) && uiMidi.logMidi();
+ }
+
+ final void programChangeReceived(ProgramChange pc) {
+ if (!enabled) {
+ return;
+ }
+ if (logMidi()) {
+ println(getLabel() + " :: Program Change :: " + pc.getNumber());
+ }
+ handleProgramChange(pc);
+ }
+
+ final void controllerChangeReceived(rwmidi.Controller cc) {
+ if (!enabled) {
+ return;
+ }
+ if (logMidi()) {
+ println(getLabel() + " :: Controller :: " + cc.getChannel() + " :: " + cc.getCC() + ":" + cc.getValue());
+ }
+ if (!handleGridControllerChange(cc)) {
+ if (!midiEngine.getFocusedPattern().controllerChange(cc)) {
+ handleControllerChange(cc);
+ }
+ }
+ }
+
+ final void noteOnReceived(Note note) {
+ if (!enabled) {
+ return;
+ }
+ if (logMidi()) {
+ println(getLabel() + " :: Note On :: " + note.getChannel() + ":" + note.getPitch() + ":" + note.getVelocity());
+ }
+ if (!handleGridNoteOn(note)) {
+ if (!midiEngine.getFocusedPattern().noteOn(note)) {
+ handleNoteOn(note);
+ }
+ }
+ }
+
+ final void noteOffReceived(Note note) {
+ if (!enabled) {
+ return;
+ }
+ if (logMidi()) {
+ println(getLabel() + " :: Note Off :: " + note.getChannel() + ":" + note.getPitch() + ":" + note.getVelocity());
+ }
+ if (!handleGridNoteOff(note)) {
+ if (!midiEngine.getFocusedPattern().noteOff(note)) {
+ handleNoteOff(note);
+ }
+ }
+ }
+
+ // Subclasses may implement these to map top-level functionality
+ protected boolean handleGridNoteOn(Note note) { return false; }
+ protected boolean handleGridNoteOff(Note note) { return false; }
+ protected boolean handleGridControllerChange(rwmidi.Controller cc) { return false; }
+ protected void handleProgramChange(ProgramChange pc) {}
+ protected void handleControllerChange(rwmidi.Controller cc) {}
+ protected void handleNoteOn(Note note) {}
+ protected void handleNoteOff(Note note) {}
+}
+
+public class VirtualKeyMidiInput extends SCMidiInput {
+
+ public static final int KEYS = 1;
+ public static final int APC = 2;
+
+ private final int mode;
+
+ private int octaveShift = 0;
+
+ class NoteMeta {
+ int channel;
+ int number;
+ NoteMeta(int channel, int number) {
+ this.channel = channel;
+ this.number = number;
+ }