|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2017 - ROLI Ltd.
-
- JUCE is an open source library subject to commercial or open-source
- licensing.
-
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
- 27th April 2017).
-
- End User License Agreement: www.juce.com/juce-5-licence
- Privacy Policy: www.juce.com/juce-5-privacy-policy
-
- Or: You may also use this code under the terms of the GPL v3 (see
- www.gnu.org/licenses).
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
-
- #pragma once
-
-
- class MPESetupComponent : public Component,
- public ChangeBroadcaster,
- private Button::Listener,
- private ComboBox::Listener
- {
- public:
- //==============================================================================
- class Listener
- {
- public:
- virtual ~Listener() {}
- virtual void zoneAdded (MPEZone newZone) = 0;
- virtual void allZonesCleared() = 0;
- virtual void legacyModeChanged (bool legacyModeEnabled, int pitchbendRange, Range<int> channelRange) = 0;
- virtual void voiceStealingEnabledChanged (bool voiceStealingEnabled) = 0;
- virtual void numberOfVoicesChanged (int numberOfVoices) = 0;
- };
-
- void addListener (Listener* listenerToAdd) { listeners.add (listenerToAdd); }
- void removeListener (Listener* listenerToRemove) { listeners.remove (listenerToRemove); }
-
- //==============================================================================
- MPESetupComponent()
- : masterChannelLabel (String(), "Master channel:"),
- noteChannelsLabel (String(), "Nr. of note channels:"),
- masterPitchbendRangeLabel (String(), "Master pitchbend range (semitones):"),
- notePitchbendRangeLabel (String(), "Note pitchbend range (semitones):"),
- addZoneButton ("Add this zone"),
- clearAllZonesButton ("Clear all zones"),
- legacyStartChannelLabel (String(), "First channel:"),
- legacyEndChannelLabel (String(), "Last channel:"),
- legacyPitchbendRangeLabel (String(), "Pitchbend range (semitones):"),
- legacyModeEnabledToggle ("Enable Legacy Mode"),
- voiceStealingEnabledToggle ("Enable synth voice stealing"),
- numberOfVoicesLabel (String(), "Number of synth voices")
- {
-
- initialiseComboBoxWithConsecutiveIntegers (masterChannel, masterChannelLabel, 1, 15, defaultMasterChannel);
- initialiseComboBoxWithConsecutiveIntegers (noteChannels, noteChannelsLabel, 1, 15, defaultNoteChannels);
- initialiseComboBoxWithConsecutiveIntegers (masterPitchbendRange, masterPitchbendRangeLabel, 0, 96, defaultMasterPitchbendRange);
- initialiseComboBoxWithConsecutiveIntegers (notePitchbendRange, notePitchbendRangeLabel, 0, 96, defaultNotePitchbendRange);
-
- initialiseComboBoxWithConsecutiveIntegers (legacyStartChannel, legacyStartChannelLabel, 1, 16, 1, false);
- initialiseComboBoxWithConsecutiveIntegers (legacyEndChannel, legacyEndChannelLabel, 1, 16, 16, false);
- initialiseComboBoxWithConsecutiveIntegers (legacyPitchbendRange, legacyPitchbendRangeLabel, 0, 96, 2, false);
-
- initialiseButton (addZoneButton);
- initialiseButton (clearAllZonesButton);
- initialiseButton (legacyModeEnabledToggle);
- initialiseButton (voiceStealingEnabledToggle);
-
- initialiseComboBoxWithConsecutiveIntegers (numberOfVoices, numberOfVoicesLabel, 1, 20, 15);
- numberOfVoices.addListener (this);
- }
-
- //==============================================================================
- void resized() override
- {
- Rectangle<int> r (proportionOfWidth (0.65f), 15, proportionOfWidth (0.25f), 3000);
- const int h = 24;
- const int hspace = 6;
- const int hbigspace = 18;
-
- masterChannel.setBounds (r.removeFromTop (h));
- r.removeFromTop (hspace);
- noteChannels.setBounds (r.removeFromTop (h));
- r.removeFromTop (hspace);
- notePitchbendRange.setBounds (r.removeFromTop (h));
- r.removeFromTop (hspace);
- masterPitchbendRange.setBounds (r.removeFromTop (h));
-
- legacyStartChannel.setBounds (masterChannel.getBounds());
- legacyEndChannel.setBounds (noteChannels.getBounds());
- legacyPitchbendRange.setBounds (notePitchbendRange.getBounds());
-
- r.removeFromTop (hbigspace);
-
- int buttonLeft = proportionOfWidth (0.5f);
-
- addZoneButton.setBounds (r.removeFromTop (h).withLeft (buttonLeft));
- r.removeFromTop (hspace);
- clearAllZonesButton.setBounds (r.removeFromTop (h).withLeft (buttonLeft));
-
- r.removeFromTop (hbigspace);
-
- int toggleLeft = proportionOfWidth (0.25f);
-
- legacyModeEnabledToggle.setBounds (r.removeFromTop (h).withLeft (toggleLeft));
- r.removeFromTop (hspace);
- voiceStealingEnabledToggle.setBounds (r.removeFromTop (h).withLeft (toggleLeft));
- r.removeFromTop (hspace);
- numberOfVoices.setBounds (r.removeFromTop (h));
- }
-
- private:
- //==============================================================================
- void initialiseComboBoxWithConsecutiveIntegers (ComboBox& comboBox, Label& labelToAttach,
- int firstValue, int numValues, int valueToSelect,
- bool makeVisible = true)
- {
- for (int i = 0; i < numValues; ++i)
- comboBox.addItem (String (i + firstValue), i + 1);
-
- comboBox.setSelectedId (valueToSelect - firstValue + 1);
- labelToAttach.attachToComponent (&comboBox, true);
-
- if (makeVisible)
- addAndMakeVisible (comboBox);
- else
- addChildComponent (comboBox);
-
- comboBox.addListener (this);
- }
-
- //==============================================================================
- void initialiseButton (Button& button)
- {
- addAndMakeVisible (button);
- button.addListener (this);
- }
-
- //==============================================================================
- void buttonClicked (Button* button) override
- {
- if (button == &addZoneButton)
- addZoneButtonClicked();
- else if (button == &clearAllZonesButton)
- clearAllZonesButtonClicked();
- else if (button == &legacyModeEnabledToggle)
- legacyModeEnabledToggleClicked();
- else if (button == &voiceStealingEnabledToggle)
- voiceStealingEnabledToggleClicked();
- }
-
- //==============================================================================
- void addZoneButtonClicked()
- {
- if (areMPEParametersValid())
- {
- MPEZone newZone (masterChannel.getText().getIntValue(),
- noteChannels.getText().getIntValue(),
- notePitchbendRange.getText().getIntValue(),
- masterPitchbendRange.getText().getIntValue());
-
- zoneLayout.addZone (newZone);
- listeners.call (&MPESetupComponent::Listener::zoneAdded, newZone);
- }
- else
- {
- handleInvalidMPEParameters();
- }
- }
-
- //==============================================================================
- void clearAllZonesButtonClicked()
- {
- zoneLayout.clearAllZones();
- listeners.call (&MPESetupComponent::Listener::allZonesCleared);
- }
-
- //==============================================================================
- void legacyModeEnabledToggleClicked()
- {
- bool legacyModeEnabled = legacyModeEnabledToggle.getToggleState();
-
- masterChannel.setVisible (! legacyModeEnabled);
- noteChannels.setVisible (! legacyModeEnabled);
- notePitchbendRange.setVisible (! legacyModeEnabled);
- masterPitchbendRange.setVisible (! legacyModeEnabled);
- addZoneButton.setVisible (! legacyModeEnabled);
- clearAllZonesButton.setVisible (! legacyModeEnabled);
-
- legacyStartChannel.setVisible (legacyModeEnabled);
- legacyEndChannel.setVisible (legacyModeEnabled);
- legacyPitchbendRange.setVisible (legacyModeEnabled);
-
- if (areLegacyModeParametersValid())
- {
- listeners.call (&MPESetupComponent::Listener::legacyModeChanged,
- legacyModeEnabledToggle.getToggleState(),
- legacyPitchbendRange.getText().getIntValue(),
- getLegacyModeChannelRange());
- }
- else
- {
- handleInvalidLegacyModeParameters();
- }
- }
-
- //==============================================================================
- void voiceStealingEnabledToggleClicked()
- {
- listeners.call (&MPESetupComponent::Listener::voiceStealingEnabledChanged,
- voiceStealingEnabledToggle.getToggleState());
- }
-
- //==============================================================================
- void comboBoxChanged (ComboBox* comboBoxThatHasChanged) override
- {
- if (comboBoxThatHasChanged == &numberOfVoices)
- {
- numberOfVoicesChanged();
- }
- else if (legacyModeEnabledToggle.getToggleState() == true)
- {
- if (comboBoxThatHasChanged == &legacyPitchbendRange)
- legacyModePitchbendRangeChanged();
- else if (comboBoxThatHasChanged == &legacyStartChannel || comboBoxThatHasChanged == &legacyEndChannel)
- legacyModeChannelRangeChanged();
- }
- }
-
- //==============================================================================
- void numberOfVoicesChanged()
- {
- listeners.call (&MPESetupComponent::Listener::numberOfVoicesChanged,
- numberOfVoices.getText().getIntValue());
- }
-
- void legacyModePitchbendRangeChanged()
- {
- jassert (legacyModeEnabledToggle.getToggleState() == true);
-
- listeners.call (&MPESetupComponent::Listener::legacyModeChanged, true,
- legacyPitchbendRange.getText().getIntValue(),
- getLegacyModeChannelRange());
- }
-
- void legacyModeChannelRangeChanged()
- {
- jassert (legacyModeEnabledToggle.getToggleState() == true);
-
- if (areLegacyModeParametersValid())
- {
- listeners.call (&MPESetupComponent::Listener::legacyModeChanged, true,
- legacyPitchbendRange.getText().getIntValue(),
- getLegacyModeChannelRange());
- }
- else
- {
- handleInvalidLegacyModeParameters();
- }
- }
-
- //==============================================================================
- bool areMPEParametersValid() const
- {
- int maxPossibleNumNoteChannels = 16 - masterChannel.getText().getIntValue();
- return noteChannels.getText().getIntValue() <= maxPossibleNumNoteChannels;
- }
-
- void handleInvalidMPEParameters() const
- {
- AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
- "Invalid zone layout",
- "Cannot create MPE zone:\n"
- "Invalid zone parameters selected!",
- "Got it");
- }
-
- bool areLegacyModeParametersValid() const
- {
- return legacyStartChannel.getText().getIntValue() <= legacyEndChannel.getText().getIntValue();
- }
-
- void handleInvalidLegacyModeParameters() const
- {
- AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
- "Invalid legacy mode channel layout",
- "Cannot set legacy mode start/end channel:\n"
- "The end channel must not be less than the start channel!",
- "Got it");
- }
-
- //==============================================================================
- Range<int> getLegacyModeChannelRange() const
- {
- return Range<int> (legacyStartChannel.getText().getIntValue(),
- legacyEndChannel.getText().getIntValue() + 1);
- }
-
- //==============================================================================
- MPEZoneLayout zoneLayout;
-
- ComboBox masterChannel, noteChannels, masterPitchbendRange, notePitchbendRange;
- Label masterChannelLabel, noteChannelsLabel, masterPitchbendRangeLabel, notePitchbendRangeLabel;
- TextButton addZoneButton, clearAllZonesButton;
-
- ComboBox legacyStartChannel, legacyEndChannel, legacyPitchbendRange;
- Label legacyStartChannelLabel, legacyEndChannelLabel, legacyPitchbendRangeLabel;
-
- ToggleButton legacyModeEnabledToggle, voiceStealingEnabledToggle;
- ComboBox numberOfVoices;
- Label numberOfVoicesLabel;
-
- ListenerList<Listener> listeners;
-
- const int defaultMasterChannel = 1, defaultNoteChannels = 15,
- defaultMasterPitchbendRange = 2, defaultNotePitchbendRange = 48;
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESetupComponent)
-
- };
|