Browse Source

Update juce

tags/1.9.4
falkTX 10 years ago
parent
commit
4f51f7a633
57 changed files with 559 additions and 364 deletions
  1. +12
    -12
      source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp
  2. +2
    -2
      source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp
  3. +4
    -4
      source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp
  4. +11
    -6
      source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp
  5. +3
    -0
      source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h
  6. +2
    -2
      source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp
  7. +4
    -0
      source/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp
  8. +1
    -1
      source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp
  9. +15
    -9
      source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm
  10. +13
    -16
      source/modules/juce_audio_processors/juce_audio_processors.cpp
  11. +3
    -3
      source/modules/juce_audio_processors/processors/juce_AudioProcessor.h
  12. +0
    -1
      source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
  13. +1
    -1
      source/modules/juce_core/containers/juce_ReferenceCountedArray.h
  14. +4
    -4
      source/modules/juce_core/javascript/juce_Javascript.cpp
  15. +20
    -33
      source/modules/juce_core/maths/juce_BigInteger.cpp
  16. +17
    -0
      source/modules/juce_core/maths/juce_MathsFunctions.h
  17. +6
    -0
      source/modules/juce_core/native/juce_android_JNIHelpers.h
  18. +25
    -14
      source/modules/juce_core/native/juce_posix_SharedCode.h
  19. +1
    -2
      source/modules/juce_core/native/juce_win32_ComSmartPtr.h
  20. +12
    -1
      source/modules/juce_core/native/juce_win32_Network.cpp
  21. +15
    -1
      source/modules/juce_core/native/juce_win32_SystemStats.cpp
  22. +1
    -1
      source/modules/juce_core/network/juce_Socket.cpp
  23. +2
    -2
      source/modules/juce_core/streams/juce_MemoryInputStream.cpp
  24. +1
    -1
      source/modules/juce_core/streams/juce_MemoryOutputStream.h
  25. +1
    -1
      source/modules/juce_core/system/juce_StandardHeader.h
  26. +1
    -1
      source/modules/juce_core/system/juce_SystemStats.cpp
  27. +1
    -1
      source/modules/juce_core/text/juce_String.cpp
  28. +1
    -1
      source/modules/juce_core/text/juce_String.h
  29. +5
    -5
      source/modules/juce_core/zip/juce_ZipFile.cpp
  30. +2
    -2
      source/modules/juce_data_structures/values/juce_Value.h
  31. +3
    -1
      source/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp
  32. +21
    -21
      source/modules/juce_events/interprocess/juce_InterprocessConnection.cpp
  33. +1
    -0
      source/modules/juce_events/interprocess/juce_InterprocessConnection.h
  34. +8
    -3
      source/modules/juce_events/messages/juce_ApplicationBase.cpp
  35. +5
    -11
      source/modules/juce_events/messages/juce_Initialisation.h
  36. +18
    -5
      source/modules/juce_events/messages/juce_MessageManager.cpp
  37. +1
    -1
      source/modules/juce_events/messages/juce_MessageManager.h
  38. +20
    -1
      source/modules/juce_gui_basics/components/juce_Component.cpp
  39. +3
    -0
      source/modules/juce_gui_basics/components/juce_Component.h
  40. +2
    -2
      source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp
  41. +1
    -1
      source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h
  42. +12
    -15
      source/modules/juce_gui_basics/layout/juce_Viewport.cpp
  43. +4
    -0
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp
  44. +1
    -0
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h
  45. +14
    -13
      source/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp
  46. +110
    -75
      source/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp
  47. +50
    -39
      source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp
  48. +29
    -17
      source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm
  49. +1
    -1
      source/modules/juce_gui_basics/native/juce_mac_Windowing.mm
  50. +3
    -2
      source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h
  51. +11
    -0
      source/modules/juce_gui_basics/widgets/juce_Label.cpp
  52. +7
    -4
      source/modules/juce_gui_basics/widgets/juce_Label.h
  53. +37
    -20
      source/modules/juce_gui_basics/widgets/juce_Slider.cpp
  54. +1
    -1
      source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp
  55. +1
    -0
      source/modules/juce_gui_basics/windows/juce_CallOutBox.h
  56. +3
    -3
      source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp
  57. +6
    -1
      source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h

+ 12
- 12
source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp View File

@@ -412,7 +412,7 @@ void JUCE_CALLTYPE FloatVectorOperations::copy (double* dest, const double* src,
void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vsmul (src, 1, &multiplier, dest, 1, num);
vDSP_vsmul (src, 1, &multiplier, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
@@ -423,7 +423,7 @@ void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (float* dest, const f
void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (double* dest, const double* src, double multiplier, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vsmulD (src, 1, &multiplier, dest, 1, num);
vDSP_vsmulD (src, 1, &multiplier, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s),
JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
@@ -446,7 +446,7 @@ void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double amount, int
void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vadd (src, 1, dest, 1, dest, 1, num);
vDSP_vadd (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
#endif
@@ -455,7 +455,7 @@ void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src, in
void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vaddD (src, 1, dest, 1, dest, 1, num);
vDSP_vaddD (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
#endif
@@ -464,7 +464,7 @@ void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src,
void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* src, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vsub (src, 1, dest, 1, dest, 1, num);
vDSP_vsub (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
#endif
@@ -473,7 +473,7 @@ void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* sr
void JUCE_CALLTYPE FloatVectorOperations::subtract (double* dest, const double* src, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vsubD (src, 1, dest, 1, dest, 1, num);
vDSP_vsubD (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
#endif
@@ -496,7 +496,7 @@ void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (double* dest, const d
void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vmul (src, 1, dest, 1, dest, 1, num);
vDSP_vmul (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
#endif
@@ -505,7 +505,7 @@ void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* sr
void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vmulD (src, 1, dest, 1, dest, 1, num);
vDSP_vmulD (src, 1, dest, 1, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
#endif
@@ -514,7 +514,7 @@ void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double*
void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, float multiplier, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vsmul (dest, 1, &multiplier, dest, 1, num);
vDSP_vsmul (dest, 1, &multiplier, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, Mode::mul (d, mult), JUCE_LOAD_DEST,
const Mode::ParallelType mult = Mode::load1 (multiplier);)
@@ -524,7 +524,7 @@ void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, float multiplie
void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, double multiplier, int num) noexcept
{
#if JUCE_USE_VDSP_FRAMEWORK
vDSP_vsmulD (dest, 1, &multiplier, dest, 1, num);
vDSP_vsmulD (dest, 1, &multiplier, dest, 1, (vDSP_Length) num);
#else
JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, Mode::mul (d, mult), JUCE_LOAD_DEST,
const Mode::ParallelType mult = Mode::load1 (multiplier);)
@@ -643,8 +643,8 @@ public:
const int range = random.nextBool() ? 500 : 10;
const int num = random.nextInt (range) + 1;
HeapBlock<ValueType> buffer1 (num + 16), buffer2 (num + 16);
HeapBlock<int> buffer3 (num + 16);
HeapBlock<ValueType> buffer1 ((size_t) num + 16), buffer2 ((size_t) num + 16);
HeapBlock<int> buffer3 ((size_t) num + 16);
#if JUCE_ARM
ValueType* const data1 = buffer1;


+ 2
- 2
source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp View File

@@ -210,7 +210,7 @@ bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, int& numBytes,
const int itemSize = MidiBufferHelpers::getEventDataSize (data);
numBytes = itemSize;
midiData = data + sizeof (int32) + sizeof (uint16);
data += sizeof (int32) + sizeof (uint16) + itemSize;
data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize;
return true;
}
@@ -223,7 +223,7 @@ bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePositio
samplePosition = MidiBufferHelpers::getEventTime (data);
const int itemSize = MidiBufferHelpers::getEventDataSize (data);
result = MidiMessage (data + sizeof (int32) + sizeof (uint16), itemSize, samplePosition);
data += sizeof (int32) + sizeof (uint16) + itemSize;
data += sizeof (int32) + sizeof (uint16) + (size_t) itemSize;
return true;
}

+ 4
- 4
source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp View File

@@ -129,7 +129,7 @@ MidiMessage::MidiMessage (const MidiMessage& other)
{
if (other.allocatedData != nullptr)
{
allocatedData.malloc (size);
allocatedData.malloc ((size_t) size);
memcpy (allocatedData, other.allocatedData, (size_t) size);
}
else
@@ -143,7 +143,7 @@ MidiMessage::MidiMessage (const MidiMessage& other, const double newTimeStamp)
{
if (other.allocatedData != nullptr)
{
allocatedData.malloc (size);
allocatedData.malloc ((size_t) size);
memcpy (allocatedData, other.allocatedData, (size_t) size);
}
else
@@ -255,7 +255,7 @@ MidiMessage& MidiMessage::operator= (const MidiMessage& other)
if (other.allocatedData != nullptr)
{
allocatedData.malloc (size);
allocatedData.malloc ((size_t) size);
memcpy (allocatedData, other.allocatedData, (size_t) size);
}
else
@@ -297,7 +297,7 @@ uint8* MidiMessage::allocateSpace (int bytes)
{
if (bytes > 4)
{
allocatedData.malloc (bytes);
allocatedData.malloc ((size_t) bytes);
return allocatedData;
}


+ 11
- 6
source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp View File

@@ -47,23 +47,28 @@ void ResamplingAudioSource::setResamplingRatio (const double samplesInPerOutputS
ratio = jmax (0.0, samplesInPerOutputSample);
}
void ResamplingAudioSource::prepareToPlay (int samplesPerBlockExpected,
double sampleRate)
void ResamplingAudioSource::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
{
const SpinLock::ScopedLockType sl (ratioLock);
input->prepareToPlay (samplesPerBlockExpected, sampleRate);
buffer.setSize (numChannels, roundToInt (samplesPerBlockExpected * ratio) + 32);
buffer.clear();
sampsInBuffer = 0;
bufferPos = 0;
subSampleOffset = 0.0;
filterStates.calloc ((size_t) numChannels);
srcBuffers.calloc ((size_t) numChannels);
destBuffers.calloc ((size_t) numChannels);
createLowPass (ratio);
flushBuffers();
}
void ResamplingAudioSource::flushBuffers()
{
buffer.clear();
bufferPos = 0;
sampsInBuffer = 0;
subSampleOffset = 0.0;
resetFilters();
}


+ 3
- 0
source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h View File

@@ -66,6 +66,9 @@ public:
*/
double getResamplingRatio() const noexcept { return ratio; }
/** Clears any buffers and filters that the resampler is using. */
void flushBuffers();
//==============================================================================
void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;
void releaseResources() override;


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

@@ -233,7 +233,7 @@ public:
size = sizeof (nameNSString);
pa.mSelector = kAudioObjectPropertyElementName;
pa.mElement = chanNum + 1;
pa.mElement = (AudioObjectPropertyElement) chanNum + 1;
if (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &nameNSString) == noErr)
{
@@ -394,7 +394,7 @@ public:
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &sr)))
sampleRate = sr;
UInt32 framesPerBuf = bufferSize;
UInt32 framesPerBuf = (UInt32) bufferSize;
size = sizeof (framesPerBuf);
pa.mSelector = kAudioDevicePropertyBufferFrameSize;
AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &framesPerBuf);


+ 4
- 0
source/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp View File

@@ -182,6 +182,10 @@ void AudioTransportSource::setNextReadPosition (int64 newPosition)
newPosition = (int64) (newPosition * sourceSampleRate / sampleRate);
positionableSource->setNextReadPosition (newPosition);
if (resamplerSource != nullptr)
resamplerSource->flushBuffers();
inputStreamEOF = false;
}
}


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

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


+ 15
- 9
source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm View File

@@ -972,16 +972,11 @@ private:
for (int i = 0; i < parameters.size(); ++i)
{
const ParamInfo& p = *parameters.getUnchecked(i);
AudioUnitParameter paramToAdd;
paramToAdd.mAudioUnit = audioUnit;
paramToAdd.mParameterID = p.paramID;
paramToAdd.mScope = kAudioUnitScope_Global;
paramToAdd.mElement = 0;
AudioUnitEvent event;
event.mArgument.mParameter = paramToAdd;
event.mArgument.mParameter.mAudioUnit = audioUnit;
event.mArgument.mParameter.mParameterID = parameters.getUnchecked(i)->paramID;
event.mArgument.mParameter.mScope = kAudioUnitScope_Global;
event.mArgument.mParameter.mElement = 0;
event.mEventType = kAudioUnitEvent_ParameterValueChange;
AUEventListenerAddEventType (eventListenerRef, nullptr, &event);
@@ -992,6 +987,16 @@ private:
event.mEventType = kAudioUnitEvent_EndParameterChangeGesture;
AUEventListenerAddEventType (eventListenerRef, nullptr, &event);
}
// Add a listener for program changes
AudioUnitEvent event;
event.mArgument.mProperty.mAudioUnit = audioUnit;
event.mArgument.mProperty.mPropertyID = kAudioUnitProperty_PresentPreset;
event.mArgument.mProperty.mScope = kAudioUnitScope_Global;
event.mArgument.mProperty.mElement = 0;
event.mEventType = kAudioUnitEvent_PropertyChange;
AUEventListenerAddEventType (eventListenerRef, nullptr, &event);
}
}
@@ -1022,6 +1027,7 @@ private:
break;
default:
sendAllParametersChangedEvents();
break;
}
}


+ 13
- 16
source/modules/juce_audio_processors/juce_audio_processors.cpp View File

@@ -112,27 +112,24 @@ struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewCompone
setView (v);
[v release];
startTimer (100);
startTimer (30);
}
void timerCallback() override
NSView* getChildView() const
{
if (NSView* parent = (NSView*) getView())
{
if ([[parent subviews] count] > 0)
{
if (NSView* child = [[parent subviews] objectAtIndex: 0])
{
NSRect f = [parent frame];
NSSize newSize = [child frame].size;
if (f.size.width != newSize.width || f.size.height != newSize.height)
{
f.size = newSize;
[parent setFrame: f];
}
}
}
return [[parent subviews] objectAtIndex: 0];
return nil;
}
void timerCallback() override
{
if (NSView* child = getChildView())
{
stopTimer();
setView (child);
}
}
};


+ 3
- 3
source/modules/juce_audio_processors/processors/juce_AudioProcessor.h View File

@@ -289,9 +289,9 @@ public:
filter will return an empty buffer, but won't block the audio thread like it would
do if you use the getCallbackLock() critical section to synchronise access.
If you're going to use this, your processBlock() method must call isSuspended() and
check whether it's suspended or not. If it is, then it should skip doing any real
processing, either emitting silence or passing the input through unchanged.
Any code that calls processBlock() should call isSuspended() before doing so, and
if the processor is suspended, it should avoid the call and emit silence or
whatever is appropriate.
@see getCallbackLock
*/


+ 0
- 1
source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h View File

@@ -396,7 +396,6 @@ private:
Array<void*> renderingOps;
friend class AudioGraphIOProcessor;
friend class CarlaPluginInstance;
AudioSampleBuffer* currentAudioInputBuffer;
AudioSampleBuffer currentAudioOutputBuffer;
MidiBuffer* currentMidiInputBuffer;


+ 1
- 1
source/modules/juce_core/containers/juce_ReferenceCountedArray.h View File

@@ -72,7 +72,7 @@ public:
const ScopedLockType lock (other.getLock());
numUsed = other.size();
data.setAllocatedSize (numUsed);
memcpy (data.elements, other.getRawDataPointer(), numUsed * sizeof (ObjectClass*));
memcpy (data.elements, other.getRawDataPointer(), (size_t) numUsed * sizeof (ObjectClass*));
for (int i = numUsed; --i >= 0;)
if (ObjectClass* o = data.elements[i])


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

@@ -543,14 +543,14 @@ struct JavascriptEngine::RootObject : public DynamicObject
struct DivideOp : public BinaryOperator
{
DivideOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::divide) {}
var getWithDoubles (double a, double b) const override { return a / b; }
var getWithInts (int64 a, int64 b) const override { return a / b; }
var getWithDoubles (double a, double b) const override { return b != 0 ? a / b : std::numeric_limits<double>::infinity(); }
var getWithInts (int64 a, int64 b) const override { return b != 0 ? var (a / b) : var (std::numeric_limits<double>::infinity()); }
};
struct ModuloOp : public BinaryOperator
{
ModuloOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::modulo) {}
var getWithInts (int64 a, int64 b) const override { return a % b; }
var getWithInts (int64 a, int64 b) const override { return b != 0 ? var (a % b) : var (std::numeric_limits<double>::infinity()); }
};
struct BitwiseOrOp : public BinaryOperator
@@ -843,7 +843,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
String::CharPointerType end (p);
while (isIdentifierBody (*++end)) {}
const size_t len = end - p;
const size_t len = (size_t) (end - p);
#define JUCE_JS_COMPARE_KEYWORD(name, str) if (len == sizeof (str) - 1 && matchToken (TokenTypes::name, len)) return TokenTypes::name;
JUCE_JS_KEYWORDS (JUCE_JS_COMPARE_KEYWORD)


+ 20
- 33
source/modules/juce_core/maths/juce_BigInteger.cpp View File

@@ -311,37 +311,24 @@ void BigInteger::negate() noexcept
#pragma intrinsic (_BitScanReverse)
#endif
namespace BitFunctions
{
inline int countBitsInInt32 (uint32 n) noexcept
{
n -= ((n >> 1) & 0x55555555);
n = (((n >> 2) & 0x33333333) + (n & 0x33333333));
n = (((n >> 4) + n) & 0x0f0f0f0f);
n += (n >> 8);
n += (n >> 16);
return (int) (n & 0x3f);
}
inline int highestBitInInt (uint32 n) noexcept
{
jassert (n != 0); // (the built-in functions may not work for n = 0)
#if JUCE_GCC
return 31 - __builtin_clz (n);
#elif JUCE_USE_INTRINSICS
unsigned long highest;
_BitScanReverse (&highest, n);
return (int) highest;
#else
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
return countBitsInInt32 (n >> 1);
#endif
}
inline static int highestBitInInt (uint32 n) noexcept
{
jassert (n != 0); // (the built-in functions may not work for n = 0)
#if JUCE_GCC
return 31 - __builtin_clz (n);
#elif JUCE_USE_INTRINSICS
unsigned long highest;
_BitScanReverse (&highest, n);
return (int) highest;
#else
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
return countBitsInInt32 (n >> 1);
#endif
}
int BigInteger::countNumberOfSetBits() const noexcept
@@ -349,7 +336,7 @@ int BigInteger::countNumberOfSetBits() const noexcept
int total = 0;
for (int i = (int) bitToIndex (highestBit) + 1; --i >= 0;)
total += BitFunctions::countBitsInInt32 (values[i]);
total += countNumberOfBits (values[i]);
return total;
}
@@ -361,7 +348,7 @@ int BigInteger::getHighestBit() const noexcept
const uint32 n = values[i];
if (n != 0)
return BitFunctions::highestBitInInt (n) + (i << 5);
return highestBitInInt (n) + (i << 5);
}
return -1;


+ 17
- 0
source/modules/juce_core/maths/juce_MathsFunctions.h View File

@@ -443,6 +443,23 @@ inline int nextPowerOfTwo (int n) noexcept
return n + 1;
}
/** Returns the number of bits in a 32-bit integer. */
inline int countNumberOfBits (uint32 n) noexcept
{
n -= ((n >> 1) & 0x55555555);
n = (((n >> 2) & 0x33333333) + (n & 0x33333333));
n = (((n >> 4) + n) & 0x0f0f0f0f);
n += (n >> 8);
n += (n >> 16);
return (int) (n & 0x3f);
}
/** Returns the number of bits in a 64-bit integer. */
inline int countNumberOfBits (uint64 n) noexcept
{
return countNumberOfBits ((uint32) n) + countNumberOfBits ((uint32) (n >> 32));
}
/** Performs a modulo operation, but can cope with the dividend being negative.
The divisor must be greater than zero.
*/


+ 6
- 0
source/modules/juce_core/native/juce_android_JNIHelpers.h View File

@@ -362,6 +362,12 @@ private:
extern ThreadLocalJNIEnvHolder threadLocalJNIEnvHolder;
struct AndroidThreadScope
{
AndroidThreadScope() { threadLocalJNIEnvHolder.attach(); }
~AndroidThreadScope() { threadLocalJNIEnvHolder.detach(); }
};
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (createNewView, "createNewView", "(ZJ)L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView;") \


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

@@ -849,12 +849,6 @@ extern "C" void* threadEntryProc (void* userData)
JUCE_AUTORELEASEPOOL
{
#if JUCE_ANDROID
struct AndroidThreadScope
{
AndroidThreadScope() { threadLocalJNIEnvHolder.attach(); }
~AndroidThreadScope() { threadLocalJNIEnvHolder.detach(); }
};
const AndroidThreadScope androidEnv;
#endif
@@ -1169,15 +1163,23 @@ struct HighResolutionTimer::Pimpl
{
if (periodMs != newPeriod)
{
stop();
periodMs = newPeriod;
if (thread != pthread_self())
{
stop();
shouldStop = false;
periodMs = newPeriod;
shouldStop = false;
if (pthread_create (&thread, nullptr, timerThread, this) == 0)
setThreadToRealtime (thread, (uint64) newPeriod);
if (pthread_create (&thread, nullptr, timerThread, this) == 0)
setThreadToRealtime (thread, (uint64) newPeriod);
else
jassertfalse;
}
else
jassertfalse;
{
periodMs = newPeriod;
shouldStop = false;
}
}
}
@@ -1201,7 +1203,9 @@ private:
static void* timerThread (void* param)
{
#if ! JUCE_ANDROID
#if JUCE_ANDROID
const AndroidThreadScope androidEnv;
#else
int dummy;
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &dummy);
#endif
@@ -1212,12 +1216,19 @@ private:
void timerThread()
{
Clock clock (periodMs);
int lastPeriod = periodMs;
Clock clock (lastPeriod);
while (! shouldStop)
{
clock.wait();
owner.hiResTimerCallback();
if (lastPeriod != periodMs)
{
lastPeriod = periodMs;
clock = Clock (lastPeriod);
}
}
periodMs = 0;


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

@@ -29,8 +29,7 @@
#ifndef JUCE_WIN32_COMSMARTPTR_H_INCLUDED
#define JUCE_WIN32_COMSMARTPTR_H_INCLUDED
// FIXME
#if 1 //! (defined (_MSC_VER) || defined (__uuidof))
#if ! (defined (_MSC_VER) || defined (__uuidof))
template<typename Type> struct UUIDGetter { static CLSID get() { jassertfalse; return CLSID(); } };
#define __uuidof(x) UUIDGetter<x>::get()
#endif


+ 12
- 1
source/modules/juce_core/native/juce_win32_Network.cpp View File

@@ -259,7 +259,8 @@ private:
{
const TCHAR* mimeTypes[] = { _T("*/*"), nullptr };
DWORD flags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES;
DWORD flags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES
| INTERNET_FLAG_NO_AUTO_REDIRECT | SECURITY_SET_MASK;
if (address.startsWithIgnoreCase ("https:"))
flags |= INTERNET_FLAG_SECURE; // (this flag only seems necessary if the OS is running IE6 -
@@ -270,6 +271,8 @@ private:
if (request != 0)
{
setSecurityFlags();
INTERNET_BUFFERS buffers = { 0 };
buffers.dwStructSize = sizeof (INTERNET_BUFFERS);
buffers.lpcszHeader = headers.toWideCharPointer();
@@ -313,6 +316,14 @@ private:
close();
}
void setSecurityFlags()
{
DWORD dwFlags = 0, dwBuffLen = sizeof (DWORD);
InternetQueryOption (request, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, &dwBuffLen);
dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_SET_MASK;
InternetSetOption (request, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags));
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream)
};


+ 15
- 1
source/modules/juce_core/native/juce_win32_SystemStats.cpp View File

@@ -253,9 +253,23 @@ public:
HiResCounterHandler()
: hiResTicksOffset (0)
{
const MMRESULT res = timeBeginPeriod (1);
// This macro allows you to override the default timer-period
// used on Windows. By default this is set to 1, because that has
// always been the value used in JUCE apps, and changing it could
// affect the behaviour of existing code, but you may wish to make
// it larger (or set it to 0 to use the system default) to make your
// app less demanding on the CPU.
// For more info, see win32 documentation about the timeBeginPeriod
// function.
#ifndef JUCE_WIN32_TIMER_PERIOD
#define JUCE_WIN32_TIMER_PERIOD 1
#endif
#if JUCE_WIN32_TIMER_PERIOD > 0
const MMRESULT res = timeBeginPeriod (JUCE_WIN32_TIMER_PERIOD);
(void) res;
jassert (res == TIMERR_NOERROR);
#endif
LARGE_INTEGER f;
QueryPerformanceFrequency (&f);


+ 1
- 1
source/modules/juce_core/network/juce_Socket.cpp View File

@@ -378,7 +378,7 @@ void StreamingSocket::close()
{
// need to do this to interrupt the accept() function..
StreamingSocket temp;
temp.connect ("localhost", portNumber, 1000);
temp.connect (IPAddress::local().toString(), portNumber, 1000);
}
}


+ 2
- 2
source/modules/juce_core/streams/juce_MemoryInputStream.cpp View File

@@ -60,7 +60,7 @@ MemoryInputStream::~MemoryInputStream()
int64 MemoryInputStream::getTotalLength()
{
return dataSize;
return (int64) dataSize;
}
int MemoryInputStream::read (void* const buffer, const int howMany)
@@ -89,7 +89,7 @@ bool MemoryInputStream::setPosition (const int64 pos)
int64 MemoryInputStream::getPosition()
{
return position;
return (int64) position;
}


+ 1
- 1
source/modules/juce_core/streams/juce_MemoryOutputStream.h View File

@@ -114,7 +114,7 @@ public:
void flush();
bool write (const void*, size_t) override;
int64 getPosition() override { return position; }
int64 getPosition() override { return (int64) position; }
bool setPosition (int64) override;
int writeFromInputStream (InputStream&, int64 maxNumBytesToWrite) override;
bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) override;


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

@@ -36,7 +36,7 @@
*/
#define JUCE_MAJOR_VERSION 3
#define JUCE_MINOR_VERSION 0
#define JUCE_BUILDNUMBER 6
#define JUCE_BUILDNUMBER 7
/** Current Juce version number.


+ 1
- 1
source/modules/juce_core/system/juce_SystemStats.cpp View File

@@ -97,7 +97,7 @@ String SystemStats::getStackBacktrace()
{
String result;
#if JUCE_ANDROID || JUCE_MINGW || JUCE_HAIKU || JUCE_MAC
#if JUCE_ANDROID || JUCE_MINGW || JUCE_HAIKU
jassertfalse; // sorry, not implemented yet!
#elif JUCE_WINDOWS


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

@@ -558,7 +558,7 @@ struct HashGenerator
Type result = Type();
while (! t.isEmpty())
result = multiplier * result + t.getAndAdvance();
result = ((Type) multiplier) * result + (Type) t.getAndAdvance();
return result;
}


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

@@ -167,7 +167,7 @@ public:
typedef CharPointer_UTF32 CharPointerType;
#elif (JUCE_STRING_UTF_TYPE == 16)
typedef CharPointer_UTF16 CharPointerType;
#elif (JUCE_STRING_UTF_TYPE == 8)
#elif (DOXYGEN || JUCE_STRING_UTF_TYPE == 8)
typedef CharPointer_UTF8 CharPointerType;
#else
#error "You must set the value of JUCE_STRING_UTF_TYPE to be either 8, 16, or 32!"


+ 5
- 5
source/modules/juce_core/zip/juce_ZipFile.cpp View File

@@ -135,7 +135,7 @@ public:
char buffer [30];
if (inputStream != nullptr
&& inputStream->setPosition (zei.streamOffset)
&& inputStream->setPosition ((int64) zei.streamOffset)
&& inputStream->read (buffer, 30) == 30
&& ByteOrder::littleEndianInt (buffer) == 0x04034b50)
{
@@ -154,7 +154,7 @@ public:
int64 getTotalLength()
{
return zipEntryHolder.compressedSize;
return (int64) zipEntryHolder.compressedSize;
}
int read (void* buffer, int howMany)
@@ -162,7 +162,7 @@ public:
if (headerSize <= 0)
return 0;
howMany = (int) jmin ((int64) howMany, (int64) (zipEntryHolder.compressedSize - pos));
howMany = (int) jmin ((int64) howMany, ((int64) zipEntryHolder.compressedSize) - pos);
if (inputStream == nullptr)
return 0;
@@ -172,12 +172,12 @@ public:
if (inputStream == file.inputStream)
{
const ScopedLock sl (file.lock);
inputStream->setPosition (pos + zipEntryHolder.streamOffset + headerSize);
inputStream->setPosition (pos + (int64) zipEntryHolder.streamOffset + headerSize);
num = inputStream->read (buffer, howMany);
}
else
{
inputStream->setPosition (pos + zipEntryHolder.streamOffset + headerSize);
inputStream->setPosition (pos + (int64) zipEntryHolder.streamOffset + headerSize);
num = inputStream->read (buffer, howMany);
}


+ 2
- 2
source/modules/juce_data_structures/values/juce_Value.h View File

@@ -147,9 +147,9 @@ public:
The listener is added to this specific Value object, and not to the shared
object that it refers to. When this object is deleted, all the listeners will
be lost, even if other references to the same Value still exist. So when you're
adding a listener, make sure that you add it to a ValueTree instance that will last
adding a listener, make sure that you add it to a Value instance that will last
for as long as you need the listener. In general, you'd never want to add a listener
to a local stack-based ValueTree, but more likely to one that's a member variable.
to a local stack-based Value, but more likely to one that's a member variable.
@see removeListener
*/


+ 3
- 1
source/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp View File

@@ -61,7 +61,9 @@ AsyncUpdater::~AsyncUpdater()
void AsyncUpdater::triggerAsyncUpdate()
{
if (activeMessage->shouldDeliver.compareAndSetBool (1, 0))
activeMessage->post();
if (! activeMessage->post())
cancelPendingUpdate(); // if the message queue fails, this avoids getting
// trapped waiting for the message to arrive
}
void AsyncUpdater::cancelPendingUpdate() noexcept


+ 21
- 21
source/modules/juce_events/interprocess/juce_InterprocessConnection.cpp View File

@@ -69,11 +69,9 @@ bool InterprocessConnection::connectToSocket (const String& hostName,
thread->startThread();
return true;
}
else
{
socket = nullptr;
return false;
}
socket = nullptr;
return false;
}
bool InterprocessConnection::connectToPipe (const String& pipeName, const int timeoutMs)
@@ -143,41 +141,43 @@ bool InterprocessConnection::isConnected() const
String InterprocessConnection::getConnectedHostName() const
{
if (pipe != nullptr)
return "localhost";
if (socket != nullptr)
{
if (! socket->isLocal())
return socket->getHostName();
const ScopedLock sl (pipeAndSocketLock);
if (pipe == nullptr && socket == nullptr)
return String();
return "localhost";
if (socket != nullptr && ! socket->isLocal())
return socket->getHostName();
}
return String();
return IPAddress::local().toString();
}
//==============================================================================
bool InterprocessConnection::sendMessage (const MemoryBlock& message)
{
uint32 messageHeader[2];
messageHeader [0] = ByteOrder::swapIfBigEndian (magicMessageHeader);
messageHeader [1] = ByteOrder::swapIfBigEndian ((uint32) message.getSize());
uint32 messageHeader[2] = { ByteOrder::swapIfBigEndian (magicMessageHeader),
ByteOrder::swapIfBigEndian ((uint32) message.getSize()) };
MemoryBlock messageData (sizeof (messageHeader) + message.getSize());
messageData.copyFrom (messageHeader, 0, sizeof (messageHeader));
messageData.copyFrom (message.getData(), sizeof (messageHeader), message.getSize());
int bytesWritten = 0;
return writeData (messageData.getData(), (int) messageData.getSize()) == (int) messageData.getSize();
}
int InterprocessConnection::writeData (void* data, int dataSize)
{
const ScopedLock sl (pipeAndSocketLock);
if (socket != nullptr)
bytesWritten = socket->write (messageData.getData(), (int) messageData.getSize());
else if (pipe != nullptr)
bytesWritten = pipe->write (messageData.getData(), (int) messageData.getSize(), pipeReceiveMessageTimeout);
return socket->write (data, dataSize);
if (pipe != nullptr)
return pipe->write (data, dataSize, pipeReceiveMessageTimeout);
return bytesWritten == (int) messageData.getSize();
return 0;
}
//==============================================================================


+ 1
- 0
source/modules/juce_events/interprocess/juce_InterprocessConnection.h View File

@@ -201,6 +201,7 @@ private:
friend struct ContainerDeletePolicy<ConnectionThread>;
ScopedPointer<ConnectionThread> thread;
void runThread();
int writeData (void*, int);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InterprocessConnection)
};


+ 8
- 3
source/modules/juce_events/messages/juce_ApplicationBase.cpp View File

@@ -138,7 +138,7 @@ String JUCEApplicationBase::getCommandLineParameters() { return String(
#else
#if JUCE_WINDOWS
#if JUCE_WINDOWS && ! defined (_CONSOLE)
String JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameters()
{
@@ -171,8 +171,13 @@ StringArray JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameterArray()
extern void initialiseNSApplication();
#endif
extern const char* const* juce_argv; // declared in juce_core
extern int juce_argc;
#if JUCE_WINDOWS
const char* const* juce_argv = nullptr;
int juce_argc = 0;
#else
extern const char* const* juce_argv; // declared in juce_core
extern int juce_argc;
#endif
String JUCEApplicationBase::getCommandLineParameters()
{


+ 5
- 11
source/modules/juce_events/messages/juce_Initialisation.h View File

@@ -92,18 +92,12 @@ public:
juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); }
#else
#if JUCE_WINDOWS
#if defined (WINAPI) || defined (_WINDOWS_) || defined(JUCE_MINGW)
#define JUCE_MAIN_FUNCTION int __stdcall WinMain (HINSTANCE, HINSTANCE, const LPSTR, int)
#elif defined (_UNICODE)
#define JUCE_MAIN_FUNCTION int __stdcall WinMain (void*, void*, const wchar_t*, int)
#else
#define JUCE_MAIN_FUNCTION int __stdcall WinMain (void*, void*, const char*, int)
#endif
#define JUCE_MAIN_FUNCTION_ARGS
#if JUCE_WINDOWS && ! defined (_CONSOLE)
#define JUCE_MAIN_FUNCTION int __stdcall WinMain (struct HINSTANCE__*, struct HINSTANCE__*, char*, int)
#define JUCE_MAIN_FUNCTION_ARGS
#else
#define JUCE_MAIN_FUNCTION int main (int argc, char* argv[])
#define JUCE_MAIN_FUNCTION_ARGS argc, (const char**) argv
#define JUCE_MAIN_FUNCTION int main (int argc, char* argv[])
#define JUCE_MAIN_FUNCTION_ARGS argc, (const char**) argv
#endif
#define START_JUCE_APPLICATION(AppClass) \


+ 18
- 5
source/modules/juce_events/messages/juce_MessageManager.cpp View File

@@ -66,12 +66,17 @@ void MessageManager::deleteInstance()
}
//==============================================================================
void MessageManager::MessageBase::post()
bool MessageManager::MessageBase::post()
{
MessageManager* const mm = MessageManager::instance;
if (mm == nullptr || mm->quitMessagePosted || ! postMessageToSystemQueue (this))
{
Ptr deleter (this); // (this will delete messages that were just created with a 0 ref count)
return false;
}
return true;
}
//==============================================================================
@@ -158,9 +163,15 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* cons
jassert (! currentThreadHasLockedMessageManager());
const ReferenceCountedObjectPtr<AsyncFunctionCallback> message (new AsyncFunctionCallback (func, parameter));
message->post();
message->finished.wait();
return message->result;
if (message->post())
{
message->finished.wait();
return message->result;
}
jassertfalse; // the OS message queue failed to send the message!
return nullptr;
}
//==============================================================================
@@ -275,7 +286,9 @@ bool MessageManagerLock::attemptLock (Thread* const threadToCheck, ThreadPoolJob
}
blockingMessage = new BlockingMessage();
blockingMessage->post();
if (! blockingMessage->post())
return false;
while (! blockingMessage->lockedEvent.wait (20))
{


+ 1
- 1
source/modules/juce_events/messages/juce_MessageManager.h View File

@@ -170,7 +170,7 @@ public:
virtual ~MessageBase() {}
virtual void messageCallback() = 0;
void post();
bool post();
typedef ReferenceCountedObjectPtr<MessageBase> Ptr;


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

@@ -1182,11 +1182,25 @@ void Component::setBounds (const int x, const int y, int w, int h)
cachedImage->invalidateAll();
}
flags.isMoveCallbackPending = wasMoved;
flags.isResizeCallbackPending = wasResized;
if (flags.hasHeavyweightPeerFlag)
if (ComponentPeer* const peer = getPeer())
peer->updateBounds();
sendMovedResizedMessages (wasMoved, wasResized);
sendMovedResizedMessagesIfPending();
}
}
void Component::sendMovedResizedMessagesIfPending()
{
if (flags.isMoveCallbackPending || flags.isResizeCallbackPending)
{
sendMovedResizedMessages (flags.isMoveCallbackPending, flags.isResizeCallbackPending);
flags.isMoveCallbackPending = false;
flags.isResizeCallbackPending = false;
}
}
@@ -2047,6 +2061,11 @@ void Component::paintComponentAndChildren (Graphics& g)
void Component::paintEntireComponent (Graphics& g, const bool ignoreAlphaLevel)
{
// If sizing a top-level-window and the OS paint message is delivered synchronously
// before resized() is called, then we'll invoke the callback here, to make sure
// the components inside have had a chance to sort their sizes out..
sendMovedResizedMessagesIfPending();
#if JUCE_DEBUG
flags.isInsidePaintCall = true;
#endif


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

@@ -2306,6 +2306,8 @@ private:
bool childCompFocusedFlag : 1;
bool dontClipGraphicsFlag : 1;
bool mouseDownWasBlocked : 1;
bool isMoveCallbackPending : 1;
bool isResizeCallbackPending : 1;
#if JUCE_DEBUG
bool isInsidePaintCall : 1;
#endif
@@ -2344,6 +2346,7 @@ private:
void paintComponentAndChildren (Graphics&);
void paintWithinParentContext (Graphics&);
void sendMovedResizedMessages (bool wasMoved, bool wasResized);
void sendMovedResizedMessagesIfPending();
void repaintParent();
void sendFakeMouseMove() const;
void takeKeyboardFocus (const FocusChangeType);


+ 2
- 2
source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp View File

@@ -287,7 +287,7 @@ void TabbedButtonBar::setTabName (const int tabIndex, const String& newName)
}
}
void TabbedButtonBar::removeTab (const int tabIndex)
void TabbedButtonBar::removeTab (const int tabIndex, const bool animate)
{
const int oldIndex = currentTabIndex;
if (tabIndex == currentTabIndex)
@@ -296,7 +296,7 @@ void TabbedButtonBar::removeTab (const int tabIndex)
tabs.remove (tabIndex);
setCurrentTabIndex (oldIndex);
resized();
updateTabPositions (animate);
}
void TabbedButtonBar::moveTab (const int currentIndex, const int newIndex, const bool animate)


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

@@ -212,7 +212,7 @@ public:
void setTabName (int tabIndex, const String& newName);
/** Gets rid of one of the tabs. */
void removeTab (int tabIndex);
void removeTab (int tabIndex, bool animate = false);
/** Moves a tab to a new index in the list.
Pass -1 as the index to move it to the end of the list.


+ 12
- 15
source/modules/juce_gui_basics/layout/juce_Viewport.cpp View File

@@ -346,15 +346,15 @@ void Viewport::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& whe
Component::mouseWheelMove (e, wheel);
}
static float rescaleMouseWheelDistance (float distance, int singleStepSize) noexcept
static int rescaleMouseWheelDistance (float distance, int singleStepSize) noexcept
{
if (distance == 0)
return 0;
distance *= 14.0f * singleStepSize;
return distance < 0 ? jmin (distance, -1.0f)
: jmax (distance, 1.0f);
return roundToInt (distance < 0 ? jmin (distance, -1.0f)
: jmax (distance, 1.0f));
}
bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelDetails& wheel)
@@ -366,26 +366,23 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelD
if (canScrollHorz || canScrollVert)
{
float wheelIncrementX = rescaleMouseWheelDistance (wheel.deltaX, singleStepX);
float wheelIncrementY = rescaleMouseWheelDistance (wheel.deltaY, singleStepY);
const int deltaX = rescaleMouseWheelDistance (wheel.deltaX, singleStepX);
const int deltaY = rescaleMouseWheelDistance (wheel.deltaY, singleStepY);
Point<int> pos (getViewPosition());
if (wheelIncrementX != 0 && wheelIncrementY != 0 && canScrollHorz && canScrollVert)
if (deltaX != 0 && deltaY != 0 && canScrollHorz && canScrollVert)
{
pos.setX (pos.x - roundToInt (wheelIncrementX));
pos.setY (pos.y - roundToInt (wheelIncrementY));
pos.x -= deltaX;
pos.y -= deltaY;
}
else if (canScrollHorz && (wheelIncrementX != 0 || e.mods.isShiftDown() || ! canScrollVert))
else if (canScrollHorz && (deltaX != 0 || e.mods.isShiftDown() || ! canScrollVert))
{
if (wheelIncrementX == 0 && ! canScrollVert)
wheelIncrementX = wheelIncrementY;
pos.setX (pos.x - roundToInt (wheelIncrementX));
pos.x -= deltaX != 0 ? deltaX : deltaY;
}
else if (canScrollVert && wheelIncrementY != 0)
else if (canScrollVert && deltaY != 0)
{
pos.setY (pos.y - roundToInt (wheelIncrementY));
pos.y -= deltaY;
}
if (pos != getViewPosition())


+ 4
- 0
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp View File

@@ -2357,6 +2357,10 @@ void LookAndFeel_V2::drawCallOutBoxBackground (CallOutBox& box, Graphics& g,
g.strokePath (path, PathStrokeType (2.0f));
}
int LookAndFeel_V2::getCallOutBoxBorderSize (const CallOutBox&)
{
return 20;
}
//==============================================================================
AttributedString LookAndFeel_V2::createFileChooserHeaderText (const String& title,


+ 1
- 0
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h View File

@@ -285,6 +285,7 @@ public:
//==============================================================================
void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path& path, Image& cachedImage) override;
int getCallOutBoxBorderSize (const CallOutBox&) override;
//==============================================================================
void drawLevelMeter (Graphics&, int width, int height, float level) override;


+ 14
- 13
source/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp View File

@@ -274,7 +274,7 @@ public:
sendMouseDrag (*current, newScreenPos + unboundedMouseOffset, time);
if (isUnboundedMouseModeOn)
handleUnboundedDrag (current);
handleUnboundedDrag (*current);
}
else
{
@@ -399,7 +399,8 @@ public:
{
// when released, return the mouse to within the component's bounds
if (Component* current = getComponentUnderMouse())
setScreenPosition (current->getScreenBounds().toFloat().getConstrainedPoint (lastScreenPos));
setScreenPosition (current->getScreenBounds().toFloat()
.getConstrainedPoint (ScalingHelpers::unscaledScreenPosToScaled (lastScreenPos)));
}
isUnboundedMouseModeOn = enable;
@@ -409,21 +410,22 @@ public:
}
}
void handleUnboundedDrag (Component* current)
void handleUnboundedDrag (Component& current)
{
const Rectangle<float> screenArea (current->getParentMonitorArea().expanded (-2, -2).toFloat());
const Rectangle<float> componentScreenBounds
= ScalingHelpers::scaledScreenPosToUnscaled (current.getParentMonitorArea().reduced (2, 2).toFloat());
if (! screenArea.contains (lastScreenPos))
if (! componentScreenBounds.contains (lastScreenPos))
{
const Point<float> componentCentre (current->getScreenBounds().toFloat().getCentre());
unboundedMouseOffset += (lastScreenPos - componentCentre);
const Point<float> componentCentre (current.getScreenBounds().toFloat().getCentre());
unboundedMouseOffset += (lastScreenPos - ScalingHelpers::scaledScreenPosToUnscaled (componentCentre));
setScreenPosition (componentCentre);
}
else if (isCursorVisibleUntilOffscreen
&& (! unboundedMouseOffset.isOrigin())
&& screenArea.contains (lastScreenPos + unboundedMouseOffset))
&& componentScreenBounds.contains (lastScreenPos + unboundedMouseOffset))
{
setScreenPosition (lastScreenPos + unboundedMouseOffset);
MouseInputSource::setRawMousePosition (lastScreenPos + unboundedMouseOffset);
unboundedMouseOffset = Point<float>();
}
}
@@ -462,10 +464,9 @@ public:
//==============================================================================
const int index;
const bool isMouseDevice;
Point<float> lastScreenPos;
Point<float> lastScreenPos, unboundedMouseOffset; // NB: these are unscaled coords
ModifierKeys buttonState;
Point<float> unboundedMouseOffset;
bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen;
private:
@@ -487,8 +488,8 @@ private:
bool canBePartOfMultipleClickWith (const RecentMouseDown& other, const int maxTimeBetweenMs) const
{
return time - other.time < RelativeTime::milliseconds (maxTimeBetweenMs)
&& abs (position.x - other.position.x) < 8
&& abs (position.y - other.position.y) < 8
&& std::abs (position.x - other.position.x) < 8
&& std::abs (position.y - other.position.y) < 8
&& buttons == other.buttons
&& peerID == other.peerID;
}


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

@@ -42,99 +42,134 @@ bool FileChooser::isPlatformDialogAvailable()
#endif
}
void FileChooser::showPlatformDialog (Array<File>& results,
const String& title,
const File& file,
const String& filters,
bool isDirectory,
bool /* selectsFiles */,
bool isSave,
bool /* warnAboutOverwritingExistingFiles */,
bool selectMultipleFiles,
FilePreviewComponent* /* previewComponent */)
static uint64 getTopWindowID() noexcept
{
String separator;
StringArray args;
if (TopLevelWindow* top = TopLevelWindow::getActiveTopLevelWindow())
return (uint64) (pointer_sized_uint) top->getWindowHandle();
const File previousWorkingDirectory (File::getCurrentWorkingDirectory());
const bool isKdeFullSession = SystemStats::getEnvironmentVariable ("KDE_FULL_SESSION", String::empty)
.equalsIgnoreCase ("true");
return 0;
}
if (exeIsAvailable ("kdialog") && (isKdeFullSession || ! exeIsAvailable ("zenity")))
{
// use kdialog for KDE sessions or if zenity is missing
args.add ("kdialog");
static bool isKdeFullSession()
{
return SystemStats::getEnvironmentVariable ("KDE_FULL_SESSION", String())
.equalsIgnoreCase ("true");
}
if (title.isNotEmpty())
args.add ("--title=" + title);
static void addKDialogArgs (StringArray& args, String& separator,
const String& title, const File& file, const String& filters,
bool isDirectory, bool isSave, bool selectMultipleFiles)
{
args.add ("kdialog");
if (selectMultipleFiles)
{
separator = "\n";
args.add ("--multiple");
args.add ("--separate-output");
args.add ("--getopenfilename");
}
else
{
if (isSave) args.add ("--getsavefilename");
else if (isDirectory) args.add ("--getexistingdirectory");
else args.add ("--getopenfilename");
}
if (title.isNotEmpty())
args.add ("--title=" + title);
String startPath;
if (selectMultipleFiles)
{
separator = "\n";
args.add ("--multiple");
args.add ("--separate-output");
args.add ("--getopenfilename");
}
else
{
if (isSave) args.add ("--getsavefilename");
else if (isDirectory) args.add ("--getexistingdirectory");
else args.add ("--getopenfilename");
}
if (file.exists())
{
startPath = file.getFullPathName();
}
else if (file.getParentDirectory().exists())
{
startPath = file.getParentDirectory().getFullPathName();
}
else
{
startPath = File::getSpecialLocation (File::userHomeDirectory).getFullPathName();
if (uint64 topWindowID = getTopWindowID())
{
args.add ("--attach");
args.add (String (topWindowID));
}
if (isSave)
startPath += "/" + file.getFileName();
}
File startPath;
args.add (startPath);
args.add (filters.replaceCharacter (';', ' '));
if (file.exists())
{
startPath = file;
}
else if (file.getParentDirectory().exists())
{
startPath = file.getParentDirectory();
}
else
{
// zenity
args.add ("zenity");
args.add ("--file-selection");
startPath = File::getSpecialLocation (File::userHomeDirectory);
if (title.isNotEmpty())
args.add ("--title=" + title);
if (isSave)
startPath = startPath.getChildFile (file.getFileName());
}
if (selectMultipleFiles)
{
separator = ":";
args.add ("--multiple");
args.add ("--separator=" + separator);
}
else
{
if (isDirectory) args.add ("--directory");
if (isSave) args.add ("--save");
}
args.add (startPath.getFullPathName());
args.add (filters.replaceCharacter (';', ' '));
}
static void addZenityArgs (StringArray& args, String& separator,
const String& title, const File& file, const String& filters,
bool isDirectory, bool isSave, bool selectMultipleFiles)
{
args.add ("zenity");
args.add ("--file-selection");
if (title.isNotEmpty())
args.add ("--title=" + title);
if (file.isDirectory())
file.setAsCurrentWorkingDirectory();
else if (file.getParentDirectory().exists())
file.getParentDirectory().setAsCurrentWorkingDirectory();
else
File::getSpecialLocation (File::userHomeDirectory).setAsCurrentWorkingDirectory();
if (selectMultipleFiles)
{
separator = ":";
args.add ("--multiple");
args.add ("--separator=" + separator);
}
else
{
if (isDirectory) args.add ("--directory");
if (isSave) args.add ("--save");
}
if (filters.isNotEmpty() && filters != "*" && filters != "*.*")
{
args.add ("--file-filter");
args.add (filters.replaceCharacter (';', ' '));
if (! file.getFileName().isEmpty())
args.add ("--filename=" + file.getFileName());
args.add ("--file-filter");
args.add ("All files | *");
}
if (file.isDirectory())
file.setAsCurrentWorkingDirectory();
else if (file.getParentDirectory().exists())
file.getParentDirectory().setAsCurrentWorkingDirectory();
else
File::getSpecialLocation (File::userHomeDirectory).setAsCurrentWorkingDirectory();
if (! file.getFileName().isEmpty())
args.add ("--filename=" + file.getFileName());
// supplying the window ID of the topmost window makes sure that Zenity pops up..
if (uint64 topWindowID = getTopWindowID())
setenv ("WINDOWID", String (topWindowID).toRawUTF8(), true);
}
void FileChooser::showPlatformDialog (Array<File>& results,
const String& title, const File& file, const String& filters,
bool isDirectory, bool /* selectsFiles */,
bool isSave, bool /* warnAboutOverwritingExistingFiles */,
bool selectMultipleFiles, FilePreviewComponent*)
{
const File previousWorkingDirectory (File::getCurrentWorkingDirectory());
StringArray args;
String separator;
// use kdialog for KDE sessions or if zenity is missing
if (exeIsAvailable ("kdialog") && (isKdeFullSession() || ! exeIsAvailable ("zenity")))
addKDialogArgs (args, separator, title, file, filters, isDirectory, isSave, selectMultipleFiles);
else
addZenityArgs (args, separator, title, file, filters, isDirectory, isSave, selectMultipleFiles);
args.add ("2>/dev/null"); // (to avoid logging info ending up in the results)
ChildProcess child;


+ 50
- 39
source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp View File

@@ -33,17 +33,18 @@ struct Atoms
{
Atoms()
{
Protocols = getIfExists ("WM_PROTOCOLS");
ProtocolList [TAKE_FOCUS] = getIfExists ("WM_TAKE_FOCUS");
ProtocolList [DELETE_WINDOW] = getIfExists ("WM_DELETE_WINDOW");
ProtocolList [PING] = getIfExists ("_NET_WM_PING");
ChangeState = getIfExists ("WM_CHANGE_STATE");
State = getIfExists ("WM_STATE");
UserTime = getCreating ("_NET_WM_USER_TIME");
ActiveWin = getCreating ("_NET_ACTIVE_WINDOW");
Pid = getCreating ("_NET_WM_PID");
WindowType = getIfExists ("_NET_WM_WINDOW_TYPE");
WindowState = getIfExists ("_NET_WM_STATE");
protocols = getIfExists ("WM_PROTOCOLS");
protocolList [TAKE_FOCUS] = getIfExists ("WM_TAKE_FOCUS");
protocolList [DELETE_WINDOW] = getIfExists ("WM_DELETE_WINDOW");
protocolList [PING] = getIfExists ("_NET_WM_PING");
changeState = getIfExists ("WM_CHANGE_STATE");
state = getIfExists ("WM_STATE");
userTime = getCreating ("_NET_WM_USER_TIME");
activeWin = getCreating ("_NET_ACTIVE_WINDOW");
pid = getCreating ("_NET_WM_PID");
windowType = getIfExists ("_NET_WM_WINDOW_TYPE");
windowState = getIfExists ("_NET_WM_STATE");
compositingManager = getCreating ("_NET_WM_CM_S0");
XdndAware = getCreating ("XdndAware");
XdndEnter = getCreating ("XdndEnter");
@@ -88,8 +89,8 @@ struct Atoms
PING = 2
};
Atom Protocols, ProtocolList[3], ChangeState, State, UserTime,
ActiveWin, Pid, WindowType, WindowState,
Atom protocols, protocolList[3], changeState, state, userTime,
activeWin, pid, windowType, windowState, compositingManager,
XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus,
XdndDrop, XdndFinished, XdndSelection, XdndTypeList, XdndActionList,
XdndActionDescription, XdndActionCopy, XdndActionPrivate,
@@ -314,6 +315,11 @@ namespace XRender
return xRenderQueryVersion != nullptr;
}
static bool hasCompositingWindowManager()
{
return XGetSelectionOwner (display, Atoms::get().compositingManager) != 0;
}
static XRenderPictFormat* findPictureFormat()
{
ScopedXLock xlock;
@@ -915,7 +921,7 @@ public:
clientMsg.window = windowH;
clientMsg.type = ClientMessage;
clientMsg.format = 32;
clientMsg.message_type = Atoms::get().WindowState;
clientMsg.message_type = Atoms::get().windowState;
clientMsg.data.l[0] = 0; // Remove
clientMsg.data.l[1] = fs;
clientMsg.data.l[2] = 0;
@@ -1002,7 +1008,7 @@ public:
clientMsg.window = windowH;
clientMsg.type = ClientMessage;
clientMsg.format = 32;
clientMsg.message_type = Atoms::get().ChangeState;
clientMsg.message_type = Atoms::get().changeState;
clientMsg.data.l[0] = IconicState;
ScopedXLock xlock;
@@ -1018,10 +1024,10 @@ public:
{
ScopedXLock xlock;
const Atoms& atoms = Atoms::get();
GetXProperty prop (windowH, atoms.State, 0, 64, false, atoms.State);
GetXProperty prop (windowH, atoms.state, 0, 64, false, atoms.state);
return prop.success
&& prop.actualType == atoms.State
&& prop.actualType == atoms.state
&& prop.actualFormat == 32
&& prop.numItems > 0
&& ((unsigned long*) prop.data)[0] == IconicState;
@@ -1152,7 +1158,7 @@ public:
ev.xclient.type = ClientMessage;
ev.xclient.serial = 0;
ev.xclient.send_event = True;
ev.xclient.message_type = Atoms::get().ActiveWin;
ev.xclient.message_type = Atoms::get().activeWin;
ev.xclient.window = windowH;
ev.xclient.format = 32;
ev.xclient.data.l[0] = 2;
@@ -1178,10 +1184,7 @@ public:
void toBehind (ComponentPeer* other) override
{
LinuxComponentPeer* const otherPeer = dynamic_cast <LinuxComponentPeer*> (other);
jassert (otherPeer != nullptr); // wrong type of window?
if (otherPeer != nullptr)
if (LinuxComponentPeer* const otherPeer = dynamic_cast<LinuxComponentPeer*> (other))
{
setMinimised (false);
@@ -1190,6 +1193,8 @@ public:
ScopedXLock xlock;
XRestackWindows (display, newStack, 2);
}
else
jassertfalse; // wrong type of window?
}
bool isFocused() const override
@@ -1221,7 +1226,7 @@ public:
void repaint (const Rectangle<int>& area) override
{
repainter->repaint (area.getIntersection (component.getLocalBounds()));
repainter->repaint (area.getIntersection (bounds.withZeroOrigin()));
}
void performAnyPendingRepaintsNow() override
@@ -1699,11 +1704,11 @@ public:
{
const Atoms& atoms = Atoms::get();
if (clientMsg.message_type == atoms.Protocols && clientMsg.format == 32)
if (clientMsg.message_type == atoms.protocols && clientMsg.format == 32)
{
const Atom atom = (Atom) clientMsg.data.l[0];
if (atom == atoms.ProtocolList [Atoms::PING])
if (atom == atoms.protocolList [Atoms::PING])
{
Window root = RootWindow (display, DefaultScreen (display));
@@ -1712,7 +1717,7 @@ public:
XSendEvent (display, root, False, NoEventMask, &event);
XFlush (display);
}
else if (atom == atoms.ProtocolList [Atoms::TAKE_FOCUS])
else if (atom == atoms.protocolList [Atoms::TAKE_FOCUS])
{
if ((getStyleFlags() & juce::ComponentPeer::windowIgnoresKeyPresses) == 0)
{
@@ -1727,7 +1732,7 @@ public:
}
}
}
else if (atom == atoms.ProtocolList [Atoms::DELETE_WINDOW])
else if (atom == atoms.protocolList [Atoms::DELETE_WINDOW])
{
handleUserClosingWindow();
}
@@ -2168,7 +2173,7 @@ private:
netHints[1] = Atoms::getIfExists ("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE");
xchangeProperty (windowH, Atoms::get().WindowType, XA_ATOM, 32, &netHints, 2);
xchangeProperty (windowH, Atoms::get().windowType, XA_ATOM, 32, &netHints, 2);
int numHints = 0;
@@ -2179,7 +2184,7 @@ private:
netHints [numHints++] = Atoms::getIfExists ("_NET_WM_STATE_ABOVE");
if (numHints > 0)
xchangeProperty (windowH, Atoms::get().WindowState, XA_ATOM, 32, &netHints, numHints);
xchangeProperty (windowH, Atoms::get().windowState, XA_ATOM, 32, &netHints, numHints);
}
void createWindow (Window parentToAddTo)
@@ -2256,10 +2261,10 @@ private:
// Associate the PID, allowing to be shut down when something goes wrong
unsigned long pid = getpid();
xchangeProperty (windowH, atoms.Pid, XA_CARDINAL, 32, &pid, 1);
xchangeProperty (windowH, atoms.pid, XA_CARDINAL, 32, &pid, 1);
// Set window manager protocols
xchangeProperty (windowH, atoms.Protocols, XA_ATOM, 32, atoms.ProtocolList, 2);
xchangeProperty (windowH, atoms.protocols, XA_ATOM, 32, atoms.protocolList, 2);
// Set drag and drop flags
xchangeProperty (windowH, atoms.XdndTypeList, XA_ATOM, 32, atoms.allowedMimeTypes, numElementsInArray (atoms.allowedMimeTypes));
@@ -2316,7 +2321,7 @@ private:
long getUserTime() const
{
GetXProperty prop (windowH, Atoms::get().UserTime, 0, 65536, false, XA_CARDINAL);
GetXProperty prop (windowH, Atoms::get().userTime, 0, 65536, false, XA_CARDINAL);
return prop.success ? *(long*) prop.data : 0;
}
@@ -3116,11 +3121,17 @@ bool MouseInputSource::SourceList::addSource()
bool Desktop::canUseSemiTransparentWindows() noexcept
{
int matchedDepth = 0;
const int desiredDepth = 32;
#if JUCE_USE_XRENDER
if (XRender::hasCompositingWindowManager())
{
int matchedDepth = 0, desiredDepth = 32;
return Visuals::findVisualFormat (desiredDepth, matchedDepth) != 0
&& (matchedDepth == desiredDepth);
return Visuals::findVisualFormat (desiredDepth, matchedDepth) != 0
&& matchedDepth == desiredDepth;
}
#endif
return false;
}
Point<float> MouseInputSource::getCurrentRawMousePosition()
@@ -3366,7 +3377,7 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
void MouseCursor::showInWindow (ComponentPeer* peer) const
{
if (LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (peer))
if (LinuxComponentPeer* const lp = dynamic_cast<LinuxComponentPeer*> (peer))
lp->showMouseCursor ((Cursor) getHandle());
}
@@ -3390,7 +3401,7 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi
if (MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0))
if (Component* sourceComp = draggingSource->getComponentUnderMouse())
if (LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (sourceComp->getPeer()))
if (LinuxComponentPeer* const lp = dynamic_cast<LinuxComponentPeer*> (sourceComp->getPeer()))
return lp->externalDragFileInit (files, canMoveFiles);
// This method must be called in response to a component's mouseDown or mouseDrag event!
@@ -3405,7 +3416,7 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
if (MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0))
if (Component* sourceComp = draggingSource->getComponentUnderMouse())
if (LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (sourceComp->getPeer()))
if (LinuxComponentPeer* const lp = dynamic_cast<LinuxComponentPeer*> (sourceComp->getPeer()))
return lp->externalDragTextInit (text);
// This method must be called in response to a component's mouseDown or mouseDrag event!


+ 29
- 17
source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm View File

@@ -390,16 +390,36 @@ public:
return ComponentPeer::isKioskMode();
}
static bool isWindowAtPoint (NSWindow* w, NSPoint screenPoint)
{
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
if ([NSWindow respondsToSelector: @selector (windowNumberAtPoint:belowWindowWithWindowNumber:)])
return [NSWindow windowNumberAtPoint: screenPoint belowWindowWithWindowNumber: 0] == [w windowNumber];
#endif
return true;
}
bool contains (Point<int> localPos, bool trueIfInAChildWindow) const override
{
NSRect frameRect = [view frame];
NSRect viewFrame = [view frame];
if (! (isPositiveAndBelow (localPos.getX(), (int) frameRect.size.width)
&& isPositiveAndBelow (localPos.getY(), (int) frameRect.size.height)))
if (! (isPositiveAndBelow (localPos.getX(), (int) viewFrame.size.width)
&& isPositiveAndBelow (localPos.getY(), (int) viewFrame.size.height)))
return false;
NSView* v = [view hitTest: NSMakePoint (frameRect.origin.x + localPos.getX(),
frameRect.origin.y + frameRect.size.height - localPos.getY())];
if (NSWindow* const viewWindow = [view window])
{
const NSRect windowFrame = [viewWindow frame];
const NSPoint screenPoint = NSMakePoint (windowFrame.origin.x + localPos.getX(),
windowFrame.origin.y + windowFrame.size.height - localPos.getY());
if (! isWindowAtPoint (viewWindow, screenPoint))
return false;
}
NSView* v = [view hitTest: NSMakePoint (viewFrame.origin.x + localPos.getX(),
viewFrame.origin.y + viewFrame.size.height - localPos.getY())];
return trueIfInAChildWindow ? (v != nil)
: (v == view);
@@ -553,19 +573,11 @@ public:
{
currentModifiers = currentModifiers.withoutMouseButtons();
#if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
if ([NSWindow respondsToSelector: @selector (windowNumberAtPoint:belowWindowWithWindowNumber:)]
&& [NSWindow windowNumberAtPoint: [[ev window] convertBaseToScreen: [ev locationInWindow]]
belowWindowWithWindowNumber: 0] != [window windowNumber])
{
if (isWindowAtPoint ([ev window], [[ev window] convertBaseToScreen: [ev locationInWindow]]))
sendMouseEvent (ev);
else
// moved into another window which overlaps this one, so trigger an exit
handleMouseEvent (0, Point<float> (-1.0f, -1.0f), currentModifiers, getMouseTime (ev));
}
else
#endif
{
sendMouseEvent (ev);
}
showArrowCursorIfNeeded();
}
@@ -1013,7 +1025,7 @@ public:
static Point<float> getMousePos (NSEvent* e, NSView* view)
{
NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil];
return Point<float> (p.x, [view frame].size.height - p.y);
return Point<float> ((float) p.x, (float) ([view frame].size.height - p.y));
}
static int getModifierForButtonNumber (const NSInteger num)


+ 1
- 1
source/modules/juce_gui_basics/native/juce_mac_Windowing.mm View File

@@ -214,7 +214,7 @@ Point<float> MouseInputSource::getCurrentRawMousePosition()
JUCE_AUTORELEASEPOOL
{
const NSPoint p ([NSEvent mouseLocation]);
return Point<float> (p.x, getMainScreenHeight() - p.y);
return Point<float> ((float) p.x, (float) (getMainScreenHeight() - p.y));
}
}


+ 3
- 2
source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h View File

@@ -81,8 +81,9 @@ public:
bool isDynamic() const;
/** Returns a string which represents this point.
This returns a comma-separated list of coordinates, in the order left, top, right, bottom. For details of
the string syntax used by the coordinates, see the RelativeCoordinate constructor notes.
This returns a comma-separated list of coordinates, in the order left, top, right, bottom.
If you're using this to position a Component, then see the notes for
Component::setBounds (const RelativeRectangle&) for details of the syntax used.
The string that is returned can be passed to the RelativeRectangle constructor to recreate the rectangle.
*/
String toString() const;


+ 11
- 0
source/modules/juce_gui_basics/widgets/juce_Label.cpp View File

@@ -289,11 +289,22 @@ bool Label::isBeingEdited() const noexcept
return editor != nullptr;
}
static void copyColourIfSpecified (Label& l, TextEditor& ed, int colourID, int targetColourID)
{
if (l.isColourSpecified (colourID) || l.getLookAndFeel().isColourSpecified (colourID))
ed.setColour (targetColourID, l.findColour (colourID));
}
TextEditor* Label::createEditorComponent()
{
TextEditor* const ed = new TextEditor (getName());
ed->applyFontToAllText (getLookAndFeel().getLabelFont (*this));
copyAllExplicitColoursTo (*ed);
copyColourIfSpecified (*this, *ed, textWhenEditingColourId, TextEditor::textColourId);
copyColourIfSpecified (*this, *ed, backgroundWhenEditingColourId, TextEditor::backgroundColourId);
copyColourIfSpecified (*this, *ed, outlineWhenEditingColourId, TextEditor::outlineColourId);
return ed;
}


+ 7
- 4
source/modules/juce_gui_basics/widgets/juce_Label.h View File

@@ -101,10 +101,13 @@ public:
*/
enum ColourIds
{
backgroundColourId = 0x1000280, /**< The background colour to fill the label with. */
textColourId = 0x1000281, /**< The colour for the text. */
outlineColourId = 0x1000282 /**< An optional colour to use to draw a border around the label.
Leave this transparent to not have an outline. */
backgroundColourId = 0x1000280, /**< The background colour to fill the label with. */
textColourId = 0x1000281, /**< The colour for the text. */
outlineColourId = 0x1000282, /**< An optional colour to use to draw a border around the label.
Leave this transparent to not have an outline. */
backgroundWhenEditingColourId = 0x1000283, /**< The background colour when the label is being edited. */
textWhenEditingColourId = 0x1000284, /**< The colour for the text when the label is being edited. */
outlineWhenEditingColourId = 0x1000285 /**< An optional border colour when the label is being edited. */
};
//==============================================================================


+ 37
- 20
source/modules/juce_gui_basics/widgets/juce_Slider.cpp View File

@@ -667,7 +667,7 @@ public:
if (isTwoValue || isThreeValue)
{
const float mousePos = (float) (isVertical() ? e.y : e.x);
const float mousePos = isVertical() ? e.position.y : e.position.x;
const float normalPosDistance = std::abs (getLinearSliderPos (currentValue.getValue()) - mousePos);
const float minPosDistance = std::abs (getLinearSliderPos (valueMin.getValue()) - 0.1f - mousePos);
@@ -689,10 +689,10 @@ public:
//==============================================================================
void handleRotaryDrag (const MouseEvent& e)
{
const int dx = e.x - sliderRect.getCentreX();
const int dy = e.y - sliderRect.getCentreY();
const float dx = e.position.x - sliderRect.getCentreX();
const float dy = e.position.y - sliderRect.getCentreY();
if (dx * dx + dy * dy > 25)
if (dx * dx + dy * dy > 25.0f)
{
double angle = std::atan2 ((double) dx, (double) -dy);
while (angle < 0.0)
@@ -736,7 +736,7 @@ public:
void handleAbsoluteDrag (const MouseEvent& e)
{
const int mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.x : e.y;
const float mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.position.x : e.position.y;
double newPos = (mousePos - sliderRegionStart) / (double) sliderRegionSize;
if (style == RotaryHorizontalDrag
@@ -781,7 +781,7 @@ public:
void handleVelocityDrag (const MouseEvent& e)
{
const float mouseDiff = style == RotaryHorizontalVerticalDrag
? (e.x - mousePosWhenLastDragged.x) + (mousePosWhenLastDragged.y - e.y)
? (e.position.x - mousePosWhenLastDragged.x) + (mousePosWhenLastDragged.y - e.position.y)
: (isHorizontal()
|| style == RotaryHorizontalDrag
|| (style == IncDecButtons && incDecDragDirectionIsHorizontal()))
@@ -789,7 +789,7 @@ public:
: e.position.y - mousePosWhenLastDragged.y;
const double maxSpeed = jmax (200, sliderRegionSize);
double speed = jlimit (0.0, maxSpeed, (double) abs (mouseDiff));
double speed = jlimit (0.0, maxSpeed, (double) std::abs (mouseDiff));
if (speed != 0)
{
@@ -981,29 +981,45 @@ public:
}
}
double getMouseWheelDelta (double value, double wheelAmount)
{
if (style == IncDecButtons)
return interval * wheelAmount;
const double proportionDelta = wheelAmount * 0.15f;
const double currentPos = owner.valueToProportionOfLength (value);
return owner.proportionOfLengthToValue (jlimit (0.0, 1.0, currentPos + proportionDelta)) - value;
}
bool mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel)
{
if (scrollWheelEnabled
&& style != TwoValueHorizontal
&& style != TwoValueVertical)
{
if (maximum > minimum && ! e.mods.isAnyMouseButtonDown())
// sometimes duplicate wheel events seem to be sent, so since we're going to
// bump the value by a minimum of the interval, avoid doing this twice..
if (e.eventTime != lastMouseWheelTime)
{
if (valueBox != nullptr)
valueBox->hideEditor (false);
lastMouseWheelTime = e.eventTime;
if (maximum > minimum && ! e.mods.isAnyMouseButtonDown())
{
if (valueBox != nullptr)
valueBox->hideEditor (false);
const double value = (double) currentValue.getValue();
const double proportionDelta = (wheel.deltaX != 0 ? -wheel.deltaX : wheel.deltaY)
* (wheel.isReversed ? -0.15f : 0.15f);
const double currentPos = owner.valueToProportionOfLength (value);
const double newValue = owner.proportionOfLengthToValue (jlimit (0.0, 1.0, currentPos + proportionDelta));
const double value = (double) currentValue.getValue();
const double delta = getMouseWheelDelta (value, (wheel.deltaX != 0 ? -wheel.deltaX : wheel.deltaY)
* (wheel.isReversed ? -1.0f : 1.0f));
double delta = (newValue != value) ? jmax (std::abs (newValue - value), interval) : 0;
if (value > newValue)
delta = -delta;
if (delta != 0)
{
const double newValue = value + jmax (interval, std::abs (delta)) * (delta < 0 ? -1.0 : 1.0);
DragInProgress drag (*this);
setValue (owner.snapValue (value + delta, notDragging), sendNotificationSync);
DragInProgress drag (*this);
setValue (owner.snapValue (newValue, notDragging), sendNotificationSync);
}
}
}
return true;
@@ -1236,6 +1252,7 @@ public:
int sliderRegionStart, sliderRegionSize;
int sliderBeingDragged;
int pixelsForFullDragExtent;
Time lastMouseWheelTime;
Rectangle<int> sliderRect;
ScopedPointer<DragInProgress> currentDrag;


+ 1
- 1
source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp View File

@@ -91,7 +91,7 @@ void CallOutBox::setArrowSize (const float newSize)
int CallOutBox::getBorderSize() const noexcept
{
return jmax (20, (int) arrowSize);
return jmax (getLookAndFeel().getCallOutBoxBorderSize (*this), (int) arrowSize);
}
void CallOutBox::paint (Graphics& g)


+ 1
- 0
source/modules/juce_gui_basics/windows/juce_CallOutBox.h View File

@@ -130,6 +130,7 @@ public:
virtual ~LookAndFeelMethods() {}
virtual void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path&, Image& cachedImage) = 0;
virtual int getCallOutBoxBorderSize (const CallOutBox&) = 0;
};
//==============================================================================


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

@@ -117,8 +117,8 @@ LivePropertyEditorBase::LivePropertyEditorBase (LiveValueBase& v, CodeDocument&
name.setFont (13.0f);
name.setText (v.name, dontSendNotification);
valueEditor.setMultiLine (true);
valueEditor.setReturnKeyStartsNewLine (true);
valueEditor.setMultiLine (v.isString());
valueEditor.setReturnKeyStartsNewLine (v.isString());
valueEditor.setText (v.getStringValue (wasHex), dontSendNotification);
valueEditor.addListener (this);
sourceEditor.setReadOnly (true);
@@ -381,7 +381,7 @@ struct ColourEditorComp : public Component,
Colour getColour() const
{
return Colour ((int) parseInt (editor.value.getStringValue (false)));
return Colour ((uint32) parseInt (editor.value.getStringValue (false)));
}
void paint (Graphics& g) override


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

@@ -53,7 +53,7 @@ namespace LiveConstantEditor
inline void setFromString (double& v, const String& s) { v = parseDouble (s); }
inline void setFromString (float& v, const String& s) { v = (float) parseDouble (s); }
inline void setFromString (String& v, const String& s) { v = s; }
inline void setFromString (Colour& v, const String& s) { v = Colour ((int) parseInt (s)); }
inline void setFromString (Colour& v, const String& s) { v = Colour ((uint32) parseInt (s)); }
template <typename Type>
inline String getAsString (const Type& v, bool) { return String (v); }
@@ -67,6 +67,9 @@ namespace LiveConstantEditor
inline String getAsString (uint64 v, bool preferHex) { return intToString ((int64) v, preferHex); }
inline String getAsString (Colour v, bool) { return intToString ((int) v.getARGB(), true); }
template <typename Type> struct isStringType { enum { value = 0 }; };
template <> struct isStringType<String> { enum { value = 1 }; };
template <typename Type>
inline String getAsCode (Type& v, bool preferHex) { return getAsString (v, preferHex); }
inline String getAsCode (Colour v, bool) { return "Colour (0x" + String::toHexString ((int) v.getARGB()).paddedLeft ('0', 8) + ")"; }
@@ -90,6 +93,7 @@ namespace LiveConstantEditor
virtual String getCodeValue (bool preferHex) const = 0;
virtual void setStringValue (const String&) = 0;
virtual String getOriginalStringValue (bool preferHex) const = 0;
virtual bool isString() const = 0;
String name, sourceFile;
int sourceLine;
@@ -175,6 +179,7 @@ namespace LiveConstantEditor
String getCodeValue (bool preferHex) const override { return getAsCode (value, preferHex); }
String getOriginalStringValue (bool preferHex) const override { return getAsString (originalValue, preferHex); }
void setStringValue (const String& s) override { setFromString (value, s); }
bool isString() const override { return isStringType<Type>::value; }
Type value, originalValue;


Loading…
Cancel
Save