From 6475111aa550d34b5ae1fe20a206ad614622848b Mon Sep 17 00:00:00 2001 From: hogliux Date: Thu, 27 Apr 2017 18:22:17 +0100 Subject: [PATCH 01/54] Fixed an incorrect UTF8 string character conversion in WebBrowserComponent --- modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index 83f617b704..20f7615ec2 100644 --- a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -86,7 +86,7 @@ private: { if ([frame isEqual: [sender mainFrame]]) { - const char* errorString = [[error localizedDescription] UTF8String]; + String errorString (nsStringToJuce ([error localizedDescription])); bool proceedToErrorPage = getOwner (self)->pageLoadHadNetworkError (errorString); From 8689df5590c68546fb50bfe12ff051c1e858cfe1 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 10:18:33 +0100 Subject: [PATCH 02/54] Fixed a few c++17 warnings --- modules/juce_core/containers/juce_Variant.h | 2 - modules/juce_graphics/images/juce_Image.cpp | 8 +--- .../components/juce_Component.cpp | 45 +++++++++---------- .../components/juce_Component.h | 23 +++++++--- .../juce_RelativeCoordinatePositioner.cpp | 18 +++----- .../juce_RelativeCoordinatePositioner.h | 23 +++++----- 6 files changed, 55 insertions(+), 64 deletions(-) diff --git a/modules/juce_core/containers/juce_Variant.h b/modules/juce_core/containers/juce_Variant.h index 522060864c..24a384d1c3 100644 --- a/modules/juce_core/containers/juce_Variant.h +++ b/modules/juce_core/containers/juce_Variant.h @@ -50,8 +50,6 @@ public: const var& thisObject; const var* arguments; int numArguments; - - JUCE_DECLARE_NON_COPYABLE (NativeFunctionArgs) }; #if JUCE_COMPILER_SUPPORTS_LAMBDAS diff --git a/modules/juce_graphics/images/juce_Image.cpp b/modules/juce_graphics/images/juce_Image.cpp index bb456272e0..278968838b 100644 --- a/modules/juce_graphics/images/juce_Image.cpp +++ b/modules/juce_graphics/images/juce_Image.cpp @@ -516,17 +516,13 @@ static void performPixelOp (const Image::BitmapData& data, const PixelOperation& struct AlphaMultiplyOp { - AlphaMultiplyOp (float alpha_) noexcept : alpha (alpha_) {} - - const float alpha; + float alpha; template void operator() (PixelType& pixel) const { pixel.multiplyAlpha (alpha); } - - JUCE_DECLARE_NON_COPYABLE (AlphaMultiplyOp) }; void Image::multiplyAllAlphas (const float amountToMultiplyBy) @@ -534,7 +530,7 @@ void Image::multiplyAllAlphas (const float amountToMultiplyBy) jassert (hasAlphaChannel()); const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite); - performPixelOp (destData, AlphaMultiplyOp (amountToMultiplyBy)); + performPixelOp (destData, AlphaMultiplyOp { amountToMultiplyBy }); } struct DesaturateOp diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 016eb352fb..5e128ff0ea 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -410,7 +410,7 @@ struct Component::ComponentHelpers if (child.isVisible() && ! child.isTransformed()) { - const Rectangle newClip (clipRect.getIntersection (child.boundsRelativeToParent)); + auto newClip = clipRect.getIntersection (child.boundsRelativeToParent); if (! newClip.isEmpty()) { @@ -1070,7 +1070,7 @@ Point Component::getLocalPoint (const Component* source, Point poi return ComponentHelpers::convertCoordinate (this, source, point); } -Rectangle Component::getLocalArea (const Component* source, const Rectangle& area) const +Rectangle Component::getLocalArea (const Component* source, Rectangle area) const { return ComponentHelpers::convertCoordinate (this, source, area); } @@ -1085,7 +1085,7 @@ Point Component::localPointToGlobal (Point point) const return ComponentHelpers::convertCoordinate (nullptr, this, point); } -Rectangle Component::localAreaToGlobal (const Rectangle& area) const +Rectangle Component::localAreaToGlobal (Rectangle area) const { return ComponentHelpers::convertCoordinate (nullptr, this, area); } @@ -1215,12 +1215,12 @@ void Component::sendMovedResizedMessages (const bool wasMoved, const bool wasRes *this, wasMoved, wasResized); } -void Component::setSize (const int w, const int h) +void Component::setSize (int w, int h) { setBounds (getX(), getY(), w, h); } -void Component::setTopLeftPosition (const int x, const int y) +void Component::setTopLeftPosition (int x, int y) { setBounds (x, y, getWidth(), getHeight()); } @@ -1235,7 +1235,7 @@ void Component::setTopRightPosition (const int x, const int y) setTopLeftPosition (x - getWidth(), y); } -void Component::setBounds (const Rectangle& r) +void Component::setBounds (Rectangle r) { setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight()); } @@ -1262,13 +1262,10 @@ void Component::setBoundsRelative (const float x, const float y, roundToInt (h * ph)); } -void Component::setCentrePosition (const int x, const int y) -{ - setTopLeftPosition (x - getWidth() / 2, - y - getHeight() / 2); -} +void Component::setCentrePosition (Point p) { setBounds (getBounds().withCentre (p)); } +void Component::setCentrePosition (int x, int y) { setCentrePosition ({x, y}); } -void Component::setCentreRelative (const float x, const float y) +void Component::setCentreRelative (float x, float y) { setCentrePosition (roundToInt (getParentWidth() * x), roundToInt (getParentHeight() * y)); @@ -1276,14 +1273,14 @@ void Component::setCentreRelative (const float x, const float y) void Component::centreWithSize (const int width, const int height) { - const Rectangle parentArea (ComponentHelpers::getParentOrMainMonitorBounds (*this)); + auto parentArea = ComponentHelpers::getParentOrMainMonitorBounds (*this); setBounds (parentArea.getCentreX() - width / 2, parentArea.getCentreY() - height / 2, width, height); } -void Component::setBoundsInset (const BorderSize& borders) +void Component::setBoundsInset (BorderSize borders) { setBounds (borders.subtractedFrom (ComponentHelpers::getParentOrMainMonitorBounds (*this))); } @@ -1886,7 +1883,7 @@ void Component::repaint (const int x, const int y, const int w, const int h) internalRepaint (Rectangle (x, y, w, h)); } -void Component::repaint (const Rectangle& area) +void Component::repaint (Rectangle area) { internalRepaint (area); } @@ -1923,9 +1920,9 @@ void Component::internalRepaintUnchecked (Rectangle area, const bool isEnti if (auto* peer = getPeer()) { // Tweak the scaling so that the component's integer size exactly aligns with the peer's scaled size - const Rectangle peerBounds (peer->getBounds()); - const Rectangle scaled (area * Point (peerBounds.getWidth() / (float) getWidth(), - peerBounds.getHeight() / (float) getHeight())); + auto peerBounds = peer->getBounds(); + auto scaled = area * Point (peerBounds.getWidth() / (float) getWidth(), + peerBounds.getHeight() / (float) getHeight()); peer->repaint (affineTransform != nullptr ? scaled.transformedBy (*affineTransform) : scaled); } @@ -1964,7 +1961,7 @@ void Component::paintWithinParentContext (Graphics& g) void Component::paintComponentAndChildren (Graphics& g) { - const Rectangle clipBounds (g.getClipBounds()); + auto clipBounds = g.getClipBounds(); if (flags.dontClipGraphicsFlag) { @@ -2049,9 +2046,9 @@ void Component::paintEntireComponent (Graphics& g, const bool ignoreAlphaLevel) if (effect != nullptr) { - const float scale = g.getInternalContext().getPhysicalPixelScaleFactor(); + auto scale = g.getInternalContext().getPhysicalPixelScaleFactor(); - const Rectangle scaledBounds (getLocalBounds() * scale); + auto scaledBounds = getLocalBounds() * scale; Image effectImage (flags.opaqueFlag ? Image::RGB : Image::ARGB, scaledBounds.getWidth(), scaledBounds.getHeight(), ! flags.opaqueFlag); @@ -2092,10 +2089,10 @@ void Component::setPaintingIsUnclipped (const bool shouldPaintWithoutClipping) n } //============================================================================== -Image Component::createComponentSnapshot (const Rectangle& areaToGrab, +Image Component::createComponentSnapshot (Rectangle areaToGrab, bool clipImageToComponentBounds, float scaleFactor) { - Rectangle r (areaToGrab); + auto r = areaToGrab; if (clipImageToComponentBounds) r = r.getIntersection (getLocalBounds()); @@ -2132,7 +2129,7 @@ void Component::setComponentEffect (ImageEffectFilter* const newEffect) //============================================================================== LookAndFeel& Component::getLookAndFeel() const noexcept { - for (const Component* c = this; c != nullptr; c = c->parentComponent) + for (auto* c = this; c != nullptr; c = c->parentComponent) if (c->lookAndFeel != nullptr) return *(c->lookAndFeel); diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index 5c2fc7a170..b390ff7252 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -299,7 +299,7 @@ public: bounds will no longer be a direct reflection of the position at which it appears within its parent, as the transform will be applied to its bounding box. */ - const Rectangle& getBounds() const noexcept { return boundsRelativeToParent; } + Rectangle getBounds() const noexcept { return boundsRelativeToParent; } /** Returns the component's bounds, relative to its own origin. This is like getBounds(), but returns the rectangle in local coordinates, In practice, it'll @@ -366,7 +366,7 @@ public: the smallest rectangle that fully contains the transformed area. */ Rectangle getLocalArea (const Component* sourceComponent, - const Rectangle& areaRelativeToSourceComponent) const; + Rectangle areaRelativeToSourceComponent) const; /** Converts a point relative to this component's top-left into a screen coordinate. @see getLocalPoint, localAreaToGlobal @@ -385,7 +385,7 @@ public: the smallest rectangle that fully contains the transformed area. @see getLocalPoint, localPointToGlobal */ - Rectangle localAreaToGlobal (const Rectangle& localArea) const; + Rectangle localAreaToGlobal (Rectangle localArea) const; //============================================================================== /** Moves the component to a new position. @@ -471,7 +471,7 @@ public: @see setBounds */ - void setBounds (const Rectangle& newBounds); + void setBounds (Rectangle newBounds); /** Changes the component's position and size. @@ -514,7 +514,7 @@ public: @see setBounds */ - void setBoundsInset (const BorderSize& borders); + void setBoundsInset (BorderSize borders); /** Positions the component within a given rectangle, keeping its proportions unchanged. @@ -543,6 +543,15 @@ public: */ void setCentrePosition (int x, int y); + /** Changes the position of the component's centre. + + Leaves the component's size unchanged, but sets the position of its centre + relative to its parent's top-left. + + @see setBounds + */ + void setCentrePosition (Point newCentrePosition); + /** Changes the position of the component's centre. Leaves the size unchanged, but positions its centre relative to its parent's size. @@ -975,7 +984,7 @@ public: @see repaint() */ - void repaint (const Rectangle& area); + void repaint (Rectangle area); //============================================================================== /** Makes the component use an internal buffer to optimise its redrawing. @@ -1007,7 +1016,7 @@ public: @see paintEntireComponent */ - Image createComponentSnapshot (const Rectangle& areaToGrab, + Image createComponentSnapshot (Rectangle areaToGrab, bool clipImageToComponentBounds = true, float scaleFactor = 1.0f); diff --git a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp index 56781cbeee..d198829f56 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp @@ -24,9 +24,8 @@ ============================================================================== */ -class MarkerListScope : public Expression::Scope +struct MarkerListScope : public Expression::Scope { -public: MarkerListScope (Component& comp) : component (comp) {} Expression getSymbolValue (const String& symbol) const override @@ -40,7 +39,7 @@ public: MarkerList* list; - if (const MarkerList::Marker* const marker = findMarker (component, symbol, list)) + if (auto* marker = findMarker (component, symbol, list)) return Expression (marker->position.getExpression().evaluate (*this)); return Expression::Scope::getSymbolValue (symbol); @@ -50,7 +49,7 @@ public: { if (scopeName == RelativeCoordinate::Strings::parent) { - if (Component* const parent = component.getParentComponent()) + if (auto* parent = component.getParentComponent()) { visitor.visit (MarkerListScope (*parent)); return; @@ -84,10 +83,7 @@ public: return marker; } -private: Component& component; - - JUCE_DECLARE_NON_COPYABLE (MarkerListScope) }; //============================================================================== @@ -127,9 +123,9 @@ Expression RelativeCoordinatePositionerBase::ComponentScope::getSymbolValue (con void RelativeCoordinatePositionerBase::ComponentScope::visitRelativeScope (const String& scopeName, Visitor& visitor) const { - if (Component* const targetComp = (scopeName == RelativeCoordinate::Strings::parent) - ? component.getParentComponent() - : findSiblingComponent (scopeName)) + if (auto* targetComp = (scopeName == RelativeCoordinate::Strings::parent) + ? component.getParentComponent() + : findSiblingComponent (scopeName)) visitor.visit (ComponentScope (*targetComp)); else Expression::Scope::visitRelativeScope (scopeName, visitor); @@ -217,8 +213,6 @@ public: private: RelativeCoordinatePositionerBase& positioner; bool& ok; - - JUCE_DECLARE_NON_COPYABLE (DependencyFinderScope) }; //============================================================================== diff --git a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h index 8877dbf0cd..0845e6359b 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h +++ b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h @@ -36,7 +36,7 @@ class JUCE_API RelativeCoordinatePositionerBase : public Component::Positioner public MarkerList::Listener { public: - RelativeCoordinatePositionerBase (Component& component); + RelativeCoordinatePositionerBase (Component&); ~RelativeCoordinatePositionerBase(); void componentMovedOrResized (Component&, bool, bool); @@ -44,31 +44,28 @@ public: void componentChildrenChanged (Component&); void componentBeingDeleted (Component&); void markersChanged (MarkerList*); - void markerListBeingDeleted (MarkerList* markerList); + void markerListBeingDeleted (MarkerList*); void apply(); - bool addCoordinate (const RelativeCoordinate& coord); - bool addPoint (const RelativePoint& point); + bool addCoordinate (const RelativeCoordinate&); + bool addPoint (const RelativePoint&); //============================================================================== /** Used for resolving a RelativeCoordinate expression in the context of a component. */ class ComponentScope : public Expression::Scope { public: - ComponentScope (Component& component); + ComponentScope (Component&); Expression getSymbolValue (const String& symbol) const; - void visitRelativeScope (const String& scopeName, Visitor& visitor) const; + void visitRelativeScope (const String& scopeName, Visitor&) const; String getScopeUID() const; protected: Component& component; Component* findSiblingComponent (const String& componentID) const; - - private: - JUCE_DECLARE_NON_COPYABLE (ComponentScope) }; protected: @@ -78,12 +75,12 @@ protected: private: class DependencyFinderScope; friend class DependencyFinderScope; - Array sourceComponents; - Array sourceMarkerLists; + Array sourceComponents; + Array sourceMarkerLists; bool registeredOk; - void registerComponentListener (Component& comp); - void registerMarkerListListener (MarkerList* const list); + void registerComponentListener (Component&); + void registerMarkerListListener (MarkerList*); void unregisterListeners(); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativeCoordinatePositionerBase) From a3e6c81911f4b37c18410e6bcf310d9463eedb16 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 10:19:51 +0100 Subject: [PATCH 03/54] Fixed an assertion in MidiMessageCollector that would have failed to trigger --- .../midi_io/juce_MidiMessageCollector.cpp | 24 ++++++++++--------- .../midi_io/juce_MidiMessageCollector.h | 7 ++++-- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp index cf4977a33f..66bab1f852 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp +++ b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp @@ -21,8 +21,6 @@ */ MidiMessageCollector::MidiMessageCollector() - : lastCallbackTime (0), - sampleRate (44100.0001) { } @@ -36,6 +34,9 @@ void MidiMessageCollector::reset (const double newSampleRate) jassert (newSampleRate > 0); const ScopedLock sl (midiCallbackLock); + #if JUCE_DEBUG + hasCalledReset = true; + #endif sampleRate = newSampleRate; incomingMessages.clear(); lastCallbackTime = Time::getMillisecondCounterHiRes(); @@ -43,8 +44,9 @@ void MidiMessageCollector::reset (const double newSampleRate) void MidiMessageCollector::addMessageToQueue (const MidiMessage& message) { - // you need to call reset() to set the correct sample rate before using this object - jassert (sampleRate != 44100.0001); + #if JUCE_DEBUG + jassert (hasCalledReset); // you need to call reset() to set the correct sample rate before using this object + #endif // the messages that come in here need to be time-stamped correctly - see MidiInput // for details of what the number should be. @@ -52,8 +54,7 @@ void MidiMessageCollector::addMessageToQueue (const MidiMessage& message) const ScopedLock sl (midiCallbackLock); - const int sampleNumber - = (int) ((message.getTimeStamp() - 0.001 * lastCallbackTime) * sampleRate); + auto sampleNumber = (int) ((message.getTimeStamp() - 0.001 * lastCallbackTime) * sampleRate); incomingMessages.addEvent (message, sampleNumber); @@ -66,12 +67,14 @@ void MidiMessageCollector::addMessageToQueue (const MidiMessage& message) void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer, const int numSamples) { - // you need to call reset() to set the correct sample rate before using this object - jassert (sampleRate != 44100.0001); + #if JUCE_DEBUG + jassert (hasCalledReset); // you need to call reset() to set the correct sample rate before using this object + #endif + jassert (numSamples > 0); - const double timeNow = Time::getMillisecondCounterHiRes(); - const double msElapsed = timeNow - lastCallbackTime; + auto timeNow = Time::getMillisecondCounterHiRes(); + auto msElapsed = timeNow - lastCallbackTime; const ScopedLock sl (midiCallbackLock); lastCallbackTime = timeNow; @@ -79,7 +82,6 @@ void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer, if (! incomingMessages.isEmpty()) { int numSourceSamples = jmax (1, roundToInt (msElapsed * 0.001 * sampleRate)); - int startSample = 0; int scale = 1 << 16; diff --git a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h index dc9bb8f372..97f2dd6bb5 100644 --- a/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h +++ b/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h @@ -89,10 +89,13 @@ public: private: //============================================================================== - double lastCallbackTime; + double lastCallbackTime = 0; CriticalSection midiCallbackLock; MidiBuffer incomingMessages; - double sampleRate; + double sampleRate = 44100.0; + #if JUCE_DEBUG + bool hasCalledReset = false; + #endif JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiMessageCollector) }; From 14bffbba3cec73bbdd1f84a3810b67efacf4b961 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 10:44:16 +0100 Subject: [PATCH 04/54] Avoided unnecessary timer activity when splash screen is disabled --- modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp b/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp index 624f23bfb6..8426a04d6d 100644 --- a/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp +++ b/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp @@ -282,8 +282,6 @@ JUCESplashScreen::JUCESplashScreen (Component& parent) JUCESplashScreen::~JUCESplashScreen() { - if (auto* p = getParentComponent()) - p->removeChildComponent (this); } void JUCESplashScreen::paint (Graphics& g) @@ -292,7 +290,8 @@ void JUCESplashScreen::paint (Graphics& g) Point bottomRight (0.9f * r.getWidth(), 0.9f * r.getHeight()); - ColourGradient cg (Colour (0x00000000), Line (0.0f, r.getHeight(), r.getWidth(), 0.0f).findNearestPointTo (bottomRight), + ColourGradient cg (Colour (0x00000000), Line (0.0f, r.getHeight(), r.getWidth(), 0.0f) + .findNearestPointTo (bottomRight), Colour (0xff000000), bottomRight, false); cg.addColour (0.25f, Colour (0x10000000)); cg.addColour (0.50f, Colour (0x30000000)); @@ -311,6 +310,7 @@ void JUCESplashScreen::paint (Graphics& g) void JUCESplashScreen::timerCallback() { + #if JUCE_DISPLAY_SPLASH_SCREEN if (isVisible() && ! hasStartedFading) { hasStartedFading = true; @@ -318,6 +318,7 @@ void JUCESplashScreen::timerCallback() } if (hasStartedFading && ! fader.isAnimating()) + #endif delete this; } From e46f1d5990be66284cb8867343778dcb80a1dae2 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 10:45:41 +0100 Subject: [PATCH 05/54] Disabled another warning in the VST3 headers --- modules/juce_audio_processors/format_types/juce_VST3Headers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/juce_audio_processors/format_types/juce_VST3Headers.h b/modules/juce_audio_processors/format_types/juce_VST3Headers.h index 248c8c8807..8721cafe37 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Headers.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Headers.h @@ -47,6 +47,7 @@ #pragma clang diagnostic ignored "-Wsign-compare" #pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" #pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic ignored "-Wextra-semi" #endif #undef DEVELOPMENT From 025513c5d39287598e76474c74e7d8143b1c9fa4 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 10:50:17 +0100 Subject: [PATCH 06/54] Made MemoryMappedAudioFormatReader::mapSectionOfFile() virtual --- .../format/juce_MemoryMappedAudioFormatReader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h b/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h index d1e7e79316..93deee3862 100644 --- a/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h +++ b/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h @@ -63,7 +63,7 @@ public: bool mapEntireFile(); /** Attempts to map a section of the file into memory. */ - bool mapSectionOfFile (Range samplesToMap); + virtual bool mapSectionOfFile (Range samplesToMap); /** Returns the sample range that's currently memory-mapped and available for reading. */ Range getMappedSection() const noexcept { return mappedSection; } From d7d1a9a99ebb0670552ab7b03ad60cbf457895d6 Mon Sep 17 00:00:00 2001 From: hogliux Date: Tue, 2 May 2017 11:25:23 +0100 Subject: [PATCH 07/54] Call AAX CreatePackage.bat script correctly from post-build script to catch any errors --- .../Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h index d42b13ca73..41c2b28fc5 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h @@ -344,7 +344,7 @@ public: const String macOSDir = bundleContents + String ("\\") + (is64Bit ? "x64" : "Win32"); const String executable = macOSDir + String ("\\") + config.getOutputFilename (".aaxplugin", true); - return String ("copy /Y \"") + getOutputFilePath (config) + String ("\" \"") + executable + String ("\"\r\n") + + return String ("copy /Y \"") + getOutputFilePath (config) + String ("\" \"") + executable + String ("\"\r\ncall ") + createRebasedPath (bundleScript) + String (" \"") + macOSDir + String ("\" ") + createRebasedPath (iconFilePath); } From 171aa9421573b8b712f146b5eee2da06794d4460 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 12:04:50 +0100 Subject: [PATCH 08/54] Fix for MidiMessage::endOfTrack() --- modules/juce_audio_basics/midi/juce_MidiMessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_audio_basics/midi/juce_MidiMessage.cpp b/modules/juce_audio_basics/midi/juce_MidiMessage.cpp index 6e4a80137a..e9e6c1be3a 100644 --- a/modules/juce_audio_basics/midi/juce_MidiMessage.cpp +++ b/modules/juce_audio_basics/midi/juce_MidiMessage.cpp @@ -855,7 +855,7 @@ MidiMessage MidiMessage::keySignatureMetaEvent (int numberOfSharpsOrFlats, bool MidiMessage MidiMessage::endOfTrack() noexcept { - return { 0xff, 0x2f }; + return { 0xff, 0x2f, 0x00 }; } //============================================================================== From 57a3cb58ec1db5d2fefc16e1f1b6005d8942d782 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 12:23:35 +0100 Subject: [PATCH 09/54] Removed incorrect constness from ColourSelector::setSwatchColour --- .../properties/jucer_ColourPropertyComponent.h | 2 +- .../Source/Utility/jucer_StoredSettings.cpp | 2 +- .../Source/Utility/jucer_StoredSettings.h | 2 +- .../juce_gui_extra/misc/juce_ColourSelector.cpp | 17 +++++++---------- .../juce_gui_extra/misc/juce_ColourSelector.h | 2 +- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/extras/Projucer/Source/ComponentEditor/properties/jucer_ColourPropertyComponent.h b/extras/Projucer/Source/ComponentEditor/properties/jucer_ColourPropertyComponent.h index a4f52e5e82..9852315be6 100644 --- a/extras/Projucer/Source/ComponentEditor/properties/jucer_ColourPropertyComponent.h +++ b/extras/Projucer/Source/ComponentEditor/properties/jucer_ColourPropertyComponent.h @@ -163,7 +163,7 @@ public: return getAppSettings().swatchColours [index]; } - void setSwatchColour (int index, const Colour& newColour) const override + void setSwatchColour (int index, const Colour& newColour) override { getAppSettings().swatchColours.set (index, newColour); } diff --git a/extras/Projucer/Source/Utility/jucer_StoredSettings.cpp b/extras/Projucer/Source/Utility/jucer_StoredSettings.cpp index fb849d4a9f..e542e59c73 100644 --- a/extras/Projucer/Source/Utility/jucer_StoredSettings.cpp +++ b/extras/Projucer/Source/Utility/jucer_StoredSettings.cpp @@ -208,7 +208,7 @@ Colour StoredSettings::ColourSelectorWithSwatches::getSwatchColour (int index) c return getAppSettings().swatchColours [index]; } -void StoredSettings::ColourSelectorWithSwatches::setSwatchColour (int index, const Colour& newColour) const +void StoredSettings::ColourSelectorWithSwatches::setSwatchColour (int index, const Colour& newColour) { getAppSettings().swatchColours.set (index, newColour); } diff --git a/extras/Projucer/Source/Utility/jucer_StoredSettings.h b/extras/Projucer/Source/Utility/jucer_StoredSettings.h index a5782c5003..14b9428d6e 100644 --- a/extras/Projucer/Source/Utility/jucer_StoredSettings.h +++ b/extras/Projucer/Source/Utility/jucer_StoredSettings.h @@ -57,7 +57,7 @@ public: int getNumSwatches() const override; Colour getSwatchColour (int index) const override; - void setSwatchColour (int index, const Colour& newColour) const override; + void setSwatchColour (int index, const Colour& newColour) override; }; //============================================================================== diff --git a/modules/juce_gui_extra/misc/juce_ColourSelector.cpp b/modules/juce_gui_extra/misc/juce_ColourSelector.cpp index af45e04c46..83fe4e7510 100644 --- a/modules/juce_gui_extra/misc/juce_ColourSelector.cpp +++ b/modules/juce_gui_extra/misc/juce_ColourSelector.cpp @@ -429,7 +429,7 @@ void ColourSelector::paint (Graphics& g) if ((flags & showColourAtTop) != 0) { - const Colour currentColour (getCurrentColour()); + auto currentColour = getCurrentColour(); g.fillCheckerBoard (previewArea, 10, 10, Colour (0xffdddddd).overlaidWith (currentColour), @@ -446,14 +446,11 @@ void ColourSelector::paint (Graphics& g) g.setColour (findColour (labelTextColourId)); g.setFont (11.0f); - for (int i = 4; --i >= 0;) - { - if (sliders[i]->isVisible()) - g.drawText (sliders[i]->getName() + ":", - 0, sliders[i]->getY(), - sliders[i]->getX() - 8, sliders[i]->getHeight(), + for (auto* s : sliders) + if (s->isVisible()) + g.drawText (s->getName() + ":", + 0, s->getY(), s->getX() - 8, s->getHeight(), Justification::centredRight, false); - } } } @@ -515,7 +512,7 @@ void ColourSelector::resized() for (int i = 0; i < numSwatches; ++i) { - SwatchComponent* const sc = new SwatchComponent (*this, i); + auto* sc = new SwatchComponent (*this, i); swatchComponents.add (sc); addAndMakeVisible (sc); } @@ -566,7 +563,7 @@ Colour ColourSelector::getSwatchColour (const int) const return Colours::black; } -void ColourSelector::setSwatchColour (const int, const Colour&) const +void ColourSelector::setSwatchColour (int, const Colour&) { jassertfalse; // if you've overridden getNumSwatches(), you also need to implement this method } diff --git a/modules/juce_gui_extra/misc/juce_ColourSelector.h b/modules/juce_gui_extra/misc/juce_ColourSelector.h index 9d4307bc95..7530278e9e 100644 --- a/modules/juce_gui_extra/misc/juce_ColourSelector.h +++ b/modules/juce_gui_extra/misc/juce_ColourSelector.h @@ -110,7 +110,7 @@ public: setSwatchColour(), to return the number of colours you want, and to set and retrieve their values. */ - virtual void setSwatchColour (int index, const Colour& newColour) const; + virtual void setSwatchColour (int index, const Colour& newColour); //============================================================================== From 99748f0ba83ff567e75e14459e59a406560624ac Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 12:25:39 +0100 Subject: [PATCH 10/54] (Fix for last commit) --- .../juce_gui_extra/misc/juce_ColourSelector.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/juce_gui_extra/misc/juce_ColourSelector.cpp b/modules/juce_gui_extra/misc/juce_ColourSelector.cpp index 83fe4e7510..662fa0dc18 100644 --- a/modules/juce_gui_extra/misc/juce_ColourSelector.cpp +++ b/modules/juce_gui_extra/misc/juce_ColourSelector.cpp @@ -429,7 +429,7 @@ void ColourSelector::paint (Graphics& g) if ((flags & showColourAtTop) != 0) { - auto currentColour = getCurrentColour(); + const Colour currentColour (getCurrentColour()); g.fillCheckerBoard (previewArea, 10, 10, Colour (0xffdddddd).overlaidWith (currentColour), @@ -446,11 +446,14 @@ void ColourSelector::paint (Graphics& g) g.setColour (findColour (labelTextColourId)); g.setFont (11.0f); - for (auto* s : sliders) - if (s->isVisible()) - g.drawText (s->getName() + ":", - 0, s->getY(), s->getX() - 8, s->getHeight(), + for (int i = 4; --i >= 0;) + { + if (sliders[i]->isVisible()) + g.drawText (sliders[i]->getName() + ":", + 0, sliders[i]->getY(), + sliders[i]->getX() - 8, sliders[i]->getHeight(), Justification::centredRight, false); + } } } @@ -522,7 +525,7 @@ void ColourSelector::resized() for (int i = 0; i < swatchComponents.size(); ++i) { - SwatchComponent* const sc = swatchComponents.getUnchecked(i); + auto* sc = swatchComponents.getUnchecked(i); sc->setBounds (x + xGap / 2, y + yGap / 2, From 3e7a111922e9776b60a152e79e52cd0bf8df3561 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 12:34:32 +0100 Subject: [PATCH 11/54] Avoided an unused member variable warning --- modules/juce_gui_basics/misc/juce_JUCESplashScreen.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h b/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h index 3e86a9e508..e42cfe5476 100644 --- a/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h +++ b/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h @@ -62,7 +62,10 @@ private: ScopedPointer content; CriticalSection appUsageReporting; ComponentAnimator fader; + + #if JUCE_DISPLAY_SPLASH_SCREEN bool hasStartedFading = false; + #endif JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JUCESplashScreen) }; From 63cf3e2057e913dec99659412c28a00783ace7e2 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 2 May 2017 12:41:38 +0100 Subject: [PATCH 12/54] Fixed some issues in the JUCE Demo project where colours weren't being updated when changing the LookAndFeel with the keyboard shortcuts --- .../Demo/Source/Demos/AudioLatencyDemo.cpp | 10 ++-- .../Demo/Source/Demos/AudioSettingsDemo.cpp | 5 ++ examples/Demo/Source/Demos/Box2DDemo.cpp | 5 ++ .../Demo/Source/Demos/ChildProcessDemo.cpp | 5 ++ .../Demo/Source/Demos/CryptographyDemo.cpp | 51 +++++++++++-------- examples/Demo/Source/Demos/FlexBoxDemo.cpp | 8 +++ examples/Demo/Source/Demos/JavaScript.cpp | 5 ++ .../Demo/Source/Demos/KeyMappingsDemo.cpp | 11 ++-- examples/Demo/Source/Demos/MDIDemo.cpp | 5 ++ examples/Demo/Source/Demos/NetworkingDemo.cpp | 5 ++ examples/Demo/Source/Demos/OpenGLDemo.cpp | 25 +++++---- examples/Demo/Source/Demos/SystemInfoDemo.cpp | 5 ++ examples/Demo/Source/Demos/UnitTestsDemo.cpp | 5 ++ examples/Demo/Source/Demos/WebBrowserDemo.cpp | 5 ++ examples/Demo/Source/Demos/WidgetsDemo.cpp | 11 ++++ 15 files changed, 125 insertions(+), 36 deletions(-) diff --git a/examples/Demo/Source/Demos/AudioLatencyDemo.cpp b/examples/Demo/Source/Demos/AudioLatencyDemo.cpp index b3a4ea0ebd..c2103c76c4 100644 --- a/examples/Demo/Source/Demos/AudioLatencyDemo.cpp +++ b/examples/Demo/Source/Demos/AudioLatencyDemo.cpp @@ -308,9 +308,6 @@ public: resultsBox.setCaretVisible (false); resultsBox.setPopupMenuEnabled (true); - resultsBox.setColour (TextEditor::backgroundColourId, - getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::widgetBackground, - Colour (0x32ffffff))); resultsBox.setColour (TextEditor::outlineColourId, Colour (0x1c000000)); resultsBox.setColour (TextEditor::shadowColourId, Colour (0x16000000)); @@ -368,6 +365,13 @@ private: startTest(); } + void lookAndFeelChanged() override + { + resultsBox.setColour (TextEditor::backgroundColourId, + getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::widgetBackground, + Colour (0x32ffffff))); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioLatencyDemo) }; diff --git a/examples/Demo/Source/Demos/AudioSettingsDemo.cpp b/examples/Demo/Source/Demos/AudioSettingsDemo.cpp index 580c9de49f..9d68ed04cd 100644 --- a/examples/Demo/Source/Demos/AudioSettingsDemo.cpp +++ b/examples/Demo/Source/Demos/AudioSettingsDemo.cpp @@ -113,6 +113,11 @@ private: dumpDeviceInfo(); } + void lookAndFeelChanged() override + { + diagnosticsBox.applyFontToAllText (diagnosticsBox.getFont()); + } + static String getListOfActiveBits (const BitArray& b) { StringArray bits; diff --git a/examples/Demo/Source/Demos/Box2DDemo.cpp b/examples/Demo/Source/Demos/Box2DDemo.cpp index 92a7adcb83..47dd1a89c5 100644 --- a/examples/Demo/Source/Demos/Box2DDemo.cpp +++ b/examples/Demo/Source/Demos/Box2DDemo.cpp @@ -299,6 +299,11 @@ private: } } + void lookAndFeelChanged() override + { + instructions.applyFontToAllText (instructions.getFont()); + } + static StringArray getTestsList() { const char* tests[] = diff --git a/examples/Demo/Source/Demos/ChildProcessDemo.cpp b/examples/Demo/Source/Demos/ChildProcessDemo.cpp index 65c75bfae6..18c25341ee 100644 --- a/examples/Demo/Source/Demos/ChildProcessDemo.cpp +++ b/examples/Demo/Source/Demos/ChildProcessDemo.cpp @@ -205,6 +205,11 @@ private: testResultsBox.moveCaretToEnd(); } + void lookAndFeelChanged() override + { + testResultsBox.applyFontToAllText (testResultsBox.getFont()); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessDemo) }; diff --git a/examples/Demo/Source/Demos/CryptographyDemo.cpp b/examples/Demo/Source/Demos/CryptographyDemo.cpp index 52eb471f4c..41eaff84ba 100644 --- a/examples/Demo/Source/Demos/CryptographyDemo.cpp +++ b/examples/Demo/Source/Demos/CryptographyDemo.cpp @@ -36,16 +36,6 @@ public: addAndMakeVisible (rsaGroup); rsaGroup.setText ("RSA Encryption"); - rsaGroup.setColour (GroupComponent::outlineColourId, - getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::outline, - Colours::grey)); - rsaGroup.setColour (GroupComponent::textColourId, - getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::defaultText, - Colours::white)); - rsaResultBox.setColour (TextEditor::backgroundColourId, - getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::widgetBackground, - Colours::white.withAlpha (0.5f))); - bitSizeLabel.setText ("Num Bits to Use:", dontSendNotification); bitSizeLabel.attachToComponent (&bitSize, true); @@ -120,6 +110,22 @@ private: createRSAKey(); } + void lookAndFeelChanged() override + { + rsaGroup.setColour (GroupComponent::outlineColourId, + getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::outline, + Colours::grey)); + rsaGroup.setColour (GroupComponent::textColourId, + getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::defaultText, + Colours::white)); + rsaResultBox.setColour (TextEditor::backgroundColourId, + getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::widgetBackground, + Colours::white.withAlpha (0.5f))); + + bitSize.applyFontToAllText (bitSize.getFont()); + rsaResultBox.applyFontToAllText (rsaResultBox.getFont()); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RSAComponent) }; @@ -133,16 +139,6 @@ public: addAndMakeVisible (hashGroup); hashGroup.setText ("Hashes"); - hashGroup.setColour (GroupComponent::outlineColourId, - getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::outline, - Colours::grey)); - hashGroup.setColour (GroupComponent::textColourId, - getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::defaultText, - Colours::white)); - hashEntryBox.setColour (TextEditor::backgroundColourId, - getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::widgetBackground, - Colours::white.withAlpha (0.5f))); - addAndMakeVisible (hashEntryBox); hashEntryBox.setMultiLine (true); @@ -214,6 +210,21 @@ private: void textEditorEscapeKeyPressed (TextEditor&) override { updateHashes(); } void textEditorFocusLost (TextEditor&) override { updateHashes(); } + void lookAndFeelChanged() override + { + hashGroup.setColour (GroupComponent::outlineColourId, + getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::outline, + Colours::grey)); + hashGroup.setColour (GroupComponent::textColourId, + getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::defaultText, + Colours::white)); + hashEntryBox.setColour (TextEditor::backgroundColourId, + getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::widgetBackground, + Colours::white.withAlpha (0.5f))); + + hashEntryBox.applyFontToAllText (hashEntryBox.getFont()); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HashesComponent) }; diff --git a/examples/Demo/Source/Demos/FlexBoxDemo.cpp b/examples/Demo/Source/Demos/FlexBoxDemo.cpp index bcf7f20918..0d5064552f 100644 --- a/examples/Demo/Source/Demos/FlexBoxDemo.cpp +++ b/examples/Demo/Source/Demos/FlexBoxDemo.cpp @@ -124,6 +124,14 @@ struct DemoFlexPanel : public juce::Component, r.reduced (4), Justification::bottomRight, 2); } + void lookAndFeelChanged() override + { + flexOrderEditor.applyFontToAllText (flexOrderEditor.getFont()); + flexGrowEditor.applyFontToAllText (flexGrowEditor.getFont()); + flexShrinkEditor.applyFontToAllText (flexShrinkEditor.getFont()); + flexBasisEditor.applyFontToAllText (flexBasisEditor.getFont()); + } + FlexItem& flexItem; TextEditor flexOrderEditor, flexGrowEditor, flexShrinkEditor, flexBasisEditor; diff --git a/examples/Demo/Source/Demos/JavaScript.cpp b/examples/Demo/Source/Demos/JavaScript.cpp index 6a8384edfe..70ba20ee1b 100644 --- a/examples/Demo/Source/Demos/JavaScript.cpp +++ b/examples/Demo/Source/Demos/JavaScript.cpp @@ -152,6 +152,11 @@ private: outputDisplay.setBounds (r.withTrimmedTop (8)); } + void lookAndFeelChanged() override + { + outputDisplay.applyFontToAllText (outputDisplay.getFont()); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JavaScriptDemo) }; diff --git a/examples/Demo/Source/Demos/KeyMappingsDemo.cpp b/examples/Demo/Source/Demos/KeyMappingsDemo.cpp index 3da3203ff5..01e2133acb 100644 --- a/examples/Demo/Source/Demos/KeyMappingsDemo.cpp +++ b/examples/Demo/Source/Demos/KeyMappingsDemo.cpp @@ -36,10 +36,6 @@ public: { setOpaque (true); addAndMakeVisible (keyMappingEditor); - - LookAndFeel* lf = &LookAndFeel::getDefaultLookAndFeel(); - keyMappingEditor.setColours (lf->findColour (KeyMappingEditorComponent::backgroundColourId), - lf->findColour (KeyMappingEditorComponent::textColourId)); } void paint (Graphics& g) override @@ -56,6 +52,13 @@ public: private: KeyMappingEditorComponent keyMappingEditor; + void lookAndFeelChanged() override + { + auto* lf = &LookAndFeel::getDefaultLookAndFeel(); + keyMappingEditor.setColours (lf->findColour (KeyMappingEditorComponent::backgroundColourId), + lf->findColour (KeyMappingEditorComponent::textColourId)); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KeyMappingsDemo) }; diff --git a/examples/Demo/Source/Demos/MDIDemo.cpp b/examples/Demo/Source/Demos/MDIDemo.cpp index 20144dd450..68f6144d73 100644 --- a/examples/Demo/Source/Demos/MDIDemo.cpp +++ b/examples/Demo/Source/Demos/MDIDemo.cpp @@ -114,6 +114,11 @@ private: changed(); } + void lookAndFeelChanged() override + { + editor.applyFontToAllText (editor.getFont()); + } + void textEditorReturnKeyPressed (TextEditor&) override {} void textEditorEscapeKeyPressed (TextEditor&) override {} void textEditorFocusLost (TextEditor&) override {} diff --git a/examples/Demo/Source/Demos/NetworkingDemo.cpp b/examples/Demo/Source/Demos/NetworkingDemo.cpp index 8c06f66a3a..0e8cefc215 100644 --- a/examples/Demo/Source/Demos/NetworkingDemo.cpp +++ b/examples/Demo/Source/Demos/NetworkingDemo.cpp @@ -118,6 +118,11 @@ private: fetchButton.triggerClick(); } + void lookAndFeelChanged() override + { + urlBox.applyFontToAllText (urlBox.getFont()); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NetworkingDemo) }; diff --git a/examples/Demo/Source/Demos/OpenGLDemo.cpp b/examples/Demo/Source/Demos/OpenGLDemo.cpp index cc7f5b839d..69e2ecbc29 100644 --- a/examples/Demo/Source/Demos/OpenGLDemo.cpp +++ b/examples/Demo/Source/Demos/OpenGLDemo.cpp @@ -368,18 +368,11 @@ struct OpenGLDemoClasses addAndMakeVisible (showBackgroundToggle); showBackgroundToggle.addListener (this); - Colour editorBackground = dynamic_cast (&LookAndFeel::getDefaultLookAndFeel()) - ? getLookAndFeel().findColour (ResizableWindow::backgroundColourId) - : Colours::white; - addAndMakeVisible (tabbedComp); tabbedComp.setTabBarDepth (25); tabbedComp.setColour (TabbedButtonBar::tabTextColourId, Colours::grey); - tabbedComp.addTab ("Vertex", editorBackground, &vertexEditorComp, false); - tabbedComp.addTab ("Fragment", editorBackground, &fragmentEditorComp, false); - - vertexEditorComp.setColour (CodeEditorComponent::backgroundColourId, editorBackground); - fragmentEditorComp.setColour (CodeEditorComponent::backgroundColourId, editorBackground); + tabbedComp.addTab ("Vertex", Colours::transparentBlack, &vertexEditorComp, false); + tabbedComp.addTab ("Fragment", Colours::transparentBlack, &fragmentEditorComp, false); vertexDocument.addListener (this); fragmentDocument.addListener (this); @@ -409,6 +402,8 @@ struct OpenGLDemoClasses addAndMakeVisible (textureLabel); textureLabel.setText ("Texture:", dontSendNotification); textureLabel.attachToComponent (&textureBox, true); + + lookAndFeelChanged(); } void initialise() @@ -562,6 +557,18 @@ struct OpenGLDemoClasses selectTexture (textureBox.getSelectedId()); } + void lookAndFeelChanged() override + { + auto editorBackground = getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::windowBackground, + Colours::white); + + for (int i = tabbedComp.getNumTabs(); i >= 0; --i) + tabbedComp.setTabBackgroundColour (i, editorBackground); + + vertexEditorComp.setColour (CodeEditorComponent::backgroundColourId, editorBackground); + fragmentEditorComp.setColour (CodeEditorComponent::backgroundColourId, editorBackground); + } + OpenGLDemo& demo; Label speedLabel, zoomLabel; diff --git a/examples/Demo/Source/Demos/SystemInfoDemo.cpp b/examples/Demo/Source/Demos/SystemInfoDemo.cpp index 7ef0049a73..4d9731bf22 100644 --- a/examples/Demo/Source/Demos/SystemInfoDemo.cpp +++ b/examples/Demo/Source/Demos/SystemInfoDemo.cpp @@ -202,6 +202,11 @@ public: private: TextEditor resultsBox; + void lookAndFeelChanged() override + { + resultsBox.applyFontToAllText (resultsBox.getFont()); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SystemInfoDemo) }; diff --git a/examples/Demo/Source/Demos/UnitTestsDemo.cpp b/examples/Demo/Source/Demos/UnitTestsDemo.cpp index 3c5e031afa..148662dcdc 100644 --- a/examples/Demo/Source/Demos/UnitTestsDemo.cpp +++ b/examples/Demo/Source/Demos/UnitTestsDemo.cpp @@ -186,6 +186,11 @@ struct UnitTestClasses TextButton startTestButton; TextEditor testResultsBox; + void lookAndFeelChanged() override + { + testResultsBox.applyFontToAllText (testResultsBox.getFont()); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnitTestsDemo) }; }; diff --git a/examples/Demo/Source/Demos/WebBrowserDemo.cpp b/examples/Demo/Source/Demos/WebBrowserDemo.cpp index 8ed7061d37..658d330d64 100644 --- a/examples/Demo/Source/Demos/WebBrowserDemo.cpp +++ b/examples/Demo/Source/Demos/WebBrowserDemo.cpp @@ -140,6 +140,11 @@ private: webView->goToURL (addressTextBox.getText()); } + void lookAndFeelChanged() override + { + addressTextBox.applyFontToAllText (addressTextBox.getFont()); + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebBrowserDemo) }; diff --git a/examples/Demo/Source/Demos/WidgetsDemo.cpp b/examples/Demo/Source/Demos/WidgetsDemo.cpp index bed2ac69b0..fc9d5237c2 100644 --- a/examples/Demo/Source/Demos/WidgetsDemo.cpp +++ b/examples/Demo/Source/Demos/WidgetsDemo.cpp @@ -447,6 +447,12 @@ struct MiscPage : public Component comboBox.setSelectedId (1); } + void lookAndFeelChanged() override + { + textEditor1.applyFontToAllText (textEditor1.getFont()); + textEditor2.applyFontToAllText (textEditor2.getFont()); + } + TextEditor textEditor1, textEditor2; ComboBox comboBox; }; @@ -1572,6 +1578,11 @@ private: setTabBackgroundColour (i, getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); } } + + void lookAndFeelChanged() override + { + updateTabColours(); + } }; //============================================================================== From c4e50b25b4798e12f5321a65e8231cdab7283316 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 2 May 2017 12:53:22 +0100 Subject: [PATCH 13/54] Made ToggleButton ticks in the Projucer larger and brighter for better visibility --- extras/Projucer/Source/Utility/jucer_ProjucerLookAndFeel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/Projucer/Source/Utility/jucer_ProjucerLookAndFeel.cpp b/extras/Projucer/Source/Utility/jucer_ProjucerLookAndFeel.cpp index e3efab0021..c6bc2a1485 100644 --- a/extras/Projucer/Source/Utility/jucer_ProjucerLookAndFeel.cpp +++ b/extras/Projucer/Source/Utility/jucer_ProjucerLookAndFeel.cpp @@ -173,7 +173,7 @@ void ProjucerLookAndFeel::drawToggleButton (Graphics& g, ToggleButton& button, b { g.setColour (button.findColour (ToggleButton::tickColourId)); const auto tick = getTickShape (0.75f); - g.fillPath (tick, tick.getTransformToScaleToFit (rectBounds.reduced (4, 5).toFloat(), false)); + g.fillPath (tick, tick.getTransformToScaleToFit (rectBounds.reduced (2).toFloat(), false)); } if (! isTextEmpty) @@ -501,7 +501,7 @@ void ProjucerLookAndFeel::setupColours() setColour (BooleanPropertyComponent::outlineColourId, Colours::transparentBlack); setColour (BooleanPropertyComponent::backgroundColourId, findColour (widgetBackgroundColourId)); setColour (ToggleButton::tickDisabledColourId, Colour (0xffa9a9a9)); - setColour (ToggleButton::tickColourId, findColour (defaultButtonBackgroundColourId)); + setColour (ToggleButton::tickColourId, findColour (defaultButtonBackgroundColourId).withMultipliedBrightness(1.3f)); setColour (CodeEditorComponent::backgroundColourId, findColour (secondaryBackgroundColourId)); setColour (CodeEditorComponent::lineNumberTextId, findColour (codeEditorLineNumberColourId)); setColour (CodeEditorComponent::lineNumberBackgroundId, findColour (backgroundColourId)); From 728e2dbe82affeb7edcf01c298613dd8955a50a4 Mon Sep 17 00:00:00 2001 From: hogliux Date: Tue, 2 May 2017 15:25:28 +0100 Subject: [PATCH 14/54] Fixed a assertion/crash when a macOS CoreAudio device becomes unavailable during playback --- .../native/juce_mac_CoreAudio.cpp | 54 +++++++++---------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp index a08cbe7611..5f4ea10796 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp @@ -1366,21 +1366,7 @@ public: } } - void stop() override - { - AudioIODeviceCallback* lastCallback = nullptr; - - { - const ScopedLock sl (callbackLock); - std::swap (callback, lastCallback); - } - - for (int i = 0; i < devices.size(); ++i) - devices.getUnchecked(i)->device->stop(); - - if (lastCallback != nullptr) - lastCallback->audioDeviceStopped(); - } + void stop() override { shutdown ({}); } String getLastError() override { @@ -1456,6 +1442,27 @@ private: } } + void shutdown (const String& error) + { + AudioIODeviceCallback* lastCallback = nullptr; + + { + const ScopedLock sl (callbackLock); + std::swap (callback, lastCallback); + } + + for (int i = 0; i < devices.size(); ++i) + devices.getUnchecked(i)->device->stop(); + + if (lastCallback != nullptr) + { + if (error.isNotEmpty()) + lastCallback->audioDeviceError (error); + else + lastCallback->audioDeviceStopped(); + } + } + void reset() { for (int i = 0; i < devices.size(); ++i) @@ -1584,21 +1591,8 @@ private: callback->audioDeviceAboutToStart (device); } - void handleAudioDeviceStopped() - { - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - callback->audioDeviceStopped(); - } - - void handleAudioDeviceError (const String& errorMessage) - { - const ScopedLock sl (callbackLock); - - if (callback != nullptr) - callback->audioDeviceError (errorMessage); - } + void handleAudioDeviceStopped() { shutdown ({}); } + void handleAudioDeviceError (const String& errorMessage) { shutdown (errorMessage.isNotEmpty() ? errorMessage : String ("unknown")); } //============================================================================== struct DeviceWrapper : private AudioIODeviceCallback From fceca976d1edc5f9ed96a5fabf2bf93940b73cf4 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 2 May 2017 15:28:39 +0100 Subject: [PATCH 15/54] Fix to avoid hitting an assertion when invoking the showBuildTab command directly from CompileEngineChildProcess::handleBuildFailed() --- .../Source/LiveBuildEngine/projucer_CompileEngineClient.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp index afdf98559e..320da9f26d 100644 --- a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp +++ b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp @@ -844,6 +844,12 @@ void CompileEngineChildProcess::handleClassListChanged (const ValueTree& newList void CompileEngineChildProcess::handleBuildFailed() { + // check that the command will be processed + auto* mcm = ModalComponentManager::getInstance(); + + if (mcm->getNumModalComponents() != 0 || findProjectContentComponent() == nullptr) + return; + if (errorList.getNumErrors() > 0) ProjucerApplication::getCommandManager().invokeDirectly (CommandIDs::showBuildTab, true); From a256e6e9e1a1958b5d90fb016dcd46d6c5809094 Mon Sep 17 00:00:00 2001 From: hogliux Date: Tue, 2 May 2017 15:40:23 +0100 Subject: [PATCH 16/54] Fixed a linker error when disabling the embedded web browser on linux --- modules/juce_events/messages/juce_ApplicationBase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/juce_events/messages/juce_ApplicationBase.cpp b/modules/juce_events/messages/juce_ApplicationBase.cpp index e9126c9365..84aa790722 100644 --- a/modules/juce_events/messages/juce_ApplicationBase.cpp +++ b/modules/juce_events/messages/juce_ApplicationBase.cpp @@ -169,7 +169,7 @@ StringArray JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameterArray() extern void initialiseNSApplication(); #endif -#if JUCE_LINUX && JUCE_MODULE_AVAILABLE_juce_gui_extra +#if JUCE_LINUX && JUCE_MODULE_AVAILABLE_juce_gui_extra && (! defined(JUCE_WEB_BROWSER) || JUCE_WEB_BROWSER) extern int juce_gtkWebkitMain (int argc, const char* argv[]); #endif @@ -214,7 +214,7 @@ int JUCEApplicationBase::main (int argc, const char* argv[], void* customDelegat initialiseNSApplication(); #endif - #if JUCE_LINUX && JUCE_MODULE_AVAILABLE_juce_gui_extra + #if JUCE_LINUX && JUCE_MODULE_AVAILABLE_juce_gui_extra && (! defined(JUCE_WEB_BROWSER) || JUCE_WEB_BROWSER) if (argc >= 2 && String (argv[1]) == "--juce-gtkwebkitfork-child") return juce_gtkWebkitMain (argc, argv); #endif From a5c9cd9bd7bcc71a893bd73d71a9fc4b931a9f02 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 2 May 2017 16:13:44 +0100 Subject: [PATCH 17/54] Added an extra check to the previous commit to make sure that the showBuildTab command is only invoked if the build tab is not already showing to prevent the command being constantly re-triggered when continuously recompiling --- .../Source/LiveBuildEngine/projucer_CompileEngineClient.cpp | 4 ++-- .../Projucer/Source/Project/jucer_ProjectContentComponent.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp index 320da9f26d..88826ef5ca 100644 --- a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp +++ b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp @@ -844,10 +844,10 @@ void CompileEngineChildProcess::handleClassListChanged (const ValueTree& newList void CompileEngineChildProcess::handleBuildFailed() { - // check that the command will be processed auto* mcm = ModalComponentManager::getInstance(); + auto* pcc = findProjectContentComponent(); - if (mcm->getNumModalComponents() != 0 || findProjectContentComponent() == nullptr) + if (mcm->getNumModalComponents() > 0 || pcc == nullptr || pcc->getCurrentTabIndex() == 1) return; if (errorList.getNumErrors() > 0) diff --git a/extras/Projucer/Source/Project/jucer_ProjectContentComponent.h b/extras/Projucer/Source/Project/jucer_ProjectContentComponent.h index 3680a563c7..f4e0d7d05e 100644 --- a/extras/Projucer/Source/Project/jucer_ProjectContentComponent.h +++ b/extras/Projucer/Source/Project/jucer_ProjectContentComponent.h @@ -80,8 +80,9 @@ public: void openInSelectedIDE (bool saveFirst); void showNewExporterMenu(); - void showProjectTab() { sidebarTabs.setCurrentTabIndex (0); } - void showBuildTab() { sidebarTabs.setCurrentTabIndex (1); } + void showProjectTab() { sidebarTabs.setCurrentTabIndex (0); } + void showBuildTab() { sidebarTabs.setCurrentTabIndex (1); } + int getCurrentTabIndex() { return sidebarTabs.getCurrentTabIndex(); } void showFilesPanel() { showProjectPanel (0); } void showModulesPanel() { showProjectPanel (1); } From 61f4333e73727b332ebe087b89d5455c87265b67 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 16:56:32 +0100 Subject: [PATCH 18/54] Marked some RelativeCoordinate functions in Component as deprecated, and updated some old code that used them. --- .../Source/Wizards/jucer_NewProjectWizard.h | 31 +---- .../Wizards/jucer_NewProjectWizardComponent.h | 121 ++++++++++-------- .../Wizards/jucer_ProjectWizard_Console.h | 11 +- .../Wizards/jucer_ProjectWizard_GUIApp.h | 14 +- .../components/juce_Component.h | 26 +--- .../drawables/juce_DrawableComposite.cpp | 12 +- 6 files changed, 86 insertions(+), 129 deletions(-) diff --git a/extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h b/extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h index 302e8a7307..ca2d578abc 100644 --- a/extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h +++ b/extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h @@ -28,35 +28,6 @@ //============================================================================== -static ComboBox& createFileCreationOptionComboBox (Component& setupComp, - OwnedArray& itemsCreated, - const StringArray& fileOptions) -{ - ComboBox* c = new ComboBox(); - itemsCreated.add (c); - setupComp.addChildAndSetID (c, "filesToCreate"); - - c->addItemList (fileOptions, 1); - c->setSelectedId (1, dontSendNotification); - - Label* l = new Label (String(), TRANS("Files to Auto-Generate") + ":"); - l->attachToComponent (c, true); - itemsCreated.add (l); - - c->setBounds ("parent.width / 2 + 160, 30, parent.width - 30, top + 22"); - - return *c; -} - -static int getFileCreationComboResult (WizardComp& setupComp) -{ - if (ComboBox* cb = dynamic_cast (setupComp.findChildWithID ("filesToCreate"))) - return cb->getSelectedItemIndex(); - - jassertfalse; - return 0; -} - static void setExecutableNameForAllTargets (Project& project, const String& exeName) { for (Project::ExporterIterator exporter (project); exporter.next();) @@ -91,7 +62,7 @@ struct NewProjectWizard virtual String getDescription() const = 0; virtual const char* getIcon() const = 0; - virtual void addSetupItems (Component&, OwnedArray&) {} + virtual StringArray getFileCreationOptions() { return {}; } virtual Result processResultsFromSetupItems (WizardComp&) { return Result::ok(); } virtual bool initialiseProject (Project& project) = 0; diff --git a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h b/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h index 0e7a87d940..5667c57e24 100644 --- a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h +++ b/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h @@ -134,10 +134,9 @@ public: const Array types (ProjectExporter::getExporterTypes()); - for (int i = 0; i < types.size(); ++i) + for (auto& type : types) { - const ProjectExporter::ExporterTypeInfo& type = types.getReference (i); - platforms.add (new PlatformType (type.getIcon(), type.name)); + platforms.add (new PlatformType { type.getIcon(), type.name }); addAndMakeVisible (toggles.add (new ToggleButton (String()))); } @@ -192,7 +191,7 @@ public: { ignoreUnused (width); - if (PlatformType* platform = platforms[rowNumber]) + if (auto* platform = platforms[rowNumber]) { auto bounds = getLocalBounds().withHeight (height).withTrimmedBottom (1); g.setColour (findColour (rowNumber % 2 == 0 ? widgetBackgroundColourId @@ -223,11 +222,6 @@ public: private: struct PlatformType { - PlatformType (const Image& platformIcon, const String& platformName) - : icon (platformIcon), name (platformName) - { - } - Image icon; String name; }; @@ -286,65 +280,49 @@ public: WizardComp() : platformTargets(), projectName (TRANS("Project name")), - nameLabel (String(), TRANS("Project Name") + ":"), - typeLabel (String(), TRANS("Project Type") + ":"), - fileBrowser (FileBrowserComponent::saveMode - | FileBrowserComponent::canSelectDirectories - | FileBrowserComponent::doNotClearFileNameOnRootChange, - NewProjectWizardClasses::getLastWizardFolder(), nullptr, nullptr), - fileOutline (String(), TRANS("Project Folder") + ":"), - targetsOutline (String(), TRANS("Target Platforms") + ":"), - createButton (TRANS("Create") + "..."), - cancelButton (TRANS("Cancel")), modulesPathBox (findDefaultModulesFolder()) { setOpaque (false); addChildAndSetID (&projectName, "projectName"); projectName.setText ("NewProject"); - projectName.setBounds ("120, 34, parent.width / 2 - 10, top + 22"); nameLabel.attachToComponent (&projectName, true); projectName.addListener (this); addChildAndSetID (&projectType, "projectType"); projectType.addItemList (getWizardNames(), 1); projectType.setSelectedId (1, dontSendNotification); - projectType.setBounds ("120, projectName.bottom + 4, projectName.right, top + 22"); typeLabel.attachToComponent (&projectType, true); projectType.addListener (this); addChildAndSetID (&fileOutline, "fileOutline"); fileOutline.setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.2f)); fileOutline.setTextLabelPosition (Justification::centred); - fileOutline.setBounds ("30, projectType.bottom + 20, projectType.right, parent.height - 30"); addChildAndSetID (&targetsOutline, "targetsOutline"); targetsOutline.setColour (GroupComponent::outlineColourId, Colours::black.withAlpha (0.2f)); targetsOutline.setTextLabelPosition (Justification::centred); - targetsOutline.setBounds ("fileOutline.right + 20, projectType.bottom + 20, parent.width - 30, parent.height - 70"); addChildAndSetID (&platformTargets, "platformTargets"); - platformTargets.setBounds ("targetsOutline.left + 15, projectType.bottom + 45, parent.width - 40, parent.height - 90"); addChildAndSetID (&fileBrowser, "fileBrowser"); - fileBrowser.setBounds ("fileOutline.left + 10, fileOutline.top + 20, fileOutline.right - 10, fileOutline.bottom - 32"); fileBrowser.setFilenameBoxLabel ("Folder:"); fileBrowser.setFileName (File::createLegalFileName (projectName.getText())); fileBrowser.addListener (this); addChildAndSetID (&createButton, "createButton"); - createButton.setBounds ("right - 130, bottom - 34, parent.width - 30, parent.height - 30"); createButton.addListener (this); addChildAndSetID (&cancelButton, "cancelButton"); cancelButton.addShortcut (KeyPress (KeyPress::escapeKey)); - cancelButton.setBounds ("right - 130, createButton.top, createButton.left - 10, createButton.bottom"); cancelButton.addListener (this); addChildAndSetID (&modulesPathBox, "modulesPathBox"); - modulesPathBox.setBounds ("targetsOutline.left, targetsOutline.top - 45, targetsOutline.right, targetsOutline.top - 20"); - updateCustomItems(); + addChildAndSetID (&filesToCreate, "filesToCreate"); + filesToCreateLabel.attachToComponent (&filesToCreate, true); + + updateFileCreationTypes(); updateCreateButton(); lookAndFeelChanged(); @@ -355,6 +333,35 @@ public: g.fillAll (findColour (backgroundColourId)); } + void resized() override + { + auto r = getLocalBounds(); + + auto left = r.removeFromLeft (getWidth() / 2).reduced (15); + auto right = r.reduced (15); + + projectName.setBounds (left.removeFromTop (22).withTrimmedLeft (120)); + left.removeFromTop (20); + projectType.setBounds (left.removeFromTop (22).withTrimmedLeft (120)); + left.removeFromTop (20); + fileOutline.setBounds (left); + fileBrowser.setBounds (left.reduced (25)); + + auto buttons = right.removeFromBottom (30); + right.removeFromBottom (10); + createButton.setBounds (buttons.removeFromRight (130)); + buttons.removeFromRight (10); + cancelButton.setBounds (buttons.removeFromRight (130)); + + filesToCreate.setBounds (right.removeFromTop (22).withTrimmedLeft (150)); + right.removeFromTop (20); + modulesPathBox.setBounds (right.removeFromTop (22)); + right.removeFromTop (20); + + targetsOutline.setBounds (right); + platformTargets.setBounds (right.reduced (25)); + } + void buttonClicked (Button* b) override { if (b == &createButton) @@ -369,7 +376,7 @@ public: void returnToTemplatesPage() { - if (SlidingPanelComponent* parent = findParentComponentOfClass()) + if (auto* parent = findParentComponentOfClass()) { if (parent->getNumTabs() > 0) parent->goToTab (parent->getCurrentTabIndex() - 1); @@ -382,12 +389,10 @@ public: void createProject() { - MainWindow* mw = Component::findParentComponentOfClass(); + auto* mw = Component::findParentComponentOfClass(); jassert (mw != nullptr); - ScopedPointer wizard (createWizard()); - - if (wizard != nullptr) + if (ScopedPointer wizard = createWizard()) { Result result (wizard->processResultsFromSetupItems (*this)); @@ -405,27 +410,27 @@ public: if (! wizard->selectJuceFolder()) return; - ScopedPointer project (wizard->runWizard (*this, projectName.getText(), - fileBrowser.getSelectedFile (0))); - - if (project != nullptr) + if (ScopedPointer project = wizard->runWizard (*this, projectName.getText(), + fileBrowser.getSelectedFile (0))) mw->setProject (project.release()); } } - void updateCustomItems() + void updateFileCreationTypes() { - customItems.clear(); + StringArray items; - ScopedPointer wizard (createWizard()); + if (ScopedPointer wizard = createWizard()) + items = wizard->getFileCreationOptions(); - if (wizard != nullptr) - wizard->addSetupItems (*this, customItems); + filesToCreate.clear(); + filesToCreate.addItemList (items, 1); + filesToCreate.setSelectedId (1, dontSendNotification); } void comboBoxChanged (ComboBox*) override { - updateCustomItems(); + updateFileCreationTypes(); } void textEditorTextChanged (TextEditor&) override @@ -444,17 +449,31 @@ public: fileBrowser.setFileName (File::createLegalFileName (projectName.getText())); } - ComboBox projectType; + int getFileCreationComboID() const + { + return filesToCreate.getSelectedItemIndex(); + } + + ComboBox projectType, filesToCreate; PlatformTargetsComp platformTargets; private: TextEditor projectName; - Label nameLabel, typeLabel; - FileBrowserComponent fileBrowser; - GroupComponent fileOutline; - GroupComponent targetsOutline; - TextButton createButton, cancelButton; - OwnedArray customItems; + + Label nameLabel { {}, TRANS("Project Name") + ":" }; + Label typeLabel { {}, TRANS("Project Type") + ":" }; + Label filesToCreateLabel { {}, TRANS("Files to Auto-Generate") + ":" }; + + FileBrowserComponent fileBrowser { FileBrowserComponent::saveMode + | FileBrowserComponent::canSelectDirectories + | FileBrowserComponent::doNotClearFileNameOnRootChange, + NewProjectWizardClasses::getLastWizardFolder(), nullptr, nullptr }; + + GroupComponent fileOutline { {}, TRANS("Project Folder") + ":" }; + GroupComponent targetsOutline { {}, TRANS("Target Platforms") + ":" }; + + TextButton createButton { TRANS("Create") + "..." }; + TextButton cancelButton { TRANS("Cancel") }; ModulesFolderPathBox modulesPathBox; NewProjectWizardClasses::NewProjectWizard* createWizard() diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Console.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Console.h index a07278d360..1dde870ca7 100644 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Console.h +++ b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_Console.h @@ -32,20 +32,17 @@ struct ConsoleAppWizard : public NewProjectWizard String getDescription() const override { return TRANS("Creates a command-line application without GUI support."); } const char* getIcon() const override { return BinaryData::wizard_ConsoleApp_svg; } - void addSetupItems (Component& setupComp, OwnedArray& itemsCreated) override + StringArray getFileCreationOptions() override { - const String fileOptions[] = { TRANS("Create a Main.cpp file"), - TRANS("Don't create any files") }; - - createFileCreationOptionComboBox (setupComp, itemsCreated, - StringArray (fileOptions, numElementsInArray (fileOptions))); + return { "Create a Main.cpp file", + "Don't create any files" }; } Result processResultsFromSetupItems (WizardComp& setupComp) override { createMainCpp = false; - switch (getFileCreationComboResult (setupComp)) + switch (setupComp.getFileCreationComboID()) { case 0: createMainCpp = true; break; case 1: break; diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h index db318b9f65..e0ede52ab5 100644 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h +++ b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h @@ -32,22 +32,18 @@ struct GUIAppWizard : public NewProjectWizard String getDescription() const override { return TRANS("Creates a blank JUCE application with a single window component."); } const char* getIcon() const override { return BinaryData::wizard_GUI_svg; } - void addSetupItems (Component& setupComp, OwnedArray& itemsCreated) override + StringArray getFileCreationOptions() override { - const String fileOptions[] = { TRANS("Create a Main.cpp file"), - TRANS("Create a Main.cpp file and a basic window"), - TRANS("Don't create any files") }; - - createFileCreationOptionComboBox (setupComp, itemsCreated, - StringArray (fileOptions, numElementsInArray (fileOptions))) - .setSelectedId (2); + return { "Create a Main.cpp file", + "Create a Main.cpp file and a basic window", + "Don't create any files" }; } Result processResultsFromSetupItems (WizardComp& setupComp) override { createMainCpp = createWindow = false; - switch (getFileCreationComboResult (setupComp)) + switch (setupComp.getFileCreationComboID()) { case 0: createMainCpp = true; break; case 1: createMainCpp = createWindow = true; break; diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index b390ff7252..6abe04d389 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -473,28 +473,6 @@ public: */ void setBounds (Rectangle newBounds); - /** Changes the component's position and size. - - This is similar to the other setBounds() methods, but uses RelativeRectangle::applyToComponent() - to set the position, This uses a Component::Positioner to make sure that any dynamic - expressions are used in the RelativeRectangle will be automatically re-applied to the - component's bounds when the source values change. See RelativeRectangle::applyToComponent() - for more details. - - For the syntax of the expressions that are allowed in the string, see the notes - for the RelativeCoordinate class. - - @see RelativeCoordinate, setBounds, RelativeRectangle::applyToComponent(), Expression - */ - void setBounds (const RelativeRectangle& newBounds); - - /** Sets the component's bounds with an expression. - The string is parsed as a RelativeRectangle expression - see the notes for - Component::setBounds (const RelativeRectangle&) for more information. This method is - basically just a shortcut for writing setBounds (RelativeRectangle ("...")) - */ - void setBounds (const String& newBoundsExpression); - /** Changes the component's position and size in terms of fractions of its parent's size. The values are factors of the parent's size, so for example @@ -2258,6 +2236,10 @@ public: JUCE_DEPRECATED (Point globalPositionToRelative (Point) const); JUCE_DEPRECATED (Point relativePositionToOtherComponent (const Component*, Point) const); + // RelativeCoordinates are eventually going to be deprecated + JUCE_DEPRECATED (void setBounds (const RelativeRectangle&)); + JUCE_DEPRECATED (void setBounds (const String&)); + private: //============================================================================== friend class ComponentPeer; diff --git a/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp b/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp index a5c63de57e..eeabaf9db3 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp @@ -28,10 +28,7 @@ DrawableComposite::DrawableComposite() : bounds (Point(), Point (100.0f, 0.0f), Point (0.0f, 100.0f)), updateBoundsReentrant (false) { - setContentArea (RelativeRectangle (RelativeCoordinate (0.0), - RelativeCoordinate (100.0), - RelativeCoordinate (0.0), - RelativeCoordinate (100.0))); + setContentArea (RelativeRectangle (Rectangle (0.0f, 0.0f, 100.0f, 100.0f))); } DrawableComposite::DrawableComposite (const DrawableComposite& other) @@ -122,12 +119,7 @@ void DrawableComposite::resetBoundingBoxToContentArea() void DrawableComposite::resetContentAreaAndBoundingBoxToFitChildren() { - const Rectangle activeArea (getDrawableBounds()); - - setContentArea (RelativeRectangle (RelativeCoordinate (activeArea.getX()), - RelativeCoordinate (activeArea.getRight()), - RelativeCoordinate (activeArea.getY()), - RelativeCoordinate (activeArea.getBottom()))); + setContentArea (RelativeRectangle (getDrawableBounds())); resetBoundingBoxToContentArea(); } From f183a506ef592a7a17f2f02c71f136834b6d16fe Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 17:04:46 +0100 Subject: [PATCH 19/54] Workaround for a VS warning --- modules/juce_gui_basics/components/juce_Component.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 5e128ff0ea..fc3622084e 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -1247,7 +1247,7 @@ void Component::setBounds (const RelativeRectangle& newBounds) void Component::setBounds (const String& newBoundsExpression) { - setBounds (RelativeRectangle (newBoundsExpression)); + RelativeRectangle (newBoundsExpression).applyToComponent (*this); } void Component::setBoundsRelative (const float x, const float y, From baddc6389e8094ba62650fbf9a3a443bc19bb652 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 2 May 2017 17:12:20 +0100 Subject: [PATCH 20/54] Workarounds for some new "recommended" Xcode warning flags --- modules/juce_audio_utils/juce_audio_utils.h | 8 ++++---- modules/juce_events/juce_events.cpp | 21 ++++++++++++++++----- modules/juce_gui_basics/juce_gui_basics.cpp | 9 +++++++++ modules/juce_gui_extra/juce_gui_extra.cpp | 10 ++++++++++ modules/juce_opengl/juce_opengl.cpp | 9 +++++++++ 5 files changed, 48 insertions(+), 9 deletions(-) diff --git a/modules/juce_audio_utils/juce_audio_utils.h b/modules/juce_audio_utils/juce_audio_utils.h index afd508c34c..d04cbda269 100644 --- a/modules/juce_audio_utils/juce_audio_utils.h +++ b/modules/juce_audio_utils/juce_audio_utils.h @@ -60,15 +60,15 @@ //============================================================================== /** Config: JUCE_USE_CDREADER - Enables the AudioCDReader class (on supported platforms). - */ + Enables the AudioCDReader class (on supported platforms). +*/ #ifndef JUCE_USE_CDREADER #define JUCE_USE_CDREADER 0 #endif /** Config: JUCE_USE_CDBURNER - Enables the AudioCDBurner class (on supported platforms). - */ + Enables the AudioCDBurner class (on supported platforms). +*/ #ifndef JUCE_USE_CDBURNER #define JUCE_USE_CDBURNER 0 #endif diff --git a/modules/juce_events/juce_events.cpp b/modules/juce_events/juce_events.cpp index 41dcbf1083..50d8fdd69a 100644 --- a/modules/juce_events/juce_events.cpp +++ b/modules/juce_events/juce_events.cpp @@ -71,13 +71,24 @@ namespace juce #include "interprocess/juce_ConnectedChildProcess.cpp" //============================================================================== -#if JUCE_MAC - #include "native/juce_osx_MessageQueue.h" - #include "native/juce_mac_MessageManager.mm" +#if JUCE_MAC || JUCE_IOS -#elif JUCE_IOS #include "native/juce_osx_MessageQueue.h" - #include "native/juce_ios_MessageManager.mm" + + #if JUCE_CLANG + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wundeclared-selector" + #endif + + #if JUCE_MAC + #include "native/juce_mac_MessageManager.mm" + #else + #include "native/juce_ios_MessageManager.mm" + #endif + + #if JUCE_CLANG + #pragma clang diagnostic pop + #endif #elif JUCE_WINDOWS #include "native/juce_win32_Messaging.cpp" diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index bd23816f66..3c1e54df04 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -268,6 +268,11 @@ extern bool juce_areThereAnyAlwaysOnTopWindows(); #if JUCE_MAC || JUCE_IOS + #if JUCE_CLANG + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wundeclared-selector" + #endif + #if JUCE_IOS #include "native/juce_ios_UIViewComponentPeer.mm" #include "native/juce_ios_Windowing.mm" @@ -277,6 +282,10 @@ extern bool juce_areThereAnyAlwaysOnTopWindows(); #include "native/juce_mac_MainMenu.mm" #endif + #if JUCE_CLANG + #pragma clang diagnostic pop + #endif + #include "native/juce_mac_MouseCursor.mm" #include "native/juce_mac_FileChooser.mm" diff --git a/modules/juce_gui_extra/juce_gui_extra.cpp b/modules/juce_gui_extra/juce_gui_extra.cpp index 27b6468ede..f89e0a86ec 100644 --- a/modules/juce_gui_extra/juce_gui_extra.cpp +++ b/modules/juce_gui_extra/juce_gui_extra.cpp @@ -111,6 +111,12 @@ namespace juce //============================================================================== #if JUCE_MAC || JUCE_IOS + + #if JUCE_CLANG + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wundeclared-selector" + #endif + #if JUCE_MAC #include "native/juce_mac_NSViewComponent.mm" #include "native/juce_mac_AppleRemote.mm" @@ -125,6 +131,10 @@ namespace juce #include "native/juce_mac_WebBrowserComponent.mm" #endif + #if JUCE_CLANG + #pragma clang diagnostic pop + #endif + //============================================================================== #elif JUCE_WINDOWS #include "native/juce_win32_ActiveXComponent.cpp" diff --git a/modules/juce_opengl/juce_opengl.cpp b/modules/juce_opengl/juce_opengl.cpp index b0a37e3c6a..3938dd566b 100644 --- a/modules/juce_opengl/juce_opengl.cpp +++ b/modules/juce_opengl/juce_opengl.cpp @@ -200,12 +200,21 @@ private: //============================================================================== #if JUCE_MAC || JUCE_IOS + #if JUCE_CLANG + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wundeclared-selector" + #endif + #if JUCE_MAC #include "native/juce_OpenGL_osx.h" #else #include "native/juce_OpenGL_ios.h" #endif + #if JUCE_CLANG + #pragma clang diagnostic pop + #endif + #elif JUCE_WINDOWS #include "native/juce_OpenGL_win32.h" From c8740688ba47cadc5020b28bbb16d4b615491017 Mon Sep 17 00:00:00 2001 From: tpoole Date: Tue, 2 May 2017 18:31:29 +0100 Subject: [PATCH 21/54] Added assertions to flag when __FILE__ returns a relative path and fixed the LiveConstants demo --- .../Demo/Builds/VisualStudio2013/JuceDemo_App.vcxproj | 2 ++ .../Demo/Builds/VisualStudio2015/JuceDemo_App.vcxproj | 2 ++ .../Demo/Builds/VisualStudio2017/JuceDemo_App.vcxproj | 2 ++ examples/Demo/JuceDemo.jucer | 7 ++++--- modules/juce_events/messages/juce_ApplicationBase.cpp | 8 ++++++++ modules/juce_gui_extra/misc/juce_LiveConstantEditor.h | 6 ++++++ 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/examples/Demo/Builds/VisualStudio2013/JuceDemo_App.vcxproj b/examples/Demo/Builds/VisualStudio2013/JuceDemo_App.vcxproj index 9ea70fa51a..a9e7f5e471 100644 --- a/examples/Demo/Builds/VisualStudio2013/JuceDemo_App.vcxproj +++ b/examples/Demo/Builds/VisualStudio2013/JuceDemo_App.vcxproj @@ -76,6 +76,7 @@ Level4 true true + /FC %(AdditionalOptions) _DEBUG;%(PreprocessorDefinitions) @@ -117,6 +118,7 @@ Level4 true true + /FC %(AdditionalOptions) NDEBUG;%(PreprocessorDefinitions) diff --git a/examples/Demo/Builds/VisualStudio2015/JuceDemo_App.vcxproj b/examples/Demo/Builds/VisualStudio2015/JuceDemo_App.vcxproj index 0c2b1846f4..92c73ec4ea 100644 --- a/examples/Demo/Builds/VisualStudio2015/JuceDemo_App.vcxproj +++ b/examples/Demo/Builds/VisualStudio2015/JuceDemo_App.vcxproj @@ -78,6 +78,7 @@ Level4 true true + /FC %(AdditionalOptions) _DEBUG;%(PreprocessorDefinitions) @@ -117,6 +118,7 @@ Level4 true true + /FC %(AdditionalOptions) NDEBUG;%(PreprocessorDefinitions) diff --git a/examples/Demo/Builds/VisualStudio2017/JuceDemo_App.vcxproj b/examples/Demo/Builds/VisualStudio2017/JuceDemo_App.vcxproj index f91e621977..05a080aef3 100644 --- a/examples/Demo/Builds/VisualStudio2017/JuceDemo_App.vcxproj +++ b/examples/Demo/Builds/VisualStudio2017/JuceDemo_App.vcxproj @@ -78,6 +78,7 @@ Level4 true true + /FC %(AdditionalOptions) _DEBUG;%(PreprocessorDefinitions) @@ -117,6 +118,7 @@ Level4 true true + /FC %(AdditionalOptions) NDEBUG;%(PreprocessorDefinitions) diff --git a/examples/Demo/JuceDemo.jucer b/examples/Demo/JuceDemo.jucer index 37f762cb32..691c407e9c 100644 --- a/examples/Demo/JuceDemo.jucer +++ b/examples/Demo/JuceDemo.jucer @@ -64,7 +64,7 @@ - + @@ -89,7 +89,7 @@ - + @@ -114,7 +114,8 @@ - + diff --git a/modules/juce_events/messages/juce_ApplicationBase.cpp b/modules/juce_events/messages/juce_ApplicationBase.cpp index 84aa790722..d850cb30bb 100644 --- a/modules/juce_events/messages/juce_ApplicationBase.cpp +++ b/modules/juce_events/messages/juce_ApplicationBase.cpp @@ -69,7 +69,15 @@ void JUCEApplicationBase::sendUnhandledException (const std::exception* const e, const int lineNumber) { if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + { + // If you hit this assertion then the __FILE__ macro is providing a + // relative path instead of an absolute path. On Windows this will be + // a path relative to the build directory rather than the currently + // running application. To fix this you must compile with the /FC flag. + jassert (File::isAbsolutePath (sourceFile)); + app->unhandledException (e, sourceFile, lineNumber); + } } //============================================================================== diff --git a/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h index 14ece65fd4..10be7df96c 100644 --- a/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h +++ b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h @@ -238,6 +238,12 @@ namespace LiveConstantEditor template inline LiveValue& getValue (const char* file, int line, const Type& initialValue) { + // If you hit this assertion then the __FILE__ macro is providing a + // relative path instead of an absolute path. On Windows this will be + // a path relative to the build directory rather than the currently + // running application. To fix this you must compile with the /FC flag. + jassert (File::isAbsolutePath (file)); + return ValueList::getInstance()->getValue (file, line, initialValue); } From c94550e4cdd82cd2a5da0ff19f6f2f27a9c35bb4 Mon Sep 17 00:00:00 2001 From: tpoole Date: Tue, 2 May 2017 18:33:28 +0100 Subject: [PATCH 22/54] Made WebBrowserComponent compilable on older versions of OS X --- modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index 20f7615ec2..cc2a720015 100644 --- a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -442,7 +442,7 @@ void WebBrowserComponent::clearCookies() { NSHTTPCookieStorage* storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - if (NSArray* cookies = [storage cookies]) + if (NSArray* cookies = [storage cookies]) { const NSUInteger n = [cookies count]; From 2a189100d728c18324723144f28c5bd469f23b9e Mon Sep 17 00:00:00 2001 From: tpoole Date: Tue, 2 May 2017 22:09:39 +0100 Subject: [PATCH 23/54] Made ListenerList.callExcluding take a pointer argument --- .../containers/juce_ListenerList.cpp | 6 +-- .../juce_core/containers/juce_ListenerList.h | 54 +++++++++---------- .../values/juce_ValueTree.cpp | 5 +- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/modules/juce_core/containers/juce_ListenerList.cpp b/modules/juce_core/containers/juce_ListenerList.cpp index 84b00adbd3..983b301180 100644 --- a/modules/juce_core/containers/juce_ListenerList.cpp +++ b/modules/juce_core/containers/juce_ListenerList.cpp @@ -110,7 +110,7 @@ public: } template - void callExcludingHelper (ListenerBase& listenerToExclude, + void callExcludingHelper (ListenerBase* listenerToExclude, std::vector& expectedCounterValues) { counter = 0; @@ -125,7 +125,7 @@ public: } template - void callExcludingHelper (ListenerBase& listenerToExclude, + void callExcludingHelper (ListenerBase* listenerToExclude, std::vector& expectedCounterValues, T first, Args... args) { const int expected = expectedCounterValues[sizeof... (args) + 1]; @@ -165,7 +165,7 @@ public: for (int i = 1; i < 8; ++i) expectedCounterValues.push_back (i); - callExcludingHelper (listener2, expectedCounterValues, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + callExcludingHelper (&listener2, expectedCounterValues, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); } int counter = 0; diff --git a/modules/juce_core/containers/juce_ListenerList.h b/modules/juce_core/containers/juce_ListenerList.h index f898d62605..36ca27e3c9 100644 --- a/modules/juce_core/containers/juce_ListenerList.h +++ b/modules/juce_core/containers/juce_ListenerList.h @@ -142,7 +142,7 @@ public: /** Calls a member function, with no parameters, on all but the specified listener in the list. This can be useful if the caller is also a listener and needs to exclude itself. */ - void callExcluding (ListenerClass& listenerToExclude, void (ListenerClass::*callbackFunction) ()) + void callExcluding (ListenerClass* listenerToExclude, void (ListenerClass::*callbackFunction) ()) { callCheckedExcluding (listenerToExclude, static_cast (DummyBailOutChecker()), callbackFunction); @@ -164,12 +164,12 @@ public: description for info about writing a bail-out checker. */ template - void callCheckedExcluding (ListenerClass& listenerToExclude, + void callCheckedExcluding (ListenerClass* listenerToExclude, const BailOutCheckerType& bailOutChecker, void (ListenerClass::*callbackFunction) ()) { for (Iterator iter (*this); iter.next (bailOutChecker);) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (); } @@ -186,11 +186,11 @@ public: This can be useful if the caller is also a listener and needs to exclude itself. */ template - void callExcluding (ListenerClass& listenerToExclude, + void callExcluding (ListenerClass* listenerToExclude, void (ListenerClass::*callbackFunction) (P1), LL_PARAM(1)) { for (Iterator iter (*this); iter.next();) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1); } @@ -211,13 +211,13 @@ public: exclude itself. See the class description for info about writing a bail-out checker. */ template - void callCheckedExcluding (ListenerClass& listenerToExclude, + void callCheckedExcluding (ListenerClass* listenerToExclude, const BailOutCheckerType& bailOutChecker, void (ListenerClass::*callbackFunction) (P1), LL_PARAM(1)) { for (Iterator iter (*this); iter.next (bailOutChecker);) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1); } @@ -235,12 +235,12 @@ public: This can be useful if the caller is also a listener and needs to exclude itself. */ template - void callExcluding (ListenerClass& listenerToExclude, + void callExcluding (ListenerClass* listenerToExclude, void (ListenerClass::*callbackFunction) (P1, P2), LL_PARAM(1), LL_PARAM(2)) { for (Iterator iter (*this); iter.next();) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2); } @@ -261,13 +261,13 @@ public: exclude itself. See the class description for info about writing a bail-out checker. */ template - void callCheckedExcluding (ListenerClass& listenerToExclude, + void callCheckedExcluding (ListenerClass* listenerToExclude, const BailOutCheckerType& bailOutChecker, void (ListenerClass::*callbackFunction) (P1, P2), LL_PARAM(1), LL_PARAM(2)) { for (Iterator iter (*this); iter.next (bailOutChecker);) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2); } @@ -285,12 +285,12 @@ public: This can be useful if the caller is also a listener and needs to exclude itself. */ template - void callExcluding (ListenerClass& listenerToExclude, + void callExcluding (ListenerClass* listenerToExclude, void (ListenerClass::*callbackFunction) (P1, P2, P3), LL_PARAM(1), LL_PARAM(2), LL_PARAM(3)) { for (Iterator iter (*this); iter.next();) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2, param3); } @@ -311,13 +311,13 @@ public: exclude itself. See the class description for info about writing a bail-out checker. */ template - void callCheckedExcluding (ListenerClass& listenerToExclude, + void callCheckedExcluding (ListenerClass* listenerToExclude, const BailOutCheckerType& bailOutChecker, void (ListenerClass::*callbackFunction) (P1, P2, P3), LL_PARAM(1), LL_PARAM(2), LL_PARAM(3)) { for (Iterator iter (*this); iter.next (bailOutChecker);) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2, param3); } @@ -335,12 +335,12 @@ public: This can be useful if the caller is also a listener and needs to exclude itself. */ template - void callExcluding (ListenerClass& listenerToExclude, + void callExcluding (ListenerClass* listenerToExclude, void (ListenerClass::*callbackFunction) (P1, P2, P3, P4), LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4)) { for (Iterator iter (*this); iter.next();) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); } @@ -361,13 +361,13 @@ public: exclude itself. See the class description for info about writing a bail-out checker. */ template - void callCheckedExcluding (ListenerClass& listenerToExclude, + void callCheckedExcluding (ListenerClass* listenerToExclude, const BailOutCheckerType& bailOutChecker, void (ListenerClass::*callbackFunction) (P1, P2, P3, P4), LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4)) { for (Iterator iter (*this); iter.next (bailOutChecker);) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); } @@ -385,12 +385,12 @@ public: This can be useful if the caller is also a listener and needs to exclude itself. */ template - void callExcluding (ListenerClass& listenerToExclude, + void callExcluding (ListenerClass* listenerToExclude, void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5), LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5)) { for (Iterator iter (*this); iter.next();) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); } @@ -411,13 +411,13 @@ public: exclude itself. See the class description for info about writing a bail-out checker. */ template - void callCheckedExcluding (ListenerClass& listenerToExclude, + void callCheckedExcluding (ListenerClass* listenerToExclude, const BailOutCheckerType& bailOutChecker, void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5), LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5)) { for (Iterator iter (*this); iter.next (bailOutChecker);) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); } @@ -435,12 +435,12 @@ public: This can be useful if the caller is also a listener and needs to exclude itself. */ template - void callExcluding (ListenerClass& listenerToExclude, + void callExcluding (ListenerClass* listenerToExclude, void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5, P6), LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5), LL_PARAM(6)) { for (Iterator iter (*this); iter.next();) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5, param6); } @@ -461,13 +461,13 @@ public: exclude itself. See the class description for info about writing a bail-out checker. */ template - void callCheckedExcluding (ListenerClass& listenerToExclude, + void callCheckedExcluding (ListenerClass* listenerToExclude, const BailOutCheckerType& bailOutChecker, void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5, P6), LL_PARAM(1), LL_PARAM(2), LL_PARAM(3), LL_PARAM(4), LL_PARAM(5), LL_PARAM(6)) { for (Iterator iter (*this); iter.next (bailOutChecker);) - if (iter.getListener() != &listenerToExclude) + if (iter.getListener() != listenerToExclude) (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5, param6); } diff --git a/modules/juce_data_structures/values/juce_ValueTree.cpp b/modules/juce_data_structures/values/juce_ValueTree.cpp index aca8cbff1d..525101871d 100644 --- a/modules/juce_data_structures/values/juce_ValueTree.cpp +++ b/modules/juce_data_structures/values/juce_ValueTree.cpp @@ -96,10 +96,7 @@ public: { ValueTree tree (this); - if (listenerToExclude == nullptr) - callListenersForAllParents ([&] (ListenerList& list) { list.call (&ValueTree::Listener::valueTreePropertyChanged, tree, property); }); - else - callListenersForAllParents ([&] (ListenerList& list) { list.callExcluding (*listenerToExclude, &ValueTree::Listener::valueTreePropertyChanged, tree, property); }); + callListenersForAllParents ([&] (ListenerList& list) { list.callExcluding (listenerToExclude, &ValueTree::Listener::valueTreePropertyChanged, tree, property); }); } void sendChildAddedMessage (ValueTree child) From f1aef382ad91de91b1af59fa6a20f66574f28557 Mon Sep 17 00:00:00 2001 From: hogliux Date: Wed, 3 May 2017 09:04:39 +0100 Subject: [PATCH 24/54] Fixed a scaling issue with ComboBoxes and Alert windows on iOS --- modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm index 1cb8b37dbf..a2d7203cf7 100644 --- a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm @@ -729,7 +729,7 @@ void UIViewComponentPeer::updateTransformAndScreenBounds() const int x = ((int) (newDesktop.getWidth() * centreRelX)) - (oldArea.getWidth() / 2); const int y = ((int) (newDesktop.getHeight() * centreRelY)) - (oldArea.getHeight() / 2); - setBounds (oldArea.withPosition (x, y), false); + component.setBounds (oldArea.withPosition (x, y)); } [view setNeedsDisplay]; From a05abbf6d030e5c2957d2e4dba36ca5fea99158b Mon Sep 17 00:00:00 2001 From: hogliux Date: Wed, 3 May 2017 10:14:00 +0100 Subject: [PATCH 25/54] Fixed an issue where the character encoding of WebBrowserComponent error messages on macOS was incorrectly displayed --- modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index cc2a720015..70cda3b03a 100644 --- a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -92,7 +92,7 @@ private: // WebKit doesn't have an internal error page, so make a really simple one ourselves if (proceedToErrorPage) - getOwner(self)->goToURL (String ("data:text/plain,") + errorString); + getOwner(self)->goToURL (String ("data:text/plain;charset=UTF-8,") + errorString); } } From 8cec15fd2a73c25d3cd5d61f9116b62b329d7280 Mon Sep 17 00:00:00 2001 From: hogliux Date: Wed, 3 May 2017 10:22:14 +0100 Subject: [PATCH 26/54] Fixed an issue where WebBrowserComponent on macOS would report a load error if the load was canceled by a goToURL request --- modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index 70cda3b03a..84d2c32c0d 100644 --- a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -84,7 +84,7 @@ private: static void didFailLoadWithError (id self, SEL, WebView* sender, NSError* error, WebFrame* frame) { - if ([frame isEqual: [sender mainFrame]]) + if ([frame isEqual: [sender mainFrame]] && error != nullptr && [error code] != NSURLErrorCancelled) { String errorString (nsStringToJuce ([error localizedDescription])); From b14d0cb33a35855e7bdca1b965aba42d42214f3c Mon Sep 17 00:00:00 2001 From: hogliux Date: Wed, 3 May 2017 10:43:40 +0100 Subject: [PATCH 27/54] Fixed broken copy&paste in WebBrowserComponent on macOS --- .../native/juce_mac_WebBrowserComponent.mm | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index 84d2c32c0d..b44fbeb35a 100644 --- a/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -26,6 +26,31 @@ #if JUCE_MAC +struct WebViewKeyEquivalentResponder : public ObjCClass +{ + WebViewKeyEquivalentResponder() : ObjCClass ("WebViewKeyEquivalentResponder_") + { + addMethod (@selector (performKeyEquivalent:), performKeyEquivalent, @encode (BOOL), "@:@"); + registerClass(); + } + +private: + static BOOL performKeyEquivalent (id self, SEL selector, NSEvent* event) + { + NSResponder* first = [[self window] firstResponder]; + if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == NSCommandKeyMask) + { + if ([[event charactersIgnoringModifiers] isEqualToString:@"x"]) return [NSApp sendAction:@selector(cut:) to:first from:self]; + if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) return [NSApp sendAction:@selector(copy:) to:first from:self]; + if ([[event charactersIgnoringModifiers] isEqualToString:@"v"]) return [NSApp sendAction:@selector(paste:) to:first from:self]; + if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) return [NSApp sendAction:@selector(selectAll:) to:first from:self]; + } + + objc_super s = { self, [WebView class] }; + return ObjCMsgSendSuper (&s, selector, event); + } +}; + struct DownloadClickDetectorClass : public ObjCClass { DownloadClickDetectorClass() : ObjCClass ("JUCEWebClickDetector_") @@ -194,9 +219,12 @@ public: Pimpl (WebBrowserComponent* owner) { #if JUCE_MAC - webView = [[WebView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) - frameName: nsEmptyString() - groupName: nsEmptyString()]; + static WebViewKeyEquivalentResponder webviewClass; + webView = (WebView*) webviewClass.createInstance(); + + webView = [webView initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f) + frameName: nsEmptyString() + groupName: nsEmptyString()]; setView (webView); static DownloadClickDetectorClass cls; From 6b5be8d9effe3e416b2e6623e56d3054d19df74f Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 3 May 2017 11:05:56 +0100 Subject: [PATCH 28/54] Tweaked the OSX broadcast notification flags to avoid problems with anotherInstanceStarted() --- modules/juce_events/native/juce_mac_MessageManager.mm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/juce_events/native/juce_mac_MessageManager.mm b/modules/juce_events/native/juce_mac_MessageManager.mm index 0ee82d81fb..95e9a59dcc 100644 --- a/modules/juce_events/native/juce_mac_MessageManager.mm +++ b/modules/juce_events/native/juce_mac_MessageManager.mm @@ -52,7 +52,8 @@ public: [[NSDistributedNotificationCenter defaultCenter] addObserver: delegate selector: @selector (broadcastMessageCallback:) name: getBroadcastEventName() - object: nil]; + object: nil + suspensionBehavior: NSNotificationSuspensionBehaviorDeliverImmediately]; } else { @@ -126,7 +127,7 @@ private: static NSApplicationTerminateReply applicationShouldTerminate (id /*self*/, SEL, NSApplication*) { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + if (auto* app = JUCEApplicationBase::getInstance()) { app->systemRequestedQuit(); @@ -144,7 +145,7 @@ private: static BOOL application_openFile (id /*self*/, SEL, NSApplication*, NSString* filename) { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + if (auto* app = JUCEApplicationBase::getInstance()) { app->anotherInstanceStarted (quotedIfContainsSpaces (filename)); return YES; @@ -155,7 +156,7 @@ private: static void application_openFiles (id /*self*/, SEL, NSApplication*, NSArray* filenames) { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + if (auto* app = JUCEApplicationBase::getInstance()) { StringArray files; @@ -200,7 +201,7 @@ private: static void getUrl_withReplyEvent (id /*self*/, SEL, NSAppleEventDescriptor* event, NSAppleEventDescriptor*) { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + if (auto* app = JUCEApplicationBase::getInstance()) app->anotherInstanceStarted (quotedIfContainsSpaces ([[event paramDescriptorForKeyword: keyDirectObject] stringValue])); } From e38643b2a902c5cd786a4ecf638f32fa846a1a45 Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 3 May 2017 11:16:22 +0100 Subject: [PATCH 29/54] Added support for removing parameters to ValueTreeSynchroniser --- .../values/juce_ValueTreeSynchroniser.cpp | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp b/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp index 5a8d85a784..e4fb27b9fb 100644 --- a/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp +++ b/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp @@ -32,7 +32,8 @@ namespace ValueTreeSynchroniserHelpers fullSync = 2, childAdded = 3, childRemoved = 4, - childMoved = 5 + childMoved = 5, + propertyRemoved = 6 }; static void getValueTreePath (ValueTree v, const ValueTree& topLevelTree, Array& path) @@ -73,14 +74,14 @@ namespace ValueTreeSynchroniserHelpers const int numLevels = input.readCompressedInt(); if (! isPositiveAndBelow (numLevels, 65536)) // sanity-check - return ValueTree(); + return {}; for (int i = numLevels; --i >= 0;) { const int index = input.readCompressedInt(); if (! isPositiveAndBelow (index, v.getNumChildren())) - return ValueTree(); + return {}; v = v.getChild (index); } @@ -110,9 +111,19 @@ void ValueTreeSynchroniser::sendFullSyncCallback() void ValueTreeSynchroniser::valueTreePropertyChanged (ValueTree& vt, const Identifier& property) { MemoryOutputStream m; - ValueTreeSynchroniserHelpers::writeHeader (*this, m, ValueTreeSynchroniserHelpers::propertyChanged, vt); - m.writeString (property.toString()); - vt.getProperty (property).writeToStream (m); + + if (auto* value = vt.getPropertyPointer (property)) + { + ValueTreeSynchroniserHelpers::writeHeader (*this, m, ValueTreeSynchroniserHelpers::propertyChanged, vt); + m.writeString (property.toString()); + vt.getProperty (property).writeToStream (m); + } + else + { + ValueTreeSynchroniserHelpers::writeHeader (*this, m, ValueTreeSynchroniserHelpers::propertyRemoved, vt); + m.writeString (property.toString()); + } + stateChanged (m.getData(), m.getDataSize()); } @@ -173,6 +184,13 @@ bool ValueTreeSynchroniser::applyChange (ValueTree& root, const void* data, size return true; } + case ValueTreeSynchroniserHelpers::propertyRemoved: + { + Identifier property (input.readString()); + v.removeProperty (property, undoManager); + return true; + } + case ValueTreeSynchroniserHelpers::childAdded: { const int index = input.readCompressedInt(); From f55cbf3724739523455c44ae237899aa9704704d Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 3 May 2017 11:23:27 +0100 Subject: [PATCH 30/54] Fixed an unused variable warning --- .../juce_data_structures/values/juce_ValueTreeSynchroniser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp b/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp index e4fb27b9fb..d29b692b4c 100644 --- a/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp +++ b/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp @@ -116,7 +116,7 @@ void ValueTreeSynchroniser::valueTreePropertyChanged (ValueTree& vt, const Ident { ValueTreeSynchroniserHelpers::writeHeader (*this, m, ValueTreeSynchroniserHelpers::propertyChanged, vt); m.writeString (property.toString()); - vt.getProperty (property).writeToStream (m); + value->writeToStream (m); } else { From 13e7fc83cd6e81e72462129585f55c4a0353a5d4 Mon Sep 17 00:00:00 2001 From: hogliux Date: Wed, 3 May 2017 12:08:46 +0100 Subject: [PATCH 31/54] Fixed a typo in the VST3 wrapper --- modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp index b07ecd44b1..333af24d11 100644 --- a/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp @@ -1483,7 +1483,7 @@ public: zerostruct (bank); bank.magic1 = (int32) htonl ('CcnK'); bank.size = (int32) htonl (bankBlockSize - 8 + (unsigned int) mem.getSize()); - bank.magic1 = (int32) htonl ('FBCh'); + bank.magic2 = (int32) htonl ('FBCh'); bank.version1 = (int32) htonl (2); bank.fxID = (int32) htonl (JucePlugin_VSTUniqueID); bank.version2 = (int32) htonl (JucePlugin_VersionCode); From 4c385e158cc9b92773707dce925cc03476cdceff Mon Sep 17 00:00:00 2001 From: hogliux Date: Wed, 3 May 2017 14:35:38 +0100 Subject: [PATCH 32/54] Added support for setting the Windows target platform version in VS2017 --- .../Project Saving/jucer_ProjectExport_MSVC.h | 27 ++++++++++++++++++- .../Projucer/Source/Utility/jucer_PresetIDs.h | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h index 41c2b28fc5..2406f59f58 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h @@ -1444,6 +1444,7 @@ public: } getOwner().addPlatformToolsetToPropertyGroup (projectXml); + getOwner().addWindowsTargetPlatformVersionToPropertyGroup (projectXml); getOwner().addIPPSettingToPropertyGroup (projectXml); } @@ -1688,7 +1689,8 @@ protected: } }; - virtual void addPlatformToolsetToPropertyGroup (XmlElement&) const {} + virtual void addPlatformToolsetToPropertyGroup (XmlElement&) const {} + virtual void addWindowsTargetPlatformVersionToPropertyGroup (XmlElement&) const {} void addIPPSettingToPropertyGroup (XmlElement& p) const { @@ -1868,6 +1870,9 @@ public: Value getCppStandardValue() { return getSetting (Ids::cppLanguageStandard); } String getCppLanguageStandard() const override { return settings [Ids::cppLanguageStandard]; } + Value getWindowsTargetPlatformVersionValue() { return getSetting (Ids::windowsTargetPlatformVersion); } + String getWindowsTargetPlatformVersion() const { return settings [Ids::windowsTargetPlatformVersion]; } + void createExporterProperties (PropertyListBuilder& props) override { MSVCProjectExporterBase::createExporterProperties (props); @@ -1889,6 +1894,26 @@ public: StringArray (cppStandardNames), cppStandardValues), "The C++ language standard to use"); + static const char* targetPlatformNames[] = { "(default)", "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0" }; + + Array targetPlatforms; + targetPlatforms.add (var()); + + for (int i = 1; i < numElementsInArray (targetPlatformNames); ++i) + targetPlatforms.add (var (targetPlatformNames[i])); + + props.add (new ChoicePropertyComponent (getWindowsTargetPlatformVersionValue(), "VS2017 Windows Target Platform", + StringArray (targetPlatformNames), targetPlatforms), + "The Windows target platform to use"); + } + + void addWindowsTargetPlatformVersionToPropertyGroup (XmlElement& p) const override + { + const String& targetVersion = getWindowsTargetPlatformVersion(); + + if (targetVersion.isNotEmpty()) + forEachXmlChildElementWithTagName (p, e, "PropertyGroup") + e->createNewChildElement ("WindowsTargetPlatformVersion")->addTextElement (getWindowsTargetPlatformVersion()); } JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2017) diff --git a/extras/Projucer/Source/Utility/jucer_PresetIDs.h b/extras/Projucer/Source/Utility/jucer_PresetIDs.h index e0bc622a7d..da0c6dde39 100644 --- a/extras/Projucer/Source/Utility/jucer_PresetIDs.h +++ b/extras/Projucer/Source/Utility/jucer_PresetIDs.h @@ -112,6 +112,7 @@ namespace Ids DECLARE_ID (linuxCodeBlocksArchitecture); DECLARE_ID (windowsCodeBlocksArchitecture); DECLARE_ID (toolset); + DECLARE_ID (windowsTargetPlatformVersion); DECLARE_ID (IPPLibrary); DECLARE_ID (msvcModuleDefinitionFile); DECLARE_ID (bigIcon); From adb5b542af9eec23ae62084fac8ca3b6e09eb93a Mon Sep 17 00:00:00 2001 From: hogliux Date: Wed, 3 May 2017 14:50:20 +0100 Subject: [PATCH 33/54] Fixed a memory access bug with the previous commit --- .../Project Saving/jucer_ProjectExport_MSVC.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h index 2406f59f58..8b19f22bfa 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h @@ -1883,7 +1883,7 @@ public: addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); addIPPLibraryProperty (props); - static const char* cppStandardNames[] = { "(default)", "C++14", "Latest C++ Standard" }; + static const char* cppStandardNames[] = { "(default)", "C++14", "Latest C++ Standard", nullptr }; Array cppStandardValues; cppStandardValues.add (var()); @@ -1894,16 +1894,11 @@ public: StringArray (cppStandardNames), cppStandardValues), "The C++ language standard to use"); - static const char* targetPlatformNames[] = { "(default)", "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0" }; - - Array targetPlatforms; - targetPlatforms.add (var()); - - for (int i = 1; i < numElementsInArray (targetPlatformNames); ++i) - targetPlatforms.add (var (targetPlatformNames[i])); + static const char* targetPlatformNames[] = { "(default)", "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0", nullptr }; + const var targetPlatforms[] = { var(), "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0" }; props.add (new ChoicePropertyComponent (getWindowsTargetPlatformVersionValue(), "VS2017 Windows Target Platform", - StringArray (targetPlatformNames), targetPlatforms), + StringArray (targetPlatformNames), Array (targetPlatforms, numElementsInArray (targetPlatforms))), "The Windows target platform to use"); } From 377a73a122800644a1c94cf5c37a0de5cb61c1d6 Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 3 May 2017 14:59:58 +0100 Subject: [PATCH 34/54] Tweaked the audio hosting demo to prevent multiple instances of the built-in filters being added --- .../audio plugin host/Source/FilterGraph.cpp | 15 +++- .../audio plugin host/Source/FilterGraph.h | 8 +- .../Source/MainHostWindow.cpp | 74 +++++++++---------- .../audio plugin host/Source/MainHostWindow.h | 10 +-- .../processors/juce_AudioProcessorGraph.h | 1 - 5 files changed, 57 insertions(+), 51 deletions(-) diff --git a/examples/audio plugin host/Source/FilterGraph.cpp b/examples/audio plugin host/Source/FilterGraph.cpp index 2c9b10118d..c6802ec658 100644 --- a/examples/audio plugin host/Source/FilterGraph.cpp +++ b/examples/audio plugin host/Source/FilterGraph.cpp @@ -69,16 +69,27 @@ int FilterGraph::getNumFilters() const noexcept return graph.getNumNodes(); } -const AudioProcessorGraph::Node::Ptr FilterGraph::getNode (const int index) const noexcept +AudioProcessorGraph::Node::Ptr FilterGraph::getNode (const int index) const noexcept { return graph.getNode (index); } -const AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForId (const uint32 uid) const noexcept +AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForId (const uint32 uid) const { return graph.getNodeForId (uid); } +AudioProcessorGraph::Node::Ptr FilterGraph::getNodeForName (const String& name) const +{ + for (int i = 0; i < graph.getNumNodes(); i++) + if (auto node = graph.getNode (i)) + if (auto p = node->getProcessor()) + if (p->getName().equalsIgnoreCase (name)) + return node; + + return nullptr; +} + void FilterGraph::addFilter (const PluginDescription* desc, double x, double y) { if (desc != nullptr) diff --git a/examples/audio plugin host/Source/FilterGraph.h b/examples/audio plugin host/Source/FilterGraph.h index bfd8c7ffd9..5ce6613633 100644 --- a/examples/audio plugin host/Source/FilterGraph.h +++ b/examples/audio plugin host/Source/FilterGraph.h @@ -47,10 +47,12 @@ public: AudioProcessorGraph& getGraph() noexcept { return graph; } int getNumFilters() const noexcept; - const AudioProcessorGraph::Node::Ptr getNode (const int index) const noexcept; - const AudioProcessorGraph::Node::Ptr getNodeForId (const uint32 uid) const noexcept; + AudioProcessorGraph::Node::Ptr getNode (int index) const noexcept; - void addFilter (const PluginDescription* desc, double x, double y); + AudioProcessorGraph::Node::Ptr getNodeForId (uint32 uid) const; + AudioProcessorGraph::Node::Ptr getNodeForName (const String& name) const; + + void addFilter (const PluginDescription*, double x, double y); void addFilterCallback (AudioPluginInstance* instance, const String& error, double x, double y); diff --git a/examples/audio plugin host/Source/MainHostWindow.cpp b/examples/audio plugin host/Source/MainHostWindow.cpp index ddbff65783..d44f0aaee0 100644 --- a/examples/audio plugin host/Source/MainHostWindow.cpp +++ b/examples/audio plugin host/Source/MainHostWindow.cpp @@ -110,7 +110,7 @@ MainHostWindow::MainHostWindow() knownPluginList.addChangeListener (this); - if (FilterGraph* filterGraph = getGraphEditor()->graph.get()) + if (auto* filterGraph = getGraphEditor()->graph.get()) filterGraph->addChangeListener (this); addKeyListener (getCommandManager().getKeyMappings()); @@ -131,7 +131,7 @@ MainHostWindow::~MainHostWindow() pluginListWindow = nullptr; knownPluginList.removeChangeListener (this); - if (FilterGraph* filterGraph = getGraphEditor()->graph.get()) + if (auto* filterGraph = getGraphEditor()->graph.get()) filterGraph->removeChangeListener (this); getAppProperties().getUserSettings()->setValue ("mainWindowPos", getWindowStateAsString()); @@ -198,9 +198,7 @@ void MainHostWindow::changeListenerCallback (ChangeBroadcaster* changed) StringArray MainHostWindow::getMenuBarNames() { - const char* const names[] = { "File", "Plugins", "Options", "Windows", nullptr }; - - return StringArray (names); + return { "File", "Plugins", "Options", "Windows" }; } PopupMenu MainHostWindow::getMenuForIndex (int topLevelMenuIndex, const String& /*menuName*/) @@ -266,12 +264,10 @@ PopupMenu MainHostWindow::getMenuForIndex (int topLevelMenuIndex, const String& void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/) { - GraphDocumentComponent* const graphEditor = getGraphEditor(); - if (menuItemID == 250) { - if (graphEditor != nullptr) - if (FilterGraph* filterGraph = getGraphEditor()->graph.get()) + if (auto* graphEditor = getGraphEditor()) + if (auto* filterGraph = graphEditor->graph.get()) filterGraph->clear(); } else if (menuItemID >= 100 && menuItemID < 200) @@ -280,10 +276,9 @@ void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/ recentFiles.restoreFromString (getAppProperties().getUserSettings() ->getValue ("recentFilterGraphFiles")); - if (graphEditor != nullptr - && getGraphEditor()->graph != nullptr - && graphEditor->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk) - graphEditor->graph->loadFrom (recentFiles.getFile (menuItemID - 100), true); + if (auto* graphEditor = getGraphEditor()) + if (graphEditor->graph != nullptr && graphEditor->graph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk) + graphEditor->graph->loadFrom (recentFiles.getFile (menuItemID - 100), true); } else if (menuItemID >= 200 && menuItemID < 210) { @@ -307,24 +302,26 @@ void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/ void MainHostWindow::menuBarActivated (bool isActivated) { - GraphDocumentComponent* const graphEditor = getGraphEditor(); - - if (graphEditor != nullptr && isActivated) - graphEditor->unfocusKeyboardComponent(); + if (auto* graphEditor = getGraphEditor()) + if (isActivated) + graphEditor->unfocusKeyboardComponent(); } void MainHostWindow::createPlugin (const PluginDescription* desc, int x, int y) { - GraphDocumentComponent* const graphEditor = getGraphEditor(); - - if (graphEditor != nullptr) + if (auto* graphEditor = getGraphEditor()) graphEditor->createNewPlugin (desc, x, y); } void MainHostWindow::addPluginsToMenu (PopupMenu& m) const { - for (int i = 0; i < internalTypes.size(); ++i) - m.addItem (i + 1, internalTypes.getUnchecked(i)->name); + if (auto* graphEditor = getGraphEditor()) + { + int i = 0; + + for (auto* t : internalTypes) + m.addItem (++i, t->name, graphEditor->graph->getNodeForName (t->name) == nullptr); + } m.addSeparator(); @@ -345,7 +342,7 @@ ApplicationCommandTarget* MainHostWindow::getNextCommandTarget() return findFirstTargetParentComponent(); } -void MainHostWindow::getAllCommands (Array & commands) +void MainHostWindow::getAllCommands (Array& commands) { // this returns the set of all commands that this target can perform.. const CommandID ids[] = { CommandIDs::newFile, @@ -420,7 +417,7 @@ void MainHostWindow::getCommandInfo (const CommandID commandID, ApplicationComma bool MainHostWindow::perform (const InvocationInfo& info) { - GraphDocumentComponent* const graphEditor = getGraphEditor(); + auto* graphEditor = getGraphEditor(); switch (info.commandID) { @@ -456,7 +453,7 @@ bool MainHostWindow::perform (const InvocationInfo& info) break; case CommandIDs::toggleDoublePrecision: - if (PropertiesFile* props = getAppProperties().getUserSettings()) + if (auto* props = getAppProperties().getUserSettings()) { bool newIsDoublePrecision = ! isDoublePrecisionProcessing(); props->setValue ("doublePrecisionProcessing", var (newIsDoublePrecision)); @@ -478,7 +475,7 @@ bool MainHostWindow::perform (const InvocationInfo& info) case CommandIDs::allWindowsForward: { - Desktop& desktop = Desktop::getInstance(); + auto& desktop = Desktop::getInstance(); for (int i = 0; i < desktop.getNumComponents(); ++i) desktop.getComponent (i)->toBehind (this); @@ -518,10 +515,9 @@ void MainHostWindow::showAudioSettings() getAppProperties().getUserSettings()->setValue ("audioDeviceState", audioState); getAppProperties().getUserSettings()->saveIfNeeded(); - GraphDocumentComponent* const graphEditor = getGraphEditor(); - - if (graphEditor != nullptr && graphEditor->graph != nullptr) - graphEditor->graph->removeIllegalConnections(); + if (auto* graphEditor = getGraphEditor()) + if (graphEditor->graph != nullptr) + graphEditor->graph->removeIllegalConnections(); } bool MainHostWindow::isInterestedInFileDrag (const StringArray&) @@ -543,25 +539,23 @@ void MainHostWindow::fileDragExit (const StringArray&) void MainHostWindow::filesDropped (const StringArray& files, int x, int y) { - GraphDocumentComponent* const graphEditor = getGraphEditor(); - - if (graphEditor != nullptr) + if (auto* graphEditor = getGraphEditor()) { if (files.size() == 1 && File (files[0]).hasFileExtension (filenameSuffix)) { - if (FilterGraph* filterGraph = graphEditor->graph.get()) - if (filterGraph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk) - filterGraph->loadFrom (File (files[0]), true); + if (auto* filterGraph = graphEditor->graph.get()) + if (filterGraph->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk) + filterGraph->loadFrom (File (files[0]), true); } else { - OwnedArray typesFound; + OwnedArray typesFound; knownPluginList.scanAndAddDragAndDroppedFiles (formatManager, files, typesFound); - Point pos (graphEditor->getLocalPoint (this, Point (x, y))); + auto pos = graphEditor->getLocalPoint (this, Point (x, y)); for (int i = 0; i < jmin (5, typesFound.size()); ++i) - createPlugin (typesFound.getUnchecked(i), pos.getX(), pos.getY()); + createPlugin (typesFound.getUnchecked(i), pos.x, pos.y); } } } @@ -573,7 +567,7 @@ GraphDocumentComponent* MainHostWindow::getGraphEditor() const bool MainHostWindow::isDoublePrecisionProcessing() { - if (PropertiesFile* props = getAppProperties().getUserSettings()) + if (auto* props = getAppProperties().getUserSettings()) return props->getBoolValue ("doublePrecisionProcessing", false); return false; diff --git a/examples/audio plugin host/Source/MainHostWindow.h b/examples/audio plugin host/Source/MainHostWindow.h index f43b1f0bb6..837a18863e 100644 --- a/examples/audio plugin host/Source/MainHostWindow.h +++ b/examples/audio plugin host/Source/MainHostWindow.h @@ -77,16 +77,16 @@ public: PopupMenu getMenuForIndex (int topLevelMenuIndex, const String& menuName); void menuItemSelected (int menuItemID, int topLevelMenuIndex); ApplicationCommandTarget* getNextCommandTarget(); - void getAllCommands (Array & commands); + void getAllCommands (Array& commands); void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result); bool perform (const InvocationInfo& info); bool tryToQuitApplication(); - void createPlugin (const PluginDescription* desc, int x, int y); + void createPlugin (const PluginDescription*, int x, int y); - void addPluginsToMenu (PopupMenu& m) const; - const PluginDescription* getChosenType (const int menuID) const; + void addPluginsToMenu (PopupMenu&) const; + const PluginDescription* getChosenType (int menuID) const; GraphDocumentComponent* getGraphEditor() const; @@ -98,7 +98,7 @@ private: AudioDeviceManager deviceManager; AudioPluginFormatManager formatManager; - OwnedArray internalTypes; + OwnedArray internalTypes; KnownPluginList knownPluginList; KnownPluginList::SortMethod pluginSortMethod; diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index e0a43f549e..85c9c545ed 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -105,7 +105,6 @@ public: */ struct JUCE_API Connection { - public: //============================================================================== Connection (uint32 sourceNodeId, int sourceChannelIndex, uint32 destNodeId, int destChannelIndex) noexcept; From db346fea6d75bdb4c26aa455050ac33c7ebf4a36 Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 3 May 2017 15:05:39 +0100 Subject: [PATCH 35/54] Change to unreadable button text colour in LookAndFeel_V3 --- modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp index e1eba00998..5108791ffc 100644 --- a/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp +++ b/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp @@ -30,7 +30,7 @@ LookAndFeel_V3::LookAndFeel_V3() const Colour textButtonColour (0xffeeeeff); setColour (TextButton::buttonColourId, textButtonColour); - setColour (TextButton::buttonOnColourId, Colour (0xff000000)); + setColour (TextButton::buttonOnColourId, Colour (0xff888888)); setColour (ComboBox::buttonColourId, textButtonColour); setColour (TextEditor::outlineColourId, Colours::transparentBlack); setColour (TabbedButtonBar::tabOutlineColourId, Colour (0x66000000)); From f4046909ab35ea23deed7244d66d021f7514b3af Mon Sep 17 00:00:00 2001 From: tpoole Date: Wed, 3 May 2017 15:36:25 +0100 Subject: [PATCH 36/54] Added an OS X 10.5 compatible std::function replacement --- extras/Projucer/Projucer.jucer | 3 +- .../projucer_CompileEngineClient.cpp | 4 + .../format/juce_AudioPluginFormat.cpp | 2 - .../format/juce_AudioPluginFormat.h | 2 - .../format/juce_AudioPluginFormatManager.cpp | 4 - .../format/juce_AudioPluginFormatManager.h | 2 - .../juce_AudioProcessorValueTreeState.cpp | 4 - .../juce_AudioProcessorValueTreeState.h | 4 - modules/juce_core/containers/juce_Variant.h | 4 - modules/juce_core/juce_core.cpp | 1 + .../juce_core/maths/juce_NormalisableRange.h | 10 - .../juce_core/misc/juce_RuntimePermissions.h | 4 - .../juce_core/misc/juce_StdFunctionCompat.cpp | 228 ++++++++++++++++++ .../juce_core/misc/juce_StdFunctionCompat.h | 225 +++++++++++++++++ .../juce_core/system/juce_CompilerSupport.h | 8 +- .../juce_core/system/juce_StandardHeader.h | 6 + modules/juce_events/timers/juce_Timer.cpp | 2 - modules/juce_events/timers/juce_Timer.h | 2 - .../components/juce_ModalComponentManager.cpp | 2 - .../components/juce_ModalComponentManager.h | 2 - 20 files changed, 472 insertions(+), 47 deletions(-) create mode 100644 modules/juce_core/misc/juce_StdFunctionCompat.cpp create mode 100644 modules/juce_core/misc/juce_StdFunctionCompat.h diff --git a/extras/Projucer/Projucer.jucer b/extras/Projucer/Projucer.jucer index 85a4f844be..103cf4bac2 100644 --- a/extras/Projucer/Projucer.jucer +++ b/extras/Projucer/Projucer.jucer @@ -664,8 +664,7 @@ - + diff --git a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp index 88826ef5ca..2f4aee7619 100644 --- a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp +++ b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp @@ -383,6 +383,10 @@ private: if (exporter->canLaunchProject()) defs << " " << exporter->getExporterIdentifierMacro() << "=1"; + // Use the JUCE implementation of std::function until the live build + // engine can compile the one from the standard library + defs << " _LIBCPP_FUNCTIONAL=1"; + return defs; } diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp b/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp index 9385da6ec7..720260de4c 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp @@ -168,7 +168,6 @@ void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& desc (new InvokeOnMessageThread (this, description, initialSampleRate, initialBufferSize, callback))->post(); } -#if JUCE_COMPILER_SUPPORTS_LAMBDAS void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& description, double initialSampleRate, int initialBufferSize, @@ -190,7 +189,6 @@ void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& desc createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, new CallbackInvoker (f)); } -#endif void AudioPluginFormat::createPluginInstanceOnMessageThread (const PluginDescription& description, double initialSampleRate, diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h index 302faaad01..f820257898 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormat.h +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormat.h @@ -92,12 +92,10 @@ public: int initialBufferSize, InstantiationCompletionCallback* completionCallback); - #if JUCE_COMPILER_SUPPORTS_LAMBDAS void createPluginInstanceAsync (const PluginDescription& description, double initialSampleRate, int initialBufferSize, std::function completionCallback); - #endif /** Should do a quick check to see if this file or directory might be a plugin of this format. diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp index 9afd881218..d9e5551ce1 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp @@ -40,7 +40,6 @@ namespace PluginFormatManagerHelpers ScopedPointer callback; }; - #if JUCE_COMPILER_SUPPORTS_LAMBDAS struct ErrorLambdaOnMessageThread : public CallbackMessage { ErrorLambdaOnMessageThread (const String& inError, @@ -54,7 +53,6 @@ namespace PluginFormatManagerHelpers String error; std::function lambda; }; - #endif } AudioPluginFormatManager::AudioPluginFormatManager() {} @@ -139,7 +137,6 @@ void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescriptio (new PluginFormatManagerHelpers::ErrorCallbackOnMessageThread (error, callback))->post(); } -#if JUCE_COMPILER_SUPPORTS_LAMBDAS void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description, double initialSampleRate, int initialBufferSize, @@ -152,7 +149,6 @@ void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescriptio (new PluginFormatManagerHelpers::ErrorLambdaOnMessageThread (error, f))->post(); } -#endif AudioPluginFormat* AudioPluginFormatManager::findFormatForDescription (const PluginDescription& description, String& errorMessage) const { diff --git a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h index 431d32ad3e..0be2c06b54 100644 --- a/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h +++ b/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h @@ -114,12 +114,10 @@ public: int initialBufferSize, AudioPluginFormat::InstantiationCompletionCallback* callback); - #if JUCE_COMPILER_SUPPORTS_LAMBDAS void createPluginInstanceAsync (const PluginDescription& description, double initialSampleRate, int initialBufferSize, std::function completionCallback); - #endif /** Checks that the file or component for this plugin actually still exists. diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp index c85252d8f0..c47602b02c 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp @@ -24,8 +24,6 @@ ============================================================================== */ -#if JUCE_COMPILER_SUPPORTS_LAMBDAS - //============================================================================== struct AudioProcessorValueTreeState::Parameter : public AudioProcessorParameterWithID, private ValueTree::Listener @@ -556,5 +554,3 @@ AudioProcessorValueTreeState::ButtonAttachment::ButtonAttachment (AudioProcessor } AudioProcessorValueTreeState::ButtonAttachment::~ButtonAttachment() {} - -#endif diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h index 8a851d1b7c..481e821b23 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h @@ -26,8 +26,6 @@ #pragma once -#if JUCE_COMPILER_SUPPORTS_LAMBDAS - /** This class contains a ValueTree which is used to manage an AudioProcessor's entire state. @@ -227,5 +225,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorValueTreeState) }; - -#endif diff --git a/modules/juce_core/containers/juce_Variant.h b/modules/juce_core/containers/juce_Variant.h index 24a384d1c3..eeb20f0252 100644 --- a/modules/juce_core/containers/juce_Variant.h +++ b/modules/juce_core/containers/juce_Variant.h @@ -52,11 +52,7 @@ public: int numArguments; }; - #if JUCE_COMPILER_SUPPORTS_LAMBDAS using NativeFunction = std::function; - #else - typedef var (*NativeFunction) (const NativeFunctionArgs&); - #endif //============================================================================== /** Creates a void variant. */ diff --git a/modules/juce_core/juce_core.cpp b/modules/juce_core/juce_core.cpp index d4a94c70fe..6a4fa7547a 100644 --- a/modules/juce_core/juce_core.cpp +++ b/modules/juce_core/juce_core.cpp @@ -140,6 +140,7 @@ namespace juce #include "misc/juce_RuntimePermissions.cpp" #include "misc/juce_Result.cpp" #include "misc/juce_Uuid.cpp" +#include "misc/juce_StdFunctionCompat.cpp" #include "network/juce_MACAddress.cpp" #include "network/juce_NamedPipe.cpp" #include "network/juce_Socket.cpp" diff --git a/modules/juce_core/maths/juce_NormalisableRange.h b/modules/juce_core/maths/juce_NormalisableRange.h index 6ea582c9f7..22a41c3c8d 100644 --- a/modules/juce_core/maths/juce_NormalisableRange.h +++ b/modules/juce_core/maths/juce_NormalisableRange.h @@ -107,7 +107,6 @@ public: checkInvariants(); } - #if JUCE_COMPILER_SUPPORTS_LAMBDAS /** Creates a NormalisableRange with a given range and an injective mapping function. @param rangeStart The minimum value in the range. @@ -135,17 +134,14 @@ public: { checkInvariants(); } - #endif /** Uses the properties of this mapping to convert a non-normalised value to its 0->1 representation. */ ValueType convertTo0to1 (ValueType v) const noexcept { - #if JUCE_COMPILER_SUPPORTS_LAMBDAS if (convertTo0To1Function != nullptr) return convertTo0To1Function (start, end, v); - #endif ValueType proportion = (v - start) / (end - start); @@ -168,10 +164,8 @@ public: */ ValueType convertFrom0to1 (ValueType proportion) const noexcept { - #if JUCE_COMPILER_SUPPORTS_LAMBDAS if (convertFrom0To1Function != nullptr) return convertFrom0To1Function (start, end, proportion); - #endif if (! symmetricSkew) { @@ -196,10 +190,8 @@ public: */ ValueType snapToLegalValue (ValueType v) const noexcept { - #if JUCE_COMPILER_SUPPORTS_LAMBDAS if (snapToLegalValueFunction != nullptr) return snapToLegalValueFunction (start, end, v); - #endif if (interval > ValueType()) v = start + interval * std::floor ((v - start) / interval + static_cast (0.5)); @@ -274,9 +266,7 @@ private: jassert (skew > ValueType()); } - #if JUCE_COMPILER_SUPPORTS_LAMBDAS std::function convertFrom0To1Function = nullptr, convertTo0To1Function = nullptr, snapToLegalValueFunction = nullptr; - #endif }; diff --git a/modules/juce_core/misc/juce_RuntimePermissions.h b/modules/juce_core/misc/juce_RuntimePermissions.h index 338ab3f1af..06ebb415a4 100644 --- a/modules/juce_core/misc/juce_RuntimePermissions.h +++ b/modules/juce_core/misc/juce_RuntimePermissions.h @@ -79,11 +79,7 @@ public: //============================================================================== /** Function type of runtime permission request callbacks. */ - #if JUCE_COMPILER_SUPPORTS_LAMBDAS typedef std::function Callback; - #else - typedef void (*Callback) (bool); - #endif //============================================================================== /** Call this method to request a runtime permission. diff --git a/modules/juce_core/misc/juce_StdFunctionCompat.cpp b/modules/juce_core/misc/juce_StdFunctionCompat.cpp new file mode 100644 index 0000000000..a4d85c671d --- /dev/null +++ b/modules/juce_core/misc/juce_StdFunctionCompat.cpp @@ -0,0 +1,228 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2017 - ROLI Ltd. + + Permission is granted to use this software under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license/ + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD + TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, + OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + OF THIS SOFTWARE. + + ----------------------------------------------------------------------------- + + To release a closed-source product which uses other parts of JUCE not + licensed under the ISC terms, commercial licenses are available: visit + www.juce.com for more information. + + ============================================================================== +*/ + +#if JUCE_UNIT_TESTS + +namespace FunctionTestsHelpers +{ + void incrementArgument (int& x) { x++; }; + double multiply (double x, double a) noexcept { return a * x; }; + + struct AddOne + { + int operator()(int i) const { return i + 1; } + }; +} + +class FunctionTests : public UnitTest +{ +public: + FunctionTests() : UnitTest ("Function") {} + + void runTest() override + { + struct BigData + { + int content[32]; + }; + BigData bigData; + bigData.content[0] = 8; + + { + beginTest ("Functions"); + + std::function f1 (FunctionTestsHelpers::incrementArgument); + + auto x = 0; + f1 (x); + expectEquals (x, 1); + + std::function f2 (FunctionTestsHelpers::multiply); + expectEquals (6.0, f2 (2.0, 3.0)); + + } + + { + beginTest ("Function objects"); + std::function f1 = FunctionTestsHelpers::AddOne(); + expectEquals (f1 (5), 6); + } + + { + beginTest ("Lambdas"); + + std::function fStack ([]() { return 3; }); + expectEquals (fStack(), 3); + + std::function fHeap ([=]() { return bigData.content[0]; }); + expectEquals (fHeap(), 8); + } + + { + beginTest ("Boolean"); + + std::function f1; + + if (f1) + expect (false); + + std::function f2 ([]() { return 3; }); + + if (! f2) + expect (false); + } + + std::function fEmpty; + + std::function fStack ([]() { return 3; }); + + std::function fHeap ([=]() { return bigData.content[0]; }); + + { + beginTest ("copy constructor"); + + std::function f1 (fStack); + expectEquals (f1(), 3); + + std::function f2 (fHeap); + expectEquals (f2(), 8); + + std::function f3 (fEmpty); + if (f3) + expect (false); + } + + { + beginTest ("assignment"); + + std::function f1; + f1 = fStack; + expectEquals (f1(), 3); + + std::function f2; + f2 = fHeap; + expectEquals (f2(), 8); + + f1 = fHeap; + expectEquals (f1(), 8); + + f2 = fStack; + expectEquals (f2(), 3); + + f1 = fEmpty; + if (f1) + expect (false); + } + + { + beginTest ("move constructor"); + + ScopedPointer> fStackTmp = new std::function (fStack); + std::function f1 (static_cast&&> (*fStackTmp)); + + fStackTmp = nullptr; + expectEquals (f1(), 3); + + ScopedPointer> fHeapTmp = new std::function (fHeap); + std::function f2 (static_cast&&> (*fHeapTmp)); + if (*fHeapTmp) + expect (false); + + fHeapTmp = nullptr; + expectEquals (f2(), 8); + + ScopedPointer> fEmptyTmp = new std::function(); + std::function f3 (static_cast&&> (*fEmptyTmp)); + fEmptyTmp = nullptr; + if (f3) + expect (false); + } + + { + beginTest ("move assignment"); + + std::function f1 (fHeap); + ScopedPointer> fStackTmp = new std::function (fStack); + f1 = static_cast&&> (*fStackTmp); + + fStackTmp = nullptr; + expectEquals (f1(), 3); + + std::function f2 (fStack); + ScopedPointer> fHeapTmp = new std::function (fHeap); + f2 = static_cast&&> (*fHeapTmp); + if (*fHeapTmp) + expect (false); + + fHeapTmp = nullptr; + expectEquals (f2(), 8); + + std::function f3 (fHeap); + ScopedPointer> fEmptyTmp = new std::function (); + f3 = static_cast&&> (*fEmptyTmp); + fEmptyTmp = nullptr; + if (f3) + expect (false); + } + + { + beginTest ("nullptr"); + + std::function f1 (nullptr); + if (f1) + expect (false); + + std::function f2 ([]() { return 11; }); + f2 = nullptr; + if (f2) + expect (false); + } + + { + beginTest ("Swap"); + + std::function f1; + std::function f2 (fStack); + f2.swap (f1); + expectEquals (f1(), 3); + if (f2) + expect (false); + + std::function f3 (fHeap); + f3.swap (f1); + expectEquals (f3(), 3); + expectEquals (f1(), 8); + } + } +}; + +static FunctionTests functionTests; + +#endif diff --git a/modules/juce_core/misc/juce_StdFunctionCompat.h b/modules/juce_core/misc/juce_StdFunctionCompat.h new file mode 100644 index 0000000000..9fcde88a94 --- /dev/null +++ b/modules/juce_core/misc/juce_StdFunctionCompat.h @@ -0,0 +1,225 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2017 - ROLI Ltd. + + Permission is granted to use this software under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license/ + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD + TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, + OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + OF THIS SOFTWARE. + + ----------------------------------------------------------------------------- + + To release a closed-source product which uses other parts of JUCE not + licensed under the ISC terms, commercial licenses are available: visit + www.juce.com for more information. + + ============================================================================== +*/ + +#pragma once + +namespace std +{ + /** + This class provides an alternative to std::function that is compatible + with OS X 10.6 and earlier. This will only be used in OS X versions 10.6 + and earlier and the Projucer live build. + */ + + template + class function; + + template + class function + { + public: + /** Creates an empty function. */ + function() noexcept {} + + /** Creates an empty function. */ + function (decltype (nullptr)) noexcept {} + + /** Creates a function targetting the provided Functor. */ + template + function (Functor f) + { + functorHolderHelper = createFunctorStorage (sizeof (FunctorHolder)); + new (functorHolderHelper) FunctorHolder (f); + } + + /** Copy constructor. */ + function (function const& other) + { + copy (other); + } + + /** Move constructor */ + function (function&& other) + { + move (other); + } + + /** Destructor. */ + ~function() + { + release(); + } + + /** Replaces the contents of this function with the contents of another. */ + function& operator= (function const& other) + { + release(); + copy (other); + + return *this; + } + + /** Moves the contents of another function into this one. */ + function& operator= (function&& other) + { + release(); + move (other); + + return *this; + } + + /** Allows conditional expressions to test if this function is empty. */ + explicit operator bool() const noexcept + { + return functorHolderHelper != nullptr; + } + + /** Swaps the contents of this function with another. After this operation the + two functions will be pointing at each other's targets. */ + void swap (function& other) + { + function tmp (*this); + *this = other; + other = tmp; + } + + /** Invokes the target of this function. */ + Result operator() (Arguments... args) const + { + return (*functorHolderHelper) (args...); + } + + bool operator== (decltype (nullptr)) const noexcept { return (functorHolderHelper == nullptr); } + bool operator!= (decltype (nullptr)) const noexcept { return (functorHolderHelper != nullptr); } + + private: + //============================================================================== + template + struct FunctorHolderBase + { + virtual ~FunctorHolderBase() {}; + virtual size_t getSize() const noexcept = 0; + virtual FunctorHolderBase* copy (void*) const = 0; + virtual ReturnType operator()(Args...) = 0; + }; + + template + struct FunctorHolder : FunctorHolderBase + { + FunctorHolder (Functor func) : f (func) {} + + size_t getSize() const noexcept override final + { + return sizeof (*this); + } + + FunctorHolder* copy (void* destination) const override final + { + return new (destination) FunctorHolder (f); + } + + ReturnType operator()(Args... args) override final + { + return f (args...); + } + + Functor f; + }; + + FunctorHolderBase* createFunctorStorage (size_t size) + { + void* storagePointer; + + if (size > functorHolderStackSize) + { + if (heapFunctorStorage != nullptr) + { + delete [] heapFunctorStorage; + heapFunctorStorage = nullptr; + } + + heapFunctorStorage = new char [size]; + storagePointer = heapFunctorStorage; + } + else + { + storagePointer = &(stackFunctorStorage[0]); + } + + return reinterpret_cast*> (storagePointer); + } + + void copy (function const& other) + { + if (other.functorHolderHelper != nullptr) + { + functorHolderHelper = createFunctorStorage (other.functorHolderHelper->getSize()); + other.functorHolderHelper->copy (functorHolderHelper); + } + } + + void move (function& other) + { + functorHolderHelper = other.functorHolderHelper; + + if (functorHolderHelper != nullptr) + { + if (functorHolderHelper->getSize() > functorHolderStackSize) + { + heapFunctorStorage = other.heapFunctorStorage; + other.heapFunctorStorage = nullptr; + } + else + { + std::copy (other.stackFunctorStorage, other.stackFunctorStorage + functorHolderStackSize, + stackFunctorStorage); + functorHolderHelper = reinterpret_cast*> (&(stackFunctorStorage[0])); + } + + other.functorHolderHelper = nullptr; + } + } + + void release() + { + if (functorHolderHelper != nullptr) + { + functorHolderHelper->~FunctorHolderBase(); + functorHolderHelper = nullptr; + } + } + + static const int functorHolderStackSize = 24; + char stackFunctorStorage[functorHolderStackSize]; + char* heapFunctorStorage = nullptr; + + FunctorHolderBase* functorHolderHelper = nullptr; + }; +} diff --git a/modules/juce_core/system/juce_CompilerSupport.h b/modules/juce_core/system/juce_CompilerSupport.h index 00e4bc7c72..6195e99e40 100644 --- a/modules/juce_core/system/juce_CompilerSupport.h +++ b/modules/juce_core/system/juce_CompilerSupport.h @@ -44,6 +44,7 @@ #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && ! defined (JUCE_COMPILER_SUPPORTS_LAMBDAS) #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 + #define JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT 1 #endif #ifndef JUCE_EXCEPTIONS_DISABLED @@ -65,10 +66,14 @@ #define JUCE_DELETED_FUNCTION = delete #endif - #if __has_feature (cxx_lambdas) && (defined (_LIBCPP_VERSION) || ! (JUCE_MAC || JUCE_IOS)) + #if __has_feature (cxx_lambdas) #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 #endif + #if (defined (_LIBCPP_VERSION) || ! (JUCE_MAC || JUCE_IOS)) + #define JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT 1 + #endif + #if __has_feature (cxx_generalized_initializers) && (defined (_LIBCPP_VERSION) || ! (JUCE_MAC || JUCE_IOS)) #define JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS 1 #endif @@ -106,6 +111,7 @@ #define JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS 1 #define JUCE_COMPILER_SUPPORTS_VARIADIC_TEMPLATES 1 #define JUCE_DELETED_FUNCTION = delete + #define JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT 1 #endif #if _MSC_VER >= 1900 diff --git a/modules/juce_core/system/juce_StandardHeader.h b/modules/juce_core/system/juce_StandardHeader.h index 7e574301e7..981457fe44 100644 --- a/modules/juce_core/system/juce_StandardHeader.h +++ b/modules/juce_core/system/juce_StandardHeader.h @@ -107,6 +107,12 @@ #undef minor #undef KeyPress +// Include a replacement for std::function on older platforms and the live +// build +#if JUCE_PROJUCER_LIVE_BUILD || ! defined (JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT) + #include "../misc/juce_StdFunctionCompat.h" +#endif + //============================================================================== // DLL building settings on Windows #if JUCE_MSVC diff --git a/modules/juce_events/timers/juce_Timer.cpp b/modules/juce_events/timers/juce_Timer.cpp index d74adaa3a2..da2ea738ee 100644 --- a/modules/juce_events/timers/juce_Timer.cpp +++ b/modules/juce_events/timers/juce_Timer.cpp @@ -341,7 +341,6 @@ void JUCE_CALLTYPE Timer::callPendingTimersSynchronously() TimerThread::instance->callTimersSynchronously(); } -#if JUCE_COMPILER_SUPPORTS_LAMBDAS struct LambdaInvoker : private Timer { LambdaInvoker (int milliseconds, std::function f) : function (f) @@ -365,4 +364,3 @@ void JUCE_CALLTYPE Timer::callAfterDelay (int milliseconds, std::function functionToCall); - #endif //============================================================================== /** For internal use only: invokes any timers that need callbacks. diff --git a/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp b/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp index 9cfc75940d..d0cbb13f5b 100644 --- a/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp +++ b/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp @@ -297,7 +297,6 @@ int ModalComponentManager::runEventLoopForCurrentComponent() #endif //============================================================================== -#if JUCE_COMPILER_SUPPORTS_LAMBDAS struct LambdaCallback : public ModalComponentManager::Callback { LambdaCallback (std::function fn) noexcept : function (fn) {} @@ -312,4 +311,3 @@ ModalComponentManager::Callback* ModalCallbackFunction::create (std::function (functionToCall, parameterValue); } - #if JUCE_COMPILER_SUPPORTS_LAMBDAS /** This is a utility function to create a ModalComponentManager::Callback that will call a lambda function. The lambda that you supply must take an integer parameter, which is the result code that @@ -197,7 +196,6 @@ public: @see ModalComponentManager::Callback */ static ModalComponentManager::Callback* create (std::function); - #endif //============================================================================== /** This is a utility function to create a ModalComponentManager::Callback that will From 7f5abd41b17d9be54f8dc9d693f2cfc9e6dbc09b Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 3 May 2017 15:42:38 +0100 Subject: [PATCH 37/54] Projucer: Fixed a crash in the android exporter when VST3 is enabled --- .../jucer_ProjectExport_Android.h | 21 +++++++------------ .../Project Saving/jucer_ProjectExporter.cpp | 20 ++++++++++-------- .../Project/jucer_ConfigTree_Exporter.h | 9 +++----- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_Android.h index b044c155bd..9710f50005 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_Android.h @@ -770,7 +770,7 @@ private: //============================================================================== String createDefaultClassName() const { - String s (project.getBundleIdentifier().toString().toLowerCase()); + auto s = project.getBundleIdentifier().toString().toLowerCase(); if (s.length() > 5 && s.containsChar ('.') @@ -790,11 +790,8 @@ private: void initialiseDependencyPathValues() { - sdkPath.referTo (Value (new DependencyPathValueSource (getSetting (Ids::androidSDKPath), - Ids::androidSDKPath, TargetOS::getThisOS()))); - - ndkPath.referTo (Value (new DependencyPathValueSource (getSetting (Ids::androidNDKPath), - Ids::androidNDKPath, TargetOS::getThisOS()))); + sdkPath.referTo (Value (new DependencyPathValueSource (getSetting (Ids::androidSDKPath), Ids::androidSDKPath, TargetOS::getThisOS()))); + ndkPath.referTo (Value (new DependencyPathValueSource (getSetting (Ids::androidNDKPath), Ids::androidNDKPath, TargetOS::getThisOS()))); } //============================================================================== @@ -807,9 +804,7 @@ private: createDirectoryOrThrow (targetFolder); - LibraryModule* const coreModule = getCoreModule (modules); - - if (coreModule != nullptr) + if (auto* coreModule = getCoreModule (modules)) { File javaDestFile (targetFolder.getChildFile (className + ".java")); @@ -840,16 +835,14 @@ private: .replace ("JuceAppActivity", className); } - File javaSourceFile (javaSourceFolder.getChildFile ("JuceAppActivity.java")); - StringArray javaSourceLines (StringArray::fromLines (javaSourceFile.loadFileAsString())); + auto javaSourceFile = javaSourceFolder.getChildFile ("JuceAppActivity.java"); + auto javaSourceLines = StringArray::fromLines (javaSourceFile.loadFileAsString()); { MemoryOutputStream newFile; - for (int i = 0; i < javaSourceLines.size(); ++i) + for (const auto& line : javaSourceLines) { - const String& line = javaSourceLines[i]; - if (line.contains ("$$JuceAndroidMidiImports$$")) newFile << juceMidiImports; else if (line.contains ("$$JuceAndroidMidiCode$$")) diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp b/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp index 5ec4b8ef62..99af25731a 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp @@ -86,10 +86,9 @@ ProjectExporter* ProjectExporter::createNewExporter (Project& project, const int StringArray ProjectExporter::getExporterNames() { StringArray s; - Array types (getExporterTypes()); - for (int i = 0; i < types.size(); ++i) - s.add (types.getReference(i).name); + for (auto& e : getExporterTypes()) + s.add (e.name); return s; } @@ -225,20 +224,23 @@ void ProjectExporter::createDependencyPathProperties (PropertyListBuilder& props { if (shouldBuildTargetType (ProjectType::Target::VST3PlugIn) || project.isVST3PluginHost()) { - props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getVST3PathValue(), "VST3 SDK Folder"), - "If you're building a VST3 plugin or host, this must be the folder containing the VST3 SDK. This can be an absolute path, or a path relative to the Projucer project file."); + if (dynamic_cast (&getVST3PathValue().getValueSource()) != nullptr) + props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getVST3PathValue(), "VST3 SDK Folder"), + "If you're building a VST3 plugin or host, this must be the folder containing the VST3 SDK. This can be an absolute path, or a path relative to the Projucer project file."); } if (shouldBuildTargetType (ProjectType::Target::AAXPlugIn) && project.shouldBuildAAX()) { - props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getAAXPathValue(), "AAX SDK Folder"), - "If you're building an AAX plugin, this must be the folder containing the AAX SDK. This can be an absolute path, or a path relative to the Projucer project file."); + if (dynamic_cast (&getAAXPathValue().getValueSource()) != nullptr) + props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getAAXPathValue(), "AAX SDK Folder"), + "If you're building an AAX plugin, this must be the folder containing the AAX SDK. This can be an absolute path, or a path relative to the Projucer project file."); } if (shouldBuildTargetType (ProjectType::Target::RTASPlugIn) && project.shouldBuildRTAS()) { - props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getRTASPathValue(), "RTAS SDK Folder"), - "If you're building an RTAS, this must be the folder containing the RTAS SDK. This can be an absolute path, or a path relative to the Projucer project file."); + if (dynamic_cast (&getRTASPathValue().getValueSource()) != nullptr) + props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getRTASPathValue(), "RTAS SDK Folder"), + "If you're building an RTAS, this must be the folder containing the RTAS SDK. This can be an absolute path, or a path relative to the Projucer project file."); } } diff --git a/extras/Projucer/Source/Project/jucer_ConfigTree_Exporter.h b/extras/Projucer/Source/Project/jucer_ConfigTree_Exporter.h index d25e699041..cb575d3ab1 100644 --- a/extras/Projucer/Source/Project/jucer_ConfigTree_Exporter.h +++ b/extras/Projucer/Source/Project/jucer_ConfigTree_Exporter.h @@ -155,9 +155,8 @@ private: int exporterIndex; //============================================================================== - class SettingsComp : public Component + struct SettingsComp : public Component { - public: SettingsComp (ProjectExporter* exp) : group (exp->getName(), ExporterItem::getIconForExporter (exp)) { @@ -169,11 +168,9 @@ private: parentSizeChanged(); } - void parentSizeChanged() override { updateSize (*this, group); } + void parentSizeChanged() override { updateSize (*this, group); } + void resized() override { group.setBounds (getLocalBounds().withTrimmedLeft (12)); } - void resized() override { group.setBounds (getLocalBounds().withTrimmedLeft (12)); } - - private: PropertyGroupComponent group; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SettingsComp) From dc2ec6fc9df135a4c8f3368674e9676096a7db61 Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 3 May 2017 16:44:05 +0100 Subject: [PATCH 38/54] Added some failure checks in internal OSC message sending code, and tidied up some old code --- modules/juce_osc/osc/juce_OSCReceiver.cpp | 62 +++++++++-------------- modules/juce_osc/osc/juce_OSCSender.cpp | 28 +++++----- 2 files changed, 40 insertions(+), 50 deletions(-) diff --git a/modules/juce_osc/osc/juce_OSCReceiver.cpp b/modules/juce_osc/osc/juce_OSCReceiver.cpp index 48f11dce6f..6dd6d2de2a 100644 --- a/modules/juce_osc/osc/juce_OSCReceiver.cpp +++ b/modules/juce_osc/osc/juce_OSCReceiver.cpp @@ -57,7 +57,7 @@ namespace size_t getDataSize() const noexcept { return input.getDataSize(); } /** Returns the current position of the stream. */ - uint64 getPosition() { return uint64 (input.getPosition()); } + uint64 getPosition() { return uint64 (input.getPosition()); } /** Attempts to set the current position of the stream. Returns true if this was successful. */ bool setPosition (int64 pos) { return input.setPosition (pos); } @@ -174,7 +174,7 @@ namespace typeList.add (type); } - size_t bytesRead = (size_t) typeList.size() + 2; + auto bytesRead = (size_t) typeList.size() + 2; readPaddingZeros (bytesRead); return typeList; @@ -205,8 +205,8 @@ namespace OSCMessage msg (ap); - for (OSCType* type = types.begin(); type != types.end(); ++type) - msg.addArgument (readArgument (*type)); + for (auto& type : types) + msg.addArgument (readArgument (type)); return msg; } @@ -227,13 +227,13 @@ namespace OSCBundle bundle (readTimeTag()); size_t bytesRead = 16; // already read "#bundle" and timeTag - size_t pos = getPosition(); + auto pos = getPosition(); while (! isExhausted() && bytesRead < maxBytesToRead) { bundle.addElement (readElement()); - const size_t newPos = getPosition(); + auto newPos = getPosition(); bytesRead += newPos - pos; pos = newPos; } @@ -245,12 +245,12 @@ namespace OSCBundle::Element readElement() { if (input.getNumBytesRemaining() < 4) - throw OSCFormatError("OSC input stream exhausted while reading bundle element size"); + throw OSCFormatError ("OSC input stream exhausted while reading bundle element size"); - const size_t elementSize = (size_t) readInt32(); + auto elementSize = (size_t) readInt32(); if (elementSize < 4) - throw OSCFormatError("OSC input stream format error: invalid bundle element size"); + throw OSCFormatError ("OSC input stream format error: invalid bundle element size"); return readElementWithKnownSize (elementSize); } @@ -261,7 +261,7 @@ namespace if ((uint64) input.getNumBytesRemaining() < elementSize) throw OSCFormatError ("OSC input stream exhausted while reading bundle element content"); - const char firstContentChar = static_cast (getData()) [getPosition()]; + auto firstContentChar = static_cast (getData()) [getPosition()]; if (firstContentChar == '/') return OSCBundle::Element (readMessageWithCheckedSize (elementSize)); if (firstContentChar == '#') return OSCBundle::Element (readBundleWithCheckedSize (elementSize)); @@ -288,8 +288,8 @@ namespace OSCBundle readBundleWithCheckedSize (size_t size) { - const size_t begin = (size_t) getPosition(); - const size_t maxBytesToRead = size - 4; // we've already read 4 bytes (the bundle size) + auto begin = (size_t) getPosition(); + auto maxBytesToRead = size - 4; // we've already read 4 bytes (the bundle size) OSCBundle bundle (readBundle (maxBytesToRead)); @@ -301,7 +301,7 @@ namespace OSCMessage readMessageWithCheckedSize (size_t size) { - const size_t begin = (size_t) getPosition(); + auto begin = (size_t) getPosition(); OSCMessage message (readMessage()); if (getPosition() - begin != size) @@ -456,7 +456,7 @@ private: if (threadShouldExit()) return; - const size_t bytesRead = (size_t) socket->read (buffer, (int) sizeof (buffer), false); + auto bytesRead = (size_t) socket->read (buffer, (int) sizeof (buffer), false); if (bytesRead >= 4) handleBuffer (buffer, bytesRead); @@ -469,8 +469,8 @@ private: OSCAddress address, Array >& array) { - for (int i = 0; i < array.size(); ++i) - if (address == array.getReference (i).first && listenerToAdd == array.getReference (i).second) + for (auto& i : array) + if (address == i.first && listenerToAdd == i.second) return; array.add (std::make_pair (address, listenerToAdd)); @@ -498,9 +498,9 @@ private: //============================================================================== void handleMessage (const Message& msg) override { - if (const CallbackMessage* callbackMessage = dynamic_cast (&msg)) + if (auto* callbackMessage = dynamic_cast (&msg)) { - const OSCBundle::Element& content = callbackMessage->content; + auto& content = callbackMessage->content; callListeners (content); @@ -533,30 +533,18 @@ private: //============================================================================== void callListenersWithAddress (const OSCMessage& message) { - typedef OSCReceiver::ListenerWithOSCAddress Listener; - - for (std::pair* entry = listenersWithAddress.begin(); - entry != listenersWithAddress.end(); - ++entry) - { - if (Listener* listener = entry->second) - if (message.getAddressPattern().matches (entry->first)) + for (auto& entry : listenersWithAddress) + if (auto* listener = entry.second) + if (message.getAddressPattern().matches (entry.first)) listener->oscMessageReceived (message); - } } void callRealtimeListenersWithAddress (const OSCMessage& message) { - typedef OSCReceiver::ListenerWithOSCAddress Listener; - - for (std::pair* entry = realtimeListenersWithAddress.begin(); - entry != realtimeListenersWithAddress.end(); - ++entry) - { - if (Listener* listener = entry->second) - if (message.getAddressPattern().matches (entry->first)) + for (auto& entry : listenersWithAddress) + if (auto* listener = entry.second) + if (message.getAddressPattern().matches (entry.first)) listener->oscMessageReceived (message); - } } //============================================================================== @@ -567,7 +555,7 @@ private: Array* > > realtimeListenersWithAddress; ScopedPointer socket; - int portNumber; + int portNumber = 0; OSCReceiver::FormatErrorHandler formatErrorHandler; enum { oscBufferSize = 4098 }; diff --git a/modules/juce_osc/osc/juce_OSCSender.cpp b/modules/juce_osc/osc/juce_OSCSender.cpp index 3f69e05260..80084c1c71 100644 --- a/modules/juce_osc/osc/juce_OSCSender.cpp +++ b/modules/juce_osc/osc/juce_OSCSender.cpp @@ -34,7 +34,7 @@ namespace This class implements the Open Sound Control 1.0 Specification for the format in which the OSC data will be written into the buffer. - */ + */ struct OSCOutputStream { OSCOutputStream() noexcept {} @@ -136,14 +136,14 @@ namespace OSCTypeList typeList; - for (OSCArgument* arg = msg.begin(); arg != msg.end(); ++arg) - typeList.add (arg->getType()); + for (auto& arg : msg) + typeList.add (arg.getType()); if (! writeTypeTagString (typeList)) return false; - for (OSCArgument* arg = msg.begin(); arg != msg.end(); ++arg) - if (! writeArgument (*arg)) + for (auto& arg : msg) + if (! writeArgument (arg)) return false; return true; @@ -157,8 +157,8 @@ namespace if (! writeTimeTag (bundle.getTimeTag())) return false; - for (OSCBundle::Element* element = bundle.begin(); element != bundle.end(); ++element) - if (! writeBundleElement (*element)) + for (auto& element : bundle) + if (! writeBundleElement (element)) return false; return true; @@ -203,7 +203,7 @@ namespace //============================================================================== struct OSCSender::Pimpl { - Pimpl() noexcept : targetPortNumber (0) {} + Pimpl() noexcept {} ~Pimpl() noexcept { disconnect(); } //============================================================================== @@ -233,15 +233,17 @@ struct OSCSender::Pimpl bool send (const OSCMessage& message, const String& hostName, int portNumber) { OSCOutputStream outStream; - outStream.writeMessage (message); - return sendOutputStream (outStream, hostName, portNumber); + + return outStream.writeMessage (message) + && sendOutputStream (outStream, hostName, portNumber); } bool send (const OSCBundle& bundle, const String& hostName, int portNumber) { OSCOutputStream outStream; - outStream.writeBundle (bundle); - return sendOutputStream (outStream, hostName, portNumber); + + return outStream.writeBundle (bundle) + && sendOutputStream (outStream, hostName, portNumber); } bool send (const OSCMessage& message) { return send (message, targetHostName, targetPortNumber); } @@ -270,7 +272,7 @@ private: //============================================================================== ScopedPointer socket; String targetHostName; - int targetPortNumber; + int targetPortNumber = 0; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) }; From 93f9ab24bb76eff5c8e7ad2dc203cdba1d37c0b4 Mon Sep 17 00:00:00 2001 From: tpoole Date: Thu, 4 May 2017 09:01:42 +0100 Subject: [PATCH 39/54] Fixed Projucer compile on VS2013 --- extras/Projucer/Source/Licenses/jucer_LicenseThread.h | 6 +++--- extras/Projucer/Source/Licenses/jucer_LicenseWebview.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseThread.h b/extras/Projucer/Source/Licenses/jucer_LicenseThread.h index 6d9a2b74a0..d65f2ae1e9 100644 --- a/extras/Projucer/Source/Licenses/jucer_LicenseThread.h +++ b/extras/Projucer/Source/Licenses/jucer_LicenseThread.h @@ -263,7 +263,7 @@ struct LicenseThread : NetWorkerThread DynamicObject::Ptr redeamObject = new DynamicObject(); redeamObject->setProperty (serialIdentifier, productKey); - String postData (JSON::toString (var (redeamObject))); + String postData (JSON::toString (var (redeamObject.get()))); ScopedPointer shared = getSharedWebInputStream (URL ("https://api.roli.com/api/v1/user/products").withPOSTData (postData), true); @@ -292,11 +292,11 @@ struct LicenseThread : NetWorkerThread DynamicObject::Ptr jsonLicenseRequest = new DynamicObject(); - jsonLicenseRequest->setProperty (licenseIdentifier, var (jsonLicenseObject)); + jsonLicenseRequest->setProperty (licenseIdentifier, var (jsonLicenseObject.get())); jsonLicenseRequest->setProperty (searchInternalIdentifier, "com.roli.projucer"); jsonLicenseRequest->setProperty (licenseTypeIdentifier, "software"); - String postData (JSON::toString (var (jsonLicenseRequest))); + String postData (JSON::toString (var (jsonLicenseRequest.get()))); ScopedPointer shared = getSharedWebInputStream (URL ("https://api.roli.com/api/v1/user/products/redeem").withPOSTData (postData), true); diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseWebview.h b/extras/Projucer/Source/Licenses/jucer_LicenseWebview.h index 1a285e0f59..21eba575ac 100644 --- a/extras/Projucer/Source/Licenses/jucer_LicenseWebview.h +++ b/extras/Projucer/Source/Licenses/jucer_LicenseWebview.h @@ -138,7 +138,7 @@ private: } } - static constexpr uint32 backgroundColour = 0xff414141; + const uint32 backgroundColour = 0xff414141; ScopedPointer juceLogo = Drawable::createFromImageData (BinaryData::jucelogowithtext_svg, BinaryData::jucelogowithtext_svgSize); From 098110bc5fe89e32405e6418a271c2d193d5778a Mon Sep 17 00:00:00 2001 From: tpoole Date: Thu, 4 May 2017 09:54:52 +0100 Subject: [PATCH 40/54] Suppressed a VS2013 assignment operator compiler warning --- modules/juce_core/containers/juce_Variant.h | 3 +++ .../positioning/juce_RelativeCoordinatePositioner.cpp | 3 +++ .../positioning/juce_RelativeCoordinatePositioner.h | 3 +++ 3 files changed, 9 insertions(+) diff --git a/modules/juce_core/containers/juce_Variant.h b/modules/juce_core/containers/juce_Variant.h index eeb20f0252..d227a6a046 100644 --- a/modules/juce_core/containers/juce_Variant.h +++ b/modules/juce_core/containers/juce_Variant.h @@ -47,6 +47,9 @@ public: { NativeFunctionArgs (const var& thisObject, const var* args, int numArgs) noexcept; + // Suppress a VS2013 compiler warning + NativeFunctionArgs& operator= (const NativeFunctionArgs&) = delete; + const var& thisObject; const var* arguments; int numArguments; diff --git a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp index d198829f56..7260710de1 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp @@ -28,6 +28,9 @@ struct MarkerListScope : public Expression::Scope { MarkerListScope (Component& comp) : component (comp) {} + // Suppress a VS2013 compiler warning + MarkerListScope& operator= (const MarkerListScope&) = delete; + Expression getSymbolValue (const String& symbol) const override { switch (RelativeCoordinate::StandardStrings::getTypeOf (symbol)) diff --git a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h index 0845e6359b..74abf43601 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h +++ b/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h @@ -58,6 +58,9 @@ public: public: ComponentScope (Component&); + // Suppress a VS2013 compiler warning + ComponentScope& operator= (const ComponentScope&) = delete; + Expression getSymbolValue (const String& symbol) const; void visitRelativeScope (const String& scopeName, Visitor&) const; String getScopeUID() const; From 2b4d0d88198d7db8c11f9c9ed542c991f97970dd Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 4 May 2017 10:49:31 +0100 Subject: [PATCH 41/54] Disabled some more warnings in 3rd party AU and AAX code --- modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp | 1 + modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm | 1 + .../juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm | 1 + 3 files changed, 3 insertions(+) diff --git a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp index cf5c997c66..2e6614bc53 100644 --- a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp +++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp @@ -37,6 +37,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnon-virtual-dtor" #pragma clang diagnostic ignored "-Wsign-conversion" + #pragma clang diagnostic ignored "-Wextra-semi" #endif #ifdef _MSC_VER diff --git a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm index adc403c78c..d940b34771 100644 --- a/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm +++ b/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm @@ -42,6 +42,7 @@ #pragma clang diagnostic ignored "-Wsign-conversion" #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Woverloaded-virtual" + #pragma clang diagnostic ignored "-Wextra-semi" #endif #include "../utility/juce_IncludeSystemHeaders.h" diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm index 897184f32b..43d9889f6e 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm @@ -32,6 +32,7 @@ #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wunused-parameter" #pragma clang diagnostic ignored "-Wunused" + #pragma clang diagnostic ignored "-Wextra-semi" #endif #ifdef _MSC_VER From 7031f595d22fb25288193bc03c045110c667364a Mon Sep 17 00:00:00 2001 From: hogliux Date: Thu, 4 May 2017 10:51:08 +0100 Subject: [PATCH 42/54] Fixed an issue where thread names were not set on Android --- modules/juce_core/native/juce_BasicNativeHeaders.h | 1 + modules/juce_core/native/juce_posix_SharedCode.h | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/juce_core/native/juce_BasicNativeHeaders.h b/modules/juce_core/native/juce_BasicNativeHeaders.h index 47b3a3b3b2..0ed4035a6a 100644 --- a/modules/juce_core/native/juce_BasicNativeHeaders.h +++ b/modules/juce_core/native/juce_BasicNativeHeaders.h @@ -252,6 +252,7 @@ #include #include #include + #include #endif // Need to clear various moronic redefinitions made by system headers.. diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h index 46886e2716..d5f20dbc1d 100644 --- a/modules/juce_core/native/juce_posix_SharedCode.h +++ b/modules/juce_core/native/juce_posix_SharedCode.h @@ -975,8 +975,9 @@ void JUCE_CALLTYPE Thread::setCurrentThreadName (const String& name) { [[NSThread currentThread] setName: juceStringToNS (name)]; } - #elif JUCE_LINUX - #if (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012 + #elif JUCE_LINUX || JUCE_ANDROID + #if ((JUCE_LINUX && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2012) \ + || JUCE_ANDROID && __ANDROID_API__ >= 9) pthread_setname_np (pthread_self(), name.toRawUTF8()); #else prctl (PR_SET_NAME, name.toRawUTF8(), 0, 0, 0); From a1794b1143fc0cde774ad4a6b0e324d58c12173d Mon Sep 17 00:00:00 2001 From: hogliux Date: Thu, 4 May 2017 11:29:05 +0100 Subject: [PATCH 43/54] Fixed a linker issue on some versions of linux where a newer webkit symbol might not be available --- .../native/juce_linux_X11_WebBrowserComponent.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp b/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp index 98146f04c6..07c64fbe23 100644 --- a/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp +++ b/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp @@ -156,6 +156,8 @@ public: : outChannel (outChannelToUse), receiver (this, inChannel) {} + typedef void (*SetHardwareAcclPolicyFunctionPtr) (WebKitSettings*, int); + int entry() { CommandReceiver::setBlocking (outChannel, true); @@ -163,7 +165,14 @@ public: gtk_init (nullptr, nullptr); WebKitSettings* settings = webkit_settings_new(); - webkit_settings_set_hardware_acceleration_policy (settings, WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER); + + // webkit_settings_set_hardware_acceleration_policy was only added recently to webkit2 + // but is needed when running a WebBrowserComponent in a Parallels VM with 3D acceleration enabled + auto setHardwarePolicy + = reinterpret_cast (dlsym (RTLD_DEFAULT, "webkit_settings_set_hardware_acceleration_policy")); + + if (setHardwarePolicy != nullptr) + setHardwarePolicy (settings, 2 /*WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER*/); GtkWidget *plug; From 0c24b48be8031d56c69d528b93d4454ded06dd4f Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 4 May 2017 11:51:06 +0100 Subject: [PATCH 44/54] Fix for detection of number of CPU cores on Windows --- modules/juce_core/native/juce_win32_SystemStats.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/juce_core/native/juce_win32_SystemStats.cpp b/modules/juce_core/native/juce_win32_SystemStats.cpp index 0207014bb4..2361a8d4eb 100644 --- a/modules/juce_core/native/juce_win32_SystemStats.cpp +++ b/modules/juce_core/native/juce_win32_SystemStats.cpp @@ -99,10 +99,10 @@ static int findNumberOfPhysicalCores() noexcept { int numPhysicalCores = 0; DWORD bufferSize = 0; + GetLogicalProcessorInformation (nullptr, &bufferSize); - if (GetLogicalProcessorInformation (nullptr, &bufferSize)) + if (auto numBuffers = (size_t) (bufferSize / sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION))) { - const size_t numBuffers = (size_t) (bufferSize / sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); HeapBlock buffer (numBuffers); if (GetLogicalProcessorInformation (buffer, &bufferSize)) From 014311fdbfcd1d7393fb34cb8588a03901a1eb52 Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 4 May 2017 12:02:37 +0100 Subject: [PATCH 45/54] Added some comparison and getter methods to Uuid. --- modules/juce_core/misc/juce_Uuid.cpp | 25 +++++++++++++++++++++++-- modules/juce_core/misc/juce_Uuid.h | 19 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/modules/juce_core/misc/juce_Uuid.cpp b/modules/juce_core/misc/juce_Uuid.cpp index f8f0e4e89f..03f911cbf2 100644 --- a/modules/juce_core/misc/juce_Uuid.cpp +++ b/modules/juce_core/misc/juce_Uuid.cpp @@ -48,6 +48,20 @@ Uuid& Uuid::operator= (const Uuid& other) noexcept bool Uuid::operator== (const Uuid& other) const noexcept { return memcmp (uuid, other.uuid, sizeof (uuid)) == 0; } bool Uuid::operator!= (const Uuid& other) const noexcept { return ! operator== (other); } +bool Uuid::operator< (const Uuid& other) const noexcept { return compare (other) < 0; } +bool Uuid::operator> (const Uuid& other) const noexcept { return compare (other) > 0; } +bool Uuid::operator<= (const Uuid& other) const noexcept { return compare (other) <= 0; } +bool Uuid::operator>= (const Uuid& other) const noexcept { return compare (other) >= 0; } + +int Uuid::compare (Uuid other) const noexcept +{ + for (size_t i = 0; i < sizeof (uuid); ++i) + if (int diff = uuid[i] - (int) other.uuid[i]) + return diff > 0 ? 1 : -1; + + return 0; +} + Uuid Uuid::null() noexcept { return Uuid ((const uint8*) nullptr); @@ -55,8 +69,8 @@ Uuid Uuid::null() noexcept bool Uuid::isNull() const noexcept { - for (size_t i = 0; i < sizeof (uuid); ++i) - if (uuid[i] != 0) + for (auto i : uuid) + if (i != 0) return false; return true; @@ -109,3 +123,10 @@ Uuid& Uuid::operator= (const uint8* const rawData) noexcept return *this; } + +uint32 Uuid::getTimeLow() const noexcept { return ByteOrder::bigEndianInt (uuid); } +uint16 Uuid::getTimeMid() const noexcept { return ByteOrder::bigEndianShort (uuid + 4); } +uint16 Uuid::getTimeHighAndVersion() const noexcept { return ByteOrder::bigEndianShort (uuid + 6); } +uint8 Uuid::getClockSeqAndReserved() const noexcept { return uuid[8]; } +uint8 Uuid::getClockSeqLow() const noexcept { return uuid[9]; } +uint64 Uuid::getNode() const noexcept { return (((uint64) ByteOrder::bigEndianShort (uuid + 10)) << 32) + ByteOrder::bigEndianInt (uuid + 12); } diff --git a/modules/juce_core/misc/juce_Uuid.h b/modules/juce_core/misc/juce_Uuid.h index 2c1b80df96..cab55d8dc7 100644 --- a/modules/juce_core/misc/juce_Uuid.h +++ b/modules/juce_core/misc/juce_Uuid.h @@ -58,6 +58,10 @@ public: bool operator== (const Uuid&) const noexcept; bool operator!= (const Uuid&) const noexcept; + bool operator< (const Uuid&) const noexcept; + bool operator> (const Uuid&) const noexcept; + bool operator<= (const Uuid&) const noexcept; + bool operator>= (const Uuid&) const noexcept; //============================================================================== /** Returns a stringified version of this UUID. @@ -85,6 +89,20 @@ public: Uuid& operator= (const String& uuidString); + //============================================================================== + /** Returns the time-low section of the UUID. */ + uint32 getTimeLow() const noexcept; + /** Returns the time-mid section of the UUID. */ + uint16 getTimeMid() const noexcept; + /** Returns the time-high-and-version section of the UUID. */ + uint16 getTimeHighAndVersion() const noexcept; + /** Returns the clock-seq-and-reserved section of the UUID. */ + uint8 getClockSeqAndReserved() const noexcept; + /** Returns the clock-seq-low section of the UUID. */ + uint8 getClockSeqLow() const noexcept; + /** Returns the node section of the UUID. */ + uint64 getNode() const noexcept; + //============================================================================== /** Returns a pointer to the internal binary representation of the ID. @@ -106,6 +124,7 @@ private: //============================================================================== uint8 uuid[16]; String getHexRegion (int, int) const; + int compare (Uuid) const noexcept; JUCE_LEAK_DETECTOR (Uuid) }; From 2f24925f0c09a9543977c296df8b4c5b5393b85f Mon Sep 17 00:00:00 2001 From: hogliux Date: Thu, 4 May 2017 12:17:33 +0100 Subject: [PATCH 46/54] Added support for testing MIDI inside the iOS simulator --- .../native/juce_mac_CoreMidi.cpp | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp index b7a160ce8e..4abff0f094 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp @@ -66,6 +66,22 @@ namespace CoreMidiHelpers return result; } + void enableSimulatorMidiSession() + { + #if TARGET_OS_SIMULATOR + static bool hasEnabledNetworkSession = false; + + if (! hasEnabledNetworkSession) + { + MIDINetworkSession* session = [MIDINetworkSession defaultSession]; + session.enabled = YES; + session.connectionPolicy = MIDINetworkConnectionPolicy_Anyone; + + hasEnabledNetworkSession = true; + } + #endif + } + static String getEndpointName (MIDIEndpointRef endpoint, bool isExternal) { String result (getMidiObjectName (endpoint)); @@ -173,6 +189,8 @@ namespace CoreMidiHelpers // search for devices. It's safest to use the message thread for calling this. jassert (MessageManager::getInstance()->isThisTheMessageThread()); + enableSimulatorMidiSession(); + const ItemCount num = forInput ? MIDIGetNumberOfSources() : MIDIGetNumberOfDestinations(); StringArray s; @@ -218,13 +236,7 @@ namespace CoreMidiHelpers // correctly when called from the message thread! jassert (MessageManager::getInstance()->isThisTheMessageThread()); - #if TARGET_OS_SIMULATOR - // Enable MIDI for iOS simulator - MIDINetworkSession* session = [MIDINetworkSession defaultSession]; - session.enabled = YES; - session.connectionPolicy = MIDINetworkConnectionPolicy_Anyone; - #endif - + enableSimulatorMidiSession(); CoreMidiHelpers::ScopedCFString name; name.cfString = getGlobalMidiClientName().toCFString(); From ece2d8b7c05b2c0800454154944e105f6738b53b Mon Sep 17 00:00:00 2001 From: hogliux Date: Thu, 4 May 2017 12:17:47 +0100 Subject: [PATCH 47/54] Fixed a warning on iOS --- modules/juce_audio_devices/native/juce_ios_Audio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_audio_devices/native/juce_ios_Audio.h b/modules/juce_audio_devices/native/juce_ios_Audio.h index 0fb0b17c60..0bbf3af27f 100644 --- a/modules/juce_audio_devices/native/juce_ios_Audio.h +++ b/modules/juce_audio_devices/native/juce_ios_Audio.h @@ -41,7 +41,7 @@ public: //============================================================================== bool isPlaying() override { return isRunning && callback != nullptr; } bool isOpen() override { return isRunning; } - String getLastError() override { return lastError; }; + String getLastError() override { return lastError; } //============================================================================== StringArray getOutputChannelNames() override { return { "Left", "Right" }; } From fa0b0976524f0a11251d2eb20d38e915d0e0165f Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 4 May 2017 12:47:18 +0100 Subject: [PATCH 48/54] Fixed some Projucer live-build errors on Windows and added an option to set the Windows target platform --- .../projucer_CompileEngineClient.cpp | 31 +++++++++++++------ .../projucer_ProjectBuildInfo.h | 3 ++ .../Projucer/Source/Utility/jucer_PresetIDs.h | 1 + .../codecs/oggvorbis/libvorbis-1.3.2/lib/os.h | 2 +- .../native/juce_win32_SystemStats.cpp | 4 +++ 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp index 2f4aee7619..350138024a 100644 --- a/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp +++ b/extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp @@ -69,16 +69,18 @@ namespace ProjectProperties static Value getLiveSetting (Project& p, const Identifier& i) { return getLiveSettings (p).getPropertyAsValue (i, p.getUndoManagerFor (getLiveSettings (p))); } static var getLiveSettingVar (Project& p, const Identifier& i) { return getLiveSettingsConst (p) [i]; } - static Value getUserHeaderPathValue (Project& p) { return getLiveSetting (p, Ids::headerPath); } - static String getUserHeaderPathString (Project& p) { return getLiveSettingVar (p, Ids::headerPath); } - static Value getSystemHeaderPathValue (Project& p) { return getLiveSetting (p, Ids::systemHeaderPath); } - static String getSystemHeaderPathString (Project& p) { return getLiveSettingVar (p, Ids::systemHeaderPath); } - static Value getExtraDLLsValue (Project& p) { return getLiveSetting (p, Ids::extraDLLs); } - static String getExtraDLLsString (Project& p) { return getLiveSettingVar (p, Ids::extraDLLs); } - static Value getExtraCompilerFlagsValue (Project& p) { return getLiveSetting (p, Ids::extraCompilerFlags); } - static String getExtraCompilerFlagsString (Project& p) { return getLiveSettingVar (p, Ids::extraCompilerFlags); } - static Value getExtraPreprocessorDefsValue (Project& p) { return getLiveSetting (p, Ids::defines); } - static String getExtraPreprocessorDefsString (Project& p) { return getLiveSettingVar (p, Ids::defines); } + static Value getUserHeaderPathValue (Project& p) { return getLiveSetting (p, Ids::headerPath); } + static String getUserHeaderPathString (Project& p) { return getLiveSettingVar (p, Ids::headerPath); } + static Value getSystemHeaderPathValue (Project& p) { return getLiveSetting (p, Ids::systemHeaderPath); } + static String getSystemHeaderPathString (Project& p) { return getLiveSettingVar (p, Ids::systemHeaderPath); } + static Value getExtraDLLsValue (Project& p) { return getLiveSetting (p, Ids::extraDLLs); } + static String getExtraDLLsString (Project& p) { return getLiveSettingVar (p, Ids::extraDLLs); } + static Value getExtraCompilerFlagsValue (Project& p) { return getLiveSetting (p, Ids::extraCompilerFlags); } + static String getExtraCompilerFlagsString (Project& p) { return getLiveSettingVar (p, Ids::extraCompilerFlags); } + static Value getExtraPreprocessorDefsValue (Project& p) { return getLiveSetting (p, Ids::defines); } + static String getExtraPreprocessorDefsString (Project& p) { return getLiveSettingVar (p, Ids::defines); } + static Value getWindowsTargetPlatformVersionValue (Project& p) { return getLiveSetting (p, Ids::liveWindowsTargetPlatformVersion); } + static String getWindowsTargetPlatformVersionString (Project& p) { return getLiveSettingVar (p, Ids::liveWindowsTargetPlatformVersion); } static File getProjucerTempFolder() { @@ -121,6 +123,13 @@ void LiveBuildProjectSettings::getLiveSettings (Project& project, PropertyListBu props.add (new TextPropertyComponent (getExtraDLLsValue (project), "Extra dynamic libraries", 2048, true), "Extra dynamic libs that the running code may require. Use new-lines or commas to separate the items"); + + static const char* targetPlatformNames[] = { "(default)", "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0", nullptr }; + const var targetPlatforms[] = { var(), "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0" }; + + props.add (new ChoicePropertyComponent (getWindowsTargetPlatformVersionValue (project), "Windows Target Platform", + StringArray (targetPlatformNames), Array (targetPlatforms, numElementsInArray (targetPlatforms))), + "The Windows target platform to use"); } void LiveBuildProjectSettings::updateNewlyOpenedProject (Project&) { /* placeholder */ } @@ -325,6 +334,8 @@ public: build.setUtilsCppInclude (project.getAppIncludeFile().getFullPathName()); + build.setWindowsTargetPlatformVersion (ProjectProperties::getWindowsTargetPlatformVersionString (project)); + scanForProjectFiles (project, build); owner.updateAllEditors(); diff --git a/extras/Projucer/Source/LiveBuildEngine/projucer_ProjectBuildInfo.h b/extras/Projucer/Source/LiveBuildEngine/projucer_ProjectBuildInfo.h index 8ddc36510a..4c6b363ddf 100644 --- a/extras/Projucer/Source/LiveBuildEngine/projucer_ProjectBuildInfo.h +++ b/extras/Projucer/Source/LiveBuildEngine/projucer_ProjectBuildInfo.h @@ -91,5 +91,8 @@ struct ProjectBuildInfo StringArray getExtraDLLs() const { return separateJoinedStrings (tree [Ids::extraDLLs]); } void setExtraDLLs (const StringArray& s) { tree.setProperty (Ids::extraDLLs, concatenateListOfStrings (s), nullptr); } + String getWindowsTargetPlatformVersion() const { return tree [Ids::liveWindowsTargetPlatformVersion]; } + void setWindowsTargetPlatformVersion (const String& s) { tree.setProperty (Ids::liveWindowsTargetPlatformVersion, s, nullptr); } + ValueTree tree; }; diff --git a/extras/Projucer/Source/Utility/jucer_PresetIDs.h b/extras/Projucer/Source/Utility/jucer_PresetIDs.h index da0c6dde39..ea92d98b4f 100644 --- a/extras/Projucer/Source/Utility/jucer_PresetIDs.h +++ b/extras/Projucer/Source/Utility/jucer_PresetIDs.h @@ -83,6 +83,7 @@ namespace Ids DECLARE_ID (defines); DECLARE_ID (headerPath); DECLARE_ID (systemHeaderPath); + DECLARE_ID (liveWindowsTargetPlatformVersion); DECLARE_ID (libraryPath); DECLARE_ID (customXcodeFlags); DECLARE_ID (customXcassetsFolder); diff --git a/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h b/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h index 621747276f..412ca7622f 100644 --- a/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h +++ b/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h @@ -145,7 +145,7 @@ static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){ /* Optimized code path for x86_64 builds. Uses SSE2 intrinsics. This can be done safely because all x86_64 CPUs supports SSE2. */ -#if (defined(_MSC_VER) && defined(_WIN64)) || (defined(__GNUC__) && defined (__x86_64__)) +#if (! JUCE_PROJUCER_LIVE_BUILD) && ((defined(_MSC_VER) && defined(_WIN64)) || (defined(__GNUC__) && defined (__x86_64__))) # define VORBIS_FPU_CONTROL typedef ogg_int16_t vorbis_fpu_control; diff --git a/modules/juce_core/native/juce_win32_SystemStats.cpp b/modules/juce_core/native/juce_win32_SystemStats.cpp index 2361a8d4eb..80473183c3 100644 --- a/modules/juce_core/native/juce_win32_SystemStats.cpp +++ b/modules/juce_core/native/juce_win32_SystemStats.cpp @@ -54,7 +54,11 @@ static void callCPUID (int result[4], uint32 type) #else static void callCPUID (int result[4], int infoType) { + #if JUCE_PROJUCER_LIVE_BUILD + std::fill (result, result + 4, 0); + #else __cpuid (result, infoType); + #endif } #endif From ed51317ee63597484fe5382fc7763525c4f03b25 Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 4 May 2017 12:51:02 +0100 Subject: [PATCH 49/54] Fixed a few Projucer UI issues --- .../Source/Application/jucer_Application.cpp | 3 +- .../projucer_ErrorListComponent.h | 20 ++++-- .../Source/Project/jucer_HeaderComponent.h | 67 +++++-------------- .../Project/jucer_ProjectContentComponent.cpp | 14 +++- .../Utility/jucer_ProjucerLookAndFeel.cpp | 10 +-- .../Wizards/jucer_ProjectWizard_GUIApp.h | 4 +- 6 files changed, 54 insertions(+), 64 deletions(-) diff --git a/extras/Projucer/Source/Application/jucer_Application.cpp b/extras/Projucer/Source/Application/jucer_Application.cpp index f255c1e3a2..d7aecfdf35 100644 --- a/extras/Projucer/Source/Application/jucer_Application.cpp +++ b/extras/Projucer/Source/Application/jucer_Application.cpp @@ -411,9 +411,8 @@ void ProjucerApplication::createViewMenu (PopupMenu& menu) void ProjucerApplication::createBuildMenu (PopupMenu& menu) { menu.addCommandItem (commandManager, CommandIDs::toggleBuildEnabled); - menu.addCommandItem (commandManager, CommandIDs::toggleContinuousBuild); menu.addCommandItem (commandManager, CommandIDs::buildNow); - + menu.addCommandItem (commandManager, CommandIDs::toggleContinuousBuild); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::launchApp); menu.addCommandItem (commandManager, CommandIDs::killApp); diff --git a/extras/Projucer/Source/LiveBuildEngine/projucer_ErrorListComponent.h b/extras/Projucer/Source/LiveBuildEngine/projucer_ErrorListComponent.h index 3e3185386a..aed354daf7 100644 --- a/extras/Projucer/Source/LiveBuildEngine/projucer_ErrorListComponent.h +++ b/extras/Projucer/Source/LiveBuildEngine/projucer_ErrorListComponent.h @@ -253,10 +253,22 @@ private: Colour getContentColour (bool isIcon) const override { - return message.isError() ? Colours::red - : message.isWarning() ? Colours::yellow - : getOwnerView()->findColour (isIcon ? treeIconColourId - : defaultTextColourId); + if (isIcon) + { + if (isSelected()) + return getOwnerView()->findColour (defaultHighlightedTextColourId); + + if (message.isError()) + return Colours::red; + + if (message.isWarning()) + return Colours::yellow; + + return getOwnerView()->findColour (treeIconColourId); + } + + return getOwnerView()->findColour (isSelected() ? defaultHighlightedTextColourId + : defaultTextColourId); } void showPopupMenu() override diff --git a/extras/Projucer/Source/Project/jucer_HeaderComponent.h b/extras/Projucer/Source/Project/jucer_HeaderComponent.h index 9160359ee1..cda7c5dbd3 100644 --- a/extras/Projucer/Source/Project/jucer_HeaderComponent.h +++ b/extras/Projucer/Source/Project/jucer_HeaderComponent.h @@ -307,11 +307,8 @@ public: project->addChangeListener (this); updateName(); - continuousRebuildButton->setEnabled (true); - updateContinuousRebuildButtonIcon(); - if (auto* pcc = findParentComponentOfClass()) - buildNowButton->setEnabled (! pcc->isContinuousRebuildEnabled() || ! pcc->isBuildEnabled()); + updateBuildButtons (pcc->isBuildEnabled(), pcc->isContinuousRebuildEnabled()); } void updateExporters() @@ -373,6 +370,16 @@ public: userSettingsWindow = &CallOutBox::launchAsynchronously (content, userSettingsButton->getScreenBounds(), nullptr); } + void updateBuildButtons (bool isBuildEnabled, bool isContinuousRebuildEnabled) + { + buildNowButton->setEnabled (isBuildEnabled && ! isContinuousRebuildEnabled); + continuousRebuildButton->setEnabled (isBuildEnabled); + + continuousRebuildButton->icon = Icon (isContinuousRebuildEnabled ? &getIcons().continuousBuildStop : &getIcons().continuousBuildStart, + Colours::transparentBlack); + repaint(); + } + void lookAndFeelChanged() override { if (userSettingsWindow != nullptr) @@ -399,40 +406,12 @@ private: { auto* pcc = findParentComponentOfClass(); - if (b == projectSettingsButton) - { - pcc->showProjectSettings(); - } - else if (b == continuousRebuildButton) - { - if (! pcc->isBuildEnabled()) - pcc->setBuildEnabled (true); - - auto newState = ! pcc->isContinuousRebuildEnabled(); - pcc->setContinuousRebuildEnabled (newState); - - updateContinuousRebuildButtonIcon(); - buildNowButton->setEnabled (! pcc->isContinuousRebuildEnabled() || ! pcc->isBuildEnabled()); - } - else if (b == buildNowButton) - { - if (! pcc->isBuildEnabled()) - pcc->setBuildEnabled (true); - - pcc->rebuildNow(); - } - else if (b == exporterSettingsButton) - { - pcc->showExporterSettings (getSelectedExporterName()); - } - else if (b == saveAndOpenInIDEButton) - { - pcc->openInSelectedIDE (true); - } - else if (b == userSettingsButton) - { - showUserSettings(); - } + if (b == projectSettingsButton) pcc->showProjectSettings(); + else if (b == continuousRebuildButton) pcc->setContinuousRebuildEnabled (! pcc->isContinuousRebuildEnabled()); + else if (b == buildNowButton) pcc->rebuildNow(); + else if (b == exporterSettingsButton) pcc->showExporterSettings (getSelectedExporterName()); + else if (b == saveAndOpenInIDEButton) pcc->openInSelectedIDE (true); + else if (b == userSettingsButton) showUserSettings(); } void comboBoxChanged (ComboBox* c) override @@ -463,11 +442,9 @@ private: addAndMakeVisible (continuousRebuildButton = new IconButton ("Continuous Rebuild", &icons.continuousBuildStart)); continuousRebuildButton->addListener (this); - continuousRebuildButton->setEnabled (false); addAndMakeVisible (buildNowButton = new IconButton ("Build Now", &icons.buildNow)); buildNowButton->addListener (this); - buildNowButton->setEnabled (false); addAndMakeVisible (exporterSettingsButton = new IconButton ("Exporter Settings", &icons.edit)); exporterSettingsButton->addListener (this); @@ -521,15 +498,5 @@ private: } } - void updateContinuousRebuildButtonIcon() - { - if (auto* pcc = findParentComponentOfClass()) - { - continuousRebuildButton->setEnabled (pcc->isBuildEnabled()); - continuousRebuildButton->icon = Icon (pcc->isContinuousRebuildEnabled() ? &getIcons().continuousBuildStop - : &getIcons().continuousBuildStart, Colours::transparentBlack); - } - } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HeaderComponent) }; diff --git a/extras/Projucer/Source/Project/jucer_ProjectContentComponent.cpp b/extras/Projucer/Source/Project/jucer_ProjectContentComponent.cpp index a979655f5f..5d41939aab 100644 --- a/extras/Projucer/Source/Project/jucer_ProjectContentComponent.cpp +++ b/extras/Projucer/Source/Project/jucer_ProjectContentComponent.cpp @@ -1244,6 +1244,9 @@ void ProjectContentComponent::setBuildEnabled (bool b) LiveBuildProjectSettings::setBuildDisabled (*project, ! b); killChildProcess(); refreshTabsIfBuildStatusChanged(); + + if (auto* h = dynamic_cast (header.get())) + h->updateBuildButtons (b, isContinuousRebuildEnabled()); } } @@ -1382,10 +1385,17 @@ bool ProjectContentComponent::isContinuousRebuildEnabled() void ProjectContentComponent::setContinuousRebuildEnabled (bool b) { - getAppSettings().getGlobalProperties().setValue ("continuousRebuild", b); - if (childProcess != nullptr) + { childProcess->setContinuousRebuild (b); + + if (auto* h = dynamic_cast (header.get())) + h->updateBuildButtons (isBuildEnabled(), b); + + getAppSettings().getGlobalProperties().setValue ("continuousRebuild", b); + + ProjucerApplication::getCommandManager().commandStatusChanged(); + } } ReferenceCountedObjectPtr ProjectContentComponent::getChildProcess() diff --git a/extras/Projucer/Source/Utility/jucer_ProjucerLookAndFeel.cpp b/extras/Projucer/Source/Utility/jucer_ProjucerLookAndFeel.cpp index c6bc2a1485..41b9c1fa4e 100644 --- a/extras/Projucer/Source/Utility/jucer_ProjucerLookAndFeel.cpp +++ b/extras/Projucer/Source/Utility/jucer_ProjucerLookAndFeel.cpp @@ -159,10 +159,14 @@ void ProjucerLookAndFeel::drawToggleButton (Graphics& g, ToggleButton& button, b g.setOpacity (0.5f); bool isTextEmpty = button.getButtonText().isEmpty(); + bool isPropertyComponentChild = (dynamic_cast (button.getParentComponent()) != nullptr); + auto bounds = button.getLocalBounds(); + + auto sideLength = isPropertyComponentChild ? 25 : bounds.getHeight(); + auto rectBounds = isTextEmpty ? bounds - : bounds.removeFromLeft (jmin (bounds.getHeight(), bounds.getWidth() / 3)); - auto sideLength = jmin (rectBounds.getWidth(), rectBounds.getHeight()); + : bounds.removeFromLeft (jmin (sideLength, bounds.getWidth() / 3)); rectBounds = rectBounds.withSizeKeepingCentre (sideLength, sideLength).reduced (4); @@ -180,8 +184,6 @@ void ProjucerLookAndFeel::drawToggleButton (Graphics& g, ToggleButton& button, b { bounds.removeFromLeft (5); - auto isPropertyComponentChild = (button.findParentComponentOfClass() != nullptr); - const auto fontSize = jmin (15.0f, button.getHeight() * 0.75f); g.setFont (fontSize); diff --git a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h index e0ede52ab5..c39a3cdc6c 100644 --- a/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h +++ b/extras/Projucer/Source/Wizards/jucer_ProjectWizard_GUIApp.h @@ -34,8 +34,8 @@ struct GUIAppWizard : public NewProjectWizard StringArray getFileCreationOptions() override { - return { "Create a Main.cpp file", - "Create a Main.cpp file and a basic window", + return { "Create a Main.cpp file and a basic window", + "Create a Main.cpp file", "Don't create any files" }; } From ceab51f7c49c0186305910cdcb96cd6f84d801df Mon Sep 17 00:00:00 2001 From: hogliux Date: Thu, 4 May 2017 13:08:34 +0100 Subject: [PATCH 50/54] Made the Projucer's Windows target platform property chooser available to all Visual Studio exporters --- .../Project Saving/jucer_ProjectExport_MSVC.h | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h index 8b19f22bfa..ce28bd944e 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h @@ -1734,6 +1734,8 @@ public: int getVisualStudioVersion() const override { return 11; } String getSolutionComment() const override { return "# Visual Studio 2012"; } String getDefaultToolset() const override { return "v110"; } + Value getWindowsTargetPlatformVersionValue() { return getSetting (Ids::windowsTargetPlatformVersion); } + String getWindowsTargetPlatformVersion() const { return settings [Ids::windowsTargetPlatformVersion]; } static MSVCProjectExporterVC2012* createForSettings (Project& project, const ValueTree& settings) { @@ -1754,6 +1756,16 @@ public: addIPPLibraryProperty (props); } + void addWindowsTargetPlatformProperties (PropertyListBuilder& props) + { + static const char* targetPlatformNames[] = { "(default)", "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0", nullptr }; + const var targetPlatforms[] = { var(), "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0" }; + + props.add (new ChoicePropertyComponent (getWindowsTargetPlatformVersionValue(), "Windows Target Platform", + StringArray (targetPlatformNames), Array (targetPlatforms, numElementsInArray (targetPlatforms))), + "The Windows target platform version to use"); + } + private: void addPlatformToolsetToPropertyGroup (XmlElement& p) const override { @@ -1761,6 +1773,15 @@ private: e->createNewChildElement ("PlatformToolset")->addTextElement (getPlatformToolset()); } + void addWindowsTargetPlatformVersionToPropertyGroup (XmlElement& p) const override + { + const String& targetVersion = getWindowsTargetPlatformVersion(); + + if (targetVersion.isNotEmpty()) + forEachXmlChildElementWithTagName (p, e, "PropertyGroup") + e->createNewChildElement ("WindowsTargetPlatformVersion")->addTextElement (getWindowsTargetPlatformVersion()); + } + JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2012) }; @@ -1798,6 +1819,7 @@ public: addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); addIPPLibraryProperty (props); + addWindowsTargetPlatformProperties (props); } JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2013) @@ -1837,6 +1859,7 @@ public: addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); addIPPLibraryProperty (props); + addWindowsTargetPlatformProperties (props); } JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2015) @@ -1870,9 +1893,6 @@ public: Value getCppStandardValue() { return getSetting (Ids::cppLanguageStandard); } String getCppLanguageStandard() const override { return settings [Ids::cppLanguageStandard]; } - Value getWindowsTargetPlatformVersionValue() { return getSetting (Ids::windowsTargetPlatformVersion); } - String getWindowsTargetPlatformVersion() const { return settings [Ids::windowsTargetPlatformVersion]; } - void createExporterProperties (PropertyListBuilder& props) override { MSVCProjectExporterBase::createExporterProperties (props); @@ -1882,6 +1902,7 @@ public: addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); addIPPLibraryProperty (props); + addWindowsTargetPlatformProperties (props); static const char* cppStandardNames[] = { "(default)", "C++14", "Latest C++ Standard", nullptr }; @@ -1893,22 +1914,6 @@ public: props.add (new ChoicePropertyComponent (getCppStandardValue(), "C++ standard to use", StringArray (cppStandardNames), cppStandardValues), "The C++ language standard to use"); - - static const char* targetPlatformNames[] = { "(default)", "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0", nullptr }; - const var targetPlatforms[] = { var(), "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0" }; - - props.add (new ChoicePropertyComponent (getWindowsTargetPlatformVersionValue(), "VS2017 Windows Target Platform", - StringArray (targetPlatformNames), Array (targetPlatforms, numElementsInArray (targetPlatforms))), - "The Windows target platform to use"); - } - - void addWindowsTargetPlatformVersionToPropertyGroup (XmlElement& p) const override - { - const String& targetVersion = getWindowsTargetPlatformVersion(); - - if (targetVersion.isNotEmpty()) - forEachXmlChildElementWithTagName (p, e, "PropertyGroup") - e->createNewChildElement ("WindowsTargetPlatformVersion")->addTextElement (getWindowsTargetPlatformVersion()); } JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2017) From 5d491ee9c7f7001353710f1236baa0bae1d39bc3 Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 4 May 2017 15:21:36 +0100 Subject: [PATCH 51/54] Added number suffixes to duplicate midi device names on Windows --- .../native/juce_win32_Midi.cpp | 117 +++++++----------- 1 file changed, 46 insertions(+), 71 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_win32_Midi.cpp b/modules/juce_audio_devices/native/juce_win32_Midi.cpp index 21154a1fc0..b614f71387 100644 --- a/modules/juce_audio_devices/native/juce_win32_Midi.cpp +++ b/modules/juce_audio_devices/native/juce_win32_Midi.cpp @@ -61,9 +61,8 @@ class WindowsMidiService : public MidiServiceType private: struct WindowsInputWrapper : public InputWrapper { - class MidiInCollector + struct MidiInCollector { - public: MidiInCollector (WindowsMidiService& s, MidiInput* const inputDevice, MidiInputCallback& cb) @@ -155,7 +154,7 @@ private: static void CALLBACK midiInCallback (HMIDIIN, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR midiMessage, DWORD_PTR timeStamp) { - MidiInCollector* const collector = reinterpret_cast (dwInstance); + auto* collector = reinterpret_cast (dwInstance); if (collector->midiService.activeMidiCollectors.contains (collector)) { @@ -176,9 +175,8 @@ private: bool volatile isStarted = false; double startTime = 0; - class MidiHeader + struct MidiHeader { - public: MidiHeader() {} void prepare (HMIDIIN device) @@ -214,7 +212,6 @@ private: write (device); } - private: MIDIHDR hdr; char data [256]; @@ -238,9 +235,9 @@ private: double convertTimeStamp (uint32 timeStamp) { - double t = startTime + timeStamp; + auto t = startTime + timeStamp; + auto now = Time::getMillisecondCounterHiRes(); - const double now = Time::getMillisecondCounterHiRes(); if (t > now) { if (t > now + 2.0) @@ -255,31 +252,19 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInCollector) }; + //============================================================================== WindowsInputWrapper (WindowsMidiService& parentService, MidiInput* const input, const int index, MidiInputCallback* const callback) { + auto names = getDevices(); UINT deviceId = MIDI_MAPPER; - int n = 0; - const UINT num = midiInGetNumDevs(); - - for (UINT i = 0; i < num; ++i) + if (isPositiveAndBelow (index, names.size())) { - MIDIINCAPS mc = { 0 }; - - if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - { - if (index == n) - { - deviceId = i; - deviceName = String (mc.szPname, (size_t) numElementsInArray (mc.szPname)); - break; - } - - ++n; - } + deviceName = names[index]; + deviceId = index; } collector = new MidiInCollector (parentService, input, *callback); @@ -308,9 +293,10 @@ private: MIDIINCAPS mc = { 0 }; if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - s.add (String (mc.szPname, sizeof (mc.szPname))); + s.add (String (mc.szPname, (size_t) numElementsInArray (mc.szPname))); } + s.appendNumbersToDuplicates (false, false, CharPointer_UTF8 ("-"), CharPointer_UTF8 ("")); return s; } @@ -333,6 +319,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsInputWrapper) }; + //============================================================================== struct WindowsOutputWrapper : public OutputWrapper { struct MidiOutHandle @@ -341,39 +328,27 @@ private: UINT deviceId; HMIDIOUT handle; - private: JUCE_LEAK_DETECTOR (MidiOutHandle) }; - WindowsOutputWrapper (WindowsMidiService& p, const int index) - : parent (p) + WindowsOutputWrapper (WindowsMidiService& p, int index) : parent (p) { + auto names = getDevices(); UINT deviceId = MIDI_MAPPER; - const UINT num = midiOutGetNumDevs(); - int n = 0; - for (UINT i = 0; i < num; ++i) + if (isPositiveAndBelow (index, names.size())) { - MIDIOUTCAPS mc = { 0 }; + deviceName = names[index]; + deviceId = index; + } - if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - { - String name = String (mc.szPname, sizeof (mc.szPname)); - - // use the microsoft sw synth as a default - best not to allow deviceId - // to be MIDI_MAPPER, or else device sharing breaks - if (name.containsIgnoreCase ("microsoft")) - deviceId = i; - - if (index == n) - { - deviceName = name; - deviceId = i; - break; - } - - ++n; - } + if (deviceId == MIDI_MAPPER) + { + // use the microsoft sw synth as a default - best not to allow deviceId + // to be MIDI_MAPPER, or else device sharing breaks + for (int i = 0; i < names.size(); ++i) + if (names[i].containsIgnoreCase ("microsoft")) + deviceId = (UINT) i; } for (int i = parent.activeOutputHandles.size(); --i >= 0;) @@ -384,7 +359,6 @@ private: { activeHandle->refCount++; han = activeHandle; - return; } } @@ -401,17 +375,13 @@ private: han->refCount = 1; han->handle = h; parent.activeOutputHandles.add (han); - return; } - else if (res == MMSYSERR_ALLOCATED) - { + + if (res == MMSYSERR_ALLOCATED) Sleep (100); - } else - { break; - } } throw std::runtime_error ("Failed to create Windows output device wrapper"); @@ -470,9 +440,9 @@ private: } } - static StringArray getDevices() + static Array getDeviceCaps() { - StringArray s; + Array devices; const UINT num = midiOutGetNumDevs(); for (UINT i = 0; i < num; ++i) @@ -480,28 +450,33 @@ private: MIDIOUTCAPS mc = { 0 }; if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - s.add (String (mc.szPname, sizeof (mc.szPname))); + devices.add (mc); } + return devices; + } + + static StringArray getDevices() + { + StringArray s; + + for (auto& mc : getDeviceCaps()) + s.add (String (mc.szPname, (size_t) numElementsInArray (mc.szPname))); + + s.appendNumbersToDuplicates (false, false, CharPointer_UTF8 ("-"), CharPointer_UTF8 ("")); return s; } static int getDefaultDeviceIndex() { - const UINT num = midiOutGetNumDevs(); int n = 0; - for (UINT i = 0; i < num; ++i) + for (auto& mc : getDeviceCaps()) { - MIDIOUTCAPS mc = { 0 }; + if ((mc.wTechnology & MOD_MAPPER) != 0) + return n; - if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - { - if ((mc.wTechnology & MOD_MAPPER) != 0) - return n; - - ++n; - } + ++n; } return 0; From 9b7e944a548368dcd9a323db45d6fc90be74c3e0 Mon Sep 17 00:00:00 2001 From: hogliux Date: Thu, 4 May 2017 15:24:28 +0100 Subject: [PATCH 52/54] Added a popup to the Projucer informing the user about the collection of analytics data --- extras/Projucer/JuceLibraryCode/AppConfig.h | 4 +- extras/Projucer/Projucer.jucer | 4 +- .../Source/Application/jucer_Application.cpp | 59 +++++-- .../Source/Application/jucer_Application.h | 8 +- .../Source/Application/jucer_CommandIDs.h | 1 + .../Source/Application/jucer_Main.cpp | 1 + .../Licenses/jucer_LicenseController.cpp | 77 ++++++-- .../Source/Licenses/jucer_LicenseController.h | 15 +- .../Project Saving/jucer_ProjectSaver.h | 1 - .../Source/Project/jucer_HeaderComponent.h | 2 +- .../Projucer/Source/Project/jucer_Project.cpp | 16 +- ...ucer_ApplicationUsageDataWindowComponent.h | 167 ++++++++++++++++++ .../Source/Utility/jucer_FloatingToolWindow.h | 7 +- 13 files changed, 322 insertions(+), 40 deletions(-) create mode 100644 extras/Projucer/Source/Utility/jucer_ApplicationUsageDataWindowComponent.h diff --git a/extras/Projucer/JuceLibraryCode/AppConfig.h b/extras/Projucer/JuceLibraryCode/AppConfig.h index d85805a50b..3f7db84b1e 100644 --- a/extras/Projucer/JuceLibraryCode/AppConfig.h +++ b/extras/Projucer/JuceLibraryCode/AppConfig.h @@ -53,8 +53,8 @@ // BEGIN SECTION A -#define JUCE_DISPLAY_SPLASH_SCREEN 1 -#define JUCE_REPORT_APP_USAGE 1 +#define JUCE_DISPLAY_SPLASH_SCREEN 0 +#define JUCE_REPORT_APP_USAGE 0 // END SECTION A diff --git a/extras/Projucer/Projucer.jucer b/extras/Projucer/Projucer.jucer index 103cf4bac2..74ab13bfa8 100644 --- a/extras/Projucer/Projucer.jucer +++ b/extras/Projucer/Projucer.jucer @@ -2,8 +2,8 @@ + defines="" includeBinaryInAppConfig="1" splashScreenColour="Dark" + displaySplashScreen="0" reportAppUsage="0"> addLicenseStatusChangedCallback (this); + + if (isRunningCommandLine) { - isRunningCommandLine = true; const int appReturnCode = performCommandLine (commandLine); if (appReturnCode != commandLineNotPerformed) @@ -149,9 +153,8 @@ bool ProjucerApplication::initialiseLogger (const char* filePrefix) void ProjucerApplication::handleAsyncUpdate() { - licenseController = new LicenseController; - licenseController->addLicenseStatusChangedCallback (this); - licenseStateChanged (licenseController->getState()); + if (licenseController != nullptr) + licenseController->startWebviewIfNeeded(); #if JUCE_MAC PopupMenu extraAppleMenuItems; @@ -175,6 +178,9 @@ void ProjucerApplication::initialiseWindows (const String& commandLine) mainWindowList.reopenLastProjects(); mainWindowList.createWindowIfNoneAreOpen(); + + if (licenseController->getState().applicationUsageDataState == LicenseState::ApplicationUsageData::notChosenYet) + showApplicationUsageDataAgreementPopup(); } void ProjucerApplication::shutdown() @@ -255,8 +261,12 @@ void ProjucerApplication::systemRequestedQuit() //============================================================================== void ProjucerApplication::licenseStateChanged (const LicenseState& state) { + #if ! JUCER_ENABLE_GPL_MODE if (state.type != LicenseState::Type::notLoggedIn && state.type != LicenseState::Type::noLicenseChosenYet) + #else + ignoreUnused (state); + #endif { initialiseWindows (getCommandLineParameters()); } @@ -370,6 +380,7 @@ void ProjucerApplication::createFileMenu (PopupMenu& menu) #if ! JUCE_MAC menu.addCommandItem (commandManager, CommandIDs::showAboutWindow); + menu.addCommandItem (commandManager, CommandIDs::showAppUsageWindow); menu.addCommandItem (commandManager, CommandIDs::showGlobalPreferences); menu.addSeparator(); menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit); @@ -467,6 +478,7 @@ void ProjucerApplication::createToolsMenu (PopupMenu& menu) void ProjucerApplication::createExtraAppleMenuItems (PopupMenu& menu) { menu.addCommandItem (commandManager, CommandIDs::showAboutWindow); + menu.addCommandItem (commandManager, CommandIDs::showAppUsageWindow); menu.addSeparator(); menu.addCommandItem (commandManager, CommandIDs::showGlobalPreferences); } @@ -508,10 +520,11 @@ void ProjucerApplication::handleMainMenuCommand (int menuItemID) lookAndFeel.setupColours(); mainWindowList.sendLookAndFeelChange(); - if (utf8Window != nullptr) utf8Window->sendLookAndFeelChange(); - if (svgPathWindow != nullptr) svgPathWindow->sendLookAndFeelChange(); - if (globalPreferencesWindow != nullptr) globalPreferencesWindow->sendLookAndFeelChange(); - if (aboutWindow != nullptr) aboutWindow->sendLookAndFeelChange(); + if (utf8Window != nullptr) utf8Window->sendLookAndFeelChange(); + if (svgPathWindow != nullptr) svgPathWindow->sendLookAndFeelChange(); + if (globalPreferencesWindow != nullptr) globalPreferencesWindow->sendLookAndFeelChange(); + if (aboutWindow != nullptr) aboutWindow->sendLookAndFeelChange(); + if (applicationUsageDataWindow != nullptr) applicationUsageDataWindow->sendLookAndFeelChange(); } else { @@ -532,6 +545,7 @@ void ProjucerApplication::getAllCommands (Array & commands) CommandIDs::showUTF8Tool, CommandIDs::showSVGPathTool, CommandIDs::showAboutWindow, + CommandIDs::showAppUsageWindow, CommandIDs::loginLogout }; commands.addArray (ids, numElementsInArray (ids)); @@ -578,6 +592,10 @@ void ProjucerApplication::getCommandInfo (CommandID commandID, ApplicationComman result.setInfo ("About Projucer", "Shows the Projucer's 'About' page.", CommandCategories::general, 0); break; + case CommandIDs::showAppUsageWindow: + result.setInfo ("Application Usage Data", "Shows the application usage data agreement window", CommandCategories::general, 0); + break; + case CommandIDs::loginLogout: { bool isLoggedIn = false; @@ -615,6 +633,7 @@ bool ProjucerApplication::perform (const InvocationInfo& info) case CommandIDs::showSVGPathTool: showSVGPathDataToolWindow(); break; case CommandIDs::showGlobalPreferences: AppearanceSettings::showGlobalPreferences (globalPreferencesWindow); break; case CommandIDs::showAboutWindow: showAboutWindow(); break; + case CommandIDs::showAppUsageWindow: showApplicationUsageDataAgreementPopup(); break; case CommandIDs::loginLogout: doLogout(); break; default: return JUCEApplication::perform (info); } @@ -686,12 +705,28 @@ void ProjucerApplication::showAboutWindow() if (aboutWindow != nullptr) aboutWindow->toFront (true); else - new FloatingToolWindow ("", - "aboutWindowPos", - new AboutWindowComponent(), aboutWindow, false, + new FloatingToolWindow ({}, {}, new AboutWindowComponent(), + aboutWindow, false, 500, 300, 500, 300, 500, 300); } +void ProjucerApplication::showApplicationUsageDataAgreementPopup() +{ + if (applicationUsageDataWindow != nullptr) + applicationUsageDataWindow->toFront (true); + else + new FloatingToolWindow ("Application Usage Analytics", + {}, new ApplicationUsageDataWindowComponent (isPaidOrGPL()), + applicationUsageDataWindow, false, + 400, 300, 400, 300, 400, 300); +} + +void ProjucerApplication::dismissApplicationUsageDataAgreementPopup() +{ + if (applicationUsageDataWindow != nullptr) + applicationUsageDataWindow = nullptr; +} + //============================================================================== struct FileWithTime { diff --git a/extras/Projucer/Source/Application/jucer_Application.h b/extras/Projucer/Source/Application/jucer_Application.h index 1aea62e0d1..c019958448 100644 --- a/extras/Projucer/Source/Application/jucer_Application.h +++ b/extras/Projucer/Source/Application/jucer_Application.h @@ -99,8 +99,8 @@ public: void showSVGPathDataToolWindow(); void showAboutWindow(); - - void showLoginWindow(); + void showApplicationUsageDataAgreementPopup(); + void dismissApplicationUsageDataAgreementPopup(); void updateAllBuildTabs(); LatestVersionChecker* createVersionChecker() const; @@ -124,7 +124,9 @@ public: OpenDocumentManager openDocumentManager; ScopedPointer commandManager; - ScopedPointer appearanceEditorWindow, globalPreferencesWindow, utf8Window, svgPathWindow, aboutWindow; + ScopedPointer appearanceEditorWindow, globalPreferencesWindow, utf8Window, + svgPathWindow, aboutWindow, applicationUsageDataWindow; + ScopedPointer logger; bool isRunningCommandLine; diff --git a/extras/Projucer/Source/Application/jucer_CommandIDs.h b/extras/Projucer/Source/Application/jucer_CommandIDs.h index 850bb41412..3046977511 100644 --- a/extras/Projucer/Source/Application/jucer_CommandIDs.h +++ b/extras/Projucer/Source/Application/jucer_CommandIDs.h @@ -49,6 +49,7 @@ namespace CommandIDs showTranslationTool = 0x300022, showSVGPathTool = 0x300023, showAboutWindow = 0x300024, + showAppUsageWindow = 0x300025, showProjectSettings = 0x300030, showProjectTab = 0x300031, diff --git a/extras/Projucer/Source/Application/jucer_Main.cpp b/extras/Projucer/Source/Application/jucer_Main.cpp index 094564b1a0..1f68447cd2 100644 --- a/extras/Projucer/Source/Application/jucer_Main.cpp +++ b/extras/Projucer/Source/Application/jucer_Main.cpp @@ -34,6 +34,7 @@ #include "../Utility/jucer_UTF8Component.h" #include "../Utility/jucer_SVGPathDataComponent.h" #include "../Utility/jucer_AboutWindowComponent.h" +#include "../Utility/jucer_ApplicationUsageDataWindowComponent.h" #include "../Utility/jucer_FloatingToolWindow.h" #include "../LiveBuildEngine/projucer_MessageIDs.h" diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp b/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp index c2e6085074..178facf086 100644 --- a/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp +++ b/extras/Projucer/Source/Licenses/jucer_LicenseController.cpp @@ -71,6 +71,23 @@ static LicenseState::Type getLicenseTypeFromValue (const String& d) return LicenseState::Type::noLicenseChosenYet; } +static const char* getApplicationUsageDataStateValue (LicenseState::ApplicationUsageData type) +{ + switch (type) + { + case LicenseState::ApplicationUsageData::enabled: return "enabled"; + case LicenseState::ApplicationUsageData::disabled: return "disabled"; + default: return "notChosen"; + } +} + +static LicenseState::ApplicationUsageData getApplicationUsageDataTypeFromValue (const String& value) +{ + if (value == getApplicationUsageDataStateValue (LicenseState::ApplicationUsageData::enabled)) return LicenseState::ApplicationUsageData::enabled; + if (value == getApplicationUsageDataStateValue (LicenseState::ApplicationUsageData::disabled)) return LicenseState::ApplicationUsageData::disabled; + return LicenseState::ApplicationUsageData::notChosenYet; +} + //============================================================================== struct LicenseController::ModalCompletionCallback : ModalComponentManager::Callback { @@ -83,15 +100,11 @@ struct LicenseController::ModalCompletionCallback : ModalComponentManager::Callb //============================================================================== LicenseController::LicenseController() - #if (! JUCER_ENABLE_GPL_MODE) : state (licenseStateFromSettings (ProjucerApplication::getApp().settings->getGlobalProperties())) - #endif { #if JUCER_ENABLE_GPL_MODE state.type = LicenseState::Type::GPL; state.username = "GPL mode"; - #else - thread = new LicenseThread (*this, false); #endif } @@ -101,6 +114,37 @@ LicenseController::~LicenseController() closeWebview (-1); } +LicenseState LicenseController::getState() const noexcept +{ + LicenseState projucerState = state; + + // if the user has never logged in before and the user is running from command line + // then we have no way to ask the user to log in, so fallback to GPL mode + if (guiNotInitialisedYet + && (state.type == LicenseState::Type::notLoggedIn + || state.type == LicenseState::Type::noLicenseChosenYet)) + { + projucerState.type = LicenseState::Type::GPL; + projucerState.username = "GPL mode"; + } + + return projucerState; +} + +void LicenseController::startWebviewIfNeeded() +{ + if (guiNotInitialisedYet) + { + guiNotInitialisedYet = false; + listeners.call (&StateChangedCallback::licenseStateChanged, getState()); + } + + #if ! JUCER_ENABLE_GPL_MODE + if (thread == nullptr) + thread = new LicenseThread (*this, false); + #endif +} + void LicenseController::logout() { jassert (MessageManager::getInstance()->isThisTheMessageThread()); @@ -127,6 +171,15 @@ void LicenseController::chooseNewLicense() #endif } +void LicenseController::setApplicationUsageDataState (LicenseState::ApplicationUsageData newState) +{ + if (state.applicationUsageDataState != newState) + { + state.applicationUsageDataState = newState; + updateState (state); + } +} + //============================================================================== void LicenseController::closeWebview (int result) { @@ -198,7 +251,7 @@ void LicenseController::updateState (const LicenseState& newState) state = newState; licenseStateToSettings (state, props); - listeners.call (&StateChangedCallback::licenseStateChanged, state); + listeners.call (&StateChangedCallback::licenseStateChanged, getState()); } LicenseState LicenseController::licenseStateFromSettings (PropertiesFile& props) @@ -208,10 +261,11 @@ LicenseState LicenseController::licenseStateFromSettings (PropertiesFile& props) if (licenseXml != nullptr) { LicenseState result; - result.type = getLicenseTypeFromValue (licenseXml->getChildElementAllSubText ("type", {})); - result.username = licenseXml->getChildElementAllSubText ("username", {}); - result.email = licenseXml->getChildElementAllSubText ("email", {}); - result.authToken = licenseXml->getChildElementAllSubText ("authToken", {}); + result.type = getLicenseTypeFromValue (licenseXml->getChildElementAllSubText ("type", {})); + result.applicationUsageDataState = getApplicationUsageDataTypeFromValue (licenseXml->getChildElementAllSubText ("applicationUsageData", {})); + result.username = licenseXml->getChildElementAllSubText ("username", {}); + result.email = licenseXml->getChildElementAllSubText ("email", {}); + result.authToken = licenseXml->getChildElementAllSubText ("authToken", {}); MemoryOutputStream imageData; Base64::convertFromBase64 (imageData, licenseXml->getChildElementAllSubText ("avatar", {})); @@ -227,14 +281,15 @@ void LicenseController::licenseStateToSettings (const LicenseState& state, Prope { props.removeValue ("license"); - if (state.type != LicenseState::Type::notLoggedIn - && state.username.isNotEmpty() && state.authToken.isNotEmpty()) + if (state.type != LicenseState::Type::notLoggedIn && state.username.isNotEmpty()) { XmlElement licenseXml ("license"); if (auto* typeString = getLicenseStateValue (state.type)) licenseXml.createNewChildElement ("type")->addTextElement (typeString); + licenseXml.createNewChildElement ("applicationUsageData")->addTextElement (getApplicationUsageDataStateValue (state.applicationUsageDataState)); + licenseXml.createNewChildElement ("username")->addTextElement (state.username); licenseXml.createNewChildElement ("email") ->addTextElement (state.email); diff --git a/extras/Projucer/Source/Licenses/jucer_LicenseController.h b/extras/Projucer/Source/Licenses/jucer_LicenseController.h index ffa654c4a4..c5a03cd6dc 100644 --- a/extras/Projucer/Source/Licenses/jucer_LicenseController.h +++ b/extras/Projucer/Source/Licenses/jucer_LicenseController.h @@ -44,7 +44,16 @@ struct LicenseState pro }; + enum class ApplicationUsageData + { + notChosenYet, + + enabled, + disabled + }; + Type type = Type::notLoggedIn; + ApplicationUsageData applicationUsageDataState = ApplicationUsageData::notChosenYet; String username; String email; String authToken; @@ -71,10 +80,13 @@ public: LicenseController(); ~LicenseController(); + void startWebviewIfNeeded(); + //============================================================================== - const LicenseState& getState() const noexcept { return state; } + LicenseState getState() const noexcept; void logout(); void chooseNewLicense(); + void setApplicationUsageDataState (LicenseState::ApplicationUsageData newState); //============================================================================== void addLicenseStatusChangedCallback (StateChangedCallback* callback) { listeners.add (callback); } @@ -103,6 +115,7 @@ private: ScopedPointer thread; LicenseWebview* licenseWebview = nullptr; ListenerList listeners; + bool guiNotInitialisedYet = true; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LicenseController) }; diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectSaver.h b/extras/Projucer/Source/Project Saving/jucer_ProjectSaver.h index 06997a5e13..44781d44e7 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectSaver.h +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectSaver.h @@ -374,7 +374,6 @@ private: << "// [END_USER_CODE_SECTION]" << newLine; out << newLine - << "//==============================================================================" << newLine << "/*" << newLine << " ==============================================================================" << newLine << newLine diff --git a/extras/Projucer/Source/Project/jucer_HeaderComponent.h b/extras/Projucer/Source/Project/jucer_HeaderComponent.h index cda7c5dbd3..833d1ba1f8 100644 --- a/extras/Projucer/Source/Project/jucer_HeaderComponent.h +++ b/extras/Projucer/Source/Project/jucer_HeaderComponent.h @@ -491,7 +491,7 @@ private: { if (LicenseController* controller = ProjucerApplication::getApp().licenseController) { - auto& state = controller->getState(); + auto state = controller->getState(); userSettingsButton->iconImage = state.avatar; userSettingsButton->repaint(); diff --git a/extras/Projucer/Source/Project/jucer_Project.cpp b/extras/Projucer/Source/Project/jucer_Project.cpp index 995a1029a4..4012db1c8e 100644 --- a/extras/Projucer/Source/Project/jucer_Project.cpp +++ b/extras/Projucer/Source/Project/jucer_Project.cpp @@ -113,13 +113,19 @@ void Project::setMissingDefaultValues() setTitle ("JUCE Project"); { - auto defaultSplashScreenAndReporting = ! ProjucerApplication::getApp().isPaidOrGPL(); + auto defaultSplashScreen = ! ProjucerApplication::getApp().isPaidOrGPL(); - if (shouldDisplaySplashScreen() == var() || defaultSplashScreenAndReporting) - shouldDisplaySplashScreen() = defaultSplashScreenAndReporting; + if (shouldDisplaySplashScreen() == var() || defaultSplashScreen) + shouldDisplaySplashScreen() = defaultSplashScreen; - if (shouldReportAppUsage() == var() || defaultSplashScreenAndReporting) - shouldReportAppUsage() = defaultSplashScreenAndReporting; + if (ProjucerApplication::getApp().isPaidOrGPL()) + { + if (shouldReportAppUsage() == var()) + shouldReportAppUsage() = ProjucerApplication::getApp().licenseController->getState().applicationUsageDataState + == LicenseState::ApplicationUsageData::enabled; + } + else + shouldReportAppUsage() = true; } if (splashScreenColour() == var()) diff --git a/extras/Projucer/Source/Utility/jucer_ApplicationUsageDataWindowComponent.h b/extras/Projucer/Source/Utility/jucer_ApplicationUsageDataWindowComponent.h new file mode 100644 index 0000000000..05b94bc263 --- /dev/null +++ b/extras/Projucer/Source/Utility/jucer_ApplicationUsageDataWindowComponent.h @@ -0,0 +1,167 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2017 - ROLI Ltd. + + JUCE is an open source library subject to commercial or open-source + licensing. + + By using JUCE, you agree to the terms of both the JUCE 5 End-User License + Agreement and JUCE 5 Privacy Policy (both updated and effective as of the + 27th April 2017). + + End User License Agreement: www.juce.com/juce-5-licence + Privacy Policy: www.juce.com/juce-5-privacy-policy + + Or: You may also use this code under the terms of the GPL v3 (see + www.gnu.org/licenses). + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#pragma once + +class ApplicationUsageDataWindowComponent : public Component, + private Button::Listener +{ +public: + ApplicationUsageDataWindowComponent (bool showCheckbox) + { + addAndMakeVisible (headerLabel); + headerLabel.setText ("Application Usage Analytics", dontSendNotification); + headerLabel.setFont (Font (20.0f, Font::FontStyleFlags::bold)); + headerLabel.setJustificationType (Justification::centred); + + auto textToShow = String ("We use analytics services to understand how developers use our software in order for JUCE to improve its software and services. "); + + if (! showCheckbox) + textToShow += String (" Analytics can be disabled with an Indie or Pro license. "); + + textToShow += String ("For more information, please read the JUCE EULA and Privacy policy:"); + + addAndMakeVisible (bodyLabel); + bodyLabel.setText (textToShow, dontSendNotification); + bodyLabel.setFont (Font (14.0f)); + bodyLabel.setJustificationType (Justification::centredLeft); + + addAndMakeVisible (juceEULALink); + juceEULALink.setButtonText ("JUCE EULA"); + juceEULALink.setFont (Font (14.0f), false); + juceEULALink.setURL (URL ("https://juce.com/juce-5-license")); + + addAndMakeVisible (privacyPolicyLink); + privacyPolicyLink.setButtonText ("Privacy Policy"); + privacyPolicyLink.setFont (Font (14.0f), false); + privacyPolicyLink.setURL (URL ("https://juce.com/privacy-policy")); + + addAndMakeVisible (okButton); + okButton.setButtonText ("OK"); + okButton.addListener (this); + + if (showCheckbox) + { + addAndMakeVisible (shareApplicationUsageDataToggle = new ToggleButton()); + shareApplicationUsageDataToggle->setToggleState (true, dontSendNotification); + + addAndMakeVisible(shareApplicationUsageDataLabel = new Label ({}, "Help JUCE to improve its software and services by sharing my application usage data")); + shareApplicationUsageDataLabel->setFont (Font (14.0f)); + shareApplicationUsageDataLabel->setMinimumHorizontalScale (1.0f); + } + else + { + addAndMakeVisible (upgradeLicenseButton = new TextButton ("Upgrade License")); + upgradeLicenseButton->addListener (this); + upgradeLicenseButton->setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); + } + } + + ~ApplicationUsageDataWindowComponent() + { + if (LicenseController* controller = ProjucerApplication::getApp().licenseController) + { + auto newApplicationUsageDataState = LicenseState::ApplicationUsageData::enabled; + + if (shareApplicationUsageDataToggle != nullptr && ! shareApplicationUsageDataToggle->getToggleState()) + newApplicationUsageDataState = LicenseState::ApplicationUsageData::disabled; + + controller->setApplicationUsageDataState (newApplicationUsageDataState); + } + } + + void resized() override + { + auto bounds = getLocalBounds().reduced (20); + headerLabel.setBounds (bounds.removeFromTop (40)); + bodyLabel.setBounds (bounds.removeFromTop (75)); + + bounds.removeFromTop (10); + + auto linkBounds = bounds.removeFromTop (20); + juceEULALink.setBounds (linkBounds.removeFromLeft (linkBounds.getWidth() / 2).reduced (2)); + privacyPolicyLink.setBounds (linkBounds.reduced (2)); + + if (shareApplicationUsageDataToggle != nullptr) + { + bounds.removeFromTop (10); + + auto toggleBounds = bounds.removeFromTop (40); + shareApplicationUsageDataToggle->setBounds (toggleBounds.removeFromLeft (40).reduced (5)); + shareApplicationUsageDataLabel->setBounds (toggleBounds); + } + + bounds.removeFromTop (10); + + auto buttonW = 125; + auto buttonH = 40; + + if (upgradeLicenseButton != nullptr) + { + auto left = bounds.removeFromLeft (bounds.getWidth() / 2); + + upgradeLicenseButton->setSize (buttonW, buttonH); + upgradeLicenseButton->setCentrePosition (left.getCentreX(), left.getCentreY()); + } + + okButton.setSize (buttonW, buttonH); + okButton.setCentrePosition (bounds.getCentreX(), bounds.getCentreY()); + } + + void paint (Graphics& g) override + { + g.fillAll (findColour (backgroundColourId)); + } + +private: + Label headerLabel, bodyLabel; + HyperlinkButton juceEULALink, privacyPolicyLink; + ScopedPointer