Add two virtual keyboard modes
authorMark Slee <mcslee@Mark-Slees-MacBook-Pro.local>
Fri, 20 Sep 2013 02:58:58 +0000 (19:58 -0700)
committerMark Slee <mcslee@Mark-Slees-MacBook-Pro.local>
Fri, 20 Sep 2013 03:05:04 +0000 (20:05 -0700)
_Internals.pde
_UIFramework.pde
_UIImplementation.pde
code/HeronLX.jar

index 044d650de195f7883980342ac25d8ba419c73bcd..3710e0eb7b8fafe6b19018e0c7db3291a4b86fe1 100644 (file)
@@ -48,7 +48,8 @@ HeronLX lx;
 LXPattern[] patterns;
 MappingTool mappingTool;
 PandaDriver[] pandaBoards;
-MidiListener midiQwerty;
+MidiListener midiQwertyKeys;
+MidiListener midiQwertyAPC;
 
 // Display configuration mode
 boolean mappingMode = false;
@@ -123,7 +124,8 @@ void setup() {
 
   // MIDI devices
   List<MidiListener> midiListeners = new ArrayList<MidiListener>();
-  midiListeners.add(midiQwerty = new MidiListener());
+  midiListeners.add(midiQwertyKeys = new MidiListener(MidiListener.KEYS));
+  midiListeners.add(midiQwertyAPC = new MidiListener(MidiListener.APC));
   for (MidiInputDevice device : RWMidi.getInputDevices()) {
     boolean enableDevice = device.getName().contains("APC");
     midiListeners.add(new MidiListener(device).setEnabled(enableDevice));
@@ -141,8 +143,8 @@ void setup() {
     new UISpeed(4, 624, 140, 50),
         
     new UIPatternDeck(lx.engine.getDeck(1), "PATTERN B", width-144, 4, 140, 324),
-    uiMidi = new UIMidi(midiListeners, width-144, 332, 140, 160),
-    new UIOutput(width-144, 498, 140, 106),
+    uiMidi = new UIMidi(midiListeners, width-144, 332, 140, 158),
+    new UIOutput(width-144, 494, 140, 106),
     
     uiCrossfader = new UICrossfader(width/2-90, height-90, 180, 86),
     
@@ -171,10 +173,16 @@ void setup() {
 }
 
 public class MidiListener extends AbstractScrollItem {
+  
+  public static final int MIDI = 0;
+  public static final int KEYS = 1;
+  public static final int APC = 2;
+  
   private boolean enabled = false;
   private final String name;
   
   MidiListener(MidiInputDevice d) {
+    mode = MIDI;
     d.createInput(this);
     name = d.getName();
   }
@@ -190,8 +198,25 @@ public class MidiListener extends AbstractScrollItem {
   
   final Map<Character, NoteMeta> keyToNote = new HashMap<Character, NoteMeta>();
   
-  MidiListener() {
-    name = "QWERTY Keyboard";
+  private final int mode;
+  private int octaveShift = 0;
+  
+  MidiListener(int mode) {
+    this.mode = mode;
+    switch (mode) {
+      case APC:
+        name = "QWERTY (APC Mode)";
+        mapAPC();
+        break;
+      default:
+      case KEYS:
+        name = "QWERTY (Key Mode)";
+        mapKeys();
+        break;
+    }
+  }
+  
+  private void mapAPC() {
     mapNote('1', 0, 53);
     mapNote('2', 1, 53);
     mapNote('3', 2, 53);
@@ -219,6 +244,26 @@ public class MidiListener extends AbstractScrollItem {
     registerKeyEvent(this);
   }
   
+  private void mapKeys() {
+    int note = 48;
+    mapNote('a', 1, note++);
+    mapNote('w', 1, note++);
+    mapNote('s', 1, note++);
+    mapNote('e', 1, note++);
+    mapNote('d', 1, note++);
+    mapNote('f', 1, note++);
+    mapNote('t', 1, note++);
+    mapNote('g', 1, note++);
+    mapNote('y', 1, note++);
+    mapNote('h', 1, note++);
+    mapNote('u', 1, note++);
+    mapNote('j', 1, note++);
+    mapNote('k', 1, note++);
+    mapNote('o', 1, note++);
+    mapNote('l', 1, note++);
+    registerKeyEvent(this);
+  }
+  
   void mapNote(char ch, int channel, int number) {
     keyToNote.put(ch, new NoteMeta(channel, number));
   }
@@ -228,15 +273,28 @@ public class MidiListener extends AbstractScrollItem {
   }
   
   public void keyEvent(KeyEvent e) {
+    if (!enabled) {
+      return;
+    }
     char c = Character.toLowerCase(e.getKeyChar());
     NoteMeta nm = keyToNote.get(c);
     if (nm != null) {
       switch (e.getID()) {
         case KeyEvent.KEY_PRESSED:
-          noteOnReceived(new Note(Note.NOTE_ON, nm.channel, nm.number, 127));
+          noteOnReceived(new Note(Note.NOTE_ON, nm.channel, nm.number + octaveShift*12, 127));
           break;
         case KeyEvent.KEY_RELEASED:
-          noteOffReceived(new Note(Note.NOTE_OFF, nm.channel, nm.number, 0));
+          noteOffReceived(new Note(Note.NOTE_OFF, nm.channel, nm.number + octaveShift*12, 0));
+          break;
+      }
+    }
+    if ((mode == KEYS) && (e.getID() == KeyEvent.KEY_PRESSED)) {
+      switch (c) {
+        case 'z':
+          octaveShift = constrain(octaveShift-1, -4, 4);
+          break;
+        case 'x':
+          octaveShift = constrain(octaveShift+1, -4, 4);
           break;
       }
     }
@@ -540,13 +598,13 @@ void keyPressed() {
       frameRate(++targetFramerate);
       break;
     case 'd':
-      if (!midiQwerty.isEnabled()) {
+      if (!midiQwertyAPC.isEnabled() && !midiQwertyKeys.isEnabled()) {
         debugMode = !debugMode;
         println("Debug output: " + (debugMode ? "ON" : "OFF"));
       }
       break;
     case 'm':
-      if (!midiQwerty.isEnabled()) {
+      if (!midiQwertyAPC.isEnabled() && !midiQwertyKeys.isEnabled()) {
         mappingMode = !mappingMode;
         uiPatternA.setVisible(!mappingMode);
         uiMapping.setVisible(mappingMode);
@@ -568,7 +626,9 @@ void keyPressed() {
       }
       break;
     case 'u':
-      uiOn = !uiOn;
+      if (!midiQwertyAPC.isEnabled() && !midiQwertyKeys.isEnabled()) {
+        uiOn = !uiOn;
+      }
       break;
   }
 }
index 2b3d0470b5c9420d44199392aeab00b9f3892e80..0e0be79c005c08fd3750c5b9795070270de008d7 100644 (file)
@@ -778,7 +778,7 @@ public class UIScrollList extends UIObject {
   }
   
   public void setScrollOffset(int offset) {
-    scrollOffset = constrain(offset, 0, items.size() - numVisibleItems);
+    scrollOffset = constrain(offset, 0, max(0, items.size() - numVisibleItems));
     scrollYStart = round(scrollOffset * h / items.size());
     scrollYHeight = round(numVisibleItems * h / items.size());
     redraw();
index ae61d30a94870a2b2c09c0dfc6c994ccf4740f36..e72d76b598976e164a04c78a0e9cb1fe7bd48627 100644 (file)
@@ -490,9 +490,9 @@ class UIMidi extends UIWindow {
     for (MidiListener ml : midiListeners) {
       scrollItems.add(ml);
     }
-    new UIScrollList(1, titleHeight, w-2, 80).setItems(scrollItems).addToContainer(this);
-    (deckMode = new UIToggleSet(4, 110, 90, 20)).setOptions(new String[] { "A", "B" }).addToContainer(this);
-    (logMode = new UIButton(98, 110, w-103, 20)).setLabel("LOG").addToContainer(this);
+    new UIScrollList(1, titleHeight, w-2, 100).setItems(scrollItems).addToContainer(this);
+    (deckMode = new UIToggleSet(4, 130, 90, 20)).setOptions(new String[] { "A", "B" }).addToContainer(this);
+    (logMode = new UIButton(98, 130, w-103, 20)).setLabel("LOG").addToContainer(this);
   }
   
   public boolean logMidi() {
index 5a98f5e5d93681e73eebac40dc9b8c4768da479e..a3f624137cafd5fdb44e9bd18cd1bcdade1dc611 100755 (executable)
Binary files a/code/HeronLX.jar and b/code/HeronLX.jar differ