Browse Source

Update juce and fix wrong channel count

tags/2018-04-16
falkTX 8 years ago
parent
commit
ee7a5c6f19
69 changed files with 789 additions and 566 deletions
  1. +2
    -0
      libs/juce-plugin/JucePluginMain.cpp
  2. +16
    -5
      libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp
  3. +2
    -2
      libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h
  4. +12
    -2
      libs/juce/source/modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h
  5. +25
    -0
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp
  6. +6
    -0
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessage.h
  7. +2
    -2
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp
  8. +2
    -2
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp
  9. +1
    -2
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h
  10. +1
    -0
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp
  11. +3
    -2
      libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h
  12. +1
    -1
      libs/juce/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h
  13. +4
    -0
      libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp
  14. +1
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp
  15. +19
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp
  16. +4
    -1
      libs/juce/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp
  17. +11
    -3
      libs/juce/source/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h
  18. +1
    -1
      libs/juce/source/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp
  19. +9
    -4
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h
  20. +1
    -1
      libs/juce/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.h
  21. +14
    -0
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.cpp
  22. +4
    -0
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.h
  23. +0
    -126
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp
  24. +9
    -0
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
  25. +6
    -0
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
  26. +3
    -0
      libs/juce/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h
  27. +1
    -1
      libs/juce/source/modules/juce_core/containers/juce_Array.h
  28. +6
    -0
      libs/juce/source/modules/juce_core/containers/juce_OwnedArray.h
  29. +6
    -0
      libs/juce/source/modules/juce_core/containers/juce_ReferenceCountedArray.h
  30. +6
    -0
      libs/juce/source/modules/juce_core/containers/juce_SortedSet.h
  31. +1
    -1
      libs/juce/source/modules/juce_core/javascript/juce_Javascript.cpp
  32. +0
    -2
      libs/juce/source/modules/juce_core/native/java/AndroidRuntimePermissions.java
  33. +2
    -0
      libs/juce/source/modules/juce_core/native/java/JuceAppActivity.java
  34. +3
    -1
      libs/juce/source/modules/juce_core/native/juce_win32_Files.cpp
  35. +1
    -0
      libs/juce/source/modules/juce_core/system/juce_StandardHeader.h
  36. +0
    -6
      libs/juce/source/modules/juce_core/text/juce_CharPointer_ASCII.h
  37. +13
    -0
      libs/juce/source/modules/juce_core/text/juce_CharacterFunctions.cpp
  38. +3
    -0
      libs/juce/source/modules/juce_core/text/juce_CharacterFunctions.h
  39. +4
    -0
      libs/juce/source/modules/juce_core/text/juce_String.cpp
  40. +4
    -1
      libs/juce/source/modules/juce_core/text/juce_StringArray.h
  41. +18
    -20
      libs/juce/source/modules/juce_core/time/juce_Time.cpp
  42. +1
    -1
      libs/juce/source/modules/juce_core/zip/juce_ZipFile.cpp
  43. +14
    -14
      libs/juce/source/modules/juce_events/native/juce_linux_Messaging.cpp
  44. +2
    -2
      libs/juce/source/modules/juce_graphics/colour/juce_FillType.cpp
  45. +2
    -2
      libs/juce/source/modules/juce_graphics/images/juce_ImageCache.cpp
  46. +10
    -0
      libs/juce/source/modules/juce_graphics/juce_graphics.cpp
  47. +1
    -1
      libs/juce/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm
  48. +3
    -3
      libs/juce/source/modules/juce_graphics/native/juce_mac_Fonts.mm
  49. +12
    -5
      libs/juce/source/modules/juce_gui_basics/components/juce_Component.cpp
  50. +1
    -1
      libs/juce/source/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp
  51. +1
    -1
      libs/juce/source/modules/juce_gui_basics/drawables/juce_SVGParser.cpp
  52. +1
    -1
      libs/juce/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp
  53. +1
    -1
      libs/juce/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp
  54. +0
    -4
      libs/juce/source/modules/juce_gui_basics/juce_gui_basics.cpp
  55. +99
    -0
      libs/juce/source/modules/juce_gui_basics/layout/juce_Viewport.cpp
  56. +16
    -0
      libs/juce/source/modules/juce_gui_basics/layout/juce_Viewport.h
  57. +5
    -6
      libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp
  58. +258
    -283
      libs/juce/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp
  59. +69
    -19
      libs/juce/source/modules/juce_gui_basics/menus/juce_PopupMenu.h
  60. +1
    -1
      libs/juce/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h
  61. +1
    -1
      libs/juce/source/modules/juce_gui_basics/native/juce_ios_Windowing.mm
  62. +2
    -2
      libs/juce/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp
  63. +16
    -15
      libs/juce/source/modules/juce_gui_basics/native/juce_mac_MainMenu.mm
  64. +32
    -4
      libs/juce/source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm
  65. +2
    -2
      libs/juce/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp
  66. +1
    -1
      libs/juce/source/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp
  67. +1
    -1
      libs/juce/source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp
  68. +2
    -2
      libs/juce/source/modules/juce_gui_extra/misc/juce_ColourSelector.cpp
  69. +8
    -5
      libs/juce/source/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp

+ 2
- 0
libs/juce-plugin/JucePluginMain.cpp View File

@@ -37,3 +37,5 @@
#if ! JucePlugin_Build_Standalone
#include "modules/juce_audio_plugin_client/utility/juce_PluginUtilities.cpp"
#endif

#include "modules/juce_audio_processors/processors/juce_AudioProcessor_export.cpp"

+ 16
- 5
libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp View File

@@ -481,6 +481,17 @@ namespace FloatVectorHelpers
#endif
}
//==============================================================================
namespace
{
#if JUCE_USE_VDSP_FRAMEWORK
// This casts away constness to account for slightly different vDSP function signatures
// in OSX 10.8 SDK and below. Can be safely removed once those SDKs are obsolete.
template <typename ValueType>
ValueType* osx108sdkCompatibilityCast (const ValueType* arg) noexcept { return const_cast<ValueType*> (arg); }
#endif
}
//==============================================================================
void JUCE_CALLTYPE FloatVectorOperations::clear (float* dest, int num) noexcept
{
@@ -568,10 +579,10 @@ void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double amount, int
const Mode::ParallelType amountToAdd = Mode::load1 (amount);)
}
void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, float* src, float amount, int num) noexcept
void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src, float amount, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vsadd (src, 1, &amount, dest, 1, (vDSP_Length) num);
vDSP_vsadd (osx108sdkCompatibilityCast (src), 1, &amount, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] + amount, Mode::add (am, s),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
@@ -579,10 +590,10 @@ void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, float* src, float am
#endif
}
void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double* src, double amount, int num) noexcept
void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src, double amount, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vsaddD (src, 1, &amount, dest, 1, (vDSP_Length) num);
vDSP_vsaddD (osx108sdkCompatibilityCast (src), 1, &amount, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] + amount, Mode::add (am, s),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
@@ -990,7 +1001,7 @@ void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnab
void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport() noexcept
{
#if JUCE_USE_SSE_INTRINSICS
const int mxcsr = _mm_getcsr();
const unsigned int mxcsr = _mm_getcsr();
_mm_setcsr (mxcsr | 0x8040); // add the DAZ and FZ bits
#endif
}


+ 2
- 2
libs/juce/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h View File

@@ -66,10 +66,10 @@ public:
static void JUCE_CALLTYPE add (double* dest, double amountToAdd, int numValues) noexcept;
/** Adds a fixed value to each source value and stores it in the destination array. */
static void JUCE_CALLTYPE add (float* dest, float* src, float amount, int numValues) noexcept;
static void JUCE_CALLTYPE add (float* dest, const float* src, float amount, int numValues) noexcept;
/** Adds a fixed value to each source value and stores it in the destination array. */
static void JUCE_CALLTYPE add (double* dest, double* src, double amount, int numValues) noexcept;
static void JUCE_CALLTYPE add (double* dest, const double* src, double amount, int numValues) noexcept;
/** Adds the source values to the destination values. */
static void JUCE_CALLTYPE add (float* dest, const float* src, int numValues) noexcept;


+ 12
- 2
libs/juce/source/modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h View File

@@ -59,7 +59,6 @@ public:
countdown = 0;
}
//==============================================================================
/** Set a new target value. */
void setValue (FloatType newValue) noexcept
{
@@ -75,7 +74,6 @@ public:
}
}
//==============================================================================
/** Compute the next value. */
FloatType getNextValue() noexcept
{
@@ -87,6 +85,18 @@ public:
return currentValue;
}
/** Returns true if the current value is currently being interpolated. */
bool isSmoothing() const noexcept
{
return countdown > 0;
}
/** Returns the target value towards which the smoothed value is currently moving. */
FloatType getTargetValue() const noexcept
{
return target;
}
private:
//==============================================================================
FloatType currentValue, target, step;


+ 25
- 0
libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp View File

@@ -309,6 +309,31 @@ uint8* MidiMessage::allocateSpace (int bytes)
return preallocatedData.asBytes;
}
String MidiMessage::getDescription() const
{
if (isNoteOn()) return "Note on " + MidiMessage::getMidiNoteName (getNoteNumber(), true, true, 3) + " Velocity " + String (getVelocity()) + " Channel " + String (getChannel());
if (isNoteOff()) return "Note off " + MidiMessage::getMidiNoteName (getNoteNumber(), true, true, 3) + " Velocity " + String (getVelocity()) + " Channel " + String (getChannel());
if (isProgramChange()) return "Program change " + String (getProgramChangeNumber()) + " Channel " + String (getChannel());
if (isPitchWheel()) return "Pitch wheel " + String (getPitchWheelValue()) + " Channel " + String (getChannel());
if (isAftertouch()) return "Aftertouch " + MidiMessage::getMidiNoteName (getNoteNumber(), true, true, 3) + ": " + String (getAfterTouchValue()) + " Channel " + String (getChannel());
if (isChannelPressure()) return "Channel pressure " + String (getChannelPressureValue()) + " Channel " + String (getChannel());
if (isAllNotesOff()) return "All notes off Channel " + String (getChannel());
if (isAllSoundOff()) return "All sound off Channel " + String (getChannel());
if (isMetaEvent()) return "Meta event";
if (isController())
{
String name (MidiMessage::getControllerName (getControllerNumber()));
if (name.isEmpty())
name = String (getControllerNumber());
return "Controller " + name + ": " + String (getControllerValue()) + " Channel " + String (getChannel());
}
return String::toHexString (getRawData(), getRawDataSize());
}
int MidiMessage::getChannel() const noexcept
{
const uint8* const data = getRawData();


+ 6
- 0
libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessage.h View File

@@ -125,6 +125,12 @@ public:
*/
int getRawDataSize() const noexcept { return size; }
//==============================================================================
/** Returns a human-readable description of the midi message as a string,
for example "Note On C#3 Velocity 120 Channel 1".
*/
String getDescription() const;
//==============================================================================
/** Returns the timestamp associated with this message.


+ 2
- 2
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp View File

@@ -324,7 +324,7 @@ void MPEInstrument::noteOff (int midiChannel,
int midiNoteNumber,
MPEValue midiNoteOffVelocity)
{
if (notes.empty() || ! isNoteChannel (midiChannel))
if (notes.isEmpty() || ! isNoteChannel (midiChannel))
return;
const ScopedLock sl (lock);
@@ -375,7 +375,7 @@ void MPEInstrument::updateDimension (int midiChannel, MPEDimension& dimension, M
{
dimension.lastValueReceivedOnChannel[midiChannel - 1] = value;
if (notes.empty())
if (notes.isEmpty())
return;
if (MPEZone* zone = zoneLayout.getZoneByMasterChannel (midiChannel))


+ 2
- 2
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp View File

@@ -103,7 +103,7 @@ void MPESynthesiserBase::renderNextBlock (AudioBuffer<floatType>& outputAudio,
int midiEventPos;
MidiMessage m;
const ScopedLock sl (renderAudioLock);
const ScopedLock sl (noteStateLock);
while (numSamples > 0)
{
@@ -147,7 +147,7 @@ void MPESynthesiserBase::setCurrentPlaybackSampleRate (const double newRate)
{
if (sampleRate != newRate)
{
const ScopedLock sl (renderAudioLock);
const ScopedLock sl (noteStateLock);
instrument->releaseAllNotes();
sampleRate = newRate;
}


+ 1
- 2
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h View File

@@ -179,11 +179,10 @@ protected:
//==============================================================================
/** @internal */
ScopedPointer<MPEInstrument> instrument;
/** @internal */
CriticalSection renderAudioLock;
private:
//==============================================================================
CriticalSection noteStateLock;
double sampleRate;
int minimumSubBlockSize;


+ 1
- 0
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp View File

@@ -34,6 +34,7 @@ MPEZoneLayout::MPEZoneLayout (const MPEZoneLayout& other)
MPEZoneLayout& MPEZoneLayout::operator= (const MPEZoneLayout& other)
{
zones = other.zones;
listeners.call (&MPEZoneLayout::Listener::zoneLayoutChanged, *this);
return *this;
}


+ 3
- 2
libs/juce/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h View File

@@ -100,8 +100,9 @@ public:
/** Returns the current number of MPE zones. */
int getNumZones() const noexcept;
/** Returns a pointer to the MPE zone at the given index,
or nullptr if there is no such zone.
/** Returns a pointer to the MPE zone at the given index, or nullptr if there
is no such zone. Zones are sorted by insertion order (most recently added
zone last).
*/
MPEZone* getZoneByIndex (int index) const noexcept;


+ 1
- 1
libs/juce/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h View File

@@ -30,7 +30,7 @@
/**
A type of AudioSource that takes an input source and changes its sample rate.
@see AudioSource
@see AudioSource, LagrangeInterpolator, CatmullRomInterpolator
*/
class JUCE_API ResamplingAudioSource : public AudioSource
{


+ 4
- 0
libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp View File

@@ -171,6 +171,10 @@ namespace CoreMidiHelpers
static StringArray findDevices (const bool forInput)
{
// It seems that OSX can be a bit picky about the thread that's first used to
// search for devices. It's safest to use the message thread for calling this.
jassert (MessageManager::getInstance()->isThisTheMessageThread());
const ItemCount num = forInput ? MIDIGetNumberOfSources()
: MIDIGetNumberOfDestinations();
StringArray s;


+ 1
- 1
libs/juce/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp View File

@@ -29,7 +29,7 @@ namespace FlacNamespace
#if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE)
#undef VERSION
#define VERSION "1.2.1"
#define VERSION "1.3.1"
#define FLAC__NO_DLL 1


+ 19
- 1
libs/juce/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp View File

@@ -646,6 +646,24 @@ namespace WavFileHelpers
return true;
}
static String getStringFromWindows1252Codepage (const uint8* data, size_t num)
{
HeapBlock<juce_wchar> unicode (num + 1);
for (size_t i = 0; i < num; ++i)
unicode[i] = CharacterFunctions::getUnicodeCharFromWindows1252Codepage (data[i]);
unicode[num] = 0;
return CharPointer_UTF32 (unicode);
}
static String getStringFromData (const MemoryBlock& mb)
{
return CharPointer_UTF8::isValidString ((const char*) mb.getData(), (int) mb.getSize())
? mb.toString()
: getStringFromWindows1252Codepage ((const uint8*) mb.getData(), mb.getSize());
}
static void addToMetadata (StringPairArray& values, InputStream& input, int64 chunkEnd)
{
while (input.getPosition() < chunkEnd)
@@ -664,7 +682,7 @@ namespace WavFileHelpers
{
MemoryBlock mb;
input.readIntoMemoryBlock (mb, (ssize_t) infoLength);
values.set (types[i], mb.toString());
values.set (types[i], getStringFromData (mb));
break;
}
}


+ 4
- 1
libs/juce/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp View File

@@ -166,6 +166,9 @@ public:
checkCoInitialiseCalled();
clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,
startSampleInFile, numSamples, lengthInSamples);
const int stride = numChannels * sizeof (int16);
while (numSamples > 0)
@@ -297,7 +300,7 @@ private:
sampleRate = inputFormat->nSamplesPerSec;
numChannels = inputFormat->nChannels;
bitsPerSample = inputFormat->wBitsPerSample;
bitsPerSample = inputFormat->wBitsPerSample != 0 ? inputFormat->wBitsPerSample : 16;
lengthInSamples = (lengthInNanoseconds * (int) sampleRate) / 10000000;
}
}


+ 11
- 3
libs/juce/source/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h View File

@@ -79,9 +79,17 @@ public:
jassert (processor != nullptr); // Your createPluginFilter() function must return a valid object!
AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::wrapperType_Undefined);
processor->setPlayConfigDetails (JucePlugin_MaxNumInputChannels,
JucePlugin_MaxNumOutputChannels,
44100, 512);
// try to disable sidechain and aux buses
const int numInBuses = processor->busArrangement.inputBuses.size();
const int numOutBuses = processor->busArrangement.inputBuses.size();
for (int busIdx = 1; busIdx < numInBuses; ++busIdx)
processor->setPreferredBusArrangement (true, busIdx, AudioChannelSet::disabled());
for (int busIdx = 1; busIdx < numOutBuses; ++busIdx)
processor->setPreferredBusArrangement (false, busIdx, AudioChannelSet::disabled());
processor->setRateAndBufferSizeDetails(44100, 512);
}
virtual void deletePlugin()


+ 1
- 1
libs/juce/source/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp View File

@@ -258,7 +258,7 @@ public:
info.stepCount = 1;
info.defaultNormalizedValue = 0.0f;
info.unitId = Vst::kRootUnitId;
info.flags = Vst::ParameterInfo::kIsBypass;
info.flags = Vst::ParameterInfo::kIsBypass | Vst::ParameterInfo::kCanAutomate;
}
virtual ~BypassParam() {}


+ 9
- 4
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_PluginHostType.h View File

@@ -45,6 +45,7 @@ public:
Ardour,
CakewalkSonar8,
CakewalkSonarGeneric,
DaVinciResolve,
DigidesignProTools,
DigitalPerformer,
FinalCut,
@@ -84,18 +85,21 @@ public:
bool isAbletonLive() const noexcept { return type == AbletonLive6 || type == AbletonLive7 || type == AbletonLive8 || type == AbletonLiveGeneric; }
bool isAdobeAudition() const noexcept { return type == AdobeAudition; }
bool isArdour() const noexcept { return type == Ardour; }
bool isDigitalPerformer() const noexcept { return type == DigitalPerformer; }
bool isCubase() const noexcept { return type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase5Bridged || type == SteinbergCubase6 || type == SteinbergCubase7 || type == SteinbergCubase8 || type == SteinbergCubaseGeneric; }
bool isCubase7orLater() const noexcept { return isCubase() && ! (type == SteinbergCubase4 || type == SteinbergCubase5 || type == SteinbergCubase6); }
bool isCubaseBridged() const noexcept { return type == SteinbergCubase5Bridged; }
bool isLogic() const noexcept { return type == AppleLogic; }
bool isDaVinciResolve() const noexcept { return type == DaVinciResolve; }
bool isDigitalPerformer() const noexcept { return type == DigitalPerformer; }
bool isFinalCut() const noexcept { return type == FinalCut; }
bool isFruityLoops() const noexcept { return type == FruityLoops; }
bool isLogic() const noexcept { return type == AppleLogic; }
bool isNuendo() const noexcept { return type == SteinbergNuendo3 || type == SteinbergNuendo4 || type == SteinbergNuendo5 || type == SteinbergNuendoGeneric; }
bool isPremiere() const noexcept { return type == AdobePremierePro; }
bool isProTools() const noexcept { return type == DigidesignProTools; }
bool isPyramix() const noexcept { return type == MergingPyramix; }
bool isReceptor() const noexcept { return type == MuseReceptorGeneric; }
bool isReaper() const noexcept { return type == Reaper; }
bool isRenoise() const noexcept { return type == Renoise; }
bool isSamplitude() const noexcept { return type == MagixSamplitude; }
bool isSonar() const noexcept { return type == CakewalkSonar8 || type == CakewalkSonarGeneric; }
bool isSteinbergTestHost() const noexcept { return type == SteinbergTestHost; }
@@ -106,8 +110,6 @@ public:
bool isWaveBurner() const noexcept { return type == WaveBurner; }
bool isWavelab() const noexcept { return isWavelabLegacy() || type == SteinbergWavelab7 || type == SteinbergWavelab8 || type == SteinbergWavelabGeneric; }
bool isWavelabLegacy() const noexcept { return type == SteinbergWavelab5 || type == SteinbergWavelab6; }
bool isRenoise() const noexcept { return type == Renoise; }
bool isProTools() const noexcept { return type == DigidesignProTools; }
//==============================================================================
const char* getHostDescription() const noexcept
@@ -123,6 +125,7 @@ public:
case AppleLogic: return "Apple Logic";
case CakewalkSonar8: return "Cakewalk Sonar 8";
case CakewalkSonarGeneric: return "Cakewalk Sonar";
case DaVinciResolve: return "DaVinci Resolve";
case DigidesignProTools: return "ProTools";
case DigitalPerformer: return "DigitalPerformer";
case FinalCut: return "Final Cut";
@@ -203,6 +206,7 @@ private:
if (hostPath.containsIgnoreCase ("Tracktion 3")) return Tracktion3;
if (hostFilename.containsIgnoreCase ("Tracktion")) return TracktionGeneric;
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
#elif JUCE_WINDOWS
if (hostFilename.containsIgnoreCase ("Live 6.")) return AbletonLive6;
@@ -241,6 +245,7 @@ private:
if (hostPath.containsIgnoreCase ("Merging Technologies")) return MergingPyramix;
if (hostFilename.startsWithIgnoreCase ("Sam")) return MagixSamplitude;
if (hostFilename.containsIgnoreCase ("Renoise")) return Renoise;
if (hostFilename.containsIgnoreCase ("Resolve")) return DaVinciResolve;
#elif JUCE_LINUX
if (hostFilename.containsIgnoreCase ("Ardour")) return Ardour;


+ 1
- 1
libs/juce/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.h View File

@@ -30,7 +30,7 @@
/**
The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc.
@see AudioFormatManager
@see AudioPluginFormatManager
*/
class JUCE_API AudioPluginFormat
{


+ 14
- 0
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.cpp View File

@@ -135,6 +135,20 @@ AudioChannelSet::ChannelType AudioChannelSet::getTypeOfChannel (int index) const
return static_cast<ChannelType> (bit);
}
int AudioChannelSet::getChannelIndexForType (AudioChannelSet::ChannelType type) const noexcept
{
int idx = 0;
for (int bit = channels.findNextSetBit (0); bit >= 0; bit = channels.findNextSetBit (bit + 1))
{
if (static_cast<ChannelType> (bit) == type)
return idx;
idx++;
}
return -1;
}
Array<AudioChannelSet::ChannelType> AudioChannelSet::getChannelTypes() const
{
Array<ChannelType> result;


+ 4
- 0
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.h View File

@@ -166,6 +166,10 @@ public:
/** Returns the type of one of the channels in the set, by index. */
ChannelType getTypeOfChannel (int channelIndex) const noexcept;
/** Returns the index for a particular channel-type.
Will return -1 if the this set does not contain a channel of this type. */
int getChannelIndexForType (ChannelType type) const noexcept;
/** Returns a string containing a whitespace-separated list of speaker types
corresponding to each channel. For example in a 5.1 arrangement,
the string may be "L R C Lfe Ls Rs". If the speaker arrangement is unknown,


+ 0
- 126
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp View File

@@ -22,48 +22,6 @@
==============================================================================
*/
static ThreadLocalValue<AudioProcessor::WrapperType> wrapperTypeBeingCreated;
void JUCE_CALLTYPE AudioProcessor::setTypeOfNextNewPlugin (AudioProcessor::WrapperType type)
{
wrapperTypeBeingCreated = type;
}
AudioProcessor::AudioProcessor()
: wrapperType (wrapperTypeBeingCreated.get()),
playHead (nullptr),
currentSampleRate (0),
blockSize (0),
latencySamples (0),
#if JUCE_DEBUG
textRecursionCheck (false),
#endif
suspended (false),
nonRealtime (false),
processingPrecision (singlePrecision)
{
#ifdef JucePlugin_PreferredChannelConfigurations
const short channelConfigs[][2] = { JucePlugin_PreferredChannelConfigurations };
#else
const short channelConfigs[][2] = { {2, 2} };
#endif
#if ! JucePlugin_IsMidiEffect
#if ! JucePlugin_IsSynth
busArrangement.inputBuses.add (AudioProcessorBus ("Input", AudioChannelSet::canonicalChannelSet (channelConfigs[0][0])));
#endif
busArrangement.outputBuses.add (AudioProcessorBus ("Output", AudioChannelSet::canonicalChannelSet (channelConfigs[0][1])));
#ifdef JucePlugin_PreferredChannelConfigurations
#if ! JucePlugin_IsSynth
AudioProcessor::setPreferredBusArrangement (true, 0, AudioChannelSet::stereo());
#endif
AudioProcessor::setPreferredBusArrangement (false, 0, AudioChannelSet::stereo());
#endif
#endif
updateSpeakerFormatStrings();
}
AudioProcessor::~AudioProcessor()
{
#if ! JUCE_AUDIO_PROCESSOR_NO_GUI
@@ -425,90 +383,6 @@ bool AudioProcessor::isInputChannelStereoPair (int index) const { return isS
bool AudioProcessor::isOutputChannelStereoPair (int index) const { return isStereoPair (busArrangement.outputBuses, index); }
//==============================================================================
bool AudioProcessor::setPreferredBusArrangement (bool isInput, int busIndex, const AudioChannelSet& preferredSet)
{
const int oldNumInputs = getTotalNumInputChannels();
const int oldNumOutputs = getTotalNumOutputChannels();
Array<AudioProcessorBus>& buses = isInput ? busArrangement.inputBuses : busArrangement.outputBuses;
const int numBuses = buses.size();
if (! isPositiveAndBelow (busIndex, numBuses))
return false;
AudioProcessorBus& bus = buses.getReference (busIndex);
#ifdef JucePlugin_PreferredChannelConfigurations
// the user is using the deprecated way to specify channel configurations
if (numBuses > 0 && busIndex == 0)
{
const short channelConfigs[][2] = { JucePlugin_PreferredChannelConfigurations };
const int numChannelConfigs = sizeof (channelConfigs) / sizeof (*channelConfigs);
// we need the main bus in the opposite direction
Array<AudioProcessorBus>& oppositeBuses = isInput ? busArrangement.outputBuses : busArrangement.inputBuses;
AudioProcessorBus* oppositeBus = (busIndex < oppositeBuses.size()) ? &oppositeBuses.getReference (0) : nullptr;
// get the target number of channels
const int mainBusNumChannels = preferredSet.size();
const int mainBusOppositeChannels = (oppositeBus != nullptr) ? oppositeBus->channels.size() : 0;
const int dir = isInput ? 0 : 1;
// find a compatible channel configuration on the opposite bus which is the closest match
// to the current number of channels on that bus
int distance = std::numeric_limits<int>::max();
int bestConfiguration = -1;
for (int i = 0; i < numChannelConfigs; ++i)
{
// is the configuration compatible with the preferred set
if (channelConfigs[i][dir] == mainBusNumChannels)
{
const int configChannels = channelConfigs[i][dir^1];
const int channelDifference = std::abs (configChannels - mainBusOppositeChannels);
if (channelDifference < distance)
{
distance = channelDifference;
bestConfiguration = configChannels;
// we can exit if we found a perfect match
if (distance == 0)
break;
}
}
}
// unable to find a good configuration
if (bestConfiguration == -1)
return false;
// did the number of channels change on the opposite bus?
if (mainBusOppositeChannels != bestConfiguration && oppositeBus != nullptr)
{
// if the channels on the opposite bus are the same as the preferred set
// then also copy over the layout information. If not, then assume
// a cononical channel layout
if (bestConfiguration == mainBusNumChannels)
oppositeBus->channels = preferredSet;
else
oppositeBus->channels = AudioChannelSet::canonicalChannelSet (bestConfiguration);
}
}
#endif
bus.channels = preferredSet;
if (oldNumInputs != getTotalNumInputChannels() || oldNumOutputs != getTotalNumOutputChannels())
{
updateSpeakerFormatStrings();
numChannelsChanged();
}
return true;
}
void AudioProcessor::disableNonMainBuses (bool isInput)
{
const Array<AudioProcessorBus>& buses = (isInput ? busArrangement.inputBuses : busArrangement.outputBuses);


+ 9
- 0
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp View File

@@ -1126,6 +1126,15 @@ bool AudioProcessorGraph::removeNode (const uint32 nodeId)
return false;
}
bool AudioProcessorGraph::removeNode (Node* node)
{
if (node != nullptr)
return removeNode (node->nodeId);
jassertfalse;
return false;
}
//==============================================================================
const AudioProcessorGraph::Connection* AudioProcessorGraph::getConnectionBetween (const uint32 sourceNodeId,
const int sourceChannelIndex,


+ 6
- 0
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h View File

@@ -183,6 +183,12 @@ public:
*/
bool removeNode (uint32 nodeId);
/** Deletes a node within the graph which has the specified ID.
This will also delete any connections that are attached to this node.
*/
bool removeNode (Node* node);
//==============================================================================
/** Returns the number of connections in the graph. */
int getNumConnections() const { return connections.size(); }


+ 3
- 0
libs/juce/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h View File

@@ -149,6 +149,7 @@ public:
private:
struct Pimpl;
friend struct ContainerDeletePolicy<Pimpl>;
ScopedPointer<Pimpl> pimpl;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SliderAttachment)
};
@@ -172,6 +173,7 @@ public:
private:
struct Pimpl;
friend struct ContainerDeletePolicy<Pimpl>;
ScopedPointer<Pimpl> pimpl;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComboBoxAttachment)
};
@@ -195,6 +197,7 @@ public:
private:
struct Pimpl;
friend struct ContainerDeletePolicy<Pimpl>;
ScopedPointer<Pimpl> pimpl;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonAttachment)
};


+ 1
- 1
libs/juce/source/modules/juce_core/containers/juce_Array.h View File

@@ -223,7 +223,7 @@ public:
}
/** Returns true if the array is empty, false otherwise. */
inline bool empty() const noexcept
inline bool isEmpty() const noexcept
{
return size() == 0;
}


+ 6
- 0
libs/juce/source/modules/juce_core/containers/juce_OwnedArray.h View File

@@ -126,6 +126,12 @@ public:
return numUsed;
}
/** Returns true if the array is empty, false otherwise. */
inline bool isEmpty() const noexcept
{
return size() == 0;
}
/** Returns a pointer to the object at this index in the array.
If the index is out-of-range, this will return a null pointer, (and


+ 6
- 0
libs/juce/source/modules/juce_core/containers/juce_ReferenceCountedArray.h View File

@@ -149,6 +149,12 @@ public:
return numUsed;
}
/** Returns true if the array is empty, false otherwise. */
inline bool isEmpty() const noexcept
{
return size() == 0;
}
/** Returns a pointer to the object at this index in the array.
If the index is out-of-range, this will return a null pointer, (and


+ 6
- 0
libs/juce/source/modules/juce_core/containers/juce_SortedSet.h View File

@@ -136,6 +136,12 @@ public:
return data.size();
}
/** Returns true if the set is empty, false otherwise. */
inline bool isEmpty() const noexcept
{
return size() == 0;
}
/** Returns one of the elements in the set.
If the index passed in is beyond the range of valid elements, this


+ 1
- 1
libs/juce/source/modules/juce_core/javascript/juce_Javascript.cpp View File

@@ -1362,7 +1362,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
{
ScopedPointer<FunctionCall> f (new FunctionCall (location));
f->object = new UnqualifiedName (location, "typeof");
f->arguments.add (parseExpression());
f->arguments.add (parseUnary());
return f.release();
}


+ 0
- 2
libs/juce/source/modules/juce_core/native/java/AndroidRuntimePermissions.java View File

@@ -1,5 +1,3 @@
private native void androidRuntimePermissionsCallback (boolean permissionWasGranted, long ptrToCallback);
@Override
public void onRequestPermissionsResult (int permissionID, String permissions[], int[] grantResults)
{


+ 2
- 0
libs/juce/source/modules/juce_core/native/java/JuceAppActivity.java View File

@@ -136,6 +136,8 @@ public class JuceAppActivity extends Activity
}
}
private native void androidRuntimePermissionsCallback (boolean permissionWasGranted, long ptrToCallback);
$$JuceAndroidRuntimePermissionsCode$$ // If you get an error here, you need to re-save your project with the introjucer!
//==============================================================================


+ 3
- 1
libs/juce/source/modules/juce_core/native/juce_win32_Files.cpp View File

@@ -524,7 +524,9 @@ bool File::isOnHardDisk() const
if (fullPath.toLowerCase()[0] <= 'b' && fullPath[1] == ':')
return n != DRIVE_REMOVABLE;
return n != DRIVE_CDROM && n != DRIVE_REMOTE;
return n != DRIVE_CDROM
&& n != DRIVE_REMOTE
&& n != DRIVE_NO_ROOT_DIR;
}
bool File::isOnRemovableDrive() const


+ 1
- 0
libs/juce/source/modules/juce_core/system/juce_StandardHeader.h View File

@@ -50,6 +50,7 @@
//==============================================================================
#include <memory>
#include <vector> // included before platform defs to provide a definition of _LIBCPP_VERSION
#include "juce_CompilerSupport.h"


+ 0
- 6
libs/juce/source/modules/juce_core/text/juce_CharPointer_ASCII.h View File

@@ -215,12 +215,6 @@ public:
CharacterFunctions::copyAll (*this, src);
}
/** Copies a source string to this pointer, advancing this pointer as it goes. */
void writeAll (const CharPointer_ASCII src) noexcept
{
strcpy (data, src.data);
}
/** Copies a source string to this pointer, advancing this pointer as it goes.
The maxDestBytes parameter specifies the maximum number of bytes that can be written
to the destination buffer before stopping.


+ 13
- 0
libs/juce/source/modules/juce_core/text/juce_CharacterFunctions.cpp View File

@@ -162,3 +162,16 @@ double CharacterFunctions::mulexp10 (const double value, int exponent) noexcept
return negative ? (value / result) : (value * result);
}
juce_wchar CharacterFunctions::getUnicodeCharFromWindows1252Codepage (const uint8 c) noexcept
{
if (c < 0x80 || c >= 0xa0)
return (juce_wchar) c;
static const uint16 lookup[] = { 0x20AC, 0x0007, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0007, 0x017D, 0x0007,
0x0007, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0007, 0x017E, 0x0178 };
return (juce_wchar) lookup[c - 0x80];
}

+ 3
- 0
libs/juce/source/modules/juce_core/text/juce_CharacterFunctions.h View File

@@ -123,6 +123,9 @@ public:
/** Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legal hex digit. */
static int getHexDigitValue (juce_wchar digit) noexcept;
/** Converts a byte of Windows 1252 codepage to unicode. */
static juce_wchar getUnicodeCharFromWindows1252Codepage (uint8 windows1252Char) noexcept;
//==============================================================================
/** Parses a character string to read a floating-point number.
Note that this will advance the pointer that is passed in, leaving it at


+ 4
- 0
libs/juce/source/modules/juce_core/text/juce_String.cpp View File

@@ -1387,6 +1387,10 @@ String String::replaceCharacter (const juce_wchar charToReplace, const juce_wcha
String String::replaceCharacters (StringRef charactersToReplace, StringRef charactersToInsertInstead) const
{
// Each character in the first string must have a matching one in the
// second, so the two strings must be the same length.
jassert (charactersToReplace.length() == charactersToInsertInstead.length());
StringCreationHelper builder (text);
for (;;)


+ 4
- 1
libs/juce/source/modules/juce_core/text/juce_StringArray.h View File

@@ -118,7 +118,10 @@ public:
//==============================================================================
/** Returns the number of strings in the array */
inline int size() const noexcept { return strings.size(); };
inline int size() const noexcept { return strings.size(); }
/** Returns true if the array is empty, false otherwise. */
inline bool isEmpty() const noexcept { return size() == 0; }
/** Returns one of the strings from the array.


+ 18
- 20
libs/juce/source/modules/juce_core/time/juce_Time.cpp View File

@@ -136,15 +136,16 @@ namespace TimeHelpers
static inline int daysFromJan1 (int year, int month) noexcept
{
const short dayOfYear[] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
const short dayOfYear[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
return dayOfYear [(isLeapYear (year) ? 12 : 0) + month];
}
static inline int64 daysFromYear0 (int year) noexcept
{
return 365 * (year - 1) + (year / 400) - (year / 100) + (year / 4);
--year;
return 365 * year + (year / 400) - (year / 100) + (year / 4);
}
static inline int64 daysFrom1970 (int year) noexcept
@@ -213,18 +214,9 @@ Time::Time (const int year,
t.tm_sec = seconds;
t.tm_isdst = -1;
const int64 time = useLocalTime ? (int64) mktime (&t)
: TimeHelpers::mktime_utc (t);
if (time >= 0)
{
millisSinceEpoch = 1000 * time + milliseconds;
}
else
{
jassertfalse; // trying to create a date that is beyond the range that mktime supports!
millisSinceEpoch = 0;
}
millisSinceEpoch = 1000 * (useLocalTime ? (int64) mktime (&t)
: TimeHelpers::mktime_utc (t))
+ milliseconds;
}
Time::~Time() noexcept
@@ -458,8 +450,8 @@ String Time::getUTCOffsetString (bool includeSemiColon) const
String Time::toISO8601 (bool includeDividerCharacters) const
{
return String::formatted (includeDividerCharacters ? "%04d-%02d-%02dT%02d:%02d:%02.03f"
: "%04d%02d%02dT%02d%02d%02.03f",
return String::formatted (includeDividerCharacters ? "%04d-%02d-%02dT%02d:%02d:%06.03f"
: "%04d%02d%02dT%02d%02d%06.03f",
getYear(),
getMonth() + 1,
getDayOfMonth(),
@@ -542,9 +534,7 @@ Time Time::fromISO8601 (StringRef iso) noexcept
return Time();
}
Time result (year, month - 1, day, hours, minutes, 0, 0, false);
result.millisSinceEpoch += milliseconds;
return result;
return Time (year, month - 1, day, hours, minutes, 0, milliseconds, false);
}
String Time::getMonthName (const bool threeLetterVersion) const
@@ -661,6 +651,14 @@ public:
expect (Time::fromISO8601 ("2016-02-16T15:03:57.999-02:30") == Time (2016, 1, 16, 17, 33, 57, 999, false));
expect (Time::fromISO8601 ("20160216T150357.999-0230") == Time (2016, 1, 16, 17, 33, 57, 999, false));
expect (Time (1970, 0, 1, 0, 0, 0, 0, false) == Time (0));
expect (Time (2106, 1, 7, 6, 28, 15, 0, false) == Time (4294967295000));
expect (Time (2007, 10, 7, 1, 7, 20, 0, false) == Time (1194397640000));
expect (Time (2038, 0, 19, 3, 14, 7, 0, false) == Time (2147483647000));
expect (Time (2016, 2, 7, 11, 20, 8, 0, false) == Time (1457349608000));
expect (Time (1969, 11, 31, 23, 59, 59, 0, false) == Time (-1000));
expect (Time (1901, 11, 13, 20, 45, 53, 0, false) == Time (-2147483647000));
expect (Time (1982, 1, 1, 12, 0, 0, 0, true) + RelativeTime::days (365) == Time (1983, 1, 1, 12, 0, 0, 0, true));
expect (Time (1970, 1, 1, 12, 0, 0, 0, true) + RelativeTime::days (365) == Time (1971, 1, 1, 12, 0, 0, 0, true));
expect (Time (2038, 1, 1, 12, 0, 0, 0, true) + RelativeTime::days (365) == Time (2039, 1, 1, 12, 0, 0, 0, true));


+ 1
- 1
libs/juce/source/modules/juce_core/zip/juce_ZipFile.cpp View File

@@ -60,7 +60,7 @@ private:
const int day = date & 31;
const int hours = time >> 11;
const int minutes = (time >> 5) & 63;
const int seconds = (time & 31) << 1;
const int seconds = (int) ((time & 31) << 1);
return Time (year, month, day, hours, minutes, seconds);
}


+ 14
- 14
libs/juce/source/modules/juce_events/native/juce_linux_Messaging.cpp View File

@@ -357,13 +357,13 @@ void MessageManager::doPlatformSpecificShutdown()
bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message)
{
if (LinuxErrorHandling::errorOccurred)
return false;
if (InternalMessageQueue* const queue = InternalMessageQueue::getInstanceWithoutCreating())
if (! LinuxErrorHandling::errorOccurred)
{
queue->postMessage (message);
return true;
if (InternalMessageQueue* queue = InternalMessageQueue::getInstanceWithoutCreating())
{
queue->postMessage (message);
return true;
}
}
return false;
@@ -389,16 +389,16 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMes
break;
}
InternalMessageQueue* const queue = InternalMessageQueue::getInstanceWithoutCreating();
jassert (queue != nullptr);
if (queue->dispatchNextEvent())
return true;
if (InternalMessageQueue* queue = InternalMessageQueue::getInstanceWithoutCreating())
{
if (queue->dispatchNextEvent())
return true;
if (returnIfNoPendingMessages)
break;
if (returnIfNoPendingMessages)
break;
queue->sleepUntilEvent (2000);
queue->sleepUntilEvent (2000);
}
}
return false;


+ 2
- 2
libs/juce/source/modules/juce_graphics/colour/juce_FillType.cpp View File

@@ -104,7 +104,7 @@ bool FillType::operator!= (const FillType& other) const
void FillType::setColour (Colour newColour) noexcept
{
gradient = nullptr;
image = Image::null;
image = Image();
colour = newColour;
}
@@ -116,7 +116,7 @@ void FillType::setGradient (const ColourGradient& newGradient)
}
else
{
image = Image::null;
image = Image();
gradient = new ColourGradient (newGradient);
colour = Colours::black;
}


+ 2
- 2
libs/juce/source/modules/juce_graphics/images/juce_ImageCache.cpp View File

@@ -47,7 +47,7 @@ public:
return item->image;
}
return Image::null;
return Image();
}
void addImageToCache (const Image& image, const int64 hashCode)
@@ -128,7 +128,7 @@ Image ImageCache::getFromHashCode (const int64 hashCode)
if (Pimpl::getInstanceWithoutCreating() != nullptr)
return Pimpl::getInstanceWithoutCreating()->getFromHashCode (hashCode);
return Image::null;
return Image();
}
void ImageCache::addImageToCache (const Image& image, const int64 hashCode)


+ 10
- 0
libs/juce/source/modules/juce_graphics/juce_graphics.cpp View File

@@ -44,6 +44,12 @@
#import <QuartzCore/QuartzCore.h>
#elif JUCE_WINDOWS
// get rid of some warnings in Window's own headers
#ifdef JUCE_MSVC
#pragma warning (push)
#pragma warning (disable : 4458)
#endif
#if JUCE_MINGW && JUCE_USE_DIRECTWRITE
#warning "DirectWrite not currently implemented with mingw..."
#undef JUCE_USE_DIRECTWRITE
@@ -62,6 +68,10 @@
#include <malloc.h>
#endif
#ifdef JUCE_MSVC
#pragma warning (pop)
#endif
#elif JUCE_IOS
#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>


+ 1
- 1
libs/juce/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm View File

@@ -863,7 +863,7 @@ Image juce_loadWithCoreImage (InputStream& input)
}
}
return Image::null;
return Image();
}
#endif


+ 3
- 3
libs/juce/source/modules/juce_graphics/native/juce_mac_Fonts.mm View File

@@ -245,9 +245,9 @@ namespace CoreTextTypeLayout
{
switch (text.getReadingDirection())
{
case AttributedString::ReadingDirection::rightToLeft: return kCTWritingDirectionRightToLeft;
case AttributedString::ReadingDirection::leftToRight: return kCTWritingDirectionLeftToRight;
default: return kCTWritingDirectionNatural;
case AttributedString::rightToLeft: return kCTWritingDirectionRightToLeft;
case AttributedString::leftToRight: return kCTWritingDirectionLeftToRight;
default: return kCTWritingDirectionNatural;
}
}


+ 12
- 5
libs/juce/source/modules/juce_gui_basics/components/juce_Component.cpp View File

@@ -438,6 +438,15 @@ struct Component::ComponentHelpers
return Desktop::getInstance().getDisplays().getMainDisplay().userArea;
}
static void releaseAllCachedImageResources (Component& c)
{
if (CachedComponentImage* cached = c.getCachedComponentImage())
cached->releaseResources();
for (int i = c.getNumChildComponents(); --i >= 0;)
releaseAllCachedImageResources (*c.getChildComponent (i));
}
};
//==============================================================================
@@ -528,8 +537,7 @@ void Component::setVisible (bool shouldBeVisible)
if (! shouldBeVisible)
{
if (cachedImage != nullptr)
cachedImage->releaseResources();
ComponentHelpers::releaseAllCachedImageResources (*this);
if (currentlyFocusedComponent == this || isParentOf (currentlyFocusedComponent))
{
@@ -813,7 +821,7 @@ public:
bool invalidateAll() override { validArea.clear(); return true; }
bool invalidate (const Rectangle<int>& area) override { validArea.subtract (area); return true; }
void releaseResources() override { image = Image::null; }
void releaseResources() override { image = Image(); }
private:
Image image;
@@ -1547,8 +1555,7 @@ Component* Component::removeChildComponent (const int index, bool sendParentEven
childComponentList.remove (index);
child->parentComponent = nullptr;
if (child->cachedImage != nullptr)
child->cachedImage->releaseResources();
ComponentHelpers::releaseAllCachedImageResources (*child);
// (NB: there are obscure situations where child->isShowing() = false, but it still has the focus)
if (currentlyFocusedComponent == child || child->isParentOf (currentlyFocusedComponent))


+ 1
- 1
libs/juce/source/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp View File

@@ -190,7 +190,7 @@ void DrawableShape::strokeChanged()
strokePath.clear();
const float extraAccuracy = 4.0f;
if (dashLengths.empty())
if (dashLengths.isEmpty())
strokeType.createStrokedPath (strokePath, path, AffineTransform(), extraAccuracy);
else
strokeType.createDashedStroke (strokePath, path, dashLengths.getRawDataPointer(),


+ 1
- 1
libs/juce/source/modules/juce_gui_basics/drawables/juce_SVGParser.cpp View File

@@ -905,7 +905,7 @@ private:
}
};
GetFillTypeOp op = { this, &path, opacity };
GetFillTypeOp op = { this, &path, opacity, FillType() };
if (topLevelXml.applyOperationToChildWithID (urlID, op))
return op.fillType;


+ 1
- 1
libs/juce/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp View File

@@ -153,7 +153,7 @@ public:
file = newFile;
fileSize = newFileSize;
modTime = newModTime;
icon = Image::null;
icon = Image();
isDirectory = fileInfo != nullptr && fileInfo->isDirectory;
repaint();


+ 1
- 1
libs/juce/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp View File

@@ -57,7 +57,7 @@ void ImagePreviewComponent::timerCallback()
{
stopTimer();
currentThumbnail = Image::null;
currentThumbnail = Image();
currentDetails.clear();
repaint();


+ 0
- 4
libs/juce/source/modules/juce_gui_basics/juce_gui_basics.cpp View File

@@ -48,11 +48,7 @@
#import <IOKit/pwr_mgt/IOPMLib.h>
#if JUCE_SUPPORT_CARBON
#define Point CarbonDummyPointName
#define Component CarbonDummyCompName
#import <Carbon/Carbon.h> // still needed for SetSystemUIMode()
#undef Point
#undef Component
#endif
//==============================================================================


+ 99
- 0
libs/juce/source/modules/juce_gui_basics/layout/juce_Viewport.cpp View File

@@ -54,6 +54,7 @@ Viewport::Viewport (const String& name)
Viewport::~Viewport()
{
setScrollOnDragEnabled (false);
deleteOrRemoveContentComp();
}
@@ -180,6 +181,104 @@ void Viewport::componentMovedOrResized (Component&, bool, bool)
updateVisibleArea();
}
//==============================================================================
typedef AnimatedPosition<AnimatedPositionBehaviours::ContinuousWithMomentum> ViewportDragPosition;
struct Viewport::DragToScrollListener : private MouseListener,
private ViewportDragPosition::Listener
{
DragToScrollListener (Viewport& v)
: viewport (v), numTouches (0), isDragging (false)
{
viewport.contentHolder.addMouseListener (this, true);
offsetX.addListener (this);
offsetY.addListener (this);
}
~DragToScrollListener()
{
viewport.contentHolder.removeMouseListener (this);
}
void positionChanged (ViewportDragPosition&, double) override
{
viewport.setViewPosition (originalViewPos - Point<int> ((int) offsetX.getPosition(),
(int) offsetY.getPosition()));
}
void mouseDown (const MouseEvent&) override
{
++numTouches;
}
void mouseDrag (const MouseEvent& e) override
{
if (numTouches == 1)
{
Point<float> totalOffset = e.getOffsetFromDragStart().toFloat();
if (! isDragging && totalOffset.getDistanceFromOrigin() > 8.0f)
{
isDragging = true;
originalViewPos = viewport.getViewPosition();
offsetX.setPosition (0.0);
offsetX.beginDrag();
offsetY.setPosition (0.0);
offsetY.beginDrag();
}
if (isDragging)
{
offsetX.drag (totalOffset.x);
offsetY.drag (totalOffset.y);
}
}
}
void mouseUp (const MouseEvent&) override
{
if (--numTouches == 0)
{
offsetX.endDrag();
offsetY.endDrag();
isDragging = false;
}
jassert (numTouches >= 0);
}
Viewport& viewport;
ViewportDragPosition offsetX, offsetY;
Point<int> originalViewPos;
int numTouches;
bool isDragging;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DragToScrollListener)
};
void Viewport::setScrollOnDragEnabled (bool shouldScrollOnDrag)
{
if (isScrollOnDragEnabled() != shouldScrollOnDrag)
{
if (shouldScrollOnDrag)
dragToScrollListener = new DragToScrollListener (*this);
else
dragToScrollListener = nullptr;
}
}
bool Viewport::isScrollOnDragEnabled() const noexcept
{
return dragToScrollListener != nullptr;
}
bool Viewport::isCurrentlyScrollingOnDrag() const noexcept
{
return dragToScrollListener != nullptr && dragToScrollListener->isDragging;
}
//==============================================================================
void Viewport::lookAndFeelChanged()
{
if (! customScrollBarThickness)


+ 16
- 0
libs/juce/source/modules/juce_gui_basics/layout/juce_Viewport.h View File

@@ -241,6 +241,17 @@ public:
ScrollBar* getHorizontalScrollBar() noexcept { return &horizontalScrollBar; }
/** Enables or disables drag-to-scroll functionality in the viewport. */
void setScrollOnDragEnabled (bool shouldScrollOnDrag);
/** Returns true if drag-to-scroll functionality is enabled. */
bool isScrollOnDragEnabled() const noexcept;
/** Returns true if the user is currently dragging-to-scroll.
@see setScrollOnDragEnabled
*/
bool isCurrentlyScrollingOnDrag() const noexcept;
//==============================================================================
/** @internal */
void resized() override;
@@ -271,6 +282,11 @@ private:
Component contentHolder;
ScrollBar verticalScrollBar, horizontalScrollBar;
struct DragToScrollListener;
friend struct DragToScrollListener;
friend struct ContainerDeletePolicy<DragToScrollListener>;
ScopedPointer<DragToScrollListener> dragToScrollListener;
Point<int> viewportPosToCompPos (Point<int>) const;
void updateVisibleArea();


+ 5
- 6
libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp View File

@@ -265,13 +265,12 @@ void LookAndFeel_V2::drawButtonText (Graphics& g, TextButton& button, bool /*isM
const int fontHeight = roundToInt (font.getHeight() * 0.6f);
const int leftIndent = jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnLeft() ? 4 : 2));
const int rightIndent = jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnRight() ? 4 : 2));
const int textWidth = button.getWidth() - leftIndent - rightIndent;
g.drawFittedText (button.getButtonText(),
leftIndent,
yIndent,
button.getWidth() - leftIndent - rightIndent,
button.getHeight() - yIndent * 2,
Justification::centred, 2);
if (textWidth > 0)
g.drawFittedText (button.getButtonText(),
leftIndent, yIndent, textWidth, button.getHeight() - yIndent * 2,
Justification::centred, 2);
}
void LookAndFeel_V2::drawTickBox (Graphics& g, Component& component,


+ 258
- 283
libs/juce/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp View File

@@ -22,120 +22,68 @@
==============================================================================
*/
//==============================================================================
namespace PopupMenuSettings
{
const int scrollZone = 24;
const int borderSize = 2;
const int timerInterval = 50;
const int dismissCommandId = 0x6287345f;
const int sectionHeaderID = 0x4734a34f;
static bool menuWasHiddenBecauseOfAppChange = false;
}
class PopupMenu::Item
//==============================================================================
struct PopupMenu::HelperClasses
{
public:
Item() : itemID (0), isActive (true), isSeparator (true), isTicked (false),
usesColour (false), commandManager (nullptr)
{}
Item (const int itemId,
const String& name,
const bool active,
const bool ticked,
Drawable* drawable,
const Colour colour,
const bool useColour,
CustomComponent* const custom,
const PopupMenu* const sub,
ApplicationCommandManager* const manager)
: itemID (itemId), text (name), textColour (colour),
isActive (active), isSeparator (false), isTicked (ticked),
usesColour (useColour), iconDrawable (drawable),
customComp (custom), subMenu (createCopyIfNotNull (sub)), commandManager (manager)
{
if (commandManager != nullptr && itemID != 0)
{
String shortcutKey;
const Array<KeyPress> keyPresses (commandManager->getKeyMappings()
->getKeyPressesAssignedToCommand (itemID));
for (int i = 0; i < keyPresses.size(); ++i)
{
const String key (keyPresses.getReference(i).getTextDescriptionWithIcons());
if (shortcutKey.isNotEmpty())
shortcutKey << ", ";
if (key.length() == 1 && key[0] < 128)
shortcutKey << "shortcut: '" << key << '\'';
else
shortcutKey << key;
}
class MouseSourceState;
class MenuWindow;
shortcutKey = shortcutKey.trim();
static bool canBeTriggered (const PopupMenu::Item& item) noexcept { return item.isEnabled && item.itemID != 0 && ! item.isSectionHeader; }
static bool hasActiveSubMenu (const PopupMenu::Item& item) noexcept { return item.isEnabled && item.subMenu != nullptr && item.subMenu->items.size() > 0; }
static const Colour* getColour (const PopupMenu::Item& item) noexcept { return item.colour != Colour (0x00000000) ? &item.colour : nullptr; }
static bool hasSubMenu (const PopupMenu::Item& item) noexcept { return item.subMenu != nullptr && (item.itemID == 0 || item.subMenu->getNumItems() > 0); }
if (shortcutKey.isNotEmpty())
text << "<end>" << shortcutKey;
}
//==============================================================================
struct HeaderItemComponent : public PopupMenu::CustomComponent
{
HeaderItemComponent (const String& name) : PopupMenu::CustomComponent (false)
{
setName (name);
}
Item (const Item& other)
: itemID (other.itemID),
text (other.text),
textColour (other.textColour),
isActive (other.isActive),
isSeparator (other.isSeparator),
isTicked (other.isTicked),
usesColour (other.usesColour),
iconDrawable (other.iconDrawable != nullptr ? other.iconDrawable->createCopy() : nullptr),
customComp (other.customComp),
subMenu (createCopyIfNotNull (other.subMenu.get())),
commandManager (other.commandManager)
{}
bool canBeTriggered() const noexcept { return isActive && itemID != 0 && itemID != PopupMenuSettings::sectionHeaderID; }
bool hasActiveSubMenu() const noexcept { return isActive && subMenu != nullptr && subMenu->items.size() > 0; }
//==============================================================================
const int itemID;
String text;
const Colour textColour;
const bool isActive, isSeparator, isTicked, usesColour;
ScopedPointer<Drawable> iconDrawable;
ReferenceCountedObjectPtr<CustomComponent> customComp;
ScopedPointer<PopupMenu> subMenu;
ApplicationCommandManager* const commandManager;
void paint (Graphics& g) override
{
getLookAndFeel().drawPopupMenuSectionHeader (g, getLocalBounds(), getName());
}
private:
Item& operator= (const Item&);
void getIdealSize (int& idealWidth, int& idealHeight) override
{
getLookAndFeel().getIdealPopupMenuItemSize (getName(), false, -1, idealWidth, idealHeight);
idealHeight += idealHeight / 2;
idealWidth += idealWidth / 4;
}
JUCE_LEAK_DETECTOR (Item)
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HeaderItemComponent)
};
//==============================================================================
struct PopupMenu::HelperClasses
struct ItemComponent : public Component
{
class MouseSourceState;
class MenuWindow;
//==============================================================================
class ItemComponent : public Component
{
public:
ItemComponent (const PopupMenu::Item& info, int standardItemHeight, MenuWindow& parent)
: itemInfo (info),
ItemComponent (const PopupMenu::Item& i, int standardItemHeight, MenuWindow& parent)
: item (i),
customComp (i.customComponent),
isHighlighted (false)
{
addAndMakeVisible (itemInfo.customComp);
if (item.isSectionHeader)
customComp = new HeaderItemComponent (item.text);
addAndMakeVisible (customComp);
parent.addAndMakeVisible (this);
updateShortcutKeyDescription();
int itemW = 80;
int itemH = 16;
getIdealSize (itemW, itemH, standardItemHeight);
@@ -146,45 +94,33 @@ public:
~ItemComponent()
{
removeChildComponent (itemInfo.customComp);
removeChildComponent (customComp);
}
void getIdealSize (int& idealWidth, int& idealHeight, const int standardItemHeight)
{
if (itemInfo.customComp != nullptr)
itemInfo.customComp->getIdealSize (idealWidth, idealHeight);
if (customComp != nullptr)
customComp->getIdealSize (idealWidth, idealHeight);
else
getLookAndFeel().getIdealPopupMenuItemSize (itemInfo.text,
itemInfo.isSeparator,
getLookAndFeel().getIdealPopupMenuItemSize (getTextForMeasurement(),
item.isSeparator,
standardItemHeight,
idealWidth, idealHeight);
}
void paint (Graphics& g) override
{
if (itemInfo.customComp == nullptr)
{
String mainText (itemInfo.text);
String endText;
const int endIndex = mainText.indexOf ("<end>");
if (endIndex >= 0)
{
endText = mainText.substring (endIndex + 5).trim();
mainText = mainText.substring (0, endIndex);
}
getLookAndFeel()
.drawPopupMenuItem (g, getLocalBounds(),
itemInfo.isSeparator,
itemInfo.isActive,
isHighlighted,
itemInfo.isTicked,
itemInfo.subMenu != nullptr && (itemInfo.itemID == 0 || itemInfo.subMenu->getNumItems() > 0),
mainText, endText,
itemInfo.iconDrawable,
itemInfo.usesColour ? &(itemInfo.textColour) : nullptr);
}
if (customComp == nullptr)
getLookAndFeel().drawPopupMenuItem (g, getLocalBounds(),
item.isSeparator,
item.isEnabled,
isHighlighted,
item.isTicked,
hasSubMenu (item),
item.text,
item.shortcutKeyDescription,
item.image,
getColour (item));
}
void resized() override
@@ -195,24 +131,57 @@ public:
void setHighlighted (bool shouldBeHighlighted)
{
shouldBeHighlighted = shouldBeHighlighted && itemInfo.isActive;
shouldBeHighlighted = shouldBeHighlighted && item.isEnabled;
if (isHighlighted != shouldBeHighlighted)
{
isHighlighted = shouldBeHighlighted;
if (itemInfo.customComp != nullptr)
itemInfo.customComp->setHighlighted (shouldBeHighlighted);
if (customComp != nullptr)
customComp->setHighlighted (shouldBeHighlighted);
repaint();
}
}
PopupMenu::Item itemInfo;
PopupMenu::Item item;
private:
// NB: we use a copy of the one from the item info in case we're using our own section comp
ReferenceCountedObjectPtr<CustomComponent> customComp;
bool isHighlighted;
void updateShortcutKeyDescription()
{
if (item.commandManager != nullptr && item.itemID != 0)
{
String shortcutKey;
const Array<KeyPress> keyPresses (item.commandManager->getKeyMappings()
->getKeyPressesAssignedToCommand (item.itemID));
for (int i = 0; i < keyPresses.size(); ++i)
{
const String key (keyPresses.getReference(i).getTextDescriptionWithIcons());
if (shortcutKey.isNotEmpty())
shortcutKey << ", ";
if (key.length() == 1 && key[0] < 128)
shortcutKey << "shortcut: '" << key << '\'';
else
shortcutKey << key;
}
item.shortcutKeyDescription = shortcutKey.trim();
}
}
String getTextForMeasurement() const
{
return item.shortcutKeyDescription.isNotEmpty() ? item.text + " " + item.shortcutKeyDescription
: item.text;
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemComponent)
};
@@ -744,43 +713,43 @@ public:
for (int i = items.size(); --i >= 0;)
{
ItemComponent* const m = items.getUnchecked(i);
if (m != nullptr
&& m->itemInfo.itemID == itemID
&& windowPos.getHeight() > PopupMenuSettings::scrollZone * 4)
if (ItemComponent* const m = items.getUnchecked(i))
{
const int currentY = m->getY();
if (wantedY > 0 || currentY < 0 || m->getBottom() > windowPos.getHeight())
if (m->item.itemID == itemID
&& windowPos.getHeight() > PopupMenuSettings::scrollZone * 4)
{
if (wantedY < 0)
wantedY = jlimit (PopupMenuSettings::scrollZone,
jmax (PopupMenuSettings::scrollZone,
windowPos.getHeight() - (PopupMenuSettings::scrollZone + m->getHeight())),
currentY);
const int currentY = m->getY();
const Rectangle<int> mon (Desktop::getInstance().getDisplays()
.getDisplayContaining (windowPos.getPosition()).userArea);
if (wantedY > 0 || currentY < 0 || m->getBottom() > windowPos.getHeight())
{
if (wantedY < 0)
wantedY = jlimit (PopupMenuSettings::scrollZone,
jmax (PopupMenuSettings::scrollZone,
windowPos.getHeight() - (PopupMenuSettings::scrollZone + m->getHeight())),
currentY);
int deltaY = wantedY - currentY;
const Rectangle<int> mon (Desktop::getInstance().getDisplays()
.getDisplayContaining (windowPos.getPosition()).userArea);
windowPos.setSize (jmin (windowPos.getWidth(), mon.getWidth()),
jmin (windowPos.getHeight(), mon.getHeight()));
int deltaY = wantedY - currentY;
const int newY = jlimit (mon.getY(),
mon.getBottom() - windowPos.getHeight(),
windowPos.getY() + deltaY);
windowPos.setSize (jmin (windowPos.getWidth(), mon.getWidth()),
jmin (windowPos.getHeight(), mon.getHeight()));
deltaY -= newY - windowPos.getY();
const int newY = jlimit (mon.getY(),
mon.getBottom() - windowPos.getHeight(),
windowPos.getY() + deltaY);
childYOffset -= deltaY;
windowPos.setPosition (windowPos.getX(), newY);
deltaY -= newY - windowPos.getY();
updateYPositions();
}
childYOffset -= deltaY;
windowPos.setPosition (windowPos.getX(), newY);
break;
updateYPositions();
}
break;
}
}
}
}
@@ -877,9 +846,9 @@ public:
activeSubMenu = nullptr;
if (childComp != nullptr
&& childComp->itemInfo.hasActiveSubMenu())
&& hasActiveSubMenu (childComp->item))
{
activeSubMenu = new HelperClasses::MenuWindow (*(childComp->itemInfo.subMenu), this,
activeSubMenu = new HelperClasses::MenuWindow (*(childComp->item.subMenu), this,
options.withTargetScreenArea (childComp->getScreenBounds())
.withMinimumWidth (0)
.withTargetComponent (nullptr),
@@ -897,11 +866,11 @@ public:
void triggerCurrentlyHighlightedItem()
{
if (currentChild != nullptr
&& currentChild->itemInfo.canBeTriggered()
&& (currentChild->itemInfo.customComp == nullptr
|| currentChild->itemInfo.customComp->isTriggeredAutomatically()))
&& canBeTriggered (currentChild->item)
&& (currentChild->item.customComponent == nullptr
|| currentChild->item.customComponent->isTriggeredAutomatically()))
{
dismissMenu (&currentChild->itemInfo);
dismissMenu (&currentChild->item);
}
}
@@ -917,7 +886,7 @@ public:
if (ItemComponent* mic = items.getUnchecked ((start + items.size()) % items.size()))
{
if (mic->itemInfo.canBeTriggered() || mic->itemInfo.hasActiveSubMenu())
if (canBeTriggered (mic->item) || hasActiveSubMenu (mic->item))
{
setCurrentlyHighlightedChild (mic);
break;
@@ -973,7 +942,7 @@ public:
if (! window.windowIsStillValid())
return;
startTimer (PopupMenuSettings::timerInterval);
startTimerHz (20);
handleMousePosition (e.getScreenPosition());
}
@@ -1175,9 +1144,8 @@ private:
};
//==============================================================================
class NormalComponentWrapper : public PopupMenu::CustomComponent
struct NormalComponentWrapper : public PopupMenu::CustomComponent
{
public:
NormalComponentWrapper (Component* const comp, const int w, const int h,
const bool triggerMenuItemAutomaticallyWhenClicked)
: PopupMenu::CustomComponent (triggerMenuItemAutomaticallyWhenClicked),
@@ -1198,38 +1166,11 @@ public:
child->setBounds (getLocalBounds());
}
private:
const int width, height;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NormalComponentWrapper)
};
//==============================================================================
class HeaderItemComponent : public PopupMenu::CustomComponent
{
public:
HeaderItemComponent (const String& name)
: PopupMenu::CustomComponent (false)
{