Browse Source

Update juce

tags/2018-04-16
falkTX 7 years ago
parent
commit
365ca740f5
69 changed files with 1031 additions and 634 deletions
  1. +13
    -0
      libs/juce/patches/fix-distrho-juceplugin-includes.patch
  2. +14
    -0
      libs/juce/patches/mingw-fixes_pt3.patch
  3. +132
    -0
      libs/juce/patches/silence-warnings.patch
  4. +8
    -8
      libs/juce/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp
  5. +32
    -62
      libs/juce/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp
  6. +5
    -5
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp
  7. +8
    -8
      libs/juce/source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp
  8. +12
    -1
      libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp
  9. +11
    -1
      libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h
  10. +2
    -2
      libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp
  11. +3
    -12
      libs/juce/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp
  12. +5
    -0
      libs/juce/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp
  13. +6
    -0
      libs/juce/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp
  14. +1
    -1
      libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm
  15. +2
    -5
      libs/juce/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
  16. +5
    -1
      libs/juce/source/modules/juce_audio_utils/gui/juce_BluetoothMidiDevicePairingDialogue.h
  17. +31
    -10
      libs/juce/source/modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp
  18. +31
    -12
      libs/juce/source/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm
  19. +2
    -1
      libs/juce/source/modules/juce_audio_utils/native/juce_linux_BluetoothMidiDevicePairingDialogue.cpp
  20. +2
    -1
      libs/juce/source/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm
  21. +2
    -1
      libs/juce/source/modules/juce_audio_utils/native/juce_win_BluetoothMidiDevicePairingDialogue.cpp
  22. +0
    -6
      libs/juce/source/modules/juce_core/maths/juce_BigInteger.h
  23. +15
    -22
      libs/juce/source/modules/juce_core/maths/juce_MathsFunctions.h
  24. +29
    -0
      libs/juce/source/modules/juce_core/memory/juce_WeakReference.h
  25. +18
    -0
      libs/juce/source/modules/juce_core/native/java/JuceAppActivity.java
  26. +1
    -1
      libs/juce/source/modules/juce_core/native/juce_android_SystemStats.cpp
  27. +2
    -2
      libs/juce/source/modules/juce_core/native/juce_linux_Files.cpp
  28. +71
    -0
      libs/juce/source/modules/juce_core/native/juce_osx_ObjCHelpers.h
  29. +2
    -0
      libs/juce/source/modules/juce_core/native/juce_posix_SharedCode.h
  30. +26
    -28
      libs/juce/source/modules/juce_core/network/juce_URL.cpp
  31. +12
    -24
      libs/juce/source/modules/juce_core/network/juce_URL.h
  32. +0
    -5
      libs/juce/source/modules/juce_core/system/juce_StandardHeader.h
  33. +3
    -2
      libs/juce/source/modules/juce_core/text/juce_CharacterFunctions.cpp
  34. +138
    -22
      libs/juce/source/modules/juce_core/text/juce_CharacterFunctions.h
  35. +1
    -1
      libs/juce/source/modules/juce_core/xml/juce_XmlElement.cpp
  36. +1
    -1
      libs/juce/source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp
  37. +6
    -1
      libs/juce/source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp
  38. +0
    -2
      libs/juce/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp
  39. +1
    -3
      libs/juce/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.h
  40. +6
    -12
      libs/juce/source/modules/juce_events/interprocess/juce_InterprocessConnection.cpp
  41. +3
    -4
      libs/juce/source/modules/juce_events/interprocess/juce_InterprocessConnection.h
  42. +2
    -2
      libs/juce/source/modules/juce_graphics/fonts/juce_CustomTypeface.cpp
  43. +24
    -22
      libs/juce/source/modules/juce_graphics/fonts/juce_TextLayout.cpp
  44. +1
    -1
      libs/juce/source/modules/juce_graphics/geometry/juce_EdgeTable.cpp
  45. +1
    -1
      libs/juce/source/modules/juce_graphics/geometry/juce_EdgeTable.h
  46. +2
    -8
      libs/juce/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp
  47. +1
    -3
      libs/juce/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h
  48. +1
    -8
      libs/juce/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp
  49. +0
    -2
      libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp
  50. +2
    -4
      libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h
  51. +2
    -0
      libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp
  52. +1
    -1
      libs/juce/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp
  53. +140
    -69
      libs/juce/source/modules/juce_gui_basics/native/juce_mac_MainMenu.mm
  54. +2
    -2
      libs/juce/source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm
  55. +2
    -2
      libs/juce/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp
  56. +59
    -89
      libs/juce/source/modules/juce_gui_basics/windows/juce_AlertWindow.cpp
  57. +2
    -2
      libs/juce/source/modules/juce_gui_basics/windows/juce_AlertWindow.h
  58. +26
    -25
      libs/juce/source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp
  59. +4
    -4
      libs/juce/source/modules/juce_gui_basics/windows/juce_CallOutBox.h
  60. +3
    -11
      libs/juce/source/modules/juce_gui_basics/windows/juce_DialogWindow.cpp
  61. +6
    -6
      libs/juce/source/modules/juce_gui_basics/windows/juce_DialogWindow.h
  62. +27
    -33
      libs/juce/source/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp
  63. +3
    -3
      libs/juce/source/modules/juce_gui_basics/windows/juce_DocumentWindow.h
  64. +25
    -27
      libs/juce/source/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp
  65. +17
    -26
      libs/juce/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp
  66. +1
    -1
      libs/juce/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.h
  67. +2
    -2
      libs/juce/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp
  68. +6
    -6
      libs/juce/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp
  69. +7
    -7
      libs/juce/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp

+ 13
- 0
libs/juce/patches/fix-distrho-juceplugin-includes.patch View File

@@ -0,0 +1,13 @@
diff --git a/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h b/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h
index 701c4df..0e8a324 100644
--- a/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h
+++ b/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h
@@ -24,6 +24,8 @@
==============================================================================
*/
+#pragma once
+
#include "../juce_audio_plugin_client.h"
namespace juce

+ 14
- 0
libs/juce/patches/mingw-fixes_pt3.patch View File

@@ -0,0 +1,14 @@
diff --git a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
index 172e348..2a33c4f 100644
--- a/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
+++ b/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
@@ -56,9 +56,6 @@ using namespace Vst2;
#ifndef WM_APPCOMMAND
#define WM_APPCOMMAND 0x0319
#endif
-
- extern "C" void _fpreset();
- extern "C" void _clearfp();
#elif ! JUCE_WINDOWS
static void _fpreset() {}
static void _clearfp() {}

+ 132
- 0
libs/juce/patches/silence-warnings.patch View File

@@ -0,0 +1,132 @@
diff --git a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp
index 05c3c44..2f03506 100644
--- a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp
+++ b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp
@@ -117,6 +117,9 @@ namespace FlacNamespace
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wshadow"
#pragma clang diagnostic ignored "-Wdeprecated-register"
+ #elif JUCE_GCC && (__GNUC__ >= 7)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
#if JUCE_INTEL
@@ -157,6 +160,8 @@ namespace FlacNamespace
#if JUCE_CLANG
#pragma clang diagnostic pop
+ #elif JUCE_GCC && (__GNUC__ >= 7)
+ #pragma GCC diagnostic pop
#endif
}
diff --git a/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp
index 0a2737b..e2ebd13 100644
--- a/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp
+++ b/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp
@@ -47,6 +47,12 @@ namespace OggVorbisNamespace
#elif JUCE_GCC
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
+ #if (__GNUC__ >= 6)
+ #pragma GCC diagnostic ignored "-Wmisleading-indentation"
+ #if (__GNUC__ >= 7)
+ #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+ #endif
+ #endif
#endif
#include "oggvorbis/vorbisenc.h"
diff --git a/modules/juce_core/native/juce_linux_Files.cpp b/modules/juce_core/native/juce_linux_Files.cpp
index d022175..1edbfe8 100644
--- a/modules/juce_core/native/juce_linux_Files.cpp
+++ b/modules/juce_core/native/juce_linux_Files.cpp
@@ -136,14 +136,14 @@ File File::getSpecialLocation (const SpecialLocationType type)
case invokedExecutableFile:
if (juce_argv != nullptr && juce_argc > 0)
return File (CharPointer_UTF8 (juce_argv[0]));
- // deliberate fall-through...
+ // fall-through
case currentExecutableFile:
case currentApplicationFile:
#if ! JUCE_STANDALONE_APPLICATION
return juce_getExecutableFile();
#endif
- // deliberate fall-through if this is not a shared-library
+ // fall-through
case hostApplicationPath:
{
diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h
index 67c884a..100d41a 100644
--- a/modules/juce_core/native/juce_posix_SharedCode.h
+++ b/modules/juce_core/native/juce_posix_SharedCode.h
@@ -1205,6 +1205,8 @@ public:
close (pipeHandles[1]); // close the write handle
}
}
+
+ ignoreUnused (streamFlags);
}
~ActiveProcess()
diff --git a/modules/juce_core/xml/juce_XmlElement.cpp b/modules/juce_core/xml/juce_XmlElement.cpp
index b04e307..5c86674 100644
--- a/modules/juce_core/xml/juce_XmlElement.cpp
+++ b/modules/juce_core/xml/juce_XmlElement.cpp
@@ -241,7 +241,7 @@ namespace XmlOutputFunctions
outputStream << (char) character;
break;
}
- // Note: deliberate fall-through here!
+ // fall-through
default:
outputStream << "&#" << ((int) character) << ';';
break;
diff --git a/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp b/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp
index df64f23..45087c6 100644
--- a/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp
+++ b/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp
@@ -92,7 +92,7 @@ private:
{
case Z_STREAM_END:
finished = true;
- // Deliberate fall-through..
+ // fall-through..
case Z_OK:
{
data += dataSize - stream.avail_in;
diff --git a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp
index 0bae4d3..bd33e93 100644
--- a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp
+++ b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp
@@ -39,6 +39,9 @@ namespace zlibNamespace
#if __has_warning("-Wcomma")
#pragma clang diagnostic ignored "-Wcomma"
#endif
+ #elif JUCE_GCC && (__GNUC__ >= 7)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
#undef OS_CODE
@@ -74,6 +77,8 @@ namespace zlibNamespace
#if JUCE_CLANG
#pragma clang diagnostic pop
+ #elif JUCE_GCC && (__GNUC__ >= 7)
+ #pragma GCC diagnostic pop
#endif
#else
#include JUCE_ZLIB_INCLUDE_PATH
@@ -136,7 +141,7 @@ public:
{
case Z_STREAM_END:
finished = true;
- // deliberate fall-through
+ // fall-through
case Z_OK:
data += dataSize - stream.avail_in;
dataSize = (z_uInt) stream.avail_in;

+ 8
- 8
libs/juce/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp View File

@@ -27,13 +27,13 @@ struct CatmullRomAlgorithm
{ {
static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept
{ {
const float y0 = inputs[3];
const float y1 = inputs[2];
const float y2 = inputs[1];
const float y3 = inputs[0];
auto y0 = inputs[3];
auto y1 = inputs[2];
auto y2 = inputs[1];
auto y3 = inputs[0];
const float halfY0 = 0.5f * y0;
const float halfY3 = 0.5f * y3;
auto halfY0 = 0.5f * y0;
auto halfY3 = 0.5f * y3;
return y1 + offset * ((0.5f * y2 - halfY0) return y1 + offset * ((0.5f * y2 - halfY0)
+ (offset * (((y0 + 2.0f * y2) - (halfY3 + 2.5f * y1)) + (offset * (((y0 + 2.0f * y2) - (halfY3 + 2.5f * y1))
@@ -48,8 +48,8 @@ void CatmullRomInterpolator::reset() noexcept
{ {
subSamplePos = 1.0; subSamplePos = 1.0;
for (int i = 0; i < numElementsInArray (lastInputSamples); ++i)
lastInputSamples[i] = 0;
for (auto& s : lastInputSamples)
s = 0;
} }
int CatmullRomInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept int CatmullRomInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept


+ 32
- 62
libs/juce/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp View File

@@ -49,97 +49,67 @@ namespace
} }
template <typename InterpolatorType> template <typename InterpolatorType>
static int interpolate (float* lastInputSamples, double& subSamplePos, const double actualRatio,
const float* in, float* out, const int numOut) noexcept
static int interpolate (float* lastInputSamples, double& subSamplePos, double actualRatio,
const float* in, float* out, int numOut) noexcept
{ {
if (actualRatio == 1.0)
auto pos = subSamplePos;
if (actualRatio == 1.0 && pos == 1.0)
{ {
memcpy (out, in, (size_t) numOut * sizeof (float)); memcpy (out, in, (size_t) numOut * sizeof (float));
pushInterpolationSamples (lastInputSamples, in, numOut); pushInterpolationSamples (lastInputSamples, in, numOut);
return numOut; return numOut;
} }
const float* const originalIn = in;
double pos = subSamplePos;
int numUsed = 0;
if (actualRatio < 1.0)
while (numOut > 0)
{ {
for (int i = numOut; --i >= 0;)
while (pos >= 1.0)
{ {
if (pos >= 1.0)
{
pushInterpolationSample (lastInputSamples, *in++);
pos -= 1.0;
}
*out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
}
}
else
{
for (int i = numOut; --i >= 0;)
{
while (pos < actualRatio)
{
pushInterpolationSample (lastInputSamples, *in++);
pos += 1.0;
}
pos -= actualRatio;
*out++ = InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos));
pushInterpolationSample (lastInputSamples, in[numUsed++]);
pos -= 1.0;
} }
*out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
--numOut;
} }
subSamplePos = pos; subSamplePos = pos;
return (int) (in - originalIn);
return numUsed;
} }
template <typename InterpolatorType> template <typename InterpolatorType>
static int interpolateAdding (float* lastInputSamples, double& subSamplePos, const double actualRatio,
const float* in, float* out, const int numOut, const float gain) noexcept
static int interpolateAdding (float* lastInputSamples, double& subSamplePos, double actualRatio,
const float* in, float* out, int numOut, const float gain) noexcept
{ {
if (actualRatio == 1.0)
auto pos = subSamplePos;
if (actualRatio == 1.0 && pos == 1.0)
{ {
FloatVectorOperations::addWithMultiply (out, in, gain, numOut); FloatVectorOperations::addWithMultiply (out, in, gain, numOut);
pushInterpolationSamples (lastInputSamples, in, numOut); pushInterpolationSamples (lastInputSamples, in, numOut);
return numOut; return numOut;
} }
const float* const originalIn = in;
double pos = subSamplePos;
int numUsed = 0;
if (actualRatio < 1.0)
while (numOut > 0)
{ {
for (int i = numOut; --i >= 0;)
while (pos >= 1.0)
{ {
if (pos >= 1.0)
{
pushInterpolationSample (lastInputSamples, *in++);
pos -= 1.0;
}
*out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
}
}
else
{
for (int i = numOut; --i >= 0;)
{
while (pos < actualRatio)
{
pushInterpolationSample (lastInputSamples, *in++);
pos += 1.0;
}
pos -= actualRatio;
*out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos));
pushInterpolationSample (lastInputSamples, in[numUsed++]);
pos -= 1.0;
} }
*out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos);
pos += actualRatio;
--numOut;
} }
subSamplePos = pos; subSamplePos = pos;
return (int) (in - originalIn);
return numUsed;
} }
} }
@@ -186,8 +156,8 @@ void LagrangeInterpolator::reset() noexcept
{ {
subSamplePos = 1.0; subSamplePos = 1.0;
for (int i = 0; i < numElementsInArray (lastInputSamples); ++i)
lastInputSamples[i] = 0;
for (auto& s : lastInputSamples)
s = 0;
} }
int LagrangeInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept int LagrangeInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept


+ 5
- 5
libs/juce/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp View File

@@ -44,24 +44,24 @@ bool MidiKeyboardState::isNoteOn (const int midiChannel, const int n) const noex
{ {
jassert (midiChannel >= 0 && midiChannel <= 16); jassert (midiChannel >= 0 && midiChannel <= 16);
return isPositiveAndBelow (n, (int) 128)
return isPositiveAndBelow (n, 128)
&& (noteStates[n] & (1 << (midiChannel - 1))) != 0; && (noteStates[n] & (1 << (midiChannel - 1))) != 0;
} }
bool MidiKeyboardState::isNoteOnForChannels (const int midiChannelMask, const int n) const noexcept bool MidiKeyboardState::isNoteOnForChannels (const int midiChannelMask, const int n) const noexcept
{ {
return isPositiveAndBelow (n, (int) 128)
return isPositiveAndBelow (n, 128)
&& (noteStates[n] & midiChannelMask) != 0; && (noteStates[n] & midiChannelMask) != 0;
} }
void MidiKeyboardState::noteOn (const int midiChannel, const int midiNoteNumber, const float velocity) void MidiKeyboardState::noteOn (const int midiChannel, const int midiNoteNumber, const float velocity)
{ {
jassert (midiChannel >= 0 && midiChannel <= 16); jassert (midiChannel >= 0 && midiChannel <= 16);
jassert (isPositiveAndBelow (midiNoteNumber, (int) 128));
jassert (isPositiveAndBelow (midiNoteNumber, 128));
const ScopedLock sl (lock); const ScopedLock sl (lock);
if (isPositiveAndBelow (midiNoteNumber, (int) 128))
if (isPositiveAndBelow (midiNoteNumber, 128))
{ {
const int timeNow = (int) Time::getMillisecondCounter(); const int timeNow = (int) Time::getMillisecondCounter();
eventsToAdd.addEvent (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity), timeNow); eventsToAdd.addEvent (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity), timeNow);
@@ -73,7 +73,7 @@ void MidiKeyboardState::noteOn (const int midiChannel, const int midiNoteNumber,
void MidiKeyboardState::noteOnInternal (const int midiChannel, const int midiNoteNumber, const float velocity) void MidiKeyboardState::noteOnInternal (const int midiChannel, const int midiNoteNumber, const float velocity)
{ {
if (isPositiveAndBelow (midiNoteNumber, (int) 128))
if (isPositiveAndBelow (midiNoteNumber, 128))
{ {
noteStates [midiNoteNumber] |= (1 << (midiChannel - 1)); noteStates [midiNoteNumber] |= (1 << (midiChannel - 1));


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

@@ -452,8 +452,8 @@ MidiMessage MidiMessage::aftertouchChange (const int channel,
const int aftertouchValue) noexcept const int aftertouchValue) noexcept
{ {
jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16
jassert (isPositiveAndBelow (noteNum, (int) 128));
jassert (isPositiveAndBelow (aftertouchValue, (int) 128));
jassert (isPositiveAndBelow (noteNum, 128));
jassert (isPositiveAndBelow (aftertouchValue, 128));
return MidiMessage (MidiHelpers::initialByte (0xa0, channel), return MidiMessage (MidiHelpers::initialByte (0xa0, channel),
noteNum & 0x7f, noteNum & 0x7f,
@@ -474,7 +474,7 @@ int MidiMessage::getChannelPressureValue() const noexcept
MidiMessage MidiMessage::channelPressureChange (const int channel, const int pressure) noexcept MidiMessage MidiMessage::channelPressureChange (const int channel, const int pressure) noexcept
{ {
jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16
jassert (isPositiveAndBelow (pressure, (int) 128));
jassert (isPositiveAndBelow (pressure, 128));
return MidiMessage (MidiHelpers::initialByte (0xd0, channel), pressure & 0x7f); return MidiMessage (MidiHelpers::initialByte (0xd0, channel), pressure & 0x7f);
} }
@@ -522,7 +522,7 @@ int MidiMessage::getPitchWheelValue() const noexcept
MidiMessage MidiMessage::pitchWheel (const int channel, const int position) noexcept MidiMessage MidiMessage::pitchWheel (const int channel, const int position) noexcept
{ {
jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16
jassert (isPositiveAndBelow (position, (int) 0x4000));
jassert (isPositiveAndBelow (position, 0x4000));
return MidiMessage (MidiHelpers::initialByte (0xe0, channel), return MidiMessage (MidiHelpers::initialByte (0xe0, channel),
position & 127, (position >> 7) & 127); position & 127, (position >> 7) & 127);
@@ -563,7 +563,7 @@ MidiMessage MidiMessage::controllerEvent (const int channel, const int controlle
MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, const uint8 velocity) noexcept MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, const uint8 velocity) noexcept
{ {
jassert (channel > 0 && channel <= 16); jassert (channel > 0 && channel <= 16);
jassert (isPositiveAndBelow (noteNumber, (int) 128));
jassert (isPositiveAndBelow (noteNumber, 128));
return MidiMessage (MidiHelpers::initialByte (0x90, channel), return MidiMessage (MidiHelpers::initialByte (0x90, channel),
noteNumber & 127, MidiHelpers::validVelocity (velocity)); noteNumber & 127, MidiHelpers::validVelocity (velocity));
@@ -577,7 +577,7 @@ MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, const
MidiMessage MidiMessage::noteOff (const int channel, const int noteNumber, uint8 velocity) noexcept MidiMessage MidiMessage::noteOff (const int channel, const int noteNumber, uint8 velocity) noexcept
{ {
jassert (channel > 0 && channel <= 16); jassert (channel > 0 && channel <= 16);
jassert (isPositiveAndBelow (noteNumber, (int) 128));
jassert (isPositiveAndBelow (noteNumber, 128));
return MidiMessage (MidiHelpers::initialByte (0x80, channel), return MidiMessage (MidiHelpers::initialByte (0x80, channel),
noteNumber & 127, MidiHelpers::validVelocity (velocity)); noteNumber & 127, MidiHelpers::validVelocity (velocity));
@@ -591,7 +591,7 @@ MidiMessage MidiMessage::noteOff (const int channel, const int noteNumber, float
MidiMessage MidiMessage::noteOff (const int channel, const int noteNumber) noexcept MidiMessage MidiMessage::noteOff (const int channel, const int noteNumber) noexcept
{ {
jassert (channel > 0 && channel <= 16); jassert (channel > 0 && channel <= 16);
jassert (isPositiveAndBelow (noteNumber, (int) 128));
jassert (isPositiveAndBelow (noteNumber, 128));
return MidiMessage (MidiHelpers::initialByte (0x80, channel), noteNumber & 127, 0); return MidiMessage (MidiHelpers::initialByte (0x80, channel), noteNumber & 127, 0);
} }
@@ -983,7 +983,7 @@ String MidiMessage::getMidiNoteName (int note, bool useSharps, bool includeOctav
static const char* const sharpNoteNames[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; static const char* const sharpNoteNames[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
static const char* const flatNoteNames[] = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" }; static const char* const flatNoteNames[] = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" };
if (isPositiveAndBelow (note, (int) 128))
if (isPositiveAndBelow (note, 128))
{ {
String s (useSharps ? sharpNoteNames [note % 12] String s (useSharps ? sharpNoteNames [note % 12]
: flatNoteNames [note % 12]); : flatNoteNames [note % 12]);


+ 12
- 1
libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp View File

@@ -731,6 +731,9 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat
const double msTaken = Time::getMillisecondCounterHiRes() - callbackStartTime; const double msTaken = Time::getMillisecondCounterHiRes() - callbackStartTime;
const double filterAmount = 0.2; const double filterAmount = 0.2;
cpuUsageMs += filterAmount * (msTaken - cpuUsageMs); cpuUsageMs += filterAmount * (msTaken - cpuUsageMs);
if (msTaken > msPerBlock)
xruns++;
} }
else else
{ {
@@ -756,13 +759,14 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat
void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device) void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device)
{ {
cpuUsageMs = 0; cpuUsageMs = 0;
xruns = 0;
const double sampleRate = device->getCurrentSampleRate(); const double sampleRate = device->getCurrentSampleRate();
const int blockSize = device->getCurrentBufferSizeSamples(); const int blockSize = device->getCurrentBufferSizeSamples();
if (sampleRate > 0.0 && blockSize > 0) if (sampleRate > 0.0 && blockSize > 0)
{ {
const double msPerBlock = 1000.0 * blockSize / sampleRate;
msPerBlock = 1000.0 * blockSize / sampleRate;
timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0; timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0;
} }
@@ -779,6 +783,7 @@ void AudioDeviceManager::audioDeviceStoppedInt()
{ {
cpuUsageMs = 0; cpuUsageMs = 0;
timeToCpuScale = 0; timeToCpuScale = 0;
xruns = 0;
sendChangeMessage(); sendChangeMessage();
const ScopedLock sl (audioCallbackLock); const ScopedLock sl (audioCallbackLock);
@@ -998,6 +1003,12 @@ void AudioDeviceManager::playTestSound()
} }
} }
int AudioDeviceManager::getXRunCount() const noexcept
{
auto deviceXRuns = (currentAudioDevice != nullptr ? currentAudioDevice->getXRunCount() : -1);
return (deviceXRuns >= 0 ? deviceXRuns : xruns);
}
double AudioDeviceManager::getCurrentInputLevel() const noexcept { return inputLevelMeter.getCurrentLevel(); } double AudioDeviceManager::getCurrentInputLevel() const noexcept { return inputLevelMeter.getCurrentLevel(); }
double AudioDeviceManager::getCurrentOutputLevel() const noexcept { return outputLevelMeter.getCurrentLevel(); } double AudioDeviceManager::getCurrentOutputLevel() const noexcept { return outputLevelMeter.getCurrentLevel(); }


+ 11
- 1
libs/juce/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h View File

@@ -436,6 +436,15 @@ public:
*/ */
CriticalSection& getMidiCallbackLock() noexcept { return midiCallbackLock; } CriticalSection& getMidiCallbackLock() noexcept { return midiCallbackLock; }
//==============================================================================
/** Returns the number of under- or over runs reported.
This method will use the underlying device's native getXRunCount if it supports
it. Otherwise it will estimate the number of under-/overruns by measuring the
time it spent in the audio callback.
*/
int getXRunCount() const noexcept;
private: private:
//============================================================================== //==============================================================================
OwnedArray<AudioIODeviceType> availableDeviceTypes; OwnedArray<AudioIODeviceType> availableDeviceTypes;
@@ -468,7 +477,8 @@ private:
ScopedPointer<AudioSampleBuffer> testSound; ScopedPointer<AudioSampleBuffer> testSound;
int testSoundPosition; int testSoundPosition;
double cpuUsageMs, timeToCpuScale;
double cpuUsageMs, timeToCpuScale, msPerBlock;
int xruns;
struct LevelMeter struct LevelMeter
{ {


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

@@ -347,7 +347,7 @@ MidiOutput* MidiOutput::openDevice (int index)
{ {
MidiOutput* mo = nullptr; MidiOutput* mo = nullptr;
if (isPositiveAndBelow (index, (int) MIDIGetNumberOfDestinations()))
if (isPositiveAndBelow (index, MIDIGetNumberOfDestinations()))
{ {
MIDIEndpointRef endPoint = MIDIGetDestination ((ItemCount) index); MIDIEndpointRef endPoint = MIDIGetDestination ((ItemCount) index);
@@ -465,7 +465,7 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
using namespace CoreMidiHelpers; using namespace CoreMidiHelpers;
MidiInput* newInput = nullptr; MidiInput* newInput = nullptr;
if (isPositiveAndBelow (index, (int) MIDIGetNumberOfSources()))
if (isPositiveAndBelow (index, MIDIGetNumberOfSources()))
{ {
if (MIDIEndpointRef endPoint = MIDIGetSource ((ItemCount) index)) if (MIDIEndpointRef endPoint = MIDIGetSource ((ItemCount) index))
{ {


+ 3
- 12
libs/juce/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp View File

@@ -1444,16 +1444,7 @@ struct ASIOAudioIODevice::ASIOCallbackFunctions <sizeof(currentASIODev) / sizeof
class ASIOAudioIODeviceType : public AudioIODeviceType class ASIOAudioIODeviceType : public AudioIODeviceType
{ {
public: public:
ASIOAudioIODeviceType()
: AudioIODeviceType ("ASIO"),
hasScanned (false)
{
}
~ASIOAudioIODeviceType()
{
masterReference.clear();
}
ASIOAudioIODeviceType() : AudioIODeviceType ("ASIO") {}
//============================================================================== //==============================================================================
void scanForDevices() void scanForDevices()
@@ -1549,13 +1540,13 @@ public:
callDeviceChangeListeners(); callDeviceChangeListeners();
} }
WeakReference<ASIOAudioIODeviceType>::Master masterReference;
JUCE_DECLARE_WEAK_REFERENCEABLE (ASIOAudioIODeviceType)
private: private:
StringArray deviceNames; StringArray deviceNames;
Array<CLSID> classIds; Array<CLSID> classIds;
bool hasScanned;
bool hasScanned = false;
//============================================================================== //==============================================================================
static bool checkClassIsOk (const String& classId) static bool checkClassIsOk (const String& classId)


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

@@ -117,6 +117,9 @@ namespace FlacNamespace
#pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wshadow" #pragma clang diagnostic ignored "-Wshadow"
#pragma clang diagnostic ignored "-Wdeprecated-register" #pragma clang diagnostic ignored "-Wdeprecated-register"
#elif JUCE_GCC && (__GNUC__ >= 7)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif #endif
#if JUCE_INTEL #if JUCE_INTEL
@@ -157,6 +160,8 @@ namespace FlacNamespace
#if JUCE_CLANG #if JUCE_CLANG
#pragma clang diagnostic pop #pragma clang diagnostic pop
#elif JUCE_GCC && (__GNUC__ >= 7)
#pragma GCC diagnostic pop
#endif #endif
} }


+ 6
- 0
libs/juce/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp View File

@@ -47,6 +47,12 @@ namespace OggVorbisNamespace
#elif JUCE_GCC #elif JUCE_GCC
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wshadow"
#if (__GNUC__ >= 6)
#pragma GCC diagnostic ignored "-Wmisleading-indentation"
#if (__GNUC__ >= 7)
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
#endif
#endif #endif
#include "oggvorbis/vorbisenc.h" #include "oggvorbis/vorbisenc.h"


+ 1
- 1
libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm View File

@@ -1704,7 +1704,7 @@ private:
for (MidiBuffer::Iterator i (midiEvents); i.getNextEvent (midiEventData, midiEventSize, midiEventPosition);) for (MidiBuffer::Iterator i (midiEvents); i.getNextEvent (midiEventData, midiEventSize, midiEventPosition);)
{ {
jassert (isPositiveAndBelow (midiEventPosition, (int) nFrames));
jassert (isPositiveAndBelow (midiEventPosition, nFrames));
ignoreUnused (nFrames); ignoreUnused (nFrames);
dataSize += (size_t) midiEventSize; dataSize += (size_t) midiEventSize;


+ 2
- 5
libs/juce/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp View File

@@ -56,9 +56,6 @@ using namespace Vst2;
#ifndef WM_APPCOMMAND #ifndef WM_APPCOMMAND
#define WM_APPCOMMAND 0x0319 #define WM_APPCOMMAND 0x0319
#endif #endif
extern "C" void _fpreset();
extern "C" void _clearfp();
#elif ! JUCE_WINDOWS #elif ! JUCE_WINDOWS
static void _fpreset() {} static void _fpreset() {}
static void _clearfp() {} static void _clearfp() {}
@@ -943,7 +940,7 @@ struct VSTPluginInstance : public AudioPluginInstance,
float getParameter (int index) override float getParameter (int index) override
{ {
if (vstEffect != nullptr && isPositiveAndBelow (index, (int) vstEffect->numParameters))
if (vstEffect != nullptr && isPositiveAndBelow (index, vstEffect->numParameters))
{ {
const ScopedLock sl (lock); const ScopedLock sl (lock);
return vstEffect->getParameterValueFunction (vstEffect, index); return vstEffect->getParameterValueFunction (vstEffect, index);
@@ -954,7 +951,7 @@ struct VSTPluginInstance : public AudioPluginInstance,
void setParameter (int index, float newValue) override void setParameter (int index, float newValue) override
{ {
if (vstEffect != nullptr && isPositiveAndBelow (index, (int) vstEffect->numParameters))
if (vstEffect != nullptr && isPositiveAndBelow (index, vstEffect->numParameters))
{ {
const ScopedLock sl (lock); const ScopedLock sl (lock);


+ 5
- 1
libs/juce/source/modules/juce_audio_utils/gui/juce_BluetoothMidiDevicePairingDialogue.h View File

@@ -52,11 +52,15 @@ public:
@param exitCallback A callback which will be called when the modal @param exitCallback A callback which will be called when the modal
bluetooth dialog is closed. bluetooth dialog is closed.
@param btWindowBounds The bounds of the bluetooth window that will
be opened. The dialog itself is opened by the OS so cannot
be customised by JUCE.
@return true if the dialogue was opened, false on error. @return true if the dialogue was opened, false on error.
@see ModalComponentManager::Callback @see ModalComponentManager::Callback
*/ */
static bool open (ModalComponentManager::Callback* exitCallback = nullptr);
static bool open (ModalComponentManager::Callback* exitCallback = nullptr,
Rectangle<int>* btWindowBounds = nullptr);
/** Checks if a Bluetooth MIDI pairing dialogue is available on this /** Checks if a Bluetooth MIDI pairing dialogue is available on this
platform. platform.


+ 31
- 10
libs/juce/source/modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp View File

@@ -391,7 +391,9 @@ private:
class BluetoothMidiSelectorOverlay : public Component class BluetoothMidiSelectorOverlay : public Component
{ {
public: public:
BluetoothMidiSelectorOverlay (ModalComponentManager::Callback* exitCallbackToUse)
BluetoothMidiSelectorOverlay (ModalComponentManager::Callback* exitCallbackToUse,
const Rectangle<int>& boundsToUse)
: bounds (boundsToUse)
{ {
ScopedPointer<ModalComponentManager::Callback> exitCallback (exitCallbackToUse); ScopedPointer<ModalComponentManager::Callback> exitCallback (exitCallbackToUse);
@@ -400,8 +402,14 @@ public:
setAlwaysOnTop (true); setAlwaysOnTop (true);
setVisible (true); setVisible (true);
addToDesktop (ComponentPeer::windowHasDropShadow); addToDesktop (ComponentPeer::windowHasDropShadow);
setBounds (0, 0, getParentWidth(), getParentHeight());
if (bounds.isEmpty())
setBounds (0, 0, getParentWidth(), getParentHeight());
else
setBounds (bounds);
toFront (true); toFront (true);
setOpaque (! bounds.isEmpty());
addAndMakeVisible (bluetoothDevicesList); addAndMakeVisible (bluetoothDevicesList);
enterModalState (true, exitCallback.release(), true); enterModalState (true, exitCallback.release(), true);
@@ -414,7 +422,7 @@ public:
void paint (Graphics& g) override void paint (Graphics& g) override
{ {
g.fillAll (Colours::black.withAlpha (0.6f));
g.fillAll (bounds.isEmpty() ? Colours::black.withAlpha (0.6f) : Colours::black);
g.setColour (Colour (0xffdfdfdf)); g.setColour (Colour (0xffdfdfdf));
Rectangle<int> overlayBounds = getOverlayBounds(); Rectangle<int> overlayBounds = getOverlayBounds();
@@ -441,19 +449,30 @@ public:
void parentSizeChanged() override { update(); } void parentSizeChanged() override { update(); }
private: private:
Rectangle<int> bounds;
void update() void update()
{ {
setBounds (0, 0, getParentWidth(), getParentHeight());
if (bounds.isEmpty())
setBounds (0, 0, getParentWidth(), getParentHeight());
else
setBounds (bounds);
bluetoothDevicesList.setBounds (getOverlayBounds().withTrimmedTop (40)); bluetoothDevicesList.setBounds (getOverlayBounds().withTrimmedTop (40));
} }
Rectangle<int> getOverlayBounds() const noexcept Rectangle<int> getOverlayBounds() const noexcept
{ {
const int pw = getParentWidth();
const int ph = getParentHeight();
if (bounds.isEmpty())
{
const int pw = getParentWidth();
const int ph = getParentHeight();
return Rectangle<int> (pw, ph).withSizeKeepingCentre (jmin (400, pw - 14),
jmin (300, ph - 40));
}
return Rectangle<int> (pw, ph).withSizeKeepingCentre (jmin (400, pw - 14),
jmin (300, ph - 40));
return bounds.withZeroOrigin();
} }
AndroidBluetoothMidiDevicesListBox bluetoothDevicesList; AndroidBluetoothMidiDevicesListBox bluetoothDevicesList;
@@ -462,9 +481,11 @@ private:
}; };
//============================================================================== //==============================================================================
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallbackPtr)
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallbackPtr,
Rectangle<int>* btBounds)
{ {
ScopedPointer<ModalComponentManager::Callback> exitCallback (exitCallbackPtr); ScopedPointer<ModalComponentManager::Callback> exitCallback (exitCallbackPtr);
auto boundsToUse = (btBounds != nullptr ? *btBounds : Rectangle<int> {});
if (! RuntimePermissions::isGranted (RuntimePermissions::bluetoothMidi)) if (! RuntimePermissions::isGranted (RuntimePermissions::bluetoothMidi))
{ {
@@ -475,7 +496,7 @@ bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback*
return false; return false;
} }
new BluetoothMidiSelectorOverlay (exitCallback.release());
new BluetoothMidiSelectorOverlay (exitCallback.release(), boundsToUse);
return true; return true;
} }


+ 31
- 12
libs/juce/source/modules/juce_audio_utils/native/juce_ios_BluetoothMidiDevicePairingDialogue.mm View File

@@ -40,15 +40,23 @@ namespace juce
class BluetoothMidiSelectorOverlay : public Component class BluetoothMidiSelectorOverlay : public Component
{ {
public: public:
BluetoothMidiSelectorOverlay (ModalComponentManager::Callback* exitCallbackToUse)
BluetoothMidiSelectorOverlay (ModalComponentManager::Callback* exitCallbackToUse,
const Rectangle<int>& boundsToUse)
: bounds (boundsToUse)
{ {
ScopedPointer<ModalComponentManager::Callback> exitCallback (exitCallbackToUse); ScopedPointer<ModalComponentManager::Callback> exitCallback (exitCallbackToUse);
setAlwaysOnTop (true); setAlwaysOnTop (true);
setVisible (true); setVisible (true);
addToDesktop (ComponentPeer::windowHasDropShadow); addToDesktop (ComponentPeer::windowHasDropShadow);
setBounds (0, 0, getParentWidth(), getParentHeight());
if (bounds.isEmpty())
setBounds (0, 0, getParentWidth(), getParentHeight());
else
setBounds (bounds);
toFront (true); toFront (true);
setOpaque (! bounds.isEmpty());
controller = [[CABTMIDICentralViewController alloc] init]; controller = [[CABTMIDICentralViewController alloc] init];
nativeSelectorComponent.setView ([controller view]); nativeSelectorComponent.setView ([controller view]);
@@ -66,7 +74,7 @@ public:
void paint (Graphics& g) override void paint (Graphics& g) override
{ {
g.fillAll (Colours::black.withAlpha (0.5f));
g.fillAll (bounds.isEmpty() ? Colours::black.withAlpha (0.5f) : Colours::black);
} }
void inputAttemptWhenModal() override { close(); } void inputAttemptWhenModal() override { close(); }
@@ -78,12 +86,19 @@ public:
private: private:
void update() void update()
{ {
const int pw = getParentWidth();
const int ph = getParentHeight();
nativeSelectorComponent.setBounds (Rectangle<int> (pw, ph)
.withSizeKeepingCentre (jmin (400, pw),
jmin (450, ph - 40)));
if (bounds.isEmpty())
{
const int pw = getParentWidth();
const int ph = getParentHeight();
nativeSelectorComponent.setBounds (Rectangle<int> (pw, ph)
.withSizeKeepingCentre (jmin (400, pw),
jmin (450, ph - 40)));
}
else
{
nativeSelectorComponent.setBounds (bounds.withZeroOrigin());
}
} }
void close() void close()
@@ -94,17 +109,20 @@ private:
CABTMIDICentralViewController* controller; CABTMIDICentralViewController* controller;
UIViewComponent nativeSelectorComponent; UIViewComponent nativeSelectorComponent;
Rectangle<int> bounds;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BluetoothMidiSelectorOverlay) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BluetoothMidiSelectorOverlay)
}; };
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback)
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback,
Rectangle<int>* btBounds)
{ {
ScopedPointer<ModalComponentManager::Callback> cb (exitCallback); ScopedPointer<ModalComponentManager::Callback> cb (exitCallback);
auto boundsToUse = (btBounds != nullptr ? *btBounds : Rectangle<int> {});
if (isAvailable()) if (isAvailable())
{ {
new BluetoothMidiSelectorOverlay (cb.release());
new BluetoothMidiSelectorOverlay (cb.release(), boundsToUse);
return true; return true;
} }
@@ -123,7 +141,8 @@ bool BluetoothMidiDevicePairingDialogue::isAvailable()
namespace juce namespace juce
{ {
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback)
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback,
Rectangle<int>*)
{ {
ScopedPointer<ModalComponentManager::Callback> cb (exitCallback); ScopedPointer<ModalComponentManager::Callback> cb (exitCallback);
return false; return false;


+ 2
- 1
libs/juce/source/modules/juce_audio_utils/native/juce_linux_BluetoothMidiDevicePairingDialogue.cpp View File

@@ -27,7 +27,8 @@
namespace juce namespace juce
{ {
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback)
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback,
Rectangle<int>*)
{ {
ScopedPointer<ModalComponentManager::Callback> cb (exitCallback); ScopedPointer<ModalComponentManager::Callback> cb (exitCallback);
// not implemented on Linux yet! // not implemented on Linux yet!


+ 2
- 1
libs/juce/source/modules/juce_audio_utils/native/juce_mac_BluetoothMidiDevicePairingDialogue.mm View File

@@ -27,7 +27,8 @@
namespace juce namespace juce
{ {
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback)
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback,
Rectangle<int>*)
{ {
ScopedPointer<ModalComponentManager::Callback> cb (exitCallback); ScopedPointer<ModalComponentManager::Callback> cb (exitCallback);
// Do not call this on OSX. Instead, you should pair Bluetooth MIDI devices // Do not call this on OSX. Instead, you should pair Bluetooth MIDI devices


+ 2
- 1
libs/juce/source/modules/juce_audio_utils/native/juce_win_BluetoothMidiDevicePairingDialogue.cpp View File

@@ -27,7 +27,8 @@
namespace juce namespace juce
{ {
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback)
bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback* exitCallback,
Rectangle<int>*)
{ {
ScopedPointer<ModalComponentManager::Callback> cb (exitCallback); ScopedPointer<ModalComponentManager::Callback> cb (exitCallback);
// not implemented on Windows yet! // not implemented on Windows yet!


+ 0
- 6
libs/juce/source/modules/juce_core/maths/juce_BigInteger.h View File

@@ -337,10 +337,4 @@ private:
/** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */ /** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */
OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value); OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value);
//==============================================================================
#ifndef DOXYGEN
// For backwards compatibility, BitArray is defined as an alias for BigInteger.
typedef BigInteger BitArray;
#endif
} // namespace juce } // namespace juce

+ 15
- 22
libs/juce/source/modules/juce_core/maths/juce_MathsFunctions.h View File

@@ -212,9 +212,9 @@ void findMinAndMax (const Type* values, int numValues, Type& lowest, Type& highe
@see jmin, jmax, jmap @see jmin, jmax, jmap
*/ */
template <typename Type> template <typename Type>
Type jlimit (const Type lowerLimit,
const Type upperLimit,
const Type valueToConstrain) noexcept
Type jlimit (Type lowerLimit,
Type upperLimit,
Type valueToConstrain) noexcept
{ {
jassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable.. jassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable..
@@ -228,15 +228,15 @@ Type jlimit (const Type lowerLimit,
@code valueToTest >= 0 && valueToTest < upperLimit @code valueToTest >= 0 && valueToTest < upperLimit
@endcode @endcode
*/ */
template <typename Type>
bool isPositiveAndBelow (Type valueToTest, Type upperLimit) noexcept
template <typename Type1, typename Type2>
bool isPositiveAndBelow (Type1 valueToTest, Type2 upperLimit) noexcept
{ {
jassert (Type() <= upperLimit); // makes no sense to call this if the upper limit is itself below zero..
return Type() <= valueToTest && valueToTest < upperLimit;
jassert (Type1() <= static_cast<Type1> (upperLimit)); // makes no sense to call this if the upper limit is itself below zero..
return Type1() <= valueToTest && valueToTest < static_cast<Type1> (upperLimit);
} }
template <>
inline bool isPositiveAndBelow (const int valueToTest, const int upperLimit) noexcept
template <typename Type>
bool isPositiveAndBelow (int valueToTest, Type upperLimit) noexcept
{ {
jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero.. jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
return static_cast<unsigned int> (valueToTest) < static_cast<unsigned int> (upperLimit); return static_cast<unsigned int> (valueToTest) < static_cast<unsigned int> (upperLimit);
@@ -247,28 +247,21 @@ inline bool isPositiveAndBelow (const int valueToTest, const int upperLimit) noe
@code valueToTest >= 0 && valueToTest <= upperLimit @code valueToTest >= 0 && valueToTest <= upperLimit
@endcode @endcode
*/ */
template <typename Type>
bool isPositiveAndNotGreaterThan (Type valueToTest, Type upperLimit) noexcept
template <typename Type1, typename Type2>
bool isPositiveAndNotGreaterThan (Type1 valueToTest, Type2 upperLimit) noexcept
{ {
jassert (Type() <= upperLimit); // makes no sense to call this if the upper limit is itself below zero..
return Type() <= valueToTest && valueToTest <= upperLimit;
jassert (Type1() <= static_cast<Type1> (upperLimit)); // makes no sense to call this if the upper limit is itself below zero..
return Type1() <= valueToTest && valueToTest <= static_cast<Type1> (upperLimit);
} }
template <>
inline bool isPositiveAndNotGreaterThan (const int valueToTest, const int upperLimit) noexcept
template <typename Type>
bool isPositiveAndNotGreaterThan (int valueToTest, Type upperLimit) noexcept
{ {
jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero.. jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
return static_cast<unsigned int> (valueToTest) <= static_cast<unsigned int> (upperLimit); return static_cast<unsigned int> (valueToTest) <= static_cast<unsigned int> (upperLimit);
} }
//============================================================================== //==============================================================================
/** Handy function to swap two values. */
template <typename Type>
void swapVariables (Type& variable1, Type& variable2)
{
std::swap (variable1, variable2);
}
/** Handy function for avoiding unused variables warning. */ /** Handy function for avoiding unused variables warning. */
template <typename Type1> template <typename Type1>
void ignoreUnused (const Type1&) noexcept {} void ignoreUnused (const Type1&) noexcept {}


+ 29
- 0
libs/juce/source/modules/juce_core/memory/juce_WeakReference.h View File

@@ -59,6 +59,8 @@ namespace juce
friend class WeakReference<MyObject>; friend class WeakReference<MyObject>;
}; };
OR: just use the handy JUCE_DECLARE_WEAK_REFERENCEABLE macro to do all this for you.
// Here's an example of using a pointer.. // Here's an example of using a pointer..
MyObject* n = new MyObject(); MyObject* n = new MyObject();
@@ -202,4 +204,31 @@ private:
} }
}; };
//==============================================================================
/**
Macro to easily allow a class to be made weak-referenceable.
This can be inserted in a class definition to add the requisite weak-ref boilerplate to that class.
e.g.
@code
class MyObject
{
public:
MyObject();
~MyObject();
private:
JUCE_DECLARE_WEAK_REFERENCEABLE (MyObject)
};
@endcode
@see WeakReference, WeakReference::Master
*/
#define JUCE_DECLARE_WEAK_REFERENCEABLE(Class) \
struct WeakRefMaster : public WeakReference<Class>::Master { ~WeakRefMaster() { this->clear(); } }; \
WeakRefMaster masterReference; \
friend class WeakReference<Class>; \
} // namespace juce } // namespace juce

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

@@ -566,6 +566,9 @@ public class JuceAppActivity extends Activity
@Override @Override
public void onDraw (Canvas canvas) public void onDraw (Canvas canvas)
{ {
if (host == 0)
return;
handlePaint (host, canvas, paint); handlePaint (host, canvas, paint);
} }
@@ -657,6 +660,9 @@ public class JuceAppActivity extends Activity
@Override @Override
public boolean onKeyDown (int keyCode, KeyEvent event) public boolean onKeyDown (int keyCode, KeyEvent event)
{ {
if (host == 0)
return false;
switch (keyCode) switch (keyCode)
{ {
case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_UP:
@@ -679,6 +685,9 @@ public class JuceAppActivity extends Activity
@Override @Override
public boolean onKeyUp (int keyCode, KeyEvent event) public boolean onKeyUp (int keyCode, KeyEvent event)
{ {
if (host == 0)
return false;
handleKeyUp (host, keyCode, event.getUnicodeChar()); handleKeyUp (host, keyCode, event.getUnicodeChar());
return true; return true;
} }
@@ -686,6 +695,9 @@ public class JuceAppActivity extends Activity
@Override @Override
public boolean onKeyMultiple (int keyCode, int count, KeyEvent event) public boolean onKeyMultiple (int keyCode, int count, KeyEvent event)
{ {
if (host == 0)
return false;
if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction() != KeyEvent.ACTION_MULTIPLE) if (keyCode != KeyEvent.KEYCODE_UNKNOWN || event.getAction() != KeyEvent.ACTION_MULTIPLE)
return super.onKeyMultiple (keyCode, count, event); return super.onKeyMultiple (keyCode, count, event);
@@ -718,6 +730,9 @@ public class JuceAppActivity extends Activity
@Override @Override
protected void onSizeChanged (int w, int h, int oldw, int oldh) protected void onSizeChanged (int w, int h, int oldw, int oldh)
{ {
if (host == 0)
return;
super.onSizeChanged (w, h, oldw, oldh); super.onSizeChanged (w, h, oldw, oldh);
viewSizeChanged (host); viewSizeChanged (host);
} }
@@ -734,6 +749,9 @@ public class JuceAppActivity extends Activity
@Override @Override
public void onFocusChange (View v, boolean hasFocus) public void onFocusChange (View v, boolean hasFocus)
{ {
if (host == 0)
return;
if (v == this) if (v == this)
focusChanged (host, hasFocus); focusChanged (host, hasFocus);
} }


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

@@ -407,7 +407,7 @@ int SystemStats::getMemorySizeInMegabytes()
struct sysinfo sysi; struct sysinfo sysi;
if (sysinfo (&sysi) == 0) if (sysinfo (&sysi) == 0)
return (static_cast<int> (sysi.totalram * sysi.mem_unit) / (1024 * 1024));
return static_cast<int> ((sysi.totalram * sysi.mem_unit) / (1024 * 1024));
#endif #endif
return 0; return 0;


+ 2
- 2
libs/juce/source/modules/juce_core/native/juce_linux_Files.cpp View File

@@ -136,14 +136,14 @@ File File::getSpecialLocation (const SpecialLocationType type)
case invokedExecutableFile: case invokedExecutableFile:
if (juce_argv != nullptr && juce_argc > 0) if (juce_argv != nullptr && juce_argc > 0)
return File (CharPointer_UTF8 (juce_argv[0])); return File (CharPointer_UTF8 (juce_argv[0]));
// deliberate fall-through...
// fall-through
case currentExecutableFile: case currentExecutableFile:
case currentApplicationFile: case currentApplicationFile:
#if ! JUCE_STANDALONE_APPLICATION #if ! JUCE_STANDALONE_APPLICATION
return juce_getExecutableFile(); return juce_getExecutableFile();
#endif #endif
// deliberate fall-through if this is not a shared-library
// fall-through
case hostApplicationPath: case hostApplicationPath:
{ {


+ 71
- 0
libs/juce/source/modules/juce_core/native/juce_osx_ObjCHelpers.h View File

@@ -202,6 +202,77 @@ private:
JUCE_DECLARE_NON_COPYABLE (ObjCClass) JUCE_DECLARE_NON_COPYABLE (ObjCClass)
}; };
//==============================================================================
#ifndef DOXYGEN
template <class JuceClass>
struct ObjCLifetimeManagedClass : public ObjCClass<NSObject>
{
ObjCLifetimeManagedClass()
: ObjCClass<NSObject> ("ObjCLifetimeManagedClass_")
{
addIvar<JuceClass*> ("cppObject");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
addMethod (@selector (initWithJuceObject:), initWithJuceObject, "@@:@");
#pragma clang diagnostic pop
addMethod (@selector (dealloc), dealloc, "v@:");
registerClass();
}
static id initWithJuceObject (id _self, SEL, JuceClass* obj)
{
NSObject* self = _self;
objc_super s = { self, [NSObject class] };
self = ObjCMsgSendSuper<NSObject*> (&s, @selector(init));
object_setInstanceVariable (self, "cppObject", obj);
return self;
}
static void dealloc (id _self, SEL)
{
if (auto* obj = getIvar<JuceClass*> (_self, "cppObject"))
{
delete obj;
object_setInstanceVariable (_self, "cppObject", nullptr);
}
objc_super s = { _self, [NSObject class] };
ObjCMsgSendSuper<void> (&s, @selector(dealloc));
}
static ObjCLifetimeManagedClass objCLifetimeManagedClass;
};
template <typename Class>
ObjCLifetimeManagedClass<Class> ObjCLifetimeManagedClass<Class>::objCLifetimeManagedClass;
#endif
// this will return an NSObject which takes ownership of the JUCE instance passed-in
// This is useful to tie the life-time of a juce instance to the life-time of an NSObject
template <typename Class>
NSObject* createNSObjectFromJuceClass (Class* obj)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-method-access"
return [ObjCLifetimeManagedClass<Class>::objCLifetimeManagedClass.createInstance() initWithJuceObject:obj];
#pragma clang diagnostic pop
}
// Get the JUCE class instance that was tied to the life-time of an NSObject with the
// function above
template <typename Class>
Class* getJuceClassFromNSObject (NSObject* obj)
{
return obj != nullptr ? ObjCLifetimeManagedClass<Class>:: template getIvar<Class*> (obj, "cppObject") : nullptr;
}
#if JUCE_COMPILER_SUPPORTS_VARIADIC_TEMPLATES #if JUCE_COMPILER_SUPPORTS_VARIADIC_TEMPLATES
template <typename ReturnT, class Class, typename... Params> template <typename ReturnT, class Class, typename... Params>


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

@@ -1205,6 +1205,8 @@ public:
close (pipeHandles[1]); // close the write handle close (pipeHandles[1]); // close the write handle
} }
} }
ignoreUnused (streamFlags);
} }
~ActiveProcess() ~ActiveProcess()


+ 26
- 28
libs/juce/source/modules/juce_core/network/juce_URL.cpp View File

@@ -130,7 +130,7 @@ URL::DownloadTask* URL::DownloadTask::createFallbackDownloader (const URL& urlTo
return nullptr; return nullptr;
} }
URL::DownloadTask::DownloadTask() : contentLength (-1), downloaded (0), finished (false), error (false), httpCode (-1) {}
URL::DownloadTask::DownloadTask() {}
URL::DownloadTask::~DownloadTask() {} URL::DownloadTask::~DownloadTask() {}
//============================================================================== //==============================================================================
@@ -250,6 +250,7 @@ namespace URLHelpers
static int findStartOfNetLocation (const String& url) static int findStartOfNetLocation (const String& url)
{ {
int start = findEndOfScheme (url); int start = findEndOfScheme (url);
while (url[start] == '/') while (url[start] == '/')
++start; ++start;
@@ -305,8 +306,8 @@ String URL::getDomain() const
const int end2 = url.indexOfChar (start, ':'); const int end2 = url.indexOfChar (start, ':');
const int end = (end1 < 0 && end2 < 0) ? std::numeric_limits<int>::max() const int end = (end1 < 0 && end2 < 0) ? std::numeric_limits<int>::max()
: ((end1 < 0 || end2 < 0) ? jmax (end1, end2)
: jmin (end1, end2));
: ((end1 < 0 || end2 < 0) ? jmax (end1, end2)
: jmin (end1, end2));
return url.substring (start, end); return url.substring (start, end);
} }
@@ -325,7 +326,7 @@ String URL::getScheme() const
int URL::getPort() const int URL::getPort() const
{ {
const int colonPos = url.indexOfChar (URLHelpers::findStartOfNetLocation (url), ':');
auto colonPos = url.indexOfChar (URLHelpers::findStartOfNetLocation (url), ':');
return colonPos > 0 ? url.substring (colonPos + 1).getIntValue() : 0; return colonPos > 0 ? url.substring (colonPos + 1).getIntValue() : 0;
} }
@@ -366,7 +367,7 @@ void URL::createHeadersAndPostData (String& headers, MemoryBlock& postDataToWrit
// (this doesn't currently support mixing custom post-data with uploads..) // (this doesn't currently support mixing custom post-data with uploads..)
jassert (postData.getSize() == 0); jassert (postData.getSize() == 0);
const String boundary (String::toHexString (Random::getSystemRandom().nextInt64()));
auto boundary = String::toHexString (Random::getSystemRandom().nextInt64());
headers << "Content-Type: multipart/form-data; boundary=" << boundary << "\r\n"; headers << "Content-Type: multipart/form-data; boundary=" << boundary << "\r\n";
@@ -379,22 +380,20 @@ void URL::createHeadersAndPostData (String& headers, MemoryBlock& postDataToWrit
<< "\r\n--" << boundary; << "\r\n--" << boundary;
} }
for (int i = 0; i < filesToUpload.size(); ++i)
for (auto* f : filesToUpload)
{ {
const Upload& f = *filesToUpload.getObjectPointerUnchecked(i);
data << "\r\nContent-Disposition: form-data; name=\"" << f.parameterName
<< "\"; filename=\"" << f.filename << "\"\r\n";
data << "\r\nContent-Disposition: form-data; name=\"" << f->parameterName
<< "\"; filename=\"" << f->filename << "\"\r\n";
if (f.mimeType.isNotEmpty())
data << "Content-Type: " << f.mimeType << "\r\n";
if (f->mimeType.isNotEmpty())
data << "Content-Type: " << f->mimeType << "\r\n";
data << "Content-Transfer-Encoding: binary\r\n\r\n"; data << "Content-Transfer-Encoding: binary\r\n\r\n";
if (f.data != nullptr)
data << *f.data;
if (f->data != nullptr)
data << *f->data;
else else
data << f.file;
data << f->file;
data << "\r\n--" << boundary; data << "\r\n--" << boundary;
} }
@@ -419,8 +418,8 @@ bool URL::isProbablyAWebsiteURL (const String& possibleURL)
{ {
static const char* validProtocols[] = { "http:", "ftp:", "https:" }; static const char* validProtocols[] = { "http:", "ftp:", "https:" };
for (int i = 0; i < numElementsInArray (validProtocols); ++i)
if (possibleURL.startsWithIgnoreCase (validProtocols[i]))
for (auto* protocol : validProtocols)
if (possibleURL.startsWithIgnoreCase (protocol))
return true; return true;
if (possibleURL.containsChar ('@') if (possibleURL.containsChar ('@')
@@ -435,7 +434,7 @@ bool URL::isProbablyAWebsiteURL (const String& possibleURL)
bool URL::isProbablyAnEmailAddress (const String& possibleEmailAddress) bool URL::isProbablyAnEmailAddress (const String& possibleEmailAddress)
{ {
const int atSign = possibleEmailAddress.indexOfChar ('@');
auto atSign = possibleEmailAddress.indexOfChar ('@');
return atSign > 0 return atSign > 0
&& possibleEmailAddress.lastIndexOfChar ('.') > (atSign + 1) && possibleEmailAddress.lastIndexOfChar ('.') > (atSign + 1)
@@ -504,8 +503,7 @@ WebInputStream* URL::createInputStream (const bool usePostCommand,
} }
//============================================================================== //==============================================================================
bool URL::readEntireBinaryStream (MemoryBlock& destData,
const bool usePostCommand) const
bool URL::readEntireBinaryStream (MemoryBlock& destData, bool usePostCommand) const
{ {
const ScopedPointer<InputStream> in (createInputStream (usePostCommand)); const ScopedPointer<InputStream> in (createInputStream (usePostCommand));
@@ -518,7 +516,7 @@ bool URL::readEntireBinaryStream (MemoryBlock& destData,
return false; return false;
} }
String URL::readEntireTextStream (const bool usePostCommand) const
String URL::readEntireTextStream (bool usePostCommand) const
{ {
const ScopedPointer<InputStream> in (createInputStream (usePostCommand)); const ScopedPointer<InputStream> in (createInputStream (usePostCommand));
@@ -528,7 +526,7 @@ String URL::readEntireTextStream (const bool usePostCommand) const
return {}; return {};
} }
XmlElement* URL::readEntireXmlStream (const bool usePostCommand) const
XmlElement* URL::readEntireXmlStream (bool usePostCommand) const
{ {
return XmlDocument::parse (readEntireTextStream (usePostCommand)); return XmlDocument::parse (readEntireTextStream (usePostCommand));
} }
@@ -601,7 +599,7 @@ URL URL::withDataToUpload (const String& parameterName, const String& filename,
//============================================================================== //==============================================================================
String URL::removeEscapeChars (const String& s) String URL::removeEscapeChars (const String& s)
{ {
String result (s.replaceCharacter ('+', ' '));
auto result = s.replaceCharacter ('+', ' ');
if (! result.containsChar ('%')) if (! result.containsChar ('%'))
return result; return result;
@@ -628,9 +626,9 @@ String URL::removeEscapeChars (const String& s)
return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size()); return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size());
} }
String URL::addEscapeChars (const String& s, const bool isParameter, bool roundBracketsAreLegal)
String URL::addEscapeChars (const String& s, bool isParameter, bool roundBracketsAreLegal)
{ {
String legalChars (isParameter ? "_-.*!'"
String legalChars (isParameter ? "_-.~"
: ",$_-.*!'"); : ",$_-.*!'");
if (roundBracketsAreLegal) if (roundBracketsAreLegal)
@@ -640,7 +638,7 @@ String URL::addEscapeChars (const String& s, const bool isParameter, bool roundB
for (int i = 0; i < utf8.size(); ++i) for (int i = 0; i < utf8.size(); ++i)
{ {
const char c = utf8.getUnchecked(i);
auto c = utf8.getUnchecked(i);
if (! (CharacterFunctions::isLetterOrDigit (c) if (! (CharacterFunctions::isLetterOrDigit (c)
|| legalChars.containsChar ((juce_wchar) c))) || legalChars.containsChar ((juce_wchar) c)))
@@ -657,12 +655,12 @@ String URL::addEscapeChars (const String& s, const bool isParameter, bool roundB
//============================================================================== //==============================================================================
bool URL::launchInDefaultBrowser() const bool URL::launchInDefaultBrowser() const
{ {
String u (toString (true));
auto u = toString (true);
if (u.containsChar ('@') && ! u.containsChar (':')) if (u.containsChar ('@') && ! u.containsChar (':'))
u = "mailto:" + u; u = "mailto:" + u;
return Process::openDocument (u, String());
return Process::openDocument (u, {});
} }
} // namespace juce } // namespace juce

+ 12
- 24
libs/juce/source/modules/juce_core/network/juce_URL.h View File

@@ -47,13 +47,13 @@ public:
URL (const String& url); URL (const String& url);
/** Creates a copy of another URL. */ /** Creates a copy of another URL. */
URL (const URL& other);
URL (const URL&);
/** Destructor. */ /** Destructor. */
~URL(); ~URL();
/** Copies this URL from another one. */ /** Copies this URL from another one. */
URL& operator= (const URL& other);
URL& operator= (const URL&);
/** Compares two URLs. /** Compares two URLs.
All aspects of the URLs must be identical for them to match, including any parameters, All aspects of the URLs must be identical for them to match, including any parameters,
@@ -78,19 +78,16 @@ public:
bool isWellFormed() const; bool isWellFormed() const;
/** Returns just the domain part of the URL. /** Returns just the domain part of the URL.
E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com". E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com".
*/ */
String getDomain() const; String getDomain() const;
/** Returns the path part of the URL. /** Returns the path part of the URL.
E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar". E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar".
*/ */
String getSubPath() const; String getSubPath() const;
/** Returns the scheme of the URL. /** Returns the scheme of the URL.
E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't
include the colon). include the colon).
*/ */
@@ -102,7 +99,6 @@ public:
int getPort() const; int getPort() const;
/** Returns a new version of this URL with a different domain and path. /** Returns a new version of this URL with a different domain and path.
E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
"abc.com/zzz", it'll return "http://abc.com/zzz?x=1". "abc.com/zzz", it'll return "http://abc.com/zzz?x=1".
@see withNewSubPath @see withNewSubPath
@@ -110,7 +106,6 @@ public:
URL withNewDomainAndPath (const String& newFullPath) const; URL withNewDomainAndPath (const String& newFullPath) const;
/** Returns a new version of this URL with a different sub-path. /** Returns a new version of this URL with a different sub-path.
E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
"bar", it'll return "http://www.xyz.com/bar?x=1". "bar", it'll return "http://www.xyz.com/bar?x=1".
@see withNewDomainAndPath @see withNewDomainAndPath
@@ -118,7 +113,6 @@ public:
URL withNewSubPath (const String& newPath) const; URL withNewSubPath (const String& newPath) const;
/** Returns a new URL that refers to a sub-path relative to this one. /** Returns a new URL that refers to a sub-path relative to this one.
E.g. if the URL is "http://www.xyz.com/foo" and you call this with E.g. if the URL is "http://www.xyz.com/foo" and you call this with
"bar", it'll return "http://www.xyz.com/foo/bar". Note that there's no way for "bar", it'll return "http://www.xyz.com/foo/bar". Note that there's no way for
this method to know whether the original URL is a file or directory, so it's this method to know whether the original URL is a file or directory, so it's
@@ -134,7 +128,6 @@ public:
/** Returns a copy of this URL, with a GET or POST parameter added to the end. /** Returns a copy of this URL, with a GET or POST parameter added to the end.
Any control characters in the value will be encoded. Any control characters in the value will be encoded.
e.g. calling "withParameter ("amount", "some fish") for the url "www.fish.com" e.g. calling "withParameter ("amount", "some fish") for the url "www.fish.com"
would produce a new url whose toString(true) method would return would produce a new url whose toString(true) method would return
"www.fish.com?amount=some+fish". "www.fish.com?amount=some+fish".
@@ -241,20 +234,17 @@ public:
//============================================================================== //==============================================================================
/** Tries to launch the system's default browser to open the URL. /** Tries to launch the system's default browser to open the URL.
Returns true if this seems to have worked. Returns true if this seems to have worked.
*/ */
bool launchInDefaultBrowser() const; bool launchInDefaultBrowser() const;
//============================================================================== //==============================================================================
/** Takes a guess as to whether a string might be a valid website address. /** Takes a guess as to whether a string might be a valid website address.
This isn't foolproof! This isn't foolproof!
*/ */
static bool isProbablyAWebsiteURL (const String& possibleURL); static bool isProbablyAWebsiteURL (const String& possibleURL);
/** Takes a guess as to whether a string might be a valid email address. /** Takes a guess as to whether a string might be a valid email address.
This isn't foolproof! This isn't foolproof!
*/ */
static bool isProbablyAnEmailAddress (const String& possibleEmailAddress); static bool isProbablyAnEmailAddress (const String& possibleEmailAddress);
@@ -319,7 +309,6 @@ public:
//============================================================================== //==============================================================================
/** Represents a download task. /** Represents a download task.
Returned by downloadToFile to allow querying and controling the download task. Returned by downloadToFile to allow querying and controling the download task.
*/ */
class DownloadTask class DownloadTask
@@ -346,34 +335,32 @@ public:
/** Returns the total length of the download task. This may return -1 if the length /** Returns the total length of the download task. This may return -1 if the length
was not returned by the server. */ was not returned by the server. */
inline int64 getTotalLength() const { return contentLength; }
int64 getTotalLength() const { return contentLength; }
/** Returns the number of bytes that have been downloaded so far. */ /** Returns the number of bytes that have been downloaded so far. */
inline int64 getLengthDownloaded() const { return downloaded; }
int64 getLengthDownloaded() const { return downloaded; }
/** Returns true if the download finished or there was an error. */ /** Returns true if the download finished or there was an error. */
inline bool isFinished() const { return finished; }
/** Returns the status code of the server's response. This will only be valid
after the download has finished.
bool isFinished() const { return finished; }
/** Returns the status code of the server's response.
This will only be valid after the download has finished.
@see isFinished @see isFinished
*/ */
inline int statusCode() const { return httpCode; }
int statusCode() const { return httpCode; }
/** Returns true if there was an error. */ /** Returns true if there was an error. */
inline bool hadError() const { return error; } inline bool hadError() const { return error; }
protected: protected:
int64 contentLength, downloaded;
bool finished, error;
int httpCode;
int64 contentLength = -1, downloaded = 0;
bool finished = false, error = false;
int httpCode = -1;
DownloadTask(); DownloadTask();
private: private:
friend class URL; friend class URL;
static DownloadTask* createFallbackDownloader (const URL&, const File&, const String&, Listener*, bool); static DownloadTask* createFallbackDownloader (const URL&, const File&, const String&, Listener*, bool);
public: public:
@@ -381,6 +368,7 @@ public:
/** internal **/ /** internal **/
static void juce_iosURLSessionNotify (const String&); static void juce_iosURLSessionNotify (const String&);
#endif #endif
private: private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadTask) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadTask)
}; };


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

@@ -114,11 +114,6 @@
#include "../misc/juce_StdFunctionCompat.h" #include "../misc/juce_StdFunctionCompat.h"
#endif #endif
// The live build fails to compile std::stringstream
#if ! JUCE_PROJUCER_LIVE_BUILD
#include <sstream>
#endif
// Include std::atomic if it's supported by the compiler // Include std::atomic if it's supported by the compiler
#if JUCE_ATOMIC_AVAILABLE #if JUCE_ATOMIC_AVAILABLE
#include <atomic> #include <atomic>


+ 3
- 2
libs/juce/source/modules/juce_core/text/juce_CharacterFunctions.cpp View File

@@ -241,12 +241,13 @@ public:
STRING_DOUBLE_PAIR_COMBOS (2087.3087e+00006), STRING_DOUBLE_PAIR_COMBOS (2087.3087e+00006),
STRING_DOUBLE_PAIR_COMBOS (6.0872e-00006), STRING_DOUBLE_PAIR_COMBOS (6.0872e-00006),
// Too many sig figs
// Too many sig figs. The parsing routine on MinGW gets the last
// significant figure wrong.
STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890), STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890),
STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890e-111) STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890e-111)
// Limits. DBL_MAX may not exist on Linux.
#if ! JUCE_LINUX #if ! JUCE_LINUX
// Limits
, STRING_DOUBLE_PAIR (DBL_MAX), , STRING_DOUBLE_PAIR (DBL_MAX),
STRING_DOUBLE_PAIR (-DBL_MAX), STRING_DOUBLE_PAIR (-DBL_MAX),
STRING_DOUBLE_PAIR (DBL_MIN) STRING_DOUBLE_PAIR (DBL_MIN)


+ 138
- 22
libs/juce/source/modules/juce_core/text/juce_CharacterFunctions.h View File

@@ -61,7 +61,7 @@ namespace juce
#endif #endif
//============================================================================== //==============================================================================
/** GNU libstdc++ does not have std::make_unsigned */
// GNU libstdc++ does not have std::make_unsigned
namespace internal namespace internal
{ {
template <typename Type> struct make_unsigned { typedef Type type; }; template <typename Type> struct make_unsigned { typedef Type type; };
@@ -140,20 +140,29 @@ public:
template <typename CharPointerType> template <typename CharPointerType>
static double readDoubleValue (CharPointerType& text) noexcept static double readDoubleValue (CharPointerType& text) noexcept
{ {
const int maxSignificantDigits = 17 + 1; // An additional digit for rounding
const int bufferSize = maxSignificantDigits + 7 + 1; // -.E-XXX and a trailing null-terminator
#if JUCE_MINGW
bool isNegative = false;
#else
JUCE_CONSTEXPR const int maxSignificantDigits = 17 + 1; // An additional digit for rounding
JUCE_CONSTEXPR const int bufferSize = maxSignificantDigits + 7 + 1; // -.E-XXX and a trailing null-terminator
char buffer[bufferSize] = {}; char buffer[bufferSize] = {};
char* currentCharacter = &(buffer[0]); char* currentCharacter = &(buffer[0]);
int numSigFigs = 0;
bool decimalPointFound = false;
#endif
text = text.findEndOfWhitespace(); text = text.findEndOfWhitespace();
auto c = *text; auto c = *text;
switch (c) switch (c)
{ {
case '-': *currentCharacter++ = '-'; // Fall-through..
case '+': c = *++text;
case '-':
#if JUCE_MINGW
isNegative = true;
#else
*currentCharacter++ = '-';
#endif
// Fall-through..
case '+':
c = *++text;
} }
switch (c) switch (c)
@@ -171,11 +180,121 @@ public:
break; break;
} }
#if JUCE_MINGW
// MinGW does not have access to the locale functions required for strtold, so we parse the doubles
// ourselves. There are some edge cases where the least significant digit will be wrong!
double result[3] = { 0 }, accumulator[2] = { 0 };
int exponentAdjustment[2] = { 0 }, exponentAccumulator[2] = { -1, -1 };
int exponent = 0, decPointIndex = 0, digit = 0;
int lastDigit = 0, numSignificantDigits = 0;
bool digitsFound = false;
JUCE_CONSTEXPR const int maxSignificantDigits = 17 + 1;
for (;;)
{
if (text.isDigit())
{
lastDigit = digit;
digit = (int) text.getAndAdvance() - '0';
digitsFound = true;
if (decPointIndex != 0)
exponentAdjustment[1]++;
if (numSignificantDigits == 0 && digit == 0)
continue;
if (++numSignificantDigits > maxSignificantDigits)
{
if (digit > 5)
++accumulator [decPointIndex];
else if (digit == 5 && (lastDigit & 1) != 0)
++accumulator [decPointIndex];
if (decPointIndex > 0)
exponentAdjustment[1]--;
else
exponentAdjustment[0]++;
while (text.isDigit())
{
++text;
if (decPointIndex == 0)
exponentAdjustment[0]++;
}
}
else
{
const auto maxAccumulatorValue = (double) ((std::numeric_limits<unsigned int>::max() - 9) / 10);
if (accumulator [decPointIndex] > maxAccumulatorValue)
{
result [decPointIndex] = mulexp10 (result [decPointIndex], exponentAccumulator [decPointIndex])
+ accumulator [decPointIndex];
accumulator [decPointIndex] = 0;
exponentAccumulator [decPointIndex] = 0;
}
accumulator [decPointIndex] = accumulator[decPointIndex] * 10 + digit;
exponentAccumulator [decPointIndex]++;
}
}
else if (decPointIndex == 0 && *text == '.')
{
++text;
decPointIndex = 1;
if (numSignificantDigits > maxSignificantDigits)
{
while (text.isDigit())
++text;
break;
}
}
else
{
break;
}
}
result[0] = mulexp10 (result[0], exponentAccumulator[0]) + accumulator[0];
if (decPointIndex != 0)
result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1];
c = *text;
if ((c == 'e' || c == 'E') && digitsFound)
{
auto negativeExponent = false;
switch (*++text)
{
case '-': negativeExponent = true; // fall-through..
case '+': ++text;
}
while (text.isDigit())
exponent = (exponent * 10) + ((int) text.getAndAdvance() - '0');
if (negativeExponent)
exponent = -exponent;
}
auto r = mulexp10 (result[0], exponent + exponentAdjustment[0]);
if (decPointIndex != 0)
r += mulexp10 (result[1], exponent - exponentAdjustment[1]);
return isNegative ? -r : r;
#else // ! JUCE_MINGW
int numSigFigs = 0;
bool decimalPointFound = false;
for (;;) for (;;)
{ {
if (text.isDigit()) if (text.isDigit())
{ {
int digit = (int) text.getAndAdvance() - '0';
auto digit = (int) text.getAndAdvance() - '0';
if (numSigFigs >= maxSignificantDigits if (numSigFigs >= maxSignificantDigits
|| ((numSigFigs == 0 && (! decimalPointFound)) && digit == 0)) || ((numSigFigs == 0 && (! decimalPointFound)) && digit == 0))
@@ -231,22 +350,19 @@ public:
*currentCharacter++ = '0'; *currentCharacter++ = '0';
} }
#if JUCE_PROJUCER_LIVE_BUILD
// This will change with locale!
return strtod (&buffer[0], nullptr);
#if JUCE_WINDOWS
static _locale_t locale = _create_locale (LC_ALL, "C");
return _strtod_l (&buffer[0], nullptr, locale);
#else #else
double result = 0;
const size_t stringSize = (size_t) (currentCharacter - &buffer[0]) + 1;
if (stringSize > 1)
{
std::istringstream is (std::string (&buffer[0], stringSize));
is.imbue (std::locale ("C"));
is >> result;
}
return result;
static locale_t locale = newlocale (LC_ALL_MASK, "C", nullptr);
#if JUCE_ANDROID
return (double) strtold_l (&buffer[0], nullptr, locale);
#else
return strtod_l (&buffer[0], nullptr, locale);
#endif
#endif #endif
#endif // JUCE_MINGW
} }
/** Parses a character string, to read a floating-point value. */ /** Parses a character string, to read a floating-point value. */


+ 1
- 1
libs/juce/source/modules/juce_core/xml/juce_XmlElement.cpp View File

@@ -241,7 +241,7 @@ namespace XmlOutputFunctions
outputStream << (char) character; outputStream << (char) character;
break; break;
} }
// Note: deliberate fall-through here!
// fall-through
default: default:
outputStream << "&#" << ((int) character) << ';'; outputStream << "&#" << ((int) character) << ';';
break; break;


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

@@ -92,7 +92,7 @@ private:
{ {
case Z_STREAM_END: case Z_STREAM_END:
finished = true; finished = true;
// Deliberate fall-through..
// fall-through..
case Z_OK: case Z_OK:
{ {
data += dataSize - stream.avail_in; data += dataSize - stream.avail_in;


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

@@ -39,6 +39,9 @@ namespace zlibNamespace
#if __has_warning("-Wcomma") #if __has_warning("-Wcomma")
#pragma clang diagnostic ignored "-Wcomma" #pragma clang diagnostic ignored "-Wcomma"
#endif #endif
#elif JUCE_GCC && (__GNUC__ >= 7)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif #endif
#undef OS_CODE #undef OS_CODE
@@ -74,6 +77,8 @@ namespace zlibNamespace
#if JUCE_CLANG #if JUCE_CLANG
#pragma clang diagnostic pop #pragma clang diagnostic pop
#elif JUCE_GCC && (__GNUC__ >= 7)
#pragma GCC diagnostic pop
#endif #endif
#else #else
#include JUCE_ZLIB_INCLUDE_PATH #include JUCE_ZLIB_INCLUDE_PATH
@@ -136,7 +141,7 @@ public:
{ {
case Z_STREAM_END: case Z_STREAM_END:
finished = true; finished = true;
// deliberate fall-through
// fall-through
case Z_OK: case Z_OK:
data += dataSize - stream.avail_in; data += dataSize - stream.avail_in;
dataSize = (z_uInt) stream.avail_in; dataSize = (z_uInt) stream.avail_in;


+ 0
- 2
libs/juce/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp View File

@@ -59,8 +59,6 @@ ActionBroadcaster::~ActionBroadcaster()
{ {
// all event-based objects must be deleted BEFORE juce is shut down! // all event-based objects must be deleted BEFORE juce is shut down!
jassert (MessageManager::getInstanceWithoutCreating() != nullptr); jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
masterReference.clear();
} }
void ActionBroadcaster::addActionListener (ActionListener* const listener) void ActionBroadcaster::addActionListener (ActionListener* const listener)


+ 1
- 3
libs/juce/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.h View File

@@ -64,15 +64,13 @@ public:
private: private:
//============================================================================== //==============================================================================
friend class WeakReference<ActionBroadcaster>;
WeakReference<ActionBroadcaster>::Master masterReference;
class ActionMessage; class ActionMessage;
friend class ActionMessage; friend class ActionMessage;
SortedSet<ActionListener*> actionListeners; SortedSet<ActionListener*> actionListeners;
CriticalSection actionListenerLock; CriticalSection actionListenerLock;
JUCE_DECLARE_WEAK_REFERENCEABLE (ActionBroadcaster)
JUCE_DECLARE_NON_COPYABLE (ActionBroadcaster) JUCE_DECLARE_NON_COPYABLE (ActionBroadcaster)
}; };


+ 6
- 12
libs/juce/source/modules/juce_events/interprocess/juce_InterprocessConnection.cpp View File

@@ -26,22 +26,16 @@ namespace juce
struct InterprocessConnection::ConnectionThread : public Thread struct InterprocessConnection::ConnectionThread : public Thread
{ {
ConnectionThread (InterprocessConnection& c) : Thread ("JUCE IPC"), owner (c) {} ConnectionThread (InterprocessConnection& c) : Thread ("JUCE IPC"), owner (c) {}
void run() override { owner.runThread(); } void run() override { owner.runThread(); }
private:
InterprocessConnection& owner; InterprocessConnection& owner;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectionThread) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConnectionThread)
}; };
//============================================================================== //==============================================================================
InterprocessConnection::InterprocessConnection (const bool callbacksOnMessageThread,
const uint32 magicMessageHeaderNumber)
: callbackConnectionState (false),
useMessageThread (callbacksOnMessageThread),
magicMessageHeader (magicMessageHeaderNumber),
pipeReceiveMessageTimeout (-1)
InterprocessConnection::InterprocessConnection (bool callbacksOnMessageThread, uint32 magicMessageHeaderNumber)
: useMessageThread (callbacksOnMessageThread),
magicMessageHeader (magicMessageHeaderNumber)
{ {
thread = new ConnectionThread (*this); thread = new ConnectionThread (*this);
} }
@@ -207,7 +201,7 @@ struct ConnectionStateMessage : public MessageManager::MessageBase
void messageCallback() override void messageCallback() override
{ {
if (InterprocessConnection* const ipc = owner)
if (auto* ipc = owner.get())
{ {
if (connectionMade) if (connectionMade)
ipc->connectionMade(); ipc->connectionMade();
@@ -256,7 +250,7 @@ struct DataDeliveryMessage : public Message
void messageCallback() override void messageCallback() override
{ {
if (InterprocessConnection* const ipc = owner)
if (auto* ipc = owner.get())
ipc->messageReceived (data); ipc->messageReceived (data);
} }
@@ -331,7 +325,7 @@ void InterprocessConnection::runThread()
{ {
if (socket != nullptr) if (socket != nullptr)
{ {
const int ready = socket->waitUntilReady (true, 0);
auto ready = socket->waitUntilReady (true, 0);
if (ready < 0) if (ready < 0)
{ {


+ 3
- 4
libs/juce/source/modules/juce_events/interprocess/juce_InterprocessConnection.h View File

@@ -176,15 +176,13 @@ public:
private: private:
//============================================================================== //==============================================================================
WeakReference<InterprocessConnection>::Master masterReference;
friend class WeakReference<InterprocessConnection>;
CriticalSection pipeAndSocketLock; CriticalSection pipeAndSocketLock;
ScopedPointer<StreamingSocket> socket; ScopedPointer<StreamingSocket> socket;
ScopedPointer<NamedPipe> pipe; ScopedPointer<NamedPipe> pipe;
bool callbackConnectionState;
bool callbackConnectionState = false;
const bool useMessageThread; const bool useMessageThread;
const uint32 magicMessageHeader; const uint32 magicMessageHeader;
int pipeReceiveMessageTimeout;
int pipeReceiveMessageTimeout = -1;
friend class InterprocessConnectionServer; friend class InterprocessConnectionServer;
void initialiseWithSocket (StreamingSocket*); void initialiseWithSocket (StreamingSocket*);
@@ -202,6 +200,7 @@ private:
void runThread(); void runThread();
int writeData (void*, int); int writeData (void*, int);
JUCE_DECLARE_WEAK_REFERENCEABLE (InterprocessConnection)
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InterprocessConnection) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InterprocessConnection)
}; };


+ 2
- 2
libs/juce/source/modules/juce_graphics/fonts/juce_CustomTypeface.cpp View File

@@ -186,7 +186,7 @@ void CustomTypeface::addGlyph (const juce_wchar character, const Path& path, con
// Check that you're not trying to add the same character twice.. // Check that you're not trying to add the same character twice..
jassert (findGlyph (character, false) == nullptr); jassert (findGlyph (character, false) == nullptr);
if (isPositiveAndBelow ((int) character, (int) numElementsInArray (lookupTable)))
if (isPositiveAndBelow ((int) character, numElementsInArray (lookupTable)))
lookupTable [character] = (short) glyphs.size(); lookupTable [character] = (short) glyphs.size();
glyphs.add (new GlyphInfo (character, path, width)); glyphs.add (new GlyphInfo (character, path, width));
@@ -205,7 +205,7 @@ void CustomTypeface::addKerningPair (const juce_wchar char1, const juce_wchar ch
CustomTypeface::GlyphInfo* CustomTypeface::findGlyph (const juce_wchar character, const bool loadIfNeeded) noexcept CustomTypeface::GlyphInfo* CustomTypeface::findGlyph (const juce_wchar character, const bool loadIfNeeded) noexcept
{ {
if (isPositiveAndBelow ((int) character, (int) numElementsInArray (lookupTable)) && lookupTable [character] > 0)
if (isPositiveAndBelow ((int) character, numElementsInArray (lookupTable)) && lookupTable [character] > 0)
return glyphs [(int) lookupTable [(int) character]]; return glyphs [(int) lookupTable [(int) character]];
for (int i = 0; i < glyphs.size(); ++i) for (int i = 0; i < glyphs.size(); ++i)


+ 24
- 22
libs/juce/source/modules/juce_graphics/fonts/juce_TextLayout.cpp View File

@@ -122,8 +122,8 @@ Range<float> TextLayout::Line::getLineBoundsX() const noexcept
Range<float> TextLayout::Line::getLineBoundsY() const noexcept Range<float> TextLayout::Line::getLineBoundsY() const noexcept
{ {
return Range<float> (lineOrigin.y - ascent,
lineOrigin.y + descent);
return { lineOrigin.y - ascent,
lineOrigin.y + descent };
} }
Rectangle<float> TextLayout::Line::getLineBounds() const noexcept Rectangle<float> TextLayout::Line::getLineBounds() const noexcept
@@ -223,7 +223,8 @@ void TextLayout::draw (Graphics& g, Rectangle<float> area) const
: runExtent.getUnionWith (glyphRange); : runExtent.getUnionWith (glyphRange);
} }
const float lineThickness = run->font.getDescent() * 0.3f;
auto lineThickness = run->font.getDescent() * 0.3f;
context.fillRect ({ runExtent.getStart() + lineOrigin.x, lineOrigin.y + lineThickness * 2.0f, context.fillRect ({ runExtent.getStart() + lineOrigin.x, lineOrigin.y + lineThickness * 2.0f,
runExtent.getLength(), lineThickness }); runExtent.getLength(), lineThickness });
} }
@@ -256,8 +257,8 @@ void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& te
void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& text, float maxWidth, float maxHeight) void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& text, float maxWidth, float maxHeight)
{ {
const float minimumWidth = maxWidth / 2.0f;
float bestWidth = maxWidth;
auto minimumWidth = maxWidth / 2.0f;
auto bestWidth = maxWidth;
float bestLineProportion = 0.0f; float bestLineProportion = 0.0f;
while (maxWidth > minimumWidth) while (maxWidth > minimumWidth)
@@ -267,12 +268,13 @@ void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& te
if (getNumLines() < 2) if (getNumLines() < 2)
return; return;
const float line1 = lines.getUnchecked (lines.size() - 1)->getLineBoundsX().getLength();
const float line2 = lines.getUnchecked (lines.size() - 2)->getLineBoundsX().getLength();
const float shortestLine = jmin (line1, line2);
const float prop = (shortestLine > 0) ? jmax (line1, line2) / shortestLine : 1.0f;
auto line1 = lines.getUnchecked (lines.size() - 1)->getLineBoundsX().getLength();
auto line2 = lines.getUnchecked (lines.size() - 2)->getLineBoundsX().getLength();
auto shortest = jmin (line1, line2);
auto longest = jmax (line1, line2);
auto prop = shortest > 0 ? longest / shortest : 1.0f;
if (prop > 0.9f)
if (prop > 0.9f && prop < 1.1f)
return; return;
if (prop > bestLineProportion) if (prop > bestLineProportion)
@@ -308,8 +310,7 @@ namespace TextLayoutHelpers
float lineHeight; float lineHeight;
const bool isWhitespace, isNewLine; const bool isWhitespace, isNewLine;
private:
Token& operator= (const Token&);
Token& operator= (const Token&) = delete;
}; };
struct TokenList struct TokenList
@@ -346,7 +347,7 @@ namespace TextLayoutHelpers
if (newGlyphs.size() > 0) if (newGlyphs.size() > 0)
{ {
currentRun->glyphs.ensureStorageAllocated (currentRun->glyphs.size() + newGlyphs.size()); currentRun->glyphs.ensureStorageAllocated (currentRun->glyphs.size() + newGlyphs.size());
const Point<float> tokenOrigin (t.area.getPosition().translated (0, t.font.getAscent()));
auto tokenOrigin = t.area.getPosition().translated (0, t.font.getAscent());
if (needToSetLineOrigin) if (needToSetLineOrigin)
{ {
@@ -354,11 +355,11 @@ namespace TextLayoutHelpers
currentLine->lineOrigin = tokenOrigin; currentLine->lineOrigin = tokenOrigin;
} }
const Point<float> glyphOffset (tokenOrigin - currentLine->lineOrigin);
auto glyphOffset = tokenOrigin - currentLine->lineOrigin;
for (int j = 0; j < newGlyphs.size(); ++j) for (int j = 0; j < newGlyphs.size(); ++j)
{ {
const float x = xOffsets.getUnchecked (j);
auto x = xOffsets.getUnchecked (j);
currentRun->glyphs.add (TextLayout::Glyph (newGlyphs.getUnchecked(j), currentRun->glyphs.add (TextLayout::Glyph (newGlyphs.getUnchecked(j),
glyphOffset.translated (x, 0), glyphOffset.translated (x, 0),
xOffsets.getUnchecked (j + 1) - x)); xOffsets.getUnchecked (j + 1) - x));
@@ -370,7 +371,7 @@ namespace TextLayoutHelpers
if (t.isWhitespace || t.isNewLine) if (t.isWhitespace || t.isNewLine)
++charPosition; ++charPosition;
if (auto* nextToken = tokens [i + 1])
if (auto* nextToken = tokens[i + 1])
{ {
if (t.font != nextToken->font || t.colour != nextToken->colour) if (t.font != nextToken->font || t.colour != nextToken->colour)
{ {
@@ -408,12 +409,12 @@ namespace TextLayoutHelpers
if ((text.getJustification().getFlags() & (Justification::right | Justification::horizontallyCentred)) != 0) if ((text.getJustification().getFlags() & (Justification::right | Justification::horizontallyCentred)) != 0)
{ {
const float totalW = layout.getWidth();
const bool isCentred = (text.getJustification().getFlags() & Justification::horizontallyCentred) != 0;
auto totalW = layout.getWidth();
bool isCentred = (text.getJustification().getFlags() & Justification::horizontallyCentred) != 0;
for (int i = 0; i < layout.getNumLines(); ++i) for (int i = 0; i < layout.getNumLines(); ++i)
{ {
float dx = totalW - layout.getLine(i).getLineBoundsX().getLength();
auto dx = totalW - layout.getLine(i).getLineBoundsX().getLength();
if (isCentred) if (isCentred)
dx /= 2.0f; dx /= 2.0f;
@@ -451,11 +452,12 @@ namespace TextLayoutHelpers
for (;;) for (;;)
{ {
const juce_wchar c = t.getAndAdvance();
auto c = t.getAndAdvance();
if (c == 0) if (c == 0)
break; break;
const int charType = getCharacterType (c);
auto charType = getCharacterType (c);
if (charType == 0 || charType != lastCharType) if (charType == 0 || charType != lastCharType)
{ {
@@ -529,7 +531,7 @@ namespace TextLayoutHelpers
void addTextRuns (const AttributedString& text) void addTextRuns (const AttributedString& text)
{ {
const int numAttributes = text.getNumAttributes();
auto numAttributes = text.getNumAttributes();
tokens.ensureStorageAllocated (jmax (64, numAttributes)); tokens.ensureStorageAllocated (jmax (64, numAttributes));
for (int i = 0; i < numAttributes; ++i) for (int i = 0; i < numAttributes; ++i)


+ 1
- 1
libs/juce/source/modules/juce_graphics/geometry/juce_EdgeTable.cpp View File

@@ -572,7 +572,7 @@ void EdgeTable::intersectWithEdgeTableLine (const int y, const int* const otherL
lastX = nextX; lastX = nextX;
const int nextLevel = (level1 * (level2 + 1)) >> 8; const int nextLevel = (level1 * (level2 + 1)) >> 8;
jassert (isPositiveAndBelow (nextLevel, (int) 256));
jassert (isPositiveAndBelow (nextLevel, 256));
if (nextLevel != lastLevel) if (nextLevel != lastLevel)
{ {


+ 1
- 1
libs/juce/source/modules/juce_graphics/geometry/juce_EdgeTable.h View File

@@ -129,7 +129,7 @@ public:
while (--numPoints >= 0) while (--numPoints >= 0)
{ {
const int level = *++line; const int level = *++line;
jassert (isPositiveAndBelow (level, (int) 256));
jassert (isPositiveAndBelow (level, 256));
const int endX = *++line; const int endX = *++line;
jassert (endX >= x); jassert (endX >= x);
const int endOfRun = (endX >> 8); const int endOfRun = (endX >> 8);


+ 2
- 8
libs/juce/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp View File

@@ -49,14 +49,8 @@ private:
}; };
//============================================================================== //==============================================================================
ApplicationCommandTarget::ApplicationCommandTarget()
{
}
ApplicationCommandTarget::~ApplicationCommandTarget()
{
masterReference.clear();
}
ApplicationCommandTarget::ApplicationCommandTarget() {}
ApplicationCommandTarget::~ApplicationCommandTarget() {}
//============================================================================== //==============================================================================
bool ApplicationCommandTarget::tryToInvoke (const InvocationInfo& info, const bool async) bool ApplicationCommandTarget::tryToInvoke (const InvocationInfo& info, const bool async)


+ 1
- 3
libs/juce/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h View File

@@ -231,14 +231,12 @@ public:
private: private:
//============================================================================== //==============================================================================
WeakReference<ApplicationCommandTarget>::Master masterReference;
friend class WeakReference<ApplicationCommandTarget>;
class CommandMessage; class CommandMessage;
friend class CommandMessage; friend class CommandMessage;
bool tryToInvoke (const InvocationInfo&, bool async); bool tryToInvoke (const InvocationInfo&, bool async);
JUCE_DECLARE_WEAK_REFERENCEABLE (ApplicationCommandTarget)
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandTarget) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandTarget)
}; };


+ 1
- 8
libs/juce/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp View File

@@ -32,11 +32,6 @@ class ComponentAnimator::AnimationTask
public: public:
AnimationTask (Component* c) noexcept : component (c) {} AnimationTask (Component* c) noexcept : component (c) {}
~AnimationTask()
{
masterReference.clear();
}
void reset (const Rectangle<int>& finalBounds, void reset (const Rectangle<int>& finalBounds,
float finalAlpha, float finalAlpha,
int millisecondsToSpendMoving, int millisecondsToSpendMoving,
@@ -186,9 +181,6 @@ public:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProxyComponent) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProxyComponent)
}; };
WeakReference<AnimationTask>::Master masterReference;
friend class WeakReference<AnimationTask>;
WeakReference<Component> component; WeakReference<Component> component;
ScopedPointer<Component> proxy; ScopedPointer<Component> proxy;
@@ -208,6 +200,7 @@ private:
+ (time - 0.5) * (midSpeed + (time - 0.5) * (endSpeed - midSpeed)); + (time - 0.5) * (midSpeed + (time - 0.5) * (endSpeed - midSpeed));
} }
JUCE_DECLARE_WEAK_REFERENCEABLE (AnimationTask)
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnimationTask) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnimationTask)
}; };


+ 0
- 2
libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp View File

@@ -37,7 +37,6 @@ extern GetTypefaceForFont juce_getTypefaceForFont;
//============================================================================== //==============================================================================
LookAndFeel::LookAndFeel() LookAndFeel::LookAndFeel()
: useNativeAlertWindows (false)
{ {
/* if this fails it means you're trying to create a LookAndFeel object before /* if this fails it means you're trying to create a LookAndFeel object before
the static Colours have been initialised. That ain't gonna work. It probably the static Colours have been initialised. That ain't gonna work. It probably
@@ -51,7 +50,6 @@ LookAndFeel::LookAndFeel()
LookAndFeel::~LookAndFeel() LookAndFeel::~LookAndFeel()
{ {
masterReference.clear();
} }
//============================================================================== //==============================================================================


+ 2
- 4
libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h View File

@@ -212,9 +212,6 @@ public:
private: private:
//============================================================================== //==============================================================================
friend class WeakReference<LookAndFeel>;
WeakReference<LookAndFeel>::Master masterReference;
struct ColourSetting struct ColourSetting
{ {
int colourID; int colourID;
@@ -226,8 +223,9 @@ private:
SortedSet<ColourSetting> colours; SortedSet<ColourSetting> colours;
String defaultSans, defaultSerif, defaultFixed; String defaultSans, defaultSerif, defaultFixed;
bool useNativeAlertWindows;
bool useNativeAlertWindows = false;
JUCE_DECLARE_WEAK_REFERENCEABLE (LookAndFeel)
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel)
}; };


+ 2
- 0
libs/juce/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp View File

@@ -200,6 +200,8 @@ void LookAndFeel_V4::positionDocumentWindowButtons (DocumentWindow&,
Button* closeButton, Button* closeButton,
bool positionTitleBarButtonsOnLeft) bool positionTitleBarButtonsOnLeft)
{ {
titleBarH = jmin (titleBarH, titleBarH - titleBarY);
const int buttonW = (int) (titleBarH * 1.2); const int buttonW = (int) (titleBarH * 1.2);
int x = positionTitleBarButtonsOnLeft ? titleBarX int x = positionTitleBarButtonsOnLeft ? titleBarX


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

@@ -1621,7 +1621,7 @@ struct PopupMenuCompletionCallback : public ModalComponentManager::Callback
if (prevTopLevel != nullptr) if (prevTopLevel != nullptr)
prevTopLevel->toFront (true); prevTopLevel->toFront (true);
if (prevFocused != nullptr)
if (prevFocused != nullptr && prevFocused->isShowing())
prevFocused->grabKeyboardFocus(); prevFocused->grabKeyboardFocus();
} }
} }


+ 140
- 69
libs/juce/source/modules/juce_gui_basics/native/juce_mac_MainMenu.mm View File

@@ -27,6 +27,41 @@
namespace juce namespace juce
{ {
//==============================================================================
struct JuceMainMenuBarHolder : private DeletedAtShutdown
{
JuceMainMenuBarHolder()
: mainMenuBar ([[NSMenu alloc] initWithTitle: nsStringLiteral ("MainMenu")])
{
auto* item = [mainMenuBar addItemWithTitle: nsStringLiteral ("Apple")
action: nil
keyEquivalent: nsEmptyString()];
auto* appMenu = [[NSMenu alloc] initWithTitle: nsStringLiteral ("Apple")];
[NSApp performSelector: @selector (setAppleMenu:) withObject: appMenu];
[mainMenuBar setSubmenu: appMenu forItem: item];
[appMenu release];
[NSApp setMainMenu: mainMenuBar];
}
~JuceMainMenuBarHolder()
{
clearSingletonInstance();
[NSApp setMainMenu: nil];
[mainMenuBar release];
}
NSMenu* mainMenuBar = nil;
juce_DeclareSingleton_SingleThreaded (JuceMainMenuBarHolder, true)
};
juce_ImplementSingleton_SingleThreaded (JuceMainMenuBarHolder)
//==============================================================================
class JuceMainMenuHandler : private MenuBarModel::Listener, class JuceMainMenuHandler : private MenuBarModel::Listener,
private DeletedAtShutdown private DeletedAtShutdown
{ {
@@ -95,7 +130,10 @@ public:
[menu setAutoenablesItems: false]; [menu setAutoenablesItems: false];
[menu update]; [menu update];
removeItemRecursive ([parentItem submenu]);
[parentItem setSubmenu: menu]; [parentItem setSubmenu: menu];
[menu release]; [menu release];
} }
@@ -104,7 +142,9 @@ public:
NSMenu* superMenu = [menu supermenu]; NSMenu* superMenu = [menu supermenu];
auto menuNames = currentModel->getMenuBarNames(); auto menuNames = currentModel->getMenuBarNames();
auto indexOfMenu = (int) [superMenu indexOfItemWithSubmenu: menu] - 1; auto indexOfMenu = (int) [superMenu indexOfItemWithSubmenu: menu] - 1;
[menu removeAllItems];
removeItemRecursive (menu);
auto updatedPopup = currentModel->getMenuForIndex (indexOfMenu, menuNames[indexOfMenu]); auto updatedPopup = currentModel->getMenuForIndex (indexOfMenu, menuNames[indexOfMenu]);
for (PopupMenu::MenuItemIterator iter (updatedPopup); iter.next();) for (PopupMenu::MenuItemIterator iter (updatedPopup); iter.next();)
@@ -113,7 +153,7 @@ public:
[menu update]; [menu update];
} }
void menuBarItemsChanged (MenuBarModel*)
void menuBarItemsChanged (MenuBarModel*) override
{ {
if (isOpen) if (isOpen)
{ {
@@ -127,10 +167,10 @@ public:
if (currentModel != nullptr) if (currentModel != nullptr)
menuNames = currentModel->getMenuBarNames(); menuNames = currentModel->getMenuBarNames();
NSMenu* menuBar = [[NSApp mainMenu] retain];
auto* menuBar = getMainMenuBar();
while ([menuBar numberOfItems] > 1 + menuNames.size()) while ([menuBar numberOfItems] > 1 + menuNames.size())
[menuBar removeItemAtIndex: [menuBar numberOfItems] - 1];
removeItemRecursive (menuBar, static_cast<int> ([menuBar numberOfItems] - 1));
int menuId = 1; int menuId = 1;
@@ -143,34 +183,36 @@ public:
else else
updateTopLevelMenu ([menuBar itemAtIndex: 1 + i], menu, menuNames[i], menuId, i); updateTopLevelMenu ([menuBar itemAtIndex: 1 + i], menu, menuNames[i], menuId, i);
} }
[menuBar release];
} }
void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info)
void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info) override
{ {
if ((info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) == 0 if ((info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) == 0
&& info.invocationMethod != ApplicationCommandTarget::InvocationInfo::fromKeyPress) && info.invocationMethod != ApplicationCommandTarget::InvocationInfo::fromKeyPress)
if (auto* item = findMenuItemWithTag ([NSApp mainMenu], info.commandID))
if (auto* item = findMenuItemWithCommandID (getMainMenuBar(), info.commandID))
flashMenuBar ([item menu]); flashMenuBar ([item menu]);
} }
void invoke (int commandId, ApplicationCommandManager* commandManager, int topLevelIndex) const
void invoke (const PopupMenu::Item& item, int topLevelIndex) const
{ {
if (currentModel != nullptr) if (currentModel != nullptr)
{ {
if (commandManager != nullptr)
if (item.customCallback != nullptr)
if (! item.customCallback->menuItemTriggered())
return;
if (item.commandManager != nullptr)
{ {
ApplicationCommandTarget::InvocationInfo info (commandId);
ApplicationCommandTarget::InvocationInfo info (item.itemID);
info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu; info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu;
commandManager->invoke (info, true);
item.commandManager->invoke (info, true);
} }
MessageManager::callAsync ([=]() MessageManager::callAsync ([=]()
{ {
if (instance != nullptr) if (instance != nullptr)
instance->invokeDirectly (commandId, topLevelIndex);
instance->invokeDirectly (item.itemID, topLevelIndex);
}); });
} }
} }
@@ -232,18 +274,19 @@ public:
} }
else else
{ {
NSMenuItem* item = [menuToAddTo addItemWithTitle: text
action: @selector (menuItemInvoked:)
keyEquivalent: nsEmptyString()];
auto* item = [[NSMenuItem alloc] initWithTitle: text
action: @selector (menuItemInvoked:)
keyEquivalent: nsEmptyString()];
[item setTag: i.itemID];
[item setTag: topLevelIndex];
[item setEnabled: i.isEnabled]; [item setEnabled: i.isEnabled];
[item setState: i.isTicked ? NSOnState : NSOffState]; [item setState: i.isTicked ? NSOnState : NSOffState];
[item setTarget: (id) callback]; [item setTarget: (id) callback];
NSMutableArray* info = [NSMutableArray arrayWithObject: [NSNumber numberWithUnsignedLongLong: (pointer_sized_uint) (void*) i.commandManager]];
[info addObject: [NSNumber numberWithInt: topLevelIndex]];
[item setRepresentedObject: info];
auto* juceItem = new PopupMenu::Item (i);
juceItem->customComponent = nullptr;
[item setRepresentedObject: [createNSObjectFromJuceClass (juceItem) autorelease]];
if (i.commandManager != nullptr) if (i.commandManager != nullptr)
{ {
@@ -264,6 +307,9 @@ public:
break; break;
} }
} }
[menuToAddTo addItem: item];
[item release];
} }
} }
@@ -357,16 +403,17 @@ private:
ScopedPointer<RecentFilesMenuItem> recent; ScopedPointer<RecentFilesMenuItem> recent;
//============================================================================== //==============================================================================
static NSMenuItem* findMenuItemWithTag (NSMenu* const menu, int tag)
static NSMenuItem* findMenuItemWithCommandID (NSMenu* const menu, int commandID)
{ {
for (NSInteger i = [menu numberOfItems]; --i >= 0;) for (NSInteger i = [menu numberOfItems]; --i >= 0;)
{ {
NSMenuItem* m = [menu itemAtIndex: i]; NSMenuItem* m = [menu itemAtIndex: i];
if ([m tag] == tag)
return m;
if (auto* menuItem = getJuceClassFromNSObject<PopupMenu::Item> ([m representedObject]))
if (menuItem->itemID == commandID)
return m;
if (NSMenu* sub = [m submenu]) if (NSMenu* sub = [m submenu])
if (NSMenuItem* found = findMenuItemWithTag (sub, tag))
if (NSMenuItem* found = findMenuItemWithCommandID (sub, commandID))
return found; return found;
} }
@@ -422,6 +469,39 @@ private:
return m; return m;
} }
// Apple Bug: For some reason [NSMenu removeAllItems] seems to leak it's objects
// on shutdown, so we need this method to release the items one-by-one manually
static void removeItemRecursive (NSMenu* parentMenu, int menuItemIndex)
{
if (isPositiveAndBelow (menuItemIndex, (int) [parentMenu numberOfItems]))
{
auto* menuItem = [parentMenu itemAtIndex:menuItemIndex];
if (auto* submenu = [menuItem submenu])
removeItemRecursive (submenu);
[parentMenu removeItem:menuItem];
}
else
jassertfalse;
}
static void removeItemRecursive (NSMenu* menu)
{
if (menu != nullptr)
{
auto n = static_cast<int> ([menu numberOfItems]);
for (auto i = n; --i >= 0;)
removeItemRecursive (menu, i);
}
}
static NSMenu* getMainMenuBar()
{
return JuceMainMenuBarHolder::getInstance()->mainMenuBar;
}
//============================================================================== //==============================================================================
struct JuceMenuCallbackClass : public ObjCClass<NSObject> struct JuceMenuCallbackClass : public ObjCClass<NSObject>
{ {
@@ -449,7 +529,7 @@ private:
{ {
auto owner = getIvar<JuceMainMenuHandler*> (self, "owner"); auto owner = getIvar<JuceMainMenuHandler*> (self, "owner");
if ([[item representedObject] isKindOfClass: [NSArray class]])
if (auto* juceItem = getJuceClassFromNSObject<PopupMenu::Item> ([item representedObject]))
{ {
// If the menu is being triggered by a keypress, the OS will have picked it up before we had a chance to offer it to // If the menu is being triggered by a keypress, the OS will have picked it up before we had a chance to offer it to
// our own components, which may have wanted to intercept it. So, rather than dispatching directly, we'll feed it back // our own components, which may have wanted to intercept it. So, rather than dispatching directly, we'll feed it back
@@ -472,12 +552,7 @@ private:
} }
} }
NSArray* info = (NSArray*) [item representedObject];
owner->invoke ((int) [item tag],
(ApplicationCommandManager*) (pointer_sized_int)
[((NSNumber*) [info objectAtIndex: 0]) unsignedLongLongValue],
(int) [((NSNumber*) [info objectAtIndex: 1]) intValue]);
owner->invoke (*juceItem, static_cast<int> ([item tag]));
} }
} }
@@ -505,28 +580,31 @@ public:
MenuBarModel::setMacMainMenu (nullptr); MenuBarModel::setMacMainMenu (nullptr);
NSMenu* menu = [[NSMenu alloc] initWithTitle: nsStringLiteral ("Edit")];
NSMenuItem* item;
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Cut"), nil)
action: @selector (cut:) keyEquivalent: nsStringLiteral ("x")];
[menu addItem: item];
[item release];
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Copy"), nil)
action: @selector (copy:) keyEquivalent: nsStringLiteral ("c")];
[menu addItem: item];
[item release];
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Paste"), nil)
action: @selector (paste:) keyEquivalent: nsStringLiteral ("v")];
[menu addItem: item];
[item release];
item = [[NSApp mainMenu] addItemWithTitle: NSLocalizedString (nsStringLiteral ("Edit"), nil)
action: nil keyEquivalent: nsEmptyString()];
[[NSApp mainMenu] setSubmenu: menu forItem: item];
[menu release];
if (auto* mainMenu = JuceMainMenuBarHolder::getInstance()->mainMenuBar)
{
NSMenu* menu = [[NSMenu alloc] initWithTitle: nsStringLiteral ("Edit")];
NSMenuItem* item;
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Cut"), nil)
action: @selector (cut:) keyEquivalent: nsStringLiteral ("x")];
[menu addItem: item];
[item release];
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Copy"), nil)
action: @selector (copy:) keyEquivalent: nsStringLiteral ("c")];
[menu addItem: item];
[item release];
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (nsStringLiteral ("Paste"), nil)
action: @selector (paste:) keyEquivalent: nsStringLiteral ("v")];
[menu addItem: item];
[item release];
item = [mainMenu addItemWithTitle: NSLocalizedString (nsStringLiteral ("Edit"), nil)
action: nil keyEquivalent: nsEmptyString()];
[mainMenu setSubmenu: menu forItem: item];
[menu release];
}
// use a dummy modal component so that apps can tell that something is currently modal. // use a dummy modal component so that apps can tell that something is currently modal.
dummyModalComponent.enterModalState (false); dummyModalComponent.enterModalState (false);
@@ -615,23 +693,16 @@ namespace MainMenuHelpers
if (auto* app = JUCEApplicationBase::getInstance()) if (auto* app = JUCEApplicationBase::getInstance())
{ {
JUCE_AUTORELEASEPOOL
if (auto* mainMenu = JuceMainMenuBarHolder::getInstance()->mainMenuBar)
{ {
NSMenu* mainMenu = [[NSMenu alloc] initWithTitle: nsStringLiteral ("MainMenu")];
NSMenuItem* item = [mainMenu addItemWithTitle: nsStringLiteral ("Apple")
action: nil
keyEquivalent: nsEmptyString()];
NSMenu* appMenu = [[NSMenu alloc] initWithTitle: nsStringLiteral ("Apple")];
[NSApp performSelector: @selector (setAppleMenu:) withObject: appMenu];
[mainMenu setSubmenu: appMenu forItem: item];
[NSApp setMainMenu: mainMenu];
MainMenuHelpers::createStandardAppMenu (appMenu, app->getApplicationName(), extraItems);
[appMenu release];
[mainMenu release];
if ([mainMenu numberOfItems] > 0)
{
if (auto* appMenu = [[mainMenu itemAtIndex:0] submenu])
{
[appMenu removeAllItems];
MainMenuHelpers::createStandardAppMenu (appMenu, app->getApplicationName(), extraItems);
}
}
} }
} }
} }


+ 2
- 2
libs/juce/source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm View File

@@ -392,8 +392,8 @@ public:
{ {
NSRect viewFrame = [view frame]; NSRect viewFrame = [view frame];
if (! (isPositiveAndBelow (localPos.getX(), (int) viewFrame.size.width)
&& isPositiveAndBelow (localPos.getY(), (int) viewFrame.size.height)))
if (! (isPositiveAndBelow (localPos.getX(), viewFrame.size.width)
&& isPositiveAndBelow (localPos.getY(), viewFrame.size.height)))
return false; return false;
if (! SystemStats::isRunningInAppExtensionSandbox()) if (! SystemStats::isRunningInAppExtensionSandbox())


+ 2
- 2
libs/juce/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp View File

@@ -1184,8 +1184,8 @@ public:
{ {
auto r = getWindowRect (hwnd); auto r = getWindowRect (hwnd);
if (! (isPositiveAndBelow (localPos.x, (int) (r.right - r.left))
&& isPositiveAndBelow (localPos.y, (int) (r.bottom - r.top))))
if (! (isPositiveAndBelow (localPos.x, r.right - r.left)
&& isPositiveAndBelow (localPos.y, r.bottom - r.top)))
return false; return false;
POINT p = { localPos.x + r.left + windowBorder.getLeft(), POINT p = { localPos.x + r.left + windowBorder.getLeft(),


+ 59
- 89
libs/juce/source/modules/juce_gui_basics/windows/juce_AlertWindow.cpp View File

@@ -43,8 +43,7 @@ AlertWindow::AlertWindow (const String& title,
Component* comp) Component* comp)
: TopLevelWindow (title, true), : TopLevelWindow (title, true),
alertIconType (iconType), alertIconType (iconType),
associatedComponent (comp),
escapeKeyCancels (true)
associatedComponent (comp)
{ {
setAlwaysOnTop (juce_areThereAnyAlwaysOnTopWindows()); setAlwaysOnTop (juce_areThereAnyAlwaysOnTopWindows());
@@ -71,7 +70,7 @@ void AlertWindow::userTriedToCloseWindow()
//============================================================================== //==============================================================================
void AlertWindow::setMessage (const String& message) void AlertWindow::setMessage (const String& message)
{ {
const String newMessage (message.substring (0, 2048));
auto newMessage = message.substring (0, 2048);
if (text != newMessage) if (text != newMessage)
{ {
@@ -84,7 +83,7 @@ void AlertWindow::setMessage (const String& message)
//============================================================================== //==============================================================================
void AlertWindow::buttonClicked (Button* button) void AlertWindow::buttonClicked (Button* button)
{ {
if (Component* parent = button->getParentComponent())
if (auto* parent = button->getParentComponent())
parent->exitModalState (button->getCommandID()); parent->exitModalState (button->getCommandID());
} }
@@ -94,7 +93,7 @@ void AlertWindow::addButton (const String& name,
const KeyPress& shortcutKey1, const KeyPress& shortcutKey1,
const KeyPress& shortcutKey2) const KeyPress& shortcutKey2)
{ {
TextButton* const b = new TextButton (name, String());
auto* b = new TextButton (name, {});
buttons.add (b); buttons.add (b);
b->setWantsKeyboardFocus (true); b->setWantsKeyboardFocus (true);
@@ -105,19 +104,18 @@ void AlertWindow::addButton (const String& name,
b->addListener (this); b->addListener (this);
Array<TextButton*> buttonsArray (buttons.begin(), buttons.size()); Array<TextButton*> buttonsArray (buttons.begin(), buttons.size());
auto& lf = getLookAndFeel();
const int buttonHeight = getLookAndFeel().getAlertWindowButtonHeight();
const Array<int> buttonWidths = getLookAndFeel().getWidthsForTextButtons (*this, buttonsArray);
auto buttonHeight = lf.getAlertWindowButtonHeight();
auto buttonWidths = lf.getWidthsForTextButtons (*this, buttonsArray);
jassert (buttonWidths.size() == buttons.size()); jassert (buttonWidths.size() == buttons.size());
int i = 0;
const int n = buttonWidths.size();
for (int i = 0; i < n; ++i)
buttons.getUnchecked (i)->setSize (buttonWidths.getReference (i), buttonHeight);
for (auto* button : buttons)
button->setSize (buttonWidths[i++], buttonHeight);
addAndMakeVisible (b, 0); addAndMakeVisible (b, 0);
updateLayout (false); updateLayout (false);
} }
@@ -128,10 +126,8 @@ int AlertWindow::getNumButtons() const
void AlertWindow::triggerButtonClick (const String& buttonName) void AlertWindow::triggerButtonClick (const String& buttonName)
{ {
for (int i = buttons.size(); --i >= 0;)
for (auto* b : buttons)
{ {
TextButton* const b = buttons.getUnchecked(i);
if (buttonName == b->getName()) if (buttonName == b->getName())
{ {
b->triggerClick(); b->triggerClick();
@@ -151,7 +147,7 @@ void AlertWindow::addTextEditor (const String& name,
const String& onScreenLabel, const String& onScreenLabel,
const bool isPasswordBox) const bool isPasswordBox)
{ {
TextEditor* ed = new TextEditor (name, isPasswordBox ? getDefaultPasswordChar() : 0);
auto* ed = new TextEditor (name, isPasswordBox ? getDefaultPasswordChar() : 0);
ed->setSelectAllWhenFocused (true); ed->setSelectAllWhenFocused (true);
ed->setEscapeAndReturnKeysConsumed (false); ed->setEscapeAndReturnKeysConsumed (false);
textBoxes.add (ed); textBoxes.add (ed);
@@ -169,9 +165,9 @@ void AlertWindow::addTextEditor (const String& name,
TextEditor* AlertWindow::getTextEditor (const String& nameOfTextEditor) const TextEditor* AlertWindow::getTextEditor (const String& nameOfTextEditor) const
{ {
for (int i = textBoxes.size(); --i >= 0;)
if (textBoxes.getUnchecked(i)->getName() == nameOfTextEditor)
return textBoxes.getUnchecked(i);
for (auto* tb : textBoxes)
if (tb->getName() == nameOfTextEditor)
return tb;
return nullptr; return nullptr;
} }
@@ -190,7 +186,7 @@ void AlertWindow::addComboBox (const String& name,
const StringArray& items, const StringArray& items,
const String& onScreenLabel) const String& onScreenLabel)
{ {
ComboBox* const cb = new ComboBox (name);
auto* cb = new ComboBox (name);
comboBoxes.add (cb); comboBoxes.add (cb);
allComps.add (cb); allComps.add (cb);
@@ -205,9 +201,9 @@ void AlertWindow::addComboBox (const String& name,
ComboBox* AlertWindow::getComboBoxComponent (const String& nameOfList) const ComboBox* AlertWindow::getComboBoxComponent (const String& nameOfList) const
{ {
for (int i = comboBoxes.size(); --i >= 0;)
if (comboBoxes.getUnchecked(i)->getName() == nameOfList)
return comboBoxes.getUnchecked(i);
for (auto* cb : comboBoxes)
if (cb->getName() == nameOfList)
return cb;
return nullptr; return nullptr;
} }
@@ -231,15 +227,12 @@ public:
setScrollbarsShown (true); setScrollbarsShown (true);
lookAndFeelChanged(); lookAndFeelChanged();
setWantsKeyboardFocus (false); setWantsKeyboardFocus (false);
setFont (font); setFont (font);
setText (message, false); setText (message, false);
bestWidth = 2 * (int) std::sqrt (font.getHeight() * font.getStringWidth (message)); bestWidth = 2 * (int) std::sqrt (font.getHeight() * font.getStringWidth (message));
} }
int getPreferredWidth() const noexcept { return bestWidth; }
void updateLayout (const int width) void updateLayout (const int width)
{ {
AttributedString s; AttributedString s;
@@ -251,7 +244,6 @@ public:
setSize (width, jmin (width, (int) (text.getHeight() + getFont().getHeight()))); setSize (width, jmin (width, (int) (text.getHeight() + getFont().getHeight())));
} }
private:
int bestWidth; int bestWidth;
JUCE_DECLARE_NON_COPYABLE (AlertTextComp) JUCE_DECLARE_NON_COPYABLE (AlertTextComp)
@@ -259,10 +251,9 @@ private:
void AlertWindow::addTextBlock (const String& textBlock) void AlertWindow::addTextBlock (const String& textBlock)
{ {
AlertTextComp* const c = new AlertTextComp (*this, textBlock, getLookAndFeel().getAlertWindowMessageFont());
auto* c = new AlertTextComp (*this, textBlock, getLookAndFeel().getAlertWindowMessageFont());
textBlocks.add (c); textBlocks.add (c);
allComps.add (c); allComps.add (c);
addAndMakeVisible (c); addAndMakeVisible (c);
updateLayout (false); updateLayout (false);
@@ -271,10 +262,9 @@ void AlertWindow::addTextBlock (const String& textBlock)
//============================================================================== //==============================================================================
void AlertWindow::addProgressBarComponent (double& progressValue) void AlertWindow::addProgressBarComponent (double& progressValue)
{ {
ProgressBar* const pb = new ProgressBar (progressValue);
auto* pb = new ProgressBar (progressValue);
progressBars.add (pb); progressBars.add (pb);
allComps.add (pb); allComps.add (pb);
addAndMakeVisible (pb); addAndMakeVisible (pb);
updateLayout (false); updateLayout (false);
@@ -285,25 +275,17 @@ void AlertWindow::addCustomComponent (Component* const component)
{ {
customComps.add (component); customComps.add (component);
allComps.add (component); allComps.add (component);
addAndMakeVisible (component); addAndMakeVisible (component);
updateLayout (false); updateLayout (false);
} }
int AlertWindow::getNumCustomComponents() const
{
return customComps.size();
}
Component* AlertWindow::getCustomComponent (const int index) const
{
return customComps [index];
}
int AlertWindow::getNumCustomComponents() const { return customComps.size(); }
Component* AlertWindow::getCustomComponent (int index) const { return customComps [index]; }
Component* AlertWindow::removeCustomComponent (const int index) Component* AlertWindow::removeCustomComponent (const int index)
{ {
Component* const c = getCustomComponent (index);
auto* c = getCustomComponent (index);
if (c != nullptr) if (c != nullptr)
{ {
@@ -320,14 +302,15 @@ Component* AlertWindow::removeCustomComponent (const int index)
//============================================================================== //==============================================================================
void AlertWindow::paint (Graphics& g) void AlertWindow::paint (Graphics& g)
{ {
getLookAndFeel().drawAlertBox (g, *this, textArea, textLayout);
auto& lf = getLookAndFeel();
lf.drawAlertBox (g, *this, textArea, textLayout);
g.setColour (findColour (textColourId)); g.setColour (findColour (textColourId));
g.setFont (getLookAndFeel().getAlertWindowFont());
g.setFont (lf.getAlertWindowFont());
for (int i = textBoxes.size(); --i >= 0;) for (int i = textBoxes.size(); --i >= 0;)
{ {
const TextEditor* const te = textBoxes.getUnchecked(i);
auto* te = textBoxes.getUnchecked(i);
g.drawFittedText (textboxNames[i], g.drawFittedText (textboxNames[i],
te->getX(), te->getY() - 14, te->getX(), te->getY() - 14,
@@ -337,7 +320,7 @@ void AlertWindow::paint (Graphics& g)
for (int i = comboBoxNames.size(); --i >= 0;) for (int i = comboBoxNames.size(); --i >= 0;)
{ {
const ComboBox* const cb = comboBoxes.getUnchecked(i);
auto* cb = comboBoxes.getUnchecked(i);
g.drawFittedText (comboBoxNames[i], g.drawFittedText (comboBoxNames[i],
cb->getX(), cb->getY() - 14, cb->getX(), cb->getY() - 14,
@@ -345,15 +328,11 @@ void AlertWindow::paint (Graphics& g)
Justification::centredLeft, 1); Justification::centredLeft, 1);
} }
for (int i = customComps.size(); --i >= 0;)
{
const Component* const c = customComps.getUnchecked(i);
for (auto* c : customComps)
g.drawFittedText (c->getName(), g.drawFittedText (c->getName(),
c->getX(), c->getY() - 14, c->getX(), c->getY() - 14,
c->getWidth(), 14, c->getWidth(), 14,
Justification::centredLeft, 1); Justification::centredLeft, 1);
}
} }
void AlertWindow::updateLayout (const bool onlyIncreaseSize) void AlertWindow::updateLayout (const bool onlyIncreaseSize)
@@ -361,15 +340,14 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize)
const int titleH = 24; const int titleH = 24;
const int iconWidth = 80; const int iconWidth = 80;
LookAndFeel& lf = getLookAndFeel();
auto& lf = getLookAndFeel();
auto messageFont (lf.getAlertWindowMessageFont());
const Font messageFont (lf.getAlertWindowMessageFont());
auto wid = jmax (messageFont.getStringWidth (text),
messageFont.getStringWidth (getName()));
const int wid = jmax (messageFont.getStringWidth (text),
messageFont.getStringWidth (getName()));
const int sw = (int) std::sqrt (messageFont.getHeight() * wid);
int w = jmin (300 + sw * 2, (int) (getParentWidth() * 0.7f));
auto sw = (int) std::sqrt (messageFont.getHeight() * wid);
auto w = jmin (300 + sw * 2, (int) (getParentWidth() * 0.7f));
const int edgeGap = 10; const int edgeGap = 10;
const int labelHeight = 18; const int labelHeight = 18;
int iconSpace = 0; int iconSpace = 0;
@@ -397,24 +375,24 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize)
w = jmax (350, (int) textLayout.getWidth() + iconSpace + edgeGap * 4); w = jmax (350, (int) textLayout.getWidth() + iconSpace + edgeGap * 4);
w = jmin (w, (int) (getParentWidth() * 0.7f)); w = jmin (w, (int) (getParentWidth() * 0.7f));
const int textLayoutH = (int) textLayout.getHeight();
const int textBottom = 16 + titleH + textLayoutH;
auto textLayoutH = (int) textLayout.getHeight();
auto textBottom = 16 + titleH + textLayoutH;
int h = textBottom; int h = textBottom;
int buttonW = 40; int buttonW = 40;
for (int i = 0; i < buttons.size(); ++i)
buttonW += 16 + buttons.getUnchecked (i)->getWidth();
for (auto* b : buttons)
buttonW += 16 + b->getWidth();
w = jmax (buttonW, w); w = jmax (buttonW, w);
h += (textBoxes.size() + comboBoxes.size() + progressBars.size()) * 50; h += (textBoxes.size() + comboBoxes.size() + progressBars.size()) * 50;
if (buttons.size() > 0)
h += 20 + buttons.getUnchecked (0)->getHeight();
if (auto* b = buttons[0])
h += 20 + b->getHeight();
for (int i = customComps.size(); --i >= 0;)
for (auto* c : customComps)
{ {
Component* c = customComps.getUnchecked (i);
w = jmax (w, (c->getWidth() * 100) / 80); w = jmax (w, (c->getWidth() * 100) / 80);
h += 10 + c->getHeight(); h += 10 + c->getHeight();
@@ -422,17 +400,14 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize)
h += labelHeight; h += labelHeight;
} }
for (int i = textBlocks.size(); --i >= 0;)
{
const AlertTextComp* const ac = static_cast<const AlertTextComp*> (textBlocks.getUnchecked(i));
w = jmax (w, ac->getPreferredWidth());
}
for (auto* tb : textBlocks)
w = jmax (w, static_cast<const AlertTextComp*> (tb)->bestWidth);
w = jmin (w, (int) (getParentWidth() * 0.7f)); w = jmin (w, (int) (getParentWidth() * 0.7f));
for (int i = textBlocks.size(); --i >= 0;)
for (auto* tb : textBlocks)
{ {
AlertTextComp* const ac = static_cast<AlertTextComp*> (textBlocks.getUnchecked(i));
auto* ac = static_cast<AlertTextComp*> (tb);
ac->updateLayout ((int) (w * 0.8f)); ac->updateLayout ((int) (w * 0.8f));
h += ac->getHeight() + 10; h += ac->getHeight() + 10;
} }
@@ -455,15 +430,14 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize)
const int spacer = 16; const int spacer = 16;
int totalWidth = -spacer; int totalWidth = -spacer;
for (int i = buttons.size(); --i >= 0;)
totalWidth += buttons.getUnchecked(i)->getWidth() + spacer;
for (auto* b : buttons)
totalWidth += b->getWidth() + spacer;
int x = (w - totalWidth) / 2;
int y = (int) (getHeight() * 0.95f);
auto x = (w - totalWidth) / 2;
auto y = (int) (getHeight() * 0.95f);
for (int i = 0; i < buttons.size(); ++i)
for (auto* c : buttons)
{ {
TextButton* const c = buttons.getUnchecked(i);
int ny = proportionOfHeight (0.95f) - c->getHeight(); int ny = proportionOfHeight (0.95f) - c->getHeight();
c->setTopLeftPosition (x, ny); c->setTopLeftPosition (x, ny);
if (ny < y) if (ny < y)
@@ -476,9 +450,8 @@ void AlertWindow::updateLayout (const bool onlyIncreaseSize)
y = textBottom; y = textBottom;
for (int i = 0; i < allComps.size(); ++i)
for (auto* c : allComps)
{ {
Component* const c = allComps.getUnchecked(i);
h = 22; h = 22;
const int comboIndex = comboBoxes.indexOf (dynamic_cast<ComboBox*> (c)); const int comboIndex = comboBoxes.indexOf (dynamic_cast<ComboBox*> (c));
@@ -531,10 +504,8 @@ void AlertWindow::mouseDrag (const MouseEvent& e)
bool AlertWindow::keyPressed (const KeyPress& key) bool AlertWindow::keyPressed (const KeyPress& key)
{ {
for (int i = buttons.size(); --i >= 0;)
for (auto* b : buttons)
{ {
TextButton* const b = buttons.getUnchecked(i);
if (b->isRegisteredForShortcut (key)) if (b->isRegisteredForShortcut (key))
{ {
b->triggerClick(); b->triggerClick();
@@ -579,8 +550,7 @@ public:
AlertWindow::AlertIconType icon, int numButts, AlertWindow::AlertIconType icon, int numButts,
ModalComponentManager::Callback* cb, bool runModally) ModalComponentManager::Callback* cb, bool runModally)
: title (t), message (m), iconType (icon), numButtons (numButts), : title (t), message (m), iconType (icon), numButtons (numButts),
returnValue (0), associatedComponent (component),
callback (cb), modal (runModally)
associatedComponent (component), callback (cb), modal (runModally)
{ {
} }
@@ -594,15 +564,15 @@ public:
private: private:
AlertWindow::AlertIconType iconType; AlertWindow::AlertIconType iconType;
int numButtons, returnValue;
int numButtons, returnValue = 0;
WeakReference<Component> associatedComponent; WeakReference<Component> associatedComponent;
ModalComponentManager::Callback* callback; ModalComponentManager::Callback* callback;
bool modal; bool modal;
void show() void show()
{ {
LookAndFeel& lf = associatedComponent != nullptr ? associatedComponent->getLookAndFeel()
: LookAndFeel::getDefaultLookAndFeel();
auto& lf = associatedComponent != nullptr ? associatedComponent->getLookAndFeel()
: LookAndFeel::getDefaultLookAndFeel();
ScopedPointer<Component> alertBox (lf.createAlertWindow (title, message, button1, button2, button3, ScopedPointer<Component> alertBox (lf.createAlertWindow (title, message, button1, button2, button3,
iconType, numButtons, associatedComponent)); iconType, numButtons, associatedComponent));


+ 2
- 2
libs/juce/source/modules/juce_gui_basics/windows/juce_AlertWindow.h View File

@@ -479,8 +479,8 @@ private:
OwnedArray<Component> textBlocks; OwnedArray<Component> textBlocks;
Array<Component*> allComps; Array<Component*> allComps;
StringArray textboxNames, comboBoxNames; StringArray textboxNames, comboBoxNames;
Component* associatedComponent;
bool escapeKeyCancels;
Component* const associatedComponent;
bool escapeKeyCancels = true;
void updateLayout (bool onlyIncreaseSize); void updateLayout (bool onlyIncreaseSize);


+ 26
- 25
libs/juce/source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp View File

@@ -27,8 +27,8 @@
namespace juce namespace juce
{ {
CallOutBox::CallOutBox (Component& c, const Rectangle<int>& area, Component* const parent)
: arrowSize (16.0f), content (c), dismissalMouseClicksAreAlwaysConsumed (false)
CallOutBox::CallOutBox (Component& c, Rectangle<int> area, Component* const parent)
: content (c)
{ {
addAndMakeVisible (content); addAndMakeVisible (content);
@@ -84,7 +84,7 @@ public:
JUCE_DECLARE_NON_COPYABLE (CallOutBoxCallback) JUCE_DECLARE_NON_COPYABLE (CallOutBoxCallback)
}; };
CallOutBox& CallOutBox::launchAsynchronously (Component* content, const Rectangle<int>& area, Component* parent)
CallOutBox& CallOutBox::launchAsynchronously (Component* content, Rectangle<int> area, Component* parent)
{ {
jassert (content != nullptr); // must be a valid content component! jassert (content != nullptr); // must be a valid content component!
@@ -110,7 +110,7 @@ void CallOutBox::paint (Graphics& g)
void CallOutBox::resized() void CallOutBox::resized()
{ {
const int borderSpace = getBorderSize();
auto borderSpace = getBorderSize();
content.setTopLeftPosition (borderSpace, borderSpace); content.setTopLeftPosition (borderSpace, borderSpace);
refreshPath(); refreshPath();
} }
@@ -143,7 +143,8 @@ void CallOutBox::inputAttemptWhenModal()
// as Windows still sends touch events before the CallOutBox had a chance // as Windows still sends touch events before the CallOutBox had a chance
// to really open. // to really open.
RelativeTime elapsed = Time::getCurrentTime() - creationTime;
auto elapsed = Time::getCurrentTime() - creationTime;
if (elapsed.inMilliseconds() > 200) if (elapsed.inMilliseconds() > 200)
dismiss(); dismiss();
} }
@@ -193,29 +194,29 @@ void CallOutBox::updatePosition (const Rectangle<int>& newAreaToPointTo, const R
targetArea = newAreaToPointTo; targetArea = newAreaToPointTo;
availableArea = newAreaToFitIn; availableArea = newAreaToFitIn;
const int borderSpace = getBorderSize();
auto borderSpace = getBorderSize();
Rectangle<int> newBounds (content.getWidth() + borderSpace * 2, Rectangle<int> newBounds (content.getWidth() + borderSpace * 2,
content.getHeight() + borderSpace * 2); content.getHeight() + borderSpace * 2);
const int hw = newBounds.getWidth() / 2;
const int hh = newBounds.getHeight() / 2;
const float hwReduced = (float) (hw - borderSpace * 2);
const float hhReduced = (float) (hh - borderSpace * 2);
const float arrowIndent = borderSpace - arrowSize;
auto hw = newBounds.getWidth() / 2;
auto hh = newBounds.getHeight() / 2;
auto hwReduced = (float) (hw - borderSpace * 2);
auto hhReduced = (float) (hh - borderSpace * 2);
auto arrowIndent = borderSpace - arrowSize;
Point<float> targets[4] = { Point<float> ((float) targetArea.getCentreX(), (float) targetArea.getBottom()),
Point<float> ((float) targetArea.getRight(), (float) targetArea.getCentreY()),
Point<float> ((float) targetArea.getX(), (float) targetArea.getCentreY()),
Point<float> ((float) targetArea.getCentreX(), (float) targetArea.getY()) };
Point<float> targets[4] = { { (float) targetArea.getCentreX(), (float) targetArea.getBottom() },
{ (float) targetArea.getRight(), (float) targetArea.getCentreY() },
{ (float) targetArea.getX(), (float) targetArea.getCentreY() },
{ (float) targetArea.getCentreX(), (float) targetArea.getY() } };
Line<float> lines[4] = { Line<float> (targets[0].translated (-hwReduced, hh - arrowIndent), targets[0].translated (hwReduced, hh - arrowIndent)),
Line<float> (targets[1].translated (hw - arrowIndent, -hhReduced), targets[1].translated (hw - arrowIndent, hhReduced)),
Line<float> (targets[2].translated (-(hw - arrowIndent), -hhReduced), targets[2].translated (-(hw - arrowIndent), hhReduced)),
Line<float> (targets[3].translated (-hwReduced, -(hh - arrowIndent)), targets[3].translated (hwReduced, -(hh - arrowIndent))) };
Line<float> lines[4] = { { targets[0].translated (-hwReduced, hh - arrowIndent), targets[0].translated (hwReduced, hh - arrowIndent) },
{ targets[1].translated (hw - arrowIndent, -hhReduced), targets[1].translated (hw - arrowIndent, hhReduced) },
{ targets[2].translated (-(hw - arrowIndent), -hhReduced), targets[2].translated (-(hw - arrowIndent), hhReduced) },
{ targets[3].translated (-hwReduced, -(hh - arrowIndent)), targets[3].translated (hwReduced, -(hh - arrowIndent)) } };
const Rectangle<float> centrePointArea (newAreaToFitIn.reduced (hw, hh).toFloat());
const Point<float> targetCentre (targetArea.getCentre().toFloat());
auto centrePointArea = newAreaToFitIn.reduced (hw, hh).toFloat();
auto targetCentre = targetArea.getCentre().toFloat();
float nearest = 1.0e9f; float nearest = 1.0e9f;
@@ -224,8 +225,8 @@ void CallOutBox::updatePosition (const Rectangle<int>& newAreaToPointTo, const R
Line<float> constrainedLine (centrePointArea.getConstrainedPoint (lines[i].getStart()), Line<float> constrainedLine (centrePointArea.getConstrainedPoint (lines[i].getStart()),
centrePointArea.getConstrainedPoint (lines[i].getEnd())); centrePointArea.getConstrainedPoint (lines[i].getEnd()));
const Point<float> centre (constrainedLine.findNearestPointTo (targetCentre));
float distanceFromCentre = centre.getDistanceFrom (targets[i]);
auto centre = constrainedLine.findNearestPointTo (targetCentre);
auto distanceFromCentre = centre.getDistanceFrom (targets[i]);
if (! centrePointArea.intersects (lines[i])) if (! centrePointArea.intersects (lines[i]))
distanceFromCentre += 1000.0f; distanceFromCentre += 1000.0f;
@@ -233,8 +234,8 @@ void CallOutBox::updatePosition (const Rectangle<int>& newAreaToPointTo, const R
if (distanceFromCentre < nearest) if (distanceFromCentre < nearest)
{ {
nearest = distanceFromCentre; nearest = distanceFromCentre;
targetPoint = targets[i]; targetPoint = targets[i];
newBounds.setPosition ((int) (centre.x - hw), newBounds.setPosition ((int) (centre.x - hw),
(int) (centre.y - hh)); (int) (centre.y - hh));
} }
@@ -246,7 +247,7 @@ void CallOutBox::updatePosition (const Rectangle<int>& newAreaToPointTo, const R
void CallOutBox::refreshPath() void CallOutBox::refreshPath()
{ {
repaint(); repaint();
background = Image();
background = {};
outline.clear(); outline.clear();
const float gap = 4.5f; const float gap = 4.5f;


+ 4
- 4
libs/juce/source/modules/juce_gui_basics/windows/juce_CallOutBox.h View File

@@ -73,7 +73,7 @@ public:
If this is a nullptr, the call-out will be added to the desktop. If this is a nullptr, the call-out will be added to the desktop.
*/ */
CallOutBox (Component& contentComponent, CallOutBox (Component& contentComponent,
const Rectangle<int>& areaToPointTo,
Rectangle<int> areaToPointTo,
Component* parentComponent); Component* parentComponent);
/** Destructor. */ /** Destructor. */
@@ -117,7 +117,7 @@ public:
If this is a nullptr, the call-out will be added to the desktop. If this is a nullptr, the call-out will be added to the desktop.
*/ */
static CallOutBox& launchAsynchronously (Component* contentComponent, static CallOutBox& launchAsynchronously (Component* contentComponent,
const Rectangle<int>& areaToPointTo,
Rectangle<int> areaToPointTo,
Component* parentComponent); Component* parentComponent);
/** Posts a message which will dismiss the callout box asynchronously. /** Posts a message which will dismiss the callout box asynchronously.
@@ -167,13 +167,13 @@ public:
private: private:
//============================================================================== //==============================================================================
float arrowSize;
Component& content; Component& content;
Path outline; Path outline;
Point<float> targetPoint; Point<float> targetPoint;
Rectangle<int> availableArea, targetArea; Rectangle<int> availableArea, targetArea;
Image background; Image background;
bool dismissalMouseClicksAreAlwaysConsumed;
float arrowSize = 16.0f;
bool dismissalMouseClicksAreAlwaysConsumed = false;
Time creationTime; Time creationTime;


+ 3
- 11
libs/juce/source/modules/juce_gui_basics/windows/juce_DialogWindow.cpp View File

@@ -63,7 +63,7 @@ void DialogWindow::resized()
if (escapeKeyTriggersCloseButton) if (escapeKeyTriggersCloseButton)
{ {
if (Button* const close = getCloseButton())
if (auto* close = getCloseButton())
{ {
const KeyPress esc (KeyPress::escapeKey, 0, 0); const KeyPress esc (KeyPress::escapeKey, 0, 0);
@@ -102,15 +102,7 @@ private:
JUCE_DECLARE_NON_COPYABLE (DefaultDialogWindow) JUCE_DECLARE_NON_COPYABLE (DefaultDialogWindow)
}; };
DialogWindow::LaunchOptions::LaunchOptions() noexcept
: dialogBackgroundColour (Colours::lightgrey),
componentToCentreAround (nullptr),
escapeKeyTriggersCloseButton (true),
useNativeTitleBar (true),
resizable (true),
useBottomRightCornerResizer (false)
{
}
DialogWindow::LaunchOptions::LaunchOptions() noexcept {}
DialogWindow* DialogWindow::LaunchOptions::create() DialogWindow* DialogWindow::LaunchOptions::create()
{ {
@@ -121,7 +113,7 @@ DialogWindow* DialogWindow::LaunchOptions::create()
DialogWindow* DialogWindow::LaunchOptions::launchAsync() DialogWindow* DialogWindow::LaunchOptions::launchAsync()
{ {
DialogWindow* const d = create();
auto* d = create();
d->enterModalState (true, nullptr, true); d->enterModalState (true, nullptr, true);
return d; return d;
} }


+ 6
- 6
libs/juce/source/modules/juce_gui_basics/windows/juce_DialogWindow.h View File

@@ -87,7 +87,7 @@ public:
String dialogTitle; String dialogTitle;
/** The background colour for the window. */ /** The background colour for the window. */
Colour dialogBackgroundColour;
Colour dialogBackgroundColour = Colours::lightgrey;
/** The content component to show in the window. This must not be null! /** The content component to show in the window. This must not be null!
Using an OptionalScopedPointer to hold this pointer lets you indicate whether Using an OptionalScopedPointer to hold this pointer lets you indicate whether
@@ -100,16 +100,16 @@ public:
dialog box in front of. See the DocumentWindow::centreAroundComponent() method for dialog box in front of. See the DocumentWindow::centreAroundComponent() method for
more info about this parameter. more info about this parameter.
*/ */
Component* componentToCentreAround;
Component* componentToCentreAround = nullptr;
/** If true, then the escape key will trigger the dialog's close button. */ /** If true, then the escape key will trigger the dialog's close button. */
bool escapeKeyTriggersCloseButton;
bool escapeKeyTriggersCloseButton = true;
/** If true, the dialog will use a native title bar. See TopLevelWindow::setUsingNativeTitleBar() */ /** If true, the dialog will use a native title bar. See TopLevelWindow::setUsingNativeTitleBar() */
bool useNativeTitleBar;
bool useNativeTitleBar = true;
/** If true, the window will be resizable. See ResizableWindow::setResizable() */ /** If true, the window will be resizable. See ResizableWindow::setResizable() */
bool resizable;
bool resizable = true;
/** Indicates whether to use a border or corner resizer component. See ResizableWindow::setResizable() */ /** Indicates whether to use a border or corner resizer component. See ResizableWindow::setResizable() */
bool useBottomRightCornerResizer;
bool useBottomRightCornerResizer = false;
/** Launches a new modal dialog window. /** Launches a new modal dialog window.
This will create a dialog based on the settings in this structure, This will create a dialog based on the settings in this structure,


+ 27
- 33
libs/juce/source/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp View File

@@ -51,16 +51,12 @@ DocumentWindow::DocumentWindow (const String& title,
int requiredButtons_, int requiredButtons_,
bool addToDesktop_) bool addToDesktop_)
: ResizableWindow (title, backgroundColour, addToDesktop_), : ResizableWindow (title, backgroundColour, addToDesktop_),
titleBarHeight (26),
menuBarHeight (24),
requiredButtons (requiredButtons_), requiredButtons (requiredButtons_),
#if JUCE_MAC #if JUCE_MAC
positionTitleBarButtonsOnLeft (true),
positionTitleBarButtonsOnLeft (true)
#else #else
positionTitleBarButtonsOnLeft (false),
positionTitleBarButtonsOnLeft (false)
#endif #endif
drawTitleTextCentred (true),
menuBarModel (nullptr)
{ {
setResizeLimits (128, 128, 32768, 32768); setResizeLimits (128, 128, 32768, 32768);
@@ -77,8 +73,8 @@ DocumentWindow::~DocumentWindow()
jassert (titleBarButtons[1] == nullptr || getIndexOfChildComponent (titleBarButtons[1]) >= 0); jassert (titleBarButtons[1] == nullptr || getIndexOfChildComponent (titleBarButtons[1]) >= 0);
jassert (titleBarButtons[2] == nullptr || getIndexOfChildComponent (titleBarButtons[2]) >= 0); jassert (titleBarButtons[2] == nullptr || getIndexOfChildComponent (titleBarButtons[2]) >= 0);
for (int i = numElementsInArray (titleBarButtons); --i >= 0;)
titleBarButtons[i] = nullptr;
for (auto& b : titleBarButtons)
b = nullptr;
menuBar = nullptr; menuBar = nullptr;
} }
@@ -193,16 +189,16 @@ void DocumentWindow::paint (Graphics& g)
{ {
ResizableWindow::paint (g); ResizableWindow::paint (g);
const Rectangle<int> titleBarArea (getTitleBarArea());
auto titleBarArea = getTitleBarArea();
g.reduceClipRegion (titleBarArea); g.reduceClipRegion (titleBarArea);
g.setOrigin (titleBarArea.getPosition()); g.setOrigin (titleBarArea.getPosition());
int titleSpaceX1 = 6; int titleSpaceX1 = 6;
int titleSpaceX2 = titleBarArea.getWidth() - 6; int titleSpaceX2 = titleBarArea.getWidth() - 6;
for (int i = 0; i < 3; ++i)
for (auto& b : titleBarButtons)
{ {
if (Button* const b = titleBarButtons[i])
if (b != nullptr)
{ {
if (positionTitleBarButtonsOnLeft) if (positionTitleBarButtonsOnLeft)
titleSpaceX1 = jmax (titleSpaceX1, b->getRight() + (getWidth() - b->getRight()) / 8); titleSpaceX1 = jmax (titleSpaceX1, b->getRight() + (getWidth() - b->getRight()) / 8);
@@ -224,10 +220,10 @@ void DocumentWindow::resized()
{ {
ResizableWindow::resized(); ResizableWindow::resized();
if (Button* const b = getMaximiseButton())
if (auto* b = getMaximiseButton())
b->setToggleState (isFullScreen(), dontSendNotification); b->setToggleState (isFullScreen(), dontSendNotification);
const Rectangle<int> titleBarArea (getTitleBarArea());
auto titleBarArea = getTitleBarArea();
getLookAndFeel() getLookAndFeel()
.positionDocumentWindowButtons (*this, .positionDocumentWindowButtons (*this,
@@ -250,7 +246,7 @@ BorderSize<int> DocumentWindow::getBorderThickness()
BorderSize<int> DocumentWindow::getContentComponentBorder() BorderSize<int> DocumentWindow::getContentComponentBorder()
{ {
BorderSize<int> border (getBorderThickness());
auto border = getBorderThickness();
if (! isKioskMode()) if (! isKioskMode())
border.setTop (border.getTop() border.setTop (border.getTop()
@@ -267,13 +263,11 @@ int DocumentWindow::getTitleBarHeight() const
Rectangle<int> DocumentWindow::getTitleBarArea() Rectangle<int> DocumentWindow::getTitleBarArea()
{ {
const BorderSize<int> border (getBorderThickness());
if (isKioskMode()) if (isKioskMode())
return Rectangle<int>();
return {};
return Rectangle<int> (border.getLeft(), border.getTop(),
getWidth() - border.getLeftAndRight(), getTitleBarHeight());
auto border = getBorderThickness();
return { border.getLeft(), border.getTop(), getWidth() - border.getLeftAndRight(), getTitleBarHeight() };
} }
Button* DocumentWindow::getCloseButton() const noexcept { return titleBarButtons[2]; } Button* DocumentWindow::getCloseButton() const noexcept { return titleBarButtons[2]; }
@@ -282,7 +276,7 @@ Button* DocumentWindow::getMaximiseButton() const noexcept { return titleBarBut
int DocumentWindow::getDesktopWindowStyleFlags() const int DocumentWindow::getDesktopWindowStyleFlags() const
{ {
int styleFlags = ResizableWindow::getDesktopWindowStyleFlags();
auto styleFlags = ResizableWindow::getDesktopWindowStyleFlags();
if ((requiredButtons & minimiseButton) != 0) styleFlags |= ComponentPeer::windowHasMinimiseButton; if ((requiredButtons & minimiseButton) != 0) styleFlags |= ComponentPeer::windowHasMinimiseButton;
if ((requiredButtons & maximiseButton) != 0) styleFlags |= ComponentPeer::windowHasMaximiseButton; if ((requiredButtons & maximiseButton) != 0) styleFlags |= ComponentPeer::windowHasMaximiseButton;
@@ -293,8 +287,8 @@ int DocumentWindow::getDesktopWindowStyleFlags() const
void DocumentWindow::lookAndFeelChanged() void DocumentWindow::lookAndFeelChanged()
{ {
for (int i = numElementsInArray (titleBarButtons); --i >= 0;)
titleBarButtons[i] = nullptr;
for (auto& b : titleBarButtons)
b = nullptr;
if (! isUsingNativeTitleBar()) if (! isUsingNativeTitleBar())
{ {
@@ -304,9 +298,9 @@ void DocumentWindow::lookAndFeelChanged()
if ((requiredButtons & maximiseButton) != 0) titleBarButtons[1] = lf.createDocumentWindowButton (maximiseButton); if ((requiredButtons & maximiseButton) != 0) titleBarButtons[1] = lf.createDocumentWindowButton (maximiseButton);
if ((requiredButtons & closeButton) != 0) titleBarButtons[2] = lf.createDocumentWindowButton (closeButton); if ((requiredButtons & closeButton) != 0) titleBarButtons[2] = lf.createDocumentWindowButton (closeButton);
for (int i = 0; i < 3; ++i)
for (auto& b : titleBarButtons)
{ {
if (Button* const b = titleBarButtons[i])
if (b != nullptr)
{ {
if (buttonListener == nullptr) if (buttonListener == nullptr)
buttonListener = new ButtonListenerProxy (*this); buttonListener = new ButtonListenerProxy (*this);
@@ -319,7 +313,7 @@ void DocumentWindow::lookAndFeelChanged()
} }
} }
if (Button* const b = getCloseButton())
if (auto* b = getCloseButton())
{ {
#if JUCE_MAC #if JUCE_MAC
b->addShortcut (KeyPress ('w', ModifierKeys::commandModifier, 0)); b->addShortcut (KeyPress ('w', ModifierKeys::commandModifier, 0));
@@ -342,21 +336,21 @@ void DocumentWindow::parentHierarchyChanged()
void DocumentWindow::activeWindowStatusChanged() void DocumentWindow::activeWindowStatusChanged()
{ {
ResizableWindow::activeWindowStatusChanged(); ResizableWindow::activeWindowStatusChanged();
bool isActive = isActiveWindow();
for (int i = numElementsInArray (titleBarButtons); --i >= 0;)
if (Button* const b = titleBarButtons[i])
b->setEnabled (isActiveWindow());
for (auto& b : titleBarButtons)
if (b != nullptr)
b->setEnabled (isActive);
if (menuBar != nullptr) if (menuBar != nullptr)
menuBar->setEnabled (isActiveWindow());
menuBar->setEnabled (isActive);
} }
void DocumentWindow::mouseDoubleClick (const MouseEvent& e) void DocumentWindow::mouseDoubleClick (const MouseEvent& e)
{ {
Button* const maximise = getMaximiseButton();
if (maximise != nullptr && getTitleBarArea().contains (e.x, e.y))
maximise->triggerClick();
if (getTitleBarArea().contains (e.x, e.y))
if (auto* maximise = getMaximiseButton())
maximise->triggerClick();
} }
void DocumentWindow::userTriedToCloseWindow() void DocumentWindow::userTriedToCloseWindow()


+ 3
- 3
libs/juce/source/modules/juce_gui_basics/windows/juce_DocumentWindow.h View File

@@ -276,12 +276,12 @@ public:
private: private:
//============================================================================== //==============================================================================
int titleBarHeight, menuBarHeight, requiredButtons;
bool positionTitleBarButtonsOnLeft, drawTitleTextCentred;
int titleBarHeight = 26, menuBarHeight = 24, requiredButtons;
bool positionTitleBarButtonsOnLeft, drawTitleTextCentred = true;
ScopedPointer<Button> titleBarButtons [3]; ScopedPointer<Button> titleBarButtons [3];
Image titleBarIcon; Image titleBarIcon;
ScopedPointer<Component> menuBar; ScopedPointer<Component> menuBar;
MenuBarModel* menuBarModel;
MenuBarModel* menuBarModel = nullptr;
class ButtonListenerProxy; class ButtonListenerProxy;
friend struct ContainerDeletePolicy<ButtonListenerProxy>; friend struct ContainerDeletePolicy<ButtonListenerProxy>;


+ 25
- 27
libs/juce/source/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp View File

@@ -37,7 +37,6 @@ ResizableWindow::ResizableWindow (const String& name, Colour bkgnd, bool shouldA
: TopLevelWindow (name, shouldAddToDesktop) : TopLevelWindow (name, shouldAddToDesktop)
{ {
setBackgroundColour (bkgnd); setBackgroundColour (bkgnd);
initialise (shouldAddToDesktop); initialise (shouldAddToDesktop);
} }
@@ -147,7 +146,7 @@ void ResizableWindow::setContentComponentSize (int width, int height)
{ {
jassert (width > 0 && height > 0); // not a great idea to give it a zero size.. jassert (width > 0 && height > 0); // not a great idea to give it a zero size..
const BorderSize<int> border (getContentComponentBorder());
auto border = getContentComponentBorder();
setSize (width + border.getLeftAndRight(), setSize (width + border.getLeftAndRight(),
height + border.getTopAndBottom()); height + border.getTopAndBottom());
@@ -156,7 +155,7 @@ void ResizableWindow::setContentComponentSize (int width, int height)
BorderSize<int> ResizableWindow::getBorderThickness() BorderSize<int> ResizableWindow::getBorderThickness()
{ {
if (isUsingNativeTitleBar() || isKioskMode()) if (isUsingNativeTitleBar() || isKioskMode())
return BorderSize<int>();
return {};
return BorderSize<int> ((resizableBorder != nullptr && ! isFullScreen()) ? 4 : 1); return BorderSize<int> ((resizableBorder != nullptr && ! isFullScreen()) ? 4 : 1);
} }
@@ -174,7 +173,6 @@ void ResizableWindow::moved()
void ResizableWindow::visibilityChanged() void ResizableWindow::visibilityChanged()
{ {
TopLevelWindow::visibilityChanged(); TopLevelWindow::visibilityChanged();
updateLastPosIfShowing(); updateLastPosIfShowing();
} }
@@ -235,9 +233,9 @@ void ResizableWindow::childBoundsChanged (Component* child)
//============================================================================== //==============================================================================
void ResizableWindow::activeWindowStatusChanged() void ResizableWindow::activeWindowStatusChanged()
{ {
const BorderSize<int> border (getContentComponentBorder());
auto border = getContentComponentBorder();
auto area = getLocalBounds();
Rectangle<int> area (getLocalBounds());
repaint (area.removeFromTop (border.getTop())); repaint (area.removeFromTop (border.getTop()));
repaint (area.removeFromLeft (border.getLeft())); repaint (area.removeFromLeft (border.getLeft()));
repaint (area.removeFromRight (border.getRight())); repaint (area.removeFromRight (border.getRight()));
@@ -287,10 +285,10 @@ bool ResizableWindow::isResizable() const noexcept
|| resizableBorder != nullptr; || resizableBorder != nullptr;
} }
void ResizableWindow::setResizeLimits (const int newMinimumWidth,
const int newMinimumHeight,
const int newMaximumWidth,
const int newMaximumHeight) noexcept
void ResizableWindow::setResizeLimits (int newMinimumWidth,
int newMinimumHeight,
int newMaximumWidth,
int newMaximumHeight) noexcept
{ {
// if you've set up a custom constrainer then these settings won't have any effect.. // if you've set up a custom constrainer then these settings won't have any effect..
jassert (constrainer == &defaultConstrainer || constrainer == nullptr); jassert (constrainer == &defaultConstrainer || constrainer == nullptr);
@@ -315,8 +313,8 @@ void ResizableWindow::setConstrainer (ComponentBoundsConstrainer* newConstrainer
{ {
constrainer = newConstrainer; constrainer = newConstrainer;
const bool useBottomRightCornerResizer = resizableCorner != nullptr;
const bool shouldBeResizable = useBottomRightCornerResizer || resizableBorder != nullptr;
bool useBottomRightCornerResizer = resizableCorner != nullptr;
bool shouldBeResizable = useBottomRightCornerResizer || resizableBorder != nullptr;
resizableCorner = nullptr; resizableCorner = nullptr;
resizableBorder = nullptr; resizableBorder = nullptr;
@@ -337,7 +335,7 @@ void ResizableWindow::setBoundsConstrained (const Rectangle<int>& newBounds)
//============================================================================== //==============================================================================
void ResizableWindow::paint (Graphics& g) void ResizableWindow::paint (Graphics& g)
{ {
LookAndFeel& lf = getLookAndFeel();
auto& lf = getLookAndFeel();
lf.fillResizableWindowBackground (g, getWidth(), getHeight(), lf.fillResizableWindowBackground (g, getWidth(), getHeight(),
getBorderThickness(), *this); getBorderThickness(), *this);
@@ -380,13 +378,12 @@ Colour ResizableWindow::getBackgroundColour() const noexcept
void ResizableWindow::setBackgroundColour (Colour newColour) void ResizableWindow::setBackgroundColour (Colour newColour)
{ {
Colour backgroundColour (newColour);
auto backgroundColour = newColour;
if (! Desktop::canUseSemiTransparentWindows()) if (! Desktop::canUseSemiTransparentWindows())
backgroundColour = newColour.withAlpha (1.0f); backgroundColour = newColour.withAlpha (1.0f);
setColour (backgroundColourId, backgroundColour); setColour (backgroundColourId, backgroundColour);
setOpaque (backgroundColour.isOpaque()); setOpaque (backgroundColour.isOpaque());
repaint(); repaint();
} }
@@ -396,7 +393,7 @@ bool ResizableWindow::isFullScreen() const
{ {
if (isOnDesktop()) if (isOnDesktop())
{ {
ComponentPeer* const peer = getPeer();
auto* peer = getPeer();
return peer != nullptr && peer->isFullScreen(); return peer != nullptr && peer->isFullScreen();
} }
@@ -412,10 +409,10 @@ void ResizableWindow::setFullScreen (const bool shouldBeFullScreen)
if (isOnDesktop()) if (isOnDesktop())
{ {
if (ComponentPeer* const peer = getPeer())
if (auto* peer = getPeer())
{ {
// keep a copy of this intact in case the real one gets messed-up while we're un-maximising // keep a copy of this intact in case the real one gets messed-up while we're un-maximising
const Rectangle<int> lastPos (lastNonFullScreenPos);
auto lastPos = lastNonFullScreenPos;
peer->setFullScreen (shouldBeFullScreen); peer->setFullScreen (shouldBeFullScreen);
@@ -441,7 +438,7 @@ void ResizableWindow::setFullScreen (const bool shouldBeFullScreen)
bool ResizableWindow::isMinimised() const bool ResizableWindow::isMinimised() const
{ {
if (ComponentPeer* const peer = getPeer())
if (auto* peer = getPeer())
return peer->isMinimised(); return peer->isMinimised();
return false; return false;
@@ -451,7 +448,7 @@ void ResizableWindow::setMinimised (const bool shouldMinimise)
{ {
if (shouldMinimise != isMinimised()) if (shouldMinimise != isMinimised())
{ {
if (ComponentPeer* const peer = getPeer())
if (auto* peer = getPeer())
{ {
updateLastPosIfShowing(); updateLastPosIfShowing();
peer->setMinimised (shouldMinimise); peer->setMinimised (shouldMinimise);
@@ -466,7 +463,7 @@ void ResizableWindow::setMinimised (const bool shouldMinimise)
bool ResizableWindow::isKioskMode() const bool ResizableWindow::isKioskMode() const
{ {
if (isOnDesktop()) if (isOnDesktop())
if (ComponentPeer* peer = getPeer())
if (auto* peer = getPeer())
return peer->isKioskMode(); return peer->isKioskMode();
return Desktop::getInstance().getKioskModeComponent() == this; return Desktop::getInstance().getKioskModeComponent() == this;
@@ -490,7 +487,7 @@ void ResizableWindow::updateLastPosIfNotFullScreen()
void ResizableWindow::updatePeerConstrainer() void ResizableWindow::updatePeerConstrainer()
{ {
if (isOnDesktop()) if (isOnDesktop())
if (ComponentPeer* const peer = getPeer())
if (auto* peer = getPeer())
peer->setConstrainer (constrainer); peer->setConstrainer (constrainer);
} }
@@ -528,19 +525,20 @@ bool ResizableWindow::restoreWindowStateFromString (const String& s)
if (newPos.isEmpty()) if (newPos.isEmpty())
return false; return false;
ComponentPeer* const peer = isOnDesktop() ? getPeer() : nullptr;
auto* peer = isOnDesktop() ? getPeer() : nullptr;
if (peer != nullptr) if (peer != nullptr)
peer->getFrameSize().addTo (newPos); peer->getFrameSize().addTo (newPos);
{ {
Desktop& desktop = Desktop::getInstance();
RectangleList<int> allMonitors (desktop.getDisplays().getRectangleList (true));
auto& desktop = Desktop::getInstance();
auto allMonitors = desktop.getDisplays().getRectangleList (true);
allMonitors.clipTo (newPos); allMonitors.clipTo (newPos);
const Rectangle<int> onScreenArea (allMonitors.getBounds());
auto onScreenArea = allMonitors.getBounds();
if (onScreenArea.getWidth() * onScreenArea.getHeight() < 32 * 32) if (onScreenArea.getWidth() * onScreenArea.getHeight() < 32 * 32)
{ {
const Rectangle<int> screen (desktop.getDisplays().getDisplayContaining (newPos.getCentre()).userArea);
auto screen = desktop.getDisplays().getDisplayContaining (newPos.getCentre()).userArea;
newPos.setSize (jmin (newPos.getWidth(), screen.getWidth()), newPos.setSize (jmin (newPos.getWidth(), screen.getWidth()),
jmin (newPos.getHeight(), screen.getHeight())); jmin (newPos.getHeight(), screen.getHeight()));


+ 17
- 26
libs/juce/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp View File

@@ -32,14 +32,8 @@ class TopLevelWindowManager : private Timer,
private DeletedAtShutdown private DeletedAtShutdown
{ {
public: public:
TopLevelWindowManager() : currentActive (nullptr)
{
}
~TopLevelWindowManager()
{
clearSingletonInstance();
}
TopLevelWindowManager() {}
~TopLevelWindowManager() { clearSingletonInstance(); }
juce_DeclareSingleton_SingleThreaded_Minimal (TopLevelWindowManager) juce_DeclareSingleton_SingleThreaded_Minimal (TopLevelWindowManager)
@@ -52,14 +46,14 @@ public:
{ {
startTimer (jmin (1731, getTimerInterval() * 2)); startTimer (jmin (1731, getTimerInterval() * 2));
TopLevelWindow* newActive = findCurrentlyActiveWindow();
auto* newActive = findCurrentlyActiveWindow();
if (newActive != currentActive) if (newActive != currentActive)
{ {
currentActive = newActive; currentActive = newActive;
for (int i = windows.size(); --i >= 0;) for (int i = windows.size(); --i >= 0;)
if (TopLevelWindow* tlw = windows[i])
if (auto* tlw = windows[i])
tlw->setWindowActive (isWindowActive (tlw)); tlw->setWindowActive (isWindowActive (tlw));
Desktop::getInstance().triggerFocusCallback(); Desktop::getInstance().triggerFocusCallback();
@@ -83,14 +77,14 @@ public:
windows.removeFirstMatchingValue (w); windows.removeFirstMatchingValue (w);
if (windows.size() == 0)
if (windows.isEmpty())
deleteInstance(); deleteInstance();
} }
Array<TopLevelWindow*> windows; Array<TopLevelWindow*> windows;
private: private:
TopLevelWindow* currentActive;
TopLevelWindow* currentActive = nullptr;
void timerCallback() override void timerCallback() override
{ {
@@ -109,8 +103,8 @@ private:
{ {
if (Process::isForegroundProcess()) if (Process::isForegroundProcess())
{ {
Component* const focusedComp = Component::getCurrentlyFocusedComponent();
TopLevelWindow* w = dynamic_cast<TopLevelWindow*> (focusedComp);
auto* focusedComp = Component::getCurrentlyFocusedComponent();
auto* w = dynamic_cast<TopLevelWindow*> (focusedComp);
if (w == nullptr && focusedComp != nullptr) if (w == nullptr && focusedComp != nullptr)
w = focusedComp->findParentComponentOfClass<TopLevelWindow>(); w = focusedComp->findParentComponentOfClass<TopLevelWindow>();
@@ -133,16 +127,13 @@ juce_ImplementSingleton_SingleThreaded (TopLevelWindowManager)
void juce_checkCurrentlyFocusedTopLevelWindow(); void juce_checkCurrentlyFocusedTopLevelWindow();
void juce_checkCurrentlyFocusedTopLevelWindow() void juce_checkCurrentlyFocusedTopLevelWindow()
{ {
if (TopLevelWindowManager* const wm = TopLevelWindowManager::getInstanceWithoutCreating())
if (auto* wm = TopLevelWindowManager::getInstanceWithoutCreating())
wm->checkFocusAsync(); wm->checkFocusAsync();
} }
//============================================================================== //==============================================================================
TopLevelWindow::TopLevelWindow (const String& name, const bool shouldAddToDesktop) TopLevelWindow::TopLevelWindow (const String& name, const bool shouldAddToDesktop)
: Component (name),
useDropShadow (true),
useNativeTitleBar (false),
isCurrentlyActive (false)
: Component (name)
{ {
setOpaque (true); setOpaque (true);
@@ -165,7 +156,7 @@ TopLevelWindow::~TopLevelWindow()
//============================================================================== //==============================================================================
void TopLevelWindow::focusOfChildComponentChanged (FocusChangeType) void TopLevelWindow::focusOfChildComponentChanged (FocusChangeType)
{ {
TopLevelWindowManager* const wm = TopLevelWindowManager::getInstance();
auto* wm = TopLevelWindowManager::getInstance();
if (hasKeyboardFocus (true)) if (hasKeyboardFocus (true))
wm->checkFocus(); wm->checkFocus();
@@ -194,7 +185,7 @@ bool TopLevelWindow::isUsingNativeTitleBar() const noexcept
void TopLevelWindow::visibilityChanged() void TopLevelWindow::visibilityChanged()
{ {
if (isShowing()) if (isShowing())
if (ComponentPeer* p = getPeer())
if (auto* p = getPeer())
if ((p->getStyleFlags() & (ComponentPeer::windowIsTemporary if ((p->getStyleFlags() & (ComponentPeer::windowIsTemporary
| ComponentPeer::windowIgnoresKeyPresses)) == 0) | ComponentPeer::windowIgnoresKeyPresses)) == 0)
toFront (true); toFront (true);
@@ -302,10 +293,10 @@ void TopLevelWindow::centreAroundComponent (Component* c, const int width, const
} }
else else
{ {
Point<int> targetCentre (c->localPointToGlobal (c->getLocalBounds().getCentre()));
Rectangle<int> parentArea (c->getParentMonitorArea());
auto targetCentre = c->localPointToGlobal (c->getLocalBounds().getCentre());
auto parentArea = c->getParentMonitorArea();
if (Component* const parent = getParentComponent())
if (auto* parent = getParentComponent())
{ {
targetCentre = parent->getLocalPoint (nullptr, targetCentre); targetCentre = parent->getLocalPoint (nullptr, targetCentre);
parentArea = parent->getLocalBounds(); parentArea = parent->getLocalBounds();
@@ -336,13 +327,13 @@ TopLevelWindow* TopLevelWindow::getActiveTopLevelWindow() noexcept
for (int i = TopLevelWindow::getNumTopLevelWindows(); --i >= 0;) for (int i = TopLevelWindow::getNumTopLevelWindows(); --i >= 0;)
{ {
TopLevelWindow* const tlw = TopLevelWindow::getTopLevelWindow (i);
auto* tlw = TopLevelWindow::getTopLevelWindow (i);
if (tlw->isActiveWindow()) if (tlw->isActiveWindow())
{ {
int numTWLParents = 0; int numTWLParents = 0;
for (const Component* c = tlw->getParentComponent(); c != nullptr; c = c->getParentComponent())
for (auto* c = tlw->getParentComponent(); c != nullptr; c = c->getParentComponent())
if (dynamic_cast<const TopLevelWindow*> (c) != nullptr) if (dynamic_cast<const TopLevelWindow*> (c) != nullptr)
++numTWLParents; ++numTWLParents;


+ 1
- 1
libs/juce/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.h View File

@@ -153,7 +153,7 @@ protected:
private: private:
friend class TopLevelWindowManager; friend class TopLevelWindowManager;
friend class ResizableWindow; friend class ResizableWindow;
bool useDropShadow, useNativeTitleBar, isCurrentlyActive;
bool useDropShadow = true, useNativeTitleBar = false, isCurrentlyActive = false;
ScopedPointer<DropShadower> shadower; ScopedPointer<DropShadower> shadower;
void setWindowActive (bool); void setWindowActive (bool);


+ 2
- 2
libs/juce/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp View File

@@ -61,8 +61,8 @@ CodeEditorComponent::ColourScheme CPlusPlusCodeTokeniser::getDefaultColourScheme
CodeEditorComponent::ColourScheme cs; CodeEditorComponent::ColourScheme cs;
for (unsigned int i = 0; i < sizeof (types) / sizeof (types[0]); ++i) // (NB: numElementsInArray doesn't work here in GCC4.2)
cs.set (types[i].name, Colour (types[i].colour));
for (auto& t : types)
cs.set (t.name, Colour (t.colour));
return cs; return cs;
} }


+ 6
- 6
libs/juce/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp View File

@@ -84,7 +84,7 @@ struct LuaTokeniserFunctions
while (CppTokeniserFunctions::isIdentifierBody (source.peekNextChar())) while (CppTokeniserFunctions::isIdentifierBody (source.peekNextChar()))
{ {
const juce_wchar c = source.nextChar();
auto c = source.nextChar();
if (tokenLength < 20) if (tokenLength < 20)
possible.write (c); possible.write (c);
@@ -108,7 +108,7 @@ struct LuaTokeniserFunctions
{ {
source.skipWhitespace(); source.skipWhitespace();
const juce_wchar firstChar = source.peekNextChar();
auto firstChar = source.peekNextChar();
switch (firstChar) switch (firstChar)
{ {
@@ -119,7 +119,7 @@ struct LuaTokeniserFunctions
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
case '.': case '.':
{ {
int result = CppTokeniserFunctions::parseNumber (source);
auto result = CppTokeniserFunctions::parseNumber (source);
if (result == LuaTokeniser::tokenType_error) if (result == LuaTokeniser::tokenType_error)
{ {
@@ -157,7 +157,7 @@ struct LuaTokeniserFunctions
case '-': case '-':
{ {
source.skip(); source.skip();
int result = CppTokeniserFunctions::parseNumber (source);
auto result = CppTokeniserFunctions::parseNumber (source);
if (source.peekNextChar() == '-') if (source.peekNextChar() == '-')
{ {
@@ -231,8 +231,8 @@ CodeEditorComponent::ColourScheme LuaTokeniser::getDefaultColourScheme()
CodeEditorComponent::ColourScheme cs; CodeEditorComponent::ColourScheme cs;
for (unsigned int i = 0; i < sizeof (types) / sizeof (types[0]); ++i) // (NB: numElementsInArray doesn't work here in GCC4.2)
cs.set (types[i].name, types[i].colour);
for (auto& t : types)
cs.set (t.name, Colour (t.colour));
return cs; return cs;
} }


+ 7
- 7
libs/juce/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp View File

@@ -53,8 +53,8 @@ CodeEditorComponent::ColourScheme XmlTokeniser::getDefaultColourScheme()
CodeEditorComponent::ColourScheme cs; CodeEditorComponent::ColourScheme cs;
for (unsigned int i = 0; i < sizeof (types) / sizeof (types[0]); ++i) // (NB: numElementsInArray doesn't work here in GCC4.2)
cs.set (types[i].name, Colour (types[i].colour));
for (auto& t : types)
cs.set (t.name, Colour (t.colour));
return cs; return cs;
} }
@@ -66,7 +66,7 @@ static void skipToEndOfXmlDTD (Iterator& source) noexcept
for (;;) for (;;)
{ {
const juce_wchar c = source.nextChar();
auto c = source.nextChar();
if (c == 0 || (c == '>' && lastWasQuestionMark)) if (c == 0 || (c == '>' && lastWasQuestionMark))
break; break;
@@ -78,11 +78,11 @@ static void skipToEndOfXmlDTD (Iterator& source) noexcept
template <typename Iterator> template <typename Iterator>
static void skipToEndOfXmlComment (Iterator& source) noexcept static void skipToEndOfXmlComment (Iterator& source) noexcept
{ {
juce_wchar last[2] = { 0 };
juce_wchar last[2] = {};
for (;;) for (;;)
{ {
const juce_wchar c = source.nextChar();
auto c = source.nextChar();
if (c == 0 || (c == '>' && last[0] == '-' && last[1] == '-')) if (c == 0 || (c == '>' && last[0] == '-' && last[1] == '-'))
break; break;
@@ -95,7 +95,7 @@ static void skipToEndOfXmlComment (Iterator& source) noexcept
int XmlTokeniser::readNextToken (CodeDocument::Iterator& source) int XmlTokeniser::readNextToken (CodeDocument::Iterator& source)
{ {
source.skipWhitespace(); source.skipWhitespace();
const juce_wchar firstChar = source.peekNextChar();
auto firstChar = source.peekNextChar();
switch (firstChar) switch (firstChar)
{ {
@@ -110,7 +110,7 @@ int XmlTokeniser::readNextToken (CodeDocument::Iterator& source)
{ {
source.skip(); source.skip();
source.skipWhitespace(); source.skipWhitespace();
const juce_wchar nextChar = source.peekNextChar();
auto nextChar = source.peekNextChar();
if (nextChar == '?') if (nextChar == '?')
{ {


Loading…
Cancel
Save