From 15567c7150ea1788740317545fc2065d2e03edc9 Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 29 May 2019 17:13:06 +0100 Subject: [PATCH] Changed the constructor of GenericAudioProcessorEditor to take a reference rather than a pointer, to match all the other AudioProcessorEditor classes. Also tweaked its implementation to resize its components horizontally to fit the width of the parent window --- examples/Plugins/ArpeggiatorPluginDemo.h | 2 +- examples/Plugins/GainPluginDemo.h | 2 +- examples/Plugins/MultiOutSynthPluginDemo.h | 2 +- examples/Plugins/NoiseGatePluginDemo.h | 2 +- .../AudioPluginHost/Source/UI/PluginWindow.h | 5 +- .../midi/juce_MidiBuffer.cpp | 91 +++++++++---------- .../juce_GenericAudioProcessorEditor.cpp | 55 +++++++---- .../juce_GenericAudioProcessorEditor.h | 7 +- 8 files changed, 90 insertions(+), 76 deletions(-) diff --git a/examples/Plugins/ArpeggiatorPluginDemo.h b/examples/Plugins/ArpeggiatorPluginDemo.h index 9ad8996f98..7eee80331d 100644 --- a/examples/Plugins/ArpeggiatorPluginDemo.h +++ b/examples/Plugins/ArpeggiatorPluginDemo.h @@ -125,7 +125,7 @@ public: bool isMidiEffect() const override { return true; } //============================================================================== - AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (this); } + AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (*this); } bool hasEditor() const override { return true; } //============================================================================== diff --git a/examples/Plugins/GainPluginDemo.h b/examples/Plugins/GainPluginDemo.h index 4d620e492c..062dce0667 100644 --- a/examples/Plugins/GainPluginDemo.h +++ b/examples/Plugins/GainPluginDemo.h @@ -74,7 +74,7 @@ public: } //============================================================================== - AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (this); } + AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (*this); } bool hasEditor() const override { return true; } //============================================================================== diff --git a/examples/Plugins/MultiOutSynthPluginDemo.h b/examples/Plugins/MultiOutSynthPluginDemo.h index 09668ae11f..05e7cc9389 100644 --- a/examples/Plugins/MultiOutSynthPluginDemo.h +++ b/examples/Plugins/MultiOutSynthPluginDemo.h @@ -125,7 +125,7 @@ public: } //============================================================================== - AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (this); } + AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (*this); } bool hasEditor() const override { return true; } //============================================================================== diff --git a/examples/Plugins/NoiseGatePluginDemo.h b/examples/Plugins/NoiseGatePluginDemo.h index 6925d0fced..7b4d49e2b3 100644 --- a/examples/Plugins/NoiseGatePluginDemo.h +++ b/examples/Plugins/NoiseGatePluginDemo.h @@ -108,7 +108,7 @@ public: } //============================================================================== - AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (this); } + AudioProcessorEditor* createEditor() override { return new GenericAudioProcessorEditor (*this); } bool hasEditor() const override { return true; } const String getName() const override { return "NoiseGate"; } bool acceptsMidi() const override { return false; } diff --git a/extras/AudioPluginHost/Source/UI/PluginWindow.h b/extras/AudioPluginHost/Source/UI/PluginWindow.h index 5ae81109b6..9550127d3f 100644 --- a/extras/AudioPluginHost/Source/UI/PluginWindow.h +++ b/extras/AudioPluginHost/Source/UI/PluginWindow.h @@ -198,7 +198,8 @@ public: private: float getDesktopScaleFactor() const override { return 1.0f; } - static AudioProcessorEditor* createProcessorEditor (AudioProcessor& processor, PluginWindow::Type type) + static AudioProcessorEditor* createProcessorEditor (AudioProcessor& processor, + PluginWindow::Type type) { if (type == PluginWindow::Type::normal) { @@ -209,7 +210,7 @@ private: } if (type == PluginWindow::Type::generic) - return new GenericAudioProcessorEditor (&processor); + return new GenericAudioProcessorEditor (processor); if (type == PluginWindow::Type::programs) return new ProgramAudioProcessorEditor (processor); diff --git a/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp b/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp index 55e2597b36..5745038a7a 100644 --- a/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp @@ -25,58 +25,53 @@ namespace juce namespace MidiBufferHelpers { - inline int getEventTime (const void* const d) noexcept + inline int getEventTime (const void* d) noexcept { return readUnaligned (d); } - inline uint16 getEventDataSize (const void* const d) noexcept + inline uint16 getEventDataSize (const void* d) noexcept { return readUnaligned (static_cast (d) + sizeof (int32)); } - inline uint16 getEventTotalSize (const void* const d) noexcept + inline uint16 getEventTotalSize (const void* d) noexcept { return (uint16) (getEventDataSize (d) + sizeof (int32) + sizeof (uint16)); } - static int findActualEventLength (const uint8* const data, const int maxBytes) noexcept + static int findActualEventLength (const uint8* data, int maxBytes) noexcept { - unsigned int byte = (unsigned int) *data; - int size = 0; + auto byte = (unsigned int) *data; if (byte == 0xf0 || byte == 0xf7) { - const uint8* d = data + 1; + int i = 1; - while (d < data + maxBytes) - if (*d++ == 0xf7) + while (i < maxBytes) + if (data[i++] == 0xf7) break; - size = (int) (d - data); + return i; } - else if (byte == 0xff) + + if (byte == 0xff) { if (maxBytes == 1) - { - size = 1; - } - else - { - int n; - const int bytesLeft = MidiMessage::readVariableLengthVal (data + 1, n); - size = jmin (maxBytes, n + 2 + bytesLeft); - } - } - else if (byte >= 0x80) - { - size = jmin (maxBytes, MidiMessage::getMessageLengthFromFirstByte ((uint8) byte)); + return 1; + + int n; + auto bytesLeft = MidiMessage::readVariableLengthVal (data + 1, n); + return jmin (maxBytes, n + 2 + bytesLeft); } - return size; + if (byte >= 0x80) + return jmin (maxBytes, MidiMessage::getMessageLengthFromFirstByte ((uint8) byte)); + + return 0; } - static uint8* findEventAfter (uint8* d, uint8* endData, const int samplePosition) noexcept + static uint8* findEventAfter (uint8* d, uint8* endData, int samplePosition) noexcept { while (d < endData && getEventTime (d) <= samplePosition) d += getEventTotalSize (d); @@ -107,31 +102,31 @@ void MidiBuffer::clear() noexcept { data.clearQuick(); void MidiBuffer::ensureSize (size_t minimumNumBytes) { data.ensureStorageAllocated ((int) minimumNumBytes); } bool MidiBuffer::isEmpty() const noexcept { return data.size() == 0; } -void MidiBuffer::clear (const int startSample, const int numSamples) +void MidiBuffer::clear (int startSample, int numSamples) { - uint8* const start = MidiBufferHelpers::findEventAfter (data.begin(), data.end(), startSample - 1); - uint8* const end = MidiBufferHelpers::findEventAfter (start, data.end(), startSample + numSamples - 1); + auto start = MidiBufferHelpers::findEventAfter (data.begin(), data.end(), startSample - 1); + auto end = MidiBufferHelpers::findEventAfter (start, data.end(), startSample + numSamples - 1); data.removeRange ((int) (start - data.begin()), (int) (end - data.begin())); } -void MidiBuffer::addEvent (const MidiMessage& m, const int sampleNumber) +void MidiBuffer::addEvent (const MidiMessage& m, int sampleNumber) { addEvent (m.getRawData(), m.getRawDataSize(), sampleNumber); } -void MidiBuffer::addEvent (const void* const newData, const int maxBytes, const int sampleNumber) +void MidiBuffer::addEvent (const void* newData, int maxBytes, int sampleNumber) { - const int numBytes = MidiBufferHelpers::findActualEventLength (static_cast (newData), maxBytes); + auto numBytes = MidiBufferHelpers::findActualEventLength (static_cast (newData), maxBytes); if (numBytes > 0) { - const size_t newItemSize = (size_t) numBytes + sizeof (int32) + sizeof (uint16); - const int offset = (int) (MidiBufferHelpers::findEventAfter (data.begin(), data.end(), sampleNumber) - data.begin()); + auto newItemSize = (size_t) numBytes + sizeof (int32) + sizeof (uint16); + auto offset = (int) (MidiBufferHelpers::findEventAfter (data.begin(), data.end(), sampleNumber) - data.begin()); data.insertMultiple (offset, 0, (int) newItemSize); - uint8* const d = data.begin() + offset; + auto d = data.begin() + offset; writeUnaligned (d, sampleNumber); writeUnaligned (d + 4, static_cast (numBytes)); memcpy (d + 6, newData, (size_t) numBytes); @@ -139,9 +134,7 @@ void MidiBuffer::addEvent (const void* const newData, const int maxBytes, const } void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, - const int startSample, - const int numSamples, - const int sampleDeltaToAdd) + int startSample, int numSamples, int sampleDeltaToAdd) { Iterator i (otherBuffer); i.setNextSamplePosition (startSample); @@ -159,9 +152,9 @@ void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, int MidiBuffer::getNumEvents() const noexcept { int n = 0; - const uint8* const end = data.end(); + auto end = data.end(); - for (const uint8* d = data.begin(); d < end; ++n) + for (auto d = data.begin(); d < end; ++n) d += MidiBufferHelpers::getEventTotalSize (d); return n; @@ -177,11 +170,11 @@ int MidiBuffer::getLastEventTime() const noexcept if (data.size() == 0) return 0; - const uint8* const endData = data.end(); + auto endData = data.end(); - for (const uint8* d = data.begin();;) + for (auto d = data.begin();;) { - const uint8* const nextOne = d + MidiBufferHelpers::getEventTotalSize (d); + auto nextOne = d + MidiBufferHelpers::getEventTotalSize (d); if (nextOne >= endData) return MidiBufferHelpers::getEventTime (d); @@ -196,24 +189,24 @@ MidiBuffer::Iterator::Iterator (const MidiBuffer& b) noexcept { } -MidiBuffer::Iterator::~Iterator() noexcept{} +MidiBuffer::Iterator::~Iterator() noexcept {} -void MidiBuffer::Iterator::setNextSamplePosition (const int samplePosition) noexcept +void MidiBuffer::Iterator::setNextSamplePosition (int samplePosition) noexcept { data = buffer.data.begin(); - const uint8* const dataEnd = buffer.data.end(); + auto dataEnd = buffer.data.end(); while (data < dataEnd && MidiBufferHelpers::getEventTime (data) < samplePosition) data += MidiBufferHelpers::getEventTotalSize (data); } -bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, int& numBytes, int& samplePosition) noexcept +bool MidiBuffer::Iterator::getNextEvent (const uint8*& midiData, int& numBytes, int& samplePosition) noexcept { if (data >= buffer.data.end()) return false; samplePosition = MidiBufferHelpers::getEventTime (data); - const int itemSize = MidiBufferHelpers::getEventDataSize (data); + auto itemSize = MidiBufferHelpers::getEventDataSize (data); numBytes = itemSize; midiData = data + sizeof (int32) + sizeof (uint16); data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize; @@ -227,7 +220,7 @@ bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePositio return false; samplePosition = MidiBufferHelpers::getEventTime (data); - const int itemSize = MidiBufferHelpers::getEventDataSize (data); + auto itemSize = MidiBufferHelpers::getEventDataSize (data); result = MidiMessage (data + sizeof (int32) + sizeof (uint16), itemSize, samplePosition); data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize; diff --git a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp index 2e13ee380c..49844cba12 100644 --- a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp +++ b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp @@ -97,6 +97,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterListener) }; +//============================================================================== class BooleanParameterComponent final : public Component, private ParameterListener { @@ -150,6 +151,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BooleanParameterComponent) }; +//============================================================================== class SwitchParameterComponent final : public Component, private ParameterListener { @@ -255,6 +257,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SwitchParameterComponent) }; +//============================================================================== class ChoiceParameterComponent final : public Component, private ParameterListener { @@ -317,6 +320,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChoiceParameterComponent) }; +//============================================================================== class SliderParameterComponent final : public Component, private ParameterListener { @@ -340,9 +344,9 @@ public: // Set the initial value. handleNewParameterValue(); - slider.onValueChange = [this]() { sliderValueChanged(); }; - slider.onDragStart = [this]() { sliderStartedDragging(); }; - slider.onDragEnd = [this]() { sliderStoppedDragging(); }; + slider.onValueChange = [this] { sliderValueChanged(); }; + slider.onDragStart = [this] { sliderStartedDragging(); }; + slider.onDragEnd = [this] { sliderStoppedDragging(); }; } void paint (Graphics&) override {} @@ -408,6 +412,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SliderParameterComponent) }; +//============================================================================== class ParameterDisplayComponent : public Component { public: @@ -427,27 +432,27 @@ public: // marking a parameter as boolean. If you want consistency across // all formats then it might be best to use a // SwitchParameterComponent instead. - parameterComp.reset (new BooleanParameterComponent (processor, param)); + parameterComp = std::make_unique (processor, param); } else if (param.getNumSteps() == 2) { // Most hosts display any parameter with just two steps as a switch. - parameterComp.reset (new SwitchParameterComponent (processor, param)); + parameterComp = std::make_unique (processor, param); } else if (! param.getAllValueStrings().isEmpty()) { // If we have a list of strings to represent the different states a // parameter can be in then we should present a dropdown allowing a // user to pick one of them. - parameterComp.reset (new ChoiceParameterComponent (processor, param)); + parameterComp = std::make_unique (processor, param); } else { // Everything else can be represented as a slider. - parameterComp.reset (new SliderParameterComponent (processor, param)); + parameterComp = std::make_unique (processor, param); } - addAndMakeVisible (parameterComp.get()); + addAndMakeVisible (*parameterComp); setSize (400, 40); } @@ -471,6 +476,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterDisplayComponent) }; +//============================================================================== class ParametersPanel : public Component { public: @@ -480,10 +486,16 @@ public: if (param->isAutomatable()) addAndMakeVisible (paramComponents.add (new ParameterDisplayComponent (processor, *param))); - if (auto* comp = paramComponents[0]) - setSize (comp->getWidth(), comp->getHeight() * paramComponents.size()); - else - setSize (400, 100); + int maxWidth = 400; + int height = 0; + + for (auto& comp : paramComponents) + { + maxWidth = jmax (maxWidth, comp->getWidth()); + height += comp->getHeight(); + } + + setSize (maxWidth, height); } void paint (Graphics& g) override @@ -508,26 +520,31 @@ private: //============================================================================== struct GenericAudioProcessorEditor::Pimpl { - Pimpl (GenericAudioProcessorEditor& parent) - : owner (parent) + Pimpl (GenericAudioProcessorEditor& parent) : owner (parent) { auto* p = parent.getAudioProcessor(); jassert (p != nullptr); - juceParameters.update (*p, false); + legacyParameters.update (*p, false); owner.setOpaque (true); - view.setViewedComponent (new ParametersPanel (*p, juceParameters.params)); + view.setViewedComponent (new ParametersPanel (*p, legacyParameters.params)); owner.addAndMakeVisible (view); view.setScrollBarsShown (true, false); } + void resize (Rectangle size) + { + view.setBounds (size); + auto content = view.getViewedComponent(); + content->setSize (view.getMaximumVisibleWidth(), content->getHeight()); + } //============================================================================== GenericAudioProcessorEditor& owner; - LegacyAudioParametersWrapper juceParameters; + LegacyAudioParametersWrapper legacyParameters; Viewport view; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) @@ -535,7 +552,7 @@ struct GenericAudioProcessorEditor::Pimpl //============================================================================== -GenericAudioProcessorEditor::GenericAudioProcessorEditor (AudioProcessor* const p) +GenericAudioProcessorEditor::GenericAudioProcessorEditor (AudioProcessor& p) : AudioProcessorEditor (p), pimpl (new Pimpl (*this)) { setSize (pimpl->view.getViewedComponent()->getWidth() + pimpl->view.getVerticalScrollBar().getWidth(), @@ -551,7 +568,7 @@ void GenericAudioProcessorEditor::paint (Graphics& g) void GenericAudioProcessorEditor::resized() { - pimpl->view.setBounds (getLocalBounds()); + pimpl->resize (getLocalBounds()); } } // namespace juce diff --git a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h index 90a1eda0c8..8bd5880c71 100644 --- a/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h +++ b/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h @@ -39,17 +39,20 @@ namespace juce @tags{Audio} */ -class JUCE_API GenericAudioProcessorEditor : public AudioProcessorEditor +class JUCE_API GenericAudioProcessorEditor : public AudioProcessorEditor { public: //============================================================================== - GenericAudioProcessorEditor (AudioProcessor* owner); + GenericAudioProcessorEditor (AudioProcessor&); ~GenericAudioProcessorEditor() override; //============================================================================== void paint (Graphics&) override; void resized() override; + // This constructor has been changed to take a reference instead of a pointer + JUCE_DEPRECATED_WITH_BODY (GenericAudioProcessorEditor (AudioProcessor* p), : GenericAudioProcessorEditor (*p) {}) + private: //============================================================================== struct Pimpl;