mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
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
This commit is contained in:
parent
a9a0f6b92f
commit
15567c7150
8 changed files with 90 additions and 76 deletions
|
|
@ -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; }
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<int32> (d);
|
||||
}
|
||||
|
||||
inline uint16 getEventDataSize (const void* const d) noexcept
|
||||
inline uint16 getEventDataSize (const void* d) noexcept
|
||||
{
|
||||
return readUnaligned<uint16> (static_cast<const char*> (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<const uint8*> (newData), maxBytes);
|
||||
auto numBytes = MidiBufferHelpers::findActualEventLength (static_cast<const uint8*> (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<int32> (d, sampleNumber);
|
||||
writeUnaligned<uint16> (d + 4, static_cast<uint16> (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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<BooleanParameterComponent> (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<SwitchParameterComponent> (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<ChoiceParameterComponent> (processor, param);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything else can be represented as a slider.
|
||||
parameterComp.reset (new SliderParameterComponent (processor, param));
|
||||
parameterComp = std::make_unique<SliderParameterComponent> (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<int> 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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue