changeset 5:0bcbe28a25a2

GUI changes to allow MIDI pitch wheel range to be set in each keyboard segment.
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Wed, 13 Nov 2013 21:00:16 +0000
parents 9c21dd60a0f6
children 36fe60d0aadb
files Builds/MacOSX/TouchKeys.xcodeproj/project.pbxproj Builds/MacOSX/TouchKeys.xcodeproj/project.xcworkspace/xcuserdata/apm.xcuserdatad/UserInterfaceState.xcuserstate Source/GUI/KeyboardZoneComponent.cpp Source/GUI/KeyboardZoneComponent.h Source/MainApplicationController.cpp Source/TouchKeys/MidiKeyboardSegment.cpp Source/TouchKeys/MidiKeyboardSegment.h TouchKeys.jucer
diffstat 8 files changed, 157 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/Builds/MacOSX/TouchKeys.xcodeproj/project.pbxproj	Tue Nov 12 12:49:12 2013 +0000
+++ b/Builds/MacOSX/TouchKeys.xcodeproj/project.pbxproj	Wed Nov 13 21:00:16 2013 +0000
@@ -744,7 +744,6 @@
 		B8CB4838AFDE0B20C61A7248 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel.cpp"; path = "../../../juce/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp"; sourceTree = "SOURCE_ROOT"; };
 		B8DF81CC9D4E0BE71C3AF558 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_WebBrowserComponent.mm"; path = "../../../juce/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm"; sourceTree = "SOURCE_ROOT"; };
 		B8F2014DEA90E3849192C12D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_XmlElement.h"; path = "../../../juce/modules/juce_core/xml/juce_XmlElement.h"; sourceTree = "SOURCE_ROOT"; };
-		B928D73E2A712404DA6A9D39 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PopupMenu.h"; path = "../../../juce/modules/juce_gui_basics/menus/juce_PopupMenu.h"; sourceTree = "SOURCE_ROOT"; };
 		B954FAFC45D231B388305CBB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_OggVorbisAudioFormat.cpp"; path = "../../../juce/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; };
 		B967DAA2B052D328B12C7DE8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Synthesiser.cpp"; path = "../../../juce/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp"; sourceTree = "SOURCE_ROOT"; };
 		B9683DFC5C73C8EA097C0C87 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativeCoordinate.h"; path = "../../../juce/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h"; sourceTree = "SOURCE_ROOT"; };
@@ -783,7 +782,6 @@
 		C25315D4D50046938BDE18D8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageConvolutionKernel.h"; path = "../../../juce/modules/juce_graphics/images/juce_ImageConvolutionKernel.h"; sourceTree = "SOURCE_ROOT"; };
 		C266C85403BF3646B729144D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OpenGLDisplayBase.h; path = ../../Source/Display/OpenGLDisplayBase.h; sourceTree = "SOURCE_ROOT"; };
 		C2673A6A3D247F3CDCF66FF0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedWriteLock.h"; path = "../../../juce/modules/juce_core/threads/juce_ScopedWriteLock.h"; sourceTree = "SOURCE_ROOT"; };
-		C26E6685AAEC528FC835CA5C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBuilder.h"; path = "../../../juce/modules/juce_gui_basics/layout/juce_ComponentBuilder.h"; sourceTree = "SOURCE_ROOT"; };
 		C2762F0E696E257A507595A5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MRPMapping.cpp; path = ../../Source/Mappings/MRPMapping.cpp; sourceTree = "SOURCE_ROOT"; };
 		C2D442FDEECC11C9BD433379 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = KeyboardDisplay.cpp; path = ../../Source/Display/KeyboardDisplay.cpp; sourceTree = "SOURCE_ROOT"; };
 		C31F902A006BD5C9BD9259B3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioIODeviceType.h"; path = "../../../juce/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h"; sourceTree = "SOURCE_ROOT"; };
@@ -832,6 +830,7 @@
 		D3AB19332A0AE6C6A82612EF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SelectedItemSet.h"; path = "../../../juce/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h"; sourceTree = "SOURCE_ROOT"; };
 		D3C368F0138FE8F3F0B7540F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_IPAddress.h"; path = "../../../juce/modules/juce_core/network/juce_IPAddress.h"; sourceTree = "SOURCE_ROOT"; };
 		D3C722814093C96312625553 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_StringPairArray.cpp"; path = "../../../juce/modules/juce_core/text/juce_StringPairArray.cpp"; sourceTree = "SOURCE_ROOT"; };
+		D3D34D4A8674E01CCE92CE65 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatWriter.h"; path = "../../../juce/modules/juce_audio_formats/format/juce_AudioFormatWriter.h"; sourceTree = "SOURCE_ROOT"; };
 		D3FE20DFB95B39D949C6B842 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LowLevelGraphicsPostScriptRenderer.cpp"; path = "../../../juce/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp"; sourceTree = "SOURCE_ROOT"; };
 		D42A52316423A9F531FFC765 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Network.cpp"; path = "../../../juce/modules/juce_core/native/juce_android_Network.cpp"; sourceTree = "SOURCE_ROOT"; };
 		D4D1E893C5144CF41D381E0E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../juce/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; };
@@ -852,23 +851,23 @@
 		DA76EEB0BD9183E2006CE9EB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../../juce/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; };
 		DB09B4EA350E52FB74BAAD9D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Component.cpp"; path = "../../../juce/modules/juce_gui_basics/components/juce_Component.cpp"; sourceTree = "SOURCE_ROOT"; };
 		DBD3326F4F7F5F41D3B7EA99 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_Files.mm"; path = "../../../juce/modules/juce_core/native/juce_mac_Files.mm"; sourceTree = "SOURCE_ROOT"; };
-		DBDB2CBDB7DD3D7B9713D4C5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Scheduler.cpp; path = ../../Source/Utility/Scheduler.cpp; sourceTree = "SOURCE_ROOT"; };
-		DDF271285760C5642E3D3346 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_Windowing.mm"; path = "../../../juce/modules/juce_gui_basics/native/juce_ios_Windowing.mm"; sourceTree = "SOURCE_ROOT"; };
+		DD18A8B0C1A5F8BDA30BAA50 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OscMidiConverter.h; path = ../../Source/TouchKeys/OscMidiConverter.h; sourceTree = "SOURCE_ROOT"; };
 		DF870F58DC21D8A032AE4D03 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
-		E263014FE404722FDDC437C8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CoreAudioFormat.h"; path = "../../../juce/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h"; sourceTree = "SOURCE_ROOT"; };
 		E9E267650C0230141C461A4B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ControlWindowMainComponent.cpp; path = ../../Source/GUI/ControlWindowMainComponent.cpp; sourceTree = "SOURCE_ROOT"; };
 		F07FDD832AD269D84A40DAF1 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
 		90E8A67FBC9B5B91FEB780F5 = { isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TouchKeys.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
+		B928D73E2A712404DA6A9D39 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PopupMenu.h"; path = "../../../juce/modules/juce_gui_basics/menus/juce_PopupMenu.h"; sourceTree = "SOURCE_ROOT"; };
+		C26E6685AAEC528FC835CA5C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBuilder.h"; path = "../../../juce/modules/juce_gui_basics/layout/juce_ComponentBuilder.h"; sourceTree = "SOURCE_ROOT"; };
 		D2F76A9A564C9C39C9110C7E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentBuilder.cpp"; path = "../../../juce/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp"; sourceTree = "SOURCE_ROOT"; };
-		D3D34D4A8674E01CCE92CE65 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioFormatWriter.h"; path = "../../../juce/modules/juce_audio_formats/format/juce_AudioFormatWriter.h"; sourceTree = "SOURCE_ROOT"; };
 		D3F247C3C568453665FD300D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LineSegment.h; path = ../../Source/Utility/LineSegment.h; sourceTree = "SOURCE_ROOT"; };
 		D70B19E3DE0323FFA2EFCBBF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentMovementWatcher.h"; path = "../../../juce/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h"; sourceTree = "SOURCE_ROOT"; };
 		D75E1147AF76C62DC23E7B18 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPress.h"; path = "../../../juce/modules/juce_gui_basics/keyboard/juce_KeyPress.h"; sourceTree = "SOURCE_ROOT"; };
 		DBC98946C2E19791899587BD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToggleButton.h"; path = "../../../juce/modules/juce_gui_basics/buttons/juce_ToggleButton.h"; sourceTree = "SOURCE_ROOT"; };
+		DBDB2CBDB7DD3D7B9713D4C5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Scheduler.cpp; path = ../../Source/Utility/Scheduler.cpp; sourceTree = "SOURCE_ROOT"; };
 		DBE3D6F70DF4558463C24395 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DrawableText.cpp"; path = "../../../juce/modules/juce_gui_basics/drawables/juce_DrawableText.cpp"; sourceTree = "SOURCE_ROOT"; };
 		DC7333AE4FD5C16D3B49EE77 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_ActiveXComponent.cpp"; path = "../../../juce/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
-		DD18A8B0C1A5F8BDA30BAA50 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OscMidiConverter.h; path = ../../Source/TouchKeys/OscMidiConverter.h; sourceTree = "SOURCE_ROOT"; };
 		DDC862F5672CFD8794EA65BC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MissingGLDefinitions.h"; path = "../../../juce/modules/juce_opengl/native/juce_MissingGLDefinitions.h"; sourceTree = "SOURCE_ROOT"; };
+		DDF271285760C5642E3D3346 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_Windowing.mm"; path = "../../../juce/modules/juce_gui_basics/native/juce_ios_Windowing.mm"; sourceTree = "SOURCE_ROOT"; };
 		DE68B78DB869AC78BCBD1214 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableText.h"; path = "../../../juce/modules/juce_gui_basics/drawables/juce_DrawableText.h"; sourceTree = "SOURCE_ROOT"; };
 		DE6A8EF9DD39C0260ADD27B0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = TouchkeyVibratoMapping.cpp; path = ../../Source/Mappings/Vibrato/TouchkeyVibratoMapping.cpp; sourceTree = "SOURCE_ROOT"; };
 		DE7280B3F30E33133756C534 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Messaging.cpp"; path = "../../../juce/modules/juce_events/native/juce_linux_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -881,6 +880,7 @@
 		E1B8E23E7491C09D6708018C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_NSViewComponentPeer.mm"; path = "../../../juce/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm"; sourceTree = "SOURCE_ROOT"; };
 		E1D304ED9044C0CE62C7B3AD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_WildcardFileFilter.h"; path = "../../../juce/modules/juce_gui_basics/filebrowser/juce_WildcardFileFilter.h"; sourceTree = "SOURCE_ROOT"; };
 		E2322B995208819DF175E332 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_mac_CoreGraphicsContext.h"; path = "../../../juce/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h"; sourceTree = "SOURCE_ROOT"; };
+		E263014FE404722FDDC437C8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CoreAudioFormat.h"; path = "../../../juce/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h"; sourceTree = "SOURCE_ROOT"; };
 		E2EE80FAFA0DADF6D8AD8EA0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGL_win32.h"; path = "../../../juce/modules/juce_opengl/native/juce_OpenGL_win32.h"; sourceTree = "SOURCE_ROOT"; };
 		E2F713FF46DF610A87C64265 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../../juce/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
 		E32397CB64E42DA5119CC3E8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FillType.h"; path = "../../../juce/modules/juce_graphics/colour/juce_FillType.h"; sourceTree = "SOURCE_ROOT"; };
@@ -907,7 +907,6 @@
 		E830ACDAC41A38A04A16E2CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_OpenGLRenderer.h"; path = "../../../juce/modules/juce_opengl/opengl/juce_OpenGLRenderer.h"; sourceTree = "SOURCE_ROOT"; };
 		E88D828B769B0DB0DC1D624B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ContainerDeletePolicy.h"; path = "../../../juce/modules/juce_core/memory/juce_ContainerDeletePolicy.h"; sourceTree = "SOURCE_ROOT"; };
 		E8D2B3CBDF5DED9EF0E0C63B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ToneGeneratorAudioSource.cpp"; path = "../../../juce/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp"; sourceTree = "SOURCE_ROOT"; };
-		E8EDACD332FC3BDFC3F0E6E1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Recorder.h; path = ../../Source/Utility/Recorder.h; sourceTree = "SOURCE_ROOT"; };
 		E91EEAE6F09A108DBF5E9BC5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectSound.cpp"; path = "../../../juce/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp"; sourceTree = "SOURCE_ROOT"; };
 		E9350A4235E42DBC9987725A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileBrowserListener.h"; path = "../../../juce/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h"; sourceTree = "SOURCE_ROOT"; };
 		E93D98571147B0AD0B0D42C1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringArray.h"; path = "../../../juce/modules/juce_core/text/juce_StringArray.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1084,7 +1083,6 @@
 				AF7CC57D767DFC1F4B121270,
 				D3F247C3C568453665FD300D,
 				7103BB75D00938B3DEF6F943,
-				E8EDACD332FC3BDFC3F0E6E1,
 				DBDB2CBDB7DD3D7B9713D4C5,
 				4B5B59C3EB40E81B0EB3FF2A,
 				32302BE7297F75C489B19CED,
@@ -2127,12 +2125,13 @@
 				"DEBUG=1",
 				"JUCER_XCODE_MAC_F6D2F4CF=1"); }; name = Debug; };
 		33B8957D355F89111F5FF5AE = { isa = XCBuildConfiguration; buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
 				HEADER_SEARCH_PATHS = "../../JuceLibraryCode ../../../juce/modules $(inherited)";
 				GCC_OPTIMIZATION_LEVEL = s;
 				INFOPLIST_FILE = Info.plist;
 				INSTALL_PATH = "$(HOME)/Applications";
 				CONFIGURATION_BUILD_DIR = "$(PROJECT_DIR)/build/$(CONFIGURATION)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
 				MACOSX_DEPLOYMENT_TARGET_ppc = 10.4;
 				SDKROOT_ppc = macosx10.5;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
Binary file Builds/MacOSX/TouchKeys.xcodeproj/project.xcworkspace/xcuserdata/apm.xcuserdatad/UserInterfaceState.xcuserstate has changed
--- a/Source/GUI/KeyboardZoneComponent.cpp	Tue Nov 12 12:49:12 2013 +0000
+++ b/Source/GUI/KeyboardZoneComponent.cpp	Wed Nov 13 21:00:16 2013 +0000
@@ -30,6 +30,7 @@
 KeyboardZoneComponent::KeyboardZoneComponent ()
     : controller_(0), keyboardSegment_(0)
 {
+    addAndMakeVisible (mappingListComponent = new MappingListComponent());
     addAndMakeVisible (midiOutputGroupComponent = new GroupComponent ("MIDI input group",
                                                                       "MIDI Output"));
 
@@ -126,20 +127,6 @@
     rangeHighComboBox->setTextWhenNoChoicesAvailable ("(no choices)");
     rangeHighComboBox->addListener (this);
 
-    addAndMakeVisible (useAftertouchButton = new ToggleButton ("use aftertouch button"));
-    useAftertouchButton->setButtonText ("Use keyboard aftertouch");
-    useAftertouchButton->addListener (this);
-    useAftertouchButton->setToggleState (true, dontSendNotification);
-
-    addAndMakeVisible (usePitchWheelButton = new ToggleButton ("use aftertouch button"));
-    usePitchWheelButton->setButtonText ("Use keyboard pitchwheel");
-    usePitchWheelButton->addListener (this);
-    usePitchWheelButton->setToggleState (true, dontSendNotification);
-
-    addAndMakeVisible (useControllersButton = new ToggleButton ("use aftertouch button"));
-    useControllersButton->setButtonText ("Use keyboard controllers");
-    useControllersButton->addListener (this);
-
     addAndMakeVisible (label6 = new Label ("new label",
                                            "Transpose:"));
     label6->setFont (Font (15.00f, Font::plain));
@@ -157,7 +144,6 @@
     midiOutputTransposeEditor->setPopupMenuEnabled (true);
     midiOutputTransposeEditor->setText (String::empty);
 
-    addAndMakeVisible (mappingListComponent = new MappingListComponent());
     addAndMakeVisible (label8 = new Label ("new label",
                                            "Mappings:"));
     label8->setFont (Font (15.00f, Font::plain));
@@ -170,6 +156,27 @@
     addMappingButton->setButtonText ("Add Mapping...");
     addMappingButton->addListener (this);
 
+    addAndMakeVisible (label9 = new Label ("new label",
+                                           "Pitchwheel range:"));
+    label9->setFont (Font (15.00f, Font::plain));
+    label9->setJustificationType (Justification::centredLeft);
+    label9->setEditable (false, false, false);
+    label9->setColour (TextEditor::textColourId, Colours::black);
+    label9->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
+
+    addAndMakeVisible (pitchWheelRangeEditor = new TextEditor ("pitch wheel range editor"));
+    pitchWheelRangeEditor->setMultiLine (false);
+    pitchWheelRangeEditor->setReturnKeyStartsNewLine (false);
+    pitchWheelRangeEditor->setReadOnly (false);
+    pitchWheelRangeEditor->setScrollbarsShown (true);
+    pitchWheelRangeEditor->setCaretVisible (true);
+    pitchWheelRangeEditor->setPopupMenuEnabled (true);
+    pitchWheelRangeEditor->setText (String::empty);
+
+    addAndMakeVisible (keyboardControllersButton = new TextButton ("keyboard controllers button"));
+    keyboardControllersButton->setButtonText ("Keyboard Controllers...");
+    keyboardControllersButton->addListener (this);
+
 
     //[UserPreSize]
     // Add modes to MIDI mode toggle box
@@ -194,7 +201,9 @@
     midiOutputChannelLowEditor->addListener(this);
     midiOutputChannelHighEditor->addListener(this);
     midiOutputTransposeEditor->addListener(this);
+    pitchWheelRangeEditor->addListener(this);
     addMappingButton->setTriggeredOnMouseDown(true);
+    keyboardControllersButton->setTriggeredOnMouseDown(true);
     //[/Constructor]
 }
 
@@ -203,6 +212,7 @@
     //[Destructor_pre]. You can add your own custom destruction code here..
     //[/Destructor_pre]
 
+    mappingListComponent = nullptr;
     midiOutputGroupComponent = nullptr;
     midiOutputDeviceComboBox = nullptr;
     label4 = nullptr;
@@ -217,14 +227,13 @@
     label7 = nullptr;
     rangeLowComboBox = nullptr;
     rangeHighComboBox = nullptr;
-    useAftertouchButton = nullptr;
-    usePitchWheelButton = nullptr;
-    useControllersButton = nullptr;
     label6 = nullptr;
     midiOutputTransposeEditor = nullptr;
-    mappingListComponent = nullptr;
     label8 = nullptr;
     addMappingButton = nullptr;
+    label9 = nullptr;
+    pitchWheelRangeEditor = nullptr;
+    keyboardControllersButton = nullptr;
 
 
     //[Destructor]. You can add your own custom destruction code here..
@@ -245,6 +254,7 @@
 
 void KeyboardZoneComponent::resized()
 {
+    mappingListComponent->setBounds (0, 168, 552, 260);
     midiOutputGroupComponent->setBounds (200, 8, 344, 128);
     midiOutputDeviceComboBox->setBounds (264, 32, 264, 24);
     label4->setBounds (208, 32, 55, 24);
@@ -259,14 +269,13 @@
     label7->setBounds (88, 32, 32, 24);
     rangeLowComboBox->setBounds (24, 32, 64, 24);
     rangeHighComboBox->setBounds (112, 32, 64, 24);
-    useAftertouchButton->setBounds (24, 56, 152, 24);
-    usePitchWheelButton->setBounds (24, 80, 152, 24);
-    useControllersButton->setBounds (24, 104, 152, 24);
     label6->setBounds (392, 96, 80, 24);
     midiOutputTransposeEditor->setBounds (472, 96, 56, 24);
-    mappingListComponent->setBounds (0, 168, 552, 260);
     label8->setBounds (8, 144, 88, 24);
     addMappingButton->setBounds (440, 144, 104, 20);
+    label9->setBounds (24, 68, 104, 24);
+    pitchWheelRangeEditor->setBounds (128, 68, 48, 24);
+    keyboardControllersButton->setBounds (24, 100, 152, 20);
     //[UserResized] Add your own custom resize handling here..
     //[/UserResized]
 }
@@ -337,34 +346,18 @@
         keyboardSegment_->setVoiceStealingEnabled(stealing);
         //[/UserButtonCode_midiOutputVoiceStealingButton]
     }
-    else if (buttonThatWasClicked == useAftertouchButton)
-    {
-        //[UserButtonCode_useAftertouchButton] -- add your button handler code here..
-        bool aftertouch = useAftertouchButton->getToggleState();
-        keyboardSegment_->setUsesKeyboardChannelPressure(aftertouch);
-        //[/UserButtonCode_useAftertouchButton]
-    }
-    else if (buttonThatWasClicked == usePitchWheelButton)
-    {
-        //[UserButtonCode_usePitchWheelButton] -- add your button handler code here..
-        bool pitchwheel = usePitchWheelButton->getToggleState();
-        keyboardSegment_->setUsesKeyboardPitchWheel(pitchwheel);
-        //[/UserButtonCode_usePitchWheelButton]
-    }
-    else if (buttonThatWasClicked == useControllersButton)
-    {
-        //[UserButtonCode_useControllersButton] -- add your button handler code here..
-        bool controllers = useControllersButton->getToggleState();
-        keyboardSegment_->setUsesKeyboardMIDIControllers(controllers);
-        //[/UserButtonCode_useControllersButton]
-    }
     else if (buttonThatWasClicked == addMappingButton)
     {
         //[UserButtonCode_addMappingButton] -- add your button handler code here..
-        // TODO: add new mapping
         createMappingListPopup();
         //[/UserButtonCode_addMappingButton]
     }
+    else if (buttonThatWasClicked == keyboardControllersButton)
+    {
+        //[UserButtonCode_keyboardControllersButton] -- add your button handler code here..
+        createKeyboardControllerPopup();
+        //[/UserButtonCode_keyboardControllersButton]
+    }
 
     //[UserbuttonClicked_Post]
     //[/UserbuttonClicked_Post]
@@ -408,6 +401,10 @@
             transpose = 48;
         keyboardSegment_->setOutputTransposition(transpose);
     }
+    else if(&editor == pitchWheelRangeEditor) {
+        float range = atof(pitchWheelRangeEditor->getText().toUTF8());
+        keyboardSegment_->setMidiPitchWheelRange(range);
+    }
 }
 
 void KeyboardZoneComponent::textEditorEscapeKeyPressed(TextEditor &editor)
@@ -476,6 +473,12 @@
     }
 
     // Update text editors
+    if(!pitchWheelRangeEditor->hasKeyboardFocus(true) || forceUpdates) {
+        float value = keyboardSegment_->midiPitchWheelRange();
+        char st[16];
+        snprintf(st, 16, "%.1f", value);
+        pitchWheelRangeEditor->setText(st);
+    }
     if(!midiOutputChannelLowEditor->hasKeyboardFocus(true) || forceUpdates) {
         int rangeLow = keyboardSegment_->outputChannelLowest() + 1; // 0-15 --> 1-16
         midiOutputChannelLowEditor->setText(String(rangeLow));
@@ -498,9 +501,9 @@
     }
 
     // Update buttons
-    useAftertouchButton->setToggleState(keyboardSegment_->usesKeyboardChannnelPressure(), dontSendNotification);
-    usePitchWheelButton->setToggleState(keyboardSegment_->usesKeyboardPitchWheel(), dontSendNotification);
-    useControllersButton->setToggleState(keyboardSegment_->usesKeyboardMIDIControllers(), dontSendNotification);
+    //useAftertouchButton->setToggleState(keyboardSegment_->usesKeyboardChannnelPressure(), dontSendNotification);
+    //usePitchWheelButton->setToggleState(keyboardSegment_->usesKeyboardPitchWheel(), dontSendNotification);
+    //useControllersButton->setToggleState(keyboardSegment_->usesKeyboardMIDIControllers(), dontSendNotification);
 
     // Update the mapping list
     mappingListComponent->synchronize();
@@ -587,6 +590,25 @@
                        ModalCallbackFunction::forComponent(staticMappingChosenCallback, this));
 }
 
+// Create a popup menu allowing selection of which controllers to retransmit
+void KeyboardZoneComponent::createKeyboardControllerPopup()
+{
+    if(controller_ == 0 || keyboardSegment_ == 0)
+        return;
+    
+    PopupMenu menu;
+    
+    menu.addItem(MidiKeyboardSegment::kControlPitchWheel, "Retransmit from Keyboard:", false);
+    menu.addSeparator();
+    menu.addItem(MidiKeyboardSegment::kControlPitchWheel, "Pitch Wheel", true, keyboardSegment_->usesKeyboardPitchWheel());
+    menu.addItem(MidiKeyboardSegment::kControlChannelAftertouch, "Aftertouch", true, keyboardSegment_->usesKeyboardChannnelPressure());
+    menu.addItem(1, "CC 1 (Mod Wheel)", true, keyboardSegment_->usesKeyboardModWheel());
+    menu.addItem(kKeyboardControllerRetransmitOthers, "Other Controllers", true, keyboardSegment_->usesKeyboardMIDIControllers());
+    
+    menu.showMenuAsync(PopupMenu::Options().withTargetComponent(keyboardControllersButton),
+                       ModalCallbackFunction::forComponent(staticKeyboardControllerChosenCallback, this));
+}
+
 // Called from the popup menu, indicating the selected item
 void KeyboardZoneComponent::mappingChosenCallback(int result)
 {
@@ -602,6 +624,27 @@
         }
     }
 }
+
+// Called from the popup menu, indicated selected controller
+void KeyboardZoneComponent::keyboardControllerChosenCallback(int result)
+{
+    if(controller_ == 0 || keyboardSegment_ == 0)
+        return;
+    
+    // Enable or disable retransmitting specific messages
+    if(result == MidiKeyboardSegment::kControlPitchWheel) {
+        keyboardSegment_->setUsesKeyboardPitchWheel(!keyboardSegment_->usesKeyboardPitchWheel());
+    }
+    else if(result == MidiKeyboardSegment::kControlChannelAftertouch) {
+        keyboardSegment_->setUsesKeyboardChannelPressure(!keyboardSegment_->usesKeyboardChannnelPressure());
+    }
+    else if(result == 1) { // ModWheel == CC 1
+        keyboardSegment_->setUsesKeyboardModWheel(!keyboardSegment_->usesKeyboardModWheel());
+    }
+    else if(result == kKeyboardControllerRetransmitOthers) {
+        keyboardSegment_->setUsesKeyboardMIDIControllers(!keyboardSegment_->usesKeyboardMIDIControllers());
+    }
+}
 //[/MiscUserCode]
 
 
@@ -620,6 +663,9 @@
                  snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330"
                  fixedSize="1" initialWidth="552" initialHeight="400">
   <BACKGROUND backgroundColour="ffd2d2d2"/>
+  <JUCERCOMP name="mapping list" id="4d5d007374cdad00" memberName="mappingListComponent"
+             virtualName="MappingListComponent" explicitFocusOrder="0" pos="0 168 552 260"
+             sourceFile="" constructorParams=""/>
   <GROUPCOMPONENT name="MIDI input group" id="49eee95279c0cc95" memberName="midiOutputGroupComponent"
                   virtualName="" explicitFocusOrder="0" pos="200 8 344 128" title="MIDI Output"/>
   <COMBOBOX name="MIDI input combo box" id="244410f02f6c1c72" memberName="midiOutputDeviceComboBox"
@@ -672,15 +718,6 @@
   <COMBOBOX name="range high combo combo box" id="7cba07ed947e85b2" memberName="rangeHighComboBox"
             virtualName="" explicitFocusOrder="0" pos="112 32 64 24" editable="1"
             layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/>
-  <TOGGLEBUTTON name="use aftertouch button" id="bd917dd46e68ffa3" memberName="useAftertouchButton"
-                virtualName="" explicitFocusOrder="0" pos="24 56 152 24" buttonText="Use keyboard aftertouch"
-                connectedEdges="0" needsCallback="1" radioGroupId="0" state="1"/>
-  <TOGGLEBUTTON name="use aftertouch button" id="479868bf74ee0a1a" memberName="usePitchWheelButton"
-                virtualName="" explicitFocusOrder="0" pos="24 80 152 24" buttonText="Use keyboard pitchwheel"
-                connectedEdges="0" needsCallback="1" radioGroupId="0" state="1"/>
-  <TOGGLEBUTTON name="use aftertouch button" id="e3b778166fac4e5f" memberName="useControllersButton"
-                virtualName="" explicitFocusOrder="0" pos="24 104 152 24" buttonText="Use keyboard controllers"
-                connectedEdges="0" needsCallback="1" radioGroupId="0" state="0"/>
   <LABEL name="new label" id="fd730bc972dffbdb" memberName="label6" virtualName=""
          explicitFocusOrder="0" pos="392 96 80 24" edTextCol="ff000000"
          edBkgCol="0" labelText="Transpose:" editableSingleClick="0" editableDoubleClick="0"
@@ -690,9 +727,6 @@
               virtualName="" explicitFocusOrder="0" pos="472 96 56 24" initialText=""
               multiline="0" retKeyStartsLine="0" readonly="0" scrollbars="1"
               caret="1" popupmenu="1"/>
-  <JUCERCOMP name="mapping list" id="4d5d007374cdad00" memberName="mappingListComponent"
-             virtualName="MappingListComponent" explicitFocusOrder="0" pos="0 168 552 260"
-             sourceFile="" constructorParams=""/>
   <LABEL name="new label" id="759d38e4603010a8" memberName="label8" virtualName=""
          explicitFocusOrder="0" pos="8 144 88 24" edTextCol="ff000000"
          edBkgCol="0" labelText="Mappings:" editableSingleClick="0" editableDoubleClick="0"
@@ -701,6 +735,18 @@
   <TEXTBUTTON name="add mapping button" id="a5fd2f0afd2d74b2" memberName="addMappingButton"
               virtualName="" explicitFocusOrder="0" pos="440 144 104 20" buttonText="Add Mapping..."
               connectedEdges="0" needsCallback="1" radioGroupId="0"/>
+  <LABEL name="new label" id="dbad09f5c5953d5f" memberName="label9" virtualName=""
+         explicitFocusOrder="0" pos="24 68 104 24" edTextCol="ff000000"
+         edBkgCol="0" labelText="Pitchwheel range:" editableSingleClick="0"
+         editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font"
+         fontsize="15" bold="0" italic="0" justification="33"/>
+  <TEXTEDITOR name="pitch wheel range editor" id="593d42c6501420c1" memberName="pitchWheelRangeEditor"
+              virtualName="" explicitFocusOrder="0" pos="128 68 48 24" initialText=""
+              multiline="0" retKeyStartsLine="0" readonly="0" scrollbars="1"
+              caret="1" popupmenu="1"/>
+  <TEXTBUTTON name="keyboard controllers button" id="a1ebab19a3375b93" memberName="keyboardControllersButton"
+              virtualName="" explicitFocusOrder="0" pos="24 100 152 20" buttonText="Keyboard Controllers..."
+              connectedEdges="0" needsCallback="1" radioGroupId="0"/>
 </JUCER_COMPONENT>
 
 END_JUCER_METADATA
--- a/Source/GUI/KeyboardZoneComponent.h	Tue Nov 12 12:49:12 2013 +0000
+++ b/Source/GUI/KeyboardZoneComponent.h	Wed Nov 13 21:00:16 2013 +0000
@@ -91,6 +91,12 @@
             component->mappingChosenCallback(result);
     }
     void mappingChosenCallback(int result);
+    
+    static void staticKeyboardControllerChosenCallback(int result, KeyboardZoneComponent* component) {
+        if (result != 0 && component != 0)
+            component->keyboardControllerChosenCallback(result);
+    }
+    void keyboardControllerChosenCallback(int result);
     //[/UserMethods]
 
     void paint (Graphics& g);
@@ -108,6 +114,11 @@
         kMidiOutputDeviceComboBoxOffset = 3,
         kMidiOutputModeComboBoxOffset = 1
     };
+    
+    enum {
+        // Special commands for keyboard controller popup button
+        kKeyboardControllerRetransmitOthers = 2000
+    };
 
     // Update list of MIDI output devices
     void updateOutputDeviceList();
@@ -115,6 +126,9 @@
     // Create popup menu for mapping list
     void createMappingListPopup();
 
+    // Create popup menu for keyboard controller retransmission
+    void createKeyboardControllerPopup();
+    
     MainApplicationController *controller_; // Pointer to the main application controller
     MidiKeyboardSegment *keyboardSegment_;  // Pointer to the segment this component controls
     std::vector<int> midiOutputDeviceIDs_;
@@ -122,6 +136,7 @@
     //[/UserVariables]
 
     //==============================================================================
+    ScopedPointer<MappingListComponent> mappingListComponent;
     ScopedPointer<GroupComponent> midiOutputGroupComponent;
     ScopedPointer<ComboBox> midiOutputDeviceComboBox;
     ScopedPointer<Label> label4;
@@ -136,14 +151,13 @@
     ScopedPointer<Label> label7;
     ScopedPointer<ComboBox> rangeLowComboBox;
     ScopedPointer<ComboBox> rangeHighComboBox;
-    ScopedPointer<ToggleButton> useAftertouchButton;
-    ScopedPointer<ToggleButton> usePitchWheelButton;
-    ScopedPointer<ToggleButton> useControllersButton;
     ScopedPointer<Label> label6;
     ScopedPointer<TextEditor> midiOutputTransposeEditor;
-    ScopedPointer<MappingListComponent> mappingListComponent;
     ScopedPointer<Label> label8;
     ScopedPointer<TextButton> addMappingButton;
+    ScopedPointer<Label> label9;
+    ScopedPointer<TextEditor> pitchWheelRangeEditor;
+    ScopedPointer<TextButton> keyboardControllersButton;
 
 
     //==============================================================================
--- a/Source/MainApplicationController.cpp	Tue Nov 12 12:49:12 2013 +0000
+++ b/Source/MainApplicationController.cpp	Wed Nov 13 21:00:16 2013 +0000
@@ -246,7 +246,7 @@
     newSegment->setVoiceStealingEnabled(false);
     newSegment->enableAllChannels();
     newSegment->setOutputTransposition(0);
-    newSegment->setUsesKeyboardChannelPressure(true);
+    newSegment->setUsesKeyboardPitchWheel(true);
     
     // Enable standalone mode on the new segment if generally enabled
     if(touchkeyStandaloneModeEnabled_)
--- a/Source/TouchKeys/MidiKeyboardSegment.cpp	Tue Nov 12 12:49:12 2013 +0000
+++ b/Source/TouchKeys/MidiKeyboardSegment.cpp	Wed Nov 13 21:00:16 2013 +0000
@@ -42,7 +42,8 @@
   mode_(ModeOff), channelMask_(0),
   noteMin_(0), noteMax_(127), outputChannelLowest_(0), outputTransposition_(0),
   damperPedalEnabled_(true), touchkeyStandaloneMode_(false),
-  usesKeyboardChannelPressure_(false), usesKeyboardPitchWheel_(true), usesKeyboardMidiControllers_(true),
+  usesKeyboardChannelPressure_(false), usesKeyboardPitchWheel_(false),
+  usesKeyboardModWheel_(false), usesKeyboardMidiControllers_(false),
   pitchWheelRange_(2.0), useVoiceStealing_(false)
 {
 	// Register for OSC messages from the internal keyboard source
@@ -133,7 +134,12 @@
 
 // Set the MIDI pitch wheel range
 void MidiKeyboardSegment::setMidiPitchWheelRange(float semitones, bool send) {
-    pitchWheelRange_ = semitones;
+    if(semitones < 0)
+        pitchWheelRange_ = 0;
+    else if(semitones > 48.0)
+        pitchWheelRange_ = 48.0;
+    else
+        pitchWheelRange_ = semitones;
     
     if(send)
         sendMidiPitchWheelRange();
@@ -302,7 +308,8 @@
         }
         
         if(message.getControllerNumber() >= 0 && message.getControllerNumber() < 128) {
-            if(usesKeyboardMidiControllers_) {
+            if((message.getControllerNumber() == 1 && usesKeyboardModWheel_) ||
+               (message.getControllerNumber() != 1 && usesKeyboardMidiControllers_)) {
                 controllerValues_[message.getControllerNumber()] = message.getControllerValue();
                 handleControlChangeRetransit(message.getControllerNumber(), message);
             }
--- a/Source/TouchKeys/MidiKeyboardSegment.h	Tue Nov 12 12:49:12 2013 +0000
+++ b/Source/TouchKeys/MidiKeyboardSegment.h	Wed Nov 13 21:00:16 2013 +0000
@@ -122,13 +122,23 @@
         if(!use)
             controllerValues_[kControlPitchWheel] = 8192;
     }
+
+    bool usesKeyboardModWheel() { return usesKeyboardModWheel_; }
+    void setUsesKeyboardModWheel(bool use) {
+        usesKeyboardModWheel_ = use;
+        // Reset to default if not using
+        if(!use) {
+            controllerValues_[1] = 0;
+        }
+    }
+    
     
     bool usesKeyboardMIDIControllers() { return usesKeyboardMidiControllers_; }
     void setUsesKeyboardMIDIControllers(bool use) {
         usesKeyboardMidiControllers_ = use;
         // Reset to default if not using
         if(!use) {
-            for(int i = 0; i < 128; i++)
+            for(int i = 2; i < 128; i++)
                 controllerValues_[i] = 0;
         }
     }
@@ -263,6 +273,7 @@
     bool touchkeyStandaloneMode_;                   // Whether we emulate MIDI data from TouchKeys
     bool usesKeyboardChannelPressure_;              // Whether this segment passes aftertouch from the keyboard
     bool usesKeyboardPitchWheel_;                   // Whether this segment passes pitchwheel from the keyboard
+    bool usesKeyboardModWheel_;                     // Whether this segment passes CC 1 (mod wheel) from keyboard
     bool usesKeyboardMidiControllers_;              // Whether this segment passes other controllers
     float pitchWheelRange_;                         // Range of MIDI pitch wheel (in semitones)
     
--- a/TouchKeys.jucer	Tue Nov 12 12:49:12 2013 +0000
+++ b/TouchKeys.jucer	Wed Nov 13 21:00:16 2013 +0000
@@ -164,7 +164,6 @@
         <FILE id="Vr8O7B" name="IIRFilter.h" compile="0" resource="0" file="Source/Utility/IIRFilter.h"/>
         <FILE id="cjfhQS" name="LineSegment.h" compile="0" resource="0" file="Source/Utility/LineSegment.h"/>
         <FILE id="cN1QXR" name="Node.h" compile="0" resource="0" file="Source/Utility/Node.h"/>
-        <FILE id="i3oBpY" name="Recorder.h" compile="0" resource="0" file="Source/Utility/Recorder.h"/>
         <FILE id="efXGfp" name="Scheduler.cpp" compile="1" resource="0" file="Source/Utility/Scheduler.cpp"/>
         <FILE id="w0DA4m" name="Scheduler.h" compile="0" resource="0" file="Source/Utility/Scheduler.h"/>
         <FILE id="kI95eE" name="TimerNode.cpp" compile="1" resource="0" file="Source/Utility/TimerNode.cpp"/>
@@ -250,7 +249,7 @@
       <CONFIGURATIONS>
         <CONFIGURATION name="Debug" osxSDK="default" osxCompatibility="default" osxArchitecture="64BitIntel"
                        isDebug="1" optimisation="1" targetName="TouchKeys"/>
-        <CONFIGURATION name="Release" osxSDK="default" osxCompatibility="default" osxArchitecture="64BitIntel"
+        <CONFIGURATION name="Release" osxSDK="default" osxCompatibility="10.6 SDK" osxArchitecture="64BitUniversal"
                        isDebug="0" optimisation="2" targetName="TouchKeys"/>
       </CONFIGURATIONS>
       <MODULEPATHS>