- use expectations

- improved gibbs sampling
- LayerArray is template class

git-svn-id: http://moon:8086/svn/software/trunk/projects/RBM@18 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
2014-10-06 17:08:50 +00:00
parent f62f1283f8
commit fc758b853a
122 changed files with 1053 additions and 1149 deletions
-2
View File
@@ -34,13 +34,11 @@
using namespace juce; using namespace juce;
#endif #endif
#if ! JUCE_DONT_DECLARE_PROJECTINFO
namespace ProjectInfo namespace ProjectInfo
{ {
const char* const projectName = "RBM"; const char* const projectName = "RBM";
const char* const versionString = "1.0.0"; const char* const versionString = "1.0.0";
const int versionNumber = 0x10000; const int versionNumber = 0x10000;
} }
#endif
#endif // __APPHEADERFILE_J0FH5E__ #endif // __APPHEADERFILE_J0FH5E__
@@ -186,10 +186,9 @@ public:
/** Retrieves a copy of the next event from the buffer. /** Retrieves a copy of the next event from the buffer.
@param result on return, this will be the message. The MidiMessage's timestamp @param result on return, this will be the message (the MidiMessage's timestamp
is set to the same value as samplePosition. is not set)
@param samplePosition on return, this will be the position of the event, as a @param samplePosition on return, this will be the position of the event
sample index in the buffer
@returns true if an event was found, or false if the iterator has reached @returns true if an event was found, or false if the iterator has reached
the end of the buffer the end of the buffer
*/ */
@@ -204,8 +203,7 @@ public:
temporarily until the MidiBuffer is altered. temporarily until the MidiBuffer is altered.
@param numBytesOfMidiData on return, this is the number of bytes of data used by the @param numBytesOfMidiData on return, this is the number of bytes of data used by the
midi message midi message
@param samplePosition on return, this will be the position of the event, as a @param samplePosition on return, this will be the position of the event
sample index in the buffer
@returns true if an event was found, or false if the iterator has reached @returns true if an event was found, or false if the iterator has reached
the end of the buffer the end of the buffer
*/ */
@@ -163,7 +163,10 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
: numSamples; : numSamples;
if (numThisTime > 0) if (numThisTime > 0)
renderVoices (outputBuffer, startSample, numThisTime); {
for (int i = voices.size(); --i >= 0;)
voices.getUnchecked (i)->renderNextBlock (outputBuffer, startSample, numThisTime);
}
if (useEvent) if (useEvent)
handleMidiEvent (m); handleMidiEvent (m);
@@ -173,12 +176,6 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
} }
} }
void Synthesiser::renderVoices (AudioSampleBuffer& buffer, int startSample, int numSamples)
{
for (int i = voices.size(); --i >= 0;)
voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples);
}
void Synthesiser::handleMidiEvent (const MidiMessage& m) void Synthesiser::handleMidiEvent (const MidiMessage& m)
{ {
if (m.isNoteOn()) if (m.isNoteOn())
@@ -187,7 +184,7 @@ void Synthesiser::handleMidiEvent (const MidiMessage& m)
} }
else if (m.isNoteOff()) else if (m.isNoteOff())
{ {
noteOff (m.getChannel(), m.getNoteNumber(), m.getFloatVelocity(), true); noteOff (m.getChannel(), m.getNoteNumber(), true);
} }
else if (m.isAllNotesOff() || m.isAllSoundOff()) else if (m.isAllNotesOff() || m.isAllSoundOff())
{ {
@@ -233,7 +230,7 @@ void Synthesiser::noteOn (const int midiChannel,
if (voice->getCurrentlyPlayingNote() == midiNoteNumber if (voice->getCurrentlyPlayingNote() == midiNoteNumber
&& voice->isPlayingChannel (midiChannel)) && voice->isPlayingChannel (midiChannel))
stopVoice (voice, 1.0f, true); stopVoice (voice, true);
} }
startVoice (findFreeVoice (sound, shouldStealNotes), startVoice (findFreeVoice (sound, shouldStealNotes),
@@ -251,7 +248,7 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
if (voice != nullptr && sound != nullptr) if (voice != nullptr && sound != nullptr)
{ {
if (voice->currentlyPlayingSound != nullptr) if (voice->currentlyPlayingSound != nullptr)
voice->stopNote (0.0f, false); voice->stopNote (false);
voice->startNote (midiNoteNumber, velocity, sound, voice->startNote (midiNoteNumber, velocity, sound,
lastPitchWheelValues [midiChannel - 1]); lastPitchWheelValues [midiChannel - 1]);
@@ -264,11 +261,11 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
} }
} }
void Synthesiser::stopVoice (SynthesiserVoice* voice, float velocity, const bool allowTailOff) void Synthesiser::stopVoice (SynthesiserVoice* voice, const bool allowTailOff)
{ {
jassert (voice != nullptr); jassert (voice != nullptr);
voice->stopNote (velocity, allowTailOff); voice->stopNote (allowTailOff);
// the subclass MUST call clearCurrentNote() if it's not tailing off! RTFM for stopNote()! // the subclass MUST call clearCurrentNote() if it's not tailing off! RTFM for stopNote()!
jassert (allowTailOff || (voice->getCurrentlyPlayingNote() < 0 && voice->getCurrentlyPlayingSound() == 0)); jassert (allowTailOff || (voice->getCurrentlyPlayingNote() < 0 && voice->getCurrentlyPlayingSound() == 0));
@@ -276,7 +273,6 @@ void Synthesiser::stopVoice (SynthesiserVoice* voice, float velocity, const bool
void Synthesiser::noteOff (const int midiChannel, void Synthesiser::noteOff (const int midiChannel,
const int midiNoteNumber, const int midiNoteNumber,
const float velocity,
const bool allowTailOff) const bool allowTailOff)
{ {
const ScopedLock sl (lock); const ScopedLock sl (lock);
@@ -295,7 +291,7 @@ void Synthesiser::noteOff (const int midiChannel,
voice->keyIsDown = false; voice->keyIsDown = false;
if (! (sustainPedalsDown [midiChannel] || voice->sostenutoPedalDown)) if (! (sustainPedalsDown [midiChannel] || voice->sostenutoPedalDown))
stopVoice (voice, velocity, allowTailOff); stopVoice (voice, allowTailOff);
} }
} }
} }
@@ -311,7 +307,7 @@ void Synthesiser::allNotesOff (const int midiChannel, const bool allowTailOff)
SynthesiserVoice* const voice = voices.getUnchecked (i); SynthesiserVoice* const voice = voices.getUnchecked (i);
if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel)) if (midiChannel <= 0 || voice->isPlayingChannel (midiChannel))
voice->stopNote (1.0f, allowTailOff); voice->stopNote (allowTailOff);
} }
sustainPedalsDown.clear(); sustainPedalsDown.clear();
@@ -383,7 +379,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
SynthesiserVoice* const voice = voices.getUnchecked (i); SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->isPlayingChannel (midiChannel) && ! voice->keyIsDown) if (voice->isPlayingChannel (midiChannel) && ! voice->keyIsDown)
stopVoice (voice, 1.0f, true); stopVoice (voice, true);
} }
sustainPedalsDown.clearBit (midiChannel); sustainPedalsDown.clearBit (midiChannel);
@@ -404,7 +400,7 @@ void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown)
if (isDown) if (isDown)
voice->sostenutoPedalDown = true; voice->sostenutoPedalDown = true;
else if (voice->sostenutoPedalDown) else if (voice->sostenutoPedalDown)
stopVoice (voice, 1.0f, true); stopVoice (voice, true);
} }
} }
} }
@@ -55,14 +55,14 @@ public:
The Synthesiser will use this information when deciding which sounds to trigger The Synthesiser will use this information when deciding which sounds to trigger
for a given note. for a given note.
*/ */
virtual bool appliesToNote (int midiNoteNumber) = 0; virtual bool appliesToNote (const int midiNoteNumber) = 0;
/** Returns true if the sound should be triggered by midi events on a given channel. /** Returns true if the sound should be triggered by midi events on a given channel.
The Synthesiser will use this information when deciding which sounds to trigger The Synthesiser will use this information when deciding which sounds to trigger
for a given note. for a given note.
*/ */
virtual bool appliesToChannel (int midiChannel) = 0; virtual bool appliesToChannel (const int midiChannel) = 0;
/** The class is reference-counted, so this is a handy pointer class for it. */ /** The class is reference-counted, so this is a handy pointer class for it. */
typedef ReferenceCountedObjectPtr<SynthesiserSound> Ptr; typedef ReferenceCountedObjectPtr<SynthesiserSound> Ptr;
@@ -127,8 +127,6 @@ public:
This will be called during the rendering callback, so must be fast and thread-safe. This will be called during the rendering callback, so must be fast and thread-safe.
The velocity indicates how quickly the note was released - 0 is slowly, 1 is quickly.
If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all
sound immediately, and must call clearCurrentNote() to reset the state of this voice sound immediately, and must call clearCurrentNote() to reset the state of this voice
and allow the synth to reassign it another sound. and allow the synth to reassign it another sound.
@@ -138,7 +136,7 @@ public:
finishes playing (during the rendering callback), it must make sure that it calls finishes playing (during the rendering callback), it must make sure that it calls
clearCurrentNote(). clearCurrentNote().
*/ */
virtual void stopNote (float velocity, bool allowTailOff) = 0; virtual void stopNote (bool allowTailOff) = 0;
/** Called to let the voice know that the pitch wheel has been moved. /** Called to let the voice know that the pitch wheel has been moved.
This will be called during the rendering callback, so must be fast and thread-safe. This will be called during the rendering callback, so must be fast and thread-safe.
@@ -175,6 +173,13 @@ public:
int startSample, int startSample,
int numSamples) = 0; int numSamples) = 0;
/** Returns true if the voice is currently playing a sound which is mapped to the given
midi channel.
If it's not currently playing, this will return false.
*/
bool isPlayingChannel (int midiChannel) const;
/** Changes the voice's reference sample rate. /** Changes the voice's reference sample rate.
The rate is set so that subclasses know the output rate and can set their pitch The rate is set so that subclasses know the output rate and can set their pitch
@@ -183,14 +188,7 @@ public:
This method is called by the synth, and subclasses can access the current rate with This method is called by the synth, and subclasses can access the current rate with
the currentSampleRate member. the currentSampleRate member.
*/ */
virtual void setCurrentPlaybackSampleRate (double newRate); void setCurrentPlaybackSampleRate (double newRate);
/** Returns true if the voice is currently playing a sound which is mapped to the given
midi channel.
If it's not currently playing, this will return false.
*/
bool isPlayingChannel (int midiChannel) const;
/** Returns true if the key that triggered this voice is still held down. /** Returns true if the key that triggered this voice is still held down.
Note that the voice may still be playing after the key was released (e.g because the Note that the voice may still be playing after the key was released (e.g because the
@@ -237,11 +235,6 @@ private:
SynthesiserSound::Ptr currentlyPlayingSound; SynthesiserSound::Ptr currentlyPlayingSound;
bool keyIsDown, sostenutoPedalDown; bool keyIsDown, sostenutoPedalDown;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// Note the new parameters for this method.
virtual int stopNote (bool) { return 0; }
#endif
JUCE_LEAK_DETECTOR (SynthesiserVoice) JUCE_LEAK_DETECTOR (SynthesiserVoice)
}; };
@@ -372,7 +365,6 @@ public:
*/ */
virtual void noteOff (int midiChannel, virtual void noteOff (int midiChannel,
int midiNoteNumber, int midiNoteNumber,
float velocity,
bool allowTailOff); bool allowTailOff);
/** Turns off all notes. /** Turns off all notes.
@@ -452,7 +444,7 @@ public:
This value is propagated to the voices so that they can use it to render the correct This value is propagated to the voices so that they can use it to render the correct
pitches. pitches.
*/ */
virtual void setCurrentPlaybackSampleRate (double sampleRate); void setCurrentPlaybackSampleRate (double sampleRate);
/** Creates the next block of audio output. /** Creates the next block of audio output.
@@ -482,13 +474,6 @@ protected:
/** The last pitch-wheel values for each midi channel. */ /** The last pitch-wheel values for each midi channel. */
int lastPitchWheelValues [16]; int lastPitchWheelValues [16];
/** Renders the voices for the given range.
By default this just calls renderNextBlock() on each voice, but you may need
to override it to handle custom cases.
*/
virtual void renderVoices (AudioSampleBuffer& outputAudio,
int startSample, int numSamples);
/** Searches through the voices to find one that's not currently playing, and which /** Searches through the voices to find one that's not currently playing, and which
can play the given sound. can play the given sound.
@@ -526,12 +511,11 @@ private:
bool shouldStealNotes; bool shouldStealNotes;
BigInteger sustainPedalsDown; BigInteger sustainPedalsDown;
void stopVoice (SynthesiserVoice*, float velocity, bool allowTailOff); void stopVoice (SynthesiserVoice*, bool allowTailOff);
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE #if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// Note the new parameters for these methods. // Note the new parameters for this method.
virtual int findFreeVoice (const bool) const { return 0; } virtual int findFreeVoice (const bool) const { return 0; }
virtual int noteOff (int, int, int) { return 0; }
#endif #endif
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser)
@@ -341,8 +341,8 @@ private:
SLDataFormat_PCM pcmFormat = SLDataFormat_PCM pcmFormat =
{ {
SL_DATAFORMAT_PCM, SL_DATAFORMAT_PCM,
(SLuint32) numChannels, numChannels,
(SLuint32) (sampleRate * 1000), // (sample rate units are millihertz) sampleRate * 1000, // (sample rate units are millihertz)
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
@@ -450,8 +450,8 @@ private:
SLDataFormat_PCM pcmFormat = SLDataFormat_PCM pcmFormat =
{ {
SL_DATAFORMAT_PCM, SL_DATAFORMAT_PCM,
(SLuint32) numChannels, numChannels,
(SLuint32) (sampleRate * 1000), // (sample rate units are millihertz) sampleRate * 1000, // (sample rate units are millihertz)
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
(numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT), (numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT),
@@ -536,9 +536,9 @@ private:
return AudioSessionGetProperty (propID, &valueSize, &result); return AudioSessionGetProperty (propID, &valueSize, &result);
} }
static bool setSessionUInt32Property (AudioSessionPropertyID propID, UInt32 v) noexcept { return AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; } static bool setSessionUInt32Property (AudioSessionPropertyID propID, UInt32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; }
static bool setSessionFloat32Property (AudioSessionPropertyID propID, Float32 v) noexcept { return AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; } static bool setSessionFloat32Property (AudioSessionPropertyID propID, Float32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; }
static bool setSessionFloat64Property (AudioSessionPropertyID propID, Float64 v) noexcept { return AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; } static bool setSessionFloat64Property (AudioSessionPropertyID propID, Float64 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v) == kAudioSessionNoError; }
JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice)
}; };
@@ -41,7 +41,7 @@ namespace
return err; return err;
} }
#else #else
#define JUCE_ALSA_LOG(x) {} #define JUCE_ALSA_LOG(x)
#define JUCE_CHECKED_RESULT(x) (x) #define JUCE_CHECKED_RESULT(x) (x)
#endif #endif
@@ -165,13 +165,13 @@ bool LAMEEncoderAudioFormat::canHandleFile (const File&)
Array<int> LAMEEncoderAudioFormat::getPossibleSampleRates() Array<int> LAMEEncoderAudioFormat::getPossibleSampleRates()
{ {
const int rates[] = { 32000, 44100, 48000, 0 }; const int rates[] = { 32000, 44100, 48000, 0 };
return Array<int> (rates); return Array <int> (rates);
} }
Array<int> LAMEEncoderAudioFormat::getPossibleBitDepths() Array<int> LAMEEncoderAudioFormat::getPossibleBitDepths()
{ {
const int depths[] = { 16, 0 }; const int depths[] = { 16, 0 };
return Array<int> (depths); return Array <int> (depths);
} }
bool LAMEEncoderAudioFormat::canDoStereo() { return true; } bool LAMEEncoderAudioFormat::canDoStereo() { return true; }
@@ -65,7 +65,6 @@ const char* const WavAudioFormat::acidNumerator = "acid numerator";
const char* const WavAudioFormat::acidTempo = "acid tempo"; const char* const WavAudioFormat::acidTempo = "acid tempo";
const char* const WavAudioFormat::ISRC = "ISRC"; const char* const WavAudioFormat::ISRC = "ISRC";
const char* const WavAudioFormat::tracktionLoopInfo = "tracktion loop info";
//============================================================================== //==============================================================================
namespace WavFileHelpers namespace WavFileHelpers
@@ -482,38 +481,6 @@ namespace WavFileHelpers
input.read (this, (int) jmin (sizeof (*this), length)); input.read (this, (int) jmin (sizeof (*this), length));
} }
AcidChunk (const StringPairArray& values)
{
zerostruct (*this);
flags = getFlagIfPresent (values, WavAudioFormat::acidOneShot, 0x01)
| getFlagIfPresent (values, WavAudioFormat::acidRootSet, 0x02)
| getFlagIfPresent (values, WavAudioFormat::acidStretch, 0x04)
| getFlagIfPresent (values, WavAudioFormat::acidDiskBased, 0x08)
| getFlagIfPresent (values, WavAudioFormat::acidizerFlag, 0x10);
if (values[WavAudioFormat::acidRootSet].getIntValue() != 0)
rootNote = ByteOrder::swapIfBigEndian ((uint16) values[WavAudioFormat::acidRootNote].getIntValue());
numBeats = ByteOrder::swapIfBigEndian ((uint32) values[WavAudioFormat::acidBeats].getIntValue());
meterDenominator = ByteOrder::swapIfBigEndian ((uint16) values[WavAudioFormat::acidDenominator].getIntValue());
meterNumerator = ByteOrder::swapIfBigEndian ((uint16) values[WavAudioFormat::acidNumerator].getIntValue());
if (values.containsKey (WavAudioFormat::acidTempo))
tempo = swapFloatByteOrder (values[WavAudioFormat::acidTempo].getFloatValue());
}
static MemoryBlock createFrom (const StringPairArray& values)
{
return AcidChunk (values).toMemoryBlock();
}
MemoryBlock toMemoryBlock() const
{
return (flags != 0 || rootNote != 0 || numBeats != 0 || meterDenominator != 0 || meterNumerator != 0)
? MemoryBlock (this, sizeof (*this)) : MemoryBlock();
}
void addToMetadata (StringPairArray& values) const void addToMetadata (StringPairArray& values) const
{ {
setBoolFlag (values, WavAudioFormat::acidOneShot, 0x01); setBoolFlag (values, WavAudioFormat::acidOneShot, 0x01);
@@ -523,65 +490,30 @@ namespace WavFileHelpers
setBoolFlag (values, WavAudioFormat::acidizerFlag, 0x10); setBoolFlag (values, WavAudioFormat::acidizerFlag, 0x10);
if (flags & 0x02) // root note set if (flags & 0x02) // root note set
values.set (WavAudioFormat::acidRootNote, String (ByteOrder::swapIfBigEndian (rootNote))); values.set (WavAudioFormat::acidRootNote, String (rootNote));
values.set (WavAudioFormat::acidBeats, String (ByteOrder::swapIfBigEndian (numBeats))); values.set (WavAudioFormat::acidBeats, String (numBeats));
values.set (WavAudioFormat::acidDenominator, String (ByteOrder::swapIfBigEndian (meterDenominator))); values.set (WavAudioFormat::acidDenominator, String (meterDenominator));
values.set (WavAudioFormat::acidNumerator, String (ByteOrder::swapIfBigEndian (meterNumerator))); values.set (WavAudioFormat::acidNumerator, String (meterNumerator));
values.set (WavAudioFormat::acidTempo, String (swapFloatByteOrder (tempo))); values.set (WavAudioFormat::acidTempo, String (tempo));
} }
void setBoolFlag (StringPairArray& values, const char* name, uint32 mask) const void setBoolFlag (StringPairArray& values, const char* name, int32 mask) const
{ {
values.set (name, (flags & ByteOrder::swapIfBigEndian (mask)) ? "1" : "0"); values.set (name, (flags & mask) ? "1" : "0");
} }
static uint32 getFlagIfPresent (const StringPairArray& values, const char* name, uint32 flag) int32 flags;
{ int16 rootNote;
return values[name].getIntValue() != 0 ? ByteOrder::swapIfBigEndian (flag) : 0; int16 reserved1;
}
static float swapFloatByteOrder (const float x) noexcept
{
#ifdef JUCE_BIG_ENDIAN
union { uint32 asInt; float asFloat; } n;
n.asFloat = x;
n.asInt = ByteOrder::swap (n.asInt);
return n.asFloat;
#else
return x;
#endif
}
uint32 flags;
uint16 rootNote;
uint16 reserved1;
float reserved2; float reserved2;
uint32 numBeats; int32 numBeats;
uint16 meterDenominator; int16 meterDenominator;
uint16 meterNumerator; int16 meterNumerator;
float tempo; float tempo;
} JUCE_PACKED; } JUCE_PACKED;
//==============================================================================
struct TracktionChunk
{
static MemoryBlock createFrom (const StringPairArray& values)
{
const String s = values[WavAudioFormat::tracktionLoopInfo];
MemoryBlock data;
if (s.isNotEmpty())
{
MemoryOutputStream os (data, false);
os.writeString (s);
}
return data;
}
};
//============================================================================== //==============================================================================
namespace AXMLChunk namespace AXMLChunk
{ {
@@ -884,12 +816,6 @@ public:
{ {
AcidChunk (*input, length).addToMetadata (metadataValues); AcidChunk (*input, length).addToMetadata (metadataValues);
} }
else if (chunkType == chunkName ("Trkn"))
{
MemoryBlock tracktion;
input->readIntoMemoryBlock (tracktion, (ssize_t) length);
metadataValues.set (WavAudioFormat::tracktionLoopInfo, tracktion.toString());
}
else if (chunkEnd <= input->getPosition()) else if (chunkEnd <= input->getPosition())
{ {
break; break;
@@ -993,8 +919,6 @@ public:
instChunk = InstChunk::createFrom (metadataValues); instChunk = InstChunk::createFrom (metadataValues);
cueChunk = CueChunk ::createFrom (metadataValues); cueChunk = CueChunk ::createFrom (metadataValues);
listChunk = ListChunk::createFrom (metadataValues); listChunk = ListChunk::createFrom (metadataValues);
acidChunk = AcidChunk::createFrom (metadataValues);
trckChunk = TracktionChunk::createFrom (metadataValues);
} }
headerPosition = out->getPosition(); headerPosition = out->getPosition();
@@ -1057,7 +981,7 @@ public:
} }
private: private:
MemoryBlock tempBlock, bwavChunk, axmlChunk, smplChunk, instChunk, cueChunk, listChunk, acidChunk, trckChunk; MemoryBlock tempBlock, bwavChunk, axmlChunk, smplChunk, instChunk, cueChunk, listChunk;
uint64 lengthInSamples, bytesWritten; uint64 lengthInSamples, bytesWritten;
int64 headerPosition; int64 headerPosition;
bool writeFailed; bool writeFailed;
@@ -1109,8 +1033,6 @@ private:
+ chunkSize (instChunk) + chunkSize (instChunk)
+ chunkSize (cueChunk) + chunkSize (cueChunk)
+ chunkSize (listChunk) + chunkSize (listChunk)
+ chunkSize (acidChunk)
+ chunkSize (trckChunk)
+ (8 + 28)); // (ds64 chunk) + (8 + 28)); // (ds64 chunk)
riffChunkSize += (riffChunkSize & 1); riffChunkSize += (riffChunkSize & 1);
@@ -1190,8 +1112,6 @@ private:
writeChunk (instChunk, chunkName ("inst"), 7); writeChunk (instChunk, chunkName ("inst"), 7);
writeChunk (cueChunk, chunkName ("cue ")); writeChunk (cueChunk, chunkName ("cue "));
writeChunk (listChunk, chunkName ("LIST")); writeChunk (listChunk, chunkName ("LIST"));
writeChunk (acidChunk, chunkName ("acid"));
writeChunk (trckChunk, chunkName ("Trkn"));
writeChunkHeader (chunkName ("data"), isRF64 ? -1 : (int) (lengthInSamples * bytesPerFrame)); writeChunkHeader (chunkName ("data"), isRF64 ? -1 : (int) (lengthInSamples * bytesPerFrame));
@@ -135,9 +135,6 @@ public:
/** Metadata property name used when reading an ISRC code from an AXML chunk. */ /** Metadata property name used when reading an ISRC code from an AXML chunk. */
static const char* const ISRC; static const char* const ISRC;
/** Metadata property name used when reading a WAV file with a Tracktion chunk. */
static const char* const tracktionLoopInfo;
//============================================================================== //==============================================================================
Array<int> getPossibleSampleRates() override; Array<int> getPossibleSampleRates() override;
Array<int> getPossibleBitDepths() override; Array<int> getPossibleBitDepths() override;
@@ -173,54 +173,35 @@ void AudioFormatReader::read (AudioSampleBuffer* buffer,
} }
} }
void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples, template <typename SampleType>
Range<float>* const results, const int channelsToRead) static Range<SampleType> getChannelMinAndMax (SampleType* channel, int numSamples) noexcept
{ {
jassert (channelsToRead > 0 && channelsToRead <= (int) numChannels); return Range<SampleType>::findMinAndMax (channel, numSamples);
}
if (numSamples <= 0) static Range<float> getChannelMinAndMax (float* channel, int numSamples) noexcept
{
return FloatVectorOperations::findMinAndMax (channel, numSamples);
}
template <typename SampleType>
static void getStereoMinAndMax (SampleType* const* channels, const int numChannels, const int numSamples,
SampleType& lmin, SampleType& lmax, SampleType& rmin, SampleType& rmax)
{
Range<SampleType> range (getChannelMinAndMax (channels[0], numSamples));
lmax = jmax (lmax, range.getEnd());
lmin = jmin (lmin, range.getStart());
if (numChannels > 1)
{ {
for (int i = 0; i < channelsToRead; ++i) range = getChannelMinAndMax (channels[1], numSamples);
results[i] = Range<float>(); rmax = jmax (rmax, range.getEnd());
rmin = jmin (rmin, range.getStart());
return;
} }
else
const int bufferSize = (int) jmin (numSamples, (int64) 4096);
AudioSampleBuffer tempSampleBuffer ((int) channelsToRead, bufferSize);
float* const* const floatBuffer = tempSampleBuffer.getArrayOfWritePointers();
int* const* intBuffer = reinterpret_cast<int* const*> (floatBuffer);
bool isFirstBlock = true;
while (numSamples > 0)
{ {
const int numToDo = (int) jmin (numSamples, (int64) bufferSize); rmax = lmax;
if (! read (intBuffer, channelsToRead, startSampleInFile, numToDo, false)) rmin = lmin;
break;
for (int i = 0; i < channelsToRead; ++i)
{
Range<float> r;
if (usesFloatingPointData)
{
r = FloatVectorOperations::findMinAndMax (floatBuffer[i], numToDo);
}
else
{
Range<int> intRange (Range<int>::findMinAndMax (intBuffer[i], numToDo));
r = Range<float> (intRange.getStart() / (float) std::numeric_limits<int>::max(),
intRange.getEnd() / (float) std::numeric_limits<int>::max());
}
results[i] = isFirstBlock ? r : results[i].getUnionWith (r);
}
isFirstBlock = false;
numSamples -= numToDo;
startSampleInFile += numToDo;
} }
} }
@@ -228,20 +209,66 @@ void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples
float& lowestLeft, float& highestLeft, float& lowestLeft, float& highestLeft,
float& lowestRight, float& highestRight) float& lowestRight, float& highestRight)
{ {
Range<float> levels[2]; if (numSamples <= 0)
readMaxLevels (startSampleInFile, numSamples, levels, jmin (2, (int) numChannels));
lowestLeft = levels[0].getStart();
highestLeft = levels[0].getEnd();
if (numChannels > 1)
{ {
lowestRight = levels[1].getStart(); lowestLeft = 0;
highestRight = levels[1].getEnd(); lowestRight = 0;
highestLeft = 0;
highestRight = 0;
return;
}
const int bufferSize = (int) jmin (numSamples, (int64) 4096);
AudioSampleBuffer tempSampleBuffer ((int) numChannels, bufferSize);
float* const* const floatBuffer = tempSampleBuffer.getArrayOfWritePointers();
int* const* intBuffer = reinterpret_cast<int* const*> (floatBuffer);
if (usesFloatingPointData)
{
float lmin = 1.0e6f;
float lmax = -lmin;
float rmin = lmin;
float rmax = lmax;
while (numSamples > 0)
{
const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
if (! read (intBuffer, 2, startSampleInFile, numToDo, false))
break;
numSamples -= numToDo;
startSampleInFile += numToDo;
getStereoMinAndMax (floatBuffer, (int) numChannels, numToDo, lmin, lmax, rmin, rmax);
}
lowestLeft = lmin;
highestLeft = lmax;
lowestRight = rmin;
highestRight = rmax;
} }
else else
{ {
lowestRight = lowestLeft; int lmax = std::numeric_limits<int>::min();
highestRight = highestLeft; int lmin = std::numeric_limits<int>::max();
int rmax = std::numeric_limits<int>::min();
int rmin = std::numeric_limits<int>::max();
while (numSamples > 0)
{
const int numToDo = (int) jmin (numSamples, (int64) bufferSize);
if (! read (intBuffer, 2, startSampleInFile, numToDo, false))
break;
numSamples -= numToDo;
startSampleInFile += numToDo;
getStereoMinAndMax (intBuffer, (int) numChannels, numToDo, lmin, lmax, rmin, rmax);
}
lowestLeft = lmin / (float) std::numeric_limits<int>::max();
highestLeft = lmax / (float) std::numeric_limits<int>::max();
lowestRight = rmin / (float) std::numeric_limits<int>::max();
highestRight = rmax / (float) std::numeric_limits<int>::max();
} }
} }
@@ -121,25 +121,6 @@ public:
bool useReaderLeftChan, bool useReaderLeftChan,
bool useReaderRightChan); bool useReaderRightChan);
/** Finds the highest and lowest sample levels from a section of the audio stream.
This will read a block of samples from the stream, and measure the
highest and lowest sample levels from the channels in that section, returning
these as normalised floating-point levels.
@param startSample the offset into the audio stream to start reading from. It's
ok for this to be beyond the start or end of the stream.
@param numSamples how many samples to read
@param results this array will be filled with Range values for each channel.
The array must contain numChannels elements.
@param numChannelsToRead the number of channels of data to scan. This must be
more than zero, but not more than the total number of channels
that the reader contains
@see read
*/
virtual void readMaxLevels (int64 startSample, int64 numSamples,
Range<float>* results, int numChannelsToRead);
/** Finds the highest and lowest sample levels from a section of the audio stream. /** Finds the highest and lowest sample levels from a section of the audio stream.
This will read a block of samples from the stream, and measure the This will read a block of samples from the stream, and measure the
@@ -157,9 +138,12 @@ public:
channel (if there is one) channel (if there is one)
@see read @see read
*/ */
virtual void readMaxLevels (int64 startSample, int64 numSamples, virtual void readMaxLevels (int64 startSample,
float& lowestLeft, float& highestLeft, int64 numSamples,
float& lowestRight, float& highestRight); float& lowestLeft,
float& highestLeft,
float& lowestRight,
float& highestRight);
/** Scans the source looking for a sample whose magnitude is in a specified range. /** Scans the source looking for a sample whose magnitude is in a specified range.
@@ -59,12 +59,12 @@ SamplerSound::~SamplerSound()
{ {
} }
bool SamplerSound::appliesToNote (int midiNoteNumber) bool SamplerSound::appliesToNote (const int midiNoteNumber)
{ {
return midiNotes [midiNoteNumber]; return midiNotes [midiNoteNumber];
} }
bool SamplerSound::appliesToChannel (int /*midiChannel*/) bool SamplerSound::appliesToChannel (const int /*midiChannel*/)
{ {
return true; return true;
} }
@@ -127,7 +127,7 @@ void SamplerVoice::startNote (const int midiNoteNumber,
} }
} }
void SamplerVoice::stopNote (float /*velocity*/, bool allowTailOff) void SamplerVoice::stopNote (const bool allowTailOff)
{ {
if (allowTailOff) if (allowTailOff)
{ {
@@ -197,7 +197,7 @@ void SamplerVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSa
if (attackReleaseLevel <= 0.0f) if (attackReleaseLevel <= 0.0f)
{ {
stopNote (0.0f, false); stopNote (false);
break; break;
} }
} }
@@ -216,7 +216,7 @@ void SamplerVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSa
if (sourceSamplePosition > playingSound->length) if (sourceSamplePosition > playingSound->length)
{ {
stopNote (0.0f, false); stopNote (false);
break; break;
} }
} }
@@ -82,8 +82,8 @@ public:
//============================================================================== //==============================================================================
bool appliesToNote (int midiNoteNumber) override; bool appliesToNote (const int midiNoteNumber) override;
bool appliesToChannel (int midiChannel) override; bool appliesToChannel (const int midiChannel) override;
private: private:
@@ -124,7 +124,7 @@ public:
bool canPlaySound (SynthesiserSound*) override; bool canPlaySound (SynthesiserSound*) override;
void startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int pitchWheel) override; void startNote (int midiNoteNumber, float velocity, SynthesiserSound*, int pitchWheel) override;
void stopNote (float velocity, bool allowTailOff) override; void stopNote (bool allowTailOff) override;
void pitchWheelMoved (int newValue); void pitchWheelMoved (int newValue);
void controllerMoved (int controllerNumber, int newValue) override; void controllerMoved (int controllerNumber, int newValue) override;
@@ -1446,7 +1446,7 @@ public:
warnOnFailure (view->removed()); warnOnFailure (view->removed());
warnOnFailure (view->setFrame (nullptr)); warnOnFailure (view->setFrame (nullptr));
processor.editorBeingDeleted (this); getAudioProcessor()->editorBeingDeleted (this);
#if JUCE_MAC #if JUCE_MAC
dummyComponent.setView (nullptr); dummyComponent.setView (nullptr);
@@ -2112,11 +2112,7 @@ private:
MemoryBlock mem; MemoryBlock mem;
if (mem.fromBase64Encoding (state->getAllSubText())) if (mem.fromBase64Encoding (state->getAllSubText()))
{ stream = new Steinberg::MemoryStream (mem.getData(), (TSize) mem.getSize());
stream = new Steinberg::MemoryStream();
stream->setSize ((TSize) mem.getSize());
mem.copyTo (stream->getData(), 0, mem.getSize());
}
} }
return stream; return stream;
@@ -787,7 +787,7 @@ public:
char buffer [512] = { 0 }; char buffer [512] = { 0 };
dispatch (effGetEffectName, 0, 0, buffer, 0); dispatch (effGetEffectName, 0, 0, buffer, 0);
desc.descriptiveName = String::fromUTF8 (buffer).trim(); desc.descriptiveName = String (buffer).trim();
if (desc.descriptiveName.isEmpty()) if (desc.descriptiveName.isEmpty())
desc.descriptiveName = name; desc.descriptiveName = name;
@@ -802,7 +802,7 @@ public:
{ {
char buffer [kVstMaxVendorStrLen + 8] = { 0 }; char buffer [kVstMaxVendorStrLen + 8] = { 0 };
dispatch (effGetVendorString, 0, 0, buffer, 0); dispatch (effGetVendorString, 0, 0, buffer, 0);
desc.manufacturerName = String::fromUTF8 (buffer); desc.manufacturerName = buffer;
} }
desc.version = getVersion(); desc.version = getVersion();
@@ -1197,7 +1197,7 @@ public:
char nm[264] = { 0 }; char nm[264] = { 0 };
if (dispatch (effGetProgramNameIndexed, jlimit (0, getNumPrograms(), index), -1, nm, 0) != 0) if (dispatch (effGetProgramNameIndexed, jlimit (0, getNumPrograms(), index), -1, nm, 0) != 0)
return String::fromUTF8 (nm).trim(); return String (CharPointer_UTF8 (nm)).trim();
} }
} }
@@ -41,9 +41,8 @@
//============================================================================== //==============================================================================
#if JUCE_MAC #if JUCE_MAC
#if JUCE_SUPPORT_CARBON \ #if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) \
&& ((JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) \ || ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)
|| ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6))
#define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers)
#define Component CarbonDummyCompName #define Component CarbonDummyCompName
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
@@ -128,8 +128,7 @@ String AudioProcessor::getParameterText (int parameterIndex, int maximumStringLe
return getParameterText (parameterIndex).substring (0, maximumStringLength); return getParameterText (parameterIndex).substring (0, maximumStringLength);
} }
int AudioProcessor::getDefaultNumParameterSteps() noexcept { return 0x7fffffff; } int AudioProcessor::getParameterNumSteps (int /*parameterIndex*/) { return 0x7fffffff; }
int AudioProcessor::getParameterNumSteps (int /*parameterIndex*/) { return getDefaultNumParameterSteps(); }
float AudioProcessor::getParameterDefaultValue (int /*parameterIndex*/) { return 0.0f; } float AudioProcessor::getParameterDefaultValue (int /*parameterIndex*/) { return 0.0f; }
AudioProcessorListener* AudioProcessor::getListenerLocked (const int index) const noexcept AudioProcessorListener* AudioProcessor::getListenerLocked (const int index) const noexcept
@@ -414,18 +414,12 @@ public:
virtual String getParameterText (int parameterIndex, int maximumStringLength); virtual String getParameterText (int parameterIndex, int maximumStringLength);
/** Returns the number of discrete steps that this parameter can represent. /** Returns the number of discrete steps that this parameter can represent.
The default return value if you don't implement this method is The default return value if you don't implement this method is 0x7fffffff.
AudioProcessor::getDefaultNumParameterSteps().
If your parameter is boolean, then you may want to make this return 2. If your parameter is boolean, then you may want to make this return 2.
The value that is returned may or may not be used, depending on the host. The value that is returned may or may not be used, depending on the host.
*/ */
virtual int getParameterNumSteps (int parameterIndex); virtual int getParameterNumSteps (int parameterIndex);
/** Returns the default number of steps for a parameter.
@see getParameterNumSteps
*/
static int getDefaultNumParameterSteps() noexcept;
/** Returns the default value for the parameter. /** Returns the default value for the parameter.
By default, this just returns 0. By default, this just returns 0.
The value that is returned may or may not be used, depending on the host. The value that is returned may or may not be used, depending on the host.
@@ -22,22 +22,16 @@
============================================================================== ==============================================================================
*/ */
AudioProcessorEditor::AudioProcessorEditor (AudioProcessor& p) noexcept : processor (p) AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* const p)
{ : owner (p)
}
AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* p) noexcept : processor (*p)
{ {
// the filter must be valid.. // the filter must be valid..
jassert (p != nullptr); jassert (owner != nullptr);
} }
AudioProcessorEditor::~AudioProcessorEditor() AudioProcessorEditor::~AudioProcessorEditor()
{ {
// if this fails, then the wrapper hasn't called editorBeingDeleted() on the // if this fails, then the wrapper hasn't called editorBeingDeleted() on the
// filter for some reason.. // filter for some reason..
jassert (processor.getActiveEditor() != this); jassert (owner->getActiveEditor() != this);
} }
void AudioProcessorEditor::setControlHighlight (ParameterControlHighlightInfo) {}
int AudioProcessorEditor::getControlParameterIndex (Component&) { return -1; }
@@ -39,11 +39,9 @@ class JUCE_API AudioProcessorEditor : public Component
{ {
protected: protected:
//============================================================================== //==============================================================================
/** Creates an editor for the specified processor. */ /** Creates an editor for the specified processor.
AudioProcessorEditor (AudioProcessor&) noexcept; */
AudioProcessorEditor (AudioProcessor* owner);
/** Creates an editor for the specified processor. */
AudioProcessorEditor (AudioProcessor*) noexcept;
public: public:
/** Destructor. */ /** Destructor. */
@@ -51,40 +49,14 @@ public:
//============================================================================== //==============================================================================
/** The AudioProcessor that this editor represents. */ /** Returns a pointer to the processor that this editor represents. */
AudioProcessor& processor; AudioProcessor* getAudioProcessor() const noexcept { return owner; }
/** Returns a pointer to the processor that this editor represents.
This method is here to support legacy code, but it's easier to just use the
AudioProcessorEditor::processor member variable directly to get this object.
*/
AudioProcessor* getAudioProcessor() const noexcept { return &processor; }
//==============================================================================
/** Used by the setParameterHighlighting() method. */
struct ParameterControlHighlightInfo
{
int parameterIndex;
bool isHighlighted;
Colour suggestedColour;
};
/** Some types of plugin can call this to suggest that the control for a particular
parameter should be highlighted.
Currently only AAX plugins will call this, and implementing it is optional.
*/
virtual void setControlHighlight (ParameterControlHighlightInfo);
/** Called by certain plug-in wrappers to find out whether a component is used
to control a parameter.
If the given component represents a particular plugin parameter, then this
method should return the index of that parameter. If not, it should return -1.
Currently only AAX plugins will call this, and implementing it is optional.
*/
virtual int getControlParameterIndex (Component&);
private: private:
//==============================================================================
AudioProcessor* const owner;
JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor) JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor)
}; };
@@ -71,26 +71,18 @@ PluginDescription& PluginDescription::operator= (const PluginDescription& other)
return *this; return *this;
} }
bool PluginDescription::isDuplicateOf (const PluginDescription& other) const noexcept bool PluginDescription::isDuplicateOf (const PluginDescription& other) const
{ {
return fileOrIdentifier == other.fileOrIdentifier return fileOrIdentifier == other.fileOrIdentifier
&& uid == other.uid; && uid == other.uid;
} }
static String getPluginDescSuffix (const PluginDescription& d)
{
return "-" + String::toHexString (d.fileOrIdentifier.hashCode())
+ "-" + String::toHexString (d.uid);
}
bool PluginDescription::matchesIdentifierString (const String& identifierString) const
{
return identifierString.endsWithIgnoreCase (getPluginDescSuffix (*this));
}
String PluginDescription::createIdentifierString() const String PluginDescription::createIdentifierString() const
{ {
return pluginFormatName + "-" + name + getPluginDescSuffix (*this); return pluginFormatName
+ "-" + name
+ "-" + String::toHexString (fileOrIdentifier.hashCode())
+ "-" + String::toHexString (uid);
} }
XmlElement* PluginDescription::createXml() const XmlElement* PluginDescription::createXml() const
@@ -107,15 +107,7 @@ public:
This isn't quite as simple as them just having the same file (because of This isn't quite as simple as them just having the same file (because of
shell plug-ins). shell plug-ins).
*/ */
bool isDuplicateOf (const PluginDescription& other) const noexcept; bool isDuplicateOf (const PluginDescription& other) const;
/** Return true if this description is equivalent to another one which created the
given identifier string.
Note that this isn't quite as simple as them just calling createIdentifierString()
and comparing the strings, because the identifers can differ (thanks to shell plug-ins).
*/
bool matchesIdentifierString (const String& identifierString) const;
//============================================================================== //==============================================================================
/** Returns a string that can be saved and used to uniquely identify the /** Returns a string that can be saved and used to uniquely identify the
@@ -46,7 +46,7 @@ PluginDescription* KnownPluginList::getTypeForFile (const String& fileOrIdentifi
PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const
{ {
for (int i = 0; i < types.size(); ++i) for (int i = 0; i < types.size(); ++i)
if (types.getUnchecked(i)->matchesIdentifierString (identifierString)) if (types.getUnchecked(i)->createIdentifierString() == identifierString)
return types.getUnchecked(i); return types.getUnchecked(i);
return nullptr; return nullptr;
@@ -65,7 +65,8 @@ private:
public: public:
//============================================================================== //==============================================================================
/** Creates an empty array. */ /** Creates an empty array. */
Array() noexcept : numUsed (0) Array() noexcept
: numUsed (0)
{ {
} }
@@ -88,8 +88,9 @@ NamedValueSet& NamedValueSet::operator= (NamedValueSet&& other) noexcept
} }
#endif #endif
NamedValueSet::~NamedValueSet() noexcept NamedValueSet::~NamedValueSet()
{ {
clear();
} }
void NamedValueSet::clear() void NamedValueSet::clear()
@@ -112,7 +113,7 @@ int NamedValueSet::size() const noexcept
return values.size(); return values.size();
} }
const var& NamedValueSet::operator[] (const Identifier& name) const noexcept const var& NamedValueSet::operator[] (const Identifier& name) const
{ {
if (const var* v = getVarPointer (name)) if (const var* v = getVarPointer (name))
return *v; return *v;
@@ -169,7 +170,7 @@ bool NamedValueSet::set (Identifier name, const var& newValue)
return true; return true;
} }
bool NamedValueSet::contains (const Identifier& name) const noexcept bool NamedValueSet::contains (const Identifier& name) const
{ {
return getVarPointer (name) != nullptr; return getVarPointer (name) != nullptr;
} }
@@ -54,7 +54,7 @@ public:
#endif #endif
/** Destructor. */ /** Destructor. */
~NamedValueSet() noexcept; ~NamedValueSet();
bool operator== (const NamedValueSet&) const; bool operator== (const NamedValueSet&) const;
bool operator!= (const NamedValueSet&) const; bool operator!= (const NamedValueSet&) const;
@@ -67,7 +67,7 @@ public:
If the name isn't found, this will return a void variant. If the name isn't found, this will return a void variant.
@see getProperty @see getProperty
*/ */
const var& operator[] (const Identifier& name) const noexcept; const var& operator[] (const Identifier& name) const;
/** Tries to return the named value, but if no such value is found, this will /** Tries to return the named value, but if no such value is found, this will
instead return the supplied default value. instead return the supplied default value.
@@ -89,7 +89,7 @@ public:
#endif #endif
/** Returns true if the set contains an item with the specified name. */ /** Returns true if the set contains an item with the specified name. */
bool contains (const Identifier& name) const noexcept; bool contains (const Identifier& name) const;
/** Removes a value from the set. /** Removes a value from the set.
@returns true if a value was removed; false if there was no value @returns true if a value was removed; false if there was no value
@@ -830,7 +830,7 @@ public:
This will use a comparator object to sort the elements into order. The object This will use a comparator object to sort the elements into order. The object
passed must have a method of the form: passed must have a method of the form:
@code @code
int compareElements (ElementType* first, ElementType* second); int compareElements (ElementType first, ElementType second);
@endcode @endcode
..and this method must return: ..and this method must return:
@@ -26,7 +26,32 @@
============================================================================== ==============================================================================
*/ */
static void parseWildcard (const String& pattern, StringArray& result) WildcardFileFilter::WildcardFileFilter (const String& fileWildcardPatterns,
const String& directoryWildcardPatterns,
const String& desc)
: FileFilter (desc.isEmpty() ? fileWildcardPatterns
: (desc + " (" + fileWildcardPatterns + ")"))
{
parse (fileWildcardPatterns, fileWildcards);
parse (directoryWildcardPatterns, directoryWildcards);
}
WildcardFileFilter::~WildcardFileFilter()
{
}
bool WildcardFileFilter::isFileSuitable (const File& file) const
{
return match (file, fileWildcards);
}
bool WildcardFileFilter::isDirectorySuitable (const File& file) const
{
return match (file, directoryWildcards);
}
//==============================================================================
void WildcardFileFilter::parse (const String& pattern, StringArray& result)
{ {
result.addTokens (pattern.toLowerCase(), ";,", "\"'"); result.addTokens (pattern.toLowerCase(), ";,", "\"'");
@@ -40,7 +65,7 @@ static void parseWildcard (const String& pattern, StringArray& result)
result.set (i, "*"); result.set (i, "*");
} }
static bool matchWildcard (const File& file, const StringArray& wildcards) bool WildcardFileFilter::match (const File& file, const StringArray& wildcards)
{ {
const String filename (file.getFileName()); const String filename (file.getFileName());
@@ -50,27 +75,3 @@ static bool matchWildcard (const File& file, const StringArray& wildcards)
return false; return false;
} }
WildcardFileFilter::WildcardFileFilter (const String& fileWildcardPatterns,
const String& directoryWildcardPatterns,
const String& desc)
: FileFilter (desc.isEmpty() ? fileWildcardPatterns
: (desc + " (" + fileWildcardPatterns + ")"))
{
parseWildcard (fileWildcardPatterns, fileWildcards);
parseWildcard (directoryWildcardPatterns, directoryWildcards);
}
WildcardFileFilter::~WildcardFileFilter()
{
}
bool WildcardFileFilter::isFileSuitable (const File& file) const
{
return matchWildcard (file, fileWildcards);
}
bool WildcardFileFilter::isDirectorySuitable (const File& file) const
{
return matchWildcard (file, directoryWildcards);
}
@@ -75,8 +75,12 @@ private:
//============================================================================== //==============================================================================
StringArray fileWildcards, directoryWildcards; StringArray fileWildcards, directoryWildcards;
static void parse (const String& pattern, StringArray& result);
static bool match (const File& file, const StringArray& wildcards);
JUCE_LEAK_DETECTOR (WildcardFileFilter) JUCE_LEAK_DETECTOR (WildcardFileFilter)
}; };
#endif // JUCE_WILDCARDFILEFILTER_H_INCLUDED #endif // JUCE_WILDCARDFILEFILTER_H_INCLUDED
@@ -544,7 +544,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
{ {
DivideOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::divide) {} DivideOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::divide) {}
var getWithDoubles (double a, double b) const override { return b != 0 ? a / b : std::numeric_limits<double>::infinity(); } var getWithDoubles (double a, double b) const override { return b != 0 ? a / b : std::numeric_limits<double>::infinity(); }
var getWithInts (int64 a, int64 b) const override { return b != 0 ? var (a / (double) b) : var (std::numeric_limits<double>::infinity()); } var getWithInts (int64 a, int64 b) const override { return b != 0 ? var (a / b) : var (std::numeric_limits<double>::infinity()); }
}; };
struct ModuloOp : public BinaryOperator struct ModuloOp : public BinaryOperator
@@ -1145,14 +1145,8 @@ struct JavascriptEngine::RootObject : public DynamicObject
match (TokenTypes::semicolon); match (TokenTypes::semicolon);
} }
if (matchIf (TokenTypes::closeParen)) s->iterator = parseExpression();
s->iterator = new Statement (location); match (TokenTypes::closeParen);
else
{
s->iterator = parseExpression();
match (TokenTypes::closeParen);
}
s->body = parseStatement(); s->body = parseStatement();
return s.release(); return s.release();
} }
@@ -1561,7 +1555,6 @@ struct JavascriptEngine::RootObject : public DynamicObject
setMethod ("log", Math_log); setMethod ("log10", Math_log10); setMethod ("log", Math_log); setMethod ("log10", Math_log10);
setMethod ("exp", Math_exp); setMethod ("pow", Math_pow); setMethod ("exp", Math_exp); setMethod ("pow", Math_pow);
setMethod ("sqr", Math_sqr); setMethod ("sqrt", Math_sqrt); setMethod ("sqr", Math_sqr); setMethod ("sqrt", Math_sqrt);
setMethod ("ceil", Math_ceil); setMethod ("floor", Math_floor);
} }
static var Math_pi (Args) { return double_Pi; } static var Math_pi (Args) { return double_Pi; }
@@ -1594,8 +1587,6 @@ struct JavascriptEngine::RootObject : public DynamicObject
static var Math_pow (Args a) { return pow (getDouble (a, 0), getDouble (a, 1)); } static var Math_pow (Args a) { return pow (getDouble (a, 0), getDouble (a, 1)); }
static var Math_sqr (Args a) { double x = getDouble (a, 0); return x * x; } static var Math_sqr (Args a) { double x = getDouble (a, 0); return x * x; }
static var Math_sqrt (Args a) { return std::sqrt (getDouble (a, 0)); } static var Math_sqrt (Args a) { return std::sqrt (getDouble (a, 0)); }
static var Math_ceil (Args a) { return std::ceil (getDouble (a, 0)); }
static var Math_floor (Args a) { return std::floor (getDouble (a, 0)); }
static Identifier getClassName() { static const Identifier i ("Math"); return i; } static Identifier getClassName() { static const Identifier i ("Math"); return i; }
template <typename Type> static Type sign (Type n) noexcept { return n > 0 ? (Type) 1 : (n < 0 ? (Type) -1 : 0); } template <typename Type> static Type sign (Type n) noexcept { return n > 0 ? (Type) 1 : (n < 0 ? (Type) -1 : 0); }
@@ -53,8 +53,6 @@
#if JUCE_WINDOWS #if JUCE_WINDOWS
#include <ctime> #include <ctime>
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
@@ -81,7 +79,6 @@
#if JUCE_LINUX #if JUCE_LINUX
#include <langinfo.h> #include <langinfo.h>
#include <ifaddrs.h>
#endif #endif
#include <pwd.h> #include <pwd.h>
@@ -307,7 +307,7 @@ void BigInteger::negate() noexcept
negative = (! negative) && ! isZero(); negative = (! negative) && ! isZero();
} }
#if JUCE_USE_MSVC_INTRINSICS && ! defined (__INTEL_COMPILER) #if JUCE_USE_INTRINSICS && ! defined (__INTEL_COMPILER)
#pragma intrinsic (_BitScanReverse) #pragma intrinsic (_BitScanReverse)
#endif #endif
@@ -317,7 +317,7 @@ inline static int highestBitInInt (uint32 n) noexcept
#if JUCE_GCC #if JUCE_GCC
return 31 - __builtin_clz (n); return 31 - __builtin_clz (n);
#elif JUCE_USE_MSVC_INTRINSICS #elif JUCE_USE_INTRINSICS
unsigned long highest; unsigned long highest;
_BitScanReverse (&highest, n); _BitScanReverse (&highest, n);
return (int) highest; return (int) highest;
@@ -218,7 +218,7 @@ private:
#else #else
#define JUCE_ATOMICS_WINDOWS 1 // Windows with intrinsics #define JUCE_ATOMICS_WINDOWS 1 // Windows with intrinsics
#if JUCE_USE_MSVC_INTRINSICS #if JUCE_USE_INTRINSICS
#ifndef __INTEL_COMPILER #ifndef __INTEL_COMPILER
#pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \ #pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \
_InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier) _InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier)
@@ -110,13 +110,13 @@ private:
//============================================================================== //==============================================================================
#if JUCE_USE_MSVC_INTRINSICS && ! defined (__INTEL_COMPILER) #if JUCE_USE_INTRINSICS && ! defined (__INTEL_COMPILER)
#pragma intrinsic (_byteswap_ulong) #pragma intrinsic (_byteswap_ulong)
#endif #endif
inline uint16 ByteOrder::swap (uint16 n) noexcept inline uint16 ByteOrder::swap (uint16 n) noexcept
{ {
#if JUCE_USE_MSVC_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic! #if JUCE_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic!
return static_cast<uint16> (_byteswap_ushort (n)); return static_cast<uint16> (_byteswap_ushort (n));
#else #else
return static_cast<uint16> ((n << 8) | (n >> 8)); return static_cast<uint16> ((n << 8) | (n >> 8));
@@ -130,7 +130,7 @@ inline uint32 ByteOrder::swap (uint32 n) noexcept
#elif JUCE_GCC && JUCE_INTEL && ! JUCE_NO_INLINE_ASM #elif JUCE_GCC && JUCE_INTEL && ! JUCE_NO_INLINE_ASM
asm("bswap %%eax" : "=a"(n) : "a"(n)); asm("bswap %%eax" : "=a"(n) : "a"(n));
return n; return n;
#elif JUCE_USE_MSVC_INTRINSICS #elif JUCE_USE_INTRINSICS
return _byteswap_ulong (n); return _byteswap_ulong (n);
#elif JUCE_MSVC && ! JUCE_NO_INLINE_ASM #elif JUCE_MSVC && ! JUCE_NO_INLINE_ASM
__asm { __asm {
@@ -150,7 +150,7 @@ inline uint64 ByteOrder::swap (uint64 value) noexcept
{ {
#if JUCE_MAC || JUCE_IOS #if JUCE_MAC || JUCE_IOS
return OSSwapInt64 (value); return OSSwapInt64 (value);
#elif JUCE_USE_MSVC_INTRINSICS #elif JUCE_USE_INTRINSICS
return _byteswap_uint64 (value); return _byteswap_uint64 (value);
#else #else
return (((int64) swap ((uint32) value)) << 32) | swap ((uint32) (value >> 32)); return (((int64) swap ((uint32) value)) << 32) | swap ((uint32) (value >> 32));
@@ -88,14 +88,14 @@ MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other)
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
MemoryBlock::MemoryBlock (MemoryBlock&& other) noexcept MemoryBlock::MemoryBlock (MemoryBlock&& other) noexcept
: data (static_cast<HeapBlock<char>&&> (other.data)), : data (static_cast <HeapBlock<char>&&> (other.data)),
size (other.size) size (other.size)
{ {
} }
MemoryBlock& MemoryBlock::operator= (MemoryBlock&& other) noexcept MemoryBlock& MemoryBlock::operator= (MemoryBlock&& other) noexcept
{ {
data = static_cast<HeapBlock<char>&&> (other.data); data = static_cast <HeapBlock<char>&&> (other.data);
size = other.size; size = other.size;
return *this; return *this;
} }
@@ -346,7 +346,7 @@ void MemoryBlock::loadFromHexString (StringRef hex)
if (c == 0) if (c == 0)
{ {
setSize (static_cast<size_t> (dest - data)); setSize (static_cast <size_t> (dest - data));
return; return;
} }
} }
@@ -182,11 +182,11 @@ public:
/** Swaps this object with that of another ScopedPointer. /** Swaps this object with that of another ScopedPointer.
The two objects simply exchange their pointers. The two objects simply exchange their pointers.
*/ */
void swapWith (ScopedPointer<ObjectType>& other) noexcept void swapWith (ScopedPointer <ObjectType>& other) noexcept
{ {
// Two ScopedPointers should never be able to refer to the same object - if // Two ScopedPointers should never be able to refer to the same object - if
// this happens, you must have done something dodgy! // this happens, you must have done something dodgy!
jassert (object != other.object || this == other.getAddress() || object == nullptr); jassert (object != other.object || this == other.getAddress());
std::swap (object, other.object); std::swap (object, other.object);
} }
@@ -231,7 +231,7 @@ private:
template <class ObjectType> template <class ObjectType>
bool operator== (const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept bool operator== (const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept
{ {
return static_cast<ObjectType*> (pointer1) == pointer2; return static_cast <ObjectType*> (pointer1) == pointer2;
} }
/** Compares a ScopedPointer with another pointer. /** Compares a ScopedPointer with another pointer.
@@ -240,7 +240,7 @@ bool operator== (const ScopedPointer<ObjectType>& pointer1, ObjectType* const po
template <class ObjectType> template <class ObjectType>
bool operator!= (const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept bool operator!= (const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept
{ {
return static_cast<ObjectType*> (pointer1) != pointer2; return static_cast <ObjectType*> (pointer1) != pointer2;
} }
//============================================================================== //==============================================================================
@@ -158,7 +158,7 @@ public:
public: public:
Master() noexcept {} Master() noexcept {}
~Master() noexcept ~Master()
{ {
// You must remember to call clear() in your source object's destructor! See the notes // You must remember to call clear() in your source object's destructor! See the notes
// for the WeakReference class for an example of how to do this. // for the WeakReference class for an example of how to do this.
@@ -187,7 +187,7 @@ public:
to zero all the references to this object that may be out there. See the WeakReference to zero all the references to this object that may be out there. See the WeakReference
class notes for an example of how to do this. class notes for an example of how to do this.
*/ */
void clear() noexcept void clear()
{ {
if (sharedPointer != nullptr) if (sharedPointer != nullptr)
sharedPointer->clearPointer(); sharedPointer->clearPointer();
@@ -166,7 +166,7 @@ public:
int numBytes = stream.callIntMethod (HTTPStream.read, javaArray, (jint) bytesToRead); int numBytes = stream.callIntMethod (HTTPStream.read, javaArray, (jint) bytesToRead);
if (numBytes > 0) if (numBytes > 0)
env->GetByteArrayRegion (javaArray, 0, numBytes, static_cast<jbyte*> (buffer)); env->GetByteArrayRegion (javaArray, 0, numBytes, static_cast <jbyte*> (buffer));
env->DeleteLocalRef (javaArray); env->DeleteLocalRef (javaArray);
return numBytes; return numBytes;
@@ -31,26 +31,26 @@ void MACAddress::findAllAddresses (Array<MACAddress>& result)
const int s = socket (AF_INET, SOCK_DGRAM, 0); const int s = socket (AF_INET, SOCK_DGRAM, 0);
if (s != -1) if (s != -1)
{ {
struct ifaddrs* addrs = nullptr; char buf [1024];
struct ifconf ifc;
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
ioctl (s, SIOCGIFCONF, &ifc);
if (getifaddrs (&addrs) != -1) for (unsigned int i = 0; i < ifc.ifc_len / sizeof (struct ifreq); ++i)
{ {
for (struct ifaddrs* i = addrs; i != nullptr; i = i->ifa_next) struct ifreq ifr;
strcpy (ifr.ifr_name, ifc.ifc_req[i].ifr_name);
if (ioctl (s, SIOCGIFFLAGS, &ifr) == 0
&& (ifr.ifr_flags & IFF_LOOPBACK) == 0
&& ioctl (s, SIOCGIFHWADDR, &ifr) == 0)
{ {
struct ifreq ifr; MACAddress ma ((const uint8*) ifr.ifr_hwaddr.sa_data);
strcpy (ifr.ifr_name, i->ifa_name);
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl (s, SIOCGIFHWADDR, &ifr) == 0) if (! ma.isNull())
{ result.addIfNotAlreadyThere (ma);
MACAddress ma ((const uint8*) ifr.ifr_hwaddr.sa_data);
if (! ma.isNull())
result.addIfNotAlreadyThere (ma);
}
} }
freeifaddrs (addrs);
} }
close (s); close (s);
@@ -263,7 +263,7 @@ private:
} }
} }
String responseHeader (readResponse (timeOutTime)); String responseHeader (readResponse (socketHandle, timeOutTime));
position = 0; position = 0;
if (responseHeader.isNotEmpty()) if (responseHeader.isNotEmpty())
@@ -302,7 +302,7 @@ private:
} }
//============================================================================== //==============================================================================
String readResponse (const uint32 timeOutTime) String readResponse (const int socketHandle, const uint32 timeOutTime)
{ {
int numConsecutiveLFs = 0; int numConsecutiveLFs = 0;
MemoryOutputStream buffer; MemoryOutputStream buffer;
@@ -338,8 +338,7 @@ private:
dest << "\r\n" << key << ' ' << value; dest << "\r\n" << key << ' ' << value;
} }
static void writeHost (MemoryOutputStream& dest, const bool isPost, static void writeHost (MemoryOutputStream& dest, const bool isPost, const String& path, const String& host, const int port)
const String& path, const String& host, int /*port*/)
{ {
dest << (isPost ? "POST " : "GET ") << path << " HTTP/1.0\r\nHost: " << host; dest << (isPost ? "POST " : "GET ") << path << " HTTP/1.0\r\nHost: " << host;
} }
@@ -234,13 +234,7 @@ namespace
if (isDir != nullptr) *isDir = statOk && ((info.st_mode & S_IFDIR) != 0); if (isDir != nullptr) *isDir = statOk && ((info.st_mode & S_IFDIR) != 0);
if (fileSize != nullptr) *fileSize = statOk ? info.st_size : 0; if (fileSize != nullptr) *fileSize = statOk ? info.st_size : 0;
if (modTime != nullptr) *modTime = Time (statOk ? (int64) info.st_mtime * 1000 : 0); if (modTime != nullptr) *modTime = Time (statOk ? (int64) info.st_mtime * 1000 : 0);
if (creationTime != nullptr) *creationTime = Time (statOk ? (int64) info.st_ctime * 1000 : 0);
if (creationTime != nullptr) *creationTime = Time ((! statOk) ? 0 : (int64) (1000 *
#if JUCE_MAC || JUCE_IOS
info.st_birthtime));
#else
info.st_ctime));
#endif
} }
if (isReadOnly != nullptr) if (isReadOnly != nullptr)
@@ -670,7 +664,6 @@ int File::getVolumeSerialNumber() const
} }
//============================================================================== //==============================================================================
#if ! JUCE_IOS
void juce_runSystemCommand (const String&); void juce_runSystemCommand (const String&);
void juce_runSystemCommand (const String& command) void juce_runSystemCommand (const String& command)
{ {
@@ -691,7 +684,7 @@ String juce_getOutputFromCommand (const String& command)
tempFile.deleteFile(); tempFile.deleteFile();
return result; return result;
} }
#endif
//============================================================================== //==============================================================================
#if JUCE_IOS #if JUCE_IOS
@@ -38,7 +38,7 @@ void Logger::outputDebugString (const String& text)
#endif #endif
//============================================================================== //==============================================================================
#if JUCE_USE_MSVC_INTRINSICS #if JUCE_USE_INTRINSICS
// CPU info functions using intrinsics... // CPU info functions using intrinsics...
@@ -313,7 +313,7 @@ double Time::getMillisecondCounterHiRes() noexcept { return hiResCounterHa
//============================================================================== //==============================================================================
static int64 juce_getClockCycleCounter() noexcept static int64 juce_getClockCycleCounter() noexcept
{ {
#if JUCE_USE_MSVC_INTRINSICS #if JUCE_USE_INTRINSICS
// MS intrinsics version... // MS intrinsics version...
return (int64) __rdtsc(); return (int64) __rdtsc();
@@ -36,7 +36,7 @@ void* getUser32Function (const char* functionName)
} }
//============================================================================== //==============================================================================
#if ! JUCE_USE_MSVC_INTRINSICS #if ! JUCE_USE_INTRINSICS
// In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in // In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in
// older ones we have to actually call the ops as win32 functions.. // older ones we have to actually call the ops as win32 functions..
long juce_InterlockedExchange (volatile long* a, long b) noexcept { return InterlockedExchange (a, b); } long juce_InterlockedExchange (volatile long* a, long b) noexcept { return InterlockedExchange (a, b); }
@@ -418,10 +418,8 @@ bool StreamingSocket::createListener (const int newPortNumber, const String& loc
if (handle < 0) if (handle < 0)
return false; return false;
#if ! JUCE_WINDOWS // on windows, adding this option produces behaviour different to posix
const int reuse = 1; const int reuse = 1;
setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const char*) &reuse, sizeof (reuse)); setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const char*) &reuse, sizeof (reuse));
#endif
if (bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) < 0 if (bind (handle, (struct sockaddr*) &servTmpAddr, sizeof (struct sockaddr_in)) < 0
|| listen (handle, SOMAXCONN) < 0) || listen (handle, SOMAXCONN) < 0)
@@ -179,11 +179,6 @@ String URL::toString (const bool includeGetParameters) const
return url; return url;
} }
bool URL::isEmpty() const noexcept
{
return url.isEmpty();
}
bool URL::isWellFormed() const bool URL::isWellFormed() const
{ {
//xxx TODO //xxx TODO
@@ -76,9 +76,6 @@ public:
*/ */
String toString (bool includeGetParameters) const; String toString (bool includeGetParameters) const;
/** Returns true if the URL is an empty string. */
bool isEmpty() const noexcept;
/** True if it seems to be valid. */ /** True if it seems to be valid. */
bool isWellFormed() const; bool isWellFormed() const;
@@ -68,7 +68,7 @@
@see jassert() @see jassert()
*/ */
#define juce_breakDebugger { ::kill (0, SIGTRAP); } #define juce_breakDebugger { ::kill (0, SIGTRAP); }
#elif JUCE_USE_MSVC_INTRINSICS #elif JUCE_USE_INTRINSICS
#ifndef __INTEL_COMPILER #ifndef __INTEL_COMPILER
#pragma intrinsic (__debugbreak) #pragma intrinsic (__debugbreak)
#endif #endif
@@ -211,26 +211,6 @@ namespace juce
#define JUCE_STRINGIFY(item) JUCE_STRINGIFY_MACRO_HELPER (item) #define JUCE_STRINGIFY(item) JUCE_STRINGIFY_MACRO_HELPER (item)
//==============================================================================
#if JUCE_MSVC && ! defined (DOXYGEN)
#define JUCE_WARNING_HELPER(file, line, mess) message(file "(" JUCE_STRINGIFY (line) ") : Warning: " #mess)
#define JUCE_COMPILER_WARNING(message) __pragma(JUCE_WARNING_HELPER (__FILE__, __LINE__, message));
#else
#ifndef DOXYGEN
#define JUCE_WARNING_HELPER(mess) message(#mess)
#endif
/** This macro allows you to emit a custom compiler warning message.
Very handy for marking bits of code as "to-do" items, or for shaming
code written by your co-workers in a way that's hard to ignore.
GCC and Clang provide the \#warning directive, but MSVC doesn't, so this macro
is a cross-compiler way to get the same functionality as \#warning.
*/
#define JUCE_COMPILER_WARNING(message) _Pragma(JUCE_STRINGIFY (JUCE_WARNING_HELPER (message)));
#endif
//============================================================================== //==============================================================================
#if JUCE_CATCH_UNHANDLED_EXCEPTIONS #if JUCE_CATCH_UNHANDLED_EXCEPTIONS
@@ -73,7 +73,7 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#if JUCE_USE_MSVC_INTRINSICS #if JUCE_USE_INTRINSICS
#include <intrin.h> #include <intrin.h>
#endif #endif
@@ -155,7 +155,7 @@
#define JUCE_BIG_ENDIAN 1 #define JUCE_BIG_ENDIAN 1
#endif #endif
#if defined (__LP64__) || defined (_LP64) || defined (__arm64__) #if defined (__LP64__) || defined (_LP64)
#define JUCE_64BIT 1 #define JUCE_64BIT 1
#else #else
#define JUCE_32BIT 1 #define JUCE_32BIT 1
@@ -192,7 +192,7 @@
#endif #endif
#if JUCE_64BIT || ! JUCE_VC7_OR_EARLIER #if JUCE_64BIT || ! JUCE_VC7_OR_EARLIER
#define JUCE_USE_MSVC_INTRINSICS 1 #define JUCE_USE_INTRINSICS 1
#endif #endif
#else #else
#error unknown compiler #error unknown compiler
@@ -1204,16 +1204,16 @@ public:
//============================================================================== //==============================================================================
#if JUCE_MAC || JUCE_IOS || DOXYGEN #if JUCE_MAC || JUCE_IOS || DOXYGEN
/** OSX ONLY - Creates a String from an OSX CFString. */ /** MAC ONLY - Creates a String from an OSX CFString. */
static String fromCFString (CFStringRef cfString); static String fromCFString (CFStringRef cfString);
/** OSX ONLY - Converts this string to a CFString. /** MAC ONLY - Converts this string to a CFString.
Remember that you must use CFRelease() to free the returned string when you're Remember that you must use CFRelease() to free the returned string when you're
finished with it. finished with it.
*/ */
CFStringRef toCFString() const; CFStringRef toCFString() const;
/** OSX ONLY - Returns a copy of this string in which any decomposed unicode characters have /** MAC ONLY - Returns a copy of this string in which any decomposed unicode characters have
been converted to their precomposed equivalents. */ been converted to their precomposed equivalents. */
String convertToPrecomposedUnicode() const; String convertToPrecomposedUnicode() const;
#endif #endif
@@ -714,7 +714,7 @@ bool XmlElement::isEquivalentTo (const XmlElement* const other,
{ {
if (thisAtt == nullptr || otherAtt == nullptr) if (thisAtt == nullptr || otherAtt == nullptr)
{ {
if (thisAtt == otherAtt) // both nullptr, so it's a match if (thisAtt == otherAtt) // both 0, so it's a match
break; break;
return false; return false;
@@ -599,17 +599,10 @@ public:
/** Returns true if the given element is a child of this one. */ /** Returns true if the given element is a child of this one. */
bool containsChildElement (const XmlElement* possibleChild) const noexcept; bool containsChildElement (const XmlElement* possibleChild) const noexcept;
/** Recursively searches all sub-elements of this one, looking for an element /** Recursively searches all sub-elements to find one that contains the specified
which is the direct parent of the specified element. child element.
Because elements don't store a pointer to their parent, if you have one
and need to find its parent, the only way to do so is to exhaustively
search the whole tree for it.
If the given child is found somewhere in this element's hierarchy, then
this method will return its parent. If not, it will return nullptr.
*/ */
XmlElement* findParentElementOf (const XmlElement* childToSearchFor) noexcept; XmlElement* findParentElementOf (const XmlElement* elementToLookFor) noexcept;
//============================================================================== //==============================================================================
/** Sorts the child elements using a comparator. /** Sorts the child elements using a comparator.
@@ -54,11 +54,6 @@ bool RSAKey::operator!= (const RSAKey& other) const noexcept
return ! operator== (other); return ! operator== (other);
} }
bool RSAKey::isValid() const noexcept
{
return operator!= (RSAKey());
}
String RSAKey::toString() const String RSAKey::toString() const
{ {
return part1.toString (16) + "," + part2.toString (16); return part1.toString (16) + "," + part2.toString (16);
@@ -113,15 +113,11 @@ public:
//============================================================================== //==============================================================================
/** Turns the key into a string representation. /** Turns the key into a string representation.
This can be reloaded using the constructor that takes a string. This can be reloaded using the constructor that takes a string.
*/ */
String toString() const; String toString() const;
/** Returns true if the object is a valid key, or false if it was created by
the default constructor.
*/
bool isValid() const noexcept;
//============================================================================== //==============================================================================
/** Encodes or decodes a value. /** Encodes or decodes a value.
@@ -29,6 +29,10 @@ struct UndoManager::ActionSet
time (Time::getCurrentTime()) time (Time::getCurrentTime())
{} {}
OwnedArray <UndoableAction> actions;
String name;
Time time;
bool perform() const bool perform() const
{ {
for (int i = 0; i < actions.size(); ++i) for (int i = 0; i < actions.size(); ++i)
@@ -56,10 +60,6 @@ struct UndoManager::ActionSet
return total; return total;
} }
OwnedArray<UndoableAction> actions;
String name;
Time time;
}; };
//============================================================================== //==============================================================================
@@ -101,19 +101,6 @@ void UndoManager::setMaxNumberOfStoredUnits (const int maxNumberOfUnitsToKeep,
//============================================================================== //==============================================================================
bool UndoManager::perform (UndoableAction* const newAction, const String& actionName) bool UndoManager::perform (UndoableAction* const newAction, const String& actionName)
{
if (perform (newAction))
{
if (actionName.isNotEmpty())
setCurrentTransactionName (actionName);
return true;
}
return false;
}
bool UndoManager::perform (UndoableAction* const newAction)
{ {
if (newAction != nullptr) if (newAction != nullptr)
{ {
@@ -126,6 +113,9 @@ bool UndoManager::perform (UndoableAction* const newAction)
return false; return false;
} }
if (actionName.isNotEmpty())
currentTransactionName = actionName;
if (action->perform()) if (action->perform())
{ {
ActionSet* actionSet = getCurrentSet(); ActionSet* actionSet = getCurrentSet();
@@ -144,7 +134,7 @@ bool UndoManager::perform (UndoableAction* const newAction)
} }
else else
{ {
actionSet = new ActionSet (newTransactionName); actionSet = new ActionSet (currentTransactionName);
transactions.insert (nextIndex, actionSet); transactions.insert (nextIndex, actionSet);
++nextIndex; ++nextIndex;
} }
@@ -184,31 +174,23 @@ void UndoManager::clearFutureTransactions()
} }
} }
void UndoManager::beginNewTransaction() noexcept void UndoManager::beginNewTransaction (const String& actionName)
{
beginNewTransaction (String());
}
void UndoManager::beginNewTransaction (const String& actionName) noexcept
{ {
newTransaction = true; newTransaction = true;
newTransactionName = actionName; currentTransactionName = actionName;
} }
void UndoManager::setCurrentTransactionName (const String& newName) noexcept void UndoManager::setCurrentTransactionName (const String& newName)
{ {
if (newTransaction) currentTransactionName = newName;
newTransactionName = newName;
else if (ActionSet* action = getCurrentSet())
action->name = newName;
} }
//============================================================================== //==============================================================================
UndoManager::ActionSet* UndoManager::getCurrentSet() const noexcept { return transactions [nextIndex - 1]; } UndoManager::ActionSet* UndoManager::getCurrentSet() const noexcept { return transactions [nextIndex - 1]; }
UndoManager::ActionSet* UndoManager::getNextSet() const noexcept { return transactions [nextIndex]; } UndoManager::ActionSet* UndoManager::getNextSet() const noexcept { return transactions [nextIndex]; }
bool UndoManager::canUndo() const noexcept { return getCurrentSet() != nullptr; } bool UndoManager::canUndo() const { return getCurrentSet() != nullptr; }
bool UndoManager::canRedo() const noexcept { return getNextSet() != nullptr; } bool UndoManager::canRedo() const { return getNextSet() != nullptr; }
bool UndoManager::undo() bool UndoManager::undo()
{ {
@@ -285,7 +267,7 @@ bool UndoManager::undoCurrentTransactionOnly()
return newTransaction ? false : undo(); return newTransaction ? false : undo();
} }
void UndoManager::getActionsInCurrentTransaction (Array<const UndoableAction*>& actionsFound) const void UndoManager::getActionsInCurrentTransaction (Array <const UndoableAction*>& actionsFound) const
{ {
if (! newTransaction) if (! newTransaction)
if (const ActionSet* const s = getCurrentSet()) if (const ActionSet* const s = getCurrentSet())
@@ -98,32 +98,16 @@ public:
//============================================================================== //==============================================================================
/** Performs an action and adds it to the undo history list. /** Performs an action and adds it to the undo history list.
@param action the action to perform - this object will be deleted by @param action the action to perform - this will be deleted by the UndoManager
the UndoManager when no longer needed when no longer needed
@returns true if the command succeeds - see UndoableAction::perform
@see beginNewTransaction
*/
bool perform (UndoableAction* action);
/** Performs an action and also gives it a name.
@param action the action to perform - this object will be deleted by
the UndoManager when no longer needed
@param actionName if this string is non-empty, the current transaction will be @param actionName if this string is non-empty, the current transaction will be
given this name; if it's empty, the current transaction name will given this name; if it's empty, the current transaction name will
be left unchanged. See setCurrentTransactionName() be left unchanged. See setCurrentTransactionName()
@returns true if the command succeeds - see UndoableAction::perform @returns true if the command succeeds - see UndoableAction::perform
@see beginNewTransaction @see beginNewTransaction
*/ */
bool perform (UndoableAction* action, const String& actionName); bool perform (UndoableAction* action,
const String& actionName = String());
/** Starts a new group of actions that together will be treated as a single transaction.
All actions that are passed to the perform() method between calls to this
method are grouped together and undone/redone together by a single call to
undo() or redo().
*/
void beginNewTransaction() noexcept;
/** Starts a new group of actions that together will be treated as a single transaction. /** Starts a new group of actions that together will be treated as a single transaction.
@@ -134,7 +118,7 @@ public:
@param actionName a description of the transaction that is about to be @param actionName a description of the transaction that is about to be
performed performed
*/ */
void beginNewTransaction (const String& actionName) noexcept; void beginNewTransaction (const String& actionName = String());
/** Changes the name stored for the current transaction. /** Changes the name stored for the current transaction.
@@ -142,15 +126,19 @@ public:
called, but this can be used to change that name without starting a new called, but this can be used to change that name without starting a new
transaction. transaction.
*/ */
void setCurrentTransactionName (const String& newName) noexcept; void setCurrentTransactionName (const String& newName);
//============================================================================== //==============================================================================
/** Returns true if there's at least one action in the list to undo. /** Returns true if there's at least one action in the list to undo.
@see getUndoDescription, undo, canRedo @see getUndoDescription, undo, canRedo
*/ */
bool canUndo() const noexcept; bool canUndo() const;
/** Returns the description of the transaction that would be next to get undone.
The description returned is the one that was passed into beginNewTransaction
before the set of actions was performed.
/** Returns the name of the transaction that will be rolled-back when undo() is called.
@see undo @see undo
*/ */
String getUndoDescription() const; String getUndoDescription() const;
@@ -184,7 +172,7 @@ public:
The first item in the list is the earliest action performed. The first item in the list is the earliest action performed.
*/ */
void getActionsInCurrentTransaction (Array<const UndoableAction*>& actionsFound) const; void getActionsInCurrentTransaction (Array <const UndoableAction*>& actionsFound) const;
/** Returns the number of UndoableAction objects that have been performed during the /** Returns the number of UndoableAction objects that have been performed during the
transaction that is currently open. transaction that is currently open.
@@ -206,9 +194,12 @@ public:
/** Returns true if there's at least one action in the list to redo. /** Returns true if there's at least one action in the list to redo.
@see getRedoDescription, redo, canUndo @see getRedoDescription, redo, canUndo
*/ */
bool canRedo() const noexcept; bool canRedo() const;
/** Returns the description of the transaction that would be next to get redone.
The description returned is the one that was passed into beginNewTransaction
before the set of actions was performed.
/** Returns the name of the transaction that will be redone when redo() is called.
@see redo @see redo
*/ */
String getRedoDescription() const; String getRedoDescription() const;
@@ -225,7 +216,7 @@ private:
struct ActionSet; struct ActionSet;
friend struct ContainerDeletePolicy<ActionSet>; friend struct ContainerDeletePolicy<ActionSet>;
OwnedArray<ActionSet> transactions; OwnedArray<ActionSet> transactions;
String newTransactionName; String currentTransactionName;
int totalUnitsStored, maxNumUnitsToKeep, minimumTransactionsToKeep, nextIndex; int totalUnitsStored, maxNumUnitsToKeep, minimumTransactionsToKeep, nextIndex;
bool newTransaction, reentrancyCheck; bool newTransaction, reentrancyCheck;
ActionSet* getCurrentSet() const noexcept; ActionSet* getCurrentSet() const noexcept;
@@ -318,10 +318,7 @@ public:
/** Creates an XmlElement that holds a complete image of this node and all its children. /** Creates an XmlElement that holds a complete image of this node and all its children.
If this node is invalid, this may return nullptr. Otherwise, the XML that is produced can If this node is invalid, this may return nullptr. Otherwise, the XML that is produced can
be used to recreate a similar node by calling fromXml(). be used to recreate a similar node by calling fromXml()
The caller must delete the object that is returned.
@see fromXml @see fromXml
*/ */
XmlElement* createXml() const; XmlElement* createXml() const;
@@ -25,11 +25,12 @@
class ActionBroadcaster::ActionMessage : public MessageManager::MessageBase class ActionBroadcaster::ActionMessage : public MessageManager::MessageBase
{ {
public: public:
ActionMessage (const ActionBroadcaster* ab, ActionMessage (const ActionBroadcaster* const broadcaster_,
const String& messageText, ActionListener* l) noexcept const String& messageText,
: broadcaster (const_cast<ActionBroadcaster*> (ab)), ActionListener* const listener_) noexcept
: broadcaster (const_cast <ActionBroadcaster*> (broadcaster_)),
message (messageText), message (messageText),
listener (l) listener (listener_)
{} {}
void messageCallback() override void messageCallback() override
@@ -232,7 +232,7 @@ int JUCEApplicationBase::main()
jassert (app != nullptr); jassert (app != nullptr);
if (! app->initialiseApp()) if (! app->initialiseApp())
return app->getApplicationReturnValue(); return 0;
JUCE_TRY JUCE_TRY
{ {
@@ -50,24 +50,24 @@
MyJUCEApp() {} MyJUCEApp() {}
~MyJUCEApp() {} ~MyJUCEApp() {}
void initialise (const String& commandLine) override void initialise (const String& commandLine)
{ {
myMainWindow = new MyApplicationWindow(); myMainWindow = new MyApplicationWindow();
myMainWindow->setBounds (100, 100, 400, 500); myMainWindow->setBounds (100, 100, 400, 500);
myMainWindow->setVisible (true); myMainWindow->setVisible (true);
} }
void shutdown() override void shutdown()
{ {
myMainWindow = nullptr; myMainWindow = nullptr;
} }
const String getApplicationName() override const String getApplicationName()
{ {
return "Super JUCE-o-matic"; return "Super JUCE-o-matic";
} }
const String getApplicationVersion() override const String getApplicationVersion()
{ {
return "1.0"; return "1.0";
} }
@@ -288,10 +288,7 @@ bool MessageManagerLock::attemptLock (Thread* const threadToCheck, ThreadPoolJob
blockingMessage = new BlockingMessage(); blockingMessage = new BlockingMessage();
if (! blockingMessage->post()) if (! blockingMessage->post())
{
blockingMessage = nullptr;
return false; return false;
}
while (! blockingMessage->lockedEvent.wait (20)) while (! blockingMessage->lockedEvent.wait (20))
{ {
@@ -83,8 +83,8 @@ public:
void transformPoint (ValueType& x, ValueType& y) const noexcept void transformPoint (ValueType& x, ValueType& y) const noexcept
{ {
const ValueType oldX = x; const ValueType oldX = x;
x = static_cast<ValueType> (mat00 * oldX + mat01 * y + mat02); x = static_cast <ValueType> (mat00 * oldX + mat01 * y + mat02);
y = static_cast<ValueType> (mat10 * oldX + mat11 * y + mat12); y = static_cast <ValueType> (mat10 * oldX + mat11 * y + mat12);
} }
/** Transforms two 2D coordinates using this matrix. /** Transforms two 2D coordinates using this matrix.
@@ -97,10 +97,10 @@ public:
ValueType& x2, ValueType& y2) const noexcept ValueType& x2, ValueType& y2) const noexcept
{ {
const ValueType oldX1 = x1, oldX2 = x2; const ValueType oldX1 = x1, oldX2 = x2;
x1 = static_cast<ValueType> (mat00 * oldX1 + mat01 * y1 + mat02); x1 = static_cast <ValueType> (mat00 * oldX1 + mat01 * y1 + mat02);
y1 = static_cast<ValueType> (mat10 * oldX1 + mat11 * y1 + mat12); y1 = static_cast <ValueType> (mat10 * oldX1 + mat11 * y1 + mat12);
x2 = static_cast<ValueType> (mat00 * oldX2 + mat01 * y2 + mat02); x2 = static_cast <ValueType> (mat00 * oldX2 + mat01 * y2 + mat02);
y2 = static_cast<ValueType> (mat10 * oldX2 + mat11 * y2 + mat12); y2 = static_cast <ValueType> (mat10 * oldX2 + mat11 * y2 + mat12);
} }
/** Transforms three 2D coordinates using this matrix. /** Transforms three 2D coordinates using this matrix.
@@ -114,12 +114,12 @@ public:
ValueType& x3, ValueType& y3) const noexcept ValueType& x3, ValueType& y3) const noexcept
{ {
const ValueType oldX1 = x1, oldX2 = x2, oldX3 = x3; const ValueType oldX1 = x1, oldX2 = x2, oldX3 = x3;
x1 = static_cast<ValueType> (mat00 * oldX1 + mat01 * y1 + mat02); x1 = static_cast <ValueType> (mat00 * oldX1 + mat01 * y1 + mat02);
y1 = static_cast<ValueType> (mat10 * oldX1 + mat11 * y1 + mat12); y1 = static_cast <ValueType> (mat10 * oldX1 + mat11 * y1 + mat12);
x2 = static_cast<ValueType> (mat00 * oldX2 + mat01 * y2 + mat02); x2 = static_cast <ValueType> (mat00 * oldX2 + mat01 * y2 + mat02);
y2 = static_cast<ValueType> (mat10 * oldX2 + mat11 * y2 + mat12); y2 = static_cast <ValueType> (mat10 * oldX2 + mat11 * y2 + mat12);
x3 = static_cast<ValueType> (mat00 * oldX3 + mat01 * y3 + mat02); x3 = static_cast <ValueType> (mat00 * oldX3 + mat01 * y3 + mat02);
y3 = static_cast<ValueType> (mat10 * oldX3 + mat11 * y3 + mat12); y3 = static_cast <ValueType> (mat10 * oldX3 + mat11 * y3 + mat12);
} }
//============================================================================== //==============================================================================
@@ -231,7 +231,8 @@ public:
float x10, float y10, float x10, float y10,
float x01, float y01) noexcept; float x01, float y01) noexcept;
/** Returns the transform that will map three specified points onto three target points. */ /** Returns the transform that will map three specified points onto three target points.
*/
static AffineTransform fromTargetPoints (float sourceX1, float sourceY1, float targetX1, float targetY1, static AffineTransform fromTargetPoints (float sourceX1, float sourceY1, float targetX1, float targetY1,
float sourceX2, float sourceY2, float targetX2, float targetY2, float sourceX2, float sourceY2, float targetX2, float targetY2,
float sourceX3, float sourceY3, float targetX3, float targetY3) noexcept; float sourceX3, float sourceY3, float targetX3, float targetY3) noexcept;
@@ -488,13 +488,12 @@ bool PNGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
PNG_COMPRESSION_TYPE_BASE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE); PNG_FILTER_TYPE_BASE);
HeapBlock<uint8> rowData ((size_t) width * 4); HeapBlock <uint8> rowData ((size_t) width * 4);
png_color_8 sig_bit; png_color_8 sig_bit;
sig_bit.red = 8; sig_bit.red = 8;
sig_bit.green = 8; sig_bit.green = 8;
sig_bit.blue = 8; sig_bit.blue = 8;
sig_bit.gray = 0;
sig_bit.alpha = 8; sig_bit.alpha = 8;
png_set_sBIT (pngWriteStruct, pngInfoStruct, &sig_bit); png_set_sBIT (pngWriteStruct, pngInfoStruct, &sig_bit);
@@ -1026,7 +1026,7 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr,
if ((transforms & PNG_TRANSFORM_SHIFT) if ((transforms & PNG_TRANSFORM_SHIFT)
&& png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
{ {
png_color_8p sig_bit = 0; png_color_8p sig_bit;
png_get_sBIT(png_ptr, info_ptr, &sig_bit); png_get_sBIT(png_ptr, info_ptr, &sig_bit);
png_set_shift(png_ptr, sig_bit); png_set_shift(png_ptr, sig_bit);
@@ -197,11 +197,11 @@ Image Image::getClippedImage (const Rectangle<int>& area) const
//============================================================================== //==============================================================================
Image::Image() noexcept Image::Image()
{ {
} }
Image::Image (ImagePixelData* const instance) noexcept Image::Image (ImagePixelData* const instance)
: image (instance) : image (instance)
{ {
} }
@@ -216,7 +216,7 @@ Image::Image (const PixelFormat format, int width, int height, bool clearImage,
{ {
} }
Image::Image (const Image& other) noexcept Image::Image (const Image& other)
: image (other.image) : image (other.image)
{ {
} }
@@ -67,7 +67,7 @@ public:
//============================================================================== //==============================================================================
/** Creates a null image. */ /** Creates a null image. */
Image() noexcept; Image();
/** Creates an image with a specified size and format. /** Creates an image with a specified size and format.
@@ -106,7 +106,7 @@ public:
point to the same shared image data. To make sure that an Image object has its own unique, point to the same shared image data. To make sure that an Image object has its own unique,
unshared internal data, call duplicateIfShared(). unshared internal data, call duplicateIfShared().
*/ */
Image (const Image&) noexcept; Image (const Image&);
/** Makes this image refer to the same underlying image as another object. /** Makes this image refer to the same underlying image as another object.
@@ -408,7 +408,7 @@ public:
ImagePixelData* getPixelData() const noexcept { return image; } ImagePixelData* getPixelData() const noexcept { return image; }
/** @internal */ /** @internal */
explicit Image (ImagePixelData*) noexcept; explicit Image (ImagePixelData*);
private: private:
//============================================================================== //==============================================================================
@@ -506,8 +506,8 @@ private:
lf.lfOutPrecision = OUT_OUTLINE_PRECIS; lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lf.lfQuality = PROOF_QUALITY; lf.lfQuality = PROOF_QUALITY;
lf.lfItalic = (BYTE) (style.contains ("Italic") ? TRUE : FALSE); lf.lfItalic = (BYTE) (style == "Italic" ? TRUE : FALSE);
lf.lfWeight = style.contains ("Bold") ? FW_BOLD : FW_NORMAL; lf.lfWeight = style == "Bold" ? FW_BOLD : FW_NORMAL;
lf.lfHeight = -256; lf.lfHeight = -256;
name.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName)); name.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
@@ -53,24 +53,24 @@
MyJUCEApp() {} MyJUCEApp() {}
~MyJUCEApp() {} ~MyJUCEApp() {}
void initialise (const String& commandLine) override void initialise (const String& commandLine)
{ {
myMainWindow = new MyApplicationWindow(); myMainWindow = new MyApplicationWindow();
myMainWindow->setBounds (100, 100, 400, 500); myMainWindow->setBounds (100, 100, 400, 500);
myMainWindow->setVisible (true); myMainWindow->setVisible (true);
} }
void shutdown() override void shutdown()
{ {
myMainWindow = nullptr; myMainWindow = nullptr;
} }
const String getApplicationName() override const String getApplicationName()
{ {
return "Super JUCE-o-matic"; return "Super JUCE-o-matic";
} }
const String getApplicationVersion() override const String getApplicationVersion()
{ {
return "1.0"; return "1.0";
} }
@@ -252,7 +252,7 @@ bool KeyPressMappingSet::restoreFromXml (const XmlElement& xmlVersion)
XmlElement* KeyPressMappingSet::createXml (const bool saveDifferencesFromDefaultSet) const XmlElement* KeyPressMappingSet::createXml (const bool saveDifferencesFromDefaultSet) const
{ {
ScopedPointer<KeyPressMappingSet> defaultSet; ScopedPointer <KeyPressMappingSet> defaultSet;
if (saveDifferencesFromDefaultSet) if (saveDifferencesFromDefaultSet)
{ {
@@ -141,7 +141,7 @@ public:
} }
private: private:
Array<MouseListener*> listeners; Array <MouseListener*> listeners;
int numDeepMouseListeners; int numDeepMouseListeners;
class BailOutChecker2 class BailOutChecker2
@@ -256,7 +256,7 @@ struct Component::ComponentHelpers
#if JUCE_MODAL_LOOPS_PERMITTED #if JUCE_MODAL_LOOPS_PERMITTED
static void* runModalLoopCallback (void* userData) static void* runModalLoopCallback (void* userData)
{ {
return (void*) (pointer_sized_int) static_cast<Component*> (userData)->runModalLoop(); return (void*) (pointer_sized_int) static_cast <Component*> (userData)->runModalLoop();
} }
#endif #endif
@@ -399,6 +399,16 @@ struct Component::ComponentHelpers
return convertFromDistantParentSpace (topLevelComp, *target, p); return convertFromDistantParentSpace (topLevelComp, *target, p);
} }
static Rectangle<int> getUnclippedArea (const Component& comp)
{
Rectangle<int> r (comp.getLocalBounds());
if (Component* const p = comp.getParentComponent())
r = r.getIntersection (convertFromParentSpace (comp, getUnclippedArea (*p)));
return r;
}
static bool clipObscuredRegions (const Component& comp, Graphics& g, const Rectangle<int>& clipRect, Point<int> delta) static bool clipObscuredRegions (const Component& comp, Graphics& g, const Rectangle<int>& clipRect, Point<int> delta)
{ {
bool nothingChanged = true; bool nothingChanged = true;
@@ -431,6 +441,35 @@ struct Component::ComponentHelpers
return nothingChanged; return nothingChanged;
} }
static void subtractObscuredRegions (const Component& comp, RectangleList<int>& result,
Point<int> delta, const Rectangle<int>& clipRect,
const Component* const compToAvoid)
{
for (int i = comp.childComponentList.size(); --i >= 0;)
{
const Component* const c = comp.childComponentList.getUnchecked(i);
if (c != compToAvoid && c->isVisible())
{
if (c->isOpaque() && c->componentTransparency == 0)
{
Rectangle<int> childBounds (c->bounds.getIntersection (clipRect));
childBounds.translate (delta.x, delta.y);
result.subtract (childBounds);
}
else
{
Rectangle<int> newClip (clipRect.getIntersection (c->bounds));
newClip.translate (-c->getX(), -c->getY());
subtractObscuredRegions (*c, result, c->getPosition() + delta,
newClip, compToAvoid);
}
}
}
}
static Rectangle<int> getParentOrMainMonitorBounds (const Component& comp) static Rectangle<int> getParentOrMainMonitorBounds (const Component& comp)
{ {
if (Component* p = comp.getParentComponent()) if (Component* p = comp.getParentComponent())
@@ -441,7 +480,7 @@ struct Component::ComponentHelpers
}; };
//============================================================================== //==============================================================================
Component::Component() noexcept Component::Component()
: parentComponent (nullptr), : parentComponent (nullptr),
lookAndFeel (nullptr), lookAndFeel (nullptr),
effect (nullptr), effect (nullptr),
@@ -450,7 +489,7 @@ Component::Component() noexcept
{ {
} }
Component::Component (const String& name) noexcept Component::Component (const String& name)
: componentName (name), : componentName (name),
parentComponent (nullptr), parentComponent (nullptr),
lookAndFeel (nullptr), lookAndFeel (nullptr),
@@ -581,6 +620,7 @@ bool Component::isShowing() const
return false; return false;
} }
//============================================================================== //==============================================================================
void* Component::getWindowHandle() const void* Component::getWindowHandle() const
{ {
@@ -840,7 +880,7 @@ void Component::setBufferedToImage (const bool shouldBeBuffered)
// so by calling setBufferedToImage, you'll be deleting the custom one - this is almost certainly // so by calling setBufferedToImage, you'll be deleting the custom one - this is almost certainly
// not what you wanted to happen... If you really do know what you're doing here, and want to // not what you wanted to happen... If you really do know what you're doing here, and want to
// avoid this assertion, just call setCachedComponentImage (nullptr) before setBufferedToImage(). // avoid this assertion, just call setCachedComponentImage (nullptr) before setBufferedToImage().
jassert (cachedImage == nullptr || dynamic_cast<StandardCachedComponentImage*> (cachedImage.get()) != nullptr); jassert (cachedImage == nullptr || dynamic_cast <StandardCachedComponentImage*> (cachedImage.get()) != nullptr);
if (shouldBeBuffered) if (shouldBeBuffered)
{ {
@@ -1603,7 +1643,7 @@ Component* Component::getChildComponent (const int index) const noexcept
int Component::getIndexOfChildComponent (const Component* const child) const noexcept int Component::getIndexOfChildComponent (const Component* const child) const noexcept
{ {
return childComponentList.indexOf (const_cast<Component*> (child)); return childComponentList.indexOf (const_cast <Component*> (child));
} }
Component* Component::findChildWithID (StringRef targetID) const noexcept Component* Component::findChildWithID (StringRef targetID) const noexcept
@@ -1625,7 +1665,7 @@ Component* Component::getTopLevelComponent() const noexcept
while (comp->parentComponent != nullptr) while (comp->parentComponent != nullptr)
comp = comp->parentComponent; comp = comp->parentComponent;
return const_cast<Component*> (comp); return const_cast <Component*> (comp);
} }
bool Component::isParentOf (const Component* possibleChild) const noexcept bool Component::isParentOf (const Component* possibleChild) const noexcept
@@ -2165,7 +2205,7 @@ void Component::sendLookAndFeelChange()
Colour Component::findColour (const int colourId, const bool inheritFromParent) const Colour Component::findColour (const int colourId, const bool inheritFromParent) const
{ {
if (const var* const v = properties.getVarPointer (ComponentHelpers::getColourPropertyId (colourId))) if (const var* const v = properties.getVarPointer (ComponentHelpers::getColourPropertyId (colourId)))
return Colour ((uint32) static_cast<int> (*v)); return Colour ((uint32) static_cast <int> (*v));
if (inheritFromParent && parentComponent != nullptr if (inheritFromParent && parentComponent != nullptr
&& (lookAndFeel == nullptr || ! lookAndFeel->isColourSpecified (colourId))) && (lookAndFeel == nullptr || ! lookAndFeel->isColourSpecified (colourId)))
@@ -2244,6 +2284,28 @@ Rectangle<int> Component::getBoundsInParent() const noexcept
: bounds.transformedBy (*affineTransform); : bounds.transformedBy (*affineTransform);
} }
void Component::getVisibleArea (RectangleList<int>& result, const bool includeSiblings) const
{
result.clear();
const Rectangle<int> unclipped (ComponentHelpers::getUnclippedArea (*this));
if (! unclipped.isEmpty())
{
result.add (unclipped);
if (includeSiblings)
{
const Component* const c = getTopLevelComponent();
ComponentHelpers::subtractObscuredRegions (*c, result, getLocalPoint (c, Point<int>()),
c->getLocalBounds(), this);
}
ComponentHelpers::subtractObscuredRegions (*this, result, Point<int>(), unclipped, nullptr);
result.consolidate();
}
}
//============================================================================== //==============================================================================
void Component::mouseEnter (const MouseEvent&) {} void Component::mouseEnter (const MouseEvent&) {}
void Component::mouseExit (const MouseEvent&) {} void Component::mouseExit (const MouseEvent&) {}
@@ -2794,7 +2856,7 @@ void Component::grabFocusInternal (const FocusChangeType cause, const bool canTr
else else
{ {
// find the default child component.. // find the default child component..
ScopedPointer<KeyboardFocusTraverser> traverser (createFocusTraverser()); ScopedPointer <KeyboardFocusTraverser> traverser (createFocusTraverser());
if (traverser != nullptr) if (traverser != nullptr)
{ {
@@ -2836,7 +2898,7 @@ void Component::moveKeyboardFocusToSibling (const bool moveToNext)
if (parentComponent != nullptr) if (parentComponent != nullptr)
{ {
ScopedPointer<KeyboardFocusTraverser> traverser (createFocusTraverser()); ScopedPointer <KeyboardFocusTraverser> traverser (createFocusTraverser());
if (traverser != nullptr) if (traverser != nullptr)
{ {
@@ -2990,7 +3052,7 @@ Point<int> Component::getMouseXYRelative() const
void Component::addKeyListener (KeyListener* const newListener) void Component::addKeyListener (KeyListener* const newListener)
{ {
if (keyListeners == nullptr) if (keyListeners == nullptr)
keyListeners = new Array<KeyListener*>(); keyListeners = new Array <KeyListener*>();
keyListeners->addIfNotAlreadyThere (newListener); keyListeners->addIfNotAlreadyThere (newListener);
} }
@@ -46,7 +46,7 @@ public:
subclass of Component or use one of the other types of component from subclass of Component or use one of the other types of component from
the library. the library.
*/ */
Component() noexcept; Component();
/** Destructor. /** Destructor.
@@ -66,7 +66,7 @@ public:
/** Creates a component, setting its name at the same time. /** Creates a component, setting its name at the same time.
@see getName, setName @see getName, setName
*/ */
explicit Component (const String& componentName) noexcept; explicit Component (const String& componentName);
/** Returns the name of this component. /** Returns the name of this component.
@see setName @see setName
@@ -315,6 +315,16 @@ public:
*/ */
Rectangle<int> getBoundsInParent() const noexcept; Rectangle<int> getBoundsInParent() const noexcept;
/** Returns the region of this component that's not obscured by other, opaque components.
The RectangleList that is returned represents the area of this component
which isn't covered by opaque child components.
If includeSiblings is true, it will also take into account any siblings
that may be overlapping the component.
*/
void getVisibleArea (RectangleList<int>& result, bool includeSiblings) const;
//============================================================================== //==============================================================================
/** Returns this component's x coordinate relative the screen's top-left origin. /** Returns this component's x coordinate relative the screen's top-left origin.
@see getX, localPointToGlobal @see getX, localPointToGlobal
@@ -797,7 +807,7 @@ public:
TargetClass* findParentComponentOfClass() const TargetClass* findParentComponentOfClass() const
{ {
for (Component* p = parentComponent; p != nullptr; p = p->parentComponent) for (Component* p = parentComponent; p != nullptr; p = p->parentComponent)
if (TargetClass* const target = dynamic_cast<TargetClass*> (p)) if (TargetClass* const target = dynamic_cast <TargetClass*> (p))
return target; return target;
return nullptr; return nullptr;
@@ -1156,7 +1166,7 @@ public:
By default, components are considered transparent, unless this is used to By default, components are considered transparent, unless this is used to
make it otherwise. make it otherwise.
@see isOpaque @see isOpaque, getVisibleArea
*/ */
void setOpaque (bool shouldBeOpaque); void setOpaque (bool shouldBeOpaque);
@@ -1747,14 +1757,11 @@ public:
*/ */
virtual void focusLost (FocusChangeType cause); virtual void focusLost (FocusChangeType cause);
/** Called to indicate a change in whether or not this component is the parent of the /** Called to indicate that one of this component's children has been focused or unfocused.
currently-focused component.
Essentially this is called when the return value of a call to hasKeyboardFocus (true) has Essentially this means that the return value of a call to hasKeyboardFocus (true) has
changed. It happens when focus moves from one of this component's children (at any depth) changed. It happens when focus moves from one of this component's children (at any depth)
to a component that isn't contained in this one, (or vice-versa). to a component that isn't contained in this one, (or vice-versa).
Note that this method does NOT get called to when focus simply moves from one of its
child components to another.
@see focusGained, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus @see focusGained, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus
*/ */
@@ -1789,7 +1796,9 @@ public:
bool isMouseButtonDown() const; bool isMouseButtonDown() const;
/** True if the mouse is over this component, or if it's being dragged in this component. /** True if the mouse is over this component, or if it's being dragged in this component.
This is a handy equivalent to (isMouseOver() || isMouseButtonDown()). This is a handy equivalent to (isMouseOver() || isMouseButtonDown()).
@see isMouseOver, isMouseButtonDown, isMouseButtonDownAnywhere @see isMouseOver, isMouseButtonDown, isMouseButtonDownAnywhere
*/ */
bool isMouseOverOrDragging() const; bool isMouseOverOrDragging() const;
@@ -2127,31 +2136,31 @@ public:
SafePointer() noexcept {} SafePointer() noexcept {}
/** Creates a SafePointer that points at the given component. */ /** Creates a SafePointer that points at the given component. */
SafePointer (ComponentType* component) : weakRef (component) {} SafePointer (ComponentType* const component) : weakRef (component) {}
/** Creates a copy of another SafePointer. */ /** Creates a copy of another SafePointer. */
SafePointer (const SafePointer& other) noexcept : weakRef (other.weakRef) {} SafePointer (const SafePointer& other) noexcept : weakRef (other.weakRef) {}
/** Copies another pointer to this one. */ /** Copies another pointer to this one. */
SafePointer& operator= (const SafePointer& other) { weakRef = other.weakRef; return *this; } SafePointer& operator= (const SafePointer& other) { weakRef = other.weakRef; return *this; }
/** Copies another pointer to this one. */ /** Copies another pointer to this one. */
SafePointer& operator= (ComponentType* newComponent) { weakRef = newComponent; return *this; } SafePointer& operator= (ComponentType* const newComponent) { weakRef = newComponent; return *this; }
/** Returns the component that this pointer refers to, or null if the component no longer exists. */ /** Returns the component that this pointer refers to, or null if the component no longer exists. */
ComponentType* getComponent() const noexcept { return dynamic_cast<ComponentType*> (weakRef.get()); } ComponentType* getComponent() const noexcept { return dynamic_cast <ComponentType*> (weakRef.get()); }
/** Returns the component that this pointer refers to, or null if the component no longer exists. */ /** Returns the component that this pointer refers to, or null if the component no longer exists. */
operator ComponentType*() const noexcept { return getComponent(); } operator ComponentType*() const noexcept { return getComponent(); }
/** Returns the component that this pointer refers to, or null if the component no longer exists. */ /** Returns the component that this pointer refers to, or null if the component no longer exists. */
ComponentType* operator->() noexcept { return getComponent(); } ComponentType* operator->() noexcept { return getComponent(); }
/** Returns the component that this pointer refers to, or null if the component no longer exists. */ /** Returns the component that this pointer refers to, or null if the component no longer exists. */
const ComponentType* operator->() const noexcept { return getComponent(); } const ComponentType* operator->() const noexcept { return getComponent(); }
/** If the component is valid, this deletes it and sets this pointer to null. */ /** If the component is valid, this deletes it and sets this pointer to null. */
void deleteAndZero() { delete getComponent(); } void deleteAndZero() { delete getComponent(); }
bool operator== (ComponentType* component) const noexcept { return weakRef == component; } bool operator== (ComponentType* component) const noexcept { return weakRef == component; }
bool operator!= (ComponentType* component) const noexcept { return weakRef != component; } bool operator!= (ComponentType* component) const noexcept { return weakRef != component; }
@@ -2259,20 +2268,20 @@ private:
String componentName, componentID; String componentName, componentID;
Component* parentComponent; Component* parentComponent;
Rectangle<int> bounds; Rectangle<int> bounds;
ScopedPointer<Positioner> positioner; ScopedPointer <Positioner> positioner;
ScopedPointer<AffineTransform> affineTransform; ScopedPointer <AffineTransform> affineTransform;
Array<Component*> childComponentList; Array <Component*> childComponentList;
LookAndFeel* lookAndFeel; LookAndFeel* lookAndFeel;
MouseCursor cursor; MouseCursor cursor;
ImageEffectFilter* effect; ImageEffectFilter* effect;
ScopedPointer<CachedComponentImage> cachedImage; ScopedPointer <CachedComponentImage> cachedImage;
class MouseListenerList; class MouseListenerList;
friend class MouseListenerList; friend class MouseListenerList;
friend struct ContainerDeletePolicy<MouseListenerList>; friend struct ContainerDeletePolicy<MouseListenerList>;
ScopedPointer<MouseListenerList> mouseListeners; ScopedPointer <MouseListenerList> mouseListeners;
ScopedPointer<Array<KeyListener*> > keyListeners; ScopedPointer <Array <KeyListener*> > keyListeners;
ListenerList<ComponentListener> componentListeners; ListenerList <ComponentListener> componentListeners;
NamedValueSet properties; NamedValueSet properties;
friend class WeakReference<Component>; friend class WeakReference<Component>;
@@ -2299,9 +2308,9 @@ private:
bool mouseDownWasBlocked : 1; bool mouseDownWasBlocked : 1;
bool isMoveCallbackPending : 1; bool isMoveCallbackPending : 1;
bool isResizeCallbackPending : 1; bool isResizeCallbackPending : 1;
#if JUCE_DEBUG #if JUCE_DEBUG
bool isInsidePaintCall : 1; bool isInsidePaintCall : 1;
#endif #endif
}; };
union union
@@ -85,13 +85,31 @@ public:
newState.viewBoxW = vwh.x; newState.viewBoxW = vwh.x;
newState.viewBoxH = vwh.y; newState.viewBoxH = vwh.y;
const int placementFlags = parsePlacementFlags (xml->getStringAttribute ("preserveAspectRatio").trim()); int placementFlags = 0;
if (placementFlags != 0) const String aspect (xml->getStringAttribute ("preserveAspectRatio"));
newState.transform = RectanglePlacement (placementFlags)
.getTransformToFit (Rectangle<float> (viewboxXY.x, viewboxXY.y, vwh.x, vwh.y), if (aspect.containsIgnoreCase ("none"))
Rectangle<float> (newState.width, newState.height)) {
.followedBy (newState.transform); placementFlags = RectanglePlacement::stretchToFit;
}
else
{
if (aspect.containsIgnoreCase ("slice")) placementFlags |= RectanglePlacement::fillDestination;
if (aspect.containsIgnoreCase ("xMin")) placementFlags |= RectanglePlacement::xLeft;
else if (aspect.containsIgnoreCase ("xMax")) placementFlags |= RectanglePlacement::xRight;
else placementFlags |= RectanglePlacement::xMid;
if (aspect.containsIgnoreCase ("yMin")) placementFlags |= RectanglePlacement::yTop;
else if (aspect.containsIgnoreCase ("yMax")) placementFlags |= RectanglePlacement::yBottom;
else placementFlags |= RectanglePlacement::yMid;
}
newState.transform = RectanglePlacement (placementFlags)
.getTransformToFit (Rectangle<float> (viewboxXY.x, viewboxXY.y, vwh.x, vwh.y),
Rectangle<float> (newState.width, newState.height))
.followedBy (newState.transform);
} }
} }
else else
@@ -542,12 +560,24 @@ private:
path.applyTransform (transform); path.applyTransform (transform);
dp->setPath (path); dp->setPath (path);
Path::Iterator iter (path);
bool containsClosedSubPath = false;
while (iter.next())
{
if (iter.elementType == Path::Iterator::closePath)
{
containsClosedSubPath = true;
break;
}
}
dp->setFill (getPathFillType (path, dp->setFill (getPathFillType (path,
getStyleAttribute (xml, "fill"), getStyleAttribute (xml, "fill"),
getStyleAttribute (xml, "fill-opacity"), getStyleAttribute (xml, "fill-opacity"),
getStyleAttribute (xml, "opacity"), getStyleAttribute (xml, "opacity"),
pathContainsClosedSubPath (path) ? Colours::black containsClosedSubPath ? Colours::black
: Colours::transparentBlack)); : Colours::transparentBlack));
const String strokeType (getStyleAttribute (xml, "stroke")); const String strokeType (getStyleAttribute (xml, "stroke"));
@@ -564,15 +594,6 @@ private:
return dp; return dp;
} }
static bool pathContainsClosedSubPath (const Path& path) noexcept
{
for (Path::Iterator iter (path); iter.next();)
if (iter.elementType == Path::Iterator::closePath)
return true;
return false;
}
struct SetGradientStopsOp struct SetGradientStopsOp
{ {
const SVGState* state; const SVGState* state;
@@ -775,41 +796,44 @@ private:
return parseColour (fill, i, defaultColour).withMultipliedAlpha (opacity); return parseColour (fill, i, defaultColour).withMultipliedAlpha (opacity);
} }
static PathStrokeType::JointStyle getJointStyle (const String& join) noexcept
{
if (join.equalsIgnoreCase ("round")) return PathStrokeType::curved;
if (join.equalsIgnoreCase ("bevel")) return PathStrokeType::beveled;
return PathStrokeType::mitered;
}
static PathStrokeType::EndCapStyle getEndCapStyle (const String& cap) noexcept
{
if (cap.equalsIgnoreCase ("round")) return PathStrokeType::rounded;
if (cap.equalsIgnoreCase ("square")) return PathStrokeType::square;
return PathStrokeType::butt;
}
float getStrokeWidth (const String& strokeWidth) const noexcept
{
return transform.getScaleFactor() * getCoordLength (strokeWidth, viewBoxW);
}
PathStrokeType getStrokeFor (const XmlPath& xml) const PathStrokeType getStrokeFor (const XmlPath& xml) const
{ {
return PathStrokeType (getStrokeWidth (getStyleAttribute (xml, "stroke-width", "1")), const String strokeWidth (getStyleAttribute (xml, "stroke-width"));
getJointStyle (getStyleAttribute (xml, "stroke-linejoin")), const String cap (getStyleAttribute (xml, "stroke-linecap"));
getEndCapStyle (getStyleAttribute (xml, "stroke-linecap"))); const String join (getStyleAttribute (xml, "stroke-linejoin"));
//const String mitreLimit (getStyleAttribute (xml, "stroke-miterlimit"));
//const String dashArray (getStyleAttribute (xml, "stroke-dasharray"));
//const String dashOffset (getStyleAttribute (xml, "stroke-dashoffset"));
PathStrokeType::JointStyle joinStyle = PathStrokeType::mitered;
PathStrokeType::EndCapStyle capStyle = PathStrokeType::butt;
if (join.equalsIgnoreCase ("round"))
joinStyle = PathStrokeType::curved;
else if (join.equalsIgnoreCase ("bevel"))
joinStyle = PathStrokeType::beveled;
if (cap.equalsIgnoreCase ("round"))
capStyle = PathStrokeType::rounded;
else if (cap.equalsIgnoreCase ("square"))
capStyle = PathStrokeType::square;
float ox = 0.0f, oy = 0.0f;
float x = getCoordLength (strokeWidth, viewBoxW), y = 0.0f;
transform.transformPoints (ox, oy, x, y);
return PathStrokeType (strokeWidth.isNotEmpty() ? juce_hypot (x - ox, y - oy) : 1.0f,
joinStyle, capStyle);
} }
//============================================================================== //==============================================================================
Drawable* parseText (const XmlPath& xml) Drawable* parseText (const XmlPath& xml)
{ {
Array<float> xCoords, yCoords, dxCoords, dyCoords; Array <float> xCoords, yCoords, dxCoords, dyCoords;
getCoordList (xCoords, getInheritedAttribute (xml, "x"), true, true); getCoordList (xCoords, getInheritedAttribute (xml, "x"), true, true);
getCoordList (yCoords, getInheritedAttribute (xml, "y"), true, false); getCoordList (yCoords, getInheritedAttribute (xml, "y"), true, false);
getCoordList (dxCoords, getInheritedAttribute (xml, "dx"), true, true); getCoordList (dxCoords, getInheritedAttribute (xml, "dx"), true, true);
getCoordList (dyCoords, getInheritedAttribute (xml, "dy"), true, false); getCoordList (dyCoords, getInheritedAttribute (xml, "dy"), true, false);
@@ -874,7 +898,7 @@ private:
return false; return false;
} }
float getCoordLength (const String& s, const float sizeForProportions) const noexcept float getCoordLength (const String& s, const float sizeForProportions) const
{ {
float n = s.getFloatValue(); float n = s.getFloatValue();
const int len = s.length(); const int len = s.length();
@@ -896,12 +920,13 @@ private:
return n; return n;
} }
float getCoordLength (const XmlPath& xml, const char* attName, const float sizeForProportions) const noexcept float getCoordLength (const XmlPath& xml, const char* attName, const float sizeForProportions) const
{ {
return getCoordLength (xml->getStringAttribute (attName), sizeForProportions); return getCoordLength (xml->getStringAttribute (attName), sizeForProportions);
} }
void getCoordList (Array<float>& coords, const String& list, bool allowUnits, const bool isX) const void getCoordList (Array <float>& coords, const String& list,
const bool allowUnits, const bool isX) const
{ {
String::CharPointerType text (list.getCharPointer()); String::CharPointerType text (list.getCharPointer());
float value; float value;
@@ -935,7 +960,7 @@ private:
return source; return source;
} }
String getStyleAttribute (const XmlPath& xml, StringRef attributeName, String getStyleAttribute (const XmlPath& xml, const String& attributeName,
const String& defaultValue = String()) const const String& defaultValue = String()) const
{ {
if (xml->hasAttribute (attributeName)) if (xml->hasAttribute (attributeName))
@@ -975,7 +1000,7 @@ private:
return defaultValue; return defaultValue;
} }
String getInheritedAttribute (const XmlPath& xml, StringRef attributeName) const String getInheritedAttribute (const XmlPath& xml, const String& attributeName) const
{ {
if (xml->hasAttribute (attributeName)) if (xml->hasAttribute (attributeName))
return xml->getStringAttribute (attributeName); return xml->getStringAttribute (attributeName);
@@ -986,30 +1011,13 @@ private:
return String(); return String();
} }
static int parsePlacementFlags (const String& align) noexcept
{
if (align.isEmpty())
return 0;
if (align.containsIgnoreCase ("none"))
return RectanglePlacement::stretchToFit;
return (align.containsIgnoreCase ("slice") ? RectanglePlacement::fillDestination : 0)
| (align.containsIgnoreCase ("xMin") ? RectanglePlacement::xLeft
: (align.containsIgnoreCase ("xMax") ? RectanglePlacement::xRight
: RectanglePlacement::xMid))
| (align.containsIgnoreCase ("yMin") ? RectanglePlacement::yTop
: (align.containsIgnoreCase ("yMax") ? RectanglePlacement::yBottom
: RectanglePlacement::yMid));
}
//============================================================================== //==============================================================================
static bool isIdentifierChar (const juce_wchar c) static bool isIdentifierChar (const juce_wchar c)
{ {
return CharacterFunctions::isLetter (c) || c == '-'; return CharacterFunctions::isLetter (c) || c == '-';
} }
static String getAttributeFromStyleList (const String& list, StringRef attributeName, const String& defaultValue) static String getAttributeFromStyleList (const String& list, const String& attributeName, const String& defaultValue)
{ {
int i = 0; int i = 0;
@@ -1213,7 +1221,7 @@ private:
const bool largeArc, const bool sweep, const bool largeArc, const bool sweep,
double& rx, double& ry, double& rx, double& ry,
double& centreX, double& centreY, double& centreX, double& centreY,
double& startAngle, double& deltaAngle) noexcept double& startAngle, double& deltaAngle)
{ {
const double midX = (x1 - x2) * 0.5; const double midX = (x1 - x2) * 0.5;
const double midY = (y1 - y2) * 0.5; const double midY = (y1 - y2) * 0.5;
@@ -49,7 +49,7 @@
#import <WebKit/WebKit.h> #import <WebKit/WebKit.h>
#import <IOKit/pwr_mgt/IOPMLib.h> #import <IOKit/pwr_mgt/IOPMLib.h>
#if JUCE_SUPPORT_CARBON && ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) #if JUCE_SUPPORT_CARBON
#define Point CarbonDummyPointName #define Point CarbonDummyPointName
#define Component CarbonDummyCompName #define Component CarbonDummyCompName
#import <Carbon/Carbon.h> // still needed for SetSystemUIMode() #import <Carbon/Carbon.h> // still needed for SetSystemUIMode()
@@ -25,7 +25,8 @@
class ComponentAnimator::AnimationTask class ComponentAnimator::AnimationTask
{ {
public: public:
AnimationTask (Component* const comp) noexcept : component (comp) AnimationTask (Component* const comp)
: component (comp)
{ {
} }
@@ -33,7 +34,7 @@ public:
float finalAlpha, float finalAlpha,
int millisecondsToSpendMoving, int millisecondsToSpendMoving,
bool useProxyComponent, bool useProxyComponent,
double startSpd, double endSpd) double startSpeed_, double endSpeed_)
{ {
msElapsed = 0; msElapsed = 0;
msTotal = jmax (1, millisecondsToSpendMoving); msTotal = jmax (1, millisecondsToSpendMoving);
@@ -50,10 +51,10 @@ public:
bottom = component->getBottom(); bottom = component->getBottom();
alpha = component->getAlpha(); alpha = component->getAlpha();
const double invTotalDistance = 4.0 / (startSpd + endSpd + 2.0); const double invTotalDistance = 4.0 / (startSpeed_ + endSpeed_ + 2.0);
startSpeed = jmax (0.0, startSpd * invTotalDistance); startSpeed = jmax (0.0, startSpeed_ * invTotalDistance);
midSpeed = invTotalDistance; midSpeed = invTotalDistance;
endSpeed = jmax (0.0, endSpd * invTotalDistance); endSpeed = jmax (0.0, endSpeed_ * invTotalDistance);
if (useProxyComponent) if (useProxyComponent)
proxy = new ProxyComponent (*component); proxy = new ProxyComponent (*component);
@@ -148,10 +148,10 @@ public:
private: private:
//============================================================================== //==============================================================================
class AnimationTask; class AnimationTask;
OwnedArray<AnimationTask> tasks; OwnedArray <AnimationTask> tasks;
uint32 lastTime; uint32 lastTime;
AnimationTask* findTaskFor (Component*) const noexcept; AnimationTask* findTaskFor (Component* component) const noexcept;
void timerCallback(); void timerCallback();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentAnimator) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentAnimator)
@@ -238,7 +238,7 @@ void ComponentBuilder::updateChildComponents (Component& parent, const ValueTree
const int numExistingChildComps = parent.getNumChildComponents(); const int numExistingChildComps = parent.getNumChildComponents();
Array<Component*> componentsInOrder; Array <Component*> componentsInOrder;
componentsInOrder.ensureStorageAllocated (numExistingChildComps); componentsInOrder.ensureStorageAllocated (numExistingChildComps);
{ {
@@ -226,7 +226,7 @@ public:
private: private:
//============================================================================= //=============================================================================
OwnedArray<TypeHandler> types; OwnedArray <TypeHandler> types;
ScopedPointer<Component> component; ScopedPointer<Component> component;
ImageProvider* imageProvider; ImageProvider* imageProvider;
#if JUCE_DEBUG #if JUCE_DEBUG
@@ -1001,16 +1001,6 @@ void LookAndFeel_V2::drawPopupMenuItem (Graphics& g, const Rectangle<int>& area,
} }
} }
void LookAndFeel_V2::drawPopupMenuSectionHeader (Graphics& g, const Rectangle<int>& area, const String& sectionName)
{
g.setFont (getPopupMenuFont().boldened());
g.setColour (findColour (PopupMenu::headerTextColourId));
g.drawFittedText (sectionName,
area.getX() + 12, area.getY(), area.getWidth() - 16, (int) (area.getHeight() * 0.8f),
Justification::bottomLeft, 1);
}
//============================================================================== //==============================================================================
int LookAndFeel_V2::getMenuWindowFlags() int LookAndFeel_V2::getMenuWindowFlags()
{ {
@@ -137,9 +137,6 @@ public:
const String& text, const String& shortcutKeyText, const String& text, const String& shortcutKeyText,
const Drawable* icon, const Colour* textColour) override; const Drawable* icon, const Colour* textColour) override;
void drawPopupMenuSectionHeader (Graphics&, const Rectangle<int>& area,
const String& sectionName) override;
Font getPopupMenuFont() override; Font getPopupMenuFont() override;
void drawPopupMenuUpDownArrow (Graphics&, int width, int height, bool isScrollUpArrow) override; void drawPopupMenuUpDownArrow (Graphics&, int width, int height, bool isScrollUpArrow) override;
@@ -22,7 +22,7 @@
============================================================================== ==============================================================================
*/ */
MenuBarComponent::MenuBarComponent (MenuBarModel* m) MenuBarComponent::MenuBarComponent (MenuBarModel* model_)
: model (nullptr), : model (nullptr),
itemUnderMouse (-1), itemUnderMouse (-1),
currentPopupIndex (-1), currentPopupIndex (-1),
@@ -32,7 +32,7 @@ MenuBarComponent::MenuBarComponent (MenuBarModel* m)
setWantsKeyboardFocus (false); setWantsKeyboardFocus (false);
setMouseClickGrabsKeyboardFocus (false); setMouseClickGrabsKeyboardFocus (false);
setModel (m); setModel (model_);
} }
MenuBarComponent::~MenuBarComponent() MenuBarComponent::~MenuBarComponent()
@@ -284,26 +284,22 @@ void MenuBarComponent::mouseMove (const MouseEvent& e)
bool MenuBarComponent::keyPressed (const KeyPress& key) bool MenuBarComponent::keyPressed (const KeyPress& key)
{ {
bool used = false;
const int numMenus = menuNames.size(); const int numMenus = menuNames.size();
const int currentIndex = jlimit (0, menuNames.size() - 1, currentPopupIndex);
if (numMenus > 0) if (key.isKeyCode (KeyPress::leftKey))
{ {
const int currentIndex = jlimit (0, numMenus - 1, currentPopupIndex); showMenu ((currentIndex + numMenus - 1) % numMenus);
used = true;
if (key.isKeyCode (KeyPress::leftKey)) }
{ else if (key.isKeyCode (KeyPress::rightKey))
showMenu ((currentIndex + numMenus - 1) % numMenus); {
return true; showMenu ((currentIndex + 1) % numMenus);
} used = true;
if (key.isKeyCode (KeyPress::rightKey))
{
showMenu ((currentIndex + 1) % numMenus);
return true;
}
} }
return false; return used;
} }
void MenuBarComponent::menuBarItemsChanged (MenuBarModel* /*menuBarModel*/) void MenuBarComponent::menuBarItemsChanged (MenuBarModel* /*menuBarModel*/)
@@ -40,9 +40,9 @@ public:
//============================================================================== //==============================================================================
/** Creates a menu bar. /** Creates a menu bar.
@param model the model object to use to control this bar. You can @param model the model object to use to control this bar. You can
pass nullptr into this if you like, and set the model pass 0 into this if you like, and set the model later
later using the setModel() method using the setModel() method
*/ */
MenuBarComponent (MenuBarModel* model); MenuBarComponent (MenuBarModel* model);
@@ -57,7 +57,8 @@ public:
*/ */
void setModel (MenuBarModel* newModel); void setModel (MenuBarModel* newModel);
/** Returns the current menu bar model being used. */ /** Returns the current menu bar model being used.
*/
MenuBarModel* getModel() const noexcept; MenuBarModel* getModel() const noexcept;
//============================================================================== //==============================================================================
@@ -80,7 +80,8 @@ public:
virtual ~Listener() {} virtual ~Listener() {}
//============================================================================== //==============================================================================
/** This callback is made when items are changed in the menu bar model. */ /** This callback is made when items are changed in the menu bar model.
*/
virtual void menuBarItemsChanged (MenuBarModel* menuBarModel) = 0; virtual void menuBarItemsChanged (MenuBarModel* menuBarModel) = 0;
/** This callback is made when an application command is invoked that /** This callback is made when an application command is invoked that
@@ -100,6 +101,7 @@ public:
void addListener (Listener* listenerToAdd) noexcept; void addListener (Listener* listenerToAdd) noexcept;
/** Removes a listener. /** Removes a listener.
@see addListener @see addListener
*/ */
void removeListener (Listener* listenerToRemove) noexcept; void removeListener (Listener* listenerToRemove) noexcept;
@@ -128,7 +130,7 @@ public:
//============================================================================== //==============================================================================
#if JUCE_MAC || DOXYGEN #if JUCE_MAC || DOXYGEN
/** OSX ONLY - Sets the model that is currently being shown as the main /** MAC ONLY - Sets the model that is currently being shown as the main
menu bar at the top of the screen on the Mac. menu bar at the top of the screen on the Mac.
You can pass 0 to stop the current model being displayed. Be careful You can pass 0 to stop the current model being displayed. Be careful
@@ -149,12 +151,12 @@ public:
const PopupMenu* extraAppleMenuItems = nullptr, const PopupMenu* extraAppleMenuItems = nullptr,
const String& recentItemsMenuName = String::empty); const String& recentItemsMenuName = String::empty);
/** OSX ONLY - Returns the menu model that is currently being shown as /** MAC ONLY - Returns the menu model that is currently being shown as
the main menu bar. the main menu bar.
*/ */
static MenuBarModel* getMacMainMenu(); static MenuBarModel* getMacMainMenu();
/** OSX ONLY - Returns the menu that was last passed as the extraAppleMenuItems /** MAC ONLY - Returns the menu that was last passed as the extraAppleMenuItems
argument to setMacMainMenu(), or nullptr if none was specified. argument to setMacMainMenu(), or nullptr if none was specified.
*/ */
static const PopupMenu* getMacExtraAppleItemsMenu(); static const PopupMenu* getMacExtraAppleItemsMenu();
@@ -162,7 +164,7 @@ public:
//============================================================================== //==============================================================================
/** @internal */ /** @internal */
void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo&) override; void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info) override;
/** @internal */ /** @internal */
void applicationCommandListChanged() override; void applicationCommandListChanged() override;
/** @internal */ /** @internal */
@@ -170,7 +172,7 @@ public:
private: private:
ApplicationCommandManager* manager; ApplicationCommandManager* manager;
ListenerList<Listener> listeners; ListenerList <Listener> listeners;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MenuBarModel) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MenuBarModel)
}; };
@@ -1216,7 +1216,12 @@ public:
void paint (Graphics& g) override void paint (Graphics& g) override
{ {
getLookAndFeel().drawPopupMenuSectionHeader (g, getLocalBounds(), getName()); g.setFont (getLookAndFeel().getPopupMenuFont().boldened());
g.setColour (findColour (PopupMenu::headerTextColourId));
g.drawFittedText (getName(),
12, 0, getWidth() - 16, proportionOfHeight (0.8f),
Justification::bottomLeft, 1);
} }
void getIdealSize (int& idealWidth, int& idealHeight) void getIdealSize (int& idealWidth, int& idealHeight)
@@ -562,9 +562,6 @@ public:
const Drawable* icon, const Drawable* icon,
const Colour* textColour) = 0; const Colour* textColour) = 0;
virtual void drawPopupMenuSectionHeader (Graphics&, const Rectangle<int>& area,
const String& sectionName) = 0;
/** Returns the size and style of font to use in popup menus. */ /** Returns the size and style of font to use in popup menus. */
virtual Font getPopupMenuFont() = 0; virtual Font getPopupMenuFont() = 0;
@@ -215,28 +215,13 @@ private:
return dynamic_cast<DragAndDropTarget*> (currentlyOverComp.get()); return dynamic_cast<DragAndDropTarget*> (currentlyOverComp.get());
} }
static Component* findDesktopComponentBelow (Point<int> screenPos)
{
Desktop& desktop = Desktop::getInstance();
for (int i = desktop.getNumComponents(); --i >= 0;)
{
Component* c = desktop.getComponent(i);
if (Component* hit = c->getComponentAt (c->getLocalPoint (nullptr, screenPos)))
return hit;
}
return nullptr;
}
DragAndDropTarget* findTarget (Point<int> screenPos, Point<int>& relativePos, DragAndDropTarget* findTarget (Point<int> screenPos, Point<int>& relativePos,
Component*& resultComponent) const Component*& resultComponent) const
{ {
Component* hit = getParentComponent(); Component* hit = getParentComponent();
if (hit == nullptr) if (hit == nullptr)
hit = findDesktopComponentBelow (screenPos); hit = Desktop::getInstance().findComponentAt (screenPos);
else else
hit = hit->getComponentAt (hit->getLocalPoint (nullptr, screenPos)); hit = hit->getComponentAt (hit->getLocalPoint (nullptr, screenPos));
@@ -128,7 +128,7 @@ private:
SpinLock MouseCursor::SharedCursorHandle::lock; SpinLock MouseCursor::SharedCursorHandle::lock;
//============================================================================== //==============================================================================
MouseCursor::MouseCursor() noexcept MouseCursor::MouseCursor()
: cursorHandle (nullptr) : cursorHandle (nullptr)
{ {
} }
@@ -72,10 +72,10 @@ public:
//============================================================================== //==============================================================================
/** Creates the standard arrow cursor. */ /** Creates the standard arrow cursor. */
MouseCursor() noexcept; MouseCursor();
/** Creates one of the standard mouse cursor */ /** Creates one of the standard mouse cursor */
MouseCursor (StandardCursorType); MouseCursor (StandardCursorType type);
/** Creates a custom cursor from an image. /** Creates a custom cursor from an image.
@@ -43,7 +43,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, launchApp, void, (JNIEnv* en
JUCEApplicationBase* app = JUCEApplicationBase::createInstance(); JUCEApplicationBase* app = JUCEApplicationBase::createInstance();
if (! app->initialiseApp()) if (! app->initialiseApp())
exit (app->getApplicationReturnValue()); exit (0);
jassert (MessageManager::getInstance()->isThisTheMessageThread()); jassert (MessageManager::getInstance()->isThisTheMessageThread());
} }
@@ -1087,7 +1087,9 @@ public:
{ {
for (int i = windowListSize; --i >= 0;) for (int i = windowListSize; --i >= 0;)
{ {
if (LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (windowList[i])) LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (windowList[i]);
if (peer != 0)
{ {
result = (peer == this); result = (peer == this);
break; break;
@@ -845,7 +845,7 @@ public:
void toBehind (ComponentPeer* other) override void toBehind (ComponentPeer* other) override
{ {
if (HWNDComponentPeer* const otherPeer = dynamic_cast<HWNDComponentPeer*> (other)) if (HWNDComponentPeer* const otherPeer = dynamic_cast <HWNDComponentPeer*> (other))
{ {
setMinimised (false); setMinimised (false);
@@ -960,7 +960,7 @@ public:
static ModifierKeys modifiersAtLastCallback; static ModifierKeys modifiersAtLastCallback;
//============================================================================== //==============================================================================
class JuceDropTarget : public ComBaseClassHelper<IDropTarget> class JuceDropTarget : public ComBaseClassHelper <IDropTarget>
{ {
public: public:
JuceDropTarget (HWNDComponentPeer& p) : ownerInfo (new OwnerInfo (p)) {} JuceDropTarget (HWNDComponentPeer& p) : ownerInfo (new OwnerInfo (p)) {}
@@ -1099,13 +1099,13 @@ public:
if (SUCCEEDED (fileData.error)) if (SUCCEEDED (fileData.error))
{ {
const LPDROPFILES dropFiles = static_cast<const LPDROPFILES> (fileData.data); const LPDROPFILES dropFiles = static_cast <const LPDROPFILES> (fileData.data);
const void* const names = addBytesToPointer (dropFiles, sizeof (DROPFILES)); const void* const names = addBytesToPointer (dropFiles, sizeof (DROPFILES));
if (dropFiles->fWide) if (dropFiles->fWide)
ownerInfo->parseFileList (static_cast<const WCHAR*> (names), fileData.dataSize); ownerInfo->parseFileList (static_cast <const WCHAR*> (names), fileData.dataSize);
else else
ownerInfo->parseFileList (static_cast<const char*> (names), fileData.dataSize); ownerInfo->parseFileList (static_cast <const char*> (names), fileData.dataSize);
} }
else else
{ {
@@ -1300,7 +1300,7 @@ private:
//============================================================================== //==============================================================================
static void* createWindowCallback (void* userData) static void* createWindowCallback (void* userData)
{ {
static_cast<HWNDComponentPeer*> (userData)->createWindow(); static_cast <HWNDComponentPeer*> (userData)->createWindow();
return nullptr; return nullptr;
} }
@@ -1528,14 +1528,10 @@ private:
// if something in a paint handler calls, e.g. a message box, this can become reentrant and // if something in a paint handler calls, e.g. a message box, this can become reentrant and
// corrupt the image it's using to paint into, so do a check here. // corrupt the image it's using to paint into, so do a check here.
static bool reentrant = false; static bool reentrant = false;
if (! reentrant) if (! (reentrant || dontRepaint))
{ {
const ScopedValueSetter<bool> setter (reentrant, true, false); const ScopedValueSetter<bool> setter (reentrant, true, false);
performPaint (dc, rgn, regionType, paintStruct);
if (dontRepaint)
component.handleCommandMessage (0); // (this triggers a repaint in the openGL context)
else
performPaint (dc, rgn, regionType, paintStruct);
} }
DeleteObject (rgn); DeleteObject (rgn);
@@ -1643,7 +1639,7 @@ private:
handlePaint (*context); handlePaint (*context);
} }
static_cast<WindowsBitmapImage*> (offscreenImage.getPixelData()) static_cast <WindowsBitmapImage*> (offscreenImage.getPixelData())
->blitToWindow (hwnd, dc, transparent, x, y, updateLayeredWindowAlpha); ->blitToWindow (hwnd, dc, transparent, x, y, updateLayeredWindowAlpha);
} }
@@ -2261,24 +2257,6 @@ private:
} }
} }
void handlePowerBroadcast (WPARAM wParam)
{
if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance())
{
switch (wParam)
{
case PBT_APMSUSPEND: app->suspended(); break;
case PBT_APMQUERYSUSPENDFAILED:
case PBT_APMRESUMECRITICAL:
case PBT_APMRESUMESUSPEND:
case PBT_APMRESUMEAUTOMATIC: app->resumed(); break;
default: break;
}
}
}
void handleLeftClickInNCArea (WPARAM wParam) void handleLeftClickInNCArea (WPARAM wParam)
{ {
if (! sendInputAttemptWhenModalMessage()) if (! sendInputAttemptWhenModalMessage())
@@ -2327,7 +2305,7 @@ private:
{ {
Desktop& desktop = Desktop::getInstance(); Desktop& desktop = Desktop::getInstance();
const_cast<Desktop::Displays&> (desktop.getDisplays()).refresh(); const_cast <Desktop::Displays&> (desktop.getDisplays()).refresh();
if (fullScreen && ! isMinimised()) if (fullScreen && ! isMinimised())
{ {
@@ -2568,10 +2546,6 @@ private:
} }
return TRUE; return TRUE;
case WM_POWERBROADCAST:
handlePowerBroadcast (wParam);
break;
case WM_SYNCPAINT: case WM_SYNCPAINT:
return 0; return 0;
@@ -2901,7 +2875,7 @@ private:
void moveCandidateWindowToLeftAlignWithSelection (HIMC hImc, ComponentPeer& peer, TextInputTarget* target) const void moveCandidateWindowToLeftAlignWithSelection (HIMC hImc, ComponentPeer& peer, TextInputTarget* target) const
{ {
if (Component* const targetComp = dynamic_cast<Component*> (target)) if (Component* const targetComp = dynamic_cast <Component*> (target))
{ {
const Rectangle<int> area (peer.getComponent().getLocalArea (targetComp, target->getCaretRectangle())); const Rectangle<int> area (peer.getComponent().getLocalArea (targetComp, target->getCaretRectangle()));
@@ -2922,15 +2896,18 @@ private:
ModifierKeys HWNDComponentPeer::currentModifiers; ModifierKeys HWNDComponentPeer::currentModifiers;
ModifierKeys HWNDComponentPeer::modifiersAtLastCallback; ModifierKeys HWNDComponentPeer::modifiersAtLastCallback;
ComponentPeer* Component::createNewPeer (int styleFlags, void* parentHWND) ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo)
{ {
return new HWNDComponentPeer (*this, styleFlags, (HWND) parentHWND, false); return new HWNDComponentPeer (*this, styleFlags,
(HWND) nativeWindowToAttachTo, false);
} }
ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component& component, void* parentHWND) ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component* component, void* parent)
{ {
return new HWNDComponentPeer (component, ComponentPeer::windowIgnoresMouseClicks, jassert (component != nullptr);
(HWND) parentHWND, true);
return new HWNDComponentPeer (*component, ComponentPeer::windowIgnoresMouseClicks,
(HWND) parent, true);
} }
@@ -3003,7 +2980,7 @@ bool JUCE_CALLTYPE Process::isForegroundProcess()
fg = GetAncestor (fg, GA_ROOT); fg = GetAncestor (fg, GA_ROOT);
for (int i = ComponentPeer::getNumPeers(); --i >= 0;) for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
if (HWNDComponentPeer* const wp = dynamic_cast<HWNDComponentPeer*> (ComponentPeer::getPeer (i))) if (HWNDComponentPeer* const wp = dynamic_cast <HWNDComponentPeer*> (ComponentPeer::getPeer (i)))
if (wp->isInside (fg)) if (wp->isInside (fg))
return true; return true;
@@ -3029,7 +3006,7 @@ static BOOL CALLBACK enumAlwaysOnTopWindows (HWND hwnd, LPARAM lParam)
if (GetWindowInfo (hwnd, &info) if (GetWindowInfo (hwnd, &info)
&& (info.dwExStyle & WS_EX_TOPMOST) != 0) && (info.dwExStyle & WS_EX_TOPMOST) != 0)
{ {
*reinterpret_cast<bool*> (lParam) = true; *reinterpret_cast <bool*> (lParam) = true;
return FALSE; return FALSE;
} }
} }
@@ -3234,7 +3211,7 @@ void SystemClipboard::copyTextToClipboard (const String& text)
{ {
if (HGLOBAL bufH = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, bytesNeeded + sizeof (WCHAR))) if (HGLOBAL bufH = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, bytesNeeded + sizeof (WCHAR)))
{ {
if (WCHAR* const data = static_cast<WCHAR*> (GlobalLock (bufH))) if (WCHAR* const data = static_cast <WCHAR*> (GlobalLock (bufH)))
{ {
text.copyToUTF16 (data, bytesNeeded); text.copyToUTF16 (data, bytesNeeded);
GlobalUnlock (bufH); GlobalUnlock (bufH);
@@ -56,10 +56,6 @@ protected:
public: public:
/** Creates a button component. /** Creates a button component.
Note that if you call this constructor then you must use the Value to interact with the
button state, and you can't override the class with your own setState or getState methods.
If you want to use getState and setState, call the other constructor instead.
@param valueToControl a Value object that this property should refer to. @param valueToControl a Value object that this property should refer to.
@param propertyName the property name to be passed to the PropertyComponent @param propertyName the property name to be passed to the PropertyComponent
@param buttonText the text shown in the ToggleButton component @param buttonText the text shown in the ToggleButton component
@@ -50,17 +50,15 @@ class JUCE_API ChoicePropertyComponent : public PropertyComponent,
{ {
protected: protected:
/** Creates the component. /** Creates the component.
Your subclass's constructor must add a list of options to the choices member variable.
Your subclass's constructor must add a list of options to the choices
member variable.
*/ */
ChoicePropertyComponent (const String& propertyName); ChoicePropertyComponent (const String& propertyName);
public: public:
/** Creates the component. /** Creates the component.
Note that if you call this constructor then you must use the Value to interact with the
index, and you can't override the class with your own setIndex or getIndex methods.
If you want to use those methods, call the other constructor instead.
@param valueToControl the value that the combo box will read and control @param valueToControl the value that the combo box will read and control
@param propertyName the name of the property @param propertyName the name of the property
@param choices the list of possible values that the drop-down list will contain @param choices the list of possible values that the drop-down list will contain
@@ -58,10 +58,6 @@ public:
If you need to customise the slider in other ways, your constructor can If you need to customise the slider in other ways, your constructor can
access the slider member variable and change it directly. access the slider member variable and change it directly.
Note that if you call this constructor then you must use the Value to interact with
the value, and you can't override the class with your own setValue or getValue methods.
If you want to use those methods, call the other constructor instead.
*/ */
SliderPropertyComponent (const Value& valueToControl, SliderPropertyComponent (const Value& valueToControl,
const String& propertyName, const String& propertyName,
@@ -418,7 +418,7 @@ private:
bool isEnabled : 1, isHeading : 1; bool isEnabled : 1, isHeading : 1;
}; };
OwnedArray<ItemInfo> items; OwnedArray <ItemInfo> items;
Value currentId; Value currentId;
int lastCurrentId; int lastCurrentId;
bool isButtonDown, separatorPending, menuActive, scrollWheelEnabled; bool isButtonDown, separatorPending, menuActive, scrollWheelEnabled;
@@ -460,3 +460,5 @@ void Label::textEditorFocusLost (TextEditor& ed)
{ {
textEditorTextChanged (ed); textEditorTextChanged (ed);
} }
void Label::Listener::editorShown (Label*, TextEditor&) {}
@@ -184,7 +184,7 @@ public:
virtual void labelTextChanged (Label* labelThatHasChanged) = 0; virtual void labelTextChanged (Label* labelThatHasChanged) = 0;
/** Called when a Label goes into editing mode and displays a TextEditor. */ /** Called when a Label goes into editing mode and displays a TextEditor. */
virtual void editorShown (Label*, TextEditor&) {} virtual void editorShown (Label*, TextEditor& textEditorShown);
}; };
/** Registers a listener that will be called when the label's text changes. */ /** Registers a listener that will be called when the label's text changes. */
@@ -45,10 +45,7 @@ public:
*/ */
virtual int getNumRows() = 0; virtual int getNumRows() = 0;
/** This method must be implemented to draw a row of the list. /** This method must be implemented to draw a row of the list. */
Note that the rowNumber value may be greater than the number of rows in your
list, so be careful that you don't assume it's less than getNumRows().
*/
virtual void paintListBoxItem (int rowNumber, virtual void paintListBoxItem (int rowNumber,
Graphics& g, Graphics& g,
int width, int height, int width, int height,
@@ -464,9 +464,9 @@ public:
const bool stopAtEnd) const bool stopAtEnd)
{ {
// make sure the values are sensible.. // make sure the values are sensible..
jassert (startAngleRadians >= 0 && endAngleRadians >= 0); jassert (rotaryStart >= 0 && rotaryEnd >= 0);
jassert (startAngleRadians < float_Pi * 4.0f && endAngleRadians < float_Pi * 4.0f); jassert (rotaryStart < float_Pi * 4.0f && rotaryEnd < float_Pi * 4.0f);
jassert (startAngleRadians < endAngleRadians); jassert (rotaryStart < rotaryEnd);
rotaryStart = startAngleRadians; rotaryStart = startAngleRadians;
rotaryEnd = endAngleRadians; rotaryEnd = endAngleRadians;
@@ -566,7 +566,6 @@ public:
valueBox->setWantsKeyboardFocus (false); valueBox->setWantsKeyboardFocus (false);
valueBox->setText (previousTextBoxContent, dontSendNotification); valueBox->setText (previousTextBoxContent, dontSendNotification);
valueBox->setTooltip (owner.getTooltip());
if (valueBox->isEditable() != editableText) // (avoid overriding the single/double click flags unless we have to) if (valueBox->isEditable() != editableText) // (avoid overriding the single/double click flags unless we have to)
valueBox->setEditable (editableText && owner.isEnabled()); valueBox->setEditable (editableText && owner.isEnabled());
@@ -578,6 +577,10 @@ public:
valueBox->addMouseListener (&owner, false); valueBox->addMouseListener (&owner, false);
valueBox->setMouseCursor (MouseCursor::ParentCursor); valueBox->setMouseCursor (MouseCursor::ParentCursor);
} }
else
{
valueBox->setTooltip (owner.getTooltip());
}
} }
else else
{ {
@@ -1006,9 +1009,9 @@ public:
valueBox->hideEditor (false); valueBox->hideEditor (false);
const double value = (double) currentValue.getValue(); const double value = (double) currentValue.getValue();
const double delta = getMouseWheelDelta (value, (std::abs (wheel.deltaX) > std::abs (wheel.deltaY) const double delta = getMouseWheelDelta (value, (wheel.deltaX != 0 ? -wheel.deltaX : wheel.deltaY)
? -wheel.deltaX : wheel.deltaY) * (wheel.isReversed ? -1.0f : 1.0f));
* (wheel.isReversed ? -1.0f : 1.0f));
if (delta != 0) if (delta != 0)
{ {
const double newValue = value + jmax (interval, std::abs (delta)) * (delta < 0 ? -1.0 : 1.0); const double newValue = value + jmax (interval, std::abs (delta)) * (delta < 0 ? -1.0 : 1.0);
@@ -26,7 +26,7 @@ class TableListBox::RowComp : public Component,
public TooltipClient public TooltipClient
{ {
public: public:
RowComp (TableListBox& tlb) noexcept : owner (tlb), row (-1), isSelected (false) RowComp (TableListBox& tlb) : owner (tlb), row (-1), isSelected (false)
{ {
} }
@@ -192,7 +192,7 @@ public:
if (TableListBoxModel* m = owner.getModel()) if (TableListBoxModel* m = owner.getModel())
return m->getCellTooltip (row, columnId); return m->getCellTooltip (row, columnId);
return String(); return String::empty;
} }
Component* findChildComponentForColumn (const int columnId) const Component* findChildComponentForColumn (const int columnId) const
@@ -275,7 +275,7 @@ void TableListBox::setHeader (TableHeaderComponent* newHeader)
{ {
jassert (newHeader != nullptr); // you need to supply a real header for a table! jassert (newHeader != nullptr); // you need to supply a real header for a table!
Rectangle<int> newBounds (100, 28); Rectangle<int> newBounds (0, 0, 100, 28);
if (header != nullptr) if (header != nullptr)
newBounds = header->getBounds(); newBounds = header->getBounds();
@@ -287,7 +287,7 @@ void TableListBox::setHeader (TableHeaderComponent* newHeader)
header->addListener (this); header->addListener (this);
} }
int TableListBox::getHeaderHeight() const noexcept int TableListBox::getHeaderHeight() const
{ {
return header->getHeight(); return header->getHeight();
} }
@@ -312,11 +312,16 @@ void TableListBox::autoSizeAllColumns()
autoSizeColumn (header->getColumnIdOfIndex (i, true)); autoSizeColumn (header->getColumnIdOfIndex (i, true));
} }
void TableListBox::setAutoSizeMenuOptionShown (const bool shouldBeShown) noexcept void TableListBox::setAutoSizeMenuOptionShown (const bool shouldBeShown)
{ {
autoSizeOptionsShown = shouldBeShown; autoSizeOptionsShown = shouldBeShown;
} }
bool TableListBox::isAutoSizeMenuOptionShown() const
{
return autoSizeOptionsShown;
}
Rectangle<int> TableListBox::getCellPosition (const int columnId, const int rowNumber, Rectangle<int> TableListBox::getCellPosition (const int columnId, const int rowNumber,
const bool relativeToComponentTopLeft) const const bool relativeToComponentTopLeft) const
{ {
@@ -332,7 +337,7 @@ Rectangle<int> TableListBox::getCellPosition (const int columnId, const int rowN
Component* TableListBox::getCellComponent (int columnId, int rowNumber) const Component* TableListBox::getCellComponent (int columnId, int rowNumber) const
{ {
if (RowComp* const rowComp = dynamic_cast<RowComp*> (getComponentForRowNumber (rowNumber))) if (RowComp* const rowComp = dynamic_cast <RowComp*> (getComponentForRowNumber (rowNumber)))
return rowComp->findChildComponentForColumn (columnId); return rowComp->findChildComponentForColumn (columnId);
return nullptr; return nullptr;
@@ -365,12 +370,12 @@ void TableListBox::paintListBoxItem (int, Graphics&, int, int, bool)
{ {
} }
Component* TableListBox::refreshComponentForRow (int rowNumber, bool rowSelected, Component* existingComponentToUpdate) Component* TableListBox::refreshComponentForRow (int rowNumber, bool isRowSelected_, Component* existingComponentToUpdate)
{ {
if (existingComponentToUpdate == nullptr) if (existingComponentToUpdate == nullptr)
existingComponentToUpdate = new RowComp (*this); existingComponentToUpdate = new RowComp (*this);
static_cast<RowComp*> (existingComponentToUpdate)->update (rowNumber, rowSelected); static_cast <RowComp*> (existingComponentToUpdate)->update (rowNumber, isRowSelected_);
return existingComponentToUpdate; return existingComponentToUpdate;
} }
@@ -445,7 +450,7 @@ void TableListBox::updateColumnComponents() const
const int firstRow = getRowContainingPosition (0, 0); const int firstRow = getRowContainingPosition (0, 0);
for (int i = firstRow + getNumRowsOnScreen() + 2; --i >= firstRow;) for (int i = firstRow + getNumRowsOnScreen() + 2; --i >= firstRow;)
if (RowComp* const rowComp = dynamic_cast<RowComp*> (getComponentForRowNumber (i))) if (RowComp* const rowComp = dynamic_cast <RowComp*> (getComponentForRowNumber (i)))
rowComp->resized(); rowComp->resized();
} }
@@ -460,7 +465,7 @@ void TableListBoxModel::deleteKeyPressed (int) {}
void TableListBoxModel::returnKeyPressed (int) {} void TableListBoxModel::returnKeyPressed (int) {}
void TableListBoxModel::listWasScrolled() {} void TableListBoxModel::listWasScrolled() {}
String TableListBoxModel::getCellTooltip (int /*rowNumber*/, int /*columnId*/) { return String(); } String TableListBoxModel::getCellTooltip (int /*rowNumber*/, int /*columnId*/) { return String::empty; }
var TableListBoxModel::getDragSourceDescription (const SparseSet<int>&) { return var(); } var TableListBoxModel::getDragSourceDescription (const SparseSet<int>&) { return var(); }
Component* TableListBoxModel::refreshComponentForCell (int, int, bool, Component* existingComponentToUpdate) Component* TableListBoxModel::refreshComponentForCell (int, int, bool, Component* existingComponentToUpdate)
@@ -57,7 +57,7 @@ public:
The graphics context has its origin at the row's top-left, and your method The graphics context has its origin at the row's top-left, and your method
should fill the area specified by the width and height parameters. should fill the area specified by the width and height parameters.
*/ */
virtual void paintRowBackground (Graphics&, virtual void paintRowBackground (Graphics& g,
int rowNumber, int rowNumber,
int width, int height, int width, int height,
bool rowIsSelected) = 0; bool rowIsSelected) = 0;
@@ -66,11 +66,8 @@ public:
The graphics context's origin will already be set to the top-left of the cell, The graphics context's origin will already be set to the top-left of the cell,
whose size is specified by (width, height). whose size is specified by (width, height).
Note that the rowNumber value may be greater than the number of rows in your
list, so be careful that you don't assume it's less than getNumRows().
*/ */
virtual void paintCell (Graphics&, virtual void paintCell (Graphics& g,
int rowNumber, int rowNumber,
int columnId, int columnId,
int width, int height, int width, int height,
@@ -145,21 +142,25 @@ public:
*/ */
virtual int getColumnAutoSizeWidth (int columnId); virtual int getColumnAutoSizeWidth (int columnId);
/** Returns a tooltip for a particular cell in the table. */ /** Returns a tooltip for a particular cell in the table.
*/
virtual String getCellTooltip (int rowNumber, int columnId); virtual String getCellTooltip (int rowNumber, int columnId);
//============================================================================== //==============================================================================
/** Override this to be informed when rows are selected or deselected. /** Override this to be informed when rows are selected or deselected.
@see ListBox::selectedRowsChanged() @see ListBox::selectedRowsChanged()
*/ */
virtual void selectedRowsChanged (int lastRowSelected); virtual void selectedRowsChanged (int lastRowSelected);
/** Override this to be informed when the delete key is pressed. /** Override this to be informed when the delete key is pressed.
@see ListBox::deleteKeyPressed() @see ListBox::deleteKeyPressed()
*/ */
virtual void deleteKeyPressed (int lastRowSelected); virtual void deleteKeyPressed (int lastRowSelected);
/** Override this to be informed when the return key is pressed. /** Override this to be informed when the return key is pressed.
@see ListBox::returnKeyPressed() @see ListBox::returnKeyPressed()
*/ */
virtual void returnKeyPressed (int lastRowSelected); virtual void returnKeyPressed (int lastRowSelected);
@@ -209,34 +210,29 @@ public:
/** Creates a TableListBox. /** Creates a TableListBox.
The model pointer passed-in can be null, in which case you can set it later The model pointer passed-in can be null, in which case you can set it later
with setModel(). The TableListBox does not take ownership of the model - it's with setModel().
the caller's responsibility to manage its lifetime and make sure it
doesn't get deleted while still being used.
*/ */
TableListBox (const String& componentName = String(), TableListBox (const String& componentName = String::empty,
TableListBoxModel* model = nullptr); TableListBoxModel* model = 0);
/** Destructor. */ /** Destructor. */
~TableListBox(); ~TableListBox();
//============================================================================== //==============================================================================
/** Changes the TableListBoxModel that is being used for this table. /** Changes the TableListBoxModel that is being used for this table.
The TableListBox does not take ownership of the model - it's the caller's responsibility
to manage its lifetime and make sure it doesn't get deleted while still being used.
*/ */
void setModel (TableListBoxModel* newModel); void setModel (TableListBoxModel* newModel);
/** Returns the model currently in use. */ /** Returns the model currently in use. */
TableListBoxModel* getModel() const noexcept { return model; } TableListBoxModel* getModel() const { return model; }
//============================================================================== //==============================================================================
/** Returns the header component being used in this table. */ /** Returns the header component being used in this table. */
TableHeaderComponent& getHeader() const noexcept { return *header; } TableHeaderComponent& getHeader() const { return *header; }
/** Sets the header component to use for the table. /** Sets the header component to use for the table.
The table will take ownership of the component that you pass in, and will delete it The table will take ownership of the component that you pass in, and will delete it
when it's no longer needed. when it's no longer needed.
The pointer passed in may not be null.
*/ */
void setHeader (TableHeaderComponent* newHeader); void setHeader (TableHeaderComponent* newHeader);
@@ -248,7 +244,7 @@ public:
/** Returns the height of the table header. /** Returns the height of the table header.
@see setHeaderHeight @see setHeaderHeight
*/ */
int getHeaderHeight() const noexcept; int getHeaderHeight() const;
//============================================================================== //==============================================================================
/** Resizes a column to fit its contents. /** Resizes a column to fit its contents.
@@ -264,14 +260,15 @@ public:
void autoSizeAllColumns(); void autoSizeAllColumns();
/** Enables or disables the auto size options on the popup menu. /** Enables or disables the auto size options on the popup menu.
By default, these are enabled. By default, these are enabled.
*/ */
void setAutoSizeMenuOptionShown (bool shouldBeShown) noexcept; void setAutoSizeMenuOptionShown (bool shouldBeShown);
/** True if the auto-size options should be shown on the menu. /** True if the auto-size options should be shown on the menu.
@see setAutoSizeMenuOptionShown @see setAutoSizeMenuOptionsShown
*/ */
bool isAutoSizeMenuOptionShown() const noexcept { return autoSizeOptionsShown; } bool isAutoSizeMenuOptionShown() const;
/** Returns the position of one of the cells in the table. /** Returns the position of one of the cells in the table.

Some files were not shown because too many files have changed in this diff Show More