Browse Source

Update to latest juce

tags/1.9.7
falkTX 10 years ago
parent
commit
2b4cfff9d2
49 changed files with 1222 additions and 757 deletions
  1. +54
    -19
      source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp
  2. +10
    -1
      source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h
  3. +14
    -8
      source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp
  4. +1
    -1
      source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp
  5. +37
    -33
      source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp
  6. +3
    -3
      source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp
  7. +2
    -2
      source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp
  8. +1
    -1
      source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp
  9. +3
    -1
      source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
  10. +619
    -395
      source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
  11. +6
    -4
      source/modules/juce_core/containers/juce_NamedValueSet.cpp
  12. +2
    -2
      source/modules/juce_core/containers/juce_NamedValueSet.h
  13. +9
    -9
      source/modules/juce_core/containers/juce_Variant.cpp
  14. +9
    -10
      source/modules/juce_core/containers/juce_Variant.h
  15. +5
    -0
      source/modules/juce_core/files/juce_File.cpp
  16. +9
    -9
      source/modules/juce_core/javascript/juce_Javascript.cpp
  17. +2
    -2
      source/modules/juce_core/javascript/juce_Javascript.h
  18. +10
    -0
      source/modules/juce_core/memory/juce_ContainerDeletePolicy.h
  19. +2
    -2
      source/modules/juce_core/memory/juce_Memory.h
  20. +21
    -7
      source/modules/juce_core/memory/juce_SharedResourcePointer.h
  21. +2
    -2
      source/modules/juce_core/native/juce_posix_SharedCode.h
  22. +12
    -0
      source/modules/juce_core/network/juce_URL.h
  23. +11
    -1
      source/modules/juce_core/text/juce_Identifier.cpp
  24. +11
    -3
      source/modules/juce_core/text/juce_Identifier.h
  25. +2
    -2
      source/modules/juce_core/text/juce_String.h
  26. +23
    -24
      source/modules/juce_data_structures/values/juce_ValueTree.cpp
  27. +13
    -13
      source/modules/juce_data_structures/values/juce_ValueTree.h
  28. +4
    -2
      source/modules/juce_graphics/contexts/juce_GraphicsContext.cpp
  29. +66
    -53
      source/modules/juce_graphics/geometry/juce_Rectangle.h
  30. +1
    -0
      source/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp
  31. +6
    -3
      source/modules/juce_gui_basics/components/juce_Component.cpp
  32. +1
    -1
      source/modules/juce_gui_basics/components/juce_Component.h
  33. +4
    -2
      source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp
  34. +13
    -12
      source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h
  35. +1
    -31
      source/modules/juce_gui_basics/layout/juce_Viewport.cpp
  36. +1
    -3
      source/modules/juce_gui_basics/layout/juce_Viewport.h
  37. +19
    -1
      source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp
  38. +3
    -0
      source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h
  39. +4
    -0
      source/modules/juce_gui_basics/mouse/juce_MouseEvent.h
  40. +12
    -4
      source/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp
  41. +23
    -11
      source/modules/juce_gui_basics/native/juce_android_Windowing.cpp
  42. +4
    -4
      source/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp
  43. +41
    -7
      source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp
  44. +56
    -23
      source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm
  45. +8
    -4
      source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm
  46. +7
    -1
      source/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp
  47. +22
    -18
      source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp
  48. +31
    -21
      source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp
  49. +2
    -2
      source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h

+ 54
- 19
source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp View File

@@ -32,6 +32,7 @@ SynthesiserVoice::SynthesiserVoice()
currentPlayingMidiChannel (0),
noteOnTime (0),
keyIsDown (false),
sustainPedalDown (false),
sostenutoPedalDown (false)
{
}
@@ -296,6 +297,7 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice,
voice->currentlyPlayingSound = sound;
voice->keyIsDown = true;
voice->sostenutoPedalDown = false;
voice->sustainPedalDown = sustainPedalsDown[midiChannel];
voice->startNote (midiNoteNumber, velocity, sound,
lastPitchWheelValues [midiChannel - 1]);
@@ -331,9 +333,11 @@ void Synthesiser::noteOff (const int midiChannel,
if (sound->appliesToNote (midiNoteNumber)
&& sound->appliesToChannel (midiChannel))
{
jassert (! voice->keyIsDown || voice->sustainPedalDown == sustainPedalsDown [midiChannel]);
voice->keyIsDown = false;
if (! (sustainPedalsDown [midiChannel] || voice->sostenutoPedalDown))
if (! (voice->sustainPedalDown || voice->sostenutoPedalDown))
stopVoice (voice, velocity, allowTailOff);
}
}
@@ -427,6 +431,14 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
if (isDown)
{
sustainPedalsDown.setBit (midiChannel);
for (int i = voices.size(); --i >= 0;)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->isPlayingChannel (midiChannel) && voice->isKeyDown())
voice->sustainPedalDown = true;
}
}
else
{
@@ -434,8 +446,13 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown)
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->isPlayingChannel (midiChannel) && ! voice->keyIsDown)
stopVoice (voice, 1.0f, true);
if (voice->isPlayingChannel (midiChannel))
{
voice->sustainPedalDown = false;
if (! voice->isKeyDown())
stopVoice (voice, 1.0f, true);
}
}
sustainPedalsDown.clearBit (midiChannel);
@@ -505,8 +522,13 @@ struct VoiceAgeSorter
SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
int /*midiChannel*/, int midiNoteNumber) const
{
SynthesiserVoice* bottom = nullptr;
SynthesiserVoice* top = nullptr;
// This voice-stealing algorithm applies the following heuristics:
// - Re-use the oldest notes first
// - Protect the lowest & topmost notes, even if sustained, but not if they've been released.
// These are the voices we want to protect (ie: only steal if unavoidable)
SynthesiserVoice* low = nullptr; // Lowest sounding note, might be sustained, but NOT in release phase
SynthesiserVoice* top = nullptr; // Highest sounding note, might be sustained, but NOT in release phase
// this is a list of voices we can steal, sorted by how long they've been running
Array<SynthesiserVoice*> usableVoices;
@@ -516,24 +538,33 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
{
SynthesiserVoice* const voice = voices.getUnchecked (i);
jassert (voice->isVoiceActive()); // We wouldn't be here otherwise
if (voice->canPlaySound (soundToPlay))
{
VoiceAgeSorter sorter;
usableVoices.addSorted (sorter, voice);
const int note = voice->getCurrentlyPlayingNote();
if (! voice->isPlayingButReleased()) // Don't protect released notes
{
const int note = voice->getCurrentlyPlayingNote();
if (bottom == nullptr || note < bottom->getCurrentlyPlayingNote())
bottom = voice;
if (low == nullptr || note < low->getCurrentlyPlayingNote())
low = voice;
if (top == nullptr || note > top->getCurrentlyPlayingNote())
top = voice;
if (top == nullptr || note > top->getCurrentlyPlayingNote())
top = voice;
}
}
}
// Eliminate pathological cases (ie: only 1 note playing): we always give precedence to the lowest note(s)
if (top == low)
top = nullptr;
const int numUsableVoices = usableVoices.size();
// The oldest note that's playing with the target pitch playing is ideal..
// The oldest note that's playing with the target pitch is ideal..
for (int i = 0; i < numUsableVoices; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
@@ -547,7 +578,7 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
if (voice != bottom && voice != top && ! voice->isKeyDown() && ! voice->isSostenutoPedalDown())
if (voice != low && voice != top && voice->isPlayingButReleased())
return voice;
}
@@ -556,21 +587,25 @@ SynthesiserVoice* Synthesiser::findVoiceToSteal (SynthesiserSound* soundToPlay,
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
if (voice != bottom && voice != top && ! voice->isKeyDown())
if (voice != low && voice != top && ! voice->isKeyDown())
return voice;
}
// At this point, all notes have fingers on them, so look for the oldest note
// that isn't the top or bottom note..
// Oldest voice that isn't protected
for (int i = 0; i < numUsableVoices; ++i)
{
SynthesiserVoice* const voice = usableVoices.getUnchecked (i);
if (voice != bottom && voice != top)
if (voice != low && voice != top)
return voice;
}
// ..otherwise, there's only one or two voices to choose from - prefer to steal the highest one:
jassert (top != nullptr || bottom != nullptr);
return (top == nullptr ? bottom : top);
// We've only got "protected" voices now: lowest note takes priority
jassert (low != nullptr);
// Duophonic synth: give priority to the bass note:
if (top != nullptr)
return top;
return low;
}

+ 10
- 1
source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h View File

@@ -214,9 +214,18 @@ public:
*/
bool isKeyDown() const noexcept { return keyIsDown; }
/** Returns true if the sustain pedal is currently active for this voice. */
bool isSustainPedalDown() const noexcept { return sustainPedalDown; }
/** Returns true if the sostenuto pedal is currently active for this voice. */
bool isSostenutoPedalDown() const noexcept { return sostenutoPedalDown; }
/** Returns true if a voice is sounding in its release phase **/
bool isPlayingButReleased() const noexcept
{
return isVoiceActive() && ! (isKeyDown() || isSostenutoPedalDown() || isSustainPedalDown());
}
/** Returns true if this voice started playing its current note before the other voice did. */
bool wasStartedBefore (const SynthesiserVoice& other) const noexcept;
@@ -244,7 +253,7 @@ private:
int currentlyPlayingNote, currentPlayingMidiChannel;
uint32 noteOnTime;
SynthesiserSound::Ptr currentlyPlayingSound;
bool keyIsDown, sostenutoPedalDown;
bool keyIsDown, sustainPedalDown, sostenutoPedalDown;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// Note the new parameters for this method.


+ 14
- 8
source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp View File

@@ -486,14 +486,17 @@ public:
sampleRate = newSampleRate;
bufferSize = newBufferSize;
inputChannelBuffer.setSize (jmax ((int) minChansIn, inputChannels.getHighestBit()) + 1, bufferSize);
int maxInputsRequested = inputChannels.getHighestBit() + 1;
maxInputsRequested = jmax ((int) minChansIn, jmin ((int) maxChansIn, maxInputsRequested));
inputChannelBuffer.setSize (maxInputsRequested, bufferSize);
inputChannelBuffer.clear();
inputChannelDataForCallback.clear();
currentInputChans.clear();
if (inputChannels.getHighestBit() >= 0)
{
for (int i = 0; i <= jmax (inputChannels.getHighestBit(), (int) minChansIn); ++i)
for (int i = 0; i < maxInputsRequested; ++i)
{
if (inputChannels[i])
{
@@ -505,14 +508,17 @@ public:
ensureMinimumNumBitsSet (outputChannels, (int) minChansOut);
outputChannelBuffer.setSize (jmax ((int) minChansOut, outputChannels.getHighestBit()) + 1, bufferSize);
int maxOutputsRequested = outputChannels.getHighestBit() + 1;
maxOutputsRequested = jmax ((int) minChansOut, jmin ((int) maxChansOut, maxOutputsRequested));
outputChannelBuffer.setSize (maxOutputsRequested, bufferSize);
outputChannelBuffer.clear();
outputChannelDataForCallback.clear();
currentOutputChans.clear();
if (outputChannels.getHighestBit() >= 0)
{
for (int i = 0; i <= jmax (outputChannels.getHighestBit(), (int) minChansOut); ++i)
for (int i = 0; i < maxOutputsRequested; ++i)
{
if (outputChannels[i])
{
@@ -796,10 +802,10 @@ class ALSAAudioIODevice : public AudioIODevice
{
public:
ALSAAudioIODevice (const String& deviceName,
const String& typeName,
const String& deviceTypeName,
const String& inputDeviceID,
const String& outputDeviceID)
: AudioIODevice (deviceName, typeName),
: AudioIODevice (deviceName, deviceTypeName),
inputId (inputDeviceID),
outputId (outputDeviceID),
isOpen_ (false),
@@ -924,8 +930,8 @@ private:
class ALSAAudioIODeviceType : public AudioIODeviceType
{
public:
ALSAAudioIODeviceType (bool onlySoundcards, const String &typeName)
: AudioIODeviceType (typeName),
ALSAAudioIODeviceType (bool onlySoundcards, const String &deviceTypeName)
: AudioIODeviceType (deviceTypeName),
hasScanned (false),
listOnlySoundcards (onlySoundcards)
{


+ 1
- 1
source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp View File

@@ -277,7 +277,7 @@ public:
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ranges)))
{
static const double possibleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0 };
static const double possibleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0, 384000.0 };
for (int i = 0; i < numElementsInArray (possibleRates); ++i)
{


+ 37
- 33
source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp View File

@@ -45,6 +45,14 @@ namespace CoreMidiHelpers
#define CHECK_ERROR(a) CoreMidiHelpers::checkError (a, __LINE__)
//==============================================================================
struct ScopedCFString
{
ScopedCFString() noexcept : cfString (nullptr) {}
~ScopedCFString() noexcept { if (cfString != nullptr) CFRelease (cfString); }
CFStringRef cfString;
};
static String getMidiObjectName (MIDIObjectRef entity)
{
String result;
@@ -116,7 +124,7 @@ namespace CoreMidiHelpers
if (numConnections > 0)
{
const SInt32* pid = reinterpret_cast <const SInt32*> (CFDataGetBytePtr (connections));
const SInt32* pid = reinterpret_cast<const SInt32*> (CFDataGetBytePtr (connections));
for (int i = 0; i < numConnections; ++i, ++pid)
{
@@ -133,7 +141,7 @@ namespace CoreMidiHelpers
|| connObjectType == kMIDIObjectType_ExternalDestination)
{
// Connected to an external device's endpoint (10.3 and later).
s = getEndpointName (static_cast <MIDIEndpointRef> (connObject), true);
s = getEndpointName (static_cast<MIDIEndpointRef> (connObject), true);
}
else
{
@@ -208,9 +216,9 @@ namespace CoreMidiHelpers
// correctly when called from the message thread!
jassert (MessageManager::getInstance()->isThisTheMessageThread());
CFStringRef name = getGlobalMidiClientName().toCFString();
CHECK_ERROR (MIDIClientCreate (name, &globalSystemChangeCallback, nullptr, &globalMidiClient));
CFRelease (name);
CoreMidiHelpers::ScopedCFString name;
name.cfString = getGlobalMidiClientName().toCFString();
CHECK_ERROR (MIDIClientCreate (name.cfString, &globalSystemChangeCallback, nullptr, &globalMidiClient));
}
return globalMidiClient;
@@ -220,12 +228,12 @@ namespace CoreMidiHelpers
class MidiPortAndEndpoint
{
public:
MidiPortAndEndpoint (MIDIPortRef p, MIDIEndpointRef ep)
MidiPortAndEndpoint (MIDIPortRef p, MIDIEndpointRef ep) noexcept
: port (p), endPoint (ep)
{
}
~MidiPortAndEndpoint()
~MidiPortAndEndpoint() noexcept
{
if (port != 0)
MIDIPortDispose (port);
@@ -234,7 +242,7 @@ namespace CoreMidiHelpers
MIDIEndpointDispose (endPoint);
}
void send (const MIDIPacketList* const packets)
void send (const MIDIPacketList* const packets) noexcept
{
if (port != 0)
MIDISend (port, endPoint, packets);
@@ -302,7 +310,7 @@ namespace CoreMidiHelpers
static void midiInputProc (const MIDIPacketList* pktlist, void* readProcRefCon, void* /*srcConnRefCon*/)
{
static_cast <MidiPortAndCallback*> (readProcRefCon)->handlePackets (pktlist);
static_cast<MidiPortAndCallback*> (readProcRefCon)->handlePackets (pktlist);
}
}
@@ -318,19 +326,18 @@ MidiOutput* MidiOutput::openDevice (int index)
{
MIDIEndpointRef endPoint = MIDIGetDestination ((ItemCount) index);
CFStringRef pname;
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname)))
CoreMidiHelpers::ScopedCFString pname;
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname.cfString)))
{
MIDIClientRef client = CoreMidiHelpers::getGlobalMidiClient();
MIDIPortRef port;
if (client != 0 && CHECK_ERROR (MIDIOutputPortCreate (client, pname, &port)))
if (client != 0 && CHECK_ERROR (MIDIOutputPortCreate (client, pname.cfString, &port)))
{
mo = new MidiOutput();
mo->internal = new CoreMidiHelpers::MidiPortAndEndpoint (port, endPoint);
}
CFRelease (pname);
}
}
@@ -339,20 +346,20 @@ MidiOutput* MidiOutput::openDevice (int index)
MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
{
MidiOutput* mo = nullptr;
MIDIClientRef client = CoreMidiHelpers::getGlobalMidiClient();
MIDIEndpointRef endPoint;
CFStringRef name = deviceName.toCFString();
if (client != 0 && CHECK_ERROR (MIDISourceCreate (client, name, &endPoint)))
CoreMidiHelpers::ScopedCFString name;
name.cfString = deviceName.toCFString();
if (client != 0 && CHECK_ERROR (MIDISourceCreate (client, name.cfString, &endPoint)))
{
mo = new MidiOutput();
MidiOutput* mo = new MidiOutput();
mo->internal = new CoreMidiHelpers::MidiPortAndEndpoint (0, endPoint);
return mo;
}
CFRelease (name);
return mo;
return nullptr;
}
MidiOutput::~MidiOutput()
@@ -370,7 +377,7 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
const MIDITimeStamp timeStamp = AudioGetCurrentHostTime();
#endif
HeapBlock <MIDIPacketList> allocatedPackets;
HeapBlock<MIDIPacketList> allocatedPackets;
MIDIPacketList stackPacket;
MIDIPacketList* packetToSend = &stackPacket;
const size_t dataSize = (size_t) message.getRawDataSize();
@@ -436,16 +443,16 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{
if (MIDIEndpointRef endPoint = MIDIGetSource ((ItemCount) index))
{
CFStringRef name;
ScopedCFString name;
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &name)))
if (CHECK_ERROR (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &name.cfString)))
{
if (MIDIClientRef client = getGlobalMidiClient())
{
MIDIPortRef port;
ScopedPointer <MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
ScopedPointer<MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
if (CHECK_ERROR (MIDIInputPortCreate (client, name, midiInputProc, mpc, &port)))
if (CHECK_ERROR (MIDIInputPortCreate (client, name.cfString, midiInputProc, mpc, &port)))
{
if (CHECK_ERROR (MIDIPortConnectSource (port, endPoint, nullptr)))
{
@@ -465,8 +472,6 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
}
}
}
CFRelease (name);
}
}
@@ -482,13 +487,14 @@ MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallba
if (MIDIClientRef client = getGlobalMidiClient())
{
ScopedPointer <MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
ScopedPointer<MidiPortAndCallback> mpc (new MidiPortAndCallback (*callback));
mpc->active = false;
MIDIEndpointRef endPoint;
CFStringRef name = deviceName.toCFString();
ScopedCFString name;
name.cfString = deviceName.toCFString();
if (CHECK_ERROR (MIDIDestinationCreate (client, name, midiInputProc, mpc, &endPoint)))
if (CHECK_ERROR (MIDIDestinationCreate (client, name.cfString, midiInputProc, mpc, &endPoint)))
{
mpc->portAndEndpoint = new MidiPortAndEndpoint (0, endPoint);
@@ -499,8 +505,6 @@ MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallba
const ScopedLock sl (callbackLock);
activeCallbacks.add (mpc.release());
}
CFRelease (name);
}
return mi;


+ 3
- 3
source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp View File

@@ -341,10 +341,10 @@ namespace AiffFileHelpers
out.writeByte ((char) labelLength + 1);
out.write (label.toUTF8(), labelLength);
out.writeByte (0);
}
if ((out.getDataSize() & 1) != 0)
out.writeByte (0);
if ((out.getDataSize() & 1) != 0)
out.writeByte (0);
}
}
}
}


+ 2
- 2
source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp View File

@@ -1267,8 +1267,8 @@ private:
class MemoryMappedWavReader : public MemoryMappedAudioFormatReader
{
public:
MemoryMappedWavReader (const File& file, const WavAudioFormatReader& reader)
: MemoryMappedAudioFormatReader (file, reader, reader.dataChunkStart,
MemoryMappedWavReader (const File& wavFile, const WavAudioFormatReader& reader)
: MemoryMappedAudioFormatReader (wavFile, reader, reader.dataChunkStart,
reader.dataLength, reader.bytesPerFrame)
{
}


+ 1
- 1
source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp View File

@@ -163,7 +163,7 @@ void AudioFormatReader::read (AudioSampleBuffer* buffer,
}
else
{
HeapBlock<int*> chans ((size_t) numTargetChannels);
HeapBlock<int*> chans ((size_t) numTargetChannels + 1);
readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels);
}


+ 3
- 1
source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp View File

@@ -318,6 +318,8 @@ namespace
static void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) noexcept
{
ignoreUnused (e);
if (increment < 0)
{
ev.xbutton.button = Button5;
@@ -1633,7 +1635,7 @@ public:
void* data = nullptr;
const size_t bytes = (size_t) dispatch (effGetChunk, isPreset ? 1 : 0, 0, &data, 0.0f);
if (data != nullptr && bytes <= maxSizeMB * 1024 * 1024)
if (data != nullptr && bytes <= (size_t) maxSizeMB * 1024 * 1024)
{
mb.setSize (bytes);
mb.copyFrom (data, 0, bytes);


+ 619
- 395
source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
File diff suppressed because it is too large
View File


+ 6
- 4
source/modules/juce_core/containers/juce_NamedValueSet.cpp View File

@@ -29,7 +29,7 @@
struct NamedValueSet::NamedValue
{
NamedValue() noexcept {}
NamedValue (Identifier n, const var& v) : name (n), value (v) {}
NamedValue (const Identifier& n, const var& v) : name (n), value (v) {}
NamedValue (const NamedValue& other) : name (other.name), value (other.value) {}
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
@@ -39,7 +39,9 @@ struct NamedValueSet::NamedValue
{
}
NamedValue (Identifier n, var&& v) : name (n), value (static_cast<var&&> (v))
NamedValue (Identifier&& n, var&& v)
: name (static_cast<Identifier&&> (n)),
value (static_cast<var&&> (v))
{
}
@@ -138,7 +140,7 @@ var* NamedValueSet::getVarPointer (const Identifier& name) const noexcept
}
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
bool NamedValueSet::set (Identifier name, var&& newValue)
bool NamedValueSet::set (const Identifier& name, var&& newValue)
{
if (var* const v = getVarPointer (name))
{
@@ -154,7 +156,7 @@ bool NamedValueSet::set (Identifier name, var&& newValue)
}
#endif
bool NamedValueSet::set (Identifier name, const var& newValue)
bool NamedValueSet::set (const Identifier& name, const var& newValue)
{
if (var* const v = getVarPointer (name))
{


+ 2
- 2
source/modules/juce_core/containers/juce_NamedValueSet.h View File

@@ -78,14 +78,14 @@ public:
@returns true if a value was changed or added; false if the
value was already set the value passed-in.
*/
bool set (Identifier name, const var& newValue);
bool set (const Identifier& name, const var& newValue);
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
/** Changes or adds a named value.
@returns true if a value was changed or added; false if the
value was already set the value passed-in.
*/
bool set (Identifier name, var&& newValue);
bool set (const Identifier& name, var&& newValue);
#endif
/** Returns true if the set contains an item with the specified name. */


+ 9
- 9
source/modules/juce_core/containers/juce_Variant.cpp View File

@@ -576,7 +576,7 @@ var var::clone() const noexcept
}
//==============================================================================
const var& var::operator[] (Identifier propertyName) const
const var& var::operator[] (const Identifier& propertyName) const
{
if (DynamicObject* const o = getDynamicObject())
return o->getProperty (propertyName);
@@ -589,7 +589,7 @@ const var& var::operator[] (const char* const propertyName) const
return operator[] (Identifier (propertyName));
}
var var::getProperty (const Identifier propertyName, const var& defaultReturnValue) const
var var::getProperty (const Identifier& propertyName, const var& defaultReturnValue) const
{
if (DynamicObject* const o = getDynamicObject())
return o->getProperties().getWithDefault (propertyName, defaultReturnValue);
@@ -602,7 +602,7 @@ var::NativeFunction var::getNativeFunction() const
return isMethod() ? value.methodValue : nullptr;
}
var var::invoke (Identifier method, const var* arguments, int numArguments) const
var var::invoke (const Identifier& method, const var* arguments, int numArguments) const
{
if (DynamicObject* const o = getDynamicObject())
return o->invokeMethod (method, var::NativeFunctionArgs (*this, arguments, numArguments));
@@ -610,35 +610,35 @@ var var::invoke (Identifier method, const var* arguments, int numArguments) cons
return var();
}
var var::call (const Identifier method) const
var var::call (const Identifier& method) const
{
return invoke (method, nullptr, 0);
}
var var::call (const Identifier method, const var& arg1) const
var var::call (const Identifier& method, const var& arg1) const
{
return invoke (method, &arg1, 1);
}
var var::call (const Identifier method, const var& arg1, const var& arg2) const
var var::call (const Identifier& method, const var& arg1, const var& arg2) const
{
var args[] = { arg1, arg2 };
return invoke (method, args, 2);
}
var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3)
var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3)
{
var args[] = { arg1, arg2, arg3 };
return invoke (method, args, 3);
}
var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const
var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const
{
var args[] = { arg1, arg2, arg3, arg4 };
return invoke (method, args, 4);
}
var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const
var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const
{
var args[] = { arg1, arg2, arg3, arg4, arg5 };
return invoke (method, args, 5);


+ 9
- 10
source/modules/juce_core/containers/juce_Variant.h View File

@@ -62,7 +62,6 @@ public:
};
typedef var (*NativeFunction) (const NativeFunctionArgs&);
typedef Identifier identifier;
//==============================================================================
/** Creates a void variant. */
@@ -242,27 +241,27 @@ public:
//==============================================================================
/** If this variant is an object, this returns one of its properties. */
const var& operator[] (Identifier propertyName) const;
const var& operator[] (const Identifier& propertyName) const;
/** If this variant is an object, this returns one of its properties. */
const var& operator[] (const char* propertyName) const;
/** If this variant is an object, this returns one of its properties, or a default
fallback value if the property is not set. */
var getProperty (Identifier propertyName, const var& defaultReturnValue) const;
var getProperty (const Identifier& propertyName, const var& defaultReturnValue) const;
/** Invokes a named method call with no arguments. */
var call (Identifier method) const;
var call (const Identifier& method) const;
/** Invokes a named method call with one argument. */
var call (Identifier method, const var& arg1) const;
var call (const Identifier& method, const var& arg1) const;
/** Invokes a named method call with 2 arguments. */
var call (Identifier method, const var& arg1, const var& arg2) const;
var call (const Identifier& method, const var& arg1, const var& arg2) const;
/** Invokes a named method call with 3 arguments. */
var call (Identifier method, const var& arg1, const var& arg2, const var& arg3);
var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3);
/** Invokes a named method call with 4 arguments. */
var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
/** Invokes a named method call with 5 arguments. */
var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
/** Invokes a named method call with a list of arguments. */
var invoke (Identifier method, const var* arguments, int numArguments) const;
var invoke (const Identifier& method, const var* arguments, int numArguments) const;
/** If this object is a method, this returns the function pointer. */
NativeFunction getNativeFunction() const;


+ 5
- 0
source/modules/juce_core/files/juce_File.cpp View File

@@ -916,6 +916,11 @@ public:
const File temp (File::getSpecialLocation (File::tempDirectory));
expect (! File::nonexistent.exists());
expect (! File::nonexistent.existsAsFile());
expect (! File::nonexistent.isDirectory());
#if ! JUCE_WINDOWS
expect (File("/").isDirectory());
#endif
expect (home.isDirectory());
expect (home.exists());
expect (! home.existsAsFile());


+ 9
- 9
source/modules/juce_core/javascript/juce_Javascript.cpp View File

@@ -102,7 +102,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
static bool isNumericOrUndefined (const var& v) { return v.isInt() || v.isDouble() || v.isInt64() || v.isBool() || v.isUndefined(); }
static int64 getOctalValue (const String& s) { BigInteger b; b.parseString (s, 8); return b.toInt64(); }
static Identifier getPrototypeIdentifier() { static const Identifier i ("prototype"); return i; }
static var* getPropertyPointer (DynamicObject* o, Identifier i) { return o->getProperties().getVarPointer (i); }
static var* getPropertyPointer (DynamicObject* o, const Identifier& i) { return o->getProperties().getVarPointer (i); }
//==============================================================================
struct CodeLocation
@@ -136,7 +136,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
ReferenceCountedObjectPtr<RootObject> root;
DynamicObject::Ptr scope;
var findFunctionCall (const CodeLocation& location, const var& targetObject, Identifier functionName) const
var findFunctionCall (const CodeLocation& location, const var& targetObject, const Identifier& functionName) const
{
if (DynamicObject* o = targetObject.getDynamicObject())
{
@@ -170,7 +170,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
return var();
}
var* findRootClassProperty (Identifier className, Identifier propName) const
var* findRootClassProperty (const Identifier& className, const Identifier& propName) const
{
if (DynamicObject* cls = root->getProperty (className).getDynamicObject())
return getPropertyPointer (cls, propName);
@@ -178,7 +178,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
return nullptr;
}
var findSymbolInParentScopes (Identifier name) const
var findSymbolInParentScopes (const Identifier& name) const
{
if (const var* v = getPropertyPointer (scope, name))
return *v;
@@ -187,7 +187,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
: var::undefined();
}
bool findAndInvokeMethod (Identifier function, const var::NativeFunctionArgs& args, var& result) const
bool findAndInvokeMethod (const Identifier& function, const var::NativeFunctionArgs& args, var& result) const
{
DynamicObject* target = args.thisObject.getDynamicObject();
@@ -352,7 +352,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
struct UnqualifiedName : public Expression
{
UnqualifiedName (const CodeLocation& l, Identifier n) noexcept : Expression (l), name (n) {}
UnqualifiedName (const CodeLocation& l, const Identifier& n) noexcept : Expression (l), name (n) {}
var getResult (const Scope& s) const override { return s.findSymbolInParentScopes (name); }
@@ -369,7 +369,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
struct DotOperator : public Expression
{
DotOperator (const CodeLocation& l, ExpPtr& p, Identifier c) noexcept : Expression (l), parent (p), child (c) {}
DotOperator (const CodeLocation& l, ExpPtr& p, const Identifier& c) noexcept : Expression (l), parent (p), child (c) {}
var getResult (const Scope& s) const override
{
@@ -1670,7 +1670,7 @@ JavascriptEngine::~JavascriptEngine() {}
void JavascriptEngine::prepareTimeout() const noexcept { root->timeout = Time::getCurrentTime() + maximumExecutionTime; }
void JavascriptEngine::registerNativeObject (Identifier name, DynamicObject* object)
void JavascriptEngine::registerNativeObject (const Identifier& name, DynamicObject* object)
{
root->setProperty (name, object);
}
@@ -1706,7 +1706,7 @@ var JavascriptEngine::evaluate (const String& code, Result* result)
return var::undefined();
}
var JavascriptEngine::callFunction (Identifier function, const var::NativeFunctionArgs& args, Result* result)
var JavascriptEngine::callFunction (const Identifier& function, const var::NativeFunctionArgs& args, Result* result)
{
var returnVal (var::undefined());


+ 2
- 2
source/modules/juce_core/javascript/juce_Javascript.h View File

@@ -78,7 +78,7 @@ public:
The function arguments are passed in the same format as used by native
methods in the var class.
*/
var callFunction (Identifier function,
var callFunction (const Identifier& function,
const var::NativeFunctionArgs& args,
Result* errorMessage = nullptr);
@@ -87,7 +87,7 @@ public:
engine until the engine is deleted. The name must be a simple JS identifier,
without any dots.
*/
void registerNativeObject (Identifier objectName, DynamicObject* object);
void registerNativeObject (const Identifier& objectName, DynamicObject* object);
/** This value indicates how long a call to one of the evaluate methods is permitted
to run before timing-out and failing.


+ 10
- 0
source/modules/juce_core/memory/juce_ContainerDeletePolicy.h View File

@@ -45,6 +45,16 @@ struct ContainerDeletePolicy
{
static void destroy (ObjectType* object)
{
// If the line below triggers a compiler error, it means that you are using
// an incomplete type for ObjectType (for example, a type that is declared
// but not defined). This is a problem because then the following delete is
// undefined behaviour. The purpose of the sizeof is to capture this situation.
// If this was caused by a ScopedPointer to a forward-declared type, move the
// implementation of all methods trying to use the ScopedPointer (e.g. the destructor
// of the class owning it) into cpp files where they can see to the definition
// of ObjectType. This should fix the error.
ignoreUnused (sizeof (ObjectType));
delete object;
}
};


+ 2
- 2
source/modules/juce_core/memory/juce_Memory.h View File

@@ -50,7 +50,7 @@ inline void deleteAndZero (Type& pointer) { delete poi
a specific number of bytes,
*/
template <typename Type, typename IntegerType>
inline Type* addBytesToPointer (Type* pointer, IntegerType bytes) noexcept { return (Type*) (((char*) pointer) + bytes); }
inline Type* addBytesToPointer (Type* basePointer, IntegerType bytes) noexcept { return (Type*) (((char*) basePointer) + bytes); }
/** A handy function which returns the difference between any two pointers, in bytes.
The address of the second pointer is subtracted from the first, and the difference in bytes is returned.
@@ -62,7 +62,7 @@ inline int getAddressDifference (Type1* pointer1, Type2* pointer2) noexcept { r
nullptr if the pointer is null.
*/
template <class Type>
inline Type* createCopyIfNotNull (const Type* pointer) { return pointer != nullptr ? new Type (*pointer) : nullptr; }
inline Type* createCopyIfNotNull (const Type* objectToCopy) { return objectToCopy != nullptr ? new Type (*objectToCopy) : nullptr; }
//==============================================================================
#if JUCE_MAC || JUCE_IOS || DOXYGEN


+ 21
- 7
source/modules/juce_core/memory/juce_SharedResourcePointer.h View File

@@ -94,13 +94,12 @@ public:
*/
SharedResourcePointer()
{
SharedObjectHolder& holder = getSharedObjectHolder();
const SpinLock::ScopedLockType sl (holder.lock);
if (++(holder.refCount) == 1)
holder.sharedInstance = new SharedObjectType();
initialise();
}
sharedObject = holder.sharedInstance;
SharedResourcePointer (const SharedResourcePointer&)
{
initialise();
}
/** Destructor.
@@ -145,7 +144,22 @@ private:
SharedObjectType* sharedObject;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedResourcePointer)
void initialise()
{
SharedObjectHolder& holder = getSharedObjectHolder();
const SpinLock::ScopedLockType sl (holder.lock);
if (++(holder.refCount) == 1)
holder.sharedInstance = new SharedObjectType();
sharedObject = holder.sharedInstance;
}
// There's no need to assign to a SharedResourcePointer because every
// instance of the class is exactly the same!
SharedResourcePointer& operator= (const SharedResourcePointer&) JUCE_DELETED_FUNCTION;
JUCE_LEAK_DETECTOR (SharedResourcePointer)
};


+ 2
- 2
source/modules/juce_core/native/juce_posix_SharedCode.h View File

@@ -265,8 +265,8 @@ bool File::isDirectory() const
{
juce_statStruct info;
return fullPath.isEmpty()
|| (juce_stat (fullPath, info) && ((info.st_mode & S_IFDIR) != 0));
return fullPath.isNotEmpty()
&& (juce_stat (fullPath, info) && ((info.st_mode & S_IFDIR) != 0));
}
bool File::exists() const


+ 12
- 0
source/modules/juce_core/network/juce_URL.h View File

@@ -248,6 +248,9 @@ public:
/** Attempts to open a stream that can read from this URL.
Note that on some platforms (Android, for example) it's not permitted to do any network
action from the message thread, so you must only call it from a background thread.
@param usePostCommand if true, it will try to do use a http 'POST' to pass
the parameters, otherwise it'll encode them into the
URL and do a 'GET'.
@@ -287,6 +290,9 @@ public:
If it succeeds, this will return true and append the data it read onto the end
of the memory block.
Note that on some platforms (Android, for example) it's not permitted to do any network
action from the message thread, so you must only call it from a background thread.
@param destData the memory block to append the new data to
@param usePostCommand whether to use a POST command to get the data (uses
a GET command if this is false)
@@ -302,6 +308,9 @@ public:
operation that fails and one that returns an empty string, you'll need to use
a different method, such as readEntireBinaryStream().
Note that on some platforms (Android, for example) it's not permitted to do any network
action from the message thread, so you must only call it from a background thread.
@param usePostCommand whether to use a POST command to get the data (uses
a GET command if this is false)
@see readEntireBinaryStream, readEntireXmlStream
@@ -316,6 +325,9 @@ public:
When it returns a valid XmlElement object, the caller is responsibile for deleting
this object when no longer needed.
Note that on some platforms (Android, for example) it's not permitted to do any network
action from the message thread, so you must only call it from a background thread.
@param usePostCommand whether to use a POST command to get the data (uses
a GET command if this is false)


+ 11
- 1
source/modules/juce_core/text/juce_Identifier.cpp View File

@@ -31,7 +31,17 @@ Identifier::~Identifier() noexcept {}
Identifier::Identifier (const Identifier& other) noexcept : name (other.name) {}
Identifier& Identifier::operator= (const Identifier other) noexcept
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Identifier::Identifier (Identifier&& other) noexcept : name (static_cast<String&&> (other.name)) {}
Identifier& Identifier::operator= (Identifier&& other) noexcept
{
name = static_cast<String&&> (other.name);
return *this;
}
#endif
Identifier& Identifier::operator= (const Identifier& other) noexcept
{
name = other.name;
return *this;


+ 11
- 3
source/modules/juce_core/text/juce_Identifier.h View File

@@ -68,16 +68,24 @@ public:
Identifier (const Identifier& other) noexcept;
/** Creates a copy of another identifier. */
Identifier& operator= (const Identifier other) noexcept;
Identifier& operator= (const Identifier& other) noexcept;
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
/** Creates a copy of another identifier. */
Identifier (Identifier&& other) noexcept;
/** Creates a copy of another identifier. */
Identifier& operator= (Identifier&& other) noexcept;
#endif
/** Destructor */
~Identifier() noexcept;
/** Compares two identifiers. This is a very fast operation. */
inline bool operator== (Identifier other) const noexcept { return name.getCharPointer() == other.name.getCharPointer(); }
inline bool operator== (const Identifier& other) const noexcept { return name.getCharPointer() == other.name.getCharPointer(); }
/** Compares two identifiers. This is a very fast operation. */
inline bool operator!= (Identifier other) const noexcept { return name.getCharPointer() != other.name.getCharPointer(); }
inline bool operator!= (const Identifier& other) const noexcept { return name.getCharPointer() != other.name.getCharPointer(); }
/** Compares the identifier with a string. */
inline bool operator== (StringRef other) const noexcept { return name == other; }


+ 2
- 2
source/modules/juce_core/text/juce_String.h View File

@@ -89,12 +89,12 @@ public:
*/
String (const char* text, size_t maxChars);
/** Creates a string from a whcar_t character string.
/** Creates a string from a wchar_t character string.
Depending on the platform, this may be treated as either UTF-32 or UTF-16.
*/
String (const wchar_t* text);
/** Creates a string from a whcar_t character string.
/** Creates a string from a wchar_t character string.
Depending on the platform, this may be treated as either UTF-32 or UTF-16.
*/
String (const wchar_t* text, size_t maxChars);


+ 23
- 24
source/modules/juce_data_structures/values/juce_ValueTree.cpp View File

@@ -27,7 +27,7 @@ class ValueTree::SharedObject : public ReferenceCountedObject
public:
typedef ReferenceCountedObjectPtr<SharedObject> Ptr;
explicit SharedObject (Identifier t) noexcept
explicit SharedObject (const Identifier& t) noexcept
: type (t), parent (nullptr)
{
}
@@ -126,7 +126,7 @@ public:
}
}
void sendPropertyChangeMessage (const Identifier property)
void sendPropertyChangeMessage (const Identifier& property)
{
ValueTree tree (this);
@@ -169,7 +169,7 @@ public:
callListeners (&ValueTree::Listener::valueTreeParentChanged, tree);
}
void setProperty (const Identifier name, const var& newValue, UndoManager* const undoManager)
void setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager)
{
if (undoManager == nullptr)
{
@@ -190,12 +190,12 @@ public:
}
}
bool hasProperty (const Identifier name) const noexcept
bool hasProperty (const Identifier& name) const noexcept
{
return properties.contains (name);
}
void removeProperty (const Identifier name, UndoManager* const undoManager)
void removeProperty (const Identifier& name, UndoManager* const undoManager)
{
if (undoManager == nullptr)
{
@@ -238,7 +238,7 @@ public:
setProperty (source.properties.getName(i), source.properties.getValueAt(i), undoManager);
}
ValueTree getChildWithName (const Identifier typeToMatch) const
ValueTree getChildWithName (const Identifier& typeToMatch) const
{
for (int i = 0; i < children.size(); ++i)
{
@@ -250,7 +250,7 @@ public:
return ValueTree();
}
ValueTree getOrCreateChildWithName (const Identifier typeToMatch, UndoManager* undoManager)
ValueTree getOrCreateChildWithName (const Identifier& typeToMatch, UndoManager* undoManager)
{
for (int i = 0; i < children.size(); ++i)
{
@@ -265,7 +265,7 @@ public:
}
ValueTree getChildWithProperty (const Identifier propertyName, const var& propertyValue) const
ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
{
for (int i = 0; i < children.size(); ++i)
{
@@ -458,7 +458,7 @@ public:
class SetPropertyAction : public UndoableAction
{
public:
SetPropertyAction (SharedObject* const so, const Identifier propertyName,
SetPropertyAction (SharedObject* const so, const Identifier& propertyName,
const var& newVal, const var& oldVal, bool isAdding, bool isDeleting)
: target (so), name (propertyName), newValue (newVal), oldValue (oldVal),
isAddingNewProperty (isAdding), isDeletingProperty (isDeleting)
@@ -629,7 +629,7 @@ ValueTree::ValueTree() noexcept
const ValueTree ValueTree::invalid;
ValueTree::ValueTree (Identifier type) : object (new ValueTree::SharedObject (type))
ValueTree::ValueTree (const Identifier& type) : object (new ValueTree::SharedObject (type))
{
jassert (type.toString().isNotEmpty()); // All objects must be given a sensible type name!
}
@@ -702,7 +702,7 @@ ValueTree ValueTree::createCopy() const
return ValueTree (createCopyIfNotNull (object.get()));
}
bool ValueTree::hasType (const Identifier typeName) const
bool ValueTree::hasType (const Identifier& typeName) const
{
return object != nullptr && object->type == typeName;
}
@@ -727,24 +727,23 @@ ValueTree ValueTree::getSibling (const int delta) const
return ValueTree (object->parent->children.getObjectPointer (index));
}
const var& ValueTree::operator[] (const Identifier name) const
const var& ValueTree::operator[] (const Identifier& name) const
{
return object == nullptr ? var::null : object->properties[name];
}
const var& ValueTree::getProperty (const Identifier name) const
const var& ValueTree::getProperty (const Identifier& name) const
{
return object == nullptr ? var::null : object->properties[name];
}
var ValueTree::getProperty (const Identifier name, const var& defaultReturnValue) const
var ValueTree::getProperty (const Identifier& name, const var& defaultReturnValue) const
{
return object == nullptr ? defaultReturnValue
: object->properties.getWithDefault (name, defaultReturnValue);
}
ValueTree& ValueTree::setProperty (const Identifier name, const var& newValue,
UndoManager* const undoManager)
ValueTree& ValueTree::setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager)
{
jassert (name.toString().isNotEmpty()); // Must have a valid property name!
jassert (object != nullptr); // Trying to add a property to a null ValueTree will fail!
@@ -755,12 +754,12 @@ ValueTree& ValueTree::setProperty (const Identifier name, const var& newValue,
return *this;
}
bool ValueTree::hasProperty (const Identifier name) const
bool ValueTree::hasProperty (const Identifier& name) const
{
return object != nullptr && object->hasProperty (name);
}
void ValueTree::removeProperty (const Identifier name, UndoManager* const undoManager)
void ValueTree::removeProperty (const Identifier& name, UndoManager* const undoManager)
{
if (object != nullptr)
object->removeProperty (name, undoManager);
@@ -803,7 +802,7 @@ class ValueTreePropertyValueSource : public Value::ValueSource,
private ValueTree::Listener
{
public:
ValueTreePropertyValueSource (const ValueTree& vt, const Identifier prop, UndoManager* um)
ValueTreePropertyValueSource (const ValueTree& vt, const Identifier& prop, UndoManager* um)
: tree (vt), property (prop), undoManager (um)
{
tree.addListener (this);
@@ -836,7 +835,7 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueTreePropertyValueSource)
};
Value ValueTree::getPropertyAsValue (const Identifier name, UndoManager* const undoManager)
Value ValueTree::getPropertyAsValue (const Identifier& name, UndoManager* const undoManager)
{
return Value (new ValueTreePropertyValueSource (*this, name, undoManager));
}
@@ -853,17 +852,17 @@ ValueTree ValueTree::getChild (int index) const
: static_cast<SharedObject*> (nullptr));
}
ValueTree ValueTree::getChildWithName (const Identifier type) const
ValueTree ValueTree::getChildWithName (const Identifier& type) const
{
return object != nullptr ? object->getChildWithName (type) : ValueTree();
}
ValueTree ValueTree::getOrCreateChildWithName (const Identifier type, UndoManager* undoManager)
ValueTree ValueTree::getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager)
{
return object != nullptr ? object->getOrCreateChildWithName (type, undoManager) : ValueTree();
}
ValueTree ValueTree::getChildWithProperty (const Identifier propertyName, const var& propertyValue) const
ValueTree ValueTree::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
{
return object != nullptr ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree();
}
@@ -945,7 +944,7 @@ void ValueTree::removeListener (Listener* listener)
object->valueTreesWithListeners.removeValue (this);
}
void ValueTree::sendPropertyChangeMessage (const Identifier property)
void ValueTree::sendPropertyChangeMessage (const Identifier& property)
{
if (object != nullptr)
object->sendPropertyChangeMessage (property);


+ 13
- 13
source/modules/juce_data_structures/values/juce_ValueTree.h View File

@@ -79,7 +79,7 @@ public:
Like an XmlElement, each ValueTree node has a type, which you can access with
getType() and hasType().
*/
explicit ValueTree (Identifier type);
explicit ValueTree (const Identifier& type);
/** Creates a reference to another ValueTree. */
ValueTree (const ValueTree&);
@@ -134,7 +134,7 @@ public:
/** Returns true if the node has this type.
The comparison is case-sensitive.
*/
bool hasType (const Identifier typeName) const;
bool hasType (const Identifier& typeName) const;
//==============================================================================
/** Returns the value of a named property.
@@ -142,21 +142,21 @@ public:
You can also use operator[] to get a property.
@see var, setProperty, hasProperty
*/
const var& getProperty (const Identifier name) const;
const var& getProperty (const Identifier& name) const;
/** Returns the value of a named property, or a user-specified default if the property doesn't exist.
If no such property has been set, this will return the value of defaultReturnValue.
You can also use operator[] and getProperty to get a property.
@see var, getProperty, setProperty, hasProperty
*/
var getProperty (const Identifier name, const var& defaultReturnValue) const;
var getProperty (const Identifier& name, const var& defaultReturnValue) const;
/** Returns the value of a named property.
If no such property has been set, this will return a void variant. This is the same as
calling getProperty().
@see getProperty
*/
const var& operator[] (const Identifier name) const;
const var& operator[] (const Identifier& name) const;
/** Changes a named property of the node.
The name identifier must not be an empty string.
@@ -165,16 +165,16 @@ public:
@see var, getProperty, removeProperty
@returns a reference to the value tree, so that you can daisy-chain calls to this method.
*/
ValueTree& setProperty (const Identifier name, const var& newValue, UndoManager* undoManager);
ValueTree& setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager);
/** Returns true if the node contains a named property. */
bool hasProperty (const Identifier name) const;
bool hasProperty (const Identifier& name) const;
/** Removes a property from the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
so that this change can be undone.
*/
void removeProperty (const Identifier name, UndoManager* undoManager);
void removeProperty (const Identifier& name, UndoManager* undoManager);
/** Removes all properties from the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
@@ -198,7 +198,7 @@ public:
it needs to change the value. Attaching a Value::Listener to the value object will provide
callbacks whenever the property changes.
*/
Value getPropertyAsValue (const Identifier name, UndoManager* undoManager);
Value getPropertyAsValue (const Identifier& name, UndoManager* undoManager);
/** Overwrites all the properties in this tree with the properties of the source tree.
Any properties that already exist will be updated; and new ones will be added, and
@@ -223,7 +223,7 @@ public:
whether a node is valid).
@see getOrCreateChildWithName
*/
ValueTree getChildWithName (const Identifier type) const;
ValueTree getChildWithName (const Identifier& type) const;
/** Returns the first child node with the speficied type name, creating and adding
a child with this name if there wasn't already one there.
@@ -232,7 +232,7 @@ public:
the method on is itself invalid.
@see getChildWithName
*/
ValueTree getOrCreateChildWithName (const Identifier type, UndoManager* undoManager);
ValueTree getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager);
/** Looks for the first child node that has the speficied property value.
@@ -242,7 +242,7 @@ public:
If no such node is found, it'll return an invalid node. (See isValid() to find out
whether a node is valid).
*/
ValueTree getChildWithProperty (const Identifier propertyName, const var& propertyValue) const;
ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const;
/** Adds a child to this node.
@@ -453,7 +453,7 @@ public:
/** Causes a property-change callback to be triggered for the specified property,
calling any listeners that are registered.
*/
void sendPropertyChangeMessage (const Identifier property);
void sendPropertyChangeMessage (const Identifier& property);
//==============================================================================
/** This method uses a comparator object to sort the tree's children into order.


+ 4
- 2
source/modules/juce_graphics/contexts/juce_GraphicsContext.cpp View File

@@ -32,8 +32,8 @@ namespace
jassert ((int) x >= -maxVal && (int) x <= maxVal
&& (int) y >= -maxVal && (int) y <= maxVal
&& (int) w >= -maxVal && (int) w <= maxVal
&& (int) h >= -maxVal && (int) h <= maxVal);
&& (int) w >= 0 && (int) w <= maxVal
&& (int) h >= 0 && (int) h <= maxVal);
#endif
return Rectangle<Type> (x, y, w, h);
@@ -427,6 +427,8 @@ void Graphics::drawRect (const Rectangle<int>& r, int lineThickness) const
void Graphics::drawRect (Rectangle<float> r, const float lineThickness) const
{
jassert (r.getWidth() >= 0.0f && r.getHeight() >= 0.0f);
RectangleList<float> rects;
rects.addWithoutMerging (r.removeFromTop (lineThickness));
rects.addWithoutMerging (r.removeFromBottom (lineThickness));


+ 66
- 53
source/modules/juce_graphics/geometry/juce_Rectangle.h View File

@@ -52,21 +52,21 @@ public:
}
/** Creates a rectangle with a given position and size. */
Rectangle (const ValueType initialX, const ValueType initialY,
const ValueType width, const ValueType height) noexcept
Rectangle (ValueType initialX, ValueType initialY,
ValueType width, ValueType height) noexcept
: pos (initialX, initialY),
w (width), h (height)
{
}
/** Creates a rectangle with a given size, and a position of (0, 0). */
Rectangle (const ValueType width, const ValueType height) noexcept
Rectangle (ValueType width, ValueType height) noexcept
: w (width), h (height)
{
}
/** Creates a Rectangle from the positions of two opposite corners. */
Rectangle (const Point<ValueType> corner1, const Point<ValueType> corner2) noexcept
Rectangle (Point<ValueType> corner1, Point<ValueType> corner2) noexcept
: pos (jmin (corner1.x, corner2.x),
jmin (corner1.y, corner2.y)),
w (corner1.x - corner2.x),
@@ -80,8 +80,8 @@ public:
The right and bottom values must be larger than the left and top ones, or the resulting
rectangle will have a negative size.
*/
static Rectangle leftTopRightBottom (const ValueType left, const ValueType top,
const ValueType right, const ValueType bottom) noexcept
static Rectangle leftTopRightBottom (ValueType left, ValueType top,
ValueType right, ValueType bottom) noexcept
{
return Rectangle (left, top, right - left, bottom - top);
}
@@ -134,17 +134,17 @@ public:
/** Returns the aspect ratio of the rectangle's width / height.
If widthOverHeight is true, it returns width / height; if widthOverHeight is false,
it returns height / width. */
ValueType getAspectRatio (const bool widthOverHeight = true) const noexcept { return widthOverHeight ? w / h : h / w; }
ValueType getAspectRatio (bool widthOverHeight = true) const noexcept { return widthOverHeight ? w / h : h / w; }
//==============================================================================
/** Returns the rectangle's top-left position as a Point. */
inline Point<ValueType> getPosition() const noexcept { return pos; }
/** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */
inline void setPosition (const Point<ValueType> newPos) noexcept { pos = newPos; }
inline void setPosition (Point<ValueType> newPos) noexcept { pos = newPos; }
/** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */
inline void setPosition (const ValueType newX, const ValueType newY) noexcept { pos.setXY (newX, newY); }
inline void setPosition (ValueType newX, ValueType newY) noexcept { pos.setXY (newX, newY); }
/** Returns the rectangle's top-left position as a Point. */
Point<ValueType> getTopLeft() const noexcept { return pos; }
@@ -158,62 +158,75 @@ public:
/** Returns the rectangle's bottom-right position as a Point. */
Point<ValueType> getBottomRight() const noexcept { return Point<ValueType> (pos.x + w, pos.y + h); }
/** Returns the rectangle's left and right positions as a Range. */
Range<ValueType> getHorizontalRange() const noexcept { return Range<ValueType>::withStartAndLength (pos.x, w); }
/** Returns the rectangle's top and bottom positions as a Range. */
Range<ValueType> getVerticalRange() const noexcept { return Range<ValueType>::withStartAndLength (pos.y, h); }
/** Changes the rectangle's size, leaving the position of its top-left corner unchanged. */
void setSize (const ValueType newWidth, const ValueType newHeight) noexcept { w = newWidth; h = newHeight; }
void setSize (ValueType newWidth, ValueType newHeight) noexcept { w = newWidth; h = newHeight; }
/** Changes all the rectangle's coordinates. */
void setBounds (const ValueType newX, const ValueType newY,
const ValueType newWidth, const ValueType newHeight) noexcept { pos.x = newX; pos.y = newY; w = newWidth; h = newHeight; }
void setBounds (ValueType newX, ValueType newY,
ValueType newWidth, ValueType newHeight) noexcept { pos.x = newX; pos.y = newY; w = newWidth; h = newHeight; }
/** Changes the rectangle's X coordinate */
inline void setX (const ValueType newX) noexcept { pos.x = newX; }
inline void setX (ValueType newX) noexcept { pos.x = newX; }
/** Changes the rectangle's Y coordinate */
inline void setY (const ValueType newY) noexcept { pos.y = newY; }
inline void setY (ValueType newY) noexcept { pos.y = newY; }
/** Changes the rectangle's width */
inline void setWidth (const ValueType newWidth) noexcept { w = newWidth; }
inline void setWidth (ValueType newWidth) noexcept { w = newWidth; }
/** Changes the rectangle's height */
inline void setHeight (const ValueType newHeight) noexcept { h = newHeight; }
inline void setHeight (ValueType newHeight) noexcept { h = newHeight; }
/** Changes the position of the rectangle's centre (leaving its size unchanged). */
inline void setCentre (const ValueType newCentreX, const ValueType newCentreY) noexcept { pos.x = newCentreX - w / (ValueType) 2; pos.y = newCentreY - h / (ValueType) 2; }
inline void setCentre (ValueType newCentreX, ValueType newCentreY) noexcept { pos.x = newCentreX - w / (ValueType) 2;
pos.y = newCentreY - h / (ValueType) 2; }
/** Changes the position of the rectangle's centre (leaving its size unchanged). */
inline void setCentre (const Point<ValueType> newCentre) noexcept { setCentre (newCentre.x, newCentre.y); }
inline void setCentre (Point<ValueType> newCentre) noexcept { setCentre (newCentre.x, newCentre.y); }
/** Changes the position of the rectangle's left and right edges. */
void setHorizontalRange (Range<ValueType> range) noexcept { pos.x = range.getStart(); w = range.getLength(); }
/** Changes the position of the rectangle's top and bottom edges. */
void setVerticalRange (Range<ValueType> range) noexcept { pos.y = range.getStart(); h = range.getLength(); }
/** Returns a rectangle which has the same size and y-position as this one, but with a different x-position. */
Rectangle withX (const ValueType newX) const noexcept { return Rectangle (newX, pos.y, w, h); }
Rectangle withX (ValueType newX) const noexcept { return Rectangle (newX, pos.y, w, h); }
/** Returns a rectangle which has the same size and x-position as this one, but with a different y-position. */
Rectangle withY (const ValueType newY) const noexcept { return Rectangle (pos.x, newY, w, h); }
Rectangle withY (ValueType newY) const noexcept { return Rectangle (pos.x, newY, w, h); }
/** Returns a rectangle with the same size as this one, but a new position. */
Rectangle withPosition (const ValueType newX, const ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); }
Rectangle withPosition (ValueType newX, ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); }
/** Returns a rectangle with the same size as this one, but a new position. */
Rectangle withPosition (const Point<ValueType> newPos) const noexcept { return Rectangle (newPos.x, newPos.y, w, h); }
Rectangle withPosition (Point<ValueType> newPos) const noexcept { return Rectangle (newPos.x, newPos.y, w, h); }
/** Returns a rectangle whose size is the same as this one, but whose top-left position is (0, 0). */
Rectangle withZeroOrigin() const noexcept { return Rectangle (w, h); }
Rectangle withZeroOrigin() const noexcept { return Rectangle (w, h); }
/** Returns a rectangle with the same size as this one, but a new centre position. */
Rectangle withCentre (const Point<ValueType> newCentre) const noexcept { return Rectangle (newCentre.x - w / (ValueType) 2,
newCentre.y - h / (ValueType) 2, w, h); }
Rectangle withCentre (Point<ValueType> newCentre) const noexcept { return Rectangle (newCentre.x - w / (ValueType) 2,
newCentre.y - h / (ValueType) 2, w, h); }
/** Returns a rectangle which has the same position and height as this one, but with a different width. */
Rectangle withWidth (ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); }
Rectangle withWidth (ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); }
/** Returns a rectangle which has the same position and width as this one, but with a different height. */
Rectangle withHeight (ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); }
Rectangle withHeight (ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); }
/** Returns a rectangle with the same top-left position as this one, but a new size. */
Rectangle withSize (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); }
Rectangle withSize (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); }
/** Returns a rectangle with the same centre position as this one, but a new size. */
Rectangle withSizeKeepingCentre (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x + (w - newWidth) / (ValueType) 2,
pos.y + (h - newHeight) / (ValueType) 2, newWidth, newHeight); }
Rectangle withSizeKeepingCentre (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x + (w - newWidth) / (ValueType) 2,
pos.y + (h - newHeight) / (ValueType) 2, newWidth, newHeight); }
/** Moves the x position, adjusting the width so that the right-hand edge remains in the same place.
If the x is moved to be on the right of the current right-hand edge, the width will be set to zero.
@@ -277,41 +290,41 @@ public:
//==============================================================================
/** Moves the rectangle's position by adding amount to its x and y coordinates. */
void translate (const ValueType deltaX,
const ValueType deltaY) noexcept
void translate (ValueType deltaX,
ValueType deltaY) noexcept
{
pos.x += deltaX;
pos.y += deltaY;
}
/** Returns a rectangle which is the same as this one moved by a given amount. */
Rectangle translated (const ValueType deltaX,
const ValueType deltaY) const noexcept
Rectangle translated (ValueType deltaX,
ValueType deltaY) const noexcept
{
return Rectangle (pos.x + deltaX, pos.y + deltaY, w, h);
}
/** Returns a rectangle which is the same as this one moved by a given amount. */
Rectangle operator+ (const Point<ValueType> deltaPosition) const noexcept
Rectangle operator+ (Point<ValueType> deltaPosition) const noexcept
{
return Rectangle (pos.x + deltaPosition.x, pos.y + deltaPosition.y, w, h);
}
/** Moves this rectangle by a given amount. */
Rectangle& operator+= (const Point<ValueType> deltaPosition) noexcept
Rectangle& operator+= (Point<ValueType> deltaPosition) noexcept
{
pos += deltaPosition;
return *this;
}
/** Returns a rectangle which is the same as this one moved by a given amount. */
Rectangle operator- (const Point<ValueType> deltaPosition) const noexcept
Rectangle operator- (Point<ValueType> deltaPosition) const noexcept
{
return Rectangle (pos.x - deltaPosition.x, pos.y - deltaPosition.y, w, h);
}
/** Moves this rectangle by a given amount. */
Rectangle& operator-= (const Point<ValueType> deltaPosition) noexcept
Rectangle& operator-= (Point<ValueType> deltaPosition) noexcept
{
pos -= deltaPosition;
return *this;
@@ -396,8 +409,8 @@ public:
Effectively, its new size is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2).
@see expanded, reduce, reduced
*/
void expand (const ValueType deltaX,
const ValueType deltaY) noexcept
void expand (ValueType deltaX,
ValueType deltaY) noexcept
{
const ValueType nw = jmax (ValueType(), w + deltaX * 2);
const ValueType nh = jmax (ValueType(), h + deltaY * 2);
@@ -409,8 +422,8 @@ public:
Effectively, the rectangle returned is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2).
@see expand, reduce, reduced
*/
Rectangle expanded (const ValueType deltaX,
const ValueType deltaY) const noexcept
Rectangle expanded (ValueType deltaX,
ValueType deltaY) const noexcept
{
const ValueType nw = jmax (ValueType(), w + deltaX * 2);
const ValueType nh = jmax (ValueType(), h + deltaY * 2);
@@ -422,7 +435,7 @@ public:
Effectively, the rectangle returned is (x - delta, y - delta, w + delta * 2, h + delta * 2).
@see expand, reduce, reduced
*/
Rectangle expanded (const ValueType delta) const noexcept
Rectangle expanded (ValueType delta) const noexcept
{
return expanded (delta, delta);
}
@@ -432,8 +445,8 @@ public:
Effectively, its new size is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2).
@see reduced, expand, expanded
*/
void reduce (const ValueType deltaX,
const ValueType deltaY) noexcept
void reduce (ValueType deltaX,
ValueType deltaY) noexcept
{
expand (-deltaX, -deltaY);
}
@@ -443,8 +456,8 @@ public:
Effectively, the rectangle returned is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2).
@see reduce, expand, expanded
*/
Rectangle reduced (const ValueType deltaX,
const ValueType deltaY) const noexcept
Rectangle reduced (ValueType deltaX,
ValueType deltaY) const noexcept
{
return expanded (-deltaX, -deltaY);
}
@@ -454,7 +467,7 @@ public:
Effectively, the rectangle returned is (x + delta, y + delta, w - delta * 2, h - delta * 2).
@see reduce, expand, expanded
*/
Rectangle reduced (const ValueType delta) const noexcept
Rectangle reduced (ValueType delta) const noexcept
{
return reduced (delta, delta);
}
@@ -468,7 +481,7 @@ public:
If amountToRemove is greater than the height of this rectangle, it'll be clipped to
that value.
*/
Rectangle removeFromTop (const ValueType amountToRemove) noexcept
Rectangle removeFromTop (ValueType amountToRemove) noexcept
{
const Rectangle r (pos.x, pos.y, w, jmin (amountToRemove, h));
pos.y += r.h; h -= r.h;
@@ -484,7 +497,7 @@ public:
If amountToRemove is greater than the width of this rectangle, it'll be clipped to
that value.
*/
Rectangle removeFromLeft (const ValueType amountToRemove) noexcept
Rectangle removeFromLeft (ValueType amountToRemove) noexcept
{
const Rectangle r (pos.x, pos.y, jmin (amountToRemove, w), h);
pos.x += r.w; w -= r.w;
@@ -533,13 +546,13 @@ public:
bool operator!= (const Rectangle& other) const noexcept { return pos != other.pos || w != other.w || h != other.h; }
/** Returns true if this coordinate is inside the rectangle. */
bool contains (const ValueType xCoord, const ValueType yCoord) const noexcept
bool contains (ValueType xCoord, ValueType yCoord) const noexcept
{
return xCoord >= pos.x && yCoord >= pos.y && xCoord < pos.x + w && yCoord < pos.y + h;
}
/** Returns true if this coordinate is inside the rectangle. */
bool contains (const Point<ValueType> point) const noexcept
bool contains (Point<ValueType> point) const noexcept
{
return point.x >= pos.x && point.y >= pos.y && point.x < pos.x + w && point.y < pos.y + h;
}
@@ -552,7 +565,7 @@ public:
}
/** Returns the nearest point to the specified point that lies within this rectangle. */
Point<ValueType> getConstrainedPoint (const Point<ValueType> point) const noexcept
Point<ValueType> getConstrainedPoint (Point<ValueType> point) const noexcept
{
return Point<ValueType> (jlimit (pos.x, pos.x + w, point.x),
jlimit (pos.y, pos.y + h, point.y));


+ 1
- 0
source/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp View File

@@ -59,6 +59,7 @@ void DrawableButton::setImages (const Drawable* normal,
overImageOn = copyDrawableIfNotNull (overOn);
downImageOn = copyDrawableIfNotNull (downOn);
disabledImageOn = copyDrawableIfNotNull (disabledOn);
currentImage = nullptr;
buttonStateChanged();
}


+ 6
- 3
source/modules/juce_gui_basics/components/juce_Component.cpp View File

@@ -1153,12 +1153,15 @@ void Component::setBounds (const int x, const int y, int w, int h)
void Component::sendMovedResizedMessagesIfPending()
{
if (flags.isMoveCallbackPending || flags.isResizeCallbackPending)
{
sendMovedResizedMessages (flags.isMoveCallbackPending, flags.isResizeCallbackPending);
const bool wasMoved = flags.isMoveCallbackPending;
const bool wasResized = flags.isResizeCallbackPending;
if (wasMoved || wasResized)
{
flags.isMoveCallbackPending = false;
flags.isResizeCallbackPending = false;
sendMovedResizedMessages (wasMoved, wasResized);
}
}


+ 1
- 1
source/modules/juce_gui_basics/components/juce_Component.h View File

@@ -812,7 +812,7 @@ public:
virtual void childrenChanged();
//==============================================================================
/** Tests whether a given point inside the component.
/** Tests whether a given point is inside the component.
Overriding this method allows you to create components which only intercept
mouse-clicks within a user-defined area.


+ 4
- 2
source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp View File

@@ -387,7 +387,7 @@ void FileBrowserComponent::fileDoubleClicked (const File& f)
{
setRoot (f);
if ((flags & canSelectDirectories) != 0)
if ((flags & canSelectDirectories) != 0 && (flags & doNotClearFileNameOnRootChange) == 0)
filenameBox.setText (String::empty);
}
else
@@ -432,7 +432,9 @@ void FileBrowserComponent::textEditorReturnKeyPressed (TextEditor&)
{
setRoot (f);
chosenFiles.clear();
filenameBox.setText (String::empty);
if ((flags & doNotClearFileNameOnRootChange) == 0)
filenameBox.setText (String());
}
else
{


+ 13
- 12
source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h View File

@@ -51,18 +51,19 @@ public:
*/
enum FileChooserFlags
{
openMode = 1, /**< specifies that the component should allow the user to
choose an existing file with the intention of opening it. */
saveMode = 2, /**< specifies that the component should allow the user to specify
the name of a file that will be used to save something. */
canSelectFiles = 4, /**< specifies that the user can select files (can be used in
conjunction with canSelectDirectories). */
canSelectDirectories = 8, /**< specifies that the user can select directories (can be used in
conjuction with canSelectFiles). */
canSelectMultipleItems = 16, /**< specifies that the user can select multiple items. */
useTreeView = 32, /**< specifies that a tree-view should be shown instead of a file list. */
filenameBoxIsReadOnly = 64, /**< specifies that the user can't type directly into the filename box. */
warnAboutOverwriting = 128 /**< specifies that the dialog should warn about overwriting existing files (if possible). */
openMode = 1, /**< specifies that the component should allow the user to
choose an existing file with the intention of opening it. */
saveMode = 2, /**< specifies that the component should allow the user to specify
the name of a file that will be used to save something. */
canSelectFiles = 4, /**< specifies that the user can select files (can be used in
conjunction with canSelectDirectories). */
canSelectDirectories = 8, /**< specifies that the user can select directories (can be used in
conjuction with canSelectFiles). */
canSelectMultipleItems = 16, /**< specifies that the user can select multiple items. */
useTreeView = 32, /**< specifies that a tree-view should be shown instead of a file list. */
filenameBoxIsReadOnly = 64, /**< specifies that the user can't type directly into the filename box. */
warnAboutOverwriting = 128, /**< specifies that the dialog should warn about overwriting existing files (if possible). */
doNotClearFileNameOnRootChange = 256 /**< specifies that the file name should not be cleared upon root change. */
};
//==============================================================================


+ 1
- 31
source/modules/juce_gui_basics/layout/juce_Viewport.cpp View File

@@ -24,13 +24,13 @@
Viewport::Viewport (const String& name)
: Component (name),
customScrollBarThickness(false),
scrollBarThickness (0),
singleStepX (16),
singleStepY (16),
showHScrollbar (true),
showVScrollbar (true),
deleteContent (true),
customScrollBarThickness (false),
allowScrollingWithoutScrollbarV (false),
allowScrollingWithoutScrollbarH (false),
verticalScrollBar (true),
@@ -55,7 +55,6 @@ Viewport::Viewport (const String& name)
Viewport::~Viewport()
{
deleteContentComp();
mouseWheelTimer = nullptr;
}
//==============================================================================
@@ -382,30 +381,6 @@ static int rescaleMouseWheelDistance (float distance, int singleStepSize) noexce
: jmax (distance, 1.0f));
}
// This puts a temporary component overlay over the content component, to prevent
// wheel events from reaching components inside it, so that while spinning a wheel
// with momentum, it won't accidentally scroll any subcomponents of the viewport.
struct Viewport::MouseWheelTimer : public Timer
{
MouseWheelTimer (Viewport& v) : viewport (v)
{
viewport.contentHolder.addAndMakeVisible (dummyOverlay);
dummyOverlay.setAlwaysOnTop (true);
dummyOverlay.setPaintingIsUnclipped (true);
dummyOverlay.setBounds (viewport.contentHolder.getLocalBounds());
}
void timerCallback() override
{
viewport.mouseWheelTimer = nullptr;
}
Component dummyOverlay;
Viewport& viewport;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MouseWheelTimer)
};
bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelDetails& wheel)
{
if (! (e.mods.isAltDown() || e.mods.isCtrlDown() || e.mods.isCommandDown()))
@@ -436,11 +411,6 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelD
if (pos != getViewPosition())
{
if (mouseWheelTimer == nullptr)
mouseWheelTimer = new MouseWheelTimer (*this);
mouseWheelTimer->startTimer (300);
setViewPosition (pos);
return true;
}


+ 1
- 3
source/modules/juce_gui_basics/layout/juce_Viewport.h View File

@@ -263,15 +263,13 @@ private:
//==============================================================================
WeakReference<Component> contentComp;
Rectangle<int> lastVisibleArea;
bool customScrollBarThickness;
int scrollBarThickness;
int singleStepX, singleStepY;
bool showHScrollbar, showVScrollbar, deleteContent;
bool customScrollBarThickness;
bool allowScrollingWithoutScrollbarV, allowScrollingWithoutScrollbarH;
Component contentHolder;
ScrollBar verticalScrollBar, horizontalScrollBar;
struct MouseWheelTimer;
ScopedPointer<Timer> mouseWheelTimer;
Point<int> viewportPosToCompPos (Point<int>) const;


+ 19
- 1
source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp View File

@@ -43,7 +43,7 @@ public:
imageOffset (offset),
hasCheckedForExternalDrag (false)
{
setSize (im.getWidth(), im.getHeight());
updateSize();
if (mouseDragSource == nullptr)
mouseDragSource = sourceComponent;
@@ -160,6 +160,13 @@ public:
forceMouseCursorUpdate();
}
void updateImage (const Image& newImage)
{
image = newImage;
updateSize();
repaint();
}
void timerCallback() override
{
forceMouseCursorUpdate();
@@ -207,6 +214,11 @@ private:
bool hasCheckedForExternalDrag;
Time lastTimeOverTarget;
void updateSize()
{
setSize (image.getWidth(), image.getHeight());
}
void forceMouseCursorUpdate()
{
Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate();
@@ -472,6 +484,12 @@ var DragAndDropContainer::getCurrentDragDescription() const
: var();
}
void DragAndDropContainer::setCurrentDragImage (const Image& newImage)
{
if (dragImageComponent != nullptr)
dragImageComponent->updateImage (newImage);
}
DragAndDropContainer* DragAndDropContainer::findParentDragContainerFor (Component* c)
{
return c != nullptr ? c->findParentComponentOfClass<DragAndDropContainer>() : nullptr;


+ 3
- 0
source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h View File

@@ -102,6 +102,9 @@ public:
*/
var getCurrentDragDescription() const;
/** If a drag is in progress, this allows the image being shown to be dynamically updated. */
void setCurrentDragImage (const Image& newImage);
/** Utility to find the DragAndDropContainer for a given Component.
This will search up this component's parent hierarchy looking for the first


+ 4
- 0
source/modules/juce_gui_basics/mouse/juce_MouseEvent.h View File

@@ -354,6 +354,10 @@ struct MouseWheelDetails
/** If true, then the wheel has continuous, un-stepped motion. */
bool isSmooth;
/** If true, then this event is part of the intertial momentum phase that follows
the wheel being released. */
bool isInertial;
};


+ 12
- 4
source/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp View File

@@ -331,10 +331,17 @@ public:
Time time, const MouseWheelDetails& wheel)
{
Desktop::getInstance().incrementMouseWheelCounter();
Point<float> screenPos;
if (Component* current = getTargetForGesture (peer, positionWithinPeer, time, screenPos))
sendMouseWheel (*current, screenPos, time, wheel);
// This will make sure that when the wheel spins in its inertial phase, any events
// continue to be sent to the last component that the mouse was over when it was being
// actively controlled by the user. This avoids confusion when scrolling through nested
// scrollable components.
if (lastNonInertialWheelTarget == nullptr || ! wheel.isInertial)
lastNonInertialWheelTarget = getTargetForGesture (peer, positionWithinPeer, time, screenPos);
if (Component* target = lastNonInertialWheelTarget)
sendMouseWheel (*target, screenPos, time, wheel);
}
void handleMagnifyGesture (ComponentPeer& peer, Point<float> positionWithinPeer,
@@ -467,7 +474,7 @@ public:
bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen;
private:
WeakReference<Component> componentUnderMouse;
WeakReference<Component> componentUnderMouse, lastNonInertialWheelTarget;
ComponentPeer* lastPeer;
void* currentCursorHandle;
@@ -512,6 +519,7 @@ private:
mouseDowns[0].peerID = 0;
mouseMovedSignificantlySincePressed = false;
lastNonInertialWheelTarget = nullptr;
}
void registerMouseDrag (Point<float> screenPos) noexcept


+ 23
- 11
source/modules/juce_gui_basics/native/juce_android_Windowing.cpp View File

@@ -112,7 +112,8 @@ public:
: ComponentPeer (comp, windowStyleFlags),
usingAndroidGraphics (false),
fullScreen (false),
sizeAllocated (0)
sizeAllocated (0),
scale ((float) Desktop::getInstance().getDisplays().getMainDisplay().scale)
{
// NB: must not put this in the initialiser list, as it invokes a callback,
// which will fail if the peer is only half-constructed.
@@ -189,8 +190,10 @@ public:
view.callVoidMethod (ComponentPeerView.setViewName, javaString (title).get());
}
void setBounds (const Rectangle<int>& r, bool isNowFullScreen) override
void setBounds (const Rectangle<int>& userRect, bool isNowFullScreen) override
{
Rectangle<int> r = userRect * scale;
if (MessageManager::getInstance()->isThisTheMessageThread())
{
fullScreen = isNowFullScreen;
@@ -224,7 +227,7 @@ public:
return Rectangle<int> (view.callIntMethod (ComponentPeerView.getLeft),
view.callIntMethod (ComponentPeerView.getTop),
view.callIntMethod (ComponentPeerView.getWidth),
view.callIntMethod (ComponentPeerView.getHeight));
view.callIntMethod (ComponentPeerView.getHeight)) / scale;
}
void handleScreenSizeChange()
@@ -238,7 +241,7 @@ public:
Point<int> getScreenPosition() const
{
return Point<int> (view.callIntMethod (ComponentPeerView.getLeft),
view.callIntMethod (ComponentPeerView.getTop));
view.callIntMethod (ComponentPeerView.getTop)) / scale;
}
Point<float> localToGlobal (Point<float> relativePosition) override
@@ -291,7 +294,8 @@ public:
return isPositiveAndBelow (localPos.x, component.getWidth())
&& isPositiveAndBelow (localPos.y, component.getHeight())
&& ((! trueIfInAChildWindow) || view.callBooleanMethod (ComponentPeerView.containsPoint,
localPos.x, localPos.y));
localPos.x * scale,
localPos.y * scale));
}
BorderSize<int> getFrameSize() const override
@@ -322,19 +326,21 @@ public:
}
//==============================================================================
void handleMouseDownCallback (int index, Point<float> pos, int64 time)
void handleMouseDownCallback (int index, Point<float> sysPos, int64 time)
{
Point<float> pos = sysPos / scale;
lastMousePos = pos;
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), time);
if (isValidPeer (this))
handleMouseDragCallback (index, pos, time);
handleMouseDragCallback (index, sysPos, time);
}
void handleMouseDragCallback (int index, Point<float> pos, int64 time)
{
pos /= scale;
lastMousePos = pos;
jassert (index < 64);
@@ -346,6 +352,7 @@ public:
void handleMouseUpCallback (int index, Point<float> pos, int64 time)
{
pos /= scale;
lastMousePos = pos;
jassert (index < 64);
@@ -441,6 +448,7 @@ public:
{
LowLevelGraphicsSoftwareRenderer g (temp);
g.setOrigin (-clip.getPosition());
g.addTransform (AffineTransform::scale (scale));
handlePaint (g);
}
}
@@ -453,8 +461,10 @@ public:
}
}
void repaint (const Rectangle<int>& area) override
void repaint (const Rectangle<int>& userArea) override
{
Rectangle<int> area = userArea * scale;
if (MessageManager::getInstance()->isThisTheMessageThread())
{
view.callVoidMethod (ComponentPeerView.invalidate, area.getX(), area.getY(), area.getRight(), area.getBottom());
@@ -507,6 +517,7 @@ private:
GlobalRef buffer;
bool usingAndroidGraphics, fullScreen;
int sizeAllocated;
float scale;
class PreallocatedImage : public ImagePixelData
{
@@ -723,11 +734,12 @@ bool juce_areThereAnyAlwaysOnTopWindows()
void Desktop::Displays::findDisplays (float masterScale)
{
Display d;
d.userArea = d.totalArea = Rectangle<int> (android.screenWidth,
android.screenHeight) / masterScale;
d.isMain = true;
d.scale = masterScale;
d.dpi = android.dpi;
d.scale = masterScale * (d.dpi / 150.);
d.userArea = d.totalArea = Rectangle<int> (android.screenWidth,
android.screenHeight) / d.scale;
displays.add (d);
}


+ 4
- 4
source/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp View File

@@ -131,11 +131,11 @@ static void addZenityArgs (StringArray& args, String& separator,
if (filters.isNotEmpty() && filters != "*" && filters != "*.*")
{
args.add ("--file-filter");
args.add (filters.replaceCharacter (';', ' '));
StringArray tokens;
tokens.addTokens (filters, ";,|", "\"");
args.add ("--file-filter");
args.add ("All files | *");
for (int i = 0; i < tokens.size(); ++i)
args.add ("--file-filter='" + tokens[i] + "'");
}
if (file.isDirectory())


+ 41
- 7
source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp View File

@@ -978,9 +978,9 @@ private:
//==============================================================================
#if JUCE_USE_XRANDR
friend class ContainerDeletePolicy<XRRScreenResources>;
friend class ContainerDeletePolicy<XRROutputInfo>;
friend class ContainerDeletePolicy<XRRCrtcInfo>;
friend struct ContainerDeletePolicy<XRRScreenResources>;
friend struct ContainerDeletePolicy<XRROutputInfo>;
friend struct ContainerDeletePolicy<XRRCrtcInfo>;
class XRandrWrapper
{
@@ -1062,9 +1062,9 @@ private:
private:
//==============================================================================
friend class ContainerDeletePolicy<XRRScreenResources>;
friend class ContainerDeletePolicy<XRROutputInfo>;
friend class ContainerDeletePolicy<XRRCrtcInfo>;
friend struct ContainerDeletePolicy<XRRScreenResources>;
friend struct ContainerDeletePolicy<XRROutputInfo>;
friend struct ContainerDeletePolicy<XRRCrtcInfo>;
void freeScreenResources (XRRScreenResources* ptr)
{
@@ -2209,6 +2209,7 @@ public:
wheel.deltaY = amount;
wheel.isReversed = false;
wheel.isSmooth = false;
wheel.isInertial = false;
handleMouseWheel (0, getMousePos (buttonPressEvent), getEventTime (buttonPressEvent), wheel);
}
@@ -3723,12 +3724,45 @@ void Desktop::Displays::findDisplays (float masterScale)
{
DisplayGeometry& geometry = DisplayGeometry::getOrCreateInstance (display, masterScale);
// add the main display first
int mainDisplayIdx;
for (mainDisplayIdx = 0; mainDisplayIdx < geometry.infos.size(); ++mainDisplayIdx)
{
const DisplayGeometry::ExtendedInfo& info = geometry.infos.getReference (mainDisplayIdx);
if (info.isMain)
break;
}
// no main display found then use the first
if (mainDisplayIdx >= geometry.infos.size())
mainDisplayIdx = 0;
// add the main display
{
const DisplayGeometry::ExtendedInfo& info =
geometry.infos.getReference (mainDisplayIdx);
Desktop::Displays::Display d;
d.isMain = true;
d.scale = masterScale * info.scale;
d.dpi = info.dpi;
d.totalArea = DisplayGeometry::physicalToScaled (info.totalBounds);
d.userArea = (info.usableBounds / d.scale) + info.topLeftScaled;
displays.add (d);
}
for (int i = 0; i < geometry.infos.size(); ++i)
{
// don't add the main display a second time
if (i == mainDisplayIdx)
continue;
const DisplayGeometry::ExtendedInfo& info = geometry.infos.getReference (i);
Desktop::Displays::Display d;
d.isMain = info.isMain;
d.isMain = false;
d.scale = masterScale * info.scale;
d.dpi = info.dpi;


+ 56
- 23
source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm View File

@@ -50,34 +50,62 @@ namespace MouseCursorHelpers
}
}
static void* fromWebKitFile (const char* filename, float hx, float hy)
static NSCursor* fromNSImage (NSImage* im, NSPoint hotspot)
{
FileInputStream fileStream (File ("/System/Library/Frameworks/WebKit.framework/Frameworks/WebCore.framework/Resources")
.getChildFile (filename));
NSCursor* c = [[NSCursor alloc] initWithImage: im
hotSpot: hotspot];
[im release];
return c;
}
if (fileStream.openedOk())
static void* fromHIServices (const char* filename)
{
JUCE_AUTORELEASEPOOL
{
BufferedInputStream buf (fileStream, 4096);
const String cursorPath (String ("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/"
"HIServices.framework/Versions/A/Resources/cursors/")
+ filename);
PNGImageFormat pngFormat;
Image im (pngFormat.decodeImage (buf));
NSImage* originalImage = [[NSImage alloc] initByReferencingFile: juceStringToNS (cursorPath + "/cursor.pdf")];
NSSize originalSize = [originalImage size];
NSImage* resultImage = [[NSImage alloc] initWithSize: originalSize];
if (im.isValid())
return CustomMouseCursorInfo (im, (int) (hx * im.getWidth()),
(int) (hy * im.getHeight())).create();
}
for (int scale = 1; scale <= 4; ++scale)
{
NSAffineTransform* scaleTransform = [NSAffineTransform transform];
[scaleTransform scaleBy: (float) scale];
if (CGImageRef rasterCGImage = [originalImage CGImageForProposedRect: nil
context: nil
hints: [NSDictionary dictionaryWithObjectsAndKeys:
NSImageHintCTM, scaleTransform, nil]])
{
NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithCGImage: rasterCGImage];
[imageRep setSize: originalSize];
[resultImage addRepresentation: imageRep];
[imageRep release];
}
else
{
return nil;
}
}
return nullptr;
NSDictionary* info = [NSDictionary dictionaryWithContentsOfFile: juceStringToNS (cursorPath + "/info.plist")];
const float hotspotX = (float) [[info valueForKey: nsStringLiteral ("hotx")] doubleValue];
const float hotspotY = (float) [[info valueForKey: nsStringLiteral ("hoty")] doubleValue];
return fromNSImage (resultImage, NSMakePoint (hotspotX, hotspotY));
}
}
}
void* CustomMouseCursorInfo::create() const
{
NSImage* im = MouseCursorHelpers::createNSImage (image);
NSCursor* c = [[NSCursor alloc] initWithImage: im
hotSpot: NSMakePoint (hotspot.x, hotspot.y)];
[im release];
return c;
return MouseCursorHelpers::fromNSImage (MouseCursorHelpers::createNSImage (image),
NSMakePoint (hotspot.x, hotspot.y));
}
void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType type)
@@ -102,9 +130,10 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
case CopyingCursor:
{
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
if (void* m = MouseCursorHelpers::fromWebKitFile ("copyCursor.png", 0, 0))
if (void* m = MouseCursorHelpers::fromHIServices ("copy"))
return m;
#endif
c = [NSCursor dragCopyCursor]; // added in 10.6
break;
}
@@ -112,10 +141,14 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
case UpDownResizeCursor:
case TopEdgeResizeCursor:
case BottomEdgeResizeCursor:
return MouseCursorHelpers::fromWebKitFile ("northSouthResizeCursor.png", 0.5f, 0.5f);
if (void* m = MouseCursorHelpers::fromHIServices ("resizenorthsouth"))
return m;
c = [NSCursor resizeUpDownCursor];
break;
case LeftRightResizeCursor:
if (void* m = MouseCursorHelpers::fromWebKitFile ("eastWestResizeCursor.png", 0.5f, 0.5f))
if (void* m = MouseCursorHelpers::fromHIServices ("resizeeastwest"))
return m;
c = [NSCursor resizeLeftRightCursor];
@@ -123,14 +156,14 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
case TopLeftCornerResizeCursor:
case BottomRightCornerResizeCursor:
return MouseCursorHelpers::fromWebKitFile ("northWestSouthEastResizeCursor.png", 0.5f, 0.5f);
return MouseCursorHelpers::fromHIServices ("resizenorthwestsoutheast");
case TopRightCornerResizeCursor:
case BottomLeftCornerResizeCursor:
return MouseCursorHelpers::fromWebKitFile ("northEastSouthWestResizeCursor.png", 0.5f, 0.5f);
return MouseCursorHelpers::fromHIServices ("resizenortheastsouthwest");
case UpDownLeftRightResizeCursor:
return MouseCursorHelpers::fromWebKitFile ("moveCursor.png", 0.5f, 0.5f);
return MouseCursorHelpers::fromHIServices ("move");
default:
jassertfalse;


+ 8
- 4
source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm View File

@@ -497,10 +497,7 @@ public:
void toBehind (ComponentPeer* other) override
{
NSViewComponentPeer* const otherPeer = dynamic_cast<NSViewComponentPeer*> (other);
jassert (otherPeer != nullptr); // wrong type of window?
if (otherPeer != nullptr)
if (NSViewComponentPeer* const otherPeer = dynamic_cast<NSViewComponentPeer*> (other))
{
if (isSharedWindow)
{
@@ -514,6 +511,10 @@ public:
relativeTo: [otherPeer->window windowNumber]];
}
}
else
{
jassertfalse; // wrong type of window?
}
}
void setIcon (const Image&) override
@@ -620,6 +621,7 @@ public:
wheel.deltaY = 0;
wheel.isReversed = false;
wheel.isSmooth = false;
wheel.isInertial = false;
#if ! JUCE_PPC
@try
@@ -628,6 +630,8 @@ public:
if ([ev respondsToSelector: @selector (isDirectionInvertedFromDevice)])
wheel.isReversed = [ev isDirectionInvertedFromDevice];
wheel.isInertial = ([ev momentumPhase] != NSEventPhaseNone);
if ([ev respondsToSelector: @selector (hasPreciseScrollingDeltas)])
{
if ([ev hasPreciseScrollingDeltas])


+ 7
- 1
source/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp View File

@@ -218,6 +218,8 @@ void FileChooser::showPlatformDialog (Array<File>& results, const String& title_
info.customComponent->enterModalState();
}
const StringRef separatorTokens (";,|");
const size_t filterSpaceNumChars = 2048;
HeapBlock<WCHAR> filters;
filters.calloc (filterSpaceNumChars);
@@ -225,6 +227,10 @@ void FileChooser::showPlatformDialog (Array<File>& results, const String& title_
filter.copyToUTF16 (filters + (bytesWritten / sizeof (WCHAR)),
((filterSpaceNumChars - 1) * sizeof (WCHAR) - bytesWritten));
for (int i = 0; i < filterSpaceNumChars; ++i)
if (separatorTokens.text.indexOf ((juce_wchar) filters[i]) >= 0)
filters[i] = 0;
OPENFILENAMEW of = { 0 };
String localPath (info.initialPath);
@@ -249,7 +255,7 @@ void FileChooser::showPlatformDialog (Array<File>& results, const String& title_
if (isSaveDialogue)
{
StringArray tokens;
tokens.addTokens (filter, ";,", "\"'");
tokens.addTokens (filter, separatorTokens, "\"'");
tokens.trim();
tokens.removeEmptyStrings();


+ 22
- 18
source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp View File

@@ -1820,6 +1820,7 @@ private:
wheel.deltaY = isVertical ? amount / 256.0f : 0.0f;
wheel.isReversed = false;
wheel.isSmooth = false;
wheel.isInertial = false;
Point<float> localPos;
if (ComponentPeer* const peer = findPeerUnderMouse (localPos))
@@ -2968,24 +2969,27 @@ bool KeyPress::isKeyCurrentlyDown (const int keyCode)
{
SHORT k = (SHORT) keyCode;
if ((keyCode & extendedKeyModifier) == 0
&& (k >= (SHORT) 'a' && k <= (SHORT) 'z'))
k += (SHORT) 'A' - (SHORT) 'a';
const SHORT translatedValues[] = { (SHORT) ',', VK_OEM_COMMA,
(SHORT) '+', VK_OEM_PLUS,
(SHORT) '-', VK_OEM_MINUS,
(SHORT) '.', VK_OEM_PERIOD,
(SHORT) ';', VK_OEM_1,
(SHORT) ':', VK_OEM_1,
(SHORT) '/', VK_OEM_2,
(SHORT) '?', VK_OEM_2,
(SHORT) '[', VK_OEM_4,
(SHORT) ']', VK_OEM_6 };
for (int i = 0; i < numElementsInArray (translatedValues); i += 2)
if (k == translatedValues [i])
k = translatedValues [i + 1];
if ((keyCode & extendedKeyModifier) == 0)
{
if (k >= (SHORT) 'a' && k <= (SHORT) 'z')
k += (SHORT) 'A' - (SHORT) 'a';
// Only translate if extendedKeyModifier flag is not set
const SHORT translatedValues[] = { (SHORT) ',', VK_OEM_COMMA,
(SHORT) '+', VK_OEM_PLUS,
(SHORT) '-', VK_OEM_MINUS,
(SHORT) '.', VK_OEM_PERIOD,
(SHORT) ';', VK_OEM_1,
(SHORT) ':', VK_OEM_1,
(SHORT) '/', VK_OEM_2,
(SHORT) '?', VK_OEM_2,
(SHORT) '[', VK_OEM_4,
(SHORT) ']', VK_OEM_6 };
for (int i = 0; i < numElementsInArray (translatedValues); i += 2)
if (k == translatedValues [i])
k = translatedValues [i + 1];
}
return HWNDComponentPeer::isKeyDown (k);
}


+ 31
- 21
source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp View File

@@ -32,13 +32,10 @@ class AllComponentRepainter : private Timer,
private DeletedAtShutdown
{
public:
AllComponentRepainter() {}
AllComponentRepainter() {}
~AllComponentRepainter() { clearSingletonInstance(); }
static AllComponentRepainter& getInstance()
{
static AllComponentRepainter* instance = new AllComponentRepainter();
return *instance;
}
juce_DeclareSingleton (AllComponentRepainter, false)
void trigger()
{
@@ -51,26 +48,45 @@ private:
{
stopTimer();
Array<Component*> alreadyDone;
for (int i = TopLevelWindow::getNumTopLevelWindows(); --i >= 0;)
if (Component* c = TopLevelWindow::getTopLevelWindow(i))
repaintAndResizeAllComps (c);
repaintAndResizeAllComps (c, alreadyDone);
Desktop& desktop = Desktop::getInstance();
for (int i = desktop.getNumComponents(); --i >= 0;)
if (Component* c = desktop.getComponent(i))
repaintAndResizeAllComps (c, alreadyDone);
}
static void repaintAndResizeAllComps (Component::SafePointer<Component> c)
static void repaintAndResizeAllComps (Component::SafePointer<Component> c,
Array<Component*>& alreadyDone)
{
if (c->isVisible())
if (c->isVisible() && ! alreadyDone.contains (c))
{
c->repaint();
c->resized();
for (int i = c->getNumChildComponents(); --i >= 0;)
if (c != nullptr)
if (Component* child = c->getChildComponent(i))
repaintAndResizeAllComps (child);
{
if (Component* child = c->getChildComponent(i))
{
repaintAndResizeAllComps (child, alreadyDone);
alreadyDone.add (child);
}
if (c == nullptr)
break;
}
}
}
};
juce_ImplementSingleton (AllComponentRepainter)
juce_ImplementSingleton (ValueList)
//==============================================================================
int64 parseInt (String s)
{
@@ -175,7 +191,7 @@ void LivePropertyEditorBase::applyNewValue (const String& s)
selectOriginalValue();
valueEditor.setText (s, dontSendNotification);
AllComponentRepainter::getInstance().trigger();
AllComponentRepainter::getInstance()->trigger();
}
void LivePropertyEditorBase::selectOriginalValue()
@@ -333,14 +349,8 @@ public:
};
//==============================================================================
ValueList::ValueList() {}
ValueList::~ValueList() {}
ValueList& ValueList::getInstance()
{
static ValueList* i = new ValueList();
return *i;
}
ValueList::ValueList() {}
ValueList::~ValueList() { clearSingletonInstance(); }
void ValueList::addValue (LiveValueBase* v)
{


+ 2
- 2
source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h View File

@@ -194,7 +194,7 @@ namespace LiveConstantEditor
ValueList();
~ValueList();
static ValueList& getInstance();
juce_DeclareSingleton (ValueList, false)
template <typename Type>
LiveValue<Type>& getValue (const char* file, int line, const Type& initialValue)
@@ -233,7 +233,7 @@ namespace LiveConstantEditor
template <typename Type>
inline LiveValue<Type>& getValue (const char* file, int line, const Type& initialValue)
{
return ValueList::getInstance().getValue (file, line, initialValue);
return ValueList::getInstance()->getValue (file, line, initialValue);
}
inline LiveValue<String>& getValue (const char* file, int line, const char* initialValue)


Loading…
Cancel
Save