Mercurial > hg > touchkeys
changeset 56:b4a2d2ae43cf tip
merge
author | Andrew McPherson <andrewm@eecs.qmul.ac.uk> |
---|---|
date | Fri, 23 Nov 2018 15:48:14 +0000 |
parents | 19650b4076ee (diff) e468cb91794a (current diff) |
children | |
files | Source/MainApplicationController.cpp |
diffstat | 4 files changed, 989 insertions(+), 984 deletions(-) [+] |
line wrap: on
line diff
--- a/Source/GUI/ControlWindowMainComponent.cpp Mon Feb 06 16:40:02 2017 +0000 +++ b/Source/GUI/ControlWindowMainComponent.cpp Fri Nov 23 15:48:14 2018 +0000 @@ -1,964 +1,964 @@ -/* - ============================================================================== - - This is an automatically generated GUI class created by the Introjucer! - - Be careful when adding custom code to these files, as only the code within - the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded - and re-saved. - - Created with Introjucer version: 3.1.0 - - ------------------------------------------------------------------------------ - - The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-13 by Raw Material Software Ltd. - - ============================================================================== -*/ - - -//[Headers] You can add your own extra header files here... -#ifndef TOUCHKEYS_NO_GUI -#include "KeyboardZoneComponent.h" -//[/Headers] - -#include "ControlWindowMainComponent.h" - - -//[MiscUserDefs] You can add your own user definitions and misc code here... -//[/MiscUserDefs] - -//============================================================================== -ControlWindowMainComponent::ControlWindowMainComponent () - : controller_(0) -{ - addAndMakeVisible (midiInputGroupComponent = new GroupComponent ("MIDI input group", - "MIDI Input")); - - addAndMakeVisible (midiInputDeviceComboBox = new ComboBox ("MIDI input combo box")); - midiInputDeviceComboBox->setEditableText (false); - midiInputDeviceComboBox->setJustificationType (Justification::centredLeft); - midiInputDeviceComboBox->setTextWhenNothingSelected (String::empty); - midiInputDeviceComboBox->setTextWhenNoChoicesAvailable ("(no choices)"); - midiInputDeviceComboBox->addListener (this); - - addAndMakeVisible (label = new Label ("new label", - "Keyboard:")); - label->setFont (Font (15.00f, Font::plain)); - label->setJustificationType (Justification::centredLeft); - label->setEditable (false, false, false); - label->setColour (TextEditor::textColourId, Colours::black); - label->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); - - addAndMakeVisible (groupComponent = new GroupComponent ("new group", - "TouchKeys")); - - addAndMakeVisible (label2 = new Label ("new label", - "Device:\n")); - label2->setFont (Font (15.00f, Font::plain)); - label2->setJustificationType (Justification::centredLeft); - label2->setEditable (false, false, false); - label2->setColour (TextEditor::textColourId, Colours::black); - label2->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); - - addAndMakeVisible (touchkeyDeviceComboBox = new ComboBox ("TouchKeys combo box")); - touchkeyDeviceComboBox->setEditableText (false); - touchkeyDeviceComboBox->setJustificationType (Justification::centredLeft); - touchkeyDeviceComboBox->setTextWhenNothingSelected (String::empty); - touchkeyDeviceComboBox->setTextWhenNoChoicesAvailable ("(no choices)"); - touchkeyDeviceComboBox->addListener (this); - - addAndMakeVisible (label3 = new Label ("new label", - "Status:\n")); - label3->setFont (Font (15.00f, Font::plain)); - label3->setJustificationType (Justification::centredLeft); - label3->setEditable (false, false, false); - label3->setColour (TextEditor::textColourId, Colours::black); - label3->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); - - addAndMakeVisible (touchkeyStartButton = new TextButton ("TouchKeys start button")); - touchkeyStartButton->setButtonText ("Start"); - touchkeyStartButton->addListener (this); - - addAndMakeVisible (touchkeyStatusLabel = new Label ("TouchKeys status label", - "not running")); - touchkeyStatusLabel->setFont (Font (15.00f, Font::plain)); - touchkeyStatusLabel->setJustificationType (Justification::centredLeft); - touchkeyStatusLabel->setEditable (false, false, false); - touchkeyStatusLabel->setColour (TextEditor::textColourId, Colours::black); - touchkeyStatusLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); - - addAndMakeVisible (oscGroupComponent = new GroupComponent ("OSC group", - "OSC Output")); - - addAndMakeVisible (label7 = new Label ("new label", - "Host:")); - label7->setFont (Font (15.00f, Font::plain)); - label7->setJustificationType (Justification::centredLeft); - label7->setEditable (false, false, false); - label7->setColour (TextEditor::textColourId, Colours::black); - label7->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); - - addAndMakeVisible (oscHostTextEditor = new TextEditor ("new text editor")); - oscHostTextEditor->setMultiLine (false); - oscHostTextEditor->setReturnKeyStartsNewLine (false); - oscHostTextEditor->setReadOnly (false); - oscHostTextEditor->setScrollbarsShown (true); - oscHostTextEditor->setCaretVisible (true); - oscHostTextEditor->setPopupMenuEnabled (true); - oscHostTextEditor->setText ("127.0.0.1"); - - addAndMakeVisible (label8 = new Label ("new label", - "Port:")); - label8->setFont (Font (15.00f, Font::plain)); - label8->setJustificationType (Justification::centredLeft); - label8->setEditable (false, false, false); - label8->setColour (TextEditor::textColourId, Colours::black); - label8->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); - - addAndMakeVisible (oscPortTextEditor = new TextEditor ("new text editor")); - oscPortTextEditor->setMultiLine (false); - oscPortTextEditor->setReturnKeyStartsNewLine (false); - oscPortTextEditor->setReadOnly (false); - oscPortTextEditor->setScrollbarsShown (true); - oscPortTextEditor->setCaretVisible (true); - oscPortTextEditor->setPopupMenuEnabled (true); - oscPortTextEditor->setText ("8000"); - - addAndMakeVisible (oscEnableButton = new ToggleButton ("OSC enable button")); - oscEnableButton->setButtonText ("Enable OSC output"); - oscEnableButton->addListener (this); - - addAndMakeVisible (oscEnableRawButton = new ToggleButton ("OSC enable raw button")); - oscEnableRawButton->setButtonText ("Send raw frames"); - oscEnableRawButton->addListener (this); - - addAndMakeVisible (label4 = new Label ("new label", - "Lowest Octave:")); - label4->setFont (Font (15.00f, Font::plain)); - label4->setJustificationType (Justification::centredLeft); - label4->setEditable (false, false, false); - label4->setColour (TextEditor::textColourId, Colours::black); - label4->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); - - addAndMakeVisible (touchkeyOctaveComboBox = new ComboBox ("TouchKeys octave box")); - touchkeyOctaveComboBox->setEditableText (false); - touchkeyOctaveComboBox->setJustificationType (Justification::centredLeft); - touchkeyOctaveComboBox->setTextWhenNothingSelected (String::empty); - touchkeyOctaveComboBox->setTextWhenNoChoicesAvailable ("(no choices)"); - touchkeyOctaveComboBox->addListener (this); - - addAndMakeVisible (oscInputGroupComponent = new GroupComponent ("MIDI input group", - "OSC Input")); - - addAndMakeVisible (oscInputEnableButton = new ToggleButton ("OSC input enable button")); - oscInputEnableButton->setButtonText ("Enable OSC input"); - oscInputEnableButton->addListener (this); - - addAndMakeVisible (label6 = new Label ("new label", - "Port:")); - label6->setFont (Font (15.00f, Font::plain)); - label6->setJustificationType (Justification::centredLeft); - label6->setEditable (false, false, false); - label6->setColour (TextEditor::textColourId, Colours::black); - label6->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); - - addAndMakeVisible (oscInputPortTextEditor = new TextEditor ("new text editor")); - oscInputPortTextEditor->setMultiLine (false); - oscInputPortTextEditor->setReturnKeyStartsNewLine (false); - oscInputPortTextEditor->setReadOnly (false); - oscInputPortTextEditor->setScrollbarsShown (true); - oscInputPortTextEditor->setCaretVisible (true); - oscInputPortTextEditor->setPopupMenuEnabled (true); - oscInputPortTextEditor->setText ("8001"); - - addAndMakeVisible (keyboardZoneTabbedComponent = new TabbedComponent (TabbedButtonBar::TabsAtTop)); - keyboardZoneTabbedComponent->setTabBarDepth (30); - keyboardZoneTabbedComponent->setCurrentTabIndex (-1); - - addAndMakeVisible (addZoneButton = new TextButton ("add zone button")); - addZoneButton->setButtonText ("Add"); - addZoneButton->addListener (this); - - addAndMakeVisible (removeZoneButton = new TextButton ("remove zone button")); - removeZoneButton->setButtonText ("Del"); - removeZoneButton->addListener (this); - - addAndMakeVisible (touchkeyAutodetectButton = new TextButton ("TouchKeys autodetect button")); - touchkeyAutodetectButton->setButtonText ("Detect"); - touchkeyAutodetectButton->addListener (this); - - addAndMakeVisible (midiInputAuxDeviceComboBox = new ComboBox ("MIDI input aux combo box")); - midiInputAuxDeviceComboBox->setEditableText (false); - midiInputAuxDeviceComboBox->setJustificationType (Justification::centredLeft); - midiInputAuxDeviceComboBox->setTextWhenNothingSelected (String::empty); - midiInputAuxDeviceComboBox->setTextWhenNoChoicesAvailable ("(no choices)"); - midiInputAuxDeviceComboBox->addListener (this); - - addAndMakeVisible (label5 = new Label ("new label", - "Aux:")); - label5->setFont (Font (15.00f, Font::plain)); - label5->setJustificationType (Justification::centredRight); - label5->setEditable (false, false, false); - label5->setColour (TextEditor::textColourId, Colours::black); - label5->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); - - - //[UserPreSize] - lastSelectedMidiInputID_ = -1; - lastSelectedMidiAuxInputID_ = -1; - lastSegmentUniqueIdentifier_ = -1; - - // Add octave labels to combo box - for(int i = 0; i <= kTouchkeysMaxOctave; i++) { - touchkeyOctaveComboBox->addItem("C" + String(i), i + kTouchkeysComponentComboBoxOffset); - } - //[/UserPreSize] - - setSize (872, 444); - - - //[Constructor] You can add your own custom stuff here.. - oscHostTextEditor->addListener(this); - oscPortTextEditor->addListener(this); - oscInputPortTextEditor->addListener(this); - //[/Constructor] -} - -ControlWindowMainComponent::~ControlWindowMainComponent() -{ - //[Destructor_pre]. You can add your own custom destruction code here.. - //[/Destructor_pre] - - midiInputGroupComponent = nullptr; - midiInputDeviceComboBox = nullptr; - label = nullptr; - groupComponent = nullptr; - label2 = nullptr; - touchkeyDeviceComboBox = nullptr; - label3 = nullptr; - touchkeyStartButton = nullptr; - touchkeyStatusLabel = nullptr; - oscGroupComponent = nullptr; - label7 = nullptr; - oscHostTextEditor = nullptr; - label8 = nullptr; - oscPortTextEditor = nullptr; - oscEnableButton = nullptr; - oscEnableRawButton = nullptr; - label4 = nullptr; - touchkeyOctaveComboBox = nullptr; - oscInputGroupComponent = nullptr; - oscInputEnableButton = nullptr; - label6 = nullptr; - oscInputPortTextEditor = nullptr; - keyboardZoneTabbedComponent = nullptr; - addZoneButton = nullptr; - removeZoneButton = nullptr; - touchkeyAutodetectButton = nullptr; - midiInputAuxDeviceComboBox = nullptr; - label5 = nullptr; - - - //[Destructor]. You can add your own custom destruction code here.. - //[/Destructor] -} - -//============================================================================== -void ControlWindowMainComponent::paint (Graphics& g) -{ - //[UserPrePaint] Add your own custom painting code here.. - //[/UserPrePaint] - - g.fillAll (Colour (0xffd2d2d2)); - - //[UserPaint] Add your own custom painting code here.. - //[/UserPaint] -} - -void ControlWindowMainComponent::resized() -{ - midiInputGroupComponent->setBounds (8, 144, 304, 96); - midiInputDeviceComboBox->setBounds (80, 168, 216, 24); - label->setBounds (16, 168, 64, 24); - groupComponent->setBounds (8, 8, 304, 128); - label2->setBounds (16, 32, 60, 24); - touchkeyDeviceComboBox->setBounds (72, 32, 224, 24); - label3->setBounds (16, 96, 60, 24); - touchkeyStartButton->setBounds (216, 96, 79, 24); - touchkeyStatusLabel->setBounds (72, 96, 136, 24); - oscGroupComponent->setBounds (8, 320, 304, 96); - label7->setBounds (16, 376, 55, 24); - oscHostTextEditor->setBounds (64, 376, 128, 24); - label8->setBounds (200, 376, 40, 24); - oscPortTextEditor->setBounds (240, 376, 56, 24); - oscEnableButton->setBounds (24, 344, 144, 24); - oscEnableRawButton->setBounds (176, 344, 144, 24); - label4->setBounds (16, 64, 104, 24); - touchkeyOctaveComboBox->setBounds (120, 64, 88, 24); - oscInputGroupComponent->setBounds (8, 248, 304, 64); - oscInputEnableButton->setBounds (24, 272, 152, 24); - label6->setBounds (200, 272, 40, 24); - oscInputPortTextEditor->setBounds (240, 272, 56, 24); - keyboardZoneTabbedComponent->setBounds (320, 0, 552, 464); - addZoneButton->setBounds (776, 4, 38, 20); - removeZoneButton->setBounds (824, 4, 38, 20); - touchkeyAutodetectButton->setBounds (216, 64, 79, 24); - midiInputAuxDeviceComboBox->setBounds (80, 200, 216, 24); - label5->setBounds (24, 200, 55, 24); - //[UserResized] Add your own custom resize handling here.. - - // Resize KeyboardZoneComponent to fit new bounds - juce::Rectangle<int> const& ourBounds = getBounds(); - juce::Rectangle<int> keyboardZoneBounds = keyboardZoneTabbedComponent->getBounds(); - keyboardZoneBounds.setHeight(ourBounds.getHeight() - keyboardZoneBounds.getY()); - keyboardZoneTabbedComponent->setBounds(keyboardZoneBounds); - //[/UserResized] -} - -void ControlWindowMainComponent::comboBoxChanged (ComboBox* comboBoxThatHasChanged) -{ - //[UsercomboBoxChanged_Pre] - if(controller_ == 0) - return; - //[/UsercomboBoxChanged_Pre] - - if (comboBoxThatHasChanged == midiInputDeviceComboBox) - { - //[UserComboBoxCode_midiInputDeviceComboBox] -- add your combo box handling code here.. - - // Look up the selected ID, remembering that Juce indices start at 1 and the first of - // these is "Disabled" - int selection = midiInputDeviceComboBox->getSelectedId() - kMidiInputDeviceComboBoxOffset; - if(selection == 1 - kMidiInputDeviceComboBoxOffset) { // Disabled - if(controller_->midiTouchkeysStandaloneModeIsEnabled()) - controller_->midiTouchkeysStandaloneModeDisable(); - controller_->disablePrimaryMIDIInputPort(); - } - else if(selection == 2 - kMidiInputDeviceComboBoxOffset) { // Standalone mode - controller_->disablePrimaryMIDIInputPort(); - controller_->midiTouchkeysStandaloneModeEnable(); - } - else if(selection >= 0 && selection < midiInputDeviceIDs_.size()) { - int deviceId = midiInputDeviceIDs_[selection]; - if(controller_->midiTouchkeysStandaloneModeIsEnabled()) - controller_->midiTouchkeysStandaloneModeDisable(); - controller_->enableMIDIInputPort(deviceId, true); - } - //[/UserComboBoxCode_midiInputDeviceComboBox] - } - else if (comboBoxThatHasChanged == touchkeyDeviceComboBox) - { - //[UserComboBoxCode_touchkeyDeviceComboBox] -- add your combo box handling code here.. - // Nothing to do here right away -- wait until start button is pressed - //[/UserComboBoxCode_touchkeyDeviceComboBox] - } - else if (comboBoxThatHasChanged == touchkeyOctaveComboBox) - { - //[UserComboBoxCode_touchkeyOctaveComboBox] -- add your combo box handling code here.. - int octave = touchkeyOctaveComboBox->getSelectedId() - kTouchkeysComponentComboBoxOffset; - - // Convert octave number to MIDI note (C4 = 60) - if(controller_ != 0) - controller_->touchkeyDeviceSetLowestMidiNote((octave + 1)*12); - //[/UserComboBoxCode_touchkeyOctaveComboBox] - } - else if (comboBoxThatHasChanged == midiInputAuxDeviceComboBox) - { - //[UserComboBoxCode_midiInputAuxDeviceComboBox] -- add your combo box handling code here.. - - // Look up the selected ID, remembering that Juce indices start at 1 and the first of - // these is "Disabled" - int selection = midiInputAuxDeviceComboBox->getSelectedId() - kMidiInputDeviceComboBoxOffset; - if(selection == 1 - kMidiInputDeviceComboBoxOffset) { // Disabled - // Disable all aux ports - controller_->disableAllMIDIInputPorts(true); - } - else if(selection == 2 - kMidiInputDeviceComboBoxOffset) { - // Shouldn't happen; standalone mode not an aux feature - controller_->disableAllMIDIInputPorts(true); - } - else if(selection >= 0 && selection < midiInputDeviceIDs_.size()) { - int deviceId = midiInputDeviceIDs_[selection]; - // Enable this aux port - controller_->disableAllMIDIInputPorts(true); - controller_->enableMIDIInputPort(deviceId, false); - } - //[/UserComboBoxCode_midiInputAuxDeviceComboBox] - } - - //[UsercomboBoxChanged_Post] - //[/UsercomboBoxChanged_Post] -} - -void ControlWindowMainComponent::buttonClicked (Button* buttonThatWasClicked) -{ - //[UserbuttonClicked_Pre] - if(controller_ == 0) - return; - //[/UserbuttonClicked_Pre] - - if (buttonThatWasClicked == touchkeyStartButton) - { - //[UserButtonCode_touchkeyStartButton] -- add your button handler code here.. -#ifdef ENABLE_TOUCHKEYS_SENSOR_TEST - if(controller_->touchkeySensorTestIsRunning()) { - // TouchKeys were performing a sensor test. Stop the test. - controller_->touchkeySensorTestStop(); - } - else if(controller_->touchkeyDeviceIsRunning()) { -#else - if(controller_->touchkeyDeviceIsRunning()) { -#endif - // TouchKeys were running. Stop and close. - controller_->closeTouchkeyDevice(); - } - else { - // TouchKeys weren't running. Open and start. - String devName = controller_->touchkeyDevicePrefix().c_str(); - devName += touchkeyDeviceComboBox->getText(); - - // This will attempt to start the device and update the state accordingly - controller_->touchkeyDeviceStartupSequence(devName.toUTF8()); - } - //[/UserButtonCode_touchkeyStartButton] - } - else if (buttonThatWasClicked == oscEnableButton) - { - //[UserButtonCode_oscEnableButton] -- add your button handler code here.. - controller_->oscTransmitSetEnabled(oscEnableButton->getToggleState()); - //[/UserButtonCode_oscEnableButton] - } - else if (buttonThatWasClicked == oscEnableRawButton) - { - //[UserButtonCode_oscEnableRawButton] -- add your button handler code here.. - controller_->oscTransmitSetRawDataEnabled(oscEnableRawButton->getToggleState()); - //[/UserButtonCode_oscEnableRawButton] - } - else if (buttonThatWasClicked == oscInputEnableButton) - { - //[UserButtonCode_oscInputEnableButton] -- add your button handler code here.. - controller_->oscReceiveSetEnabled(oscInputEnableButton->getToggleState()); - //[/UserButtonCode_oscInputEnableButton] - } - else if (buttonThatWasClicked == addZoneButton) - { - //[UserButtonCode_addZoneButton] -- add your button handler code here.. - controller_->midiSegmentAdd(); - //[/UserButtonCode_addZoneButton] - } - else if (buttonThatWasClicked == removeZoneButton) - { - //[UserButtonCode_removeZoneButton] -- add your button handler code here.. - int tabIndex = keyboardZoneTabbedComponent->getCurrentTabIndex(); - if(tabIndex != 0) { - KeyboardZoneComponent* selectedComponent = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(tabIndex)); - controller_->midiSegmentRemove(selectedComponent->keyboardSegment()); - } - //[/UserButtonCode_removeZoneButton] - } - else if (buttonThatWasClicked == touchkeyAutodetectButton) - { - //[UserButtonCode_touchkeyAutodetectButton] -- add your button handler code here.. - if(controller_->touchkeyDeviceIsAutodetecting()) - controller_->touchkeyDeviceStopAutodetecting(); - else - controller_->touchkeyDeviceAutodetectLowestMidiNote(); - //[/UserButtonCode_touchkeyAutodetectButton] - } - - //[UserbuttonClicked_Post] - //[/UserbuttonClicked_Post] -} - - - -//[MiscUserCode] You can add your own definitions of your custom methods or any other code here... - -void ControlWindowMainComponent::textEditorReturnKeyPressed(TextEditor &editor) -{ - if(controller_ == 0) - return; - if(&editor == oscHostTextEditor || &editor == oscPortTextEditor) - updateOscHostPort(); - else if(&editor == oscInputPortTextEditor) { - int port = atoi(oscInputPortTextEditor->getText().toUTF8()); - controller_->oscReceiveSetPort(port); - } -} - -void ControlWindowMainComponent::textEditorEscapeKeyPressed(TextEditor &editor) -{ - // Nothing to do here -} - -void ControlWindowMainComponent::textEditorFocusLost(TextEditor &editor) -{ - textEditorReturnKeyPressed(editor); -} - -// Update list of TouchKeys and MIDI input devices -void ControlWindowMainComponent::updateInputDeviceList() -{ - if(controller_ == 0) - return; - - // *** TouchKeys devices *** - vector<string> tkdevices = controller_->availableTouchkeyDevices(); - vector<string>::iterator tkit; - int counter; - - touchkeyDeviceComboBox->clear(); - - if(tkdevices.size() == 0) { - touchkeyDeviceComboBox->addItem("No devices", 1); - touchkeyDeviceComboBox->setSelectedId(1, dontSendNotification); - touchkeyDeviceComboBox->setEnabled(false); - touchkeyStartButton->setEnabled(false); - } - else { - counter = 1; - for(tkit = tkdevices.begin(); tkit != tkdevices.end(); ++tkit) { - touchkeyDeviceComboBox->addItem(tkit->c_str(), counter++); - } - touchkeyDeviceComboBox->setSelectedId(1, dontSendNotification); - touchkeyDeviceComboBox->setEnabled(true); - touchkeyStartButton->setEnabled(true); - } - - // *** MIDI input devices *** - vector<pair<int, string> > devices = controller_->availableMIDIInputDevices(); - vector<pair<int, string> >::iterator it; - - midiInputDeviceComboBox->clear(); - midiInputDeviceIDs_.clear(); - midiInputDeviceComboBox->addItem("Disabled", 1); - midiInputDeviceComboBox->addItem("TouchKeys Standalone", 2); - - midiInputAuxDeviceComboBox->clear(); - midiInputAuxDeviceComboBox->addItem("Disabled", 1); - - counter = kMidiInputDeviceComboBoxOffset; - - // Check whether the currently selected ID still exists while - // we build the list - bool lastSelectedDeviceExists = false; - bool lastSelectedAuxDeviceExists = false; - for(it = devices.begin(); it != devices.end(); ++it) { - midiInputDeviceComboBox->addItem((*it).second.c_str(), counter); - midiInputAuxDeviceComboBox->addItem((*it).second.c_str(), counter); - midiInputDeviceIDs_.push_back(it->first); - if(it->first == lastSelectedMidiInputID_) - lastSelectedDeviceExists = true; - if(it->first == lastSelectedMidiAuxInputID_) - lastSelectedAuxDeviceExists = true; - counter++; - } - - if(!lastSelectedDeviceExists && lastSelectedMidiInputID_ >= 0) - controller_->disablePrimaryMIDIInputPort(); - if(!lastSelectedAuxDeviceExists && lastSelectedMidiAuxInputID_ >= 0) - controller_->disableAllMIDIInputPorts(true); -} - -void ControlWindowMainComponent::updateOscHostPort() -{ - if(controller_ == 0) - return; - - String oscHost = oscHostTextEditor->getText(); - String oscPort = oscPortTextEditor->getText(); - controller_->oscTransmitClearAddresses(); - controller_->oscTransmitAddAddress(oscHost.toUTF8(), oscPort.toUTF8()); -} - -// Synchronize the UI state with the underlying state of the controller -void ControlWindowMainComponent::synchronize() { - if(controller_ == 0) - return; - - bool devicesUpdated = false; - - if(controller_->devicesShouldUpdate() != lastControllerUpdateDeviceCount_) { - lastControllerUpdateDeviceCount_ = controller_->devicesShouldUpdate(); - updateInputDeviceList(); - devicesUpdated = true; - } - - // Update TouchKeys status -#ifdef ENABLE_TOUCHKEYS_SENSOR_TEST - if(controller_->touchkeySensorTestIsRunning()) { - touchkeyStartButton->setButtonText("Stop"); - touchkeyStatusLabel->setText("Testing", dontSendNotification); - } - else if(controller_->touchkeyDeviceIsRunning()) { -#else - if(controller_->touchkeyDeviceIsRunning()) { -#endif - touchkeyStartButton->setButtonText("Stop"); - touchkeyStatusLabel->setText("Running", dontSendNotification); - } - else if(controller_->touchkeyDeviceErrorOccurred()) { - touchkeyStartButton->setButtonText("Start"); - touchkeyStatusLabel->setText(controller_->touchkeyDeviceErrorMessage().c_str(), dontSendNotification); - } - else { - touchkeyStartButton->setButtonText("Start"); - touchkeyStatusLabel->setText("Not running", dontSendNotification); - } - - // Update MIDI input status - if(controller_->midiTouchkeysStandaloneModeIsEnabled()) { - midiInputDeviceComboBox->setSelectedId(2, dontSendNotification); - } - else { - // First query the primary port - int selectedPrimaryPort = controller_->selectedMIDIPrimaryInputPort(); - if(selectedPrimaryPort < 0) { - midiInputDeviceComboBox->setSelectedId(1, dontSendNotification); - } - else if(selectedPrimaryPort != lastSelectedMidiInputID_ || devicesUpdated){ - // Input has changed from before. Find it in vector - // If there is more than one selected ID, we will only take the first one for - // the current UI. This affects the display but not the functionality. - for(int i = 0; i < midiInputDeviceIDs_.size(); i++) { - if(midiInputDeviceIDs_[i] == selectedPrimaryPort) { - midiInputDeviceComboBox->setSelectedId(i + kMidiInputDeviceComboBoxOffset, dontSendNotification); - break; - } - } - // ...and cache this as the last ID so we don't search again next time - lastSelectedMidiInputID_ = selectedPrimaryPort; - - // Now disable this item in the auxiliary combo box - for(int i = 0; i < midiInputAuxDeviceComboBox->getNumItems(); i++) { - int itemId = midiInputAuxDeviceComboBox->getItemId(i) - kMidiInputDeviceComboBoxOffset; - if(itemId >= 0) { - midiInputAuxDeviceComboBox->setItemEnabled(midiInputAuxDeviceComboBox->getItemId(i), - (itemId != selectedPrimaryPort)); - } - } - } - } - - // Then get all aux ports and display the first one - const std::vector<int>& selectedMidiInputDevices(controller_->selectedMIDIAuxInputPorts()); - if(selectedMidiInputDevices.empty()) { - midiInputAuxDeviceComboBox->setSelectedId(1, dontSendNotification); - } - else if(selectedMidiInputDevices.front() != lastSelectedMidiAuxInputID_ || devicesUpdated){ - // Input has changed from before. Find it in vector - // If there is more than one selected ID, we will only take the first one for - // the current UI. This affects the display but not the functionality. - for(int i = 0; i < midiInputDeviceIDs_.size(); i++) { - if(midiInputDeviceIDs_[i] == selectedMidiInputDevices.front()) { - midiInputAuxDeviceComboBox->setSelectedId(i + kMidiInputDeviceComboBoxOffset, dontSendNotification); - break; - } - } - // ...and cache this as the last ID so we don't search again next time - lastSelectedMidiAuxInputID_ = selectedMidiInputDevices.front(); - } - - // Update OSC status - oscEnableButton->setToggleState(controller_->oscTransmitEnabled(), dontSendNotification); - oscEnableRawButton->setToggleState(controller_->oscTransmitRawDataEnabled(), dontSendNotification); - oscInputEnableButton->setToggleState(controller_->oscReceiveEnabled(), dontSendNotification); - - // Update the OSC fields only if the text editors aren't active - if(!oscHostTextEditor->hasKeyboardFocus(true) && !oscPortTextEditor->hasKeyboardFocus(true)) { - const std::vector<lo_address>& oscAddresses = controller_->oscTransmitAddresses(); - if(oscAddresses.empty()) { - oscHostTextEditor->setText("", false); - oscPortTextEditor->setText("", false); - } - else { - // Take the first address to display in the text editor. As with MIDI input, - // this doesn't affect the functionality, only the UI display. - lo_address firstAddress = oscAddresses.front(); - - oscHostTextEditor->setText(lo_address_get_hostname(firstAddress), false); - oscPortTextEditor->setText(lo_address_get_port(firstAddress), false); - } - } - if(!oscInputPortTextEditor->hasKeyboardFocus(true)) { - int port = controller_->oscReceivePort(); - oscInputPortTextEditor->setText(String(port), false); - } - - // Set the octave button - int octave = (controller_->touchkeyDeviceLowestMidiNote() / 12) - 1; - if(octave >= 0 && octave <= kTouchkeysMaxOctave) - touchkeyOctaveComboBox->setSelectedId(octave + kTouchkeysComponentComboBoxOffset, dontSendNotification); - - // Enable or disable the autodetect button depending on the device status - if(!controller_->touchkeyDeviceIsRunning()) { - touchkeyAutodetectButton->setEnabled(false); - } - else if(controller_->touchkeyDeviceIsAutodetecting()) { - touchkeyAutodetectButton->setEnabled(true); - touchkeyAutodetectButton->setButtonText("Cancel"); - } - else { - touchkeyAutodetectButton->setEnabled(true); - touchkeyAutodetectButton->setButtonText("Detect"); - } - - // Update segments list if it has changed - if(lastSegmentUniqueIdentifier_ != controller_->midiSegmentUniqueIdentifier()) - updateKeyboardSegments(); - - // Synchronize every tab component - for(int tab = 0; tab < keyboardZoneTabbedComponent->getNumTabs(); tab++) { - KeyboardZoneComponent *component = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(tab)); - component->synchronize(devicesUpdated); - } - - // Update add/remove buttons - if(keyboardZoneTabbedComponent->getCurrentTabIndex() <= 0) { - removeZoneButton->setEnabled(false); - } - else { - removeZoneButton->setEnabled(true); - } - if(controller_->midiSegmentsCount() >= 8) - addZoneButton->setEnabled(false); - else - addZoneButton->setEnabled(true); -} - -// Return the currently selected TouchKeys string -String ControlWindowMainComponent::currentTouchkeysSelectedPath() -{ - String devName = controller_->touchkeyDevicePrefix().c_str(); - devName += touchkeyDeviceComboBox->getText(); - - return devName; -} - -// Update the state of the keyboard segment tab bar. Called only when segments change -void ControlWindowMainComponent::updateKeyboardSegments() -{ - if(controller_ == 0) - return; - // Update the identifier to say we've matched the current state of the segments - lastSegmentUniqueIdentifier_ = controller_->midiSegmentUniqueIdentifier(); - - // Save the current selected index in case we later remove it - int currentlySelectedIndex = keyboardZoneTabbedComponent->getCurrentTabIndex(); - - KeyboardZoneComponent* currentlySelectedComponent = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(currentlySelectedIndex)); - MidiKeyboardSegment* currentlySelectedSegment = 0; - if(currentlySelectedComponent != 0) - currentlySelectedSegment = currentlySelectedComponent->keyboardSegment(); - bool selectedNewTab = false; - - // First, go through the segments and create tabs as needed - int maxNumSegments = controller_->midiSegmentsCount(); - for(int i = 0; i < maxNumSegments; i++) { - MidiKeyboardSegment* segment = controller_->midiSegment(i); - bool matched = false; - if(segment == 0) - continue; - // Look for this segment among the tabs we already have - for(int tab = 0; tab < keyboardZoneTabbedComponent->getNumTabs(); tab++) { - KeyboardZoneComponent *component = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(tab)); - if(component->keyboardSegment() == segment && component->keyboardZone() == segment->outputPort()) { - // Found it... - matched = true; - break; - } - } - // If we didn't find it, add a tab for this segment - if(!matched) { - KeyboardZoneComponent *newComponent = new KeyboardZoneComponent(); - newComponent->setMainApplicationController(controller_); - newComponent->setKeyboardSegment(segment, segment->outputPort()); - - char name[16]; -#ifdef _MSC_VER - _snprintf_s(name, 16, _TRUNCATE, "Zone %d", segment->outputPort()); -#else - snprintf(name, 16, "Zone %d", segment->outputPort()); -#endif - - // Add the component, telling the tab manager to take charge of deleting it at the end - keyboardZoneTabbedComponent->addTab(name, Colours::lightgrey, newComponent, true); - keyboardZoneTabbedComponent->setCurrentTabIndex(keyboardZoneTabbedComponent->getNumTabs() - 1); - selectedNewTab = true; - - //std::cout << "Adding tab for segment " << segment << endl; - } - } - - // Now go through the other way and remove tabs that are no longer needed - // Iterate through each tab: find a match in the segments - int tab = 0; - while(tab < keyboardZoneTabbedComponent->getNumTabs()) { - KeyboardZoneComponent *component = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(tab)); - MidiKeyboardSegment *segment = component->keyboardSegment(); - bool matched = false; - - for(int i = 0; i < maxNumSegments; i++) { - if(segment == controller_->midiSegment(i) && component->keyboardZone() == segment->outputPort()) { - matched = true; - break; - } - } - if(segment == 0 || !matched) { - // This tab holds a nonexistent segment and should be removed - keyboardZoneTabbedComponent->removeTab(tab); - - if(currentlySelectedSegment == segment) { - // The currently selected tab has been removed. Select the prior one. - if(currentlySelectedIndex > 0) { - int indexToSelect = currentlySelectedIndex - 1; - if(indexToSelect >= keyboardZoneTabbedComponent->getNumTabs()) - indexToSelect = keyboardZoneTabbedComponent->getNumTabs() - 1; - if(indexToSelect < 0) - indexToSelect = 0; - keyboardZoneTabbedComponent->setCurrentTabIndex(indexToSelect); - } - else - keyboardZoneTabbedComponent->setCurrentTabIndex(0); - } - - // And we have to start over again since the tab indexing has changed - tab = 0; - } - else // Found a match: check the next tab - tab++; - // Eventually, we get to the end of the list of tabs an we know every existing tab matches a segment - } -} - -//[/MiscUserCode] - - -//============================================================================== -#if 0 -/* -- Introjucer information section -- - - This is where the Introjucer stores the metadata that describe this GUI layout, so - make changes in here at your peril! - -BEGIN_JUCER_METADATA - -<JUCER_COMPONENT documentType="Component" className="ControlWindowMainComponent" - componentName="" parentClasses="public Component, public TextEditor::Listener" - constructorParams="" variableInitialisers="controller_(0)" snapPixels="8" - snapActive="1" snapShown="1" overlayOpacity="0.330" fixedSize="0" - initialWidth="872" initialHeight="444"> - <BACKGROUND backgroundColour="ffd2d2d2"/> - <GROUPCOMPONENT name="MIDI input group" id="ce80a86ee6475cd9" memberName="midiInputGroupComponent" - virtualName="" explicitFocusOrder="0" pos="8 144 304 96" title="MIDI Input"/> - <COMBOBOX name="MIDI input combo box" id="def32c74505cfa50" memberName="midiInputDeviceComboBox" - virtualName="" explicitFocusOrder="0" pos="80 168 216 24" editable="0" - layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> - <LABEL name="new label" id="ad7bc4640d8023b7" memberName="label" virtualName="" - explicitFocusOrder="0" pos="16 168 64 24" edTextCol="ff000000" - edBkgCol="0" labelText="Keyboard:" editableSingleClick="0" editableDoubleClick="0" - focusDiscardsChanges="0" fontname="Default font" fontsize="15" - bold="0" italic="0" justification="33"/> - <GROUPCOMPONENT name="new group" id="9106305fd2211185" memberName="groupComponent" - virtualName="" explicitFocusOrder="0" pos="8 8 304 128" title="TouchKeys"/> - <LABEL name="new label" id="944877a84dcfc602" memberName="label2" virtualName="" - explicitFocusOrder="0" pos="16 32 60 24" edTextCol="ff000000" - edBkgCol="0" labelText="Device: " editableSingleClick="0" - editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" - fontsize="15" bold="0" italic="0" justification="33"/> - <COMBOBOX name="TouchKeys combo box" id="871223bdcad0e693" memberName="touchkeyDeviceComboBox" - virtualName="" explicitFocusOrder="0" pos="72 32 224 24" editable="0" - layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> - <LABEL name="new label" id="1cdf89082d95c72c" memberName="label3" virtualName="" - explicitFocusOrder="0" pos="16 96 60 24" edTextCol="ff000000" - edBkgCol="0" labelText="Status: " editableSingleClick="0" - editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" - fontsize="15" bold="0" italic="0" justification="33"/> - <TEXTBUTTON name="TouchKeys start button" id="1bb1c69c957fc984" memberName="touchkeyStartButton" - virtualName="" explicitFocusOrder="0" pos="216 96 79 24" buttonText="Start" - connectedEdges="0" needsCallback="1" radioGroupId="0"/> - <LABEL name="TouchKeys status label" id="c91b132696e6ba1d" memberName="touchkeyStatusLabel" - virtualName="" explicitFocusOrder="0" pos="72 96 136 24" edTextCol="ff000000" - edBkgCol="0" labelText="not running" editableSingleClick="0" - editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" - fontsize="15" bold="0" italic="0" justification="33"/> - <GROUPCOMPONENT name="OSC group" id="8268119e22809825" memberName="oscGroupComponent" - virtualName="" explicitFocusOrder="0" pos="8 320 304 96" title="OSC Output"/> - <LABEL name="new label" id="896c0c48a1cf50a" memberName="label7" virtualName="" - explicitFocusOrder="0" pos="16 376 55 24" edTextCol="ff000000" - edBkgCol="0" labelText="Host:" editableSingleClick="0" editableDoubleClick="0" - focusDiscardsChanges="0" fontname="Default font" fontsize="15" - bold="0" italic="0" justification="33"/> - <TEXTEDITOR name="new text editor" id="84778d0bbebedd36" memberName="oscHostTextEditor" - virtualName="" explicitFocusOrder="0" pos="64 376 128 24" initialText="127.0.0.1" - multiline="0" retKeyStartsLine="0" readonly="0" scrollbars="1" - caret="1" popupmenu="1"/> - <LABEL name="new label" id="157c85bf83a7f936" memberName="label8" virtualName="" - explicitFocusOrder="0" pos="200 376 40 24" edTextCol="ff000000" - edBkgCol="0" labelText="Port:" editableSingleClick="0" editableDoubleClick="0" - focusDiscardsChanges="0" fontname="Default font" fontsize="15" - bold="0" italic="0" justification="33"/> - <TEXTEDITOR name="new text editor" id="7c21f0c238812d11" memberName="oscPortTextEditor" - virtualName="" explicitFocusOrder="0" pos="240 376 56 24" initialText="8000" - multiline="0" retKeyStartsLine="0" readonly="0" scrollbars="1" - caret="1" popupmenu="1"/> - <TOGGLEBUTTON name="OSC enable button" id="ccd52591cfd0b632" memberName="oscEnableButton" - virtualName="" explicitFocusOrder="0" pos="24 344 144 24" buttonText="Enable OSC output" - connectedEdges="0" needsCallback="1" radioGroupId="0" state="0"/> - <TOGGLEBUTTON name="OSC enable raw button" id="4aaf8f80edaff24" memberName="oscEnableRawButton" - virtualName="" explicitFocusOrder="0" pos="176 344 144 24" buttonText="Send raw frames" - connectedEdges="0" needsCallback="1" radioGroupId="0" state="0"/> - <LABEL name="new label" id="c5873c6498f8156d" memberName="label4" virtualName="" - explicitFocusOrder="0" pos="16 64 104 24" edTextCol="ff000000" - edBkgCol="0" labelText="Lowest Octave:" editableSingleClick="0" - editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" - fontsize="15" bold="0" italic="0" justification="33"/> - <COMBOBOX name="TouchKeys octave box" id="36ace32027c81d30" memberName="touchkeyOctaveComboBox" - virtualName="" explicitFocusOrder="0" pos="120 64 88 24" editable="0" - layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> - <GROUPCOMPONENT name="MIDI input group" id="bb54712f78382055" memberName="oscInputGroupComponent" - virtualName="" explicitFocusOrder="0" pos="8 248 304 64" title="OSC Input"/> - <TOGGLEBUTTON name="OSC input enable button" id="22a196770a440560" memberName="oscInputEnableButton" - virtualName="" explicitFocusOrder="0" pos="24 272 152 24" buttonText="Enable OSC input" - connectedEdges="0" needsCallback="1" radioGroupId="0" state="0"/> - <LABEL name="new label" id="c680c2da87cdcbf2" memberName="label6" virtualName="" - explicitFocusOrder="0" pos="200 272 40 24" edTextCol="ff000000" - edBkgCol="0" labelText="Port:" editableSingleClick="0" editableDoubleClick="0" - focusDiscardsChanges="0" fontname="Default font" fontsize="15" - bold="0" italic="0" justification="33"/> - <TEXTEDITOR name="new text editor" id="d4a91e8bff5b6bc9" memberName="oscInputPortTextEditor" - virtualName="" explicitFocusOrder="0" pos="240 272 56 24" initialText="8001" - multiline="0" retKeyStartsLine="0" readonly="0" scrollbars="1" - caret="1" popupmenu="1"/> - <TABBEDCOMPONENT name="keyboard zone tabbed component" id="33da3d6583cdacbf" memberName="keyboardZoneTabbedComponent" - virtualName="" explicitFocusOrder="0" pos="320 0 552 464" orientation="top" - tabBarDepth="30" initialTab="-1"/> - <TEXTBUTTON name="add zone button" id="1d2fa7fd74f31315" memberName="addZoneButton" - virtualName="" explicitFocusOrder="0" pos="776 4 38 20" buttonText="Add" - connectedEdges="0" needsCallback="1" radioGroupId="0"/> - <TEXTBUTTON name="remove zone button" id="7865f7787a191e0e" memberName="removeZoneButton" - virtualName="" explicitFocusOrder="0" pos="824 4 38 20" buttonText="Del" - connectedEdges="0" needsCallback="1" radioGroupId="0"/> - <TEXTBUTTON name="TouchKeys autodetect button" id="6e19894bc11d0276" memberName="touchkeyAutodetectButton" - virtualName="" explicitFocusOrder="0" pos="216 64 79 24" buttonText="Detect" - connectedEdges="0" needsCallback="1" radioGroupId="0"/> - <COMBOBOX name="MIDI input aux combo box" id="1b77c934a4790942" memberName="midiInputAuxDeviceComboBox" - virtualName="" explicitFocusOrder="0" pos="80 200 216 24" editable="0" - layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> - <LABEL name="new label" id="7409cb92cfa3b9f2" memberName="label5" virtualName="" - explicitFocusOrder="0" pos="24 200 55 24" edTextCol="ff000000" - edBkgCol="0" labelText="Aux:" editableSingleClick="0" editableDoubleClick="0" - focusDiscardsChanges="0" fontname="Default font" fontsize="15" - bold="0" italic="0" justification="34"/> -</JUCER_COMPONENT> - -END_JUCER_METADATA -*/ -#endif - - -//[EndFile] You can add extra defines here... -#endif // TOUCHKEYS_NO_GUI -//[/EndFile] +/* + ============================================================================== + + This is an automatically generated GUI class created by the Introjucer! + + Be careful when adding custom code to these files, as only the code within + the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded + and re-saved. + + Created with Introjucer version: 3.1.0 + + ------------------------------------------------------------------------------ + + The Introjucer is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-13 by Raw Material Software Ltd. + + ============================================================================== +*/ + + +//[Headers] You can add your own extra header files here... +#ifndef TOUCHKEYS_NO_GUI +#include "KeyboardZoneComponent.h" +//[/Headers] + +#include "ControlWindowMainComponent.h" + + +//[MiscUserDefs] You can add your own user definitions and misc code here... +//[/MiscUserDefs] + +//============================================================================== +ControlWindowMainComponent::ControlWindowMainComponent () + : controller_(0) +{ + addAndMakeVisible (midiInputGroupComponent = new GroupComponent ("MIDI input group", + "MIDI Input")); + + addAndMakeVisible (midiInputDeviceComboBox = new ComboBox ("MIDI input combo box")); + midiInputDeviceComboBox->setEditableText (false); + midiInputDeviceComboBox->setJustificationType (Justification::centredLeft); + midiInputDeviceComboBox->setTextWhenNothingSelected (String::empty); + midiInputDeviceComboBox->setTextWhenNoChoicesAvailable ("(no choices)"); + midiInputDeviceComboBox->addListener (this); + + addAndMakeVisible (label = new Label ("new label", + "Keyboard:")); + label->setFont (Font (15.00f, Font::plain)); + label->setJustificationType (Justification::centredLeft); + label->setEditable (false, false, false); + label->setColour (TextEditor::textColourId, Colours::black); + label->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); + + addAndMakeVisible (groupComponent = new GroupComponent ("new group", + "TouchKeys")); + + addAndMakeVisible (label2 = new Label ("new label", + "Device:\n")); + label2->setFont (Font (15.00f, Font::plain)); + label2->setJustificationType (Justification::centredLeft); + label2->setEditable (false, false, false); + label2->setColour (TextEditor::textColourId, Colours::black); + label2->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); + + addAndMakeVisible (touchkeyDeviceComboBox = new ComboBox ("TouchKeys combo box")); + touchkeyDeviceComboBox->setEditableText (false); + touchkeyDeviceComboBox->setJustificationType (Justification::centredLeft); + touchkeyDeviceComboBox->setTextWhenNothingSelected (String::empty); + touchkeyDeviceComboBox->setTextWhenNoChoicesAvailable ("(no choices)"); + touchkeyDeviceComboBox->addListener (this); + + addAndMakeVisible (label3 = new Label ("new label", + "Status:\n")); + label3->setFont (Font (15.00f, Font::plain)); + label3->setJustificationType (Justification::centredLeft); + label3->setEditable (false, false, false); + label3->setColour (TextEditor::textColourId, Colours::black); + label3->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); + + addAndMakeVisible (touchkeyStartButton = new TextButton ("TouchKeys start button")); + touchkeyStartButton->setButtonText ("Start"); + touchkeyStartButton->addListener (this); + + addAndMakeVisible (touchkeyStatusLabel = new Label ("TouchKeys status label", + "not running")); + touchkeyStatusLabel->setFont (Font (15.00f, Font::plain)); + touchkeyStatusLabel->setJustificationType (Justification::centredLeft); + touchkeyStatusLabel->setEditable (false, false, false); + touchkeyStatusLabel->setColour (TextEditor::textColourId, Colours::black); + touchkeyStatusLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); + + addAndMakeVisible (oscGroupComponent = new GroupComponent ("OSC group", + "OSC Output")); + + addAndMakeVisible (label7 = new Label ("new label", + "Host:")); + label7->setFont (Font (15.00f, Font::plain)); + label7->setJustificationType (Justification::centredLeft); + label7->setEditable (false, false, false); + label7->setColour (TextEditor::textColourId, Colours::black); + label7->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); + + addAndMakeVisible (oscHostTextEditor = new TextEditor ("new text editor")); + oscHostTextEditor->setMultiLine (false); + oscHostTextEditor->setReturnKeyStartsNewLine (false); + oscHostTextEditor->setReadOnly (false); + oscHostTextEditor->setScrollbarsShown (true); + oscHostTextEditor->setCaretVisible (true); + oscHostTextEditor->setPopupMenuEnabled (true); + oscHostTextEditor->setText ("127.0.0.1"); + + addAndMakeVisible (label8 = new Label ("new label", + "Port:")); + label8->setFont (Font (15.00f, Font::plain)); + label8->setJustificationType (Justification::centredLeft); + label8->setEditable (false, false, false); + label8->setColour (TextEditor::textColourId, Colours::black); + label8->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); + + addAndMakeVisible (oscPortTextEditor = new TextEditor ("new text editor")); + oscPortTextEditor->setMultiLine (false); + oscPortTextEditor->setReturnKeyStartsNewLine (false); + oscPortTextEditor->setReadOnly (false); + oscPortTextEditor->setScrollbarsShown (true); + oscPortTextEditor->setCaretVisible (true); + oscPortTextEditor->setPopupMenuEnabled (true); + oscPortTextEditor->setText ("8000"); + + addAndMakeVisible (oscEnableButton = new ToggleButton ("OSC enable button")); + oscEnableButton->setButtonText ("Enable OSC output"); + oscEnableButton->addListener (this); + + addAndMakeVisible (oscEnableRawButton = new ToggleButton ("OSC enable raw button")); + oscEnableRawButton->setButtonText ("Send raw frames"); + oscEnableRawButton->addListener (this); + + addAndMakeVisible (label4 = new Label ("new label", + "Lowest Octave:")); + label4->setFont (Font (15.00f, Font::plain)); + label4->setJustificationType (Justification::centredLeft); + label4->setEditable (false, false, false); + label4->setColour (TextEditor::textColourId, Colours::black); + label4->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); + + addAndMakeVisible (touchkeyOctaveComboBox = new ComboBox ("TouchKeys octave box")); + touchkeyOctaveComboBox->setEditableText (false); + touchkeyOctaveComboBox->setJustificationType (Justification::centredLeft); + touchkeyOctaveComboBox->setTextWhenNothingSelected (String::empty); + touchkeyOctaveComboBox->setTextWhenNoChoicesAvailable ("(no choices)"); + touchkeyOctaveComboBox->addListener (this); + + addAndMakeVisible (oscInputGroupComponent = new GroupComponent ("MIDI input group", + "OSC Input")); + + addAndMakeVisible (oscInputEnableButton = new ToggleButton ("OSC input enable button")); + oscInputEnableButton->setButtonText ("Enable OSC input"); + oscInputEnableButton->addListener (this); + + addAndMakeVisible (label6 = new Label ("new label", + "Port:")); + label6->setFont (Font (15.00f, Font::plain)); + label6->setJustificationType (Justification::centredLeft); + label6->setEditable (false, false, false); + label6->setColour (TextEditor::textColourId, Colours::black); + label6->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); + + addAndMakeVisible (oscInputPortTextEditor = new TextEditor ("new text editor")); + oscInputPortTextEditor->setMultiLine (false); + oscInputPortTextEditor->setReturnKeyStartsNewLine (false); + oscInputPortTextEditor->setReadOnly (false); + oscInputPortTextEditor->setScrollbarsShown (true); + oscInputPortTextEditor->setCaretVisible (true); + oscInputPortTextEditor->setPopupMenuEnabled (true); + oscInputPortTextEditor->setText ("8001"); + + addAndMakeVisible (keyboardZoneTabbedComponent = new TabbedComponent (TabbedButtonBar::TabsAtTop)); + keyboardZoneTabbedComponent->setTabBarDepth (30); + keyboardZoneTabbedComponent->setCurrentTabIndex (-1); + + addAndMakeVisible (addZoneButton = new TextButton ("add zone button")); + addZoneButton->setButtonText ("Add"); + addZoneButton->addListener (this); + + addAndMakeVisible (removeZoneButton = new TextButton ("remove zone button")); + removeZoneButton->setButtonText ("Del"); + removeZoneButton->addListener (this); + + addAndMakeVisible (touchkeyAutodetectButton = new TextButton ("TouchKeys autodetect button")); + touchkeyAutodetectButton->setButtonText ("Detect"); + touchkeyAutodetectButton->addListener (this); + + addAndMakeVisible (midiInputAuxDeviceComboBox = new ComboBox ("MIDI input aux combo box")); + midiInputAuxDeviceComboBox->setEditableText (false); + midiInputAuxDeviceComboBox->setJustificationType (Justification::centredLeft); + midiInputAuxDeviceComboBox->setTextWhenNothingSelected (String::empty); + midiInputAuxDeviceComboBox->setTextWhenNoChoicesAvailable ("(no choices)"); + midiInputAuxDeviceComboBox->addListener (this); + + addAndMakeVisible (label5 = new Label ("new label", + "Aux:")); + label5->setFont (Font (15.00f, Font::plain)); + label5->setJustificationType (Justification::centredRight); + label5->setEditable (false, false, false); + label5->setColour (TextEditor::textColourId, Colours::black); + label5->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); + + + //[UserPreSize] + lastSelectedMidiInputID_ = -1; + lastSelectedMidiAuxInputID_ = -1; + lastSegmentUniqueIdentifier_ = -1; + + // Add octave labels to combo box + for(int i = 0; i <= kTouchkeysMaxOctave; i++) { + touchkeyOctaveComboBox->addItem("C" + String(i), i + kTouchkeysComponentComboBoxOffset); + } + //[/UserPreSize] + + setSize (872, 444); + + + //[Constructor] You can add your own custom stuff here.. + oscHostTextEditor->addListener(this); + oscPortTextEditor->addListener(this); + oscInputPortTextEditor->addListener(this); + //[/Constructor] +} + +ControlWindowMainComponent::~ControlWindowMainComponent() +{ + //[Destructor_pre]. You can add your own custom destruction code here.. + //[/Destructor_pre] + + midiInputGroupComponent = nullptr; + midiInputDeviceComboBox = nullptr; + label = nullptr; + groupComponent = nullptr; + label2 = nullptr; + touchkeyDeviceComboBox = nullptr; + label3 = nullptr; + touchkeyStartButton = nullptr; + touchkeyStatusLabel = nullptr; + oscGroupComponent = nullptr; + label7 = nullptr; + oscHostTextEditor = nullptr; + label8 = nullptr; + oscPortTextEditor = nullptr; + oscEnableButton = nullptr; + oscEnableRawButton = nullptr; + label4 = nullptr; + touchkeyOctaveComboBox = nullptr; + oscInputGroupComponent = nullptr; + oscInputEnableButton = nullptr; + label6 = nullptr; + oscInputPortTextEditor = nullptr; + keyboardZoneTabbedComponent = nullptr; + addZoneButton = nullptr; + removeZoneButton = nullptr; + touchkeyAutodetectButton = nullptr; + midiInputAuxDeviceComboBox = nullptr; + label5 = nullptr; + + + //[Destructor]. You can add your own custom destruction code here.. + //[/Destructor] +} + +//============================================================================== +void ControlWindowMainComponent::paint (Graphics& g) +{ + //[UserPrePaint] Add your own custom painting code here.. + //[/UserPrePaint] + + g.fillAll (Colour (0xffd2d2d2)); + + //[UserPaint] Add your own custom painting code here.. + //[/UserPaint] +} + +void ControlWindowMainComponent::resized() +{ + midiInputGroupComponent->setBounds (8, 144, 304, 96); + midiInputDeviceComboBox->setBounds (80, 168, 216, 24); + label->setBounds (16, 168, 64, 24); + groupComponent->setBounds (8, 8, 304, 128); + label2->setBounds (16, 32, 60, 24); + touchkeyDeviceComboBox->setBounds (72, 32, 224, 24); + label3->setBounds (16, 96, 60, 24); + touchkeyStartButton->setBounds (216, 96, 79, 24); + touchkeyStatusLabel->setBounds (72, 96, 136, 24); + oscGroupComponent->setBounds (8, 320, 304, 96); + label7->setBounds (16, 376, 55, 24); + oscHostTextEditor->setBounds (64, 376, 128, 24); + label8->setBounds (200, 376, 40, 24); + oscPortTextEditor->setBounds (240, 376, 56, 24); + oscEnableButton->setBounds (24, 344, 144, 24); + oscEnableRawButton->setBounds (176, 344, 144, 24); + label4->setBounds (16, 64, 104, 24); + touchkeyOctaveComboBox->setBounds (120, 64, 88, 24); + oscInputGroupComponent->setBounds (8, 248, 304, 64); + oscInputEnableButton->setBounds (24, 272, 152, 24); + label6->setBounds (200, 272, 40, 24); + oscInputPortTextEditor->setBounds (240, 272, 56, 24); + keyboardZoneTabbedComponent->setBounds (320, 0, 552, 464); + addZoneButton->setBounds (776, 4, 38, 20); + removeZoneButton->setBounds (824, 4, 38, 20); + touchkeyAutodetectButton->setBounds (216, 64, 79, 24); + midiInputAuxDeviceComboBox->setBounds (80, 200, 216, 24); + label5->setBounds (24, 200, 55, 24); + //[UserResized] Add your own custom resize handling here.. + + // Resize KeyboardZoneComponent to fit new bounds + juce::Rectangle<int> const& ourBounds = getBounds(); + juce::Rectangle<int> keyboardZoneBounds = keyboardZoneTabbedComponent->getBounds(); + keyboardZoneBounds.setHeight(ourBounds.getHeight() - keyboardZoneBounds.getY()); + keyboardZoneTabbedComponent->setBounds(keyboardZoneBounds); + //[/UserResized] +} + +void ControlWindowMainComponent::comboBoxChanged (ComboBox* comboBoxThatHasChanged) +{ + //[UsercomboBoxChanged_Pre] + if(controller_ == 0) + return; + //[/UsercomboBoxChanged_Pre] + + if (comboBoxThatHasChanged == midiInputDeviceComboBox) + { + //[UserComboBoxCode_midiInputDeviceComboBox] -- add your combo box handling code here.. + + // Look up the selected ID, remembering that Juce indices start at 1 and the first of + // these is "Disabled" + int selection = midiInputDeviceComboBox->getSelectedId() - kMidiInputDeviceComboBoxOffset; + if(selection == 1 - kMidiInputDeviceComboBoxOffset) { // Disabled + if(controller_->midiTouchkeysStandaloneModeIsEnabled()) + controller_->midiTouchkeysStandaloneModeDisable(); + controller_->disablePrimaryMIDIInputPort(); + } + else if(selection == 2 - kMidiInputDeviceComboBoxOffset) { // Standalone mode + controller_->disablePrimaryMIDIInputPort(); + controller_->midiTouchkeysStandaloneModeEnable(); + } + else if(selection >= 0 && selection < midiInputDeviceIDs_.size()) { + int deviceId = midiInputDeviceIDs_[selection]; + if(controller_->midiTouchkeysStandaloneModeIsEnabled()) + controller_->midiTouchkeysStandaloneModeDisable(); + controller_->enableMIDIInputPort(deviceId, true); + } + //[/UserComboBoxCode_midiInputDeviceComboBox] + } + else if (comboBoxThatHasChanged == touchkeyDeviceComboBox) + { + //[UserComboBoxCode_touchkeyDeviceComboBox] -- add your combo box handling code here.. + // Nothing to do here right away -- wait until start button is pressed + //[/UserComboBoxCode_touchkeyDeviceComboBox] + } + else if (comboBoxThatHasChanged == touchkeyOctaveComboBox) + { + //[UserComboBoxCode_touchkeyOctaveComboBox] -- add your combo box handling code here.. + int octave = touchkeyOctaveComboBox->getSelectedId() - kTouchkeysComponentComboBoxOffset; + + // Convert octave number to MIDI note (C4 = 60) + if(controller_ != 0) + controller_->touchkeyDeviceSetLowestMidiNote((octave + 1)*12); + //[/UserComboBoxCode_touchkeyOctaveComboBox] + } + else if (comboBoxThatHasChanged == midiInputAuxDeviceComboBox) + { + //[UserComboBoxCode_midiInputAuxDeviceComboBox] -- add your combo box handling code here.. + + // Look up the selected ID, remembering that Juce indices start at 1 and the first of + // these is "Disabled" + int selection = midiInputAuxDeviceComboBox->getSelectedId() - kMidiInputDeviceComboBoxOffset; + if(selection == 1 - kMidiInputDeviceComboBoxOffset) { // Disabled + // Disable all aux ports + controller_->disableAllMIDIInputPorts(true); + } + else if(selection == 2 - kMidiInputDeviceComboBoxOffset) { + // Shouldn't happen; standalone mode not an aux feature + controller_->disableAllMIDIInputPorts(true); + } + else if(selection >= 0 && selection < midiInputDeviceIDs_.size()) { + int deviceId = midiInputDeviceIDs_[selection]; + // Enable this aux port + controller_->disableAllMIDIInputPorts(true); + controller_->enableMIDIInputPort(deviceId, false); + } + //[/UserComboBoxCode_midiInputAuxDeviceComboBox] + } + + //[UsercomboBoxChanged_Post] + //[/UsercomboBoxChanged_Post] +} + +void ControlWindowMainComponent::buttonClicked (Button* buttonThatWasClicked) +{ + //[UserbuttonClicked_Pre] + if(controller_ == 0) + return; + //[/UserbuttonClicked_Pre] + + if (buttonThatWasClicked == touchkeyStartButton) + { + //[UserButtonCode_touchkeyStartButton] -- add your button handler code here.. +#ifdef ENABLE_TOUCHKEYS_SENSOR_TEST + if(controller_->touchkeySensorTestIsRunning()) { + // TouchKeys were performing a sensor test. Stop the test. + controller_->touchkeySensorTestStop(); + } + else if(controller_->touchkeyDeviceIsRunning()) { +#else + if(controller_->touchkeyDeviceIsRunning()) { +#endif + // TouchKeys were running. Stop and close. + controller_->closeTouchkeyDevice(); + } + else { + // TouchKeys weren't running. Open and start. + String devName = controller_->touchkeyDevicePrefix().c_str(); + devName += touchkeyDeviceComboBox->getText(); + + // This will attempt to start the device and update the state accordingly + controller_->touchkeyDeviceStartupSequence(devName.toUTF8()); + } + //[/UserButtonCode_touchkeyStartButton] + } + else if (buttonThatWasClicked == oscEnableButton) + { + //[UserButtonCode_oscEnableButton] -- add your button handler code here.. + controller_->oscTransmitSetEnabled(oscEnableButton->getToggleState()); + //[/UserButtonCode_oscEnableButton] + } + else if (buttonThatWasClicked == oscEnableRawButton) + { + //[UserButtonCode_oscEnableRawButton] -- add your button handler code here.. + controller_->oscTransmitSetRawDataEnabled(oscEnableRawButton->getToggleState()); + //[/UserButtonCode_oscEnableRawButton] + } + else if (buttonThatWasClicked == oscInputEnableButton) + { + //[UserButtonCode_oscInputEnableButton] -- add your button handler code here.. + controller_->oscReceiveSetEnabled(oscInputEnableButton->getToggleState()); + //[/UserButtonCode_oscInputEnableButton] + } + else if (buttonThatWasClicked == addZoneButton) + { + //[UserButtonCode_addZoneButton] -- add your button handler code here.. + controller_->midiSegmentAdd(); + //[/UserButtonCode_addZoneButton] + } + else if (buttonThatWasClicked == removeZoneButton) + { + //[UserButtonCode_removeZoneButton] -- add your button handler code here.. + int tabIndex = keyboardZoneTabbedComponent->getCurrentTabIndex(); + if(tabIndex != 0) { + KeyboardZoneComponent* selectedComponent = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(tabIndex)); + controller_->midiSegmentRemove(selectedComponent->keyboardSegment()); + } + //[/UserButtonCode_removeZoneButton] + } + else if (buttonThatWasClicked == touchkeyAutodetectButton) + { + //[UserButtonCode_touchkeyAutodetectButton] -- add your button handler code here.. + if(controller_->touchkeyDeviceIsAutodetecting()) + controller_->touchkeyDeviceStopAutodetecting(); + else + controller_->touchkeyDeviceAutodetectLowestMidiNote(); + //[/UserButtonCode_touchkeyAutodetectButton] + } + + //[UserbuttonClicked_Post] + //[/UserbuttonClicked_Post] +} + + + +//[MiscUserCode] You can add your own definitions of your custom methods or any other code here... + +void ControlWindowMainComponent::textEditorReturnKeyPressed(TextEditor &editor) +{ + if(controller_ == 0) + return; + if(&editor == oscHostTextEditor || &editor == oscPortTextEditor) + updateOscHostPort(); + else if(&editor == oscInputPortTextEditor) { + int port = atoi(oscInputPortTextEditor->getText().toUTF8()); + controller_->oscReceiveSetPort(port); + } +} + +void ControlWindowMainComponent::textEditorEscapeKeyPressed(TextEditor &editor) +{ + // Nothing to do here +} + +void ControlWindowMainComponent::textEditorFocusLost(TextEditor &editor) +{ + textEditorReturnKeyPressed(editor); +} + +// Update list of TouchKeys and MIDI input devices +void ControlWindowMainComponent::updateInputDeviceList() +{ + if(controller_ == 0) + return; + + // *** TouchKeys devices *** + vector<string> tkdevices = controller_->availableTouchkeyDevices(); + vector<string>::iterator tkit; + int counter; + + touchkeyDeviceComboBox->clear(); + + if(tkdevices.size() == 0) { + touchkeyDeviceComboBox->addItem("No devices", 1); + touchkeyDeviceComboBox->setSelectedId(1, dontSendNotification); + touchkeyDeviceComboBox->setEnabled(false); + touchkeyStartButton->setEnabled(false); + } + else { + counter = 1; + for(tkit = tkdevices.begin(); tkit != tkdevices.end(); ++tkit) { + touchkeyDeviceComboBox->addItem(tkit->c_str(), counter++); + } + touchkeyDeviceComboBox->setSelectedId(1, dontSendNotification); + touchkeyDeviceComboBox->setEnabled(true); + touchkeyStartButton->setEnabled(true); + } + + // *** MIDI input devices *** + vector<pair<int, string> > devices = controller_->availableMIDIInputDevices(); + vector<pair<int, string> >::iterator it; + + midiInputDeviceComboBox->clear(); + midiInputDeviceIDs_.clear(); + midiInputDeviceComboBox->addItem("Disabled", 1); + midiInputDeviceComboBox->addItem("TouchKeys Standalone", 2); + + midiInputAuxDeviceComboBox->clear(); + midiInputAuxDeviceComboBox->addItem("Disabled", 1); + + counter = kMidiInputDeviceComboBoxOffset; + + // Check whether the currently selected ID still exists while + // we build the list + bool lastSelectedDeviceExists = false; + bool lastSelectedAuxDeviceExists = false; + for(it = devices.begin(); it != devices.end(); ++it) { + midiInputDeviceComboBox->addItem((*it).second.c_str(), counter); + midiInputAuxDeviceComboBox->addItem((*it).second.c_str(), counter); + midiInputDeviceIDs_.push_back(it->first); + if(it->first == lastSelectedMidiInputID_) + lastSelectedDeviceExists = true; + if(it->first == lastSelectedMidiAuxInputID_) + lastSelectedAuxDeviceExists = true; + counter++; + } + + if(!lastSelectedDeviceExists && lastSelectedMidiInputID_ >= 0) + controller_->disablePrimaryMIDIInputPort(); + if(!lastSelectedAuxDeviceExists && lastSelectedMidiAuxInputID_ >= 0) + controller_->disableAllMIDIInputPorts(true); +} + +void ControlWindowMainComponent::updateOscHostPort() +{ + if(controller_ == 0) + return; + + String oscHost = oscHostTextEditor->getText(); + String oscPort = oscPortTextEditor->getText(); + controller_->oscTransmitClearAddresses(); + controller_->oscTransmitAddAddress(oscHost.toUTF8(), oscPort.toUTF8()); +} + +// Synchronize the UI state with the underlying state of the controller +void ControlWindowMainComponent::synchronize() { + if(controller_ == 0) + return; + + bool devicesUpdated = false; + + if(controller_->devicesShouldUpdate() != lastControllerUpdateDeviceCount_) { + lastControllerUpdateDeviceCount_ = controller_->devicesShouldUpdate(); + updateInputDeviceList(); + devicesUpdated = true; + } + + // Update TouchKeys status +#ifdef ENABLE_TOUCHKEYS_SENSOR_TEST + if(controller_->touchkeySensorTestIsRunning()) { + touchkeyStartButton->setButtonText("Stop"); + touchkeyStatusLabel->setText("Testing", dontSendNotification); + } + else if(controller_->touchkeyDeviceIsRunning()) { +#else + if(controller_->touchkeyDeviceIsRunning()) { +#endif + touchkeyStartButton->setButtonText("Stop"); + touchkeyStatusLabel->setText("Running", dontSendNotification); + } + else if(controller_->touchkeyDeviceErrorOccurred()) { + touchkeyStartButton->setButtonText("Start"); + touchkeyStatusLabel->setText(controller_->touchkeyDeviceErrorMessage().c_str(), dontSendNotification); + } + else { + touchkeyStartButton->setButtonText("Start"); + touchkeyStatusLabel->setText("Not running", dontSendNotification); + } + + // Update MIDI input status + if(controller_->midiTouchkeysStandaloneModeIsEnabled()) { + midiInputDeviceComboBox->setSelectedId(2, dontSendNotification); + } + else { + // First query the primary port + int selectedPrimaryPort = controller_->selectedMIDIPrimaryInputPort(); + if(selectedPrimaryPort < 0) { + midiInputDeviceComboBox->setSelectedId(1, dontSendNotification); + } + else if(selectedPrimaryPort != lastSelectedMidiInputID_ || devicesUpdated){ + // Input has changed from before. Find it in vector + // If there is more than one selected ID, we will only take the first one for + // the current UI. This affects the display but not the functionality. + for(int i = 0; i < midiInputDeviceIDs_.size(); i++) { + if(midiInputDeviceIDs_[i] == selectedPrimaryPort) { + midiInputDeviceComboBox->setSelectedId(i + kMidiInputDeviceComboBoxOffset, dontSendNotification); + break; + } + } + // ...and cache this as the last ID so we don't search again next time + lastSelectedMidiInputID_ = selectedPrimaryPort; + + // Now disable this item in the auxiliary combo box + for(int i = 0; i < midiInputAuxDeviceComboBox->getNumItems(); i++) { + int itemId = midiInputAuxDeviceComboBox->getItemId(i) - kMidiInputDeviceComboBoxOffset; + if(itemId >= 0) { + midiInputAuxDeviceComboBox->setItemEnabled(midiInputAuxDeviceComboBox->getItemId(i), + (itemId != selectedPrimaryPort)); + } + } + } + } + + // Then get all aux ports and display the first one + const std::vector<int>& selectedMidiInputDevices(controller_->selectedMIDIAuxInputPorts()); + if(selectedMidiInputDevices.empty()) { + midiInputAuxDeviceComboBox->setSelectedId(1, dontSendNotification); + } + else if(selectedMidiInputDevices.front() != lastSelectedMidiAuxInputID_ || devicesUpdated){ + // Input has changed from before. Find it in vector + // If there is more than one selected ID, we will only take the first one for + // the current UI. This affects the display but not the functionality. + for(int i = 0; i < midiInputDeviceIDs_.size(); i++) { + if(midiInputDeviceIDs_[i] == selectedMidiInputDevices.front()) { + midiInputAuxDeviceComboBox->setSelectedId(i + kMidiInputDeviceComboBoxOffset, dontSendNotification); + break; + } + } + // ...and cache this as the last ID so we don't search again next time + lastSelectedMidiAuxInputID_ = selectedMidiInputDevices.front(); + } + + // Update OSC status + oscEnableButton->setToggleState(controller_->oscTransmitEnabled(), dontSendNotification); + oscEnableRawButton->setToggleState(controller_->oscTransmitRawDataEnabled(), dontSendNotification); + oscInputEnableButton->setToggleState(controller_->oscReceiveEnabled(), dontSendNotification); + + // Update the OSC fields only if the text editors aren't active + if(!oscHostTextEditor->hasKeyboardFocus(true) && !oscPortTextEditor->hasKeyboardFocus(true)) { + const std::vector<lo_address>& oscAddresses = controller_->oscTransmitAddresses(); + if(oscAddresses.empty()) { + oscHostTextEditor->setText("", false); + oscPortTextEditor->setText("", false); + } + else { + // Take the first address to display in the text editor. As with MIDI input, + // this doesn't affect the functionality, only the UI display. + lo_address firstAddress = oscAddresses.front(); + + oscHostTextEditor->setText(lo_address_get_hostname(firstAddress), false); + oscPortTextEditor->setText(lo_address_get_port(firstAddress), false); + } + } + if(!oscInputPortTextEditor->hasKeyboardFocus(true)) { + int port = controller_->oscReceivePort(); + oscInputPortTextEditor->setText(String(port), false); + } + + // Set the octave button + int octave = (controller_->touchkeyDeviceLowestMidiNote() / 12) - 1; + if(octave >= 0 && octave <= kTouchkeysMaxOctave) + touchkeyOctaveComboBox->setSelectedId(octave + kTouchkeysComponentComboBoxOffset, dontSendNotification); + + // Enable or disable the autodetect button depending on the device status + if(!controller_->touchkeyDeviceIsRunning()) { + touchkeyAutodetectButton->setEnabled(false); + } + else if(controller_->touchkeyDeviceIsAutodetecting()) { + touchkeyAutodetectButton->setEnabled(true); + touchkeyAutodetectButton->setButtonText("Cancel"); + } + else { + touchkeyAutodetectButton->setEnabled(true); + touchkeyAutodetectButton->setButtonText("Detect"); + } + + // Update segments list if it has changed + if(lastSegmentUniqueIdentifier_ != controller_->midiSegmentUniqueIdentifier()) + updateKeyboardSegments(); + + // Synchronize every tab component + for(int tab = 0; tab < keyboardZoneTabbedComponent->getNumTabs(); tab++) { + KeyboardZoneComponent *component = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(tab)); + component->synchronize(devicesUpdated); + } + + // Update add/remove buttons + if(keyboardZoneTabbedComponent->getCurrentTabIndex() <= 0) { + removeZoneButton->setEnabled(false); + } + else { + removeZoneButton->setEnabled(true); + } + if(controller_->midiSegmentsCount() >= 8) + addZoneButton->setEnabled(false); + else + addZoneButton->setEnabled(true); +} + +// Return the currently selected TouchKeys string +String ControlWindowMainComponent::currentTouchkeysSelectedPath() +{ + String devName = controller_->touchkeyDevicePrefix().c_str(); + devName += touchkeyDeviceComboBox->getText(); + + return devName; +} + +// Update the state of the keyboard segment tab bar. Called only when segments change +void ControlWindowMainComponent::updateKeyboardSegments() +{ + if(controller_ == 0) + return; + // Update the identifier to say we've matched the current state of the segments + lastSegmentUniqueIdentifier_ = controller_->midiSegmentUniqueIdentifier(); + + // Save the current selected index in case we later remove it + int currentlySelectedIndex = keyboardZoneTabbedComponent->getCurrentTabIndex(); + + KeyboardZoneComponent* currentlySelectedComponent = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(currentlySelectedIndex)); + MidiKeyboardSegment* currentlySelectedSegment = 0; + if(currentlySelectedComponent != 0) + currentlySelectedSegment = currentlySelectedComponent->keyboardSegment(); + bool selectedNewTab = false; + + // First, go through the segments and create tabs as needed + int maxNumSegments = controller_->midiSegmentsCount(); + for(int i = 0; i < maxNumSegments; i++) { + MidiKeyboardSegment* segment = controller_->midiSegment(i); + bool matched = false; + if(segment == 0) + continue; + // Look for this segment among the tabs we already have + for(int tab = 0; tab < keyboardZoneTabbedComponent->getNumTabs(); tab++) { + KeyboardZoneComponent *component = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(tab)); + if(component->keyboardSegment() == segment && component->keyboardZone() == segment->outputPort()) { + // Found it... + matched = true; + break; + } + } + // If we didn't find it, add a tab for this segment + if(!matched) { + KeyboardZoneComponent *newComponent = new KeyboardZoneComponent(); + newComponent->setMainApplicationController(controller_); + newComponent->setKeyboardSegment(segment, segment->outputPort()); + + char name[16]; +#ifdef _MSC_VER + _snprintf_s(name, 16, _TRUNCATE, "Zone %d", segment->outputPort()); +#else + snprintf(name, 16, "Zone %d", segment->outputPort()); +#endif + + // Add the component, telling the tab manager to take charge of deleting it at the end + keyboardZoneTabbedComponent->addTab(name, Colours::lightgrey, newComponent, true); + keyboardZoneTabbedComponent->setCurrentTabIndex(keyboardZoneTabbedComponent->getNumTabs() - 1); + selectedNewTab = true; + + //std::cout << "Adding tab for segment " << segment << endl; + } + } + + // Now go through the other way and remove tabs that are no longer needed + // Iterate through each tab: find a match in the segments + int tab = 0; + while(tab < keyboardZoneTabbedComponent->getNumTabs()) { + KeyboardZoneComponent *component = static_cast<KeyboardZoneComponent*> (keyboardZoneTabbedComponent->getTabContentComponent(tab)); + MidiKeyboardSegment *segment = component->keyboardSegment(); + bool matched = false; + + for(int i = 0; i < maxNumSegments; i++) { + if(segment == controller_->midiSegment(i) && component->keyboardZone() == segment->outputPort()) { + matched = true; + break; + } + } + if(segment == 0 || !matched) { + // This tab holds a nonexistent segment and should be removed + keyboardZoneTabbedComponent->removeTab(tab); + + if(currentlySelectedSegment == segment) { + // The currently selected tab has been removed. Select the prior one. + if(currentlySelectedIndex > 0) { + int indexToSelect = currentlySelectedIndex - 1; + if(indexToSelect >= keyboardZoneTabbedComponent->getNumTabs()) + indexToSelect = keyboardZoneTabbedComponent->getNumTabs() - 1; + if(indexToSelect < 0) + indexToSelect = 0; + keyboardZoneTabbedComponent->setCurrentTabIndex(indexToSelect); + } + else + keyboardZoneTabbedComponent->setCurrentTabIndex(0); + } + + // And we have to start over again since the tab indexing has changed + tab = 0; + } + else // Found a match: check the next tab + tab++; + // Eventually, we get to the end of the list of tabs an we know every existing tab matches a segment + } +} + +//[/MiscUserCode] + + +//============================================================================== +#if 0 +/* -- Introjucer information section -- + + This is where the Introjucer stores the metadata that describe this GUI layout, so + make changes in here at your peril! + +BEGIN_JUCER_METADATA + +<JUCER_COMPONENT documentType="Component" className="ControlWindowMainComponent" + componentName="" parentClasses="public Component, public TextEditor::Listener" + constructorParams="" variableInitialisers="controller_(0)" snapPixels="8" + snapActive="1" snapShown="1" overlayOpacity="0.330" fixedSize="0" + initialWidth="872" initialHeight="444"> + <BACKGROUND backgroundColour="ffd2d2d2"/> + <GROUPCOMPONENT name="MIDI input group" id="ce80a86ee6475cd9" memberName="midiInputGroupComponent" + virtualName="" explicitFocusOrder="0" pos="8 144 304 96" title="MIDI Input"/> + <COMBOBOX name="MIDI input combo box" id="def32c74505cfa50" memberName="midiInputDeviceComboBox" + virtualName="" explicitFocusOrder="0" pos="80 168 216 24" editable="0" + layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> + <LABEL name="new label" id="ad7bc4640d8023b7" memberName="label" virtualName="" + explicitFocusOrder="0" pos="16 168 64 24" edTextCol="ff000000" + edBkgCol="0" labelText="Keyboard:" editableSingleClick="0" editableDoubleClick="0" + focusDiscardsChanges="0" fontname="Default font" fontsize="15" + bold="0" italic="0" justification="33"/> + <GROUPCOMPONENT name="new group" id="9106305fd2211185" memberName="groupComponent" + virtualName="" explicitFocusOrder="0" pos="8 8 304 128" title="TouchKeys"/> + <LABEL name="new label" id="944877a84dcfc602" memberName="label2" virtualName="" + explicitFocusOrder="0" pos="16 32 60 24" edTextCol="ff000000" + edBkgCol="0" labelText="Device: " editableSingleClick="0" + editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" + fontsize="15" bold="0" italic="0" justification="33"/> + <COMBOBOX name="TouchKeys combo box" id="871223bdcad0e693" memberName="touchkeyDeviceComboBox" + virtualName="" explicitFocusOrder="0" pos="72 32 224 24" editable="0" + layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> + <LABEL name="new label" id="1cdf89082d95c72c" memberName="label3" virtualName="" + explicitFocusOrder="0" pos="16 96 60 24" edTextCol="ff000000" + edBkgCol="0" labelText="Status: " editableSingleClick="0" + editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" + fontsize="15" bold="0" italic="0" justification="33"/> + <TEXTBUTTON name="TouchKeys start button" id="1bb1c69c957fc984" memberName="touchkeyStartButton" + virtualName="" explicitFocusOrder="0" pos="216 96 79 24" buttonText="Start" + connectedEdges="0" needsCallback="1" radioGroupId="0"/> + <LABEL name="TouchKeys status label" id="c91b132696e6ba1d" memberName="touchkeyStatusLabel" + virtualName="" explicitFocusOrder="0" pos="72 96 136 24" edTextCol="ff000000" + edBkgCol="0" labelText="not running" editableSingleClick="0" + editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" + fontsize="15" bold="0" italic="0" justification="33"/> + <GROUPCOMPONENT name="OSC group" id="8268119e22809825" memberName="oscGroupComponent" + virtualName="" explicitFocusOrder="0" pos="8 320 304 96" title="OSC Output"/> + <LABEL name="new label" id="896c0c48a1cf50a" memberName="label7" virtualName="" + explicitFocusOrder="0" pos="16 376 55 24" edTextCol="ff000000" + edBkgCol="0" labelText="Host:" editableSingleClick="0" editableDoubleClick="0" + focusDiscardsChanges="0" fontname="Default font" fontsize="15" + bold="0" italic="0" justification="33"/> + <TEXTEDITOR name="new text editor" id="84778d0bbebedd36" memberName="oscHostTextEditor" + virtualName="" explicitFocusOrder="0" pos="64 376 128 24" initialText="127.0.0.1" + multiline="0" retKeyStartsLine="0" readonly="0" scrollbars="1" + caret="1" popupmenu="1"/> + <LABEL name="new label" id="157c85bf83a7f936" memberName="label8" virtualName="" + explicitFocusOrder="0" pos="200 376 40 24" edTextCol="ff000000" + edBkgCol="0" labelText="Port:" editableSingleClick="0" editableDoubleClick="0" + focusDiscardsChanges="0" fontname="Default font" fontsize="15" + bold="0" italic="0" justification="33"/> + <TEXTEDITOR name="new text editor" id="7c21f0c238812d11" memberName="oscPortTextEditor" + virtualName="" explicitFocusOrder="0" pos="240 376 56 24" initialText="8000" + multiline="0" retKeyStartsLine="0" readonly="0" scrollbars="1" + caret="1" popupmenu="1"/> + <TOGGLEBUTTON name="OSC enable button" id="ccd52591cfd0b632" memberName="oscEnableButton" + virtualName="" explicitFocusOrder="0" pos="24 344 144 24" buttonText="Enable OSC output" + connectedEdges="0" needsCallback="1" radioGroupId="0" state="0"/> + <TOGGLEBUTTON name="OSC enable raw button" id="4aaf8f80edaff24" memberName="oscEnableRawButton" + virtualName="" explicitFocusOrder="0" pos="176 344 144 24" buttonText="Send raw frames" + connectedEdges="0" needsCallback="1" radioGroupId="0" state="0"/> + <LABEL name="new label" id="c5873c6498f8156d" memberName="label4" virtualName="" + explicitFocusOrder="0" pos="16 64 104 24" edTextCol="ff000000" + edBkgCol="0" labelText="Lowest Octave:" editableSingleClick="0" + editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" + fontsize="15" bold="0" italic="0" justification="33"/> + <COMBOBOX name="TouchKeys octave box" id="36ace32027c81d30" memberName="touchkeyOctaveComboBox" + virtualName="" explicitFocusOrder="0" pos="120 64 88 24" editable="0" + layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> + <GROUPCOMPONENT name="MIDI input group" id="bb54712f78382055" memberName="oscInputGroupComponent" + virtualName="" explicitFocusOrder="0" pos="8 248 304 64" title="OSC Input"/> + <TOGGLEBUTTON name="OSC input enable button" id="22a196770a440560" memberName="oscInputEnableButton" + virtualName="" explicitFocusOrder="0" pos="24 272 152 24" buttonText="Enable OSC input" + connectedEdges="0" needsCallback="1" radioGroupId="0" state="0"/> + <LABEL name="new label" id="c680c2da87cdcbf2" memberName="label6" virtualName="" + explicitFocusOrder="0" pos="200 272 40 24" edTextCol="ff000000" + edBkgCol="0" labelText="Port:" editableSingleClick="0" editableDoubleClick="0" + focusDiscardsChanges="0" fontname="Default font" fontsize="15" + bold="0" italic="0" justification="33"/> + <TEXTEDITOR name="new text editor" id="d4a91e8bff5b6bc9" memberName="oscInputPortTextEditor" + virtualName="" explicitFocusOrder="0" pos="240 272 56 24" initialText="8001" + multiline="0" retKeyStartsLine="0" readonly="0" scrollbars="1" + caret="1" popupmenu="1"/> + <TABBEDCOMPONENT name="keyboard zone tabbed component" id="33da3d6583cdacbf" memberName="keyboardZoneTabbedComponent" + virtualName="" explicitFocusOrder="0" pos="320 0 552 464" orientation="top" + tabBarDepth="30" initialTab="-1"/> + <TEXTBUTTON name="add zone button" id="1d2fa7fd74f31315" memberName="addZoneButton" + virtualName="" explicitFocusOrder="0" pos="776 4 38 20" buttonText="Add" + connectedEdges="0" needsCallback="1" radioGroupId="0"/> + <TEXTBUTTON name="remove zone button" id="7865f7787a191e0e" memberName="removeZoneButton" + virtualName="" explicitFocusOrder="0" pos="824 4 38 20" buttonText="Del" + connectedEdges="0" needsCallback="1" radioGroupId="0"/> + <TEXTBUTTON name="TouchKeys autodetect button" id="6e19894bc11d0276" memberName="touchkeyAutodetectButton" + virtualName="" explicitFocusOrder="0" pos="216 64 79 24" buttonText="Detect" + connectedEdges="0" needsCallback="1" radioGroupId="0"/> + <COMBOBOX name="MIDI input aux combo box" id="1b77c934a4790942" memberName="midiInputAuxDeviceComboBox" + virtualName="" explicitFocusOrder="0" pos="80 200 216 24" editable="0" + layout="33" items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/> + <LABEL name="new label" id="7409cb92cfa3b9f2" memberName="label5" virtualName="" + explicitFocusOrder="0" pos="24 200 55 24" edTextCol="ff000000" + edBkgCol="0" labelText="Aux:" editableSingleClick="0" editableDoubleClick="0" + focusDiscardsChanges="0" fontname="Default font" fontsize="15" + bold="0" italic="0" justification="34"/> +</JUCER_COMPONENT> + +END_JUCER_METADATA +*/ +#endif + + +//[EndFile] You can add extra defines here... +#endif // TOUCHKEYS_NO_GUI +//[/EndFile]
--- a/Source/MainApplicationController.cpp Mon Feb 06 16:40:02 2017 +0000 +++ b/Source/MainApplicationController.cpp Fri Nov 23 15:48:14 2018 +0000 @@ -914,6 +914,10 @@ // Load the preset from this element bool result = midiInputController_.loadSegmentPreset(segmentsElement); + // Enable any necessary MIDI outputs + for(int i = 0; i < midiInputController_.numSegments(); i++) + loadMIDIOutputFromApplicationPreferences(i); + // Loading a preset won't set standalone mode; so re-enable it when finished // if needed if(touchkeyStandaloneModeEnabled_) { @@ -1699,4 +1703,4 @@ // Send back an OSC message to indicate the result of a control command void MainApplicationOSCController::oscControlTransmitResult(int result) { controller_.oscTransmitter_.sendMessage("/touchkeys/control/result", "i", result, LO_ARGS_END); -} \ No newline at end of file +}
--- a/Source/MainApplicationController.h Mon Feb 06 16:40:02 2017 +0000 +++ b/Source/MainApplicationController.h Fri Nov 23 15:48:14 2018 +0000 @@ -280,7 +280,7 @@ // from a file. They return true on success. bool savePresetToFile(const char *filename); bool loadPresetFromFile(const char *filename); - + #ifndef TOUCHKEYS_NO_GUI bool savePresetWithDialog(); bool loadPresetWithDialog();
--- a/Source/TouchKeys/MidiKeyboardSegment.cpp Mon Feb 06 16:40:02 2017 +0000 +++ b/Source/TouchKeys/MidiKeyboardSegment.cpp Fri Nov 23 15:48:14 2018 +0000 @@ -955,21 +955,6 @@ if(!properties.containsKey("outputPort")) return false; outputPortNumber_ = properties.getIntValue("outputPort"); - if(!properties.containsKey("mode")) - return false; - int mode = properties.getIntValue("mode"); - // Setting the mode affects a few other variables so use the - // functions rather than setting mode_ directly - if(mode == ModePassThrough) - setModePassThrough(); - else if(mode == ModeMonophonic) - setModeMonophonic(); - else if(mode == ModePolyphonic) - setModePolyphonic(); - else if(mode == ModeMPE) - setModeMPE(); - else // Off or unknown - setModeOff(); if(!properties.containsKey("channelMask")) return false; channelMask_ = properties.getIntValue("channelMask"); @@ -1014,6 +999,22 @@ return false; useVoiceStealing_ = properties.getBoolValue("useVoiceStealing"); + if(!properties.containsKey("mode")) + return false; + int mode = properties.getIntValue("mode"); + // Setting the mode affects a few other variables so use the + // functions rather than setting mode_ directly + if(mode == ModePassThrough) + setModePassThrough(); + else if(mode == ModeMonophonic) + setModeMonophonic(); + else if(mode == ModePolyphonic) + setModePolyphonic(); + else if(mode == ModeMPE) + setModeMPE(); + else // Off or unknown + setModeOff(); + // Load each mapping factory XmlElement *element = preset->getChildByName("MappingFactory"); @@ -1112,7 +1113,7 @@ // And turn on note on MIDI controller if(midiOutputController_ != 0) { - MidiMessage newMessage = MidiMessage::noteOn(message.getChannel(), message.getNoteNumber() + outputTransposition_, message.getVelocity()); + MidiMessage newMessage = MidiMessage::noteOn(outputChannelLowest_ + 1, message.getNoteNumber() + outputTransposition_, message.getVelocity()); midiOutputController_->sendMessage(outputPortNumber_, newMessage); } @@ -1120,7 +1121,7 @@ int note = message.getNoteNumber(); if(keyboard_.key(note) != 0) keyboard_.key(note)->midiNoteOn(this, message.getVelocity(), - message.getChannel() - 1, keyboard_.schedulerCurrentTimestamp()); + outputChannelLowest_, keyboard_.schedulerCurrentTimestamp()); // Now resume the current note's mapping if(keyboard_.mappingFactory(this) != 0) { @@ -1142,7 +1143,7 @@ // And turn off note on MIDI controller if(midiOutputController_ != 0) { - MidiMessage newMessage = MidiMessage::noteOff(message.getChannel(), message.getNoteNumber() + outputTransposition_, message.getVelocity()); + MidiMessage newMessage = MidiMessage::noteOff(outputChannelLowest_ + 1, message.getNoteNumber() + outputTransposition_, message.getVelocity()); midiOutputController_->sendMessage(outputPortNumber_, newMessage); } }