diff --git a/Makefile b/Makefile index 894e0d68c..610e6ef5f 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,7 @@ ALL_LIBS += $(MODULEDIR)/native-plugins.a ALL_LIBS += $(MODULEDIR)/juce_audio_basics.a ALL_LIBS += $(MODULEDIR)/juce_audio_formats.a ALL_LIBS += $(MODULEDIR)/juce_core.a +ALL_LIBS += $(MODULEDIR)/juce_events.a ALL_LIBS += $(MODULEDIR)/lilv.a ALL_LIBS += $(MODULEDIR)/rtmempool.a @@ -73,7 +74,6 @@ ifeq ($(MACOS_OR_WIN32),true) ALL_LIBS += $(MODULEDIR)/juce_audio_devices.a ALL_LIBS += $(MODULEDIR)/juce_audio_processors.a ALL_LIBS += $(MODULEDIR)/juce_data_structures.a -ALL_LIBS += $(MODULEDIR)/juce_events.a ALL_LIBS += $(MODULEDIR)/juce_graphics.a ALL_LIBS += $(MODULEDIR)/juce_gui_basics.a ifeq ($(MACOS),true) diff --git a/data/copy-juce-carla b/data/copy-juce-carla index 4a1517543..a4d3152c3 100755 --- a/data/copy-juce-carla +++ b/data/copy-juce-carla @@ -3,12 +3,13 @@ set -e JUCE_MODULES_DIR="/Shared/Personal/FOSS/GIT/DISTRHO/DISTRHO-Ports/libs/juce/source/modules/" -CARLA_MODULES_DIR="/home/falktx/FOSS/GIT-mine/falkTX/Carla/source/modules/" +CARLA_MODULES_DIR="/Shared/Personal/FOSS/GIT/falkTX/Carla/source/modules/" MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics juce_gui_extra") for M in $MODULES; do echo $M; + #rm -rf $CARLA_MODULES_DIR/$M/* cp -r -v $JUCE_MODULES_DIR/$M/* $CARLA_MODULES_DIR/$M/ done diff --git a/source/backend/CarlaStandalone.cpp b/source/backend/CarlaStandalone.cpp index ab8e89351..5a1822eaa 100644 --- a/source/backend/CarlaStandalone.cpp +++ b/source/backend/CarlaStandalone.cpp @@ -37,9 +37,7 @@ #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) # include "juce_gui_basics/juce_gui_basics.h" #else -namespace juce { -# include "juce_events/messages/juce_Initialisation.h" -} // namespace juce +# include "juce_events/juce_events.h" #endif namespace CB = CarlaBackend; @@ -315,6 +313,8 @@ bool carla_engine_init(const char* driverName, const char* clientName) #else gStandalone.engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, static_cast(gStandalone.engineOptions.processMode), nullptr); gStandalone.engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, static_cast(gStandalone.engineOptions.transportMode), gStandalone.engineOptions.transportExtra); + + juce::initialiseJuce_GUI(); #endif carla_engine_init_common(); @@ -322,7 +322,6 @@ bool carla_engine_init(const char* driverName, const char* clientName) if (gStandalone.engine->init(clientName)) { #ifndef BUILD_BRIDGE - juce::initialiseJuce_GUI(); if (gStandalone.logThreadEnabled && std::getenv("CARLA_LOGS_DISABLED") == nullptr) gStandalone.logThread.init(); #endif @@ -334,6 +333,9 @@ bool carla_engine_init(const char* driverName, const char* clientName) gStandalone.lastError = gStandalone.engine->getLastError(); delete gStandalone.engine; gStandalone.engine = nullptr; +#ifndef BUILD_BRIDGE + juce::shutdownJuce_GUI(); +#endif return false; } } @@ -411,14 +413,14 @@ bool carla_engine_close() if (! closed) gStandalone.lastError = gStandalone.engine->getLastError(); + delete gStandalone.engine; + gStandalone.engine = nullptr; + #ifndef BUILD_BRIDGE juce::shutdownJuce_GUI(); gStandalone.logThread.stop(); #endif - delete gStandalone.engine; - gStandalone.engine = nullptr; - return closed; } @@ -1954,6 +1956,6 @@ const char* carla_get_host_osc_url_udp() #include "CarlaPatchbayUtils.cpp" #include "CarlaPipeUtils.cpp" #include "CarlaStateUtils.cpp" -#include "CarlaJuceEvents.cpp" +#include "CarlaJuceAudioProcessors.cpp" // ------------------------------------------------------------------------------------------------------------------- diff --git a/source/backend/Makefile b/source/backend/Makefile index 744b12615..112ab4568 100644 --- a/source/backend/Makefile +++ b/source/backend/Makefile @@ -29,6 +29,7 @@ STANDALONE_LIBS += $(MODULEDIR)/jackbridge.a STANDALONE_LIBS += $(MODULEDIR)/juce_audio_basics.a STANDALONE_LIBS += $(MODULEDIR)/juce_audio_formats.a STANDALONE_LIBS += $(MODULEDIR)/juce_core.a +STANDALONE_LIBS += $(MODULEDIR)/juce_events.a STANDALONE_LIBS += $(MODULEDIR)/lilv.a STANDALONE_LIBS += $(MODULEDIR)/native-plugins.a STANDALONE_LIBS += $(MODULEDIR)/rtmempool.a @@ -45,7 +46,6 @@ ifeq ($(MACOS_OR_WIN32),true) STANDALONE_LIBS += $(MODULEDIR)/juce_audio_devices.a STANDALONE_LIBS += $(MODULEDIR)/juce_audio_processors.a STANDALONE_LIBS += $(MODULEDIR)/juce_data_structures.a -STANDALONE_LIBS += $(MODULEDIR)/juce_events.a STANDALONE_LIBS += $(MODULEDIR)/juce_graphics.a STANDALONE_LIBS += $(MODULEDIR)/juce_gui_basics.a ifeq ($(MACOS),true) @@ -59,12 +59,12 @@ endif UTILS_LIBS = $(MODULEDIR)/juce_audio_basics.a UTILS_LIBS += $(MODULEDIR)/juce_audio_formats.a UTILS_LIBS += $(MODULEDIR)/juce_core.a +UTILS_LIBS += $(MODULEDIR)/juce_events.a UTILS_LIBS += $(MODULEDIR)/lilv.a ifeq ($(MACOS),true) UTILS_LIBS += $(MODULEDIR)/juce_audio_processors.a UTILS_LIBS += $(MODULEDIR)/juce_data_structures.a -UTILS_LIBS += $(MODULEDIR)/juce_events.a UTILS_LIBS += $(MODULEDIR)/juce_graphics.a UTILS_LIBS += $(MODULEDIR)/juce_gui_basics.a UTILS_LIBS += $(MODULEDIR)/juce_gui_extra.a diff --git a/source/backend/engine/CarlaEngineGraph.cpp b/source/backend/engine/CarlaEngineGraph.cpp index 2288824ae..ee9117b2e 100644 --- a/source/backend/engine/CarlaEngineGraph.cpp +++ b/source/backend/engine/CarlaEngineGraph.cpp @@ -1340,7 +1340,7 @@ public: int getNumPrograms() override { return 0; } int getCurrentProgram() override { return 0; } -#ifndef JUCE_AUDIO_PROCESSOR_NO_GUI +#if ! JUCE_AUDIOPROCESSOR_NO_GUI bool hasEditor() const override { return false; } AudioProcessorEditor* createEditor() override { return nullptr; } #endif diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index 2c9777b64..9f7a7607e 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -39,22 +39,18 @@ #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) # include "juce_gui_basics/juce_gui_basics.h" #else -namespace juce { -# include "juce_events/messages/juce_Initialisation.h" -} // namespace juce +# include "juce_events/juce_events.h" #endif using juce::File; using juce::FloatVectorOperations; using juce::MemoryOutputStream; +using juce::ScopedJuceInitialiser_GUI; using juce::ScopedPointer; using juce::String; using juce::XmlDocument; using juce::XmlElement; -static bool gNeedsJuceHandling = false; -static int gJuceReferenceCounter = 0; - CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- @@ -603,11 +599,6 @@ public: { carla_debug("CarlaEngineNative::CarlaEngineNative()"); - CARLA_SAFE_ASSERT_INT(gJuceReferenceCounter >= 0, gJuceReferenceCounter); - - if (gNeedsJuceHandling && ++gJuceReferenceCounter == 1) - juce::initialiseJuce_GUI(); - carla_zeroChars(fTmpBuf, STR_MAX+1); pData->bufferSize = pHost->get_buffer_size(pHost->handle); @@ -666,9 +657,6 @@ public: pData->graph.destroy(); - if (gNeedsJuceHandling && --gJuceReferenceCounter == 0) - juce::shutdownJuce_GUI(); - carla_debug("CarlaEngineNative::~CarlaEngineNative() - END"); } @@ -1846,6 +1834,8 @@ private: bool fWaitForReadyMsg; char fTmpBuf[STR_MAX+1]; + const ScopedJuceInitialiser_GUI juceGuiInit; + CarlaPlugin* _getFirstPlugin() const noexcept { if (pData->curPluginCount == 0 || pData->plugins == nullptr) @@ -2097,9 +2087,6 @@ CARLA_EXPORT const NativePluginDescriptor* carla_get_native_rack_plugin(); const NativePluginDescriptor* carla_get_native_rack_plugin() { - // if this is called then we're running as special plugin - gNeedsJuceHandling = true; - CARLA_BACKEND_USE_NAMESPACE; return &carlaRackDesc; } @@ -2108,9 +2095,6 @@ CARLA_EXPORT const NativePluginDescriptor* carla_get_native_patchbay_plugin(); const NativePluginDescriptor* carla_get_native_patchbay_plugin() { - // if this is called then we're running as special plugin - gNeedsJuceHandling = true; - CARLA_BACKEND_USE_NAMESPACE; return &carlaPatchbayDesc; } @@ -2146,7 +2130,7 @@ CARLA_BACKEND_END_NAMESPACE #include "CarlaPatchbayUtils.cpp" #include "CarlaPipeUtils.cpp" #include "CarlaStateUtils.cpp" -#include "CarlaJuceEvents.cpp" +#include "CarlaJuceAudioProcessors.cpp" #endif diff --git a/source/modules/AppConfig.h b/source/modules/AppConfig.h index 27e04c75d..d8fe6a41c 100644 --- a/source/modules/AppConfig.h +++ b/source/modules/AppConfig.h @@ -66,8 +66,8 @@ #define JUCE_USE_VFORK 1 #if ! (defined(APPCONFIG_OS_MAC) || defined(APPCONFIG_OS_WIN)) -# define JUCE_MODAL_LOOPS_PERMITTED 0 -# define JUCE_AUDIO_PROCESSOR_NO_GUI 1 +# define JUCE_MODAL_LOOPS_PERMITTED 0 +# define JUCE_AUDIOPROCESSOR_NO_GUI 1 #endif // -------------------------------------------------------------------------------------------------------------------- diff --git a/source/modules/Makefile.mk b/source/modules/Makefile.mk index 62d5245cf..9813ca337 100644 --- a/source/modules/Makefile.mk +++ b/source/modules/Makefile.mk @@ -29,5 +29,6 @@ endif BUILD_C_FLAGS += -I. -I$(CWD)/includes BUILD_CXX_FLAGS += -I. -I$(CWD)/includes -I$(CWD)/utils +BUILD_CXX_FLAGS += -DJUCE_APP_CONFIG_HEADER='' # ---------------------------------------------------------------------------------------------------------------------------- diff --git a/source/modules/juce_audio_processors/processors/juce_AudioPlayHead.h b/source/modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h similarity index 75% rename from source/modules/juce_audio_processors/processors/juce_AudioPlayHead.h rename to source/modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h index c54e7c35d..b8c3b0f52 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioPlayHead.h +++ b/source/modules/juce_audio_basics/audio_play_head/juce_AudioPlayHead.h @@ -2,28 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + The code included in this file is provided 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. - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPLAYHEAD_H_INCLUDED -#define JUCE_AUDIOPLAYHEAD_H_INCLUDED +#pragma once //============================================================================== @@ -55,6 +52,8 @@ public: fps30 = 3, fps2997drop = 4, fps30drop = 5, + fps60 = 6, + fps60drop = 7, fpsUnknown = 99 }; @@ -138,7 +137,16 @@ public: multithreading issues if it's not called on the audio thread. */ virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0; -}; + /** Returns true if this object can control the transport. */ + virtual bool canControlTransport() { return false; } -#endif // JUCE_AUDIOPLAYHEAD_H_INCLUDED + /** Starts or stops the audio. */ + virtual void transportPlay (bool shouldStartPlaying) { ignoreUnused (shouldStartPlaying); } + + /** Starts or stops recording the audio. */ + virtual void transportRecord (bool shouldStartRecording) { ignoreUnused (shouldStartRecording); } + + /** Rewinds the audio. */ + virtual void transportRewind() {} +}; diff --git a/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp b/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp index 932c43cd2..e75f90b4e 100644 --- a/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp +++ b/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp @@ -2,33 +2,30 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ AudioChannelSet::AudioChannelSet (uint32 c) : channels (c) {} +AudioChannelSet::AudioChannelSet (const Array& c) +{ + for (auto channel : c) + addChannel (channel); +} bool AudioChannelSet::operator== (const AudioChannelSet& other) const noexcept { return channels == other.channels; } bool AudioChannelSet::operator!= (const AudioChannelSet& other) const noexcept { return channels != other.channels; } @@ -37,7 +34,7 @@ bool AudioChannelSet::operator< (const AudioChannelSet& other) const noexcept String AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type) { if (type >= discreteChannel0) - return String ("Discrete ") + String (type - discreteChannel0 + 1); + return "Discrete " + String (type - discreteChannel0 + 1); switch (type) { @@ -62,8 +59,8 @@ String AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type) case wideLeft: return NEEDS_TRANS("Wide Left"); case wideRight: return NEEDS_TRANS("Wide Right"); case LFE2: return NEEDS_TRANS("LFE 2"); - case leftSurroundSide: return NEEDS_TRANS ("Left Surround Side"); - case rightSurroundSide: return NEEDS_TRANS ("Right Surround Side"); + case leftSurroundSide: return NEEDS_TRANS("Left Surround Side"); + case rightSurroundSide: return NEEDS_TRANS("Right Surround Side"); case ambisonicW: return NEEDS_TRANS("Ambisonic W"); case ambisonicX: return NEEDS_TRANS("Ambisonic X"); case ambisonicY: return NEEDS_TRANS("Ambisonic Y"); @@ -111,7 +108,7 @@ String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelT default: break; } - return ""; + return {}; } AudioChannelSet::ChannelType AudioChannelSet::getChannelTypeFromAbbreviation (const String& abbr) @@ -120,33 +117,33 @@ AudioChannelSet::ChannelType AudioChannelSet::getChannelTypeFromAbbreviation (co return static_cast (static_cast (discreteChannel0) + abbr.getIntValue() + 1); - if (abbr == "L") return left; - else if (abbr == "R") return right; - else if (abbr == "C") return centre; - else if (abbr == "Lfe") return LFE; - else if (abbr == "Ls") return leftSurround; - else if (abbr == "Rs") return rightSurround; - else if (abbr == "Lc") return leftCentre; - else if (abbr == "Rc") return rightCentre; - else if (abbr == "Cs") return centreSurround; - else if (abbr == "Lrs") return leftSurroundRear; - else if (abbr == "Rrs") return rightSurroundRear; - else if (abbr == "Tm") return topMiddle; - else if (abbr == "Tfl") return topFrontLeft; - else if (abbr == "Tfc") return topFrontCentre; - else if (abbr == "Tfr") return topFrontRight; - else if (abbr == "Trl") return topRearLeft; - else if (abbr == "Trc") return topRearCentre; - else if (abbr == "Trr") return topRearRight; - else if (abbr == "Wl") return wideLeft; - else if (abbr == "Wr") return wideRight; - else if (abbr == "Lfe2") return LFE2; - else if (abbr == "Lss") return leftSurroundSide; - else if (abbr == "Rss") return rightSurroundSide; - else if (abbr == "W") return ambisonicW; - else if (abbr == "X") return ambisonicX; - else if (abbr == "Y") return ambisonicY; - else if (abbr == "Z") return ambisonicZ; + if (abbr == "L") return left; + if (abbr == "R") return right; + if (abbr == "C") return centre; + if (abbr == "Lfe") return LFE; + if (abbr == "Ls") return leftSurround; + if (abbr == "Rs") return rightSurround; + if (abbr == "Lc") return leftCentre; + if (abbr == "Rc") return rightCentre; + if (abbr == "Cs") return centreSurround; + if (abbr == "Lrs") return leftSurroundRear; + if (abbr == "Rrs") return rightSurroundRear; + if (abbr == "Tm") return topMiddle; + if (abbr == "Tfl") return topFrontLeft; + if (abbr == "Tfc") return topFrontCentre; + if (abbr == "Tfr") return topFrontRight; + if (abbr == "Trl") return topRearLeft; + if (abbr == "Trc") return topRearCentre; + if (abbr == "Trr") return topRearRight; + if (abbr == "Wl") return wideLeft; + if (abbr == "Wr") return wideRight; + if (abbr == "Lfe2") return LFE2; + if (abbr == "Lss") return leftSurroundSide; + if (abbr == "Rss") return rightSurroundSide; + if (abbr == "W") return ambisonicW; + if (abbr == "X") return ambisonicX; + if (abbr == "Y") return ambisonicY; + if (abbr == "Z") return ambisonicZ; return unknown; } @@ -154,11 +151,10 @@ AudioChannelSet::ChannelType AudioChannelSet::getChannelTypeFromAbbreviation (co String AudioChannelSet::getSpeakerArrangementAsString() const { StringArray speakerTypes; - Array speakers = getChannelTypes(); - for (int i = 0; i < speakers.size(); ++i) + for (auto& speaker : getChannelTypes()) { - String name = getAbbreviatedChannelTypeName (speakers.getReference (i)); + auto name = getAbbreviatedChannelTypeName (speaker); if (name.isNotEmpty()) speakerTypes.add (name); @@ -169,12 +165,11 @@ String AudioChannelSet::getSpeakerArrangementAsString() const AudioChannelSet AudioChannelSet::fromAbbreviatedString (const String& str) { - StringArray abbr = StringArray::fromTokens(str, true); AudioChannelSet set; - for (int i = 0; i < abbr.size(); ++i) + for (auto& abbr : StringArray::fromTokens (str, true)) { - AudioChannelSet::ChannelType type = getChannelTypeFromAbbreviation (abbr[i]); + auto type = getChannelTypeFromAbbreviation (abbr); if (type != unknown) set.addChannel (type); @@ -185,7 +180,7 @@ AudioChannelSet AudioChannelSet::fromAbbreviatedString (const String& str) String AudioChannelSet::getDescription() const { - if (isDiscreteLayout()) return String ("Discrete #") + String (size()); + if (isDiscreteLayout()) return "Discrete #" + String (size()); if (*this == disabled()) return "Disabled"; if (*this == mono()) return "Mono"; if (*this == stereo()) return "Stereo"; @@ -194,16 +189,16 @@ String AudioChannelSet::getDescription() const if (*this == createLRS()) return "LRS"; if (*this == createLCRS()) return "LCRS"; - if (*this == create5point0()) return "5.1 Surround"; - if (*this == create5point1()) return "5.1 Surround (+Lfe)"; - if (*this == create6point0()) return "6.1 Surround"; - if (*this == create6point1()) return "6.1 Surround (+Lfe)"; - if (*this == create6point0Music()) return "6.1 (Music) Surround"; - if (*this == create6point1Music()) return "6.1 (Music) Surround (+Lfe)"; - if (*this == create7point0()) return "7.1 Surround"; - if (*this == create7point1()) return "7.1 Surround (Lfe)"; - if (*this == create7point0SDDS()) return "7.1 Surround SDDS"; - if (*this == create7point1SDDS()) return "7.1 Surround SDDS (+Lfe)"; + if (*this == create5point0()) return "5.0 Surround"; + if (*this == create5point1()) return "5.1 Surround"; + if (*this == create6point0()) return "6.0 Surround"; + if (*this == create6point1()) return "6.1 Surround"; + if (*this == create6point0Music()) return "6.0 (Music) Surround"; + if (*this == create6point1Music()) return "6.1 (Music) Surround"; + if (*this == create7point0()) return "7.0 Surround"; + if (*this == create7point1()) return "7.1 Surround"; + if (*this == create7point0SDDS()) return "7.0 Surround SDDS"; + if (*this == create7point1SDDS()) return "7.1 Surround SDDS"; if (*this == quadraphonic()) return "Quadraphonic"; if (*this == pentagonal()) return "Pentagonal"; @@ -211,19 +206,16 @@ String AudioChannelSet::getDescription() const if (*this == octagonal()) return "Octagonal"; if (*this == ambisonic()) return "Ambisonic"; - - return "Unknown"; } bool AudioChannelSet::isDiscreteLayout() const noexcept { - Array speakers = getChannelTypes(); - for (int i = 0; i < speakers.size(); ++i) - if (speakers.getReference (i) > ambisonicZ) - return true; + for (auto& speaker : getChannelTypes()) + if (speaker <= ambisonicZ) + return false; - return false; + return true; } int AudioChannelSet::size() const noexcept @@ -244,6 +236,7 @@ AudioChannelSet::ChannelType AudioChannelSet::getTypeOfChannel (int index) const int AudioChannelSet::getChannelIndexForType (AudioChannelSet::ChannelType type) const noexcept { int idx = 0; + for (int bit = channels.findNextSetBit (0); bit >= 0; bit = channels.findNextSetBit (bit + 1)) { if (static_cast (bit) == type) @@ -279,27 +272,27 @@ void AudioChannelSet::removeChannel (ChannelType newChannel) channels.clearBit (bit); } -AudioChannelSet AudioChannelSet::disabled() { return AudioChannelSet(); } +AudioChannelSet AudioChannelSet::disabled() { return {}; } AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); } AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); } AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); } AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); } AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); } AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); } -AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << LFE)); } +AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround)); } AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } -AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << LFE)); } +AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } -AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << LFE)); } +AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } -AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << LFE)); } -AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre) | (1u << LFE)); } +AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } +AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); } AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); } AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } -AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << centre) | (1u << centreSurround)); } -AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << centre) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); } +AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } +AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); } AudioChannelSet AudioChannelSet::discreteChannels (int numChannels) @@ -311,30 +304,30 @@ AudioChannelSet AudioChannelSet::discreteChannels (int numChannels) AudioChannelSet AudioChannelSet::canonicalChannelSet (int numChannels) { - if (numChannels == 1) return AudioChannelSet::mono(); - if (numChannels == 2) return AudioChannelSet::stereo(); - if (numChannels == 3) return AudioChannelSet::createLCR(); - if (numChannels == 4) return AudioChannelSet::quadraphonic(); - if (numChannels == 5) return AudioChannelSet::create5point0(); - if (numChannels == 6) return AudioChannelSet::create5point1(); - if (numChannels == 7) return AudioChannelSet::create7point0(); - if (numChannels == 8) return AudioChannelSet::create7point1(); + if (numChannels == 1) return AudioChannelSet::mono(); + if (numChannels == 2) return AudioChannelSet::stereo(); + if (numChannels == 3) return AudioChannelSet::createLCR(); + if (numChannels == 4) return AudioChannelSet::quadraphonic(); + if (numChannels == 5) return AudioChannelSet::create5point0(); + if (numChannels == 6) return AudioChannelSet::create5point1(); + if (numChannels == 7) return AudioChannelSet::create7point0(); + if (numChannels == 8) return AudioChannelSet::create7point1(); return discreteChannels (numChannels); } AudioChannelSet AudioChannelSet::namedChannelSet (int numChannels) { - if (numChannels == 1) return AudioChannelSet::mono(); - if (numChannels == 2) return AudioChannelSet::stereo(); - if (numChannels == 3) return AudioChannelSet::createLCR(); - if (numChannels == 4) return AudioChannelSet::quadraphonic(); - if (numChannels == 5) return AudioChannelSet::create5point0(); - if (numChannels == 6) return AudioChannelSet::create5point1(); - if (numChannels == 7) return AudioChannelSet::create7point0(); - if (numChannels == 8) return AudioChannelSet::create7point1(); - - return AudioChannelSet(); + if (numChannels == 1) return AudioChannelSet::mono(); + if (numChannels == 2) return AudioChannelSet::stereo(); + if (numChannels == 3) return AudioChannelSet::createLCR(); + if (numChannels == 4) return AudioChannelSet::quadraphonic(); + if (numChannels == 5) return AudioChannelSet::create5point0(); + if (numChannels == 6) return AudioChannelSet::create5point1(); + if (numChannels == 7) return AudioChannelSet::create7point0(); + if (numChannels == 8) return AudioChannelSet::create7point1(); + + return {}; } Array AudioChannelSet::channelSetsWithNumberOfChannels (int numChannels) @@ -393,3 +386,31 @@ Array AudioChannelSet::channelSetsWithNumberOfChannels (int num return retval; } + +AudioChannelSet JUCE_CALLTYPE AudioChannelSet::channelSetWithChannels (const Array& channelArray) +{ + AudioChannelSet set; + + for (auto ch : channelArray) + { + jassert (! set.channels[static_cast (ch)]); + + set.addChannel (ch); + } + + return set; +} + +//============================================================================== +AudioChannelSet JUCE_CALLTYPE AudioChannelSet::fromWaveChannelMask (int32 dwChannelMask) +{ + return AudioChannelSet (static_cast ((dwChannelMask & ((1 << 18) - 1)) << 1)); +} + +int32 AudioChannelSet::getWaveChannelMask() const noexcept +{ + if (channels.getHighestBit() > topRearRight) + return -1; + + return (channels.toInteger() >> 1); +} diff --git a/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h b/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h index 40f5209a2..14c0ff900 100644 --- a/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h +++ b/source/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOCHANNELSET_H_INCLUDED -#define JUCE_AUDIOCHANNELSET_H_INCLUDED +#pragma once //============================================================================== @@ -60,21 +51,21 @@ public: /** Creates a zero-channel set which can be used to indicate that a bus is disabled. */ - static AudioChannelSet disabled(); + static AudioChannelSet JUCE_CALLTYPE disabled(); //============================================================================== /** Creates a one-channel mono set (centre). Is equivalent to: kMonoAAX (VST), AAX_eStemFormat_Mono (AAX), kAudioChannelLayoutTag_Mono (CoreAudio) */ - static AudioChannelSet mono(); + static AudioChannelSet JUCE_CALLTYPE mono(); /** Creates a set containing a stereo set (left, right). Is equivalent to: kStereo (VST), AAX_eStemFormat_Stereo (AAX), kAudioChannelLayoutTag_Stereo (CoreAudio) */ - static AudioChannelSet stereo(); + static AudioChannelSet JUCE_CALLTYPE stereo(); //============================================================================== @@ -85,7 +76,7 @@ public: This format is referred to as "LRC" in Cubase. This format is referred to as "LCR" in Pro Tools. */ - static AudioChannelSet createLCR(); + static AudioChannelSet JUCE_CALLTYPE createLCR(); /** Creates a set containing an LRS set (left, right, surround). @@ -94,7 +85,7 @@ public: This format is referred to as "LRS" in Cubase. */ - static AudioChannelSet createLRS(); + static AudioChannelSet JUCE_CALLTYPE createLRS(); /** Creates a set containing an LCRS set (left, right, centre, surround). @@ -105,7 +96,7 @@ public: This format is referred to as "LRCS" in Cubase. This format is referred to as "LCRS" in Pro Tools. */ - static AudioChannelSet createLCRS(); + static AudioChannelSet JUCE_CALLTYPE createLCRS(); //============================================================================== @@ -116,7 +107,7 @@ public: This format is referred to as "5.0" in Cubase. This format is referred to as "5.0" in Pro Tools. */ - static AudioChannelSet create5point0(); + static AudioChannelSet JUCE_CALLTYPE create5point0(); /** Creates a set for a 5.1 surround setup (left, right, centre, leftSurround, rightSurround, LFE). @@ -127,7 +118,7 @@ public: This format is referred to as "5.1" in Cubase. This format is referred to as "5.1" in Pro Tools. */ - static AudioChannelSet create5point1(); + static AudioChannelSet JUCE_CALLTYPE create5point1(); /** Creates a set for a 6.0 Cine surround setup (left, right, centre, leftSurround, rightSurround, centreSurround). @@ -138,7 +129,7 @@ public: This format is referred to as "6.0 Cine" in Cubase. This format is referred to as "6.0" in Pro Tools. */ - static AudioChannelSet create6point0(); + static AudioChannelSet JUCE_CALLTYPE create6point0(); /** Creates a set for a 6.1 Cine surround setup (left, right, centre, leftSurround, rightSurround, centreSurround, LFE). @@ -147,7 +138,7 @@ public: This format is referred to as "6.1" in Pro Tools. */ - static AudioChannelSet create6point1(); + static AudioChannelSet JUCE_CALLTYPE create6point1(); /** Creates a set for a 6.0 Music surround setup (left, right, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide). @@ -156,14 +147,14 @@ public: This format is referred to as "6.0 Music" in Cubase. */ - static AudioChannelSet create6point0Music(); + static AudioChannelSet JUCE_CALLTYPE create6point0Music(); /** Creates a set for a 6.0 Music surround setup (left, right, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide, LFE). Is equivalent to: k61Music (VST), n/a (AAX), kAudioChannelLayoutTag_DTS_6_1_A (CoreAudio) */ - static AudioChannelSet create6point1Music(); + static AudioChannelSet JUCE_CALLTYPE create6point1Music(); /** Creates a set for a DTS 7.0 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear). @@ -172,7 +163,7 @@ public: This format is referred to as "7.0" in Pro Tools. */ - static AudioChannelSet create7point0(); + static AudioChannelSet JUCE_CALLTYPE create7point0(); /** Creates a set for a SDDS 7.0 surround setup (left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre). @@ -181,7 +172,7 @@ public: This format is referred to as "7.0 SDDS" in Pro Tools. */ - static AudioChannelSet create7point0SDDS(); + static AudioChannelSet JUCE_CALLTYPE create7point0SDDS(); /** Creates a set for a DTS 7.1 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, LFE). @@ -191,7 +182,7 @@ public: This format is referred to as "7.1 (3/4.1)" in Logic Pro. This format is referred to as "7.1" in Pro Tools. */ - static AudioChannelSet create7point1(); + static AudioChannelSet JUCE_CALLTYPE create7point1(); /** Creates a set for a 7.1 surround setup (left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre, LFE). @@ -201,7 +192,7 @@ public: This format is referred to as "7.1 (SDDS)" in Logic Pro. This format is referred to as "7.1 SDDS" in Pro Tools. */ - static AudioChannelSet create7point1SDDS(); + static AudioChannelSet JUCE_CALLTYPE create7point1SDDS(); //============================================================================== @@ -209,7 +200,7 @@ public: Is equivalent to: kBFormat (VST), n/a (AAX), kAudioChannelLayoutTag_Ambisonic_B_Format (CoreAudio) */ - static AudioChannelSet ambisonic(); + static AudioChannelSet JUCE_CALLTYPE ambisonic(); /** Creates a set for quadraphonic surround setup (left, right, leftSurround, rightSurround) @@ -220,45 +211,45 @@ public: This format is referred to as "Quadro" in Cubase. This format is referred to as "Quad" in Pro Tools. */ - static AudioChannelSet quadraphonic(); + static AudioChannelSet JUCE_CALLTYPE quadraphonic(); /** Creates a set for pentagonal surround setup (left, right, centre, leftSurroundRear, rightSurroundRear). Is equivalent to: n/a (VST), n/a (AAX), kAudioChannelLayoutTag_Pentagonal (CoreAudio) */ - static AudioChannelSet pentagonal(); + static AudioChannelSet JUCE_CALLTYPE pentagonal(); /** Creates a set for hexagonal surround setup (left, right, leftSurroundRear, rightSurroundRear, centre, surroundCentre). Is equivalent to: n/a (VST), n/a (AAX), kAudioChannelLayoutTag_Hexagonal (CoreAudio) */ - static AudioChannelSet hexagonal(); + static AudioChannelSet JUCE_CALLTYPE hexagonal(); /** Creates a set for octagonal surround setup (left, right, leftSurround, rightSurround, centre, centreSurround, wideLeft, wideRight). Is equivalent to: n/a (VST), n/a (AAX), kAudioChannelLayoutTag_Octagonal (CoreAudio) */ - static AudioChannelSet octagonal(); + static AudioChannelSet JUCE_CALLTYPE octagonal(); //============================================================================== /** Creates a set of untyped discrete channels. */ - static AudioChannelSet discreteChannels (int numChannels); + static AudioChannelSet JUCE_CALLTYPE discreteChannels (int numChannels); /** Create a canonical channel set for a given number of channels. For example, numChannels = 1 will return mono, numChannels = 2 will return stereo, etc. */ - static AudioChannelSet canonicalChannelSet (int numChannels); + static AudioChannelSet JUCE_CALLTYPE canonicalChannelSet (int numChannels); /** Create a channel set for a given number of channels which is non-discrete. If numChannels is larger than the number of channels of the surround format with the maximum amount of channels (currently 7.1 Surround), then this function returns an empty set.*/ - static AudioChannelSet namedChannelSet (int numChannels); + static AudioChannelSet JUCE_CALLTYPE namedChannelSet (int numChannels); /** Return an array of channel sets which have a given number of channels */ - static Array channelSetsWithNumberOfChannels (int numChannels); + static Array JUCE_CALLTYPE channelSetsWithNumberOfChannels (int numChannels); //============================================================================== /** Represents different audio channel types. */ @@ -303,13 +294,13 @@ public: }; /** Returns the name of a given channel type. For example, this method may return "Surround Left". */ - static String getChannelTypeName (ChannelType); + static String JUCE_CALLTYPE getChannelTypeName (ChannelType); /** Returns the abbreviated name of a channel type. For example, this method may return "Ls". */ - static String getAbbreviatedChannelTypeName (ChannelType); + static String JUCE_CALLTYPE getAbbreviatedChannelTypeName (ChannelType); /** Returns the channel type from an abbreviated name. */ - static ChannelType getChannelTypeFromAbbreviation (const String& abbreviation); + static ChannelType JUCE_CALLTYPE getChannelTypeFromAbbreviation (const String& abbreviation); //============================================================================== enum @@ -360,16 +351,40 @@ public: /** Intersect two channel layouts. */ void intersect (const AudioChannelSet& other) { channels &= other.channels; } + /** Creates a channel set for a list of channel types. This function will assert + if you supply a duplicate channel. + + Note that this method ignores the order in which the channels are given, i.e. + two arrays with the same elements but in a different order will still result + in the same channel set. + */ + static AudioChannelSet JUCE_CALLTYPE channelSetWithChannels (const Array&); + + //============================================================================== + // Conversion between wave and juce channel layout identifiers + + /** Create an AudioChannelSet from a WAVEFORMATEXTENSIBLE channelMask (typically used + in .wav files). */ + static AudioChannelSet JUCE_CALLTYPE fromWaveChannelMask (int32 dwChannelMask); + + /** Returns a WAVEFORMATEXTENSIBLE channelMask representation (typically used in .wav + files) of the receiver. + + Returns -1 if the receiver cannot be represented in a WAVEFORMATEXTENSIBLE channelMask + representation. + */ + int32 getWaveChannelMask() const noexcept; + //============================================================================== bool operator== (const AudioChannelSet&) const noexcept; bool operator!= (const AudioChannelSet&) const noexcept; bool operator< (const AudioChannelSet&) const noexcept; + private: + //============================================================================== BigInteger channels; + //============================================================================== explicit AudioChannelSet (uint32); + explicit AudioChannelSet (const Array&); }; - - - -#endif // JUCE_AUDIOCHANNELSET_H_INCLUDED diff --git a/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp b/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp index 9288ee0b3..de705a8d3 100644 --- a/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp +++ b/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -483,7 +475,7 @@ void AudioDataConverters::deinterleaveSamples (const float* const source, class AudioConversionTests : public UnitTest { public: - AudioConversionTests() : UnitTest ("Audio data conversion") {} + AudioConversionTests() : UnitTest ("Audio data conversion", "Audio") {} template struct Test5 diff --git a/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h b/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h index ad6250586..c56fe0c1e 100644 --- a/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h +++ b/source/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIODATACONVERTERS_H_INCLUDED -#define JUCE_AUDIODATACONVERTERS_H_INCLUDED +#pragma once //============================================================================== @@ -371,7 +362,7 @@ public: { // If you're using interleaved data, call the other constructor! If you're using non-interleaved data, // you should pass NonInterleaved as the template parameter for the interleaving type! - static_jassert (InterleavingType::isInterleavedType == 0); + static_assert (InterleavingType::isInterleavedType == 0, "Incorrect constructor for interleaved data"); } /** Creates a pointer from some raw data in the appropriate format with the specified number of interleaved channels. @@ -411,7 +402,8 @@ public: */ inline void setAsFloat (float newValue) noexcept { - static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! + // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! + static_assert (Constness::isConst == 0, "Attempt to write to a const pointer"); Endianness::setAsFloat (data, newValue); } @@ -428,7 +420,8 @@ public: */ inline void setAsInt32 (int32 newValue) noexcept { - static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! + // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! + static_assert (Constness::isConst == 0, "Attempt to write to a const pointer"); Endianness::setAsInt32 (data, newValue); } @@ -446,7 +439,8 @@ public: */ void convertSamples (Pointer source, int numSamples) const noexcept { - static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! + // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! + static_assert (Constness::isConst == 0, "Attempt to write to a const pointer"); for (Pointer dest (*this); --numSamples >= 0;) { @@ -462,7 +456,8 @@ public: template void convertSamples (OtherPointerType source, int numSamples) const noexcept { - static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! + // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead! + static_assert (Constness::isConst == 0, "Attempt to write to a const pointer"); Pointer dest (*this); @@ -713,6 +708,3 @@ private: AudioDataConverters(); JUCE_DECLARE_NON_COPYABLE (AudioDataConverters) }; - - -#endif // JUCE_AUDIODATACONVERTERS_H_INCLUDED diff --git a/source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp b/source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp deleted file mode 100644 index e9fd6e002..000000000 --- a/source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.cpp +++ /dev/null @@ -1,673 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioSampleBuffer::AudioSampleBuffer() noexcept - : numChannels (0), size (0), allocatedBytes (0), - channels (static_cast (preallocatedChannelSpace)), - isClear (false) -{ -} - -AudioSampleBuffer::AudioSampleBuffer (const int numChans, - const int numSamples) noexcept - : numChannels (numChans), - size (numSamples) -{ - jassert (numSamples >= 0); - jassert (numChans >= 0); - - allocateData(); -} - -AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) noexcept - : numChannels (other.numChannels), - size (other.size), - allocatedBytes (other.allocatedBytes) -{ - if (allocatedBytes == 0) - { - allocateChannels (other.channels, 0); - } - else - { - allocateData(); - - if (other.isClear) - { - clear(); - } - else - { - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::copy (channels[i], other.channels[i], size); - } - } -} - -void AudioSampleBuffer::allocateData() -{ - const size_t channelListSize = sizeof (float*) * (size_t) (numChannels + 1); - allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (float) + channelListSize + 32; - allocatedData.malloc (allocatedBytes); - channels = reinterpret_cast (allocatedData.getData()); - - float* chan = (float*) (allocatedData + channelListSize); - for (int i = 0; i < numChannels; ++i) - { - channels[i] = chan; - chan += size; - } - - channels [numChannels] = nullptr; - isClear = false; -} - -AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo, - const int numChans, - const int numSamples) noexcept - : numChannels (numChans), - size (numSamples), - allocatedBytes (0) -{ - jassert (dataToReferTo != nullptr); - jassert (numChans >= 0 && numSamples >= 0); - allocateChannels (dataToReferTo, 0); -} - -AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo, - const int numChans, - const int startSample, - const int numSamples) noexcept - : numChannels (numChans), - size (numSamples), - allocatedBytes (0), - isClear (false) -{ - jassert (dataToReferTo != nullptr); - jassert (numChans >= 0 && startSample >= 0 && numSamples >= 0); - allocateChannels (dataToReferTo, startSample); -} - -void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo, - const int newNumChannels, - const int newNumSamples) noexcept -{ - jassert (dataToReferTo != nullptr); - jassert (newNumChannels >= 0 && newNumSamples >= 0); - - if (allocatedBytes != 0) - { - allocatedBytes = 0; - allocatedData.free(); - } - - numChannels = newNumChannels; - size = newNumSamples; - - allocateChannels (dataToReferTo, 0); - jassert (! isClear); -} - -void AudioSampleBuffer::allocateChannels (float* const* const dataToReferTo, int offset) -{ - jassert (offset >= 0); - - // (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools) - if (numChannels < (int) numElementsInArray (preallocatedChannelSpace)) - { - channels = static_cast (preallocatedChannelSpace); - } - else - { - allocatedData.malloc ((size_t) numChannels + 1, sizeof (float*)); - channels = reinterpret_cast (allocatedData.getData()); - } - - for (int i = 0; i < numChannels; ++i) - { - // you have to pass in the same number of valid pointers as numChannels - jassert (dataToReferTo[i] != nullptr); - - channels[i] = dataToReferTo[i] + offset; - } - - channels [numChannels] = nullptr; - isClear = false; -} - -AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other) noexcept -{ - if (this != &other) - { - setSize (other.getNumChannels(), other.getNumSamples(), false, false, false); - - if (other.isClear) - { - clear(); - } - else - { - isClear = false; - - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::copy (channels[i], other.channels[i], size); - } - } - - return *this; -} - -AudioSampleBuffer::~AudioSampleBuffer() noexcept -{ -} - -void AudioSampleBuffer::setSize (const int newNumChannels, - const int newNumSamples, - const bool keepExistingContent, - const bool clearExtraSpace, - const bool avoidReallocating) noexcept -{ - jassert (newNumChannels >= 0); - jassert (newNumSamples >= 0); - - if (newNumSamples != size || newNumChannels != numChannels) - { - const size_t allocatedSamplesPerChannel = ((size_t) newNumSamples + 3) & ~3u; - const size_t channelListSize = ((sizeof (float*) * (size_t) (newNumChannels + 1)) + 15) & ~15u; - const size_t newTotalBytes = ((size_t) newNumChannels * (size_t) allocatedSamplesPerChannel * sizeof (float)) - + channelListSize + 32; - - if (keepExistingContent) - { - HeapBlock newData; - newData.allocate (newTotalBytes, clearExtraSpace || isClear); - - const size_t numSamplesToCopy = (size_t) jmin (newNumSamples, size); - - float** const newChannels = reinterpret_cast (newData.getData()); - float* newChan = reinterpret_cast (newData + channelListSize); - - for (int j = 0; j < newNumChannels; ++j) - { - newChannels[j] = newChan; - newChan += allocatedSamplesPerChannel; - } - - if (! isClear) - { - const int numChansToCopy = jmin (numChannels, newNumChannels); - for (int i = 0; i < numChansToCopy; ++i) - FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy); - } - - allocatedData.swapWith (newData); - allocatedBytes = newTotalBytes; - channels = newChannels; - } - else - { - if (avoidReallocating && allocatedBytes >= newTotalBytes) - { - if (clearExtraSpace || isClear) - allocatedData.clear (newTotalBytes); - } - else - { - allocatedBytes = newTotalBytes; - allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear); - channels = reinterpret_cast (allocatedData.getData()); - } - - float* chan = reinterpret_cast (allocatedData + channelListSize); - for (int i = 0; i < newNumChannels; ++i) - { - channels[i] = chan; - chan += allocatedSamplesPerChannel; - } - } - - channels [newNumChannels] = 0; - size = newNumSamples; - numChannels = newNumChannels; - } -} - -void AudioSampleBuffer::clear() noexcept -{ - if (! isClear) - { - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::clear (channels[i], size); - - isClear = true; - } -} - -void AudioSampleBuffer::clear (const int startSample, - const int numSamples) noexcept -{ - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (! isClear) - { - if (startSample == 0 && numSamples == size) - isClear = true; - - for (int i = 0; i < numChannels; ++i) - FloatVectorOperations::clear (channels[i] + startSample, numSamples); - } -} - -void AudioSampleBuffer::clear (const int channel, - const int startSample, - const int numSamples) noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (! isClear) - FloatVectorOperations::clear (channels [channel] + startSample, numSamples); -} - -float AudioSampleBuffer::getSample (int channel, int index) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (isPositiveAndBelow (index, size)); - return *(channels [channel] + index); -} - -void AudioSampleBuffer::setSample (int channel, int index, float newValue) noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (isPositiveAndBelow (index, size)); - *(channels [channel] + index) = newValue; - isClear = false; -} - -void AudioSampleBuffer::addSample (int channel, int index, float valueToAdd) noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (isPositiveAndBelow (index, size)); - *(channels [channel] + index) += valueToAdd; - isClear = false; -} - -void AudioSampleBuffer::applyGain (const int channel, - const int startSample, - int numSamples, - const float gain) noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (gain != 1.0f && ! isClear) - { - float* const d = channels [channel] + startSample; - - if (gain == 0.0f) - FloatVectorOperations::clear (d, numSamples); - else - FloatVectorOperations::multiply (d, gain, numSamples); - } -} - -void AudioSampleBuffer::applyGainRamp (const int channel, - const int startSample, - int numSamples, - float startGain, - float endGain) noexcept -{ - if (! isClear) - { - if (startGain == endGain) - { - applyGain (channel, startSample, numSamples, startGain); - } - else - { - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - const float increment = (endGain - startGain) / numSamples; - float* d = channels [channel] + startSample; - - while (--numSamples >= 0) - { - *d++ *= startGain; - startGain += increment; - } - } - } -} - -void AudioSampleBuffer::applyGain (int startSample, int numSamples, float gain) noexcept -{ - for (int i = 0; i < numChannels; ++i) - applyGain (i, startSample, numSamples, gain); -} - -void AudioSampleBuffer::applyGain (const float gain) noexcept -{ - applyGain (0, size, gain); -} - -void AudioSampleBuffer::applyGainRamp (int startSample, int numSamples, - float startGain, float endGain) noexcept -{ - for (int i = 0; i < numChannels; ++i) - applyGainRamp (i, startSample, numSamples, startGain, endGain); -} - -void AudioSampleBuffer::addFrom (const int destChannel, - const int destStartSample, - const AudioSampleBuffer& source, - const int sourceChannel, - const int sourceStartSample, - int numSamples, - const float gain) noexcept -{ - jassert (&source != this || sourceChannel != destChannel); - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (isPositiveAndBelow (sourceChannel, source.numChannels)); - jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size); - - if (gain != 0.0f && numSamples > 0 && ! source.isClear) - { - float* const d = channels [destChannel] + destStartSample; - const float* const s = source.channels [sourceChannel] + sourceStartSample; - - if (isClear) - { - isClear = false; - - if (gain != 1.0f) - FloatVectorOperations::copyWithMultiply (d, s, gain, numSamples); - else - FloatVectorOperations::copy (d, s, numSamples); - } - else - { - if (gain != 1.0f) - FloatVectorOperations::addWithMultiply (d, s, gain, numSamples); - else - FloatVectorOperations::add (d, s, numSamples); - } - } -} - -void AudioSampleBuffer::addFrom (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - const float gain) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (gain != 0.0f && numSamples > 0) - { - float* const d = channels [destChannel] + destStartSample; - - if (isClear) - { - isClear = false; - - if (gain != 1.0f) - FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples); - else - FloatVectorOperations::copy (d, source, numSamples); - } - else - { - if (gain != 1.0f) - FloatVectorOperations::addWithMultiply (d, source, gain, numSamples); - else - FloatVectorOperations::add (d, source, numSamples); - } - } -} - -void AudioSampleBuffer::addFromWithRamp (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - float startGain, - const float endGain) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (startGain == endGain) - { - addFrom (destChannel, destStartSample, source, numSamples, startGain); - } - else - { - if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) - { - isClear = false; - const float increment = (endGain - startGain) / numSamples; - float* d = channels [destChannel] + destStartSample; - - while (--numSamples >= 0) - { - *d++ += startGain * *source++; - startGain += increment; - } - } - } -} - -void AudioSampleBuffer::copyFrom (const int destChannel, - const int destStartSample, - const AudioSampleBuffer& source, - const int sourceChannel, - const int sourceStartSample, - int numSamples) noexcept -{ - jassert (&source != this || sourceChannel != destChannel); - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (isPositiveAndBelow (sourceChannel, source.numChannels)); - jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size); - - if (numSamples > 0) - { - if (source.isClear) - { - if (! isClear) - FloatVectorOperations::clear (channels [destChannel] + destStartSample, numSamples); - } - else - { - isClear = false; - FloatVectorOperations::copy (channels [destChannel] + destStartSample, - source.channels [sourceChannel] + sourceStartSample, - numSamples); - } - } -} - -void AudioSampleBuffer::copyFrom (const int destChannel, - const int destStartSample, - const float* source, - int numSamples) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (numSamples > 0) - { - isClear = false; - FloatVectorOperations::copy (channels [destChannel] + destStartSample, source, numSamples); - } -} - -void AudioSampleBuffer::copyFrom (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - const float gain) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (numSamples > 0) - { - float* const d = channels [destChannel] + destStartSample; - - if (gain != 1.0f) - { - if (gain == 0) - { - if (! isClear) - FloatVectorOperations::clear (d, numSamples); - } - else - { - isClear = false; - FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples); - } - } - else - { - isClear = false; - FloatVectorOperations::copy (d, source, numSamples); - } - } -} - -void AudioSampleBuffer::copyFromWithRamp (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - float startGain, - float endGain) noexcept -{ - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - - if (startGain == endGain) - { - copyFrom (destChannel, destStartSample, source, numSamples, startGain); - } - else - { - if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) - { - isClear = false; - const float increment = (endGain - startGain) / numSamples; - float* d = channels [destChannel] + destStartSample; - - while (--numSamples >= 0) - { - *d++ = startGain * *source++; - startGain += increment; - } - } - } -} - -void AudioSampleBuffer::reverse (int channel, int startSample, int numSamples) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (! isClear) - std::reverse (channels[channel] + startSample, - channels[channel] + startSample + numSamples); -} - -void AudioSampleBuffer::reverse (int startSample, int numSamples) const noexcept -{ - for (int i = 0; i < numChannels; ++i) - reverse (i, startSample, numSamples); -} - -Range AudioSampleBuffer::findMinMax (const int channel, - const int startSample, - int numSamples) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (isClear) - return Range(); - - return FloatVectorOperations::findMinAndMax (channels [channel] + startSample, numSamples); -} - -float AudioSampleBuffer::getMagnitude (const int channel, - const int startSample, - const int numSamples) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (isClear) - return 0.0f; - - const Range r (findMinMax (channel, startSample, numSamples)); - - return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd()); -} - -float AudioSampleBuffer::getMagnitude (int startSample, int numSamples) const noexcept -{ - float mag = 0.0f; - - if (! isClear) - for (int i = 0; i < numChannels; ++i) - mag = jmax (mag, getMagnitude (i, startSample, numSamples)); - - return mag; -} - -float AudioSampleBuffer::getRMSLevel (const int channel, - const int startSample, - const int numSamples) const noexcept -{ - jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); - - if (numSamples <= 0 || channel < 0 || channel >= numChannels || isClear) - return 0.0f; - - const float* const data = channels [channel] + startSample; - double sum = 0.0; - - for (int i = 0; i < numSamples; ++i) - { - const float sample = data [i]; - sum += sample * sample; - } - - return (float) std::sqrt (sum / numSamples); -} diff --git a/source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h b/source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h index 0d17f25cf..04dc75813 100644 --- a/source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h +++ b/source/modules/juce_audio_basics/buffers/juce_AudioSampleBuffer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED -#define JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED +#pragma once //============================================================================== @@ -62,13 +53,11 @@ public: throw a std::bad_alloc exception. */ AudioBuffer (int numChannelsToAllocate, - int numSamplesToAllocate) noexcept + int numSamplesToAllocate) : numChannels (numChannelsToAllocate), size (numSamplesToAllocate) { - jassert (size >= 0); - jassert (numChannels >= 0); - + jassert (size >= 0 && numChannels >= 0); allocateData(); } @@ -89,7 +78,7 @@ public: */ AudioBuffer (Type* const* dataToReferTo, int numChannelsToUse, - int numSamples) noexcept + int numSamples) : numChannels (numChannelsToUse), size (numSamples), allocatedBytes (0) @@ -118,7 +107,7 @@ public: AudioBuffer (Type* const* dataToReferTo, int numChannelsToUse, int startSample, - int numSamples) noexcept + int numSamples) : numChannels (numChannelsToUse), size (numSamples), allocatedBytes (0), @@ -135,7 +124,7 @@ public: using an external data buffer, in which case boths buffers will just point to the same shared block of data. */ - AudioBuffer (const AudioBuffer& other) noexcept + AudioBuffer (const AudioBuffer& other) : numChannels (other.numChannels), size (other.size), allocatedBytes (other.allocatedBytes) @@ -163,7 +152,7 @@ public: /** Copies another buffer onto this one. This buffer's size will be changed to that of the other buffer. */ - AudioBuffer& operator= (const AudioBuffer& other) noexcept + AudioBuffer& operator= (const AudioBuffer& other) { if (this != &other) { @@ -190,7 +179,6 @@ public: */ ~AudioBuffer() noexcept {} - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS /** Move constructor */ AudioBuffer (AudioBuffer&& other) noexcept : numChannels (other.numChannels), @@ -221,16 +209,15 @@ public: other.allocatedBytes = 0; return *this; } - #endif //============================================================================== /** Returns the number of channels of audio data that this buffer contains. - @see getSampleData + @see getNumSamples, getReadPointer, getWritePointer */ int getNumChannels() const noexcept { return numChannels; } /** Returns the number of samples allocated in each of the buffer's channels. - @see getSampleData + @see getNumChannels, getReadPointer, getWritePointer */ int getNumSamples() const noexcept { return size; } @@ -244,7 +231,7 @@ public: const Type* getReadPointer (int channelNumber) const noexcept { jassert (isPositiveAndBelow (channelNumber, numChannels)); - return channels [channelNumber]; + return channels[channelNumber]; } /** Returns a pointer to an array of read-only samples in one of the buffer's channels. @@ -258,7 +245,7 @@ public: { jassert (isPositiveAndBelow (channelNumber, numChannels)); jassert (isPositiveAndBelow (sampleIndex, size)); - return channels [channelNumber] + sampleIndex; + return channels[channelNumber] + sampleIndex; } /** Returns a writeable pointer to one of the buffer's channels. @@ -271,7 +258,7 @@ public: { jassert (isPositiveAndBelow (channelNumber, numChannels)); isClear = false; - return channels [channelNumber]; + return channels[channelNumber]; } /** Returns a writeable pointer to one of the buffer's channels. @@ -285,7 +272,7 @@ public: jassert (isPositiveAndBelow (channelNumber, numChannels)); jassert (isPositiveAndBelow (sampleIndex, size)); isClear = false; - return channels [channelNumber] + sampleIndex; + return channels[channelNumber] + sampleIndex; } /** Returns an array of pointers to the channels in the buffer. @@ -326,27 +313,27 @@ public: int newNumSamples, bool keepExistingContent = false, bool clearExtraSpace = false, - bool avoidReallocating = false) noexcept + bool avoidReallocating = false) { jassert (newNumChannels >= 0); jassert (newNumSamples >= 0); if (newNumSamples != size || newNumChannels != numChannels) { - const size_t allocatedSamplesPerChannel = ((size_t) newNumSamples + 3) & ~3u; - const size_t channelListSize = ((sizeof (Type*) * (size_t) (newNumChannels + 1)) + 15) & ~15u; - const size_t newTotalBytes = ((size_t) newNumChannels * (size_t) allocatedSamplesPerChannel * sizeof (Type)) - + channelListSize + 32; + const auto allocatedSamplesPerChannel = ((size_t) newNumSamples + 3) & ~3u; + const auto channelListSize = ((sizeof (Type*) * (size_t) (newNumChannels + 1)) + 15) & ~15u; + const auto newTotalBytes = ((size_t) newNumChannels * (size_t) allocatedSamplesPerChannel * sizeof (Type)) + + channelListSize + 32; if (keepExistingContent) { HeapBlock newData; newData.allocate (newTotalBytes, clearExtraSpace || isClear); - const size_t numSamplesToCopy = (size_t) jmin (newNumSamples, size); + auto numSamplesToCopy = (size_t) jmin (newNumSamples, size); - Type** const newChannels = reinterpret_cast (newData.getData()); - Type* newChan = reinterpret_cast (newData + channelListSize); + auto newChannels = reinterpret_cast (newData.getData()); + auto newChan = reinterpret_cast (newData + channelListSize); for (int j = 0; j < newNumChannels; ++j) { @@ -356,7 +343,8 @@ public: if (! isClear) { - const int numChansToCopy = jmin (numChannels, newNumChannels); + auto numChansToCopy = jmin (numChannels, newNumChannels); + for (int i = 0; i < numChansToCopy; ++i) FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy); } @@ -379,7 +367,8 @@ public: channels = reinterpret_cast (allocatedData.getData()); } - Type* chan = reinterpret_cast (allocatedData + channelListSize); + auto* chan = reinterpret_cast (allocatedData + channelListSize); + for (int i = 0; i < newNumChannels; ++i) { channels[i] = chan; @@ -387,7 +376,7 @@ public: } } - channels [newNumChannels] = 0; + channels[newNumChannels] = 0; size = newNumSamples; numChannels = newNumChannels; } @@ -408,12 +397,14 @@ public: it when the buffer is deleted or resized. @param newNumChannels the number of channels to use - this must correspond to the number of elements in the array passed in + @param newStartSample the offset within the arrays at which the data begins @param newNumSamples the number of samples to use - this must correspond to the size of the arrays passed in */ void setDataToReferTo (Type** dataToReferTo, - const int newNumChannels, - const int newNumSamples) noexcept + int newNumChannels, + int newStartSample, + int newNumSamples) { jassert (dataToReferTo != nullptr); jassert (newNumChannels >= 0 && newNumSamples >= 0); @@ -427,10 +418,35 @@ public: numChannels = newNumChannels; size = newNumSamples; - allocateChannels (dataToReferTo, 0); + allocateChannels (dataToReferTo, newStartSample); jassert (! isClear); } + /** Makes this buffer point to a pre-allocated set of channel data arrays. + + There's also a constructor that lets you specify arrays like this, but this + lets you change the channels dynamically. + + Note that if the buffer is resized or its number of channels is changed, it + will re-allocate memory internally and copy the existing data to this new area, + so it will then stop directly addressing this memory. + + @param dataToReferTo a pre-allocated array containing pointers to the data + for each channel that should be used by this buffer. The + buffer will only refer to this memory, it won't try to delete + it when the buffer is deleted or resized. + @param newNumChannels the number of channels to use - this must correspond to the + number of elements in the array passed in + @param newNumSamples the number of samples to use - this must correspond to the + size of the arrays passed in + */ + void setDataToReferTo (Type** dataToReferTo, + int newNumChannels, + int newNumSamples) + { + setDataToReferTo (dataToReferTo, newNumChannels, 0, newNumSamples); + } + /** Resizes this buffer to match the given one, and copies all of its content across. The source buffer can contain a different floating point type, so this can be used to convert between 32 and 64 bit float buffer types. @@ -446,10 +462,12 @@ public: } else { + isClear = false; + for (int chan = 0; chan < numChannels; ++chan) { - Type* const dest = channels[chan]; - const OtherType* const src = other.getReadPointer (chan); + auto* dest = channels[chan]; + auto* src = other.getReadPointer (chan); for (int i = 0; i < size; ++i) dest[i] = static_cast (src[i]); @@ -475,10 +493,9 @@ public: For speed, this doesn't check whether the channel and sample number are in-range, so be careful! */ - void clear (int startSample, - int numSamples) noexcept + void clear (int startSample, int numSamples) noexcept { - jassert (startSample >= 0 && startSample + numSamples <= size); + jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); if (! isClear) { @@ -495,15 +512,13 @@ public: For speed, this doesn't check whether the channel and sample number are in-range, so be careful! */ - void clear (int channel, - int startSample, - int numSamples) noexcept + void clear (int channel, int startSample, int numSamples) noexcept { jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); + jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); if (! isClear) - FloatVectorOperations::clear (channels [channel] + startSample, numSamples); + FloatVectorOperations::clear (channels[channel] + startSample, numSamples); } /** Returns true if the buffer has been entirely cleared. @@ -524,7 +539,7 @@ public: { jassert (isPositiveAndBelow (channel, numChannels)); jassert (isPositiveAndBelow (sampleIndex, size)); - return *(channels [channel] + sampleIndex); + return *(channels[channel] + sampleIndex); } /** Sets a sample in the buffer. @@ -536,7 +551,7 @@ public: { jassert (isPositiveAndBelow (destChannel, numChannels)); jassert (isPositiveAndBelow (destSample, size)); - *(channels [destChannel] + destSample) = newValue; + *(channels[destChannel] + destSample) = newValue; isClear = false; } @@ -549,7 +564,7 @@ public: { jassert (isPositiveAndBelow (destChannel, numChannels)); jassert (isPositiveAndBelow (destSample, size)); - *(channels [destChannel] + destSample) += valueToAdd; + *(channels[destChannel] + destSample) += valueToAdd; isClear = false; } @@ -558,19 +573,16 @@ public: For speed, this doesn't check whether the channel and sample number are in-range, so be careful! */ - void applyGain (int channel, - int startSample, - int numSamples, - Type gain) noexcept + void applyGain (int channel, int startSample, int numSamples, Type gain) noexcept { jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); + jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); - if (gain != 1.0f && ! isClear) + if (gain != (Type) 1 && ! isClear) { - Type* const d = channels [channel] + startSample; + auto* d = channels[channel] + startSample; - if (gain == 0.0f) + if (gain == 0) FloatVectorOperations::clear (d, numSamples); else FloatVectorOperations::multiply (d, gain, numSamples); @@ -582,9 +594,7 @@ public: For speed, this doesn't check whether the sample numbers are in-range, so be careful! */ - void applyGain (int startSample, - int numSamples, - Type gain) noexcept + void applyGain (int startSample, int numSamples, Type gain) noexcept { for (int i = 0; i < numChannels; ++i) applyGain (i, startSample, numSamples, gain); @@ -605,11 +615,8 @@ public: For speed, this doesn't check whether the sample numbers are in-range, so be careful! */ - void applyGainRamp (int channel, - int startSample, - int numSamples, - Type startGain, - Type endGain) noexcept + void applyGainRamp (int channel, int startSample, int numSamples, + Type startGain, Type endGain) noexcept { if (! isClear) { @@ -620,10 +627,10 @@ public: else { jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); + jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); - const Type increment = (endGain - startGain) / numSamples; - Type* d = channels [channel] + startSample; + const auto increment = (endGain - startGain) / numSamples; + auto* d = channels[channel] + startSample; while (--numSamples >= 0) { @@ -643,10 +650,8 @@ public: For speed, this doesn't check whether the sample numbers are in-range, so be careful! */ - void applyGainRamp (int startSample, - int numSamples, - Type startGain, - Type endGain) noexcept + void applyGainRamp (int startSample, int numSamples, + Type startGain, Type endGain) noexcept { for (int i = 0; i < numChannels; ++i) applyGainRamp (i, startSample, numSamples, startGain, endGain); @@ -675,27 +680,27 @@ public: { jassert (&source != this || sourceChannel != destChannel); jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); + jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size); jassert (isPositiveAndBelow (sourceChannel, source.numChannels)); jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size); - if (gainToApplyToSource != 0.0f && numSamples > 0 && ! source.isClear) + if (gainToApplyToSource != 0 && numSamples > 0 && ! source.isClear) { - Type* const d = channels [destChannel] + destStartSample; - const Type* const s = source.channels [sourceChannel] + sourceStartSample; + auto* d = channels[destChannel] + destStartSample; + auto* s = source.channels[sourceChannel] + sourceStartSample; if (isClear) { isClear = false; - if (gainToApplyToSource != 1.0f) + if (gainToApplyToSource != (Type) 1) FloatVectorOperations::copyWithMultiply (d, s, gainToApplyToSource, numSamples); else FloatVectorOperations::copy (d, s, numSamples); } else { - if (gainToApplyToSource != 1.0f) + if (gainToApplyToSource != (Type) 1) FloatVectorOperations::addWithMultiply (d, s, gainToApplyToSource, numSamples); else FloatVectorOperations::add (d, s, numSamples); @@ -722,25 +727,25 @@ public: Type gainToApplyToSource = (Type) 1) noexcept { jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); + jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size); jassert (source != nullptr); - if (gainToApplyToSource != 0.0f && numSamples > 0) + if (gainToApplyToSource != 0 && numSamples > 0) { - Type* const d = channels [destChannel] + destStartSample; + auto* d = channels[destChannel] + destStartSample; if (isClear) { isClear = false; - if (gainToApplyToSource != 1.0f) + if (gainToApplyToSource != (Type) 1) FloatVectorOperations::copyWithMultiply (d, source, gainToApplyToSource, numSamples); else FloatVectorOperations::copy (d, source, numSamples); } else { - if (gainToApplyToSource != 1.0f) + if (gainToApplyToSource != (Type) 1) FloatVectorOperations::addWithMultiply (d, source, gainToApplyToSource, numSamples); else FloatVectorOperations::add (d, source, numSamples); @@ -767,21 +772,21 @@ public: Type startGain, Type endGain) noexcept { - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - if (startGain == endGain) { addFrom (destChannel, destStartSample, source, numSamples, startGain); } else { - if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) + jassert (isPositiveAndBelow (destChannel, numChannels)); + jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size); + jassert (source != nullptr); + + if (numSamples > 0) { isClear = false; - const Type increment = (endGain - startGain) / numSamples; - Type* d = channels [destChannel] + destStartSample; + const auto increment = (endGain - startGain) / numSamples; + auto* d = channels[destChannel] + destStartSample; while (--numSamples >= 0) { @@ -814,20 +819,20 @@ public: jassert (isPositiveAndBelow (destChannel, numChannels)); jassert (destStartSample >= 0 && destStartSample + numSamples <= size); jassert (isPositiveAndBelow (sourceChannel, source.numChannels)); - jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size); + jassert (sourceStartSample >= 0 && numSamples >= 0 && sourceStartSample + numSamples <= source.size); if (numSamples > 0) { if (source.isClear) { if (! isClear) - FloatVectorOperations::clear (channels [destChannel] + destStartSample, numSamples); + FloatVectorOperations::clear (channels[destChannel] + destStartSample, numSamples); } else { isClear = false; - FloatVectorOperations::copy (channels [destChannel] + destStartSample, - source.channels [sourceChannel] + sourceStartSample, + FloatVectorOperations::copy (channels[destChannel] + destStartSample, + source.channels[sourceChannel] + sourceStartSample, numSamples); } } @@ -848,13 +853,13 @@ public: int numSamples) noexcept { jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); + jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size); jassert (source != nullptr); if (numSamples > 0) { isClear = false; - FloatVectorOperations::copy (channels [destChannel] + destStartSample, source, numSamples); + FloatVectorOperations::copy (channels[destChannel] + destStartSample, source, numSamples); } } @@ -875,14 +880,14 @@ public: Type gain) noexcept { jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); + jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size); jassert (source != nullptr); if (numSamples > 0) { - Type* const d = channels [destChannel] + destStartSample; + auto* d = channels[destChannel] + destStartSample; - if (gain != 1.0f) + if (gain != (Type) 1) { if (gain == 0) { @@ -923,21 +928,21 @@ public: Type startGain, Type endGain) noexcept { - jassert (isPositiveAndBelow (destChannel, numChannels)); - jassert (destStartSample >= 0 && destStartSample + numSamples <= size); - jassert (source != nullptr); - if (startGain == endGain) { copyFrom (destChannel, destStartSample, source, numSamples, startGain); } else { - if (numSamples > 0 && (startGain != 0.0f || endGain != 0.0f)) + jassert (isPositiveAndBelow (destChannel, numChannels)); + jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size); + jassert (source != nullptr); + + if (numSamples > 0) { isClear = false; - const Type increment = (endGain - startGain) / numSamples; - Type* d = channels [destChannel] + destStartSample; + const auto increment = (endGain - startGain) / numSamples; + auto* d = channels[destChannel] + destStartSample; while (--numSamples >= 0) { @@ -954,41 +959,35 @@ public: @param startSample the start sample within the channel @param numSamples the number of samples to check */ - Range findMinMax (int channel, - int startSample, - int numSamples) const noexcept + Range findMinMax (int channel, int startSample, int numSamples) const noexcept { jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); + jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); if (isClear) - return Range(); + return {}; - return FloatVectorOperations::findMinAndMax (channels [channel] + startSample, numSamples); + return FloatVectorOperations::findMinAndMax (channels[channel] + startSample, numSamples); } - /** Finds the highest absolute sample value within a region of a channel. */ - Type getMagnitude (int channel, - int startSample, - int numSamples) const noexcept + Type getMagnitude (int channel, int startSample, int numSamples) const noexcept { jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); + jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); if (isClear) - return 0.0f; + return {}; - const Range r (findMinMax (channel, startSample, numSamples)); + auto r = findMinMax (channel, startSample, numSamples); return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd()); } /** Finds the highest absolute sample value within a region on all channels. */ - Type getMagnitude (int startSample, - int numSamples) const noexcept + Type getMagnitude (int startSample, int numSamples) const noexcept { - Type mag = 0.0f; + Type mag = 0; if (! isClear) for (int i = 0; i < numChannels; ++i) @@ -998,22 +997,20 @@ public: } /** Returns the root mean squared level for a region of a channel. */ - Type getRMSLevel (int channel, - int startSample, - int numSamples) const noexcept + Type getRMSLevel (int channel, int startSample, int numSamples) const noexcept { jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); + jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); if (numSamples <= 0 || channel < 0 || channel >= numChannels || isClear) - return 0.0f; + return {}; - const Type* const data = channels [channel] + startSample; + auto* data = channels[channel] + startSample; double sum = 0.0; for (int i = 0; i < numSamples; ++i) { - const Type sample = data [i]; + const Type sample = data[i]; sum += sample * sample; } @@ -1024,7 +1021,7 @@ public: void reverse (int channel, int startSample, int numSamples) const noexcept { jassert (isPositiveAndBelow (channel, numChannels)); - jassert (startSample >= 0 && startSample + numSamples <= size); + jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size); if (! isClear) std::reverse (channels[channel] + startSample, @@ -1045,28 +1042,29 @@ private: size_t allocatedBytes; Type** channels; HeapBlock allocatedData; - Type* preallocatedChannelSpace [32]; + Type* preallocatedChannelSpace[32]; bool isClear; void allocateData() { - const size_t channelListSize = sizeof (Type*) * (size_t) (numChannels + 1); + jassert (size >= 0); + auto channelListSize = sizeof (Type*) * (size_t) (numChannels + 1); allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (Type) + channelListSize + 32; allocatedData.malloc (allocatedBytes); channels = reinterpret_cast (allocatedData.getData()); + auto* chan = (Type*) (allocatedData + channelListSize); - Type* chan = (Type*) (allocatedData + channelListSize); for (int i = 0; i < numChannels; ++i) { channels[i] = chan; chan += size; } - channels [numChannels] = nullptr; + channels[numChannels] = nullptr; isClear = false; } - void allocateChannels (Type* const* const dataToReferTo, int offset) + void allocateChannels (Type* const* dataToReferTo, int offset) { jassert (offset >= 0); @@ -1089,7 +1087,7 @@ private: channels[i] = dataToReferTo[i] + offset; } - channels [numChannels] = nullptr; + channels[numChannels] = nullptr; isClear = false; } @@ -1107,6 +1105,3 @@ private: @see AudioBuffer */ typedef AudioBuffer AudioSampleBuffer; - - -#endif // JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED diff --git a/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp b/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp index c34943d79..be1d59f65 100644 --- a/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp +++ b/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -697,9 +689,13 @@ void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (float* dest, const fl void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (double* dest, const double* src, double multiplier, int num) noexcept { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsmaD (src, 1, &multiplier, dest, 1, dest, 1, (vDSP_Length) num); + #else JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i] * multiplier, Mode::add (d, Mode::mul (mult, s)), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, const Mode::ParallelType mult = Mode::load1 (multiplier);) + #endif } void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept @@ -724,6 +720,34 @@ void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (double* dest, const d #endif } +void JUCE_CALLTYPE FloatVectorOperations::subtractWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept +{ + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i] * multiplier, Mode::sub (d, Mode::mul (mult, s)), + JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) +} + +void JUCE_CALLTYPE FloatVectorOperations::subtractWithMultiply (double* dest, const double* src, double multiplier, int num) noexcept +{ + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i] * multiplier, Mode::sub (d, Mode::mul (mult, s)), + JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) +} + +void JUCE_CALLTYPE FloatVectorOperations::subtractWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept +{ + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] -= src1[i] * src2[i], Mode::sub (d, Mode::mul (s1, s2)), + JUCE_LOAD_SRC1_SRC2_DEST, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) +} + +void JUCE_CALLTYPE FloatVectorOperations::subtractWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept +{ + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] -= src1[i] * src2[i], Mode::sub (d, Mode::mul (s1, s2)), + JUCE_LOAD_SRC1_SRC2_DEST, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) +} + void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src, int num) noexcept { #if JUCE_USE_VDSP_FRAMEWORK @@ -1003,7 +1027,7 @@ double JUCE_CALLTYPE FloatVectorOperations::findMaximum (const double* src, int void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnable) noexcept { - #if JUCE_USE_SSE_INTRINSICS && ! JUCE_MINGW + #if JUCE_USE_SSE_INTRINSICS _MM_SET_FLUSH_ZERO_MODE (shouldEnable ? _MM_FLUSH_ZERO_ON : _MM_FLUSH_ZERO_OFF); #endif ignoreUnused (shouldEnable); @@ -1011,7 +1035,7 @@ void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnab void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport() noexcept { - #if JUCE_USE_SSE_INTRINSICS && ! JUCE_MINGW + #if JUCE_USE_SSE_INTRINSICS const unsigned int mxcsr = _mm_getcsr(); _mm_setcsr (mxcsr | 0x8040); // add the DAZ and FZ bits #endif @@ -1024,7 +1048,7 @@ void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport() noe class FloatVectorOperationsTests : public UnitTest { public: - FloatVectorOperationsTests() : UnitTest ("FloatVectorOperations") {} + FloatVectorOperationsTests() : UnitTest ("FloatVectorOperations", "Audio") {} template struct TestRunner diff --git a/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h b/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h index e15db4360..2b9741cb1 100644 --- a/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h +++ b/source/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h @@ -2,35 +2,31 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FLOATVECTOROPERATIONS_H_INCLUDED -#define JUCE_FLOATVECTOROPERATIONS_H_INCLUDED +#pragma once +#if JUCE_INTEL + #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0; +#else + #define JUCE_SNAP_TO_ZERO(n) +#endif //============================================================================== /** @@ -113,6 +109,18 @@ public: /** Multiplies each source1 value by the corresponding source2 value, then adds it to the destination value. */ static void JUCE_CALLTYPE addWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept; + /** Multiplies each source value by the given multiplier, then subtracts it to the destination value. */ + static void JUCE_CALLTYPE subtractWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; + + /** Multiplies each source value by the given multiplier, then subtracts it to the destination value. */ + static void JUCE_CALLTYPE subtractWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept; + + /** Multiplies each source1 value by the corresponding source2 value, then subtracts it to the destination value. */ + static void JUCE_CALLTYPE subtractWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept; + + /** Multiplies each source1 value by the corresponding source2 value, then subtracts it to the destination value. */ + static void JUCE_CALLTYPE subtractWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept; + /** Multiplies the destination values by the source values. */ static void JUCE_CALLTYPE multiply (float* dest, const float* src, int numValues) noexcept; @@ -211,6 +219,3 @@ public: */ static void JUCE_CALLTYPE disableDenormalisedNumberSupport() noexcept; }; - - -#endif // JUCE_FLOATVECTOROPERATIONS_H_INCLUDED diff --git a/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp b/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp index 8fe801c07..11f996b02 100644 --- a/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp +++ b/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h b/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h index 36dcbb888..75eaeeca4 100644 --- a/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h +++ b/source/modules/juce_audio_basics/effects/juce_CatmullRomInterpolator.h @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/effects/juce_Decibels.h b/source/modules/juce_audio_basics/effects/juce_Decibels.h index db2bf10bd..e144f11e0 100644 --- a/source/modules/juce_audio_basics/effects/juce_Decibels.h +++ b/source/modules/juce_audio_basics/effects/juce_Decibels.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DECIBELS_H_INCLUDED -#define JUCE_DECIBELS_H_INCLUDED +#pragma once //============================================================================== @@ -105,6 +96,3 @@ private: Decibels(); // This class can't be instantiated, it's just a holder for static methods.. JUCE_DECLARE_NON_COPYABLE (Decibels) }; - - -#endif // JUCE_DECIBELS_H_INCLUDED diff --git a/source/modules/juce_audio_basics/effects/juce_FFT.cpp b/source/modules/juce_audio_basics/effects/juce_FFT.cpp deleted file mode 100644 index 8ccb23f8b..000000000 --- a/source/modules/juce_audio_basics/effects/juce_FFT.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2016 - 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. - - ============================================================================== -*/ - -// (For the moment, we'll implement a few local operators for this complex class - one -// day we'll probably either have a juce complex class, or use the C++11 one) -static FFT::Complex operator+ (FFT::Complex a, FFT::Complex b) noexcept { FFT::Complex c = { a.r + b.r, a.i + b.i }; return c; } -static FFT::Complex operator- (FFT::Complex a, FFT::Complex b) noexcept { FFT::Complex c = { a.r - b.r, a.i - b.i }; return c; } -static FFT::Complex operator* (FFT::Complex a, FFT::Complex b) noexcept { FFT::Complex c = { a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r }; return c; } -static FFT::Complex& operator+= (FFT::Complex& a, FFT::Complex b) noexcept { a.r += b.r; a.i += b.i; return a; } - -//============================================================================== -struct FFT::FFTConfig -{ - FFTConfig (int sizeOfFFT, bool isInverse) - : fftSize (sizeOfFFT), inverse (isInverse), twiddleTable ((size_t) sizeOfFFT) - { - for (int i = 0; i < fftSize; ++i) - { - const double phase = (isInverse ? 2.0 : -2.0) * double_Pi * i / fftSize; - twiddleTable[i].r = (float) cos (phase); - twiddleTable[i].i = (float) sin (phase); - } - - const int root = (int) std::sqrt ((double) fftSize); - int divisor = 4, n = fftSize; - - for (int i = 0; i < numElementsInArray (factors); ++i) - { - while ((n % divisor) != 0) - { - if (divisor == 2) divisor = 3; - else if (divisor == 4) divisor = 2; - else divisor += 2; - - if (divisor > root) - divisor = n; - } - - n /= divisor; - - jassert (divisor == 1 || divisor == 2 || divisor == 4); - factors[i].radix = divisor; - factors[i].length = n; - } - } - - void perform (const Complex* input, Complex* output) const noexcept - { - perform (input, output, 1, 1, factors); - } - - const int fftSize; - const bool inverse; - - struct Factor { int radix, length; }; - Factor factors[32]; - HeapBlock twiddleTable; - - void perform (const Complex* input, Complex* output, const int stride, const int strideIn, const Factor* facs) const noexcept - { - const Factor factor (*facs++); - Complex* const originalOutput = output; - const Complex* const outputEnd = output + factor.radix * factor.length; - - if (stride == 1 && factor.radix <= 5) - { - for (int i = 0; i < factor.radix; ++i) - perform (input + stride * strideIn * i, output + i * factor.length, stride * factor.radix, strideIn, facs); - - butterfly (factor, output, stride); - return; - } - - if (factor.length == 1) - { - do - { - *output++ = *input; - input += stride * strideIn; - } - while (output < outputEnd); - } - else - { - do - { - perform (input, output, stride * factor.radix, strideIn, facs); - input += stride * strideIn; - output += factor.length; - } - while (output < outputEnd); - } - - butterfly (factor, originalOutput, stride); - } - - void butterfly (const Factor factor, Complex* data, const int stride) const noexcept - { - switch (factor.radix) - { - case 1: break; - case 2: butterfly2 (data, stride, factor.length); return; - case 4: butterfly4 (data, stride, factor.length); return; - default: jassertfalse; break; - } - - Complex* scratch = static_cast (alloca (sizeof (Complex) * (size_t) factor.radix)); - - for (int i = 0; i < factor.length; ++i) - { - for (int k = i, q1 = 0; q1 < factor.radix; ++q1) - { - scratch[q1] = data[k]; - k += factor.length; - } - - for (int k = i, q1 = 0; q1 < factor.radix; ++q1) - { - int twiddleIndex = 0; - data[k] = scratch[0]; - - for (int q = 1; q < factor.radix; ++q) - { - twiddleIndex += stride * k; - - if (twiddleIndex >= fftSize) - twiddleIndex -= fftSize; - - data[k] += scratch[q] * twiddleTable[twiddleIndex]; - } - - k += factor.length; - } - } - } - - void butterfly2 (Complex* data, const int stride, const int length) const noexcept - { - Complex* dataEnd = data + length; - const Complex* tw = twiddleTable; - - for (int i = length; --i >= 0;) - { - const Complex s (*dataEnd * *tw); - tw += stride; - *dataEnd++ = *data - s; - *data++ += s; - } - } - - void butterfly4 (Complex* data, const int stride, const int length) const noexcept - { - const int lengthX2 = length * 2; - const int lengthX3 = length * 3; - - const Complex* twiddle1 = twiddleTable; - const Complex* twiddle2 = twiddle1; - const Complex* twiddle3 = twiddle1; - - for (int i = length; --i >= 0;) - { - const Complex s0 = data[length] * *twiddle1; - const Complex s1 = data[lengthX2] * *twiddle2; - const Complex s2 = data[lengthX3] * *twiddle3; - const Complex s3 = s0 + s2; - const Complex s4 = s0 - s2; - const Complex s5 = *data - s1; - *data += s1; - data[lengthX2] = *data - s3; - twiddle1 += stride; - twiddle2 += stride * 2; - twiddle3 += stride * 3; - *data += s3; - - if (inverse) - { - data[length].r = s5.r - s4.i; - data[length].i = s5.i + s4.r; - data[lengthX3].r = s5.r + s4.i; - data[lengthX3].i = s5.i - s4.r; - } - else - { - data[length].r = s5.r + s4.i; - data[length].i = s5.i - s4.r; - data[lengthX3].r = s5.r - s4.i; - data[lengthX3].i = s5.i + s4.r; - } - - ++data; - } - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FFTConfig) -}; - - -//============================================================================== -FFT::FFT (int order, bool inverse) : config (new FFTConfig (1 << order, inverse)), size (1 << order) {} -FFT::~FFT() {} - -void FFT::perform (const Complex* const input, Complex* const output) const noexcept -{ - config->perform (input, output); -} - -const size_t maxFFTScratchSpaceToAlloca = 256 * 1024; - -void FFT::performRealOnlyForwardTransform (float* d) const noexcept -{ - const size_t scratchSize = 16 + sizeof (FFT::Complex) * (size_t) size; - - if (scratchSize < maxFFTScratchSpaceToAlloca) - { - performRealOnlyForwardTransform (static_cast (alloca (scratchSize)), d); - } - else - { - HeapBlock heapSpace (scratchSize); - performRealOnlyForwardTransform (reinterpret_cast (heapSpace.getData()), d); - } -} - -void FFT::performRealOnlyInverseTransform (float* d) const noexcept -{ - const size_t scratchSize = 16 + sizeof (FFT::Complex) * (size_t) size; - - if (scratchSize < maxFFTScratchSpaceToAlloca) - { - performRealOnlyInverseTransform (static_cast (alloca (scratchSize)), d); - } - else - { - HeapBlock heapSpace (scratchSize); - performRealOnlyInverseTransform (reinterpret_cast (heapSpace.getData()), d); - } -} - -void FFT::performRealOnlyForwardTransform (Complex* scratch, float* d) const noexcept -{ - // This can only be called on an FFT object that was created to do forward transforms. - jassert (! config->inverse); - - for (int i = 0; i < size; ++i) - { - scratch[i].r = d[i]; - scratch[i].i = 0; - } - - perform (scratch, reinterpret_cast (d)); -} - -void FFT::performRealOnlyInverseTransform (Complex* scratch, float* d) const noexcept -{ - // This can only be called on an FFT object that was created to do inverse transforms. - jassert (config->inverse); - - perform (reinterpret_cast (d), scratch); - - const float scaleFactor = 1.0f / size; - - for (int i = 0; i < size; ++i) - { - d[i] = scratch[i].r * scaleFactor; - d[i + size] = scratch[i].i * scaleFactor; - } -} - -void FFT::performFrequencyOnlyForwardTransform (float* d) const noexcept -{ - performRealOnlyForwardTransform (d); - const int twiceSize = size * 2; - - for (int i = 0; i < twiceSize; i += 2) - { - d[i / 2] = juce_hypot (d[i], d[i + 1]); - - if (i >= size) - { - d[i] = 0; - d[i + 1] = 0; - } - } -} diff --git a/source/modules/juce_audio_basics/effects/juce_FFT.h b/source/modules/juce_audio_basics/effects/juce_FFT.h deleted file mode 100644 index e245fd495..000000000 --- a/source/modules/juce_audio_basics/effects/juce_FFT.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2016 - 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. - - ============================================================================== -*/ - -/** - A very minimal FFT class. - - This is only a simple low-footprint implementation and isn't tuned for speed - it may - be useful for simple applications where one of the more complex FFT libraries would be - overkill. (But in the future it may end up becoming optimised of course...) - - The FFT class itself contains lookup tables, so there's some overhead in creating - one, you should create and cache an FFT object for each size/direction of transform - that you need, and re-use them to perform the actual operation. -*/ -class JUCE_API FFT -{ -public: - /** Initialises an object for performing either a forward or inverse FFT with the given size. - The the number of points the FFT will operate on will be 2 ^ order. - */ - FFT (int order, bool isInverse); - - /** Destructor. */ - ~FFT(); - - /** A complex number, for the purposes of the FFT class. */ - struct Complex - { - float r; /**< Real part. */ - float i; /**< Imaginary part. */ - }; - - /** Performs an out-of-place FFT, either forward or inverse depending on the mode - that was passed to this object's constructor. - - The arrays must contain at least getSize() elements. - */ - void perform (const Complex* input, Complex* output) const noexcept; - - /** Performs an in-place forward transform on a block of real data. - - The size of the array passed in must be 2 * getSize(), and the first half - should contain your raw input sample data. On return, the array will contain - complex frequency + phase data, and can be passed to performRealOnlyInverseTransform() - in order to convert it back to reals. - */ - void performRealOnlyForwardTransform (float* inputOutputData) const noexcept; - - /** Performs a reverse operation to data created in performRealOnlyForwardTransform(). - - The size of the array passed in must be 2 * getSize(), containing complex - frequency and phase data. On return, the first half of the array will contain - the reconstituted samples. - */ - void performRealOnlyInverseTransform (float* inputOutputData) const noexcept; - - /** Takes an array and simply transforms it to the frequency spectrum. - This may be handy for things like frequency displays or analysis. - */ - void performFrequencyOnlyForwardTransform (float* inputOutputData) const noexcept; - - /** Returns the number of data points that this FFT was created to work with. */ - int getSize() const noexcept { return size; } - -private: - JUCE_PUBLIC_IN_DLL_BUILD (struct FFTConfig) - ScopedPointer config; - const int size; - - void performRealOnlyForwardTransform (Complex*, float*) const noexcept; - void performRealOnlyInverseTransform (Complex*, float*) const noexcept; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FFT) -}; diff --git a/source/modules/juce_audio_basics/effects/juce_IIRFilter.cpp b/source/modules/juce_audio_basics/effects/juce_IIRFilter.cpp index b30ae3c93..39def04d3 100644 --- a/source/modules/juce_audio_basics/effects/juce_IIRFilter.cpp +++ b/source/modules/juce_audio_basics/effects/juce_IIRFilter.cpp @@ -2,38 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#if JUCE_INTEL - #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0; -#else - #define JUCE_SNAP_TO_ZERO(n) -#endif - //============================================================================== IIRCoefficients::IIRCoefficients() noexcept { diff --git a/source/modules/juce_audio_basics/effects/juce_IIRFilter.h b/source/modules/juce_audio_basics/effects/juce_IIRFilter.h index aa85aa711..b0ef1fa11 100644 --- a/source/modules/juce_audio_basics/effects/juce_IIRFilter.h +++ b/source/modules/juce_audio_basics/effects/juce_IIRFilter.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IIRFILTER_H_INCLUDED -#define JUCE_IIRFILTER_H_INCLUDED +#pragma once class IIRFilter; @@ -214,6 +205,3 @@ protected: IIRFilter& operator= (const IIRFilter&); JUCE_LEAK_DETECTOR (IIRFilter) }; - - -#endif // JUCE_IIRFILTER_H_INCLUDED diff --git a/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp b/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp index 900b446b4..ecd892d72 100644 --- a/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp +++ b/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h b/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h index 139d893c6..7143842e3 100644 --- a/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h +++ b/source/modules/juce_audio_basics/effects/juce_LagrangeInterpolator.h @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h b/source/modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h index 18a1ef105..d39dc9173 100644 --- a/source/modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h +++ b/source/modules/juce_audio_basics/effects/juce_LinearSmoothedValue.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LINEARSMOOTHEDVALUE_H_INCLUDED -#define JUCE_LINEARSMOOTHEDVALUE_H_INCLUDED +#pragma once //============================================================================== @@ -45,18 +36,20 @@ class LinearSmoothedValue public: /** Constructor. */ LinearSmoothedValue() noexcept - : currentValue (0), target (0), step (0), countdown (0), stepsToTarget (0) { } /** Constructor. */ LinearSmoothedValue (FloatType initialValue) noexcept - : currentValue (initialValue), target (initialValue), step (0), countdown (0), stepsToTarget (0) + : currentValue (initialValue), target (initialValue) { } //============================================================================== - /** Reset to a new sample rate and ramp length. */ + /** Reset to a new sample rate and ramp length. + @param sampleRate The sampling rate + @param rampLengthInSeconds The duration of the ramp in seconds + */ void reset (double sampleRate, double rampLengthInSeconds) noexcept { jassert (sampleRate > 0 && rampLengthInSeconds >= 0); @@ -65,7 +58,10 @@ public: countdown = 0; } - /** Set a new target value. */ + //============================================================================== + /** Set a new target value. + @param newValue New target value + */ void setValue (FloatType newValue) noexcept { if (target != newValue) @@ -80,7 +76,10 @@ public: } } - /** Compute the next value. */ + //============================================================================== + /** Compute the next value. + @returns Smoothed value + */ FloatType getNextValue() noexcept { if (countdown <= 0) @@ -103,11 +102,83 @@ public: return target; } -private: //============================================================================== - FloatType currentValue, target, step; - int countdown, stepsToTarget; -}; + /** Applies a linear smoothed gain to a stream of samples + S[i] *= gain + @param samples Pointer to a raw array of samples + @param numSamples Length of array of samples + */ + void applyGain (FloatType* samples, int numSamples) noexcept + { + jassert(numSamples >= 0); + + if (isSmoothing()) + { + for (int i = 0; i < numSamples; i++) + samples[i] *= getNextValue(); + } + else + { + FloatVectorOperations::multiply (samples, target, numSamples); + } + } + //============================================================================== + /** Computes output as linear smoothed gain applied to a stream of samples. + Sout[i] = Sin[i] * gain + @param samplesOut A pointer to a raw array of output samples + @param samplesIn A pointer to a raw array of input samples + @param numSamples The length of the array of samples + */ + void applyGain (FloatType* samplesOut, const FloatType* samplesIn, int numSamples) noexcept + { + jassert (numSamples >= 0); -#endif // JUCE_LINEARSMOOTHEDVALUE_H_INCLUDED + if (isSmoothing()) + { + for (int i = 0; i < numSamples; i++) + samplesOut[i] = samplesIn[i] * getNextValue(); + } + else + { + FloatVectorOperations::multiply (samplesOut, samplesIn, target, numSamples); + } + } + + //============================================================================== + /** Applies a linear smoothed gain to a buffer */ + void applyGain (AudioBuffer& buffer, int numSamples) noexcept + { + jassert (numSamples >= 0); + + if (isSmoothing()) + { + if (buffer.getNumChannels() == 1) + { + FloatType* samples = buffer.getWritePointer(0); + + for (int i = 0; i < numSamples; i++) + samples[i] *= getNextValue(); + } + else + { + for (int i = 0; i < numSamples; i++) + { + const FloatType gain = getNextValue(); + + for (int channel = 0; channel < buffer.getNumChannels(); channel++) + buffer.setSample (channel, i, buffer.getSample (channel, i) * gain); + } + } + } + else + { + buffer.applyGain (0, numSamples, target); + } + } + +private: + //============================================================================== + FloatType currentValue = 0, target = 0, step = 0; + int countdown = 0, stepsToTarget = 0; +}; diff --git a/source/modules/juce_audio_basics/effects/juce_Reverb.h b/source/modules/juce_audio_basics/effects/juce_Reverb.h index f01c8aba1..375fda090 100644 --- a/source/modules/juce_audio_basics/effects/juce_Reverb.h +++ b/source/modules/juce_audio_basics/effects/juce_Reverb.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_REVERB_H_INCLUDED -#define JUCE_REVERB_H_INCLUDED +#pragma once //============================================================================== @@ -325,6 +316,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb) }; - - -#endif // JUCE_REVERB_H_INCLUDED diff --git a/source/modules/juce_audio_basics/juce_audio_basics.cpp b/source/modules/juce_audio_basics/juce_audio_basics.cpp index b99de6b43..c5a6bfa9f 100644 --- a/source/modules/juce_audio_basics/juce_audio_basics.cpp +++ b/source/modules/juce_audio_basics/juce_audio_basics.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -37,8 +29,6 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #include "juce_audio_basics.h" #if JUCE_MINGW && ! defined (__SSE2__) @@ -96,7 +86,6 @@ namespace juce #include "effects/juce_IIRFilterOld.cpp" #include "effects/juce_LagrangeInterpolator.cpp" #include "effects/juce_CatmullRomInterpolator.cpp" -#include "effects/juce_FFT.cpp" #include "midi/juce_MidiBuffer.cpp" #include "midi/juce_MidiFile.cpp" #include "midi/juce_MidiKeyboardState.cpp" @@ -115,6 +104,7 @@ namespace juce #include "sources/juce_BufferingAudioSource.cpp" #include "sources/juce_ChannelRemappingAudioSource.cpp" #include "sources/juce_IIRFilterAudioSource.cpp" +#include "sources/juce_MemoryAudioSource.cpp" #include "sources/juce_MixerAudioSource.cpp" #include "sources/juce_ResamplingAudioSource.cpp" #include "sources/juce_ReverbAudioSource.cpp" diff --git a/source/modules/juce_audio_basics/juce_audio_basics.h b/source/modules/juce_audio_basics/juce_audio_basics.h index ab239dfa3..ce6c8f45c 100644 --- a/source/modules/juce_audio_basics/juce_audio_basics.h +++ b/source/modules/juce_audio_basics/juce_audio_basics.h @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -39,7 +31,7 @@ ID: juce_audio_basics vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE audio and MIDI data classes description: Classes for audio buffer manipulation, midi message handling, synthesis, etc. website: http://www.juce.com/juce @@ -54,10 +46,10 @@ *******************************************************************************/ -#ifndef JUCE_AUDIO_BASICS_H_INCLUDED +#pragma once #define JUCE_AUDIO_BASICS_H_INCLUDED -#include "juce_core/juce_core.h" +#include namespace juce { @@ -74,7 +66,6 @@ namespace juce #include "effects/juce_IIRFilterOld.h" #include "effects/juce_LagrangeInterpolator.h" #include "effects/juce_CatmullRomInterpolator.h" -#include "effects/juce_FFT.h" #include "effects/juce_LinearSmoothedValue.h" #include "effects/juce_Reverb.h" #include "midi/juce_MidiMessage.h" @@ -97,12 +88,12 @@ namespace juce #include "sources/juce_BufferingAudioSource.h" #include "sources/juce_ChannelRemappingAudioSource.h" #include "sources/juce_IIRFilterAudioSource.h" +#include "sources/juce_MemoryAudioSource.h" #include "sources/juce_MixerAudioSource.h" #include "sources/juce_ResamplingAudioSource.h" #include "sources/juce_ReverbAudioSource.h" #include "sources/juce_ToneGeneratorAudioSource.h" #include "synthesisers/juce_Synthesiser.h" +#include "audio_play_head/juce_AudioPlayHead.h" } - -#endif // JUCE_AUDIO_BASICS_H_INCLUDED diff --git a/source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp b/source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp index b1ce34473..cc71ff0bc 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp +++ b/source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/midi/juce_MidiBuffer.h b/source/modules/juce_audio_basics/midi/juce_MidiBuffer.h index 36dde82f6..b69d8796c 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiBuffer.h +++ b/source/modules/juce_audio_basics/midi/juce_MidiBuffer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIBUFFER_H_INCLUDED -#define JUCE_MIDIBUFFER_H_INCLUDED +#pragma once //============================================================================== @@ -236,6 +227,3 @@ public: private: JUCE_LEAK_DETECTOR (MidiBuffer) }; - - -#endif // JUCE_MIDIBUFFER_H_INCLUDED diff --git a/source/modules/juce_audio_basics/midi/juce_MidiFile.cpp b/source/modules/juce_audio_basics/midi/juce_MidiFile.cpp index 5145cc0ba..727f9f62d 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiFile.cpp +++ b/source/modules/juce_audio_basics/midi/juce_MidiFile.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/midi/juce_MidiFile.h b/source/modules/juce_audio_basics/midi/juce_MidiFile.h index 5d2134f32..47a1fab98 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiFile.h +++ b/source/modules/juce_audio_basics/midi/juce_MidiFile.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIFILE_H_INCLUDED -#define JUCE_MIDIFILE_H_INCLUDED +#pragma once //============================================================================== @@ -187,6 +178,3 @@ private: JUCE_LEAK_DETECTOR (MidiFile) }; - - -#endif // JUCE_MIDIFILE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp b/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp index 79f95a31e..9f093628b 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp +++ b/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h b/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h index 95f469aef..ef9a8f43c 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h +++ b/source/modules/juce_audio_basics/midi/juce_MidiKeyboardState.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIKEYBOARDSTATE_H_INCLUDED -#define JUCE_MIDIKEYBOARDSTATE_H_INCLUDED +#pragma once class MidiKeyboardState; @@ -206,6 +197,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState) }; - - -#endif // JUCE_MIDIKEYBOARDSTATE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp b/source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp index 2c683516c..e9e6c1be3 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp +++ b/source/modules/juce_audio_basics/midi/juce_MidiMessage.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -44,6 +36,9 @@ namespace MidiHelpers //============================================================================== uint8 MidiMessage::floatValueToMidiByte (const float v) noexcept { + jassert (v >= 0 && v <= 1.0f); // if your value is > 1, maybe you're passing an + // integer value to a float method by mistake? + return MidiHelpers::validVelocity (roundToInt (v * 127.0f)); } @@ -100,7 +95,7 @@ int MidiMessage::getMessageLengthFromFirstByte (const uint8 firstByte) noexcept //============================================================================== MidiMessage::MidiMessage() noexcept - : timeStamp (0), size (2) + : size (2) { packedData.asBytes[0] = 0xf0; packedData.asBytes[1] = 0xf7; @@ -168,12 +163,12 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const double t, bool sysexHasEmbeddedLength) : timeStamp (t) { - const uint8* src = static_cast (srcData); - unsigned int byte = (unsigned int) *src; + auto src = static_cast (srcData); + auto byte = (unsigned int) *src; if (byte < 0x80) { - byte = (unsigned int) (uint8) lastStatusByte; + byte = (unsigned int) lastStatusByte; numBytesUsed = -1; } else @@ -187,7 +182,7 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const { if (byte == 0xf0) { - const uint8* d = src; + auto d = src; bool haveReadAllLengthBytes = ! sysexHasEmbeddedLength; int numVariableLengthSysexBytes = 0; @@ -218,11 +213,11 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const src += numVariableLengthSysexBytes; size = 1 + (int) (d - src); - uint8* dest = allocateSpace (size); + auto dest = allocateSpace (size); *dest = (uint8) byte; memcpy (dest + 1, src, (size_t) (size - 1)); - numBytesUsed += numVariableLengthSysexBytes; // (these aren't counted in the size) + numBytesUsed += (numVariableLengthSysexBytes + size); // (these aren't counted in the size) } else if (byte == 0xff) { @@ -230,9 +225,11 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const const int bytesLeft = readVariableLengthVal (src + 1, n); size = jmin (sz + 1, n + 2 + bytesLeft); - uint8* dest = allocateSpace (size); + auto dest = allocateSpace (size); *dest = (uint8) byte; memcpy (dest + 1, src, (size_t) size - 1); + + numBytesUsed += size; } else { @@ -241,14 +238,14 @@ MidiMessage::MidiMessage (const void* srcData, int sz, int& numBytesUsed, const if (size > 1) { - packedData.asBytes[1] = src[0]; + packedData.asBytes[1] = (sz > 0 ? src[0] : 0); if (size > 2) - packedData.asBytes[2] = src[1]; + packedData.asBytes[2] = (sz > 1 ? src[1] : 0); } - } - numBytesUsed += size; + numBytesUsed += jmin (size, sz + 1); + } } else { @@ -285,7 +282,6 @@ MidiMessage& MidiMessage::operator= (const MidiMessage& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS MidiMessage::MidiMessage (MidiMessage&& other) noexcept : timeStamp (other.timeStamp), size (other.size) { @@ -301,7 +297,6 @@ MidiMessage& MidiMessage::operator= (MidiMessage&& other) noexcept other.size = 0; return *this; } -#endif MidiMessage::~MidiMessage() noexcept { @@ -313,7 +308,7 @@ uint8* MidiMessage::allocateSpace (int bytes) { if (bytes > (int) sizeof (packedData)) { - uint8* d = static_cast (std::malloc ((size_t) bytes)); + auto d = static_cast (std::malloc ((size_t) bytes)); packedData.allocatedData = d; return d; } @@ -348,7 +343,7 @@ String MidiMessage::getDescription() const int MidiMessage::getChannel() const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); if ((data[0] & 0xf0) != 0xf0) return (data[0] & 0xf) + 1; @@ -360,7 +355,7 @@ bool MidiMessage::isForChannel (const int channel) const noexcept { jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 - const uint8* const data = getRawData(); + auto data = getRawData(); return ((data[0] & 0xf) == channel - 1) && ((data[0] & 0xf0) != 0xf0); @@ -370,7 +365,7 @@ void MidiMessage::setChannel (const int channel) noexcept { jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 - uint8* const data = getData(); + auto data = getData(); if ((data[0] & 0xf0) != (uint8) 0xf0) data[0] = (uint8) ((data[0] & (uint8) 0xf0) @@ -379,7 +374,7 @@ void MidiMessage::setChannel (const int channel) noexcept bool MidiMessage::isNoteOn (const bool returnTrueForVelocity0) const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); return ((data[0] & 0xf0) == 0x90) && (returnTrueForVelocity0 || data[2] != 0); @@ -387,7 +382,7 @@ bool MidiMessage::isNoteOn (const bool returnTrueForVelocity0) const noexcept bool MidiMessage::isNoteOff (const bool returnTrueForNoteOnVelocity0) const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); return ((data[0] & 0xf0) == 0x80) || (returnTrueForNoteOnVelocity0 && (data[2] == 0) && ((data[0] & 0xf0) == 0x90)); @@ -395,9 +390,7 @@ bool MidiMessage::isNoteOff (const bool returnTrueForNoteOnVelocity0) const noex bool MidiMessage::isNoteOnOrOff() const noexcept { - const uint8* const data = getRawData(); - - const int d = data[0] & 0xf0; + auto d = getRawData()[0] & 0xf0; return (d == 0x90) || (d == 0x80); } @@ -435,7 +428,7 @@ void MidiMessage::multiplyVelocity (const float scaleFactor) noexcept { if (isNoteOnOrOff()) { - uint8* const data = getData(); + auto data = getData(); data[2] = MidiHelpers::validVelocity (roundToInt (scaleFactor * data[2])); } } @@ -519,7 +512,7 @@ bool MidiMessage::isPitchWheel() const noexcept int MidiMessage::getPitchWheelValue() const noexcept { jassert (isPitchWheel()); - const uint8* const data = getRawData(); + auto data = getRawData(); return data[1] | (data[2] << 7); } @@ -539,7 +532,7 @@ bool MidiMessage::isController() const noexcept bool MidiMessage::isControllerOfType (const int controllerType) const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); return (data[0] & 0xf0) == 0xb0 && data[1] == controllerType; } @@ -607,7 +600,7 @@ MidiMessage MidiMessage::allNotesOff (const int channel) noexcept bool MidiMessage::isAllNotesOff() const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); return (data[0] & 0xf0) == 0xb0 && data[1] == 123; } @@ -618,8 +611,8 @@ MidiMessage MidiMessage::allSoundOff (const int channel) noexcept bool MidiMessage::isAllSoundOff() const noexcept { - const uint8* const data = getRawData(); - return (data[0] & 0xf0) == 0xb0 && data[1] == 120; + auto data = getRawData(); + return data[1] == 120 && (data[0] & 0xf0) == 0xb0; } MidiMessage MidiMessage::allControllersOff (const int channel) noexcept @@ -629,14 +622,9 @@ MidiMessage MidiMessage::allControllersOff (const int channel) noexcept MidiMessage MidiMessage::masterVolume (const float volume) { - const int vol = jlimit (0, 0x3fff, roundToInt (volume * 0x4000)); - - const uint8 buf[] = { 0xf0, 0x7f, 0x7f, 0x04, 0x01, - (uint8) (vol & 0x7f), - (uint8) (vol >> 7), - 0xf7 }; + auto vol = jlimit (0, 0x3fff, roundToInt (volume * 0x4000)); - return MidiMessage (buf, 8); + return { 0xf0, 0x7f, 0x7f, 0x04, 0x01, vol & 0x7f, vol >> 7, 0xf7 }; } //============================================================================== @@ -672,13 +660,14 @@ bool MidiMessage::isActiveSense() const noexcept { return *getRawData() == 0x int MidiMessage::getMetaEventType() const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); return *data != 0xff ? -1 : data[1]; } int MidiMessage::getMetaEventLength() const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); + if (*data == 0xff) { int n; @@ -693,7 +682,7 @@ const uint8* MidiMessage::getMetaEventData() const noexcept jassert (isMetaEvent()); int n; - const uint8* d = getRawData() + 2; + auto d = getRawData() + 2; readVariableLengthVal (d, n); return d + n; } @@ -703,13 +692,14 @@ bool MidiMessage::isEndOfTrackMetaEvent() const noexcept { return getMetaEven bool MidiMessage::isTextMetaEvent() const noexcept { - const int t = getMetaEventType(); + auto t = getMetaEventType(); return t > 0 && t < 16; } String MidiMessage::getTextFromTextMetaEvent() const { - const char* const textData = reinterpret_cast (getMetaEventData()); + auto textData = reinterpret_cast (getMetaEventData()); + return String (CharPointer_UTF8 (textData), CharPointer_UTF8 (textData + getMetaEventLength())); } @@ -736,7 +726,7 @@ MidiMessage MidiMessage::textMetaEvent (int type, StringRef text) const size_t headerLen = sizeof (header) - n; const int totalSize = (int) (headerLen + textSize); - uint8* const dest = result.allocateSpace (totalSize); + auto dest = result.allocateSpace (totalSize); result.size = totalSize; memcpy (dest, header + n, headerLen); @@ -745,9 +735,9 @@ MidiMessage MidiMessage::textMetaEvent (int type, StringRef text) return result; } -bool MidiMessage::isTrackNameEvent() const noexcept { const uint8* data = getRawData(); return (data[1] == 3) && (*data == 0xff); } -bool MidiMessage::isTempoMetaEvent() const noexcept { const uint8* data = getRawData(); return (data[1] == 81) && (*data == 0xff); } -bool MidiMessage::isMidiChannelMetaEvent() const noexcept { const uint8* data = getRawData(); return (data[1] == 0x20) && (*data == 0xff) && (data[2] == 1); } +bool MidiMessage::isTrackNameEvent() const noexcept { auto data = getRawData(); return (data[1] == 3) && (*data == 0xff); } +bool MidiMessage::isTempoMetaEvent() const noexcept { auto data = getRawData(); return (data[1] == 81) && (*data == 0xff); } +bool MidiMessage::isMidiChannelMetaEvent() const noexcept { auto data = getRawData(); return (data[1] == 0x20) && (*data == 0xff) && (data[2] == 1); } int MidiMessage::getMidiChannelMetaEventChannel() const noexcept { @@ -760,7 +750,7 @@ double MidiMessage::getTempoSecondsPerQuarterNote() const noexcept if (! isTempoMetaEvent()) return 0.0; - const uint8* const d = getMetaEventData(); + auto d = getMetaEventData(); return (((unsigned int) d[0] << 16) | ((unsigned int) d[1] << 8) @@ -777,37 +767,33 @@ double MidiMessage::getTempoMetaEventTickLength (const short timeFormat) const n return getTempoSecondsPerQuarterNote() / timeFormat; } - else - { - const int frameCode = (-timeFormat) >> 8; - double framesPerSecond; - switch (frameCode) - { - case 24: framesPerSecond = 24.0; break; - case 25: framesPerSecond = 25.0; break; - case 29: framesPerSecond = 29.97; break; - case 30: framesPerSecond = 30.0; break; - default: framesPerSecond = 30.0; break; - } + const int frameCode = (-timeFormat) >> 8; + double framesPerSecond; - return (1.0 / framesPerSecond) / (timeFormat & 0xff); + switch (frameCode) + { + case 24: framesPerSecond = 24.0; break; + case 25: framesPerSecond = 25.0; break; + case 29: framesPerSecond = 30.0 * 1000.0 / 1001.0; break; + case 30: framesPerSecond = 30.0; break; + default: framesPerSecond = 30.0; break; } + + return (1.0 / framesPerSecond) / (timeFormat & 0xff); } MidiMessage MidiMessage::tempoMetaEvent (int microsecondsPerQuarterNote) noexcept { - const uint8 d[] = { 0xff, 81, 3, - (uint8) (microsecondsPerQuarterNote >> 16), - (uint8) (microsecondsPerQuarterNote >> 8), - (uint8) microsecondsPerQuarterNote }; - - return MidiMessage (d, 6, 0.0); + return { 0xff, 81, 3, + (uint8) (microsecondsPerQuarterNote >> 16), + (uint8) (microsecondsPerQuarterNote >> 8), + (uint8) microsecondsPerQuarterNote }; } bool MidiMessage::isTimeSignatureMetaEvent() const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); return (data[1] == 0x58) && (*data == (uint8) 0xff); } @@ -815,7 +801,7 @@ void MidiMessage::getTimeSignatureInfo (int& numerator, int& denominator) const { if (isTimeSignatureMetaEvent()) { - const uint8* const d = getMetaEventData(); + auto d = getMetaEventData(); numerator = d[0]; denominator = 1 << d[1]; } @@ -837,14 +823,12 @@ MidiMessage MidiMessage::timeSignatureMetaEvent (const int numerator, const int ++powerOfTwo; } - const uint8 d[] = { 0xff, 0x58, 0x04, (uint8) numerator, (uint8) powerOfTwo, 1, 96 }; - return MidiMessage (d, 7, 0.0); + return { 0xff, 0x58, 0x04, numerator, powerOfTwo, 1, 96 }; } MidiMessage MidiMessage::midiChannelMetaEvent (const int channel) noexcept { - const uint8 d[] = { 0xff, 0x20, 0x01, (uint8) jlimit (0, 0xff, channel - 1) }; - return MidiMessage (d, 4, 0.0); + return { 0xff, 0x20, 0x01, jlimit (0, 0xff, channel - 1) }; } bool MidiMessage::isKeySignatureMetaEvent() const noexcept @@ -866,37 +850,36 @@ MidiMessage MidiMessage::keySignatureMetaEvent (int numberOfSharpsOrFlats, bool { jassert (numberOfSharpsOrFlats >= -7 && numberOfSharpsOrFlats <= 7); - const uint8 d[] = { 0xff, 0x59, 0x02, (uint8) numberOfSharpsOrFlats, isMinorKey ? (uint8) 1 : (uint8) 0 }; - return MidiMessage (d, 5, 0.0); + return { 0xff, 0x59, 0x02, numberOfSharpsOrFlats, isMinorKey ? 1 : 0 }; } MidiMessage MidiMessage::endOfTrack() noexcept { - return MidiMessage (0xff, 0x2f, 0, 0.0); + return { 0xff, 0x2f, 0x00 }; } //============================================================================== bool MidiMessage::isSongPositionPointer() const noexcept { return *getRawData() == 0xf2; } -int MidiMessage::getSongPositionPointerMidiBeat() const noexcept { const uint8* data = getRawData(); return data[1] | (data[2] << 7); } +int MidiMessage::getSongPositionPointerMidiBeat() const noexcept { auto data = getRawData(); return data[1] | (data[2] << 7); } MidiMessage MidiMessage::songPositionPointer (const int positionInMidiBeats) noexcept { - return MidiMessage (0xf2, - positionInMidiBeats & 127, - (positionInMidiBeats >> 7) & 127); + return { 0xf2, + positionInMidiBeats & 127, + (positionInMidiBeats >> 7) & 127 }; } -bool MidiMessage::isMidiStart() const noexcept { return *getRawData() == 0xfa; } -MidiMessage MidiMessage::midiStart() noexcept { return MidiMessage (0xfa); } +bool MidiMessage::isMidiStart() const noexcept { return *getRawData() == 0xfa; } +MidiMessage MidiMessage::midiStart() noexcept { return MidiMessage (0xfa); } -bool MidiMessage::isMidiContinue() const noexcept { return *getRawData() == 0xfb; } -MidiMessage MidiMessage::midiContinue() noexcept { return MidiMessage (0xfb); } +bool MidiMessage::isMidiContinue() const noexcept { return *getRawData() == 0xfb; } +MidiMessage MidiMessage::midiContinue() noexcept { return MidiMessage (0xfb); } -bool MidiMessage::isMidiStop() const noexcept { return *getRawData() == 0xfc; } -MidiMessage MidiMessage::midiStop() noexcept { return MidiMessage (0xfc); } +bool MidiMessage::isMidiStop() const noexcept { return *getRawData() == 0xfc; } +MidiMessage MidiMessage::midiStop() noexcept { return MidiMessage (0xfc); } -bool MidiMessage::isMidiClock() const noexcept { return *getRawData() == 0xf8; } -MidiMessage MidiMessage::midiClock() noexcept { return MidiMessage (0xf8); } +bool MidiMessage::isMidiClock() const noexcept { return *getRawData() == 0xf8; } +MidiMessage MidiMessage::midiClock() noexcept { return MidiMessage (0xf8); } bool MidiMessage::isQuarterFrame() const noexcept { return *getRawData() == 0xf1; } int MidiMessage::getQuarterFrameSequenceNumber() const noexcept { return ((int) getRawData()[1]) >> 4; } @@ -909,7 +892,7 @@ MidiMessage MidiMessage::quarterFrame (const int sequenceNumber, const int value bool MidiMessage::isFullFrame() const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); return data[0] == 0xf0 && data[1] == 0x7f @@ -923,7 +906,7 @@ void MidiMessage::getFullFrameParameters (int& hours, int& minutes, int& seconds { jassert (isFullFrame()); - const uint8* const data = getRawData(); + auto data = getRawData(); timecodeType = (SmpteTimecodeType) (data[5] >> 5); hours = data[5] & 0x1f; minutes = data[6]; @@ -931,23 +914,19 @@ void MidiMessage::getFullFrameParameters (int& hours, int& minutes, int& seconds frames = data[8]; } -MidiMessage MidiMessage::fullFrame (const int hours, const int minutes, - const int seconds, const int frames, +MidiMessage MidiMessage::fullFrame (int hours, int minutes, int seconds, int frames, MidiMessage::SmpteTimecodeType timecodeType) { - const uint8 d[] = { 0xf0, 0x7f, 0x7f, 0x01, 0x01, - (uint8) ((hours & 0x01f) | (timecodeType << 5)), - (uint8) minutes, - (uint8) seconds, - (uint8) frames, - 0xf7 }; - - return MidiMessage (d, 10, 0.0); + return { 0xf0, 0x7f, 0x7f, 0x01, 0x01, + (hours & 0x01f) | (timecodeType << 5), + minutes, seconds, frames, + 0xf7 }; } bool MidiMessage::isMidiMachineControlMessage() const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); + return data[0] == 0xf0 && data[1] == 0x7f && data[3] == 0x06 @@ -963,15 +942,14 @@ MidiMessage::MidiMachineControlCommand MidiMessage::getMidiMachineControlCommand MidiMessage MidiMessage::midiMachineControlCommand (MidiMessage::MidiMachineControlCommand command) { - const uint8 d[] = { 0xf0, 0x7f, 0, 6, (uint8) command, 0xf7 }; - - return MidiMessage (d, 6, 0.0); + return { 0xf0, 0x7f, 0, 6, command, 0xf7 }; } //============================================================================== bool MidiMessage::isMidiMachineControlGoto (int& hours, int& minutes, int& seconds, int& frames) const noexcept { - const uint8* const data = getRawData(); + auto data = getRawData(); + if (size >= 12 && data[0] == 0xf0 && data[1] == 0x7f @@ -993,14 +971,7 @@ bool MidiMessage::isMidiMachineControlGoto (int& hours, int& minutes, int& secon MidiMessage MidiMessage::midiMachineControlGoto (int hours, int minutes, int seconds, int frames) { - const uint8 d[] = { 0xf0, 0x7f, 0, 6, 0x44, 6, 1, - (uint8) hours, - (uint8) minutes, - (uint8) seconds, - (uint8) frames, - 0xf7 }; - - return MidiMessage (d, 12, 0.0); + return { 0xf0, 0x7f, 0, 6, 0x44, 6, 1, hours, minutes, seconds, frames, 0xf7 }; } //============================================================================== @@ -1020,7 +991,7 @@ String MidiMessage::getMidiNoteName (int note, bool useSharps, bool includeOctav return s; } - return String(); + return {}; } double MidiMessage::getMidiNoteInHertz (const int noteNumber, const double frequencyOfA) noexcept diff --git a/source/modules/juce_audio_basics/midi/juce_MidiMessage.h b/source/modules/juce_audio_basics/midi/juce_MidiMessage.h index d09115412..aea8d4207 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiMessage.h +++ b/source/modules/juce_audio_basics/midi/juce_MidiMessage.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIMESSAGE_H_INCLUDED -#define JUCE_MIDIMESSAGE_H_INCLUDED +#pragma once //============================================================================== @@ -69,6 +60,18 @@ public: */ MidiMessage (int byte1, double timeStamp = 0) noexcept; + /** Creates a midi message from a list of bytes. */ + template + MidiMessage (int byte1, int byte2, int byte3, Data... otherBytes) : size (3 + sizeof... (otherBytes)) + { + // this checks that the length matches the data.. + jassert (size > 3 || byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == size); + + const uint8 data[] = { (uint8) byte1, (uint8) byte2, (uint8) byte3, static_cast (otherBytes)... }; + memcpy (allocateSpace (size), data, (size_t) size); + } + + /** Creates a midi message from a block of data. */ MidiMessage (const void* data, int numBytes, double timeStamp = 0); @@ -115,10 +118,11 @@ public: /** Copies this message from another one. */ MidiMessage& operator= (const MidiMessage& other); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ MidiMessage (MidiMessage&&) noexcept; + + /** Move assignment operator */ MidiMessage& operator= (MidiMessage&&) noexcept; - #endif //============================================================================== /** Returns a pointer to the raw midi data. @@ -473,7 +477,6 @@ public: bool isControllerOfType (int controllerType) const noexcept; /** Creates a controller message. - @param channel the midi channel, in the range 1 to 16 @param controllerType the type of controller @param value the controller value @@ -494,21 +497,18 @@ public: bool isAllSoundOff() const noexcept; /** Creates an all-notes-off message. - @param channel the midi channel, in the range 1 to 16 @see isAllNotesOff */ static MidiMessage allNotesOff (int channel) noexcept; /** Creates an all-sound-off message. - @param channel the midi channel, in the range 1 to 16 @see isAllSoundOff */ static MidiMessage allSoundOff (int channel) noexcept; /** Creates an all-controllers-off message. - @param channel the midi channel, in the range 1 to 16 */ static MidiMessage allControllersOff (int channel) noexcept; @@ -928,7 +928,7 @@ private: }; PackedData packedData; - double timeStamp; + double timeStamp = 0; int size; #endif @@ -936,5 +936,3 @@ private: inline uint8* getData() const noexcept { return isHeapAllocated() ? packedData.allocatedData : (uint8*) packedData.asBytes; } uint8* allocateSpace (int); }; - -#endif // JUCE_MIDIMESSAGE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp b/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp index 2de57df3c..6a3f851cb 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp +++ b/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.cpp @@ -2,32 +2,30 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ + +MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm) : message (mm) {} +MidiMessageSequence::MidiEventHolder::MidiEventHolder (MidiMessage&& mm) : message (static_cast (mm)) {} +MidiMessageSequence::MidiEventHolder::~MidiEventHolder() {} + +//============================================================================== MidiMessageSequence::MidiMessageSequence() { } @@ -45,15 +43,25 @@ MidiMessageSequence& MidiMessageSequence::operator= (const MidiMessageSequence& return *this; } -void MidiMessageSequence::swapWith (MidiMessageSequence& other) noexcept +MidiMessageSequence::MidiMessageSequence (MidiMessageSequence&& other) noexcept + : list (static_cast&&> (other.list)) +{} + +MidiMessageSequence& MidiMessageSequence::operator= (MidiMessageSequence&& other) noexcept { - list.swapWith (other.list); + list = static_cast&&> (other.list); + return *this; } MidiMessageSequence::~MidiMessageSequence() { } +void MidiMessageSequence::swapWith (MidiMessageSequence& other) noexcept +{ + list.swapWith (other.list); +} + void MidiMessageSequence::clear() { list.clear(); @@ -64,34 +72,37 @@ int MidiMessageSequence::getNumEvents() const noexcept return list.size(); } -MidiMessageSequence::MidiEventHolder* MidiMessageSequence::getEventPointer (const int index) const noexcept +MidiMessageSequence::MidiEventHolder* MidiMessageSequence::getEventPointer (int index) const noexcept { - return list [index]; + return list[index]; } -double MidiMessageSequence::getTimeOfMatchingKeyUp (const int index) const noexcept +MidiMessageSequence::MidiEventHolder** MidiMessageSequence::begin() const noexcept { return list.begin(); } +MidiMessageSequence::MidiEventHolder** MidiMessageSequence::end() const noexcept { return list.end(); } + +double MidiMessageSequence::getTimeOfMatchingKeyUp (int index) const noexcept { - if (const MidiEventHolder* const meh = list [index]) + if (auto* meh = list[index]) if (meh->noteOffObject != nullptr) return meh->noteOffObject->message.getTimeStamp(); return 0.0; } -int MidiMessageSequence::getIndexOfMatchingKeyUp (const int index) const noexcept +int MidiMessageSequence::getIndexOfMatchingKeyUp (int index) const noexcept { - if (const MidiEventHolder* const meh = list [index]) + if (auto* meh = list [index]) return list.indexOf (meh->noteOffObject); return -1; } -int MidiMessageSequence::getIndexOf (const MidiEventHolder* const event) const noexcept +int MidiMessageSequence::getIndexOf (const MidiEventHolder* event) const noexcept { return list.indexOf (event); } -int MidiMessageSequence::getNextIndexAtTime (const double timeStamp) const noexcept +int MidiMessageSequence::getNextIndexAtTime (double timeStamp) const noexcept { const int numEvents = list.size(); @@ -116,32 +127,38 @@ double MidiMessageSequence::getEndTime() const noexcept double MidiMessageSequence::getEventTime (const int index) const noexcept { - if (const MidiEventHolder* const meh = list [index]) + if (auto* meh = list [index]) return meh->message.getTimeStamp(); return 0.0; } //============================================================================== -MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (const MidiMessage& newMessage, - double timeAdjustment) +MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (MidiEventHolder* newEvent, double timeAdjustment) { - MidiEventHolder* const newOne = new MidiEventHolder (newMessage); - - timeAdjustment += newMessage.getTimeStamp(); - newOne->message.setTimeStamp (timeAdjustment); + newEvent->message.addToTimeStamp (timeAdjustment); + auto time = newEvent->message.getTimeStamp(); int i; for (i = list.size(); --i >= 0;) - if (list.getUnchecked(i)->message.getTimeStamp() <= timeAdjustment) + if (list.getUnchecked(i)->message.getTimeStamp() <= time) break; - list.insert (i + 1, newOne); - return newOne; + list.insert (i + 1, newEvent); + return newEvent; +} + +MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (const MidiMessage& newMessage, double timeAdjustment) +{ + return addEvent (new MidiEventHolder (newMessage), timeAdjustment); +} + +MidiMessageSequence::MidiEventHolder* MidiMessageSequence::addEvent (MidiMessage&& newMessage, double timeAdjustment) +{ + return addEvent (new MidiEventHolder (static_cast (newMessage)), timeAdjustment); } -void MidiMessageSequence::deleteEvent (const int index, - const bool deleteMatchingNoteUp) +void MidiMessageSequence::deleteEvent (int index, bool deleteMatchingNoteUp) { if (isPositiveAndBelow (index, list.size())) { @@ -152,23 +169,11 @@ void MidiMessageSequence::deleteEvent (const int index, } } -struct MidiMessageSequenceSorter -{ - static int compareElements (const MidiMessageSequence::MidiEventHolder* const first, - const MidiMessageSequence::MidiEventHolder* const second) noexcept - { - const double diff = first->message.getTimeStamp() - second->message.getTimeStamp(); - return (diff > 0) - (diff < 0); - } -}; - void MidiMessageSequence::addSequence (const MidiMessageSequence& other, double timeAdjustment) { - for (int i = 0; i < other.list.size(); ++i) + for (auto* m : other) { - const MidiMessage& m = other.list.getUnchecked(i)->message; - - MidiEventHolder* const newOne = new MidiEventHolder (m); + auto newOne = new MidiEventHolder (m->message); newOne->message.addToTimeStamp (timeAdjustment); list.add (newOne); } @@ -181,16 +186,14 @@ void MidiMessageSequence::addSequence (const MidiMessageSequence& other, double firstAllowableTime, double endOfAllowableDestTimes) { - for (int i = 0; i < other.list.size(); ++i) + for (auto* m : other) { - const MidiMessage& m = other.list.getUnchecked(i)->message; - const double t = m.getTimeStamp() + timeAdjustment; + auto t = m->message.getTimeStamp() + timeAdjustment; if (t >= firstAllowableTime && t < endOfAllowableDestTimes) { - MidiEventHolder* const newOne = new MidiEventHolder (m); + auto newOne = new MidiEventHolder (m->message); newOne->message.setTimeStamp (t); - list.add (newOne); } } @@ -198,7 +201,16 @@ void MidiMessageSequence::addSequence (const MidiMessageSequence& other, sort(); } -//============================================================================== +struct MidiMessageSequenceSorter +{ + static int compareElements (const MidiMessageSequence::MidiEventHolder* first, + const MidiMessageSequence::MidiEventHolder* second) noexcept + { + auto diff = first->message.getTimeStamp() - second->message.getTimeStamp(); + return (diff > 0) - (diff < 0); + } +}; + void MidiMessageSequence::sort() noexcept { MidiMessageSequenceSorter sorter; @@ -209,30 +221,32 @@ void MidiMessageSequence::updateMatchedPairs() noexcept { for (int i = 0; i < list.size(); ++i) { - MidiEventHolder* const meh = list.getUnchecked(i); - const MidiMessage& m1 = meh->message; + auto* meh = list.getUnchecked(i); + auto& m1 = meh->message; if (m1.isNoteOn()) { meh->noteOffObject = nullptr; - const int note = m1.getNoteNumber(); - const int chan = m1.getChannel(); - const int len = list.size(); + auto note = m1.getNoteNumber(); + auto chan = m1.getChannel(); + auto len = list.size(); for (int j = i + 1; j < len; ++j) { - const MidiMessage& m = list.getUnchecked(j)->message; + auto* meh2 = list.getUnchecked(j); + auto& m = meh2->message; if (m.getNoteNumber() == note && m.getChannel() == chan) { if (m.isNoteOff()) { - meh->noteOffObject = list[j]; + meh->noteOffObject = meh2; break; } - else if (m.isNoteOn()) + + if (m.isNoteOn()) { - MidiEventHolder* const newEvent = new MidiEventHolder (MidiMessage::noteOff (chan, note)); + auto newEvent = new MidiEventHolder (MidiMessage::noteOff (chan, note)); list.insert (j, newEvent); newEvent->message.setTimeStamp (m.getTimeStamp()); meh->noteOffObject = newEvent; @@ -244,13 +258,11 @@ void MidiMessageSequence::updateMatchedPairs() noexcept } } -void MidiMessageSequence::addTimeToMessages (const double delta) noexcept +void MidiMessageSequence::addTimeToMessages (double delta) noexcept { - for (int i = list.size(); --i >= 0;) - { - MidiMessage& mm = list.getUnchecked(i)->message; - mm.setTimeStamp (mm.getTimeStamp() + delta); - } + if (delta != 0) + for (auto* m : list) + m->message.addToTimeStamp (delta); } //============================================================================== @@ -258,24 +270,17 @@ void MidiMessageSequence::extractMidiChannelMessages (const int channelNumberToE MidiMessageSequence& destSequence, const bool alsoIncludeMetaEvents) const { - for (int i = 0; i < list.size(); ++i) - { - const MidiMessage& mm = list.getUnchecked(i)->message; - - if (mm.isForChannel (channelNumberToExtract) || (alsoIncludeMetaEvents && mm.isMetaEvent())) - destSequence.addEvent (mm); - } + for (auto* meh : list) + if (meh->message.isForChannel (channelNumberToExtract) + || (alsoIncludeMetaEvents && meh->message.isMetaEvent())) + destSequence.addEvent (meh->message); } void MidiMessageSequence::extractSysExMessages (MidiMessageSequence& destSequence) const { - for (int i = 0; i < list.size(); ++i) - { - const MidiMessage& mm = list.getUnchecked(i)->message; - - if (mm.isSysEx()) - destSequence.addEvent (mm); - } + for (auto* meh : list) + if (meh->message.isSysEx()) + destSequence.addEvent (meh->message); } void MidiMessageSequence::deleteMidiChannelMessages (const int channelNumberToRemove) @@ -293,15 +298,15 @@ void MidiMessageSequence::deleteSysExMessages() } //============================================================================== -void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumber, const double time, Array& dest) +void MidiMessageSequence::createControllerUpdatesForTime (int channelNumber, double time, Array& dest) { bool doneProg = false; bool donePitchWheel = false; - bool doneControllers[128] = { 0 }; + bool doneControllers[128] = {}; for (int i = list.size(); --i >= 0;) { - const MidiMessage& mm = list.getUnchecked(i)->message; + auto& mm = list.getUnchecked(i)->message; if (mm.isForChannel (channelNumber) && mm.getTimeStamp() <= time) { @@ -329,14 +334,3 @@ void MidiMessageSequence::createControllerUpdatesForTime (const int channelNumbe } } } - - -//============================================================================== -MidiMessageSequence::MidiEventHolder::MidiEventHolder (const MidiMessage& mm) - : message (mm), noteOffObject (nullptr) -{ -} - -MidiMessageSequence::MidiEventHolder::~MidiEventHolder() -{ -} diff --git a/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h b/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h index 92e38db88..916431b98 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h +++ b/source/modules/juce_audio_basics/midi/juce_MidiMessageSequence.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIMESSAGESEQUENCE_H_INCLUDED -#define JUCE_MIDIMESSAGESEQUENCE_H_INCLUDED +#pragma once //============================================================================== @@ -54,17 +45,11 @@ public: /** Replaces this sequence with another one. */ MidiMessageSequence& operator= (const MidiMessageSequence&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - MidiMessageSequence (MidiMessageSequence&& other) noexcept - : list (static_cast&&> (other.list)) - {} + /** Move constructor */ + MidiMessageSequence (MidiMessageSequence&&) noexcept; - MidiMessageSequence& operator= (MidiMessageSequence&& other) noexcept - { - list = static_cast&&> (other.list); - return *this; - } - #endif + /** Move assignment operator */ + MidiMessageSequence& operator= (MidiMessageSequence&&) noexcept; /** Destructor. */ ~MidiMessageSequence(); @@ -95,12 +80,13 @@ public: note-offs up-to-date after events have been moved around in the sequence or deleted. */ - MidiEventHolder* noteOffObject; + MidiEventHolder* noteOffObject = nullptr; private: //============================================================================== friend class MidiMessageSequence; MidiEventHolder (const MidiMessage&); + MidiEventHolder (MidiMessage&&); JUCE_LEAK_DETECTOR (MidiEventHolder) }; @@ -114,6 +100,12 @@ public: /** Returns a pointer to one of the events. */ MidiEventHolder* getEventPointer (int index) const noexcept; + /** Iterator for the list of MidiEventHolders */ + MidiEventHolder** begin() const noexcept; + + /** Iterator for the list of MidiEventHolders */ + MidiEventHolder** end() const noexcept; + /** Returns the time of the note-up that matches the note-on at this index. If the event at this index isn't a note-on, it'll just return 0. @see MidiMessageSequence::MidiEventHolder::noteOffObject @@ -164,8 +156,21 @@ public: that will be inserted @see updateMatchedPairs */ - MidiEventHolder* addEvent (const MidiMessage& newMessage, - double timeAdjustment = 0); + MidiEventHolder* addEvent (const MidiMessage& newMessage, double timeAdjustment = 0); + + /** Inserts a midi message into the sequence. + + The index at which the new message gets inserted will depend on its timestamp, + because the sequence is kept sorted. + + Remember to call updateMatchedPairs() after adding note-on events. + + @param newMessage the new message to add (an internal copy will be made) + @param timeAdjustment an optional value to add to the timestamp of the message + that will be inserted + @see updateMatchedPairs + */ + MidiEventHolder* addEvent (MidiMessage&& newMessage, double timeAdjustment = 0); /** Deletes one of the events in the sequence. @@ -285,8 +290,7 @@ private: friend class MidiFile; OwnedArray list; + MidiEventHolder* addEvent (MidiEventHolder*, double); + JUCE_LEAK_DETECTOR (MidiMessageSequence) }; - - -#endif // JUCE_MIDIMESSAGESEQUENCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/midi/juce_MidiRPN.cpp b/source/modules/juce_audio_basics/midi/juce_MidiRPN.cpp index 53cc15d31..a5189566c 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiRPN.cpp +++ b/source/modules/juce_audio_basics/midi/juce_MidiRPN.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -171,7 +163,7 @@ MidiBuffer MidiRPNGenerator::generate (int midiChannel, class MidiRPNDetectorTests : public UnitTest { public: - MidiRPNDetectorTests() : UnitTest ("MidiRPNDetector class") {} + MidiRPNDetectorTests() : UnitTest ("MidiRPNDetector class", "MIDI/MPE") {} void runTest() override { @@ -313,7 +305,7 @@ static MidiRPNDetectorTests MidiRPNDetectorUnitTests; class MidiRPNGeneratorTests : public UnitTest { public: - MidiRPNGeneratorTests() : UnitTest ("MidiRPNGenerator class") {} + MidiRPNGeneratorTests() : UnitTest ("MidiRPNGenerator class", "MIDI/MPE") {} void runTest() override { @@ -369,7 +361,7 @@ private: expectEquals (result.channel, expected.channel); expectEquals (result.parameterNumber, expected.parameterNumber); expectEquals (result.value, expected.value); - expect (result.isNRPN == expected.isNRPN), + expect (result.isNRPN == expected.isNRPN); expect (result.is14BitValue == expected.is14BitValue); } }; diff --git a/source/modules/juce_audio_basics/midi/juce_MidiRPN.h b/source/modules/juce_audio_basics/midi/juce_MidiRPN.h index d6447c064..53219c1f9 100644 --- a/source/modules/juce_audio_basics/midi/juce_MidiRPN.h +++ b/source/modules/juce_audio_basics/midi/juce_MidiRPN.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIRPNDETECTOR_H_INCLUDED -#define JUCE_MIDIRPNDETECTOR_H_INCLUDED +#pragma once //============================================================================== @@ -153,6 +144,3 @@ public: bool isNRPN = false, bool use14BitValue = true); }; - - -#endif // JUCE_MIDIRPNDETECTOR_H_INCLUDED diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp b/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp index 93e2c357d..70aee29fd 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp +++ b/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -703,7 +695,7 @@ class MPEInstrumentTests : public UnitTest { public: MPEInstrumentTests() - : UnitTest ("MPEInstrument class") + : UnitTest ("MPEInstrument class", "MIDI/MPE") { // using two MPE zones with the following layout for testing // diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.h b/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.h index 037ebaae7..8fe26ae91 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.h +++ b/source/modules/juce_audio_basics/mpe/juce_MPEInstrument.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MPEINSTRUMENT_H_INCLUDED -#define JUCE_MPEINSTRUMENT_H_INCLUDED +#pragma once //============================================================================== @@ -383,6 +374,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPEInstrument) }; - - -#endif // JUCE_MPE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp b/source/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp index b8d64c4cf..09939a104 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp +++ b/source/modules/juce_audio_basics/mpe/juce_MPEMessages.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -79,7 +71,7 @@ MidiBuffer MPEMessages::setZoneLayout (const MPEZoneLayout& layout) class MPEMessagesTests : public UnitTest { public: - MPEMessagesTests() : UnitTest ("MPEMessages class") {} + MPEMessagesTests() : UnitTest ("MPEMessages class", "MIDI/MPE") {} void runTest() override { diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEMessages.h b/source/modules/juce_audio_basics/mpe/juce_MPEMessages.h index d8e27d84e..87b12f09d 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEMessages.h +++ b/source/modules/juce_audio_basics/mpe/juce_MPEMessages.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MPEMESSAGES_H_INCLUDED -#define JUCE_MPEMESSAGES_H_INCLUDED +#pragma once //============================================================================== @@ -96,7 +87,3 @@ public: */ static const int zoneLayoutMessagesRpnNumber = 6; }; - - - -#endif // JUCE_MPEMESSAGES_H_INCLUDED diff --git a/source/modules/juce_audio_basics/mpe/juce_MPENote.cpp b/source/modules/juce_audio_basics/mpe/juce_MPENote.cpp index a1fcbbcef..1f47cec02 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPENote.cpp +++ b/source/modules/juce_audio_basics/mpe/juce_MPENote.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -107,7 +99,7 @@ bool MPENote::operator!= (const MPENote& other) const noexcept class MPENoteTests : public UnitTest { public: - MPENoteTests() : UnitTest ("MPENote class") {} + MPENoteTests() : UnitTest ("MPENote class", "MIDI/MPE") {} //============================================================================== void runTest() override diff --git a/source/modules/juce_audio_basics/mpe/juce_MPENote.h b/source/modules/juce_audio_basics/mpe/juce_MPENote.h index 26bf42a25..874a03f3e 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPENote.h +++ b/source/modules/juce_audio_basics/mpe/juce_MPENote.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MPENOTE_H_INCLUDED -#define JUCE_MPENOTE_H_INCLUDED +#pragma once //============================================================================== @@ -181,6 +172,3 @@ struct JUCE_API MPENote /** Returns true if two notes are different notes, determined by their unique ID. */ bool operator!= (const MPENote& other) const noexcept; }; - - -#endif // JUCE_MPENOTE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp index 74730f250..3e965f434 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp +++ b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -32,7 +24,7 @@ MPESynthesiser::MPESynthesiser() { } -MPESynthesiser::MPESynthesiser (MPEInstrument* instrument) : MPESynthesiserBase (instrument) +MPESynthesiser::MPESynthesiser (MPEInstrument* mpeInstrument) : MPESynthesiserBase (mpeInstrument) { } diff --git a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h index 90108eb18..73dcc9772 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h +++ b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiser.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MPESynthesiser_H_INCLUDED -#define JUCE_MPESynthesiser_H_INCLUDED +#pragma once //============================================================================== @@ -314,6 +305,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiser) }; - - -#endif // JUCE_MPESynthesiser_H_INCLUDED diff --git a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp index a2ba5892f..671249a30 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp +++ b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h index e485ccf1c..649abc884 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h +++ b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserBase.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MPESynthesiserBase_H_INCLUDED -#define JUCE_MPESynthesiserBase_H_INCLUDED +#pragma once //============================================================================== @@ -213,6 +204,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserBase) }; - - -#endif // JUCE_MPESynthesiserBase_H_INCLUDED diff --git a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp index 3e2108bad..cdd35cfc0 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp +++ b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h index f03e8f8f7..9f8205e63 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h +++ b/source/modules/juce_audio_basics/mpe/juce_MPESynthesiserVoice.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MPEVoice_H_INCLUDED -#define JUCE_MPEVoice_H_INCLUDED +#pragma once //============================================================================== /** @@ -192,6 +183,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MPESynthesiserVoice) }; - - -#endif // JUCE_MPEVoice_H_INCLUDED diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEValue.cpp b/source/modules/juce_audio_basics/mpe/juce_MPEValue.cpp index 54af0a16b..941305754 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEValue.cpp +++ b/source/modules/juce_audio_basics/mpe/juce_MPEValue.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -97,7 +89,7 @@ bool MPEValue::operator!= (const MPEValue& other) const noexcept class MPEValueTests : public UnitTest { public: - MPEValueTests() : UnitTest ("MPEValue class") {} + MPEValueTests() : UnitTest ("MPEValue class", "MIDI/MPE") {} void runTest() override { diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEValue.h b/source/modules/juce_audio_basics/mpe/juce_MPEValue.h index 540de65c8..574341005 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEValue.h +++ b/source/modules/juce_audio_basics/mpe/juce_MPEValue.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MPEVALUE_H_INCLUDED -#define JUCE_MPEVALUE_H_INCLUDED +#pragma once //============================================================================== @@ -97,6 +88,3 @@ private: MPEValue (int normalisedValue); int normalisedValue; }; - - -#endif // JUCE_MPEVALUE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEZone.cpp b/source/modules/juce_audio_basics/mpe/juce_MPEZone.cpp index 4d661bea0..912a86c3c 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEZone.cpp +++ b/source/modules/juce_audio_basics/mpe/juce_MPEZone.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -171,7 +163,7 @@ bool MPEZone::operator!= (const MPEZone& other) const noexcept class MPEZoneTests : public UnitTest { public: - MPEZoneTests() : UnitTest ("MPEZone class") {} + MPEZoneTests() : UnitTest ("MPEZone class", "MIDI/MPE") {} void runTest() override { diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEZone.h b/source/modules/juce_audio_basics/mpe/juce_MPEZone.h index 6daac1001..9fdfb5548 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEZone.h +++ b/source/modules/juce_audio_basics/mpe/juce_MPEZone.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MPEZONE_H_INCLUDED -#define JUCE_MPEZONE_H_INCLUDED +#pragma once //============================================================================== @@ -147,6 +138,3 @@ private: int perNotePitchbendRange; int masterPitchbendRange; }; - - -#endif // JUCE_MPEZONE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp b/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp index e2eb5b84d..450dc09f6 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp +++ b/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -212,7 +204,7 @@ void MPEZoneLayout::removeListener (Listener* const listenerToRemove) noexcept class MPEZoneLayoutTests : public UnitTest { public: - MPEZoneLayoutTests() : UnitTest ("MPEZoneLayout class") {} + MPEZoneLayoutTests() : UnitTest ("MPEZoneLayout class", "MIDI/MPE") {} void runTest() override { diff --git a/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h b/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h index 40bfdeaad..0b08eb561 100644 --- a/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h +++ b/source/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MPEZONELAYOUT_H_INCLUDED -#define JUCE_MPEZONELAYOUT_H_INCLUDED +#pragma once //============================================================================== @@ -166,6 +157,3 @@ private: void processZoneLayoutRpnMessage (MidiRPNMessage); void processPitchbendRangeRpnMessage (MidiRPNMessage); }; - - -#endif // JUCE_MPEZONELAYOUT_H_INCLUDED diff --git a/source/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h b/source/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h new file mode 100644 index 000000000..d6b95326e --- /dev/null +++ b/source/modules/juce_audio_basics/native/juce_mac_CoreAudioLayouts.h @@ -0,0 +1,307 @@ +/* + ============================================================================== + + 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. + + The code included in this file is provided 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. + + 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 + +#if JUCE_MAC || JUCE_IOS + +struct CoreAudioLayouts +{ + //============================================================================== + /** Convert CoreAudio's native AudioChannelLayout to JUCE's AudioChannelSet. + + Note that this method cannot preserve the order of channels. + */ + static AudioChannelSet fromCoreAudio (const AudioChannelLayout& layout) + { + return AudioChannelSet::channelSetWithChannels (getCoreAudioLayoutChannels (layout)); + } + + /** Convert JUCE's AudioChannelSet to CoreAudio's AudioChannelLayoutTag. + + Note that this method cannot preserve the order of channels. + */ + static AudioChannelLayoutTag toCoreAudio (const AudioChannelSet& set) + { + for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl) + { + AudioChannelSet caSet; + + for (int i = 0; i < numElementsInArray (tbl->channelTypes) + && tbl->channelTypes[i] != AudioChannelSet::unknown; ++i) + caSet.addChannel (tbl->channelTypes[i]); + + if (caSet == set) + return tbl->tag; + } + + return kAudioChannelLayoutTag_DiscreteInOrder | static_cast (set.size()); + } + + static const Array& getKnownCoreAudioTags() + { + static Array tags (createKnownCoreAudioTags()); + return tags; + } + + //============================================================================== + /** Convert CoreAudio's native AudioChannelLayout to an array of JUCE ChannelTypes. */ + static Array getCoreAudioLayoutChannels (const AudioChannelLayout& layout) + { + switch (layout.mChannelLayoutTag) + { + case kAudioChannelLayoutTag_UseChannelBitmap: + return AudioChannelSet::fromWaveChannelMask (static_cast (layout.mChannelBitmap)).getChannelTypes(); + case kAudioChannelLayoutTag_UseChannelDescriptions: + { + Array channels; + + for (UInt32 i = 0; i < layout.mNumberChannelDescriptions; ++i) + channels.addIfNotAlreadyThere (getChannelTypeFromAudioChannelLabel (layout.mChannelDescriptions[i].mChannelLabel)); + + // different speaker mappings may point to the same JUCE speaker so fill up + // this array with discrete channels + for (int j = 0; channels.size() < static_cast (layout.mNumberChannelDescriptions); ++j) + channels.addIfNotAlreadyThere (static_cast (AudioChannelSet::discreteChannel0 + j)); + + return channels; + } + case kAudioChannelLayoutTag_DiscreteInOrder: + return AudioChannelSet::discreteChannels (static_cast (layout.mChannelLayoutTag) & 0xffff).getChannelTypes(); + default: + break; + } + + return getSpeakerLayoutForCoreAudioTag (layout.mChannelLayoutTag); + } + + //============================================================================== + /* Convert between a CoreAudio and JUCE channel indices - and vice versa. */ + // TODO: Fabian remove this +// static int convertChannelIndex (const AudioChannelLayout& caLayout, const AudioChannelSet& juceLayout, int index, bool fromJUCE) +// { +// auto coreAudioChannels = getCoreAudioLayoutChannels (caLayout); +// +// jassert (juceLayout.size() == coreAudioChannels.size()); +// jassert (index >= 0 && index < juceLayout.size()); +// +// return (fromJUCE ? coreAudioChannels.indexOf (juceLayout.getTypeOfChannel (index)) +// : juceLayout.getChannelIndexForType (coreAudioChannels.getReference (index))); +// } + +private: + //============================================================================== + struct LayoutTagSpeakerList + { + AudioChannelLayoutTag tag; + AudioChannelSet::ChannelType channelTypes[16]; + }; + + static Array getSpeakerLayoutForCoreAudioTag (AudioChannelLayoutTag tag) + { + Array speakers; + + for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl) + { + if (tag == tbl->tag) + { + for (int i = 0; i < numElementsInArray (tbl->channelTypes) + && tbl->channelTypes[i] != AudioChannelSet::unknown; ++i) + speakers.add (tbl->channelTypes[i]); + + return speakers; + } + } + + auto numChannels = tag & 0xffff; + for (UInt32 i = 0; i < numChannels; ++i) + speakers.add (static_cast (AudioChannelSet::discreteChannel0 + i)); + + return speakers; + } + + static Array createKnownCoreAudioTags() + { + Array tags; + + for (auto* tbl = SpeakerLayoutTable::get(); tbl->tag != 0; ++tbl) + tags.addIfNotAlreadyThere (tbl->tag); + + return tags; + } + + //============================================================================== + // This list has been derived from https://pastebin.com/24dQ4BPJ + // Apple channel labels have been replaced by JUCE channel names + // This means that some layouts will be identical in JUCE but not in CoreAudio + + // In Apple's official definition the following tags exist with the same speaker layout and order + // even when *not* represented in JUCE channels + // kAudioChannelLayoutTag_Binaural = kAudioChannelLayoutTag_Stereo + // kAudioChannelLayoutTag_MPEG_5_0_B = kAudioChannelLayoutTag_Pentagonal + // kAudioChannelLayoutTag_ITU_2_2 = kAudioChannelLayoutTag_Quadraphonic + // kAudioChannelLayoutTag_AudioUnit_6_0 = kAudioChannelLayoutTag_Hexagonal + struct SpeakerLayoutTable : AudioChannelSet // save us some typing + { + static LayoutTagSpeakerList* get() noexcept + { + static LayoutTagSpeakerList tbl[] = { + // list layouts for which there is a corresponding named AudioChannelSet first + { kAudioChannelLayoutTag_Mono, { centre } }, + { kAudioChannelLayoutTag_Stereo, { left, right } }, + { kAudioChannelLayoutTag_MPEG_3_0_A, { left, right, centre } }, + { kAudioChannelLayoutTag_ITU_2_1, { left, right, centreSurround } }, + { kAudioChannelLayoutTag_MPEG_4_0_A, { left, right, centre, centreSurround } }, + { kAudioChannelLayoutTag_MPEG_5_0_A, { left, right, centre, leftSurround, rightSurround } }, + { kAudioChannelLayoutTag_MPEG_5_1_A, { left, right, centre, LFE, leftSurround, rightSurround } }, + { kAudioChannelLayoutTag_AudioUnit_6_0, { left, right, leftSurround, rightSurround, centre, centreSurround } }, + { kAudioChannelLayoutTag_MPEG_6_1_A, { left, right, centre, LFE, leftSurround, rightSurround, centreSurround } }, + { kAudioChannelLayoutTag_DTS_6_0_A, { leftSurroundSide, rightSurroundSide, left, right, leftSurround, rightSurround } }, + { kAudioChannelLayoutTag_DTS_6_1_A, { leftSurroundSide, rightSurroundSide, left, right, leftSurround, rightSurround, LFE } }, + { kAudioChannelLayoutTag_AudioUnit_7_0, { left, right, leftSurroundSide, rightSurroundSide, centre, leftSurroundRear, rightSurroundRear } }, + { kAudioChannelLayoutTag_AudioUnit_7_0_Front, { left, right, leftSurround, rightSurround, centre, leftCentre, rightCentre } }, + { kAudioChannelLayoutTag_MPEG_7_1_C, { left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear } }, + { kAudioChannelLayoutTag_MPEG_7_1_A, { left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre } }, + { kAudioChannelLayoutTag_Ambisonic_B_Format, { ambisonicW, ambisonicX, ambisonicY, ambisonicZ } }, + { kAudioChannelLayoutTag_Quadraphonic, { left, right, leftSurround, rightSurround } }, + { kAudioChannelLayoutTag_Pentagonal, { left, right, leftSurroundRear, rightSurroundRear, centre } }, + { kAudioChannelLayoutTag_Hexagonal, { left, right, leftSurroundRear, rightSurroundRear, centre, centreSurround } }, + { kAudioChannelLayoutTag_Octagonal, { left, right, leftSurround, rightSurround, centre, centreSurround, wideLeft, wideRight } }, + + // more uncommon layouts + { kAudioChannelLayoutTag_StereoHeadphones, { left, right } }, + { kAudioChannelLayoutTag_MatrixStereo, { left, right } }, + { kAudioChannelLayoutTag_MidSide, { centre, discreteChannel0 } }, + { kAudioChannelLayoutTag_XY, { ambisonicX, ambisonicY } }, + { kAudioChannelLayoutTag_Binaural, { left, right } }, + { kAudioChannelLayoutTag_Cube, { left, right, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight } }, + { kAudioChannelLayoutTag_MPEG_3_0_B, { centre, left, right } }, + { kAudioChannelLayoutTag_MPEG_4_0_B, { centre, left, right, centreSurround } }, + { kAudioChannelLayoutTag_MPEG_5_0_B, { left, right, leftSurround, rightSurround, centre } }, + { kAudioChannelLayoutTag_MPEG_5_0_C, { left, centre, right, leftSurround, rightSurround } }, + { kAudioChannelLayoutTag_MPEG_5_0_D, { centre, left, right, leftSurround, rightSurround } }, + { kAudioChannelLayoutTag_MPEG_5_1_B, { left, right, leftSurround, rightSurround, centre, LFE } }, + { kAudioChannelLayoutTag_MPEG_5_1_C, { left, centre, right, leftSurround, rightSurround, LFE } }, + { kAudioChannelLayoutTag_MPEG_5_1_D, { centre, left, right, leftSurround, rightSurround, LFE } }, + { kAudioChannelLayoutTag_MPEG_7_1_B, { centre, leftCentre, rightCentre, left, right, leftSurround, rightSurround, LFE } }, + { kAudioChannelLayoutTag_Emagic_Default_7_1, { left, right, leftSurround, rightSurround, centre, LFE, leftCentre, rightCentre } }, + { kAudioChannelLayoutTag_SMPTE_DTV, { left, right, centre, LFE, leftSurround, rightSurround, discreteChannel0 /* leftMatrixTotal */, (ChannelType) (discreteChannel0 + 1) /* rightMatrixTotal */} }, + { kAudioChannelLayoutTag_ITU_2_2, { left, right, leftSurround, rightSurround } }, + { kAudioChannelLayoutTag_DVD_4, { left, right, LFE } }, + { kAudioChannelLayoutTag_DVD_5, { left, right, LFE, centreSurround } }, + { kAudioChannelLayoutTag_DVD_6, { left, right, LFE, leftSurround, rightSurround } }, + { kAudioChannelLayoutTag_DVD_10, { left, right, centre, LFE } }, + { kAudioChannelLayoutTag_DVD_11, { left, right, centre, LFE, centreSurround } }, + { kAudioChannelLayoutTag_DVD_18, { left, right, leftSurround, rightSurround, LFE } }, + { kAudioChannelLayoutTag_AAC_6_0, { centre, left, right, leftSurround, rightSurround, centreSurround } }, + { kAudioChannelLayoutTag_AAC_6_1, { centre, left, right, leftSurround, rightSurround, centreSurround, LFE } }, + { kAudioChannelLayoutTag_AAC_7_0, { centre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear } }, + { kAudioChannelLayoutTag_AAC_7_1_B, { centre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, LFE } }, + { kAudioChannelLayoutTag_AAC_7_1_C, { centre, left, right, leftSurround, rightSurround, LFE, topFrontLeft, topFrontRight } }, + { kAudioChannelLayoutTag_AAC_Octagonal, { centre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, centreSurround } }, + { kAudioChannelLayoutTag_TMH_10_2_std, { left, right, centre, topFrontCentre, leftSurroundSide, rightSurroundSide, leftSurround, rightSurround, topFrontLeft, topFrontRight, wideLeft, wideRight, topRearCentre, centreSurround, LFE, LFE2 } }, + { kAudioChannelLayoutTag_AC3_1_0_1, { centre, LFE } }, + { kAudioChannelLayoutTag_AC3_3_0, { left, centre, right } }, + { kAudioChannelLayoutTag_AC3_3_1, { left, centre, right, centreSurround } }, + { kAudioChannelLayoutTag_AC3_3_0_1, { left, centre, right, LFE } }, + { kAudioChannelLayoutTag_AC3_2_1_1, { left, right, centreSurround, LFE } }, + { kAudioChannelLayoutTag_AC3_3_1_1, { left, centre, right, centreSurround, LFE } }, + { kAudioChannelLayoutTag_EAC_6_0_A, { left, centre, right, leftSurround, rightSurround, centreSurround } }, + { kAudioChannelLayoutTag_EAC_7_0_A, { left, centre, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear } }, + { kAudioChannelLayoutTag_EAC3_6_1_A, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround } }, + { kAudioChannelLayoutTag_EAC3_6_1_B, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround } }, + { kAudioChannelLayoutTag_EAC3_6_1_C, { left, centre, right, leftSurround, rightSurround, LFE, topFrontCentre } }, + { kAudioChannelLayoutTag_EAC3_7_1_A, { left, centre, right, leftSurround, rightSurround, LFE, leftSurroundRear, rightSurroundRear } }, + { kAudioChannelLayoutTag_EAC3_7_1_B, { left, centre, right, leftSurround, rightSurround, LFE, leftCentre, rightCentre } }, + { kAudioChannelLayoutTag_EAC3_7_1_C, { left, centre, right, leftSurround, rightSurround, LFE, leftSurroundSide, rightSurroundSide } }, + { kAudioChannelLayoutTag_EAC3_7_1_D, { left, centre, right, leftSurround, rightSurround, LFE, wideLeft, wideRight } }, + { kAudioChannelLayoutTag_EAC3_7_1_E, { left, centre, right, leftSurround, rightSurround, LFE, topFrontLeft, topFrontRight } }, + { kAudioChannelLayoutTag_EAC3_7_1_F, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround, topMiddle } }, + { kAudioChannelLayoutTag_EAC3_7_1_G, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround, topFrontCentre } }, + { kAudioChannelLayoutTag_EAC3_7_1_H, { left, centre, right, leftSurround, rightSurround, LFE, centreSurround, topFrontCentre } }, + { kAudioChannelLayoutTag_DTS_3_1, { centre, left, right, LFE } }, + { kAudioChannelLayoutTag_DTS_4_1, { centre, left, right, centreSurround, LFE } }, + { kAudioChannelLayoutTag_DTS_6_0_B, { centre, left, right, leftSurroundRear, rightSurroundRear, centreSurround } }, + { kAudioChannelLayoutTag_DTS_6_0_C, { centre, centreSurround, left, right, leftSurroundRear, rightSurroundRear } }, + { kAudioChannelLayoutTag_DTS_6_1_B, { centre, left, right, leftSurroundRear, rightSurroundRear, centreSurround, LFE } }, + { kAudioChannelLayoutTag_DTS_6_1_C, { centre, centreSurround, left, right, leftSurroundRear, rightSurroundRear, LFE } }, + { kAudioChannelLayoutTag_DTS_6_1_D, { centre, left, right, leftSurround, rightSurround, LFE, centreSurround } }, + { kAudioChannelLayoutTag_DTS_7_0, { leftCentre, centre, rightCentre, left, right, leftSurround, rightSurround } }, + { kAudioChannelLayoutTag_DTS_7_1, { leftCentre, centre, rightCentre, left, right, leftSurround, rightSurround, LFE } }, + { kAudioChannelLayoutTag_DTS_8_0_A, { leftCentre, rightCentre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear } }, + { kAudioChannelLayoutTag_DTS_8_0_B, { leftCentre, centre, rightCentre, left, right, leftSurround, centreSurround, rightSurround } }, + { kAudioChannelLayoutTag_DTS_8_1_A, { leftCentre, rightCentre, left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, LFE } }, + { kAudioChannelLayoutTag_DTS_8_1_B, { leftCentre, centre, rightCentre, left, right, leftSurround, centreSurround, rightSurround, LFE } }, + { 0, {} } + }; + + return tbl; + } + }; + + //============================================================================== + static AudioChannelSet::ChannelType getChannelTypeFromAudioChannelLabel (AudioChannelLabel label) noexcept + { + if (label >= kAudioChannelLabel_Discrete_0 && label <= kAudioChannelLabel_Discrete_65535) + { + const unsigned int discreteChannelNum = label - kAudioChannelLabel_Discrete_0; + return static_cast (AudioChannelSet::discreteChannel0 + discreteChannelNum); + } + + switch (label) + { + case kAudioChannelLabel_Center: + case kAudioChannelLabel_Mono: return AudioChannelSet::centre; + case kAudioChannelLabel_Left: + case kAudioChannelLabel_HeadphonesLeft: return AudioChannelSet::left; + case kAudioChannelLabel_Right: + case kAudioChannelLabel_HeadphonesRight: return AudioChannelSet::right; + case kAudioChannelLabel_LFEScreen: return AudioChannelSet::LFE; + case kAudioChannelLabel_LeftSurround: return AudioChannelSet::leftSurround; + case kAudioChannelLabel_RightSurround: return AudioChannelSet::rightSurround; + case kAudioChannelLabel_LeftCenter: return AudioChannelSet::leftCentre; + case kAudioChannelLabel_RightCenter: return AudioChannelSet::rightCentre; + case kAudioChannelLabel_CenterSurround: return AudioChannelSet::surround; + case kAudioChannelLabel_LeftSurroundDirect: return AudioChannelSet::leftSurroundSide; + case kAudioChannelLabel_RightSurroundDirect: return AudioChannelSet::rightSurroundSide; + case kAudioChannelLabel_TopCenterSurround: return AudioChannelSet::topMiddle; + case kAudioChannelLabel_VerticalHeightLeft: return AudioChannelSet::topFrontLeft; + case kAudioChannelLabel_VerticalHeightRight: return AudioChannelSet::topFrontRight; + case kAudioChannelLabel_VerticalHeightCenter: return AudioChannelSet::topFrontCentre; + case kAudioChannelLabel_TopBackLeft: return AudioChannelSet::topRearLeft; + case kAudioChannelLabel_RearSurroundLeft: return AudioChannelSet::leftSurroundRear; + case kAudioChannelLabel_TopBackRight: return AudioChannelSet::topRearRight; + case kAudioChannelLabel_RearSurroundRight: return AudioChannelSet::rightSurroundRear; + case kAudioChannelLabel_TopBackCenter: return AudioChannelSet::topRearCentre; + case kAudioChannelLabel_LFE2: return AudioChannelSet::LFE2; + case kAudioChannelLabel_LeftWide: return AudioChannelSet::wideLeft; + case kAudioChannelLabel_RightWide: return AudioChannelSet::wideRight; + case kAudioChannelLabel_Ambisonic_W: return AudioChannelSet::ambisonicW; + case kAudioChannelLabel_Ambisonic_X: return AudioChannelSet::ambisonicX; + case kAudioChannelLabel_Ambisonic_Y: return AudioChannelSet::ambisonicY; + case kAudioChannelLabel_Ambisonic_Z: return AudioChannelSet::ambisonicZ; + default: return AudioChannelSet::unknown; + } + } +}; + +#endif diff --git a/source/modules/juce_audio_basics/sources/juce_AudioSource.h b/source/modules/juce_audio_basics/sources/juce_AudioSource.h index bf50c30a4..e58f93b29 100644 --- a/source/modules/juce_audio_basics/sources/juce_AudioSource.h +++ b/source/modules/juce_audio_basics/sources/juce_AudioSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOSOURCE_H_INCLUDED -#define JUCE_AUDIOSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -182,6 +173,3 @@ public: */ virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0; }; - - -#endif // JUCE_AUDIOSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp b/source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp index b560c4873..1cf471839 100644 --- a/source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp +++ b/source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h b/source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h index 7f6de2ab2..803695ea4 100644 --- a/source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h +++ b/source/modules/juce_audio_basics/sources/juce_BufferingAudioSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BUFFERINGAUDIOSOURCE_H_INCLUDED -#define JUCE_BUFFERINGAUDIOSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -122,6 +113,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioSource) }; - - -#endif // JUCE_BUFFERINGAUDIOSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp b/source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp index a5570d76e..a70fe866e 100644 --- a/source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp +++ b/source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h b/source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h index fb42dd264..1ed44d824 100644 --- a/source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h +++ b/source/modules/juce_audio_basics/sources/juce_ChannelRemappingAudioSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHANNELREMAPPINGAUDIOSOURCE_H_INCLUDED -#define JUCE_CHANNELREMAPPINGAUDIOSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -144,6 +135,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChannelRemappingAudioSource) }; - - -#endif // JUCE_CHANNELREMAPPINGAUDIOSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp b/source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp index fc2a3fa9b..be4479fbb 100644 --- a/source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp +++ b/source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h b/source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h index bce56e552..9f38d1ce8 100644 --- a/source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h +++ b/source/modules/juce_audio_basics/sources/juce_IIRFilterAudioSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IIRFILTERAUDIOSOURCE_H_INCLUDED -#define JUCE_IIRFILTERAUDIOSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -71,6 +62,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IIRFilterAudioSource) }; - - -#endif // JUCE_IIRFILTERAUDIOSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp b/source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp new file mode 100644 index 000000000..220debfd1 --- /dev/null +++ b/source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.cpp @@ -0,0 +1,66 @@ +/* + ============================================================================== + + 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. + + The code included in this file is provided 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. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +//============================================================================== +MemoryAudioSource::MemoryAudioSource (AudioBuffer& bufferToUse, bool copyMemory, bool shouldLoop) + : isLooping (shouldLoop) +{ + if (copyMemory) + buffer.makeCopyOf (bufferToUse); + else + buffer.setDataToReferTo (bufferToUse.getArrayOfWritePointers(), + bufferToUse.getNumChannels(), + bufferToUse.getNumSamples()); +} + +//============================================================================== +void MemoryAudioSource::prepareToPlay (int /*samplesPerBlockExpected*/, double /*sampleRate*/) +{ + position = 0; +} + +void MemoryAudioSource::releaseResources() {} + +void MemoryAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) +{ + auto& dst = *bufferToFill.buffer; + auto channels = jmin (dst.getNumChannels(), buffer.getNumChannels()); + auto max = 0, pos = 0; + auto n = buffer.getNumSamples(), m = bufferToFill.numSamples; + + for (auto i = position; (i < n || isLooping) && (pos < m); i += max) + { + max = jmin (m - pos, n - (i % n)); + + int ch = 0; + for (; ch < channels; ++ch) + dst.copyFrom (ch, bufferToFill.startSample + pos, buffer, ch, i % n, max); + + for (; ch < dst.getNumChannels(); ++ch) + dst.clear (ch, bufferToFill.startSample + pos, max); + + pos += max; + } + + if (pos < m) + dst.clear (bufferToFill.startSample + pos, m - pos); +} diff --git a/source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h b/source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h new file mode 100644 index 000000000..1a6fabf1b --- /dev/null +++ b/source/modules/juce_audio_basics/sources/juce_MemoryAudioSource.h @@ -0,0 +1,61 @@ +/* + ============================================================================== + + 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. + + The code included in this file is provided 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. + + 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 + + +//============================================================================== +/** + An AudioSource which takes some float audio data as an input. +*/ +class JUCE_API MemoryAudioSource : public AudioSource +{ +public: + //============================================================================== + /** Creates a MemoryAudioSource by providing an audio buffer. + + If copyMemory is true then the buffer will be copied into an internal + buffer which will be owned by the MemoryAudioSource. If copyMemory is + false, then you must ensure that the lifetime of the audio buffer is + at least as long as the MemoryAudioSource. + */ + MemoryAudioSource (AudioBuffer& audioBuffer, bool copyMemory, bool shouldLoop = false); + + //============================================================================== + /** Implementation of the AudioSource method. */ + void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; + + /** Implementation of the AudioSource method. */ + void releaseResources() override; + + /** Implementation of the AudioSource method. */ + void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override; + +private: + //============================================================================== + AudioBuffer buffer; + int position = 0; + bool isLooping; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryAudioSource) +}; diff --git a/source/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp b/source/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp index 91a6ba35d..70b265865 100644 --- a/source/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp +++ b/source/modules/juce_audio_basics/sources/juce_MixerAudioSource.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/sources/juce_MixerAudioSource.h b/source/modules/juce_audio_basics/sources/juce_MixerAudioSource.h index 082438549..5a3883f8e 100644 --- a/source/modules/juce_audio_basics/sources/juce_MixerAudioSource.h +++ b/source/modules/juce_audio_basics/sources/juce_MixerAudioSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIXERAUDIOSOURCE_H_INCLUDED -#define JUCE_MIXERAUDIOSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -102,6 +93,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MixerAudioSource) }; - - -#endif // JUCE_MIXERAUDIOSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h b/source/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h index a7ed8086b..c9195dc90 100644 --- a/source/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h +++ b/source/modules/juce_audio_basics/sources/juce_PositionableAudioSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_POSITIONABLEAUDIOSOURCE_H_INCLUDED -#define JUCE_POSITIONABLEAUDIOSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -79,6 +70,3 @@ public: /** Tells the source whether you'd like it to play in a loop. */ virtual void setLooping (bool shouldLoop) { ignoreUnused (shouldLoop); } }; - - -#endif // JUCE_POSITIONABLEAUDIOSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp b/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp index 8fec9cd38..386f894ca 100644 --- a/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp +++ b/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h b/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h index 9f90ca0af..72134f983 100644 --- a/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h +++ b/source/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RESAMPLINGAUDIOSOURCE_H_INCLUDED -#define JUCE_RESAMPLINGAUDIOSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -108,6 +99,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResamplingAudioSource) }; - - -#endif // JUCE_RESAMPLINGAUDIOSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp b/source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp index 5b00c5083..86e54eaf9 100644 --- a/source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp +++ b/source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h b/source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h index 7161a78d8..fbdf48c94 100644 --- a/source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h +++ b/source/modules/juce_audio_basics/sources/juce_ReverbAudioSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_REVERBAUDIOSOURCE_H_INCLUDED -#define JUCE_REVERBAUDIOSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -77,6 +68,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ReverbAudioSource) }; - - -#endif // JUCE_REVERBAUDIOSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp b/source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp index 628ae3671..b0f24d390 100644 --- a/source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp +++ b/source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h b/source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h index df9d7de7f..a5fc03b4f 100644 --- a/source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h +++ b/source/modules/juce_audio_basics/sources/juce_ToneGeneratorAudioSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TONEGENERATORAUDIOSOURCE_H_INCLUDED -#define JUCE_TONEGENERATORAUDIOSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -74,6 +65,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToneGeneratorAudioSource) }; - - -#endif // JUCE_TONEGENERATORAUDIOSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp b/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp index 92c0c2421..3e0fd4b7e 100644 --- a/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp +++ b/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h b/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h index be140db20..51369a9ea 100644 --- a/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h +++ b/source/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SYNTHESISER_H_INCLUDED -#define JUCE_SYNTHESISER_H_INCLUDED +#pragma once //============================================================================== @@ -641,6 +632,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser) }; - - -#endif // JUCE_SYNTHESISER_H_INCLUDED diff --git a/source/modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h b/source/modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h deleted file mode 100644 index fae2cd06c..000000000 --- a/source/modules/juce_audio_devices/audio_cd/juce_AudioCDBurner.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOCDBURNER_H_INCLUDED -#define JUCE_AUDIOCDBURNER_H_INCLUDED - -#if JUCE_USE_CDBURNER || DOXYGEN - - -//============================================================================== -/** -*/ -class AudioCDBurner : public ChangeBroadcaster -{ -public: - //============================================================================== - /** Returns a list of available optical drives. - - Use openDevice() to open one of the items from this list. - */ - static StringArray findAvailableDevices(); - - /** Tries to open one of the optical drives. - - The deviceIndex is an index into the array returned by findAvailableDevices(). - */ - static AudioCDBurner* openDevice (const int deviceIndex); - - /** Destructor. */ - ~AudioCDBurner(); - - //============================================================================== - enum DiskState - { - unknown, /**< An error condition, if the device isn't responding. */ - trayOpen, /**< The drive is currently open. Note that a slot-loading drive - may seem to be permanently open. */ - noDisc, /**< The drive has no disk in it. */ - writableDiskPresent, /**< The drive contains a writeable disk. */ - readOnlyDiskPresent /**< The drive contains a read-only disk. */ - }; - - /** Returns the current status of the device. - - To get informed when the drive's status changes, attach a ChangeListener to - the AudioCDBurner. - */ - DiskState getDiskState() const; - - /** Returns true if there's a writable disk in the drive. */ - bool isDiskPresent() const; - - /** Sends an eject signal to the drive. - The eject will happen asynchronously, so you can use getDiskState() and - waitUntilStateChange() to monitor its progress. - */ - bool openTray(); - - /** Blocks the current thread until the drive's state changes, or until the timeout expires. - @returns the device's new state - */ - DiskState waitUntilStateChange (int timeOutMilliseconds); - - //============================================================================== - /** Returns the set of possible write speeds that the device can handle. - These are as a multiple of 'normal' speed, so e.g. '24x' returns 24, etc. - Note that if there's no media present in the drive, this value may be unavailable! - @see setWriteSpeed, getWriteSpeed - */ - Array getAvailableWriteSpeeds() const; - - //============================================================================== - /** Tries to enable or disable buffer underrun safety on devices that support it. - @returns true if it's now enabled. If the device doesn't support it, this - will always return false. - */ - bool setBufferUnderrunProtection (bool shouldBeEnabled); - - //============================================================================== - /** Returns the number of free blocks on the disk. - - There are 75 blocks per second, at 44100Hz. - */ - int getNumAvailableAudioBlocks() const; - - /** Adds a track to be written. - - The source passed-in here will be kept by this object, and it will - be used and deleted at some point in the future, either during the - burn() method or when this AudioCDBurner object is deleted. Your caller - method shouldn't keep a reference to it or use it again after passing - it in here. - */ - bool addAudioTrack (AudioSource* source, int numSamples); - - //============================================================================== - /** Receives progress callbacks during a cd-burn operation. - @see AudioCDBurner::burn() - */ - class BurnProgressListener - { - public: - BurnProgressListener() noexcept {} - virtual ~BurnProgressListener() {} - - /** Called at intervals to report on the progress of the AudioCDBurner. - - To cancel the burn, return true from this method. - */ - virtual bool audioCDBurnProgress (float proportionComplete) = 0; - }; - - /** Runs the burn process. - This method will block until the operation is complete. - - @param listener the object to receive callbacks about progress - @param ejectDiscAfterwards whether to eject the disk after the burn completes - @param performFakeBurnForTesting if true, no data will actually be written to the disk - @param writeSpeed one of the write speeds from getAvailableWriteSpeeds(), or - 0 or less to mean the fastest speed. - */ - String burn (BurnProgressListener* listener, - bool ejectDiscAfterwards, - bool performFakeBurnForTesting, - int writeSpeed); - - /** If a burn operation is currently in progress, this tells it to stop - as soon as possible. - - It's also possible to stop the burn process by returning true from - BurnProgressListener::audioCDBurnProgress() - */ - void abortBurn(); - -private: - //============================================================================== - AudioCDBurner (const int deviceIndex); - - class Pimpl; - friend struct ContainerDeletePolicy; - ScopedPointer pimpl; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioCDBurner) -}; - - -#endif -#endif // JUCE_AUDIOCDBURNER_H_INCLUDED diff --git a/source/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp b/source/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp deleted file mode 100644 index b9d798789..000000000 --- a/source/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_USE_CDREADER - -int AudioCDReader::getNumTracks() const -{ - return trackStartSamples.size() - 1; -} - -int AudioCDReader::getPositionOfTrackStart (int trackNum) const -{ - return trackStartSamples [trackNum]; -} - -const Array& AudioCDReader::getTrackOffsets() const -{ - return trackStartSamples; -} - -int AudioCDReader::getCDDBId() -{ - int checksum = 0; - const int numTracks = getNumTracks(); - - for (int i = 0; i < numTracks; ++i) - for (int offset = (trackStartSamples.getUnchecked(i) + 88200) / 44100; offset > 0; offset /= 10) - checksum += offset % 10; - - const int length = (trackStartSamples.getLast() - trackStartSamples.getFirst()) / 44100; - - // CCLLLLTT: checksum, length, tracks - return ((checksum & 0xff) << 24) | (length << 8) | numTracks; -} - -#endif diff --git a/source/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h b/source/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h deleted file mode 100644 index bb9ac6ec8..000000000 --- a/source/modules/juce_audio_devices/audio_cd/juce_AudioCDReader.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOCDREADER_H_INCLUDED -#define JUCE_AUDIOCDREADER_H_INCLUDED - -#if JUCE_USE_CDREADER || DOXYGEN - - -//============================================================================== -/** - A type of AudioFormatReader that reads from an audio CD. - - One of these can be used to read a CD as if it's one big audio stream. Use the - getPositionOfTrackStart() method to find where the individual tracks are - within the stream. - - @see AudioFormatReader -*/ -class JUCE_API AudioCDReader : public AudioFormatReader -{ -public: - //============================================================================== - /** Returns a list of names of Audio CDs currently available for reading. - - If there's a CD drive but no CD in it, this might return an empty list, or - possibly a device that can be opened but which has no tracks, depending - on the platform. - - @see createReaderForCD - */ - static StringArray getAvailableCDNames(); - - /** Tries to create an AudioFormatReader that can read from an Audio CD. - - @param index the index of one of the available CDs - use getAvailableCDNames() - to find out how many there are. - @returns a new AudioCDReader object, or nullptr if it couldn't be created. The - caller will be responsible for deleting the object returned. - */ - static AudioCDReader* createReaderForCD (const int index); - - //============================================================================== - /** Destructor. */ - ~AudioCDReader(); - - /** Implementation of the AudioFormatReader method. */ - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) override; - - /** Checks whether the CD has been removed from the drive. */ - bool isCDStillPresent() const; - - /** Returns the total number of tracks (audio + data). */ - int getNumTracks() const; - - /** Finds the sample offset of the start of a track. - @param trackNum the track number, where trackNum = 0 is the first track - and trackNum = getNumTracks() means the end of the CD. - */ - int getPositionOfTrackStart (int trackNum) const; - - /** Returns true if a given track is an audio track. - @param trackNum the track number, where 0 is the first track. - */ - bool isTrackAudio (int trackNum) const; - - /** Returns an array of sample offsets for the start of each track, followed by - the sample position of the end of the CD. - */ - const Array& getTrackOffsets() const; - - /** Refreshes the object's table of contents. - - If the disc has been ejected and a different one put in since this - object was created, this will cause it to update its idea of how many tracks - there are, etc. - */ - void refreshTrackLengths(); - - /** Enables scanning for indexes within tracks. - @see getLastIndex - */ - void enableIndexScanning (bool enabled); - - /** Returns the index number found during the last read() call. - - Index scanning is turned off by default - turn it on with enableIndexScanning(). - - Then when the read() method is called, if it comes across an index within that - block, the index number is stored and returned by this method. - - Some devices might not support indexes, of course. - - (If you don't know what CD indexes are, it's unlikely you'll ever need them). - - @see enableIndexScanning - */ - int getLastIndex() const; - - /** Scans a track to find the position of any indexes within it. - @param trackNumber the track to look in, where 0 is the first track on the disc - @returns an array of sample positions of any index points found (not including - the index that marks the start of the track) - */ - Array findIndexesInTrack (const int trackNumber); - - /** Returns the CDDB id number for the CD. - It's not a great way of identifying a disc, but it's traditional. - */ - int getCDDBId(); - - /** Tries to eject the disk. - Ejecting the disk might not actually be possible, e.g. if some other process is using it. - */ - void ejectDisk(); - - //============================================================================== - enum - { - framesPerSecond = 75, - samplesPerFrame = 44100 / framesPerSecond - }; - -private: - //============================================================================== - Array trackStartSamples; - - #if JUCE_MAC - File volumeDir; - Array tracks; - int currentReaderTrack; - ScopedPointer reader; - AudioCDReader (const File& volume); - - #elif JUCE_WINDOWS - bool audioTracks [100]; - void* handle; - MemoryBlock buffer; - bool indexingEnabled; - int lastIndex, firstFrameInBuffer, samplesInBuffer; - AudioCDReader (void* handle); - int getIndexAt (int samplePos); - - #elif JUCE_LINUX - AudioCDReader(); - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioCDReader) -}; - -#endif -#endif // JUCE_AUDIOCDREADER_H_INCLUDED diff --git a/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp b/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp index 76e469ff2..89eb7cf9f 100644 --- a/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +++ b/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -442,7 +434,7 @@ String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup jassert (&newSetup != ¤tSetup); // this will have no effect if (newSetup == currentSetup && currentAudioDevice != nullptr) - return String(); + return {}; if (! (newSetup == currentSetup)) sendChangeMessage(); @@ -462,7 +454,7 @@ String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup if (treatAsChosenDevice) updateXml(); - return String(); + return {}; } if (currentSetup.inputDeviceName != newInputDeviceName diff --git a/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h b/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h index 5889a4ae4..f4169644c 100644 --- a/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h +++ b/source/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIODEVICEMANAGER_H_INCLUDED -#define JUCE_AUDIODEVICEMANAGER_H_INCLUDED +#pragma once //============================================================================== @@ -527,5 +518,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDeviceManager) }; - -#endif // JUCE_AUDIODEVICEMANAGER_H_INCLUDED diff --git a/source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp b/source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp index fe027c8ad..0fd48370f 100644 --- a/source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp +++ b/source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h b/source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h index 6038cef62..6c3b8300f 100644 --- a/source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h +++ b/source/modules/juce_audio_devices/audio_io/juce_AudioIODevice.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOIODEVICE_H_INCLUDED -#define JUCE_AUDIOIODEVICE_H_INCLUDED +#pragma once class AudioIODevice; @@ -310,6 +301,3 @@ protected: /** @internal */ String name, typeName; }; - - -#endif // JUCE_AUDIOIODEVICE_H_INCLUDED diff --git a/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp b/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp index c00fb56b4..aef772d0a 100644 --- a/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp +++ b/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h b/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h index cad0095ba..eaba0080e 100644 --- a/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h +++ b/source/modules/juce_audio_devices/audio_io/juce_AudioIODeviceType.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOIODEVICETYPE_H_INCLUDED -#define JUCE_AUDIOIODEVICETYPE_H_INCLUDED +#pragma once //============================================================================== @@ -183,6 +174,3 @@ private: JUCE_DECLARE_NON_COPYABLE (AudioIODeviceType) }; - - -#endif // JUCE_AUDIOIODEVICETYPE_H_INCLUDED diff --git a/source/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h b/source/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h index baaceb485..592215c9d 100644 --- a/source/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h +++ b/source/modules/juce_audio_devices/audio_io/juce_SystemAudioVolume.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SYSTEMAUDIOVOLUME_H_INCLUDED -#define JUCE_SYSTEMAUDIOVOLUME_H_INCLUDED +#pragma once //============================================================================== @@ -62,6 +53,3 @@ private: SystemAudioVolume(); // Don't instantiate this class, just call its static fns. JUCE_DECLARE_NON_COPYABLE (SystemAudioVolume) }; - - -#endif // JUCE_SYSTEMAUDIOVOLUME_H_INCLUDED diff --git a/source/modules/juce_audio_devices/juce_audio_devices.cpp b/source/modules/juce_audio_devices/juce_audio_devices.cpp index bf6fee2c7..33c6fe0c9 100644 --- a/source/modules/juce_audio_devices/juce_audio_devices.cpp +++ b/source/modules/juce_audio_devices/juce_audio_devices.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -37,14 +29,20 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #define JUCE_CORE_INCLUDE_OBJC_HELPERS 1 #define JUCE_CORE_INCLUDE_COM_SMART_PTR 1 #define JUCE_CORE_INCLUDE_JNI_HELPERS 1 #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 #define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1 +#ifndef JUCE_USE_WINRT_MIDI + #define JUCE_USE_WINRT_MIDI 0 +#endif + +#if JUCE_USE_WINRT_MIDI + #define JUCE_EVENTS_INCLUDE_WINRT_WRAPPER 1 +#endif + #include "juce_audio_devices.h" //============================================================================== @@ -72,6 +70,30 @@ #include #endif + #if JUCE_USE_WINRT_MIDI + /* If you cannot find any of the header files below then you are probably + attempting to use the Windows 10 Bluetooth Low Energy API. For this to work you + need to install version 10.0.14393.0 of the Windows Standalone SDK and add the + path to the WinRT headers to your build system. This path should have the form + "C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\winrt". + + Also please note that Microsoft's Bluetooth MIDI stack has multiple issues, so + this API is EXPERIMENTAL - use at your own risk! + */ + #include + #include + #include + #include + #if JUCE_MSVC + #pragma warning (push) + #pragma warning (disable: 4467) + #endif + #include + #if JUCE_MSVC + #pragma warning (pop) + #endif + #endif + #if JUCE_ASIO /* This is very frustrating - we only need to use a handful of definitions from a couple of the header files in Steinberg's ASIO SDK, and it'd be easy to copy diff --git a/source/modules/juce_audio_devices/juce_audio_devices.h b/source/modules/juce_audio_devices/juce_audio_devices.h index 6c223e043..533bcd1af 100644 --- a/source/modules/juce_audio_devices/juce_audio_devices.h +++ b/source/modules/juce_audio_devices/juce_audio_devices.h @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -39,7 +31,7 @@ ID: juce_audio_devices vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE audio and MIDI I/O device classes description: Classes to play and record from audio and MIDI I/O devices website: http://www.juce.com/juce @@ -56,12 +48,16 @@ *******************************************************************************/ -#ifndef JUCE_AUDIO_DEVICES_H_INCLUDED +#pragma once #define JUCE_AUDIO_DEVICES_H_INCLUDED #include #include +#if JUCE_MODULE_AVAILABLE_juce_graphics +#include +#endif + //============================================================================== /** Config: JUCE_ASIO Enables ASIO audio devices (MS Windows only). @@ -123,20 +119,42 @@ #endif #endif +/** Config: JUCE_USE_WINRT_MIDI + *** + EXPERIMENTAL - Microsoft's Bluetooth MIDI stack has multiple issues, + use at your own risk! + *** + + Enables the use of the Windows Runtime API for MIDI, which supports + Bluetooth Low Energy connections on computers with the Anniversary Update + of Windows 10. + + To compile with this flag requires version 10.0.14393.0 of the Windows + Standalone SDK and you must add the path to the WinRT headers. This path + should be something similar to + "C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\winrt". +*/ +#ifndef JUCE_USE_WINRT_MIDI + #define JUCE_USE_WINRT_MIDI 0 +#endif + + //============================================================================== namespace juce { -#include "audio_io/juce_AudioIODevice.h" -#include "audio_io/juce_AudioIODeviceType.h" -#include "audio_io/juce_SystemAudioVolume.h" #include "midi_io/juce_MidiInput.h" #include "midi_io/juce_MidiMessageCollector.h" #include "midi_io/juce_MidiOutput.h" +#include "audio_io/juce_AudioIODevice.h" +#include "audio_io/juce_AudioIODeviceType.h" +#include "audio_io/juce_SystemAudioVolume.h" #include "sources/juce_AudioSourcePlayer.h" #include "sources/juce_AudioTransportSource.h" #include "audio_io/juce_AudioDeviceManager.h" -} +#if JUCE_IOS + #include "native/juce_ios_Audio.h" +#endif -#endif // JUCE_AUDIO_DEVICES_H_INCLUDED +} diff --git a/source/modules/juce_audio_devices/midi_io/juce_MidiInput.h b/source/modules/juce_audio_devices/midi_io/juce_MidiInput.h index f1c457ece..54cd0e4e7 100644 --- a/source/modules/juce_audio_devices/midi_io/juce_MidiInput.h +++ b/source/modules/juce_audio_devices/midi_io/juce_MidiInput.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIINPUT_H_INCLUDED -#define JUCE_MIDIINPUT_H_INCLUDED +#pragma once class MidiInput; @@ -173,13 +164,10 @@ public: private: //============================================================================== String name; - void* internal; + void* internal = nullptr; // The input objects are created with the openDevice() method. explicit MidiInput (const String&); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput) }; - - -#endif // JUCE_MIDIINPUT_H_INCLUDED diff --git a/source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp b/source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp index 5deea4324..66bab1f85 100644 --- a/source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp +++ b/source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.cpp @@ -2,35 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ MidiMessageCollector::MidiMessageCollector() - : lastCallbackTime (0), - sampleRate (44100.0001) { } @@ -44,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(); @@ -51,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. @@ -60,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); @@ -74,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; @@ -87,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/source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h b/source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h index d18fcc6d5..97f2dd6bb 100644 --- a/source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h +++ b/source/modules/juce_audio_devices/midi_io/juce_MidiMessageCollector.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIMESSAGECOLLECTOR_H_INCLUDED -#define JUCE_MIDIMESSAGECOLLECTOR_H_INCLUDED +#pragma once //============================================================================== @@ -98,13 +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) }; - - -#endif // JUCE_MIDIMESSAGECOLLECTOR_H_INCLUDED diff --git a/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp b/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp index c9be2a986..f364b31cd 100644 --- a/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp +++ b/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -38,7 +30,7 @@ struct MidiOutput::PendingMessage PendingMessage* next; }; -MidiOutput::MidiOutput(const String& midiName) +MidiOutput::MidiOutput (const String& midiName) : Thread ("midi out"), internal (nullptr), firstMessage (nullptr), diff --git a/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.h b/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.h index de6599fb2..f71553dc7 100644 --- a/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.h +++ b/source/modules/juce_audio_devices/midi_io/juce_MidiOutput.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIOUTPUT_H_INCLUDED -#define JUCE_MIDIOUTPUT_H_INCLUDED +#pragma once //============================================================================== @@ -137,17 +128,14 @@ public: private: //============================================================================== - void* internal; + void* internal = nullptr; CriticalSection lock; struct PendingMessage; PendingMessage* firstMessage; String name; - MidiOutput(const String& midiName); // These objects are created with the openDevice() method. + MidiOutput (const String& midiName); // These objects are created with the openDevice() method. void run() override; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutput) }; - - -#endif // JUCE_MIDIOUTPUT_H_INCLUDED diff --git a/source/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h b/source/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h index 58a7d48fa..0cf7e285d 100644 --- a/source/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h +++ b/source/modules/juce_audio_devices/native/juce_MidiDataConcatenator.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MIDIDATACONCATENATOR_H_INCLUDED -#define JUCE_MIDIDATACONCATENATOR_H_INCLUDED +#pragma once //============================================================================== /** @@ -196,5 +187,3 @@ private: JUCE_DECLARE_NON_COPYABLE (MidiDataConcatenator) }; - -#endif // JUCE_MIDIDATACONCATENATOR_H_INCLUDED diff --git a/source/modules/juce_audio_devices/native/juce_android_Audio.cpp b/source/modules/juce_audio_devices/native/juce_android_Audio.cpp index dd4e5a452..a22f0619f 100644 --- a/source/modules/juce_audio_devices/native/juce_android_Audio.cpp +++ b/source/modules/juce_audio_devices/native/juce_android_Audio.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -199,7 +191,7 @@ public: numDeviceOutputChannels = 2; outputDevice = GlobalRef (env->NewObject (AudioTrack, AudioTrack.constructor, STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT, - (jint) (minBufferSizeOut * numDeviceOutputChannels * sizeof (int16)), MODE_STREAM)); + (jint) (minBufferSizeOut * numDeviceOutputChannels * static_cast (sizeof (int16))), MODE_STREAM)); int outputDeviceState = env->CallIntMethod (outputDevice, AudioTrack.getState); if (outputDeviceState > 0) @@ -232,7 +224,7 @@ public: 0 /* (default audio source) */, sampleRate, numDeviceInputChannelsAvailable > 1 ? CHANNEL_IN_STEREO : CHANNEL_IN_MONO, ENCODING_PCM_16BIT, - (jint) (minBufferSizeIn * numDeviceInputChannels * sizeof (int16)))); + (jint) (minBufferSizeIn * numDeviceInputChannels * static_cast (sizeof (int16))))); int inputDeviceState = env->CallIntMethod (inputDevice, AudioRecord.getState); if (inputDeviceState > 0) @@ -441,9 +433,9 @@ public: //============================================================================== void scanForDevices() {} - StringArray getDeviceNames (bool wantInputNames) const { return StringArray (javaAudioTypeName); } - int getDefaultDeviceIndex (bool forInput) const { return 0; } - int getIndexOfDevice (AudioIODevice* device, bool asInput) const { return device != nullptr ? 0 : -1; } + StringArray getDeviceNames (bool) const { return StringArray (javaAudioTypeName); } + int getDefaultDeviceIndex (bool) const { return 0; } + int getIndexOfDevice (AudioIODevice* device, bool) const { return device != nullptr ? 0 : -1; } bool hasSeparateInputsAndOutputs() const { return false; } AudioIODevice* createDevice (const String& outputDeviceName, diff --git a/source/modules/juce_audio_devices/native/juce_android_Midi.cpp b/source/modules/juce_audio_devices/native/juce_android_Midi.cpp index a1f73a997..c968982cb 100644 --- a/source/modules/juce_audio_devices/native/juce_android_Midi.cpp +++ b/source/modules/juce_audio_devices/native/juce_android_Midi.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -96,8 +88,8 @@ public: jassert (byteArray != nullptr); jbyte* data = getEnv()->GetByteArrayElements (byteArray, nullptr); - HeapBlock buffer (len); - std::memcpy (buffer.getData(), data + offset, len); + HeapBlock buffer (static_cast (len)); + std::memcpy (buffer.getData(), data + offset, static_cast (len)); midiConcatenator.pushMidiData (buffer.getData(), len, static_cast (timestamp) * 1.0e-9, @@ -109,8 +101,8 @@ public: private: MidiInput* juceMidiInput; MidiInputCallback* callback; - GlobalRef javaMidiDevice; MidiDataConcatenator midiConcatenator; + GlobalRef javaMidiDevice; }; //============================================================================== @@ -144,7 +136,7 @@ private: }; JUCE_JNI_CALLBACK (JUCE_JOIN_MACRO (JUCE_ANDROID_ACTIVITY_CLASSNAME, _00024JuceMidiInputPort), handleReceive, - void, (JNIEnv* env, jobject device, jlong host, jbyteArray byteArray, + void, (JNIEnv* env, jobject, jlong host, jbyteArray byteArray, jint offset, jint count, jlong timestamp)) { // Java may create a Midi thread which JUCE doesn't know about and this callback may be @@ -172,7 +164,7 @@ public: return juceString (string); } - return String(); + return {}; } String getOutputPortNameForJuceIndex (int idx) @@ -183,7 +175,7 @@ public: return juceString (string); } - return String(); + return {}; } StringArray getDevices (bool input) @@ -200,7 +192,7 @@ public: return javaStringArrayToJuce (devices); } - return StringArray(); + return {}; } AndroidMidiInput* openMidiInputPortWithIndex (int idx, MidiInput* juceMidiInput, juce::MidiInputCallback* callback) @@ -302,7 +294,7 @@ void MidiOutput::sendMessageNow (const MidiMessage& message) jbyteArray content = messageContent.get(); jbyte* rawBytes = env->GetByteArrayElements (content, nullptr); - std::memcpy (rawBytes, message.getRawData(), messageSize); + std::memcpy (rawBytes, message.getRawData(), static_cast (messageSize)); env->ReleaseByteArrayElements (content, rawBytes, 0); androidMidi->send (content, (jint) 0, (jint) messageSize); diff --git a/source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp b/source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp index 60446f101..248db71a9 100644 --- a/source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp +++ b/source/modules/juce_audio_devices/native/juce_android_OpenSL.cpp @@ -2,52 +2,733 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. - ----------------------------------------------------------------------------- + ============================================================================== +*/ + +//============================================================================== +#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ +STATICFIELD (SDK_INT, "SDK_INT", "I") \ + +DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION"); +#undef JNI_CLASS_MEMBERS + +//============================================================================== +#ifndef SL_ANDROID_DATAFORMAT_PCM_EX + #define SL_ANDROID_DATAFORMAT_PCM_EX ((SLuint32) 0x00000004) +#endif + +#ifndef SL_ANDROID_PCM_REPRESENTATION_FLOAT + #define SL_ANDROID_PCM_REPRESENTATION_FLOAT ((SLuint32) 0x00000003) +#endif + +#ifndef SL_ANDROID_RECORDING_PRESET_UNPROCESSED + #define SL_ANDROID_RECORDING_PRESET_UNPROCESSED ((SLuint32) 0x00000005) +#endif + +//============================================================================== +struct PCMDataFormatEx : SLDataFormat_PCM +{ + SLuint32 representation; +}; + +//============================================================================== +template struct IntfIID; +template <> struct IntfIID { static SLInterfaceID_ iid; }; +template <> struct IntfIID { static SLInterfaceID_ iid; }; +template <> struct IntfIID { static SLInterfaceID_ iid; }; +template <> struct IntfIID { static SLInterfaceID_ iid; }; +template <> struct IntfIID { static SLInterfaceID_ iid; }; +template <> struct IntfIID { static SLInterfaceID_ iid; }; +template <> struct IntfIID { static SLInterfaceID_ iid; }; + +SLInterfaceID_ IntfIID::iid = { 0x79216360, 0xddd7, 0x11db, 0xac16, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b} }; +SLInterfaceID_ IntfIID::iid = { 0x8d97c260, 0xddd4, 0x11db, 0x958f, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b} }; +SLInterfaceID_ IntfIID::iid = { 0x97750f60, 0xddd7, 0x11db, 0x92b1, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b} }; +SLInterfaceID_ IntfIID::iid = { 0xef0bd9c0, 0xddd7, 0x11db, 0xbf49, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b} }; +SLInterfaceID_ IntfIID::iid = { 0xc5657aa0, 0xdddb, 0x11db, 0x82f7, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b} }; +SLInterfaceID_ IntfIID::iid = { 0x198e4940, 0xc5d7, 0x11df, 0xa2a6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b} }; +SLInterfaceID_ IntfIID::iid = { 0x89f6a7e0, 0xbeac, 0x11df, 0x8b5c, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b} }; + +//============================================================================== +// Some life-time and type management of OpenSL objects +class SlObjectRef +{ +public: + //============================================================================== + SlObjectRef() noexcept {} + SlObjectRef (const SlObjectRef& obj) noexcept : cb (obj.cb) {} + SlObjectRef (SlObjectRef&& obj) noexcept : cb (static_cast&&> (obj.cb)) { obj.cb = nullptr; } + explicit SlObjectRef (SLObjectItf o) : cb (new ControlBlock (o)) {} + + //============================================================================== + SlObjectRef& operator=(const SlObjectRef& r) noexcept { cb = r.cb; return *this; } + SlObjectRef& operator=(SlObjectRef&& r) noexcept { cb = static_cast&&> (r.cb); r.cb = nullptr; return *this; } + SlObjectRef& operator=(std::nullptr_t) noexcept { cb = nullptr; return *this; } + + //============================================================================== + const SLObjectItf_* const operator*() noexcept { return *cb->ptr.get(); } + SLObjectItf operator->() noexcept { return (cb == nullptr ? nullptr : cb->ptr.get()); } + operator SLObjectItf() noexcept { return (cb == nullptr ? nullptr : cb->ptr.get()); } + + //============================================================================== + bool operator== (nullptr_t) const noexcept { return (cb == nullptr || cb->ptr == nullptr); } + bool operator!= (nullptr_t) const noexcept { return (cb != nullptr && cb->ptr != nullptr); } +private: + + //============================================================================== + struct ControlBlock : ReferenceCountedObject { ScopedPointer ptr; ControlBlock() {} ControlBlock (SLObjectItf o) : ptr (o) {} }; + ReferenceCountedObjectPtr cb; +}; + +template +class SlRef : public SlObjectRef +{ +public: + //============================================================================== + SlRef() noexcept : type (nullptr) {} + SlRef (SlRef& r) noexcept : SlObjectRef (r), type (r.type) {} + SlRef (SlRef&& r) noexcept : SlObjectRef (static_cast (r)), type (r.type) { r.type = nullptr; } + + //============================================================================== + SlRef& operator= (const SlRef& r) noexcept { SlObjectRef::operator= (r); type = r.type; return *this; } + SlRef& operator= (SlRef&& r) noexcept { SlObjectRef::operator= (static_cast (r)); type = r.type; r.type = nullptr; return *this; } + SlRef& operator= (std::nullptr_t) noexcept { SlObjectRef::operator= (nullptr); type = nullptr; return *this; } + + //============================================================================== + T* const operator*() noexcept { return *type; } + T* const * operator->() noexcept { return type; } + operator T* const *() noexcept { return type; } + + //============================================================================== + static SlRef cast (SlObjectRef& base) { return SlRef (base); } + static SlRef cast (SlObjectRef&& base) { return SlRef (static_cast (base)); } +private: + //============================================================================== + SlRef (SlObjectRef& base) : SlObjectRef (base) + { + SLObjectItf obj = SlObjectRef::operator->(); + SLresult err = (*obj)->GetInterface (obj, &IntfIID::iid, &type); + if (type == nullptr || err != SL_RESULT_SUCCESS) + *this = nullptr; + } + + SlRef (SlObjectRef&& base) : SlObjectRef (static_cast (base)) + { + SLObjectItf obj = SlObjectRef::operator->(); + SLresult err = (*obj)->GetInterface (obj, &IntfIID::iid, &type); + base = nullptr; + + if (type == nullptr || err != SL_RESULT_SUCCESS) + *this = nullptr; + } + T* const * type; +}; + +template <> +struct ContainerDeletePolicy +{ + static void destroy (SLObjectItf object) + { + if (object != nullptr) + (*object)->Destroy (object); + } +}; + +//============================================================================== +template struct BufferHelpers {}; + +template <> +struct BufferHelpers +{ + enum { isFloatingPoint = 0 }; + + static void initPCMDataFormat (PCMDataFormatEx& dataFormat, int numChannels, double sampleRate) + { + dataFormat.formatType = SL_DATAFORMAT_PCM; + dataFormat.numChannels = (SLuint32) numChannels; + dataFormat.samplesPerSec = (SLuint32) (sampleRate * 1000); + dataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; + dataFormat.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; + dataFormat.channelMask = (numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : + (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT); + dataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN; + dataFormat.representation = 0; + } + + static void prepareCallbackBuffer (AudioSampleBuffer&, int16*) {} + + static void convertFromOpenSL (const int16* srcInterleaved, AudioSampleBuffer& audioBuffer) + { + for (int i = 0; i < audioBuffer.getNumChannels(); ++i) + { + typedef AudioData::Pointer DstSampleType; + typedef AudioData::Pointer SrcSampleType; + + DstSampleType dstData (audioBuffer.getWritePointer (i)); + SrcSampleType srcData (srcInterleaved + i, audioBuffer.getNumChannels()); + dstData.convertSamples (srcData, audioBuffer.getNumSamples()); + } + } + + static void convertToOpenSL (const AudioSampleBuffer& audioBuffer, int16* dstInterleaved) + { + for (int i = 0; i < audioBuffer.getNumChannels(); ++i) + { + typedef AudioData::Pointer DstSampleType; + typedef AudioData::Pointer SrcSampleType; + + DstSampleType dstData (dstInterleaved + i, audioBuffer.getNumChannels()); + SrcSampleType srcData (audioBuffer.getReadPointer (i)); + + dstData.convertSamples (srcData, audioBuffer.getNumSamples()); + } + } + +}; + +template <> +struct BufferHelpers +{ + enum { isFloatingPoint = 1 }; + + static void initPCMDataFormat (PCMDataFormatEx& dataFormat, int numChannels, double sampleRate) + { + dataFormat.formatType = SL_ANDROID_DATAFORMAT_PCM_EX; + dataFormat.numChannels = (SLuint32) numChannels; + dataFormat.samplesPerSec = (SLuint32) (sampleRate * 1000); + dataFormat.bitsPerSample = 32; + dataFormat.containerSize = 32; + dataFormat.channelMask = (numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : + (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT); + dataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN; + dataFormat.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT; + } + + static void prepareCallbackBuffer (AudioSampleBuffer& audioBuffer, float* native) + { + if (audioBuffer.getNumChannels() == 1) + audioBuffer.setDataToReferTo (&native, 1, audioBuffer.getNumSamples()); + } + + static void convertFromOpenSL (const float* srcInterleaved, AudioSampleBuffer& audioBuffer) + { + if (audioBuffer.getNumChannels() == 1) + { + jassert (srcInterleaved == audioBuffer.getWritePointer (0)); + return; + } + + for (int i = 0; i < audioBuffer.getNumChannels(); ++i) + { + typedef AudioData::Pointer DstSampleType; + typedef AudioData::Pointer SrcSampleType; + + DstSampleType dstData (audioBuffer.getWritePointer (i)); + SrcSampleType srcData (srcInterleaved + i, audioBuffer.getNumChannels()); + dstData.convertSamples (srcData, audioBuffer.getNumSamples()); + } + } + + static void convertToOpenSL (const AudioSampleBuffer& audioBuffer, float* dstInterleaved) + { + if (audioBuffer.getNumChannels() == 1) + { + jassert (dstInterleaved == audioBuffer.getReadPointer (0)); + return; + } + + for (int i = 0; i < audioBuffer.getNumChannels(); ++i) + { + typedef AudioData::Pointer DstSampleType; + typedef AudioData::Pointer SrcSampleType; + + DstSampleType dstData (dstInterleaved + i, audioBuffer.getNumChannels()); + SrcSampleType srcData (audioBuffer.getReadPointer (i)); + + dstData.convertSamples (srcData, audioBuffer.getNumSamples()); + } + } +}; + +class SLRealtimeThread; + +//============================================================================== +class OpenSLAudioIODevice : public AudioIODevice +{ +public: + //============================================================================== + template + class OpenSLSessionT; + + //============================================================================== + // CRTP + template + struct OpenSLQueueRunner + { + OpenSLQueueRunner (OpenSLSessionT& sessionToUse, int numChannelsToUse) + : owner (sessionToUse), + numChannels (numChannelsToUse), + nativeBuffer (static_cast (numChannels * owner.bufferSize * owner.numBuffers)), + scratchBuffer (numChannelsToUse, owner.bufferSize), + sampleBuffer (scratchBuffer.getArrayOfWritePointers(), numChannelsToUse, owner.bufferSize), + nextBlock (0), numBlocksOut (0) + {} + + bool init() + { + runner = crtp().createPlayerOrRecorder(); + if (runner == nullptr) + return false; + + queue = SlRef::cast (runner); + if (queue == nullptr) + return false; + + return ((*queue)->RegisterCallback (queue, staticFinished, this) == SL_RESULT_SUCCESS); + } + + + void clear() + { + nextBlock.set (0); + numBlocksOut.set (0); + + zeromem (nativeBuffer.getData(), static_cast (owner.bufferSize * numChannels * owner.numBuffers) * sizeof (T)); + scratchBuffer.clear(); + (*queue)->Clear (queue); + } + + void enqueueBuffer() + { + (*queue)->Enqueue (queue, getCurrentBuffer(), static_cast (getBufferSizeInSamples() * sizeof (T))); + ++numBlocksOut; + } + + bool isBufferAvailable() const { return (numBlocksOut.get() < owner.numBuffers); } + T* getNextBuffer() { nextBlock.set((nextBlock.get() + 1) % owner.numBuffers); return getCurrentBuffer(); } + T* getCurrentBuffer() { return nativeBuffer.getData() + (static_cast (nextBlock.get()) * getBufferSizeInSamples()); } + size_t getBufferSizeInSamples() const { return static_cast (owner.bufferSize * numChannels); } + + void finished (SLAndroidSimpleBufferQueueItf) + { + attachAndroidJNI(); + + --numBlocksOut; + owner.doSomeWorkOnAudioThread(); + } + + static void staticFinished (SLAndroidSimpleBufferQueueItf caller, void *pContext) + { + reinterpret_cast (pContext)->finished (caller); + } + + // get the "this" pointer for CRTP + Child& crtp() { return * ((Child*) this); } + const Child& crtp() const { return * ((Child*) this); } + + OpenSLSessionT& owner; + + SlRef runner; + SlRef queue; + + int numChannels; + + HeapBlock nativeBuffer; + AudioSampleBuffer scratchBuffer, sampleBuffer; + + Atomic nextBlock, numBlocksOut; + }; + + //============================================================================== + template + struct OpenSLQueueRunnerPlayer : OpenSLQueueRunner, SLPlayItf_> + { + typedef OpenSLQueueRunner, SLPlayItf_> Base; + + enum { isPlayer = 1 }; + + OpenSLQueueRunnerPlayer (OpenSLSessionT& sessionToUse, int numChannelsToUse) + : Base (sessionToUse, numChannelsToUse) + {} + + SlRef createPlayerOrRecorder() + { + SLDataLocator_AndroidSimpleBufferQueue queueLocator = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, static_cast (Base::owner.numBuffers)}; + SLDataLocator_OutputMix outputMix = {SL_DATALOCATOR_OUTPUTMIX, Base::owner.outputMix}; + + PCMDataFormatEx dataFormat; + BufferHelpers::initPCMDataFormat (dataFormat, Base::numChannels, Base::owner.sampleRate); + + SLDataSource source = {&queueLocator, &dataFormat}; + SLDataSink sink = {&outputMix, nullptr}; + + SLInterfaceID queueInterfaces[] = { &IntfIID::iid }; + SLboolean trueFlag = SL_BOOLEAN_TRUE; + + SLObjectItf obj = nullptr; + + SLresult status = (*Base::owner.engine)->CreateAudioPlayer (Base::owner.engine, &obj, &source, &sink, 1, queueInterfaces, &trueFlag); + if (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) + { + if (obj != nullptr) + (*obj)->Destroy (obj); + + return SlRef(); + } + + return SlRef::cast (SlObjectRef (obj)); + } + + void setState (bool running) { (*Base::runner)->SetPlayState (Base::runner, running ? SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_STOPPED); } + }; + + template + struct OpenSLQueueRunnerRecorder : OpenSLQueueRunner, SLRecordItf_> + { + typedef OpenSLQueueRunner, SLRecordItf_> Base; + + enum { isPlayer = 0 }; + + OpenSLQueueRunnerRecorder (OpenSLSessionT& sessionToUse, int numChannelsToUse) + : Base (sessionToUse, numChannelsToUse) + {} + + SlRef createPlayerOrRecorder() + { + SLDataLocator_IODevice ioDeviceLocator = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, nullptr}; + SLDataLocator_AndroidSimpleBufferQueue queueLocator = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, static_cast (Base::owner.numBuffers)}; + + PCMDataFormatEx dataFormat; + BufferHelpers::initPCMDataFormat (dataFormat, Base::numChannels, Base::owner.sampleRate); + + SLDataSource source = {&ioDeviceLocator, nullptr}; + SLDataSink sink = {&queueLocator, &dataFormat}; + + SLInterfaceID queueInterfaces[] = { &IntfIID::iid, &IntfIID::iid }; + SLboolean interfaceRequired[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE}; + + SLObjectItf obj = nullptr; + + SLresult status = (*Base::owner.engine)->CreateAudioRecorder (Base::owner.engine, &obj, &source, &sink, 2, queueInterfaces, interfaceRequired); + if (status != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) + { + if (obj != nullptr) + (*obj)->Destroy (obj); + + return SlRef(); + } + + SlRef recorder = SlRef::cast (SlObjectRef (obj)); + + // may return nullptr on some platforms - that's ok + config = SlRef::cast (recorder); + + return recorder; + } + + bool setAudioPreprocessingEnabled (bool shouldEnable) + { + if (config != nullptr) + { + const bool supportsUnprocessed = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 25); + const SLuint32 recordingPresetValue + = (shouldEnable ? SL_ANDROID_RECORDING_PRESET_GENERIC + : (supportsUnprocessed ? SL_ANDROID_RECORDING_PRESET_UNPROCESSED + : SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION)); + + SLresult status = (*config)->SetConfiguration (config, SL_ANDROID_KEY_RECORDING_PRESET, + &recordingPresetValue, sizeof (recordingPresetValue)); + + return (status == SL_RESULT_SUCCESS); + } + + return false; + } + + void setState (bool running) { (*Base::runner)->SetRecordState (Base::runner, running ? SL_RECORDSTATE_RECORDING : SL_RECORDSTATE_STOPPED); } + + SlRef config; + }; + + //============================================================================== + class OpenSLSession + { + public: + OpenSLSession (DynamicLibrary& slLibraryToUse, + int numInputChannels, int numOutputChannels, + double samleRateToUse, int bufferSizeToUse, + int numBuffersToUse) + : inputChannels (numInputChannels), outputChannels (numOutputChannels), + sampleRate (samleRateToUse), bufferSize (bufferSizeToUse), numBuffers (numBuffersToUse), + running (false), audioProcessingEnabled (true), callback (nullptr) + { + jassert (numInputChannels > 0 || numOutputChannels > 0); + + if (CreateEngineFunc createEngine = (CreateEngineFunc) slLibraryToUse.getFunction ("slCreateEngine")) + { + SLObjectItf obj = nullptr; + + SLresult err = createEngine (&obj, 0, nullptr, 0, nullptr, nullptr); + if (err != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) + { + if (obj != nullptr) + (*obj)->Destroy (obj); + + return; + } + + engine = SlRef::cast (SlObjectRef (obj)); + } + + if (outputChannels > 0) + { + SLObjectItf obj = nullptr; + + SLresult err = (*engine)->CreateOutputMix (engine, &obj, 0, nullptr, nullptr); + if (err != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) + { + if (obj != nullptr) + (*obj)->Destroy (obj); + + return; + } + + outputMix = SlRef::cast (SlObjectRef (obj)); + } + } + + virtual ~OpenSLSession() {} + + virtual bool openedOK() const { return (engine != nullptr && (outputChannels == 0 || (outputMix != nullptr))); } + virtual void start() { stop(); jassert (callback.get() != nullptr); running = true; } + virtual void stop() { running = false; } + virtual bool setAudioPreprocessingEnabled (bool shouldEnable) = 0; + virtual bool supportsFloatingPoint() const noexcept = 0; + + void setCallback (AudioIODeviceCallback* callbackToUse) + { + if (! running) + { + callback.set (callbackToUse); + return; + } + + // don't set callback to null! stop the playback instead! + jassert (callbackToUse != nullptr); + + // spin-lock until we can set the callback + while (true) + { + AudioIODeviceCallback* old = callback.get(); + if (old == callbackToUse) + break; + + if (callback.compareAndSetBool (callbackToUse, old)) + break; + + Thread::sleep (1); + } + } + + void process (const float** inputChannelData, float** outputChannelData) + { + if (AudioIODeviceCallback* cb = callback.exchange(nullptr)) + { + cb->audioDeviceIOCallback (inputChannelData, inputChannels, outputChannelData, outputChannels, bufferSize); + callback.set (cb); + } + else + { + for (int i = 0; i < outputChannels; ++i) + zeromem (outputChannelData[i], sizeof(float) * static_cast (bufferSize)); + } + } + + static OpenSLSession* create (DynamicLibrary& slLibrary, + int numInputChannels, int numOutputChannels, + double samleRateToUse, int bufferSizeToUse, + int numBuffersToUse); + + //============================================================================== + typedef SLresult (*CreateEngineFunc)(SLObjectItf*,SLuint32,const SLEngineOption*,SLuint32,const SLInterfaceID*,const SLboolean*); + + //============================================================================== + int inputChannels, outputChannels; + double sampleRate; + int bufferSize, numBuffers; + + bool running, audioProcessingEnabled; + + SlRef engine; + SlRef outputMix; + + Atomic callback; + }; + + template + class OpenSLSessionT : public OpenSLSession + { + public: + OpenSLSessionT (DynamicLibrary& slLibraryToUse, + int numInputChannels, int numOutputChannels, + double samleRateToUse, int bufferSizeToUse, + int numBuffersToUse) + : OpenSLSession (slLibraryToUse, numInputChannels, numOutputChannels, samleRateToUse, bufferSizeToUse, numBuffersToUse) + { + jassert (numInputChannels > 0 || numOutputChannels > 0); + + if (OpenSLSession::openedOK()) + { + if (inputChannels > 0) + { + recorder = new OpenSLQueueRunnerRecorder(*this, inputChannels); + + if (! recorder->init()) + { + recorder = nullptr; + return; + } + } + + if (outputChannels > 0) + { + player = new OpenSLQueueRunnerPlayer(*this, outputChannels); + + if (! player->init()) + { + player = nullptr; + return; + } + } + } + } + + bool openedOK() const override + { + return (OpenSLSession::openedOK() && (inputChannels == 0 || recorder != nullptr) + && (outputChannels == 0 || player != nullptr)); + } + + void start() override + { + OpenSLSession::start(); + + guard.set (0); + + if (inputChannels > 0) + recorder->clear(); + + if (outputChannels > 0) + player->clear(); + + // first enqueue all buffers + for (int i = 0; i < numBuffers; ++i) + doSomeWorkOnAudioThread(); + + if (inputChannels > 0) + recorder->setState (true); + + if (outputChannels > 0) + player->setState (true); + } + + void stop() override + { + OpenSLSession::stop(); - 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 (inputChannels > 0) + recorder->setState (false); - ============================================================================== -*/ + if (outputChannels > 0) + player->setState (false); + } -#undef check + bool setAudioPreprocessingEnabled (bool shouldEnable) override + { + if (shouldEnable != audioProcessingEnabled) + { + audioProcessingEnabled = shouldEnable; -const char* const openSLTypeName = "Android OpenSL"; + if (recorder != nullptr) + return recorder->setAudioPreprocessingEnabled (audioProcessingEnabled); + } -bool isOpenSLAvailable() -{ - DynamicLibrary library; - return library.open ("libOpenSLES.so"); -} + return true; + } -//============================================================================== -class OpenSLAudioIODevice : public AudioIODevice, - private Thread -{ -public: + bool supportsFloatingPoint() const noexcept override { return (BufferHelpers::isFloatingPoint != 0); } + + void doSomeWorkOnAudioThread() + { + // only the player or the recorder should enter this section at any time + if (guard.compareAndSetBool (1, 0)) + { + // are there enough buffers avaialable to process some audio + if ((inputChannels == 0 || recorder->isBufferAvailable()) && (outputChannels == 0 || player->isBufferAvailable())) + { + T* recorderBuffer = (inputChannels > 0 ? recorder->getNextBuffer() : nullptr); + T* playerBuffer = (outputChannels > 0 ? player->getNextBuffer() : nullptr); + + const float** inputChannelData = nullptr; + float** outputChannelData = nullptr; + + if (recorderBuffer != nullptr) + { + BufferHelpers::prepareCallbackBuffer (recorder->sampleBuffer, recorderBuffer); + BufferHelpers::convertFromOpenSL (recorderBuffer, recorder->sampleBuffer); + + inputChannelData = recorder->sampleBuffer.getArrayOfReadPointers(); + } + + if (playerBuffer != nullptr) + { + BufferHelpers::prepareCallbackBuffer (player->sampleBuffer, playerBuffer); + outputChannelData = player->sampleBuffer.getArrayOfWritePointers(); + } + + process (inputChannelData, outputChannelData); + + if (recorderBuffer != nullptr) + recorder->enqueueBuffer(); + + if (playerBuffer != nullptr) + { + BufferHelpers::convertToOpenSL (player->sampleBuffer, playerBuffer); + player->enqueueBuffer(); + } + } + + guard.set (0); + } + } + + //============================================================================== + ScopedPointer > player; + ScopedPointer > recorder; + Atomic guard; + }; + + //============================================================================== OpenSLAudioIODevice (const String& deviceName) : AudioIODevice (deviceName, openSLTypeName), - Thread ("OpenSL"), - callback (nullptr), sampleRate (0), deviceOpen (false), - inputBuffer (2, 2), outputBuffer (2, 2) + actualBufferSize (0), sampleRate (0), + audioProcessingEnabled (true), + callback (nullptr) { // OpenSL has piss-poor support for determining latency, so the only way I can find to // get a number for this is by asking the AudioTrack/AudioRecord classes.. @@ -62,6 +743,12 @@ public: const int64 totalLatency = inputLatency + outputLatency; inputLatency = (int) ((longestLatency * inputLatency) / totalLatency) & ~15; outputLatency = (int) ((longestLatency * outputLatency) / totalLatency) & ~15; + + bool success = slLibrary.open ("libOpenSLES.so"); + + // You can only create this class if you are sure that your hardware supports OpenSL + jassert (success); + ignoreUnused (success); } ~OpenSLAudioIODevice() @@ -69,7 +756,7 @@ public: close(); } - bool openedOk() const { return engine.outputMixObject != nullptr; } + bool openedOk() const { return session != nullptr; } StringArray getOutputChannelNames() override { @@ -88,7 +775,10 @@ public: Array getAvailableSampleRates() override { - static const double rates[] = { 8000.0, 16000.0, 32000.0, 44100.0, 48000.0 }; + //see https://developer.android.com/ndk/guides/audio/opensl-for-android.html + + static const double rates[] = { 8000.0, 11025.0, 12000.0, 16000.0, + 22050.0, 24000.0, 32000.0, 44100.0, 48000.0 }; Array retval (rates, numElementsInArray (rates)); // make sure the native sample rate is pafrt of the list @@ -127,81 +817,70 @@ public: activeOutputChans = outputChannels; activeOutputChans.setRange (2, activeOutputChans.getHighestBit(), false); - numOutputChannels = activeOutputChans.countNumberOfSetBits(); + int numOutputChannels = activeOutputChans.countNumberOfSetBits(); activeInputChans = inputChannels; activeInputChans.setRange (1, activeInputChans.getHighestBit(), false); - numInputChannels = activeInputChans.countNumberOfSetBits(); + int numInputChannels = activeInputChans.countNumberOfSetBits(); actualBufferSize = preferredBufferSize; - inputBuffer.setSize (jmax (1, numInputChannels), actualBufferSize); - outputBuffer.setSize (jmax (1, numOutputChannels), actualBufferSize); - outputBuffer.clear(); - const int audioBuffersToEnqueue = hasLowLatencyAudioPath() ? buffersToEnqueueForLowLatency : buffersToEnqueueSlowAudio; - DBG ("OpenSL: numInputChannels = " << numInputChannels - << ", numOutputChannels = " << numOutputChannels - << ", nativeBufferSize = " << getNativeBufferSize() - << ", nativeSampleRate = " << getNativeSampleRate() - << ", actualBufferSize = " << actualBufferSize - << ", audioBuffersToEnqueue = " << audioBuffersToEnqueue - << ", sampleRate = " << sampleRate); - - if (numInputChannels > 0) + if (numInputChannels > 0 && (! RuntimePermissions::isGranted (RuntimePermissions::recordAudio))) { - if (! RuntimePermissions::isGranted (RuntimePermissions::recordAudio)) - { - // If you hit this assert, you probably forgot to get RuntimePermissions::recordAudio - // before trying to open an audio input device. This is not going to work! - jassertfalse; - lastError = "Error opening OpenSL input device: the app was not granted android.permission.RECORD_AUDIO"; - } - else - { - recorder = engine.createRecorder (numInputChannels, sampleRate, - audioBuffersToEnqueue, actualBufferSize); - - if (recorder == nullptr) - lastError = "Error opening OpenSL input device: creating Recorder failed."; - } + // If you hit this assert, you probably forgot to get RuntimePermissions::recordAudio + // before trying to open an audio input device. This is not going to work! + jassertfalse; + lastError = "Error opening OpenSL input device: the app was not granted android.permission.RECORD_AUDIO"; } - if (numOutputChannels > 0) + session = OpenSLSession::create (slLibrary, numInputChannels, numOutputChannels, + sampleRate, actualBufferSize, audioBuffersToEnqueue); + if (session != nullptr) + session->setAudioPreprocessingEnabled (audioProcessingEnabled); + else { - player = engine.createPlayer (numOutputChannels, sampleRate, - audioBuffersToEnqueue, actualBufferSize); + if (numInputChannels > 0 && numOutputChannels > 0 && RuntimePermissions::isGranted (RuntimePermissions::recordAudio)) + { + // New versions of the Android emulator do not seem to support audio input anymore on OS X + activeInputChans = BigInteger(0); + numInputChannels = 0; - if (player == nullptr) - lastError = "Error opening OpenSL input device: creating Player failed."; + session = OpenSLSession::create(slLibrary, numInputChannels, numOutputChannels, + sampleRate, actualBufferSize, audioBuffersToEnqueue); + } } - // pre-fill buffers - for (int i = 0; i < audioBuffersToEnqueue; ++i) - processBuffers(); - - startThread (8); - - deviceOpen = true; + DBG ("OpenSL: numInputChannels = " << numInputChannels + << ", numOutputChannels = " << numOutputChannels + << ", nativeBufferSize = " << getNativeBufferSize() + << ", nativeSampleRate = " << getNativeSampleRate() + << ", actualBufferSize = " << actualBufferSize + << ", audioBuffersToEnqueue = " << audioBuffersToEnqueue + << ", sampleRate = " << sampleRate + << ", supportsFloatingPoint = " << (session != nullptr && session->supportsFloatingPoint() ? "true" : "false")); + + if (session == nullptr) + lastError = "Unknown error initializing opensl session"; + + deviceOpen = (session != nullptr); return lastError; } void close() override { stop(); - stopThread (6000); - deviceOpen = false; - recorder = nullptr; - player = nullptr; + session = nullptr; + callback = nullptr; } int getOutputLatencyInSamples() override { return outputLatency; } int getInputLatencyInSamples() override { return inputLatency; } bool isOpen() override { return deviceOpen; } int getCurrentBufferSizeSamples() override { return actualBufferSize; } - int getCurrentBitDepth() override { return 16; } + int getCurrentBitDepth() override { return (session != nullptr && session->supportsFloatingPoint() ? 32 : 16); } BigInteger getActiveOutputChannels() const override { return activeOutputChans; } BigInteger getActiveInputChannels() const override { return activeInputChans; } String getLastError() override { return lastError; } @@ -223,48 +902,79 @@ public: void start (AudioIODeviceCallback* newCallback) override { - stop(); - - if (deviceOpen && callback != newCallback) + if (session != nullptr && callback != newCallback) { + AudioIODeviceCallback* oldCallback = callback; + if (newCallback != nullptr) newCallback->audioDeviceAboutToStart (this); - setCallback (newCallback); + if (oldCallback != nullptr) + { + // already running + if (newCallback == nullptr) + stop(); + else + session->setCallback (newCallback); + + oldCallback->audioDeviceStopped(); + } + else + { + jassert (newCallback != nullptr); + + // session hasn't started yet + session->setCallback (newCallback); + session->start(); + } + + callback = newCallback; } } void stop() override { - if (AudioIODeviceCallback* const oldCallback = setCallback (nullptr)) - oldCallback->audioDeviceStopped(); + if (session != nullptr && callback != nullptr) + { + callback = nullptr; + session->stop(); + session->setCallback (nullptr); + } } - bool setAudioPreprocessingEnabled (bool enable) override + bool setAudioPreprocessingEnabled (bool shouldAudioProcessingBeEnabled) override { - return recorder != nullptr && recorder->setAudioPreprocessingEnabled (enable); + audioProcessingEnabled = shouldAudioProcessingBeEnabled; + + if (session != nullptr) + session->setAudioPreprocessingEnabled (audioProcessingEnabled); + + return true; } + static const char* const openSLTypeName; + private: //============================================================================== - CriticalSection callbackLock; - AudioIODeviceCallback* callback; + friend class SLRealtimeThread; + + //============================================================================== + DynamicLibrary slLibrary; int actualBufferSize, sampleRate; int inputLatency, outputLatency; - bool deviceOpen; + bool deviceOpen, audioProcessingEnabled; String lastError; BigInteger activeOutputChans, activeInputChans; - int numInputChannels, numOutputChannels; - AudioSampleBuffer inputBuffer, outputBuffer; - struct Player; - struct Recorder; + AudioIODeviceCallback* callback; + + ScopedPointer session; enum { // The number of buffers to enqueue needs to be at least two for the audio to use the low-latency // audio path (see "Performance" section in ndk/docs/Additional_library_docs/opensles/index.html) - buffersToEnqueueForLowLatency = 2, - buffersToEnqueueSlowAudio = 4, + buffersToEnqueueForLowLatency = 4, + buffersToEnqueueSlowAudio = 8, defaultBufferSizeIsMultipleOfNative = 1 }; @@ -277,7 +987,7 @@ private: if (text.get() != 0) return juceString (text); - return String(); + return {}; } static bool androidHasSystemFeature (const String& property) @@ -307,473 +1017,264 @@ private: return androidHasSystemFeature ("android.hardware.audio.low_latency"); } - //============================================================================== - AudioIODeviceCallback* setCallback (AudioIODeviceCallback* const newCallback) - { - const ScopedLock sl (callbackLock); - AudioIODeviceCallback* const oldCallback = callback; - callback = newCallback; - return oldCallback; - } - - void processBuffers() - { - if (recorder != nullptr) - recorder->readNextBlock (inputBuffer, *this); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenSLAudioIODevice) +}; - { - const ScopedLock sl (callbackLock); +OpenSLAudioIODevice::OpenSLSession* OpenSLAudioIODevice::OpenSLSession::create (DynamicLibrary& slLibrary, + int numInputChannels, int numOutputChannels, + double samleRateToUse, int bufferSizeToUse, + int numBuffersToUse) +{ + ScopedPointer retval; + auto sdkVersion = getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT); - if (callback != nullptr) - callback->audioDeviceIOCallback (numInputChannels > 0 ? inputBuffer.getArrayOfReadPointers() : nullptr, numInputChannels, - numOutputChannels > 0 ? outputBuffer.getArrayOfWritePointers() : nullptr, numOutputChannels, - actualBufferSize); - else - outputBuffer.clear(); - } + // SDK versions 21 and higher should natively support floating point... + if (sdkVersion >= 21) + { + retval = new OpenSLSessionT (slLibrary, numInputChannels, numOutputChannels, samleRateToUse, + bufferSizeToUse, numBuffersToUse); - if (player != nullptr) - player->writeBuffer (outputBuffer, *this); + // ...however, some devices lie so re-try without floating point + if (retval != nullptr && (! retval->openedOK())) + retval = nullptr; } - void run() override + if (retval == nullptr) { - setThreadToAudioPriority(); + retval = new OpenSLSessionT (slLibrary, numInputChannels, numOutputChannels, samleRateToUse, + bufferSizeToUse, numBuffersToUse); - if (recorder != nullptr) recorder->start(); - if (player != nullptr) player->start(); - - while (! threadShouldExit()) - processBuffers(); + if (retval != nullptr && (! retval->openedOK())) + retval = nullptr; } - void setThreadToAudioPriority() - { - // see android.os.Process.THREAD_PRIORITY_AUDIO - const int THREAD_PRIORITY_AUDIO = -16; - jint priority = THREAD_PRIORITY_AUDIO; + return retval.release(); +} - if (priority != android.activity.callIntMethod (JuceAppActivity.setCurrentThreadPriority, (jint) priority)) - DBG ("Unable to set audio thread priority: priority is still " << priority); - } +//============================================================================== +class OpenSLAudioDeviceType : public AudioIODeviceType +{ +public: + OpenSLAudioDeviceType() : AudioIODeviceType (OpenSLAudioIODevice::openSLTypeName) {} //============================================================================== - struct Engine - { - Engine() - : engineObject (nullptr), engineInterface (nullptr), outputMixObject (nullptr) - { - if (library.open ("libOpenSLES.so")) - { - typedef SLresult (*CreateEngineFunc) (SLObjectItf*, SLuint32, const SLEngineOption*, - SLuint32, const SLInterfaceID*, const SLboolean*); + void scanForDevices() override {} - if (CreateEngineFunc createEngine = (CreateEngineFunc) library.getFunction ("slCreateEngine")) - { - check (createEngine (&engineObject, 0, nullptr, 0, nullptr, nullptr)); + StringArray getDeviceNames (bool) const override { return StringArray (OpenSLAudioIODevice::openSLTypeName); } + int getDefaultDeviceIndex (bool) const override { return 0; } + int getIndexOfDevice (AudioIODevice* device, bool) const override { return device != nullptr ? 0 : -1; } + bool hasSeparateInputsAndOutputs() const override { return false; } - SLInterfaceID* SL_IID_ENGINE = (SLInterfaceID*) library.getFunction ("SL_IID_ENGINE"); - SL_IID_ANDROIDSIMPLEBUFFERQUEUE = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDSIMPLEBUFFERQUEUE"); - SL_IID_PLAY = (SLInterfaceID*) library.getFunction ("SL_IID_PLAY"); - SL_IID_RECORD = (SLInterfaceID*) library.getFunction ("SL_IID_RECORD"); - SL_IID_ANDROIDCONFIGURATION = (SLInterfaceID*) library.getFunction ("SL_IID_ANDROIDCONFIGURATION"); + AudioIODevice* createDevice (const String& outputDeviceName, + const String& inputDeviceName) override + { + ScopedPointer dev; - check ((*engineObject)->Realize (engineObject, SL_BOOLEAN_FALSE)); - check ((*engineObject)->GetInterface (engineObject, *SL_IID_ENGINE, &engineInterface)); + if (outputDeviceName.isNotEmpty() || inputDeviceName.isNotEmpty()) + dev = new OpenSLAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName + : inputDeviceName); - check ((*engineInterface)->CreateOutputMix (engineInterface, &outputMixObject, 0, nullptr, nullptr)); - check ((*outputMixObject)->Realize (outputMixObject, SL_BOOLEAN_FALSE)); - } - } - } + return dev.release(); + } - ~Engine() - { - if (outputMixObject != nullptr) (*outputMixObject)->Destroy (outputMixObject); - if (engineObject != nullptr) (*engineObject)->Destroy (engineObject); - } + static bool isOpenSLAvailable() + { + DynamicLibrary library; + return library.open ("libOpenSLES.so"); + } - Player* createPlayer (const int numChannels, const int sampleRate, const int numBuffers, const int bufferSize) - { - if (numChannels <= 0) - return nullptr; +private: - ScopedPointer player (new Player (numChannels, sampleRate, *this, numBuffers, bufferSize)); - return player->openedOk() ? player.release() : nullptr; - } - Recorder* createRecorder (const int numChannels, const int sampleRate, const int numBuffers, const int bufferSize) - { - if (numChannels <= 0) - return nullptr; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenSLAudioDeviceType) +}; - ScopedPointer recorder (new Recorder (numChannels, sampleRate, *this, numBuffers, bufferSize)); - return recorder->openedOk() ? recorder.release() : nullptr; - } +const char* const OpenSLAudioIODevice::openSLTypeName = "Android OpenSL"; - SLObjectItf engineObject; - SLEngineItf engineInterface; - SLObjectItf outputMixObject; - SLInterfaceID* SL_IID_ANDROIDSIMPLEBUFFERQUEUE; - SLInterfaceID* SL_IID_PLAY; - SLInterfaceID* SL_IID_RECORD; - SLInterfaceID* SL_IID_ANDROIDCONFIGURATION; +//============================================================================== +bool isOpenSLAvailable() { return OpenSLAudioDeviceType::isOpenSLAvailable(); } - private: - DynamicLibrary library; +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() +{ + return isOpenSLAvailable() ? new OpenSLAudioDeviceType() : nullptr; +} - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Engine) - }; +//============================================================================== +class SLRealtimeThread +{ +public: + static constexpr int numBuffers = 4; - //============================================================================== - struct BufferList + SLRealtimeThread() { - BufferList (const int numChannels_, const int numBuffers_, const int numSamples_) - : numChannels (numChannels_), numBuffers (numBuffers_), numSamples (numSamples_), - bufferSpace (numChannels_ * numSamples * numBuffers), nextBlock (0) + if (auto createEngine = (OpenSLAudioIODevice::OpenSLSession::CreateEngineFunc) slLibrary.getFunction ("slCreateEngine")) { - } + SLObjectItf obj = nullptr; + auto err = createEngine (&obj, 0, nullptr, 0, nullptr, nullptr); - int16* waitForFreeBuffer (Thread& threadToCheck) noexcept - { - while (numBlocksOut.get() == numBuffers) - { - dataArrived.wait (1); + if (err != SL_RESULT_SUCCESS || obj == nullptr) + return; - if (threadToCheck.threadShouldExit()) - return nullptr; + if ((*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) + { + (*obj)->Destroy (obj); + return; } - return getNextBuffer(); - } - - int16* getNextBuffer() noexcept - { - if (++nextBlock == numBuffers) - nextBlock = 0; - - return bufferSpace + nextBlock * numChannels * numSamples; - } - - void bufferReturned() noexcept { --numBlocksOut; dataArrived.signal(); } - void bufferSent() noexcept { ++numBlocksOut; dataArrived.signal(); } - - int getBufferSizeBytes() const noexcept { return numChannels * numSamples * sizeof (int16); } + engine = SlRef::cast (SlObjectRef (obj)); - const int numChannels, numBuffers, numSamples; + if (engine == nullptr) + { + (*obj)->Destroy (obj); + return; + } - private: - HeapBlock bufferSpace; - int nextBlock; - Atomic numBlocksOut; - WaitableEvent dataArrived; - }; + obj = nullptr; + err = (*engine)->CreateOutputMix (engine, &obj, 0, nullptr, nullptr); - //============================================================================== - struct Player - { - Player (int numChannels, int sampleRate, Engine& engine, int playerNumBuffers, int playerBufferSize) - : playerObject (nullptr), playerPlay (nullptr), playerBufferQueue (nullptr), - bufferList (numChannels, playerNumBuffers, playerBufferSize) - { - SLDataFormat_PCM pcmFormat = + if (err != SL_RESULT_SUCCESS || obj == nullptr || (*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) { - SL_DATAFORMAT_PCM, - (SLuint32) numChannels, - (SLuint32) (sampleRate * 1000), - SL_PCMSAMPLEFORMAT_FIXED_16, - SL_PCMSAMPLEFORMAT_FIXED_16, - (numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT), - SL_BYTEORDER_LITTLEENDIAN - }; - - SLDataLocator_AndroidSimpleBufferQueue bufferQueue = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, - static_cast (bufferList.numBuffers) }; - SLDataSource audioSrc = { &bufferQueue, &pcmFormat }; - - SLDataLocator_OutputMix outputMix = { SL_DATALOCATOR_OUTPUTMIX, engine.outputMixObject }; - SLDataSink audioSink = { &outputMix, nullptr }; - - // (SL_IID_BUFFERQUEUE is not guaranteed to remain future-proof, so use SL_IID_ANDROIDSIMPLEBUFFERQUEUE) - const SLInterfaceID interfaceIDs[] = { *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE }; - const SLboolean flags[] = { SL_BOOLEAN_TRUE }; - - check ((*engine.engineInterface)->CreateAudioPlayer (engine.engineInterface, &playerObject, &audioSrc, &audioSink, - 1, interfaceIDs, flags)); - - check ((*playerObject)->Realize (playerObject, SL_BOOLEAN_FALSE)); - check ((*playerObject)->GetInterface (playerObject, *engine.SL_IID_PLAY, &playerPlay)); - check ((*playerObject)->GetInterface (playerObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &playerBufferQueue)); - check ((*playerBufferQueue)->RegisterCallback (playerBufferQueue, staticCallback, this)); - } + (*obj)->Destroy (obj); + return; + } - ~Player() - { - if (playerPlay != nullptr) - check ((*playerPlay)->SetPlayState (playerPlay, SL_PLAYSTATE_STOPPED)); + outputMix = SlRef::cast (SlObjectRef (obj)); - if (playerBufferQueue != nullptr) - check ((*playerBufferQueue)->Clear (playerBufferQueue)); + if (outputMix == nullptr) + { + (*obj)->Destroy (obj); + return; + } - if (playerObject != nullptr) - (*playerObject)->Destroy (playerObject); - } + SLDataLocator_AndroidSimpleBufferQueue queueLocator = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, static_cast (numBuffers)}; + SLDataLocator_OutputMix outputMixLocator = {SL_DATALOCATOR_OUTPUTMIX, outputMix}; - bool openedOk() const noexcept { return playerBufferQueue != nullptr; } + PCMDataFormatEx dataFormat; + BufferHelpers::initPCMDataFormat (dataFormat, 1, OpenSLAudioIODevice::getNativeSampleRate()); - void start() - { - jassert (openedOk()); + SLDataSource source = { &queueLocator, &dataFormat }; + SLDataSink sink = { &outputMixLocator, nullptr }; - check ((*playerPlay)->SetPlayState (playerPlay, SL_PLAYSTATE_PLAYING)); - } + SLInterfaceID queueInterfaces[] = { &IntfIID::iid }; + SLboolean trueFlag = SL_BOOLEAN_TRUE; - void writeBuffer (const AudioSampleBuffer& buffer, Thread& thread) noexcept - { - jassert (buffer.getNumChannels() == bufferList.numChannels); - jassert (buffer.getNumSamples() < bufferList.numSamples * bufferList.numBuffers); + obj = nullptr; + err = (*engine)->CreateAudioPlayer (engine, &obj, &source, &sink, 1, queueInterfaces, &trueFlag); - int offset = 0; - int numSamples = buffer.getNumSamples(); + if (err != SL_RESULT_SUCCESS || obj == nullptr) + return; - while (numSamples > 0) + if ((*obj)->Realize (obj, 0) != SL_RESULT_SUCCESS) { - if (int16* const destBuffer = bufferList.waitForFreeBuffer (thread)) - { - for (int i = 0; i < bufferList.numChannels; ++i) - { - typedef AudioData::Pointer DstSampleType; - typedef AudioData::Pointer SrcSampleType; - - DstSampleType dstData (destBuffer + i, bufferList.numChannels); - SrcSampleType srcData (buffer.getReadPointer (i, offset)); - dstData.convertSamples (srcData, bufferList.numSamples); - } - - enqueueBuffer (destBuffer); - - numSamples -= bufferList.numSamples; - offset += bufferList.numSamples; - } - else - { - break; - } + (*obj)->Destroy (obj); + return; } - } - - private: - SLObjectItf playerObject; - SLPlayItf playerPlay; - SLAndroidSimpleBufferQueueItf playerBufferQueue; - BufferList bufferList; + player = SlRef::cast (SlObjectRef (obj)); - void enqueueBuffer (int16* buffer) noexcept - { - check ((*playerBufferQueue)->Enqueue (playerBufferQueue, buffer, bufferList.getBufferSizeBytes())); - bufferList.bufferSent(); - } - - static void staticCallback (SLAndroidSimpleBufferQueueItf queue, void* context) noexcept - { - jassert (queue == static_cast (context)->playerBufferQueue); ignoreUnused (queue); - static_cast (context)->bufferList.bufferReturned(); - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Player) - }; - - //============================================================================== - struct Recorder - { - Recorder (int numChannels, int sampleRate, Engine& engine, const int numBuffers, const int numSamples) - : recorderObject (nullptr), recorderRecord (nullptr), - recorderBufferQueue (nullptr), configObject (nullptr), - bufferList (numChannels, numBuffers, numSamples) - { - SLDataFormat_PCM pcmFormat = - { - SL_DATAFORMAT_PCM, - (SLuint32) numChannels, - (SLuint32) (sampleRate * 1000), // (sample rate units are millihertz) - SL_PCMSAMPLEFORMAT_FIXED_16, - SL_PCMSAMPLEFORMAT_FIXED_16, - (numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT), - SL_BYTEORDER_LITTLEENDIAN - }; - - SLDataLocator_IODevice ioDevice = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, nullptr }; - SLDataSource audioSrc = { &ioDevice, nullptr }; - - SLDataLocator_AndroidSimpleBufferQueue bufferQueue = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, - static_cast (bufferList.numBuffers) }; - SLDataSink audioSink = { &bufferQueue, &pcmFormat }; - - const SLInterfaceID interfaceIDs[] = { *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE }; - const SLboolean flags[] = { SL_BOOLEAN_TRUE }; - - if (check ((*engine.engineInterface)->CreateAudioRecorder (engine.engineInterface, &recorderObject, &audioSrc, - &audioSink, 1, interfaceIDs, flags))) + if (player == nullptr) { - if (check ((*recorderObject)->Realize (recorderObject, SL_BOOLEAN_FALSE))) - { - check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_RECORD, &recorderRecord)); - check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue)); - // not all android versions seem to have a config object - SLresult result = (*recorderObject)->GetInterface (recorderObject, - *engine.SL_IID_ANDROIDCONFIGURATION, &configObject); - if (result != SL_RESULT_SUCCESS) - configObject = nullptr; - - check ((*recorderBufferQueue)->RegisterCallback (recorderBufferQueue, staticCallback, this)); - check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_STOPPED)); - } + (*obj)->Destroy (obj); + return; } - } - ~Recorder() - { - if (recorderRecord != nullptr) - check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_STOPPED)); + queue = SlRef::cast (player); + if (queue == nullptr) + return; - if (recorderBufferQueue != nullptr) - check ((*recorderBufferQueue)->Clear (recorderBufferQueue)); + if ((*queue)->RegisterCallback (queue, staticFinished, this) != SL_RESULT_SUCCESS) + { + queue = nullptr; + return; + } - if (recorderObject != nullptr) - (*recorderObject)->Destroy (recorderObject); + pthread_cond_init (&threadReady, nullptr); + pthread_mutex_init (&threadReadyMutex, nullptr); } + } - bool openedOk() const noexcept { return recorderBufferQueue != nullptr; } + bool isOK() const { return queue != nullptr; } - void start() - { - jassert (openedOk()); - check ((*recorderRecord)->SetRecordState (recorderRecord, SL_RECORDSTATE_RECORDING)); - } + pthread_t startThread (void* (*entry) (void*), void* userPtr) + { + memset (buffer.getData(), 0, static_cast (sizeof (int16) * static_cast (bufferSize * numBuffers))); - void readNextBlock (AudioSampleBuffer& buffer, Thread& thread) + for (int i = 0; i < numBuffers; ++i) { - jassert (buffer.getNumChannels() == bufferList.numChannels); - jassert (buffer.getNumSamples() < bufferList.numSamples * bufferList.numBuffers); - jassert ((buffer.getNumSamples() % bufferList.numSamples) == 0); - - int offset = 0; - int numSamples = buffer.getNumSamples(); - - while (numSamples > 0) - { - if (int16* const srcBuffer = bufferList.waitForFreeBuffer (thread)) - { - for (int i = 0; i < bufferList.numChannels; ++i) - { - typedef AudioData::Pointer DstSampleType; - typedef AudioData::Pointer SrcSampleType; - - DstSampleType dstData (buffer.getWritePointer (i, offset)); - SrcSampleType srcData (srcBuffer + i, bufferList.numChannels); - dstData.convertSamples (srcData, bufferList.numSamples); - } - - enqueueBuffer (srcBuffer); - - numSamples -= bufferList.numSamples; - offset += bufferList.numSamples; - } - else - { - break; - } - } + int16* dst = buffer.getData() + (bufferSize * i); + (*queue)->Enqueue (queue, dst, static_cast (static_cast (bufferSize) * sizeof (int16))); } - bool setAudioPreprocessingEnabled (bool enable) - { - SLuint32 mode = enable ? SL_ANDROID_RECORDING_PRESET_GENERIC - : SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION; + pthread_mutex_lock (&threadReadyMutex); - return configObject != nullptr - && check ((*configObject)->SetConfiguration (configObject, SL_ANDROID_KEY_RECORDING_PRESET, &mode, sizeof (mode))); - } + threadEntryProc = entry; + threadUserPtr = userPtr; - private: - SLObjectItf recorderObject; - SLRecordItf recorderRecord; - SLAndroidSimpleBufferQueueItf recorderBufferQueue; - SLAndroidConfigurationItf configObject; + (*player)->SetPlayState (player, SL_PLAYSTATE_PLAYING); - BufferList bufferList; + pthread_cond_wait (&threadReady, &threadReadyMutex); + pthread_mutex_unlock (&threadReadyMutex); - void enqueueBuffer (int16* buffer) noexcept - { - check ((*recorderBufferQueue)->Enqueue (recorderBufferQueue, buffer, bufferList.getBufferSizeBytes())); - bufferList.bufferSent(); - } + return threadID; + } - static void staticCallback (SLAndroidSimpleBufferQueueItf queue, void* context) noexcept + void finished() + { + if (threadEntryProc != nullptr) { - jassert (queue == static_cast (context)->recorderBufferQueue); ignoreUnused (queue); - static_cast (context)->bufferList.bufferReturned(); - } + pthread_mutex_lock (&threadReadyMutex); - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Recorder) - }; + threadID = pthread_self(); + pthread_cond_signal (&threadReady); + pthread_mutex_unlock (&threadReadyMutex); - //============================================================================== - Engine engine; + threadEntryProc (threadUserPtr); + threadEntryProc = nullptr; - ScopedPointer player; - ScopedPointer recorder; + (*player)->SetPlayState (player, SL_PLAYSTATE_STOPPED); + MessageManager::callAsync ([this] () { delete this; }); + } + } - //============================================================================== - static bool check (const SLresult result) noexcept +private: + //============================================================================= + static void staticFinished (SLAndroidSimpleBufferQueueItf, void* context) { - jassert (result == SL_RESULT_SUCCESS); - return result == SL_RESULT_SUCCESS; + static_cast (context)->finished(); } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenSLAudioIODevice) -}; + //============================================================================= + DynamicLibrary slLibrary { "libOpenSLES.so" }; + SlRef engine; + SlRef outputMix; + SlRef player; + SlRef queue; -//============================================================================== -class OpenSLAudioDeviceType : public AudioIODeviceType -{ -public: - OpenSLAudioDeviceType() : AudioIODeviceType (openSLTypeName) {} + int bufferSize = OpenSLAudioIODevice::getNativeBufferSize(); + HeapBlock buffer { HeapBlock (static_cast (1 * bufferSize * numBuffers)) }; - //============================================================================== - void scanForDevices() override {} - StringArray getDeviceNames (bool wantInputNames) const override { return StringArray (openSLTypeName); } - int getDefaultDeviceIndex (bool forInput) const override { return 0; } - int getIndexOfDevice (AudioIODevice* device, bool asInput) const override { return device != nullptr ? 0 : -1; } - bool hasSeparateInputsAndOutputs() const override { return false; } + void* (*threadEntryProc) (void*) = nullptr; + void* threadUserPtr = nullptr; - AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) override - { - ScopedPointer dev; + pthread_cond_t threadReady; + pthread_mutex_t threadReadyMutex; + pthread_t threadID; +}; - if (outputDeviceName.isNotEmpty() || inputDeviceName.isNotEmpty()) - { - dev = new OpenSLAudioIODevice (outputDeviceName.isNotEmpty() ? outputDeviceName - : inputDeviceName); - if (! dev->openedOk()) - dev = nullptr; - } +pthread_t juce_createRealtimeAudioThread (void* (*entry) (void*), void* userPtr) +{ + ScopedPointer thread (new SLRealtimeThread); - return dev.release(); - } + if (! thread->isOK()) + return 0; -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenSLAudioDeviceType) -}; + pthread_t threadID = thread->startThread (entry, userPtr); + // the thread will de-allocate itself + thread.release(); -//============================================================================== -AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_OpenSLES() -{ - return isOpenSLAvailable() ? new OpenSLAudioDeviceType() : nullptr; + return threadID; } diff --git a/source/modules/juce_audio_devices/native/juce_ios_Audio.cpp b/source/modules/juce_audio_devices/native/juce_ios_Audio.cpp index e39b80cb7..ee158b7b7 100644 --- a/source/modules/juce_audio_devices/native/juce_ios_Audio.cpp +++ b/source/modules/juce_audio_devices/native/juce_ios_Audio.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -33,14 +25,18 @@ class iOSAudioIODevice; static const char* const iOSAudioDeviceName = "iOS Audio"; //============================================================================== -struct AudioSessionHolder +struct AudioSessionHolder : public AsyncUpdater { AudioSessionHolder(); ~AudioSessionHolder(); + void handleAsyncUpdate() override; + void handleStatusChange (bool enabled, const char* reason) const; - void handleRouteChange (const char* reason) const; + void handleRouteChange (const char* reason); + CriticalSection routeChangeLock; + String lastRouteChangeReason; Array activeDevices; id nativeSession; @@ -210,35 +206,27 @@ static void logNSError (NSError* e) #define JUCE_NSERROR_CHECK(X) { NSError* error = nil; X; logNSError (error); } +#if JUCE_MODULE_AVAILABLE_juce_graphics +#include +#endif //============================================================================== -class iOSAudioIODevice : public AudioIODevice +struct iOSAudioIODevice::Pimpl : public AudioPlayHead, + public AsyncUpdater { -public: - iOSAudioIODevice (const String& deviceName) - : AudioIODevice (deviceName, iOSAudioDeviceName) + Pimpl (iOSAudioIODevice& ioDevice) + : owner (ioDevice) { - sessionHolder->activeDevices.add (this); - updateSampleRateAndAudioInput(); - } + sessionHolder->activeDevices.add (&owner); - ~iOSAudioIODevice() - { - sessionHolder->activeDevices.removeFirstMatchingValue (this); - close(); - } - - StringArray getOutputChannelNames() override - { - return { "Left", "Right" }; + updateSampleRateAndAudioInput(); } - StringArray getInputChannelNames() override + ~Pimpl() { - if (audioInputIsAvailable) - return { "Left", "Right" }; + sessionHolder->activeDevices.removeFirstMatchingValue (&owner); - return {}; + close(); } static void setAudioSessionActive (bool enabled) @@ -255,8 +243,10 @@ public: return session.sampleRate; } - Array getAvailableSampleRates() override + Array getAvailableSampleRates() { + const ScopedLock sl (callbackLock); + Array rates; // Important: the supported audio sample rates change on the iPhone 6S @@ -265,7 +255,7 @@ public: AudioUnitRemovePropertyListenerWithUserData (audioUnit, kAudioUnitProperty_StreamFormat, - handleStreamFormatChangeCallback, + dispatchAudioUnitPropertyChange, this); const double lowestRate = trySampleRate (4000); @@ -275,27 +265,24 @@ public: { const double supportedRate = trySampleRate (rate); - rates.addIfNotAlreadyThere (supportedRate); + if (rates.addIfNotAlreadyThere (supportedRate)) + JUCE_IOS_AUDIO_LOG ("available rate = " + String (supportedRate, 0) + "Hz"); + rate = jmax (rate, supportedRate); } - trySampleRate (getCurrentSampleRate()); + trySampleRate (sampleRate); + updateCurrentBufferSize(); AudioUnitAddPropertyListener (audioUnit, kAudioUnitProperty_StreamFormat, - handleStreamFormatChangeCallback, + dispatchAudioUnitPropertyChange, this); - for (auto r : rates) - { - ignoreUnused (r); - JUCE_IOS_AUDIO_LOG ("available rate = " + String (r, 0) + "Hz"); - } - return rates; } - Array getAvailableBufferSizes() override + Array getAvailableBufferSizes() { Array r; @@ -305,24 +292,26 @@ public: return r; } - int getDefaultBufferSize() override + void updateSampleRateAndAudioInput() { - #if TARGET_IPHONE_SIMULATOR - return 512; - #else - return 256; - #endif + auto session = [AVAudioSession sharedInstance]; + sampleRate = session.sampleRate; + audioInputIsAvailable = session.isInputAvailable; + actualBufferSize = roundToInt (sampleRate * session.IOBufferDuration); + + JUCE_IOS_AUDIO_LOG ("AVAudioSession: sampleRate: " << sampleRate + << " Hz, audioInputAvailable: " << (int) audioInputIsAvailable + << ", buffer size: " << actualBufferSize); } String open (const BigInteger& inputChannelsWanted, const BigInteger& outputChannelsWanted, - double targetSampleRate, int bufferSize) override + double targetSampleRate, int bufferSize) { close(); lastError.clear(); - preferredBufferSize = bufferSize <= 0 ? getDefaultBufferSize() - : bufferSize; + preferredBufferSize = bufferSize <= 0 ? defaultBufferSize : bufferSize; // xxx set up channel mapping @@ -372,7 +361,7 @@ public: return lastError; } - void close() override + void close() { if (isRunning) { @@ -389,31 +378,19 @@ public: } } - bool isOpen() override { return isRunning; } - - int getCurrentBufferSizeSamples() override { return actualBufferSize; } - double getCurrentSampleRate() override { return sampleRate; } - int getCurrentBitDepth() override { return 16; } - - BigInteger getActiveOutputChannels() const override { return activeOutputChans; } - BigInteger getActiveInputChannels() const override { return activeInputChans; } - - int getOutputLatencyInSamples() override { return roundToInt (getCurrentSampleRate() * [AVAudioSession sharedInstance].outputLatency); } - int getInputLatencyInSamples() override { return roundToInt (getCurrentSampleRate() * [AVAudioSession sharedInstance].inputLatency); } - - void start (AudioIODeviceCallback* newCallback) override + void start (AudioIODeviceCallback* newCallback) { if (isRunning && callback != newCallback) { if (newCallback != nullptr) - newCallback->audioDeviceAboutToStart (this); + newCallback->audioDeviceAboutToStart (&owner); const ScopedLock sl (callbackLock); callback = newCallback; } } - void stop() override + void stop() { if (isRunning) { @@ -430,10 +407,7 @@ public: } } - bool isPlaying() override { return isRunning && callback != nullptr; } - String getLastError() override { return lastError; } - - bool setAudioPreprocessingEnabled (bool enable) override + bool setAudioPreprocessingEnabled (bool enable) { auto session = [AVAudioSession sharedInstance]; @@ -446,6 +420,166 @@ public: return session.mode == mode; } + //============================================================================== + bool canControlTransport() override { return interAppAudioConnected; } + + void transportPlay (bool shouldSartPlaying) override + { + if (! canControlTransport()) + return; + + HostCallbackInfo callbackInfo; + fillHostCallbackInfo (callbackInfo); + + Boolean hostIsPlaying = NO; + OSStatus err = callbackInfo.transportStateProc2 (callbackInfo.hostUserData, + &hostIsPlaying, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr); + + ignoreUnused (err); + jassert (err == noErr); + + if (hostIsPlaying != shouldSartPlaying) + handleAudioTransportEvent (kAudioUnitRemoteControlEvent_TogglePlayPause); + } + + void transportRecord (bool shouldStartRecording) override + { + if (! canControlTransport()) + return; + + HostCallbackInfo callbackInfo; + fillHostCallbackInfo (callbackInfo); + + Boolean hostIsRecording = NO; + OSStatus err = callbackInfo.transportStateProc2 (callbackInfo.hostUserData, + nullptr, + &hostIsRecording, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr); + ignoreUnused (err); + jassert (err == noErr); + + if (hostIsRecording != shouldStartRecording) + handleAudioTransportEvent (kAudioUnitRemoteControlEvent_ToggleRecord); + } + + void transportRewind() override + { + if (canControlTransport()) + handleAudioTransportEvent (kAudioUnitRemoteControlEvent_Rewind); + } + + bool getCurrentPosition (CurrentPositionInfo& result) override + { + if (! canControlTransport()) + return false; + + zerostruct (result); + + HostCallbackInfo callbackInfo; + fillHostCallbackInfo (callbackInfo); + + if (callbackInfo.hostUserData == nullptr) + return false; + + Boolean hostIsPlaying = NO; + Boolean hostIsRecording = NO; + Float64 hostCurrentSampleInTimeLine = 0; + Boolean hostIsCycling = NO; + Float64 hostCycleStartBeat = 0; + Float64 hostCycleEndBeat = 0; + OSStatus err = callbackInfo.transportStateProc2 (callbackInfo.hostUserData, + &hostIsPlaying, + &hostIsRecording, + nullptr, + &hostCurrentSampleInTimeLine, + &hostIsCycling, + &hostCycleStartBeat, + &hostCycleEndBeat); + if (err == kAUGraphErr_CannotDoInCurrentContext) + return false; + + jassert (err == noErr); + + result.timeInSamples = (int64) hostCurrentSampleInTimeLine; + result.isPlaying = hostIsPlaying; + result.isRecording = hostIsRecording; + result.isLooping = hostIsCycling; + result.ppqLoopStart = hostCycleStartBeat; + result.ppqLoopEnd = hostCycleEndBeat; + + result.timeInSeconds = result.timeInSamples / sampleRate; + + Float64 hostBeat = 0; + Float64 hostTempo = 0; + err = callbackInfo.beatAndTempoProc (callbackInfo.hostUserData, + &hostBeat, + &hostTempo); + jassert (err == noErr); + + result.ppqPosition = hostBeat; + result.bpm = hostTempo; + + Float32 hostTimeSigNumerator = 0; + UInt32 hostTimeSigDenominator = 0; + Float64 hostCurrentMeasureDownBeat = 0; + err = callbackInfo.musicalTimeLocationProc (callbackInfo.hostUserData, + nullptr, + &hostTimeSigNumerator, + &hostTimeSigDenominator, + &hostCurrentMeasureDownBeat); + jassert (err == noErr); + + result.ppqPositionOfLastBarStart = hostCurrentMeasureDownBeat; + result.timeSigNumerator = (int) hostTimeSigNumerator; + result.timeSigDenominator = (int) hostTimeSigDenominator; + + result.frameRate = AudioPlayHead::fpsUnknown; + + return true; + } + + //============================================================================== + #if JUCE_MODULE_AVAILABLE_juce_graphics + Image getIcon (int size) + { + if (interAppAudioConnected) + { + UIImage* hostUIImage = AudioOutputUnitGetHostIcon (audioUnit, size); + if (hostUIImage != nullptr) + return juce_createImageFromUIImage (hostUIImage); + } + return Image(); + } + #endif + + void switchApplication() + { + if (! interAppAudioConnected) + return; + + CFURLRef hostUrl; + UInt32 dataSize = sizeof (hostUrl); + OSStatus err = AudioUnitGetProperty(audioUnit, + kAudioUnitProperty_PeerURL, + kAudioUnitScope_Global, + 0, + &hostUrl, + &dataSize); + if (err == noErr) + [[UIApplication sharedApplication] openURL:(NSURL*)hostUrl]; + } + + //============================================================================== void invokeAudioDeviceErrorCallback (const String& reason) { const ScopedLock sl (callbackLock); @@ -481,50 +615,74 @@ public: fixAudioRouteIfSetToReceiver(); if (isRunning) - { invokeAudioDeviceErrorCallback (reason); - updateSampleRateAndAudioInput(); - updateCurrentBufferSize(); - createAudioUnit(); - setAudioSessionActive (true); + restart(); + } - if (audioUnit != 0) + void handleAudioUnitPropertyChange (AudioUnit, + AudioUnitPropertyID propertyID, + AudioUnitScope scope, + AudioUnitElement element) + { + JUCE_IOS_AUDIO_LOG ("handleAudioUnitPropertyChange: propertyID: " << String (propertyID) + << " scope: " << String (scope) + << " element: " << String (element)); + + switch (propertyID) + { + case kAudioUnitProperty_IsInterAppConnected: + handleInterAppAudioConnectionChange(); + return; + case kAudioUnitProperty_StreamFormat: + if (scope == kAudioUnitScope_Output && element == 0) + handleStreamFormatChange(); + + return; + default: + jassertfalse; + return; + } + } + + void handleInterAppAudioConnectionChange() + { + UInt32 connected; + UInt32 dataSize = sizeof (connected); + OSStatus err = AudioUnitGetProperty (audioUnit, kAudioUnitProperty_IsInterAppConnected, + kAudioUnitScope_Global, 0, &connected, &dataSize); + ignoreUnused (err); + jassert (err == noErr); + + JUCE_IOS_AUDIO_LOG ("handleInterAppAudioConnectionChange: " << (connected ? "connected" + : "disconnected")); + + if (connected != interAppAudioConnected) + { + const ScopedLock myScopedLock (callbackLock); + + interAppAudioConnected = connected; + + UIApplicationState appstate = [UIApplication sharedApplication].applicationState; + bool inForeground = (appstate != UIApplicationStateBackground); + + if (interAppAudioConnected || inForeground) { - UInt32 formatSize = sizeof (format); - AudioUnitGetProperty (audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &format, &formatSize); + setAudioSessionActive (true); AudioOutputUnitStart (audioUnit); - } - if (callback != nullptr) + if (callback != nullptr) + callback->audioDeviceAboutToStart (&owner); + } + else if (! inForeground) { - callback->audioDeviceStopped(); - callback->audioDeviceAboutToStart (this); + AudioOutputUnitStop (audioUnit); + setAudioSessionActive (false); } } } -private: //============================================================================== - SharedResourcePointer sessionHolder; - CriticalSection callbackLock; - NSTimeInterval sampleRate = 0; - int numInputChannels = 2, numOutputChannels = 2; - int preferredBufferSize = 0, actualBufferSize = 0; - bool isRunning = false; - String lastError; - - AudioStreamBasicDescription format; - AudioUnit audioUnit {}; - bool audioInputIsAvailable = false; - AudioIODeviceCallback* callback = nullptr; - BigInteger activeOutputChans, activeInputChans; - - AudioSampleBuffer floatData; - float* inputChannels[3]; - float* outputChannels[3]; - bool monoInputChannelNumber, monoOutputChannelNumber; - void prepareFloatBuffers (int bufferSize) { if (numInputChannels + numOutputChannels > 0) @@ -623,18 +781,6 @@ private: return err; } - void updateSampleRateAndAudioInput() - { - auto session = [AVAudioSession sharedInstance]; - sampleRate = session.sampleRate; - audioInputIsAvailable = session.isInputAvailable; - actualBufferSize = roundToInt (sampleRate * session.IOBufferDuration); - - JUCE_IOS_AUDIO_LOG ("AVAudioSession: sampleRate: " << sampleRate - << " Hz, audioInputAvailable: " << (int) audioInputIsAvailable - << ", buffer size: " << actualBufferSize); - } - void updateCurrentBufferSize() { NSTimeInterval bufferDuration = sampleRate > 0 ? (NSTimeInterval) ((preferredBufferSize + 1) / sampleRate) : 0.0; @@ -649,7 +795,7 @@ private: UInt32 /*busNumber*/, UInt32 numFrames, AudioBufferList* data) { - return static_cast (client)->process (flags, time, numFrames, data); + return static_cast (client)->process (flags, time, numFrames, data); } //============================================================================== @@ -687,6 +833,31 @@ private: if (audioUnit == 0) return false; + #if JucePlugin_Enable_IAA + AudioComponentDescription appDesc; + appDesc.componentType = JucePlugin_IAAType; + appDesc.componentSubType = JucePlugin_IAASubType; + appDesc.componentManufacturer = JucePlugin_ManufacturerCode; + appDesc.componentFlags = 0; + appDesc.componentFlagsMask = 0; + OSStatus err = AudioOutputUnitPublish (&appDesc, + CFSTR(JucePlugin_IAAName), + JucePlugin_VersionCode, + audioUnit); + + // This assert will be hit if the Inter-App Audio entitlement has not + // been enabled, or the description being published with + // AudioOutputUnitPublish is different from any in the AudioComponents + // array in this application's .plist file. + jassert (err == noErr); + + err = AudioUnitAddPropertyListener (audioUnit, + kAudioUnitProperty_IsInterAppConnected, + dispatchAudioUnitPropertyChange, + this); + jassert (err == noErr); + #endif + if (numInputChannels > 0) { const UInt32 one = 1; @@ -726,11 +897,33 @@ private: prepareFloatBuffers (static_cast (framesPerSlice)); } - AudioUnitAddPropertyListener (audioUnit, kAudioUnitProperty_StreamFormat, handleStreamFormatChangeCallback, this); + AudioUnitAddPropertyListener (audioUnit, kAudioUnitProperty_StreamFormat, dispatchAudioUnitPropertyChange, this); return true; } + void fillHostCallbackInfo (HostCallbackInfo& callbackInfo) + { + zerostruct (callbackInfo); + UInt32 dataSize = sizeof (HostCallbackInfo); + OSStatus err = AudioUnitGetProperty (audioUnit, + kAudioUnitProperty_HostCallbacks, + kAudioUnitScope_Global, + 0, + &callbackInfo, + &dataSize); + ignoreUnused (err); + jassert (err == noErr); + } + + void handleAudioTransportEvent (AudioUnitRemoteControlEvent event) + { + OSStatus err = AudioUnitSetProperty (audioUnit, kAudioOutputUnitProperty_RemoteControlToHost, + kAudioUnitScope_Global, 0, &event, sizeof (event)); + ignoreUnused (err); + jassert (err == noErr); + } + // If the routing is set to go through the receiver (i.e. the speaker, but quiet), this re-routes it // to make it loud. Needed because by default when using an input + output, the output is kept quiet. static void fixAudioRouteIfSetToReceiver() @@ -757,6 +950,36 @@ private: } } + void restart() + { + if (isRunning) + { + updateSampleRateAndAudioInput(); + updateCurrentBufferSize(); + createAudioUnit(); + + setAudioSessionActive (true); + + if (audioUnit != 0) + { + UInt32 formatSize = sizeof (format); + AudioUnitGetProperty (audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &format, &formatSize); + AudioOutputUnitStart (audioUnit); + } + + if (callback != nullptr) + { + callback->audioDeviceStopped(); + callback->audioDeviceAboutToStart (&owner); + } + } + } + + void handleAsyncUpdate() override + { + restart(); + } + void handleStreamFormatChange() { AudioStreamBasicDescription desc; @@ -768,36 +991,127 @@ private: 0, &desc, &dataSize); - if (desc.mSampleRate != getCurrentSampleRate()) + + if (desc.mSampleRate != sampleRate) { - updateSampleRateAndAudioInput(); - const ScopedLock sl (callbackLock); - if (callback != nullptr) - { - callback->audioDeviceStopped(); - callback->audioDeviceAboutToStart (this); - } + JUCE_IOS_AUDIO_LOG ("handleStreamFormatChange: sample rate " << desc.mSampleRate); + triggerAsyncUpdate(); } } - static void handleStreamFormatChangeCallback (void* device, - AudioUnit, - AudioUnitPropertyID, - AudioUnitScope scope, - AudioUnitElement element) + static void dispatchAudioUnitPropertyChange (void* data, AudioUnit unit, AudioUnitPropertyID propertyID, + AudioUnitScope scope, AudioUnitElement element) + { + static_cast (data)->handleAudioUnitPropertyChange (unit, propertyID, scope, element); + } + + void handleMidiMessage (MidiMessage msg) + { + if (messageCollector != nullptr) + messageCollector->addMessageToQueue (msg); + } + + static void midiEventCallback (void *client, UInt32 status, UInt32 data1, UInt32 data2, UInt32) { - if (scope == kAudioUnitScope_Output && element == 0) - static_cast (device)->handleStreamFormatChange(); + return static_cast (client)->handleMidiMessage (MidiMessage ((int) status, + (int) data1, + (int) data2, + Time::getMillisecondCounter() / 1000.0)); } - JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) + bool isRunning = false; + AudioIODeviceCallback* callback = nullptr; + + String lastError; + + bool audioInputIsAvailable = false; + + const int defaultBufferSize = + #if TARGET_IPHONE_SIMULATOR + 512; + #else + 256; + #endif + double sampleRate = 0; + int numInputChannels = 2, numOutputChannels = 2; + int preferredBufferSize = 0, actualBufferSize = 0; + + bool interAppAudioConnected = false; + + BigInteger activeOutputChans, activeInputChans; + + MidiMessageCollector* messageCollector = nullptr; + + iOSAudioIODevice& owner; + SharedResourcePointer sessionHolder; + CriticalSection callbackLock; + + AudioStreamBasicDescription format; + AudioUnit audioUnit {}; + + AudioSampleBuffer floatData; + float* inputChannels[3]; + float* outputChannels[3]; + bool monoInputChannelNumber, monoOutputChannelNumber; + + JUCE_DECLARE_NON_COPYABLE (Pimpl) }; //============================================================================== -class iOSAudioIODeviceType : public AudioIODeviceType +iOSAudioIODevice::iOSAudioIODevice (const String& deviceName) + : AudioIODevice (deviceName, iOSAudioDeviceName), + pimpl (new Pimpl (*this)) +{} + +//============================================================================== +String iOSAudioIODevice::open (const BigInteger& inChans, const BigInteger& outChans, + double requestedSampleRate, int requestedBufferSize) +{ + return pimpl->open (inChans, outChans, requestedSampleRate, requestedBufferSize); +} +void iOSAudioIODevice::close() { pimpl->close(); } + +void iOSAudioIODevice::start (AudioIODeviceCallback* callbackToUse) { pimpl->start (callbackToUse); } +void iOSAudioIODevice::stop() { pimpl->stop(); } + +Array iOSAudioIODevice::getAvailableSampleRates() { return pimpl->getAvailableSampleRates(); } +Array iOSAudioIODevice::getAvailableBufferSizes() { return pimpl->getAvailableBufferSizes(); } + +bool iOSAudioIODevice::setAudioPreprocessingEnabled (bool enabled) { return pimpl->setAudioPreprocessingEnabled (enabled); } + +bool iOSAudioIODevice::isPlaying() { return pimpl->isRunning && pimpl->callback != nullptr; } +bool iOSAudioIODevice::isOpen() { return pimpl->isRunning; } +String iOSAudioIODevice::getLastError() { return pimpl->lastError; } + +StringArray iOSAudioIODevice::getOutputChannelNames() { return { "Left", "Right" }; } +StringArray iOSAudioIODevice::getInputChannelNames() { return pimpl->audioInputIsAvailable ? getOutputChannelNames() : StringArray(); } + +int iOSAudioIODevice::getDefaultBufferSize() { return pimpl->defaultBufferSize; } +int iOSAudioIODevice::getCurrentBufferSizeSamples() { return pimpl->actualBufferSize; } + +double iOSAudioIODevice::getCurrentSampleRate() { return pimpl->sampleRate; } + +int iOSAudioIODevice::getCurrentBitDepth() { return 16; } + +BigInteger iOSAudioIODevice::getActiveOutputChannels() const { return pimpl->activeOutputChans; } +BigInteger iOSAudioIODevice::getActiveInputChannels() const { return pimpl->activeInputChans; } + +int iOSAudioIODevice::getOutputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].outputLatency); } +int iOSAudioIODevice::getInputLatencyInSamples() { return roundToInt (pimpl->sampleRate * [AVAudioSession sharedInstance].inputLatency); } + +void iOSAudioIODevice::setMidiMessageCollector (MidiMessageCollector* collector) { pimpl->messageCollector = collector; } +AudioPlayHead* iOSAudioIODevice::getAudioPlayHead() const { return pimpl; } + +bool iOSAudioIODevice::isInterAppAudioConnected() const { return pimpl->interAppAudioConnected; } +#if JUCE_MODULE_AVAILABLE_juce_graphics +Image iOSAudioIODevice::getIcon (int size) { return pimpl->getIcon (size); } +#endif +void iOSAudioIODevice::switchApplication() { return pimpl->switchApplication(); } + +//============================================================================== +struct iOSAudioIODeviceType : public AudioIODeviceType { -public: iOSAudioIODeviceType() : AudioIODeviceType (iOSAudioDeviceName) {} void scanForDevices() {} @@ -814,7 +1128,6 @@ public: return nullptr; } -private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSAudioIODeviceType) }; @@ -828,32 +1141,24 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() AudioSessionHolder::AudioSessionHolder() { nativeSession = [[iOSAudioSessionNative alloc] init: this]; } AudioSessionHolder::~AudioSessionHolder() { [nativeSession release]; } -void AudioSessionHolder::handleStatusChange (bool enabled, const char* reason) const +void AudioSessionHolder::handleAsyncUpdate() { + const ScopedLock sl (routeChangeLock); for (auto device: activeDevices) - device->handleStatusChange (enabled, reason); + device->pimpl->handleRouteChange (lastRouteChangeReason.toRawUTF8()); } -void AudioSessionHolder::handleRouteChange (const char* reason) const +void AudioSessionHolder::handleStatusChange (bool enabled, const char* reason) const { - struct RouteChangeMessage : public CallbackMessage - { - RouteChangeMessage (Array devs, const char* r) - : devices (devs), changeReason (r) - { - } - - void messageCallback() override - { - for (auto device: devices) - device->handleRouteChange (changeReason); - } - - Array devices; - const char* changeReason; - }; + for (auto device: activeDevices) + device->pimpl->handleStatusChange (enabled, reason); +} - (new RouteChangeMessage (activeDevices, reason))->post(); +void AudioSessionHolder::handleRouteChange (const char* reason) +{ + const ScopedLock sl (routeChangeLock); + lastRouteChangeReason = reason; + triggerAsyncUpdate(); } #undef JUCE_NSERROR_CHECK diff --git a/source/modules/juce_audio_devices/native/juce_ios_Audio.h b/source/modules/juce_audio_devices/native/juce_ios_Audio.h new file mode 100644 index 000000000..bab757384 --- /dev/null +++ b/source/modules/juce_audio_devices/native/juce_ios_Audio.h @@ -0,0 +1,88 @@ +/* + ============================================================================== + + 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. + + The code included in this file is provided 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. + + 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 + +struct iOSAudioIODeviceType; + +class iOSAudioIODevice : public AudioIODevice +{ +public: + //============================================================================== + String open (const BigInteger&, const BigInteger&, double, int) override; + void close() override; + + void start (AudioIODeviceCallback*) override; + void stop() override; + + Array getAvailableSampleRates() override; + Array getAvailableBufferSizes() override; + + bool setAudioPreprocessingEnabled (bool) override; + + //============================================================================== + bool isPlaying() override; + bool isOpen() override; + String getLastError() override; + + //============================================================================== + StringArray getOutputChannelNames() override; + StringArray getInputChannelNames() override; + + int getDefaultBufferSize() override; + int getCurrentBufferSizeSamples() override; + + double getCurrentSampleRate() override; + + int getCurrentBitDepth() override; + + BigInteger getActiveOutputChannels() const override; + BigInteger getActiveInputChannels() const override; + + int getOutputLatencyInSamples() override; + int getInputLatencyInSamples() override; + + //============================================================================== + void setMidiMessageCollector (MidiMessageCollector*); + AudioPlayHead* getAudioPlayHead() const; + + //============================================================================== + bool isInterAppAudioConnected() const; + #if JUCE_MODULE_AVAILABLE_juce_graphics + Image getIcon (int size); + #endif + void switchApplication(); + +private: + //============================================================================== + iOSAudioIODevice (const String&); + + //============================================================================== + friend struct iOSAudioIODeviceType; + friend struct AudioSessionHolder; + + struct Pimpl; + friend struct Pimpl; + ScopedPointer pimpl; + + JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) +}; diff --git a/source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp b/source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp index a790835a7..0912f4e46 100644 --- a/source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp +++ b/source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp b/source/modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp deleted file mode 100644 index 938486b61..000000000 --- a/source/modules/juce_audio_devices/native/juce_linux_AudioCDReader.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioCDReader::AudioCDReader() - : AudioFormatReader (0, "CD Audio") -{ -} - -StringArray AudioCDReader::getAvailableCDNames() -{ - StringArray names; - return names; -} - -AudioCDReader* AudioCDReader::createReaderForCD (const int index) -{ - return nullptr; -} - -AudioCDReader::~AudioCDReader() -{ -} - -void AudioCDReader::refreshTrackLengths() -{ -} - -bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) -{ - return false; -} - -bool AudioCDReader::isCDStillPresent() const -{ - return false; -} - -bool AudioCDReader::isTrackAudio (int trackNum) const -{ - return false; -} - -void AudioCDReader::enableIndexScanning (bool b) -{ -} - -int AudioCDReader::getLastIndex() const -{ - return 0; -} - -Array AudioCDReader::findIndexesInTrack (const int trackNumber) -{ - return Array(); -} diff --git a/source/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp b/source/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp index 8cbb8f40e..482437e89 100644 --- a/source/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp +++ b/source/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_devices/native/juce_linux_Midi.cpp b/source/modules/juce_audio_devices/native/juce_linux_Midi.cpp index ea0f838a3..74bbe4131 100644 --- a/source/modules/juce_audio_devices/native/juce_linux_Midi.cpp +++ b/source/modules/juce_audio_devices/native/juce_linux_Midi.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,118 +23,276 @@ #if JUCE_ALSA // You can define these strings in your app if you want to override the default names: -#ifndef JUCE_ALSA_MIDI_INPUT_NAME - #define JUCE_ALSA_MIDI_INPUT_NAME "Juce Midi Input" -#endif - -#ifndef JUCE_ALSA_MIDI_OUTPUT_NAME - #define JUCE_ALSA_MIDI_OUTPUT_NAME "Juce Midi Output" +#ifndef JUCE_ALSA_MIDI_NAME + #define JUCE_ALSA_MIDI_NAME JUCEApplicationBase::getInstance()->getApplicationName().toUTF8() #endif //============================================================================== namespace { -class AlsaPortAndCallback; - //============================================================================== class AlsaClient : public ReferenceCountedObject { public: typedef ReferenceCountedObjectPtr Ptr; - static Ptr getInstance (bool forInput) + //============================================================================== + // represents an input or output port of the supplied AlsaClient + class Port { - AlsaClient*& instance = (forInput ? inInstance : outInstance); - if (instance == nullptr) - instance = new AlsaClient (forInput); + public: + Port (AlsaClient& c, bool forInput) noexcept + : portId (-1), + callbackEnabled (false), + client (c), + isInput (forInput), + callback (nullptr), + maxEventSize (4 * 1024), + midiInput (nullptr) + {} + + ~Port() + { + if (isValid()) + { + if (isInput) + enableCallback (false); + else + snd_midi_event_free (midiParser); - return instance; - } + snd_seq_delete_simple_port (client.get(), portId); + } + } - bool isInput() const noexcept { return input; } + void connectWith (int sourceClient, int sourcePort) const noexcept + { + if (isInput) + snd_seq_connect_from (client.get(), portId, sourceClient, sourcePort); + else + snd_seq_connect_to (client.get(), portId, sourceClient, sourcePort); + } - void registerCallback (AlsaPortAndCallback* cb) - { - if (cb != nullptr) + bool isValid() const noexcept + { + return client.get() != nullptr && portId >= 0; + } + + void setupInput(MidiInput* input, MidiInputCallback* cb) + { + jassert (cb && input); + + callback = cb; + midiInput = input; + } + + void setupOutput() + { + jassert (! isInput); + + snd_midi_event_new ((size_t) maxEventSize, &midiParser); + } + + void enableCallback (bool enable) { + if (callbackEnabled != enable) { - const ScopedLock sl (callbackLock); - activeCallbacks.add (cb); + callbackEnabled = enable; - if (inputThread == nullptr) - inputThread = new MidiInputThread (*this); + if (enable) + client.registerCallback(); + else + client.unregisterCallback(); } + } - inputThread->startThread(); + bool sendMessageNow (const MidiMessage& message) + { + if (message.getRawDataSize() > maxEventSize) + { + maxEventSize = message.getRawDataSize(); + snd_midi_event_free (midiParser); + snd_midi_event_new ((size_t) maxEventSize, &midiParser); + } + + snd_seq_event_t event; + snd_seq_ev_clear (&event); + + long numBytes = (long) message.getRawDataSize(); + const uint8* data = message.getRawData(); + + snd_seq_t* seqHandle = client.get(); + bool success = true; + + while (numBytes > 0) + { + const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event); + + if (numSent <= 0) + { + success = numSent == 0; + break; + } + + numBytes -= numSent; + data += numSent; + + snd_seq_ev_set_source (&event, portId); + snd_seq_ev_set_subs (&event); + snd_seq_ev_set_direct (&event); + + if (snd_seq_event_output_direct (seqHandle, &event) < 0) + { + success = false; + break; + } + } + + snd_midi_event_reset_encode (midiParser); + return success; + } + + + bool operator== (const Port& lhs) const noexcept + { + return portId != -1 && portId == lhs.portId; + } + + int portId; + bool callbackEnabled; + + private: + friend class AlsaClient; + + AlsaClient& client; + bool isInput; + MidiInputCallback* callback; + snd_midi_event_t* midiParser; + int maxEventSize; + MidiInput* midiInput; + + void createPort (const String& name, bool enableSubscription) + { + if (snd_seq_t* seqHandle = client.get()) + { + const unsigned int caps = + isInput + ? (SND_SEQ_PORT_CAP_WRITE | (enableSubscription ? SND_SEQ_PORT_CAP_SUBS_WRITE : 0)) + : (SND_SEQ_PORT_CAP_WRITE | (enableSubscription ? SND_SEQ_PORT_CAP_SUBS_READ : 0)); + portId = snd_seq_create_simple_port (seqHandle, name.toUTF8(), caps, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | + SND_SEQ_PORT_TYPE_APPLICATION); + } + } + + void handleIncomingMidiMessage (const MidiMessage& message) const + { + callback->handleIncomingMidiMessage (midiInput, message); + } + + void handlePartialSysexMessage (const uint8* messageData, int numBytesSoFar, double timeStamp) + { + callback->handlePartialSysexMessage (midiInput, messageData, numBytesSoFar, timeStamp); } + }; + + static Ptr getInstance() + { + if (instance == nullptr) + instance = new AlsaClient(); + + return instance; } - void unregisterCallback (AlsaPortAndCallback* cb) + void registerCallback() { - const ScopedLock sl (callbackLock); + if (inputThread == nullptr) + inputThread = new MidiInputThread (*this); - jassert (activeCallbacks.contains (cb)); - activeCallbacks.removeAllInstancesOf (cb); + if (++activeCallbacks - 1 == 0) + inputThread->startThread(); + } - if (activeCallbacks.size() == 0 && inputThread->isThreadRunning()) + void unregisterCallback() + { + jassert (activeCallbacks.get() > 0); + if (--activeCallbacks == 0 && inputThread->isThreadRunning()) inputThread->signalThreadShouldExit(); } - void handleIncomingMidiMessage (snd_seq_event*, const MidiMessage&); - void handlePartialSysexMessage (snd_seq_event*, const uint8*, int, double); + void handleIncomingMidiMessage (snd_seq_event* event, const MidiMessage& message) + { + if (event->dest.port < ports.size() + && ports[event->dest.port]->callbackEnabled) + ports[event->dest.port]->handleIncomingMidiMessage (message); + } + + void handlePartialSysexMessage (snd_seq_event* event, const uint8* messageData, int numBytesSoFar, double timeStamp) + { + if (event->dest.port < ports.size() + && ports[event->dest.port]->callbackEnabled) + ports[event->dest.port]->handlePartialSysexMessage (messageData, numBytesSoFar, timeStamp); + } snd_seq_t* get() const noexcept { return handle; } + int getId() const noexcept { return clientId; } + + Port* createPort (const String& name, bool forInput, bool enableSubscription) + { + Port* port = new Port (*this, forInput); + port->createPort (name, enableSubscription); + ports.set (port->portId, port); + incReferenceCount(); + return port; + } + + void deletePort (Port* port) + { + ports.remove (port->portId); + decReferenceCount(); + } private: - bool input; snd_seq_t* handle; - - Array activeCallbacks; + int clientId; + OwnedArray ports; + Atomic activeCallbacks; CriticalSection callbackLock; - static AlsaClient* inInstance; - static AlsaClient* outInstance; + static AlsaClient* instance; //============================================================================== friend class ReferenceCountedObjectPtr; friend struct ContainerDeletePolicy; - AlsaClient (bool forInput) - : input (forInput), handle (nullptr) + AlsaClient() + : handle (nullptr), + inputThread (nullptr) { - AlsaClient*& instance = (input ? inInstance : outInstance); jassert (instance == nullptr); - instance = this; + snd_seq_open (&handle, "default", SND_SEQ_OPEN_DUPLEX, 0); + snd_seq_nonblock (handle, SND_SEQ_NONBLOCK); + snd_seq_set_client_name (handle, JUCE_ALSA_MIDI_NAME); + clientId = snd_seq_client_id(handle); - snd_seq_open (&handle, "default", forInput ? SND_SEQ_OPEN_INPUT - : SND_SEQ_OPEN_OUTPUT, 0); - - snd_seq_set_client_name (handle, forInput ? JUCE_ALSA_MIDI_INPUT_NAME - : JUCE_ALSA_MIDI_OUTPUT_NAME); + // It's good idea to pre-allocate a good number of elements + ports.ensureStorageAllocated (32); } ~AlsaClient() { - AlsaClient*& instance = (input ? inInstance : outInstance); jassert (instance != nullptr); instance = nullptr; if (handle != nullptr) - { snd_seq_close (handle); - handle = nullptr; - } - jassert (activeCallbacks.size() == 0); + jassert (activeCallbacks.get() == 0); if (inputThread) - { inputThread->stopThread (3000); - inputThread = nullptr; - } } //============================================================================== @@ -152,7 +302,7 @@ private: MidiInputThread (AlsaClient& c) : Thread ("Juce MIDI Input"), client (c), concatenator (2048) { - jassert (client.input && client.get() != nullptr); + jassert (client.get() != nullptr); } void run() override @@ -176,8 +326,6 @@ private: if (threadShouldExit()) break; - snd_seq_nonblock (seqHandle, 1); - do { snd_seq_event_t* inputEvent = nullptr; @@ -203,7 +351,7 @@ private: snd_midi_event_free (midiParser); } - }; + } private: AlsaClient& client; @@ -213,202 +361,91 @@ private: ScopedPointer inputThread; }; -AlsaClient* AlsaClient::inInstance = nullptr; -AlsaClient* AlsaClient::outInstance = nullptr; +AlsaClient* AlsaClient::instance = nullptr; //============================================================================== -// represents an input or output port of the supplied AlsaClient -class AlsaPort +static AlsaClient::Port* iterateMidiClient (const AlsaClient::Ptr& client, + snd_seq_client_info_t* clientInfo, + const bool forInput, + StringArray& deviceNamesFound, + const int deviceIndexToOpen) { -public: - AlsaPort() noexcept : portId (-1) {} - AlsaPort (const AlsaClient::Ptr& c, int port) noexcept : client (c), portId (port) {} - - void createPort (const AlsaClient::Ptr& c, const String& name, bool forInput) - { - client = c; - - if (snd_seq_t* handle = client->get()) - portId = snd_seq_create_simple_port (handle, name.toUTF8(), - forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE) - : (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ), - SND_SEQ_PORT_TYPE_MIDI_GENERIC); - } - - void deletePort() - { - if (isValid()) - { - snd_seq_delete_simple_port (client->get(), portId); - portId = -1; - } - } + AlsaClient::Port* port = nullptr; - void connectWith (int sourceClient, int sourcePort) - { - if (client->isInput()) - snd_seq_connect_from (client->get(), portId, sourceClient, sourcePort); - else - snd_seq_connect_to (client->get(), portId, sourceClient, sourcePort); - } - - bool isValid() const noexcept - { - return client != nullptr && client->get() != nullptr && portId >= 0; - } - - AlsaClient::Ptr client; - int portId; -}; + snd_seq_t* seqHandle = client->get(); + snd_seq_port_info_t* portInfo = nullptr; -//============================================================================== -class AlsaPortAndCallback -{ -public: - AlsaPortAndCallback (AlsaPort p, MidiInput* in, MidiInputCallback* cb) - : port (p), midiInput (in), callback (cb), callbackEnabled (false) - { - } + snd_seq_port_info_alloca (&portInfo); + jassert (portInfo); + int numPorts = snd_seq_client_info_get_num_ports (clientInfo); + const int sourceClient = snd_seq_client_info_get_client (clientInfo); - ~AlsaPortAndCallback() - { - enableCallback (false); - port.deletePort(); - } + snd_seq_port_info_set_client (portInfo, sourceClient); + snd_seq_port_info_set_port (portInfo, -1); - void enableCallback (bool enable) + while (--numPorts >= 0) { - if (callbackEnabled != enable) + if (snd_seq_query_next_port (seqHandle, portInfo) == 0 + && (snd_seq_port_info_get_capability (portInfo) + & (forInput ? SND_SEQ_PORT_CAP_SUBS_WRITE : SND_SEQ_PORT_CAP_SUBS_READ)) != 0) { - callbackEnabled = enable; - - if (enable) - port.client->registerCallback (this); - else - port.client->unregisterCallback (this); - } - } - - void handleIncomingMidiMessage (const MidiMessage& message) const - { - callback->handleIncomingMidiMessage (midiInput, message); - } - - void handlePartialSysexMessage (const uint8* messageData, int numBytesSoFar, double timeStamp) - { - callback->handlePartialSysexMessage (midiInput, messageData, numBytesSoFar, timeStamp); - } - -private: - AlsaPort port; - MidiInput* midiInput; - MidiInputCallback* callback; - bool callbackEnabled; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AlsaPortAndCallback) -}; - -void AlsaClient::handleIncomingMidiMessage (snd_seq_event_t* event, const MidiMessage& message) -{ - const ScopedLock sl (callbackLock); - - if (AlsaPortAndCallback* const cb = activeCallbacks[event->dest.port]) - cb->handleIncomingMidiMessage (message); -} - -void AlsaClient::handlePartialSysexMessage (snd_seq_event* event, const uint8* messageData, int numBytesSoFar, double timeStamp) -{ - const ScopedLock sl (callbackLock); - - if (AlsaPortAndCallback* const cb = activeCallbacks[event->dest.port]) - cb->handlePartialSysexMessage (messageData, numBytesSoFar, timeStamp); -} - -//============================================================================== -static AlsaPort iterateMidiClient (const AlsaClient::Ptr& seq, - snd_seq_client_info_t* clientInfo, - const bool forInput, - StringArray& deviceNamesFound, - const int deviceIndexToOpen) -{ - AlsaPort port; - - snd_seq_t* seqHandle = seq->get(); - snd_seq_port_info_t* portInfo = nullptr; + const String portName = snd_seq_port_info_get_name(portInfo); - if (snd_seq_port_info_malloc (&portInfo) == 0) - { - int numPorts = snd_seq_client_info_get_num_ports (clientInfo); - const int client = snd_seq_client_info_get_client (clientInfo); - - snd_seq_port_info_set_client (portInfo, client); - snd_seq_port_info_set_port (portInfo, -1); + deviceNamesFound.add (portName); - while (--numPorts >= 0) - { - if (snd_seq_query_next_port (seqHandle, portInfo) == 0 - && (snd_seq_port_info_get_capability (portInfo) & (forInput ? SND_SEQ_PORT_CAP_READ - : SND_SEQ_PORT_CAP_WRITE)) != 0) + if (deviceNamesFound.size() == deviceIndexToOpen + 1) { - const String clientName = snd_seq_client_info_get_name (clientInfo); - const String portName = snd_seq_port_info_get_name(portInfo); - - if (clientName == portName) - deviceNamesFound.add (clientName); - else - deviceNamesFound.add (clientName + ": " + portName); - - if (deviceNamesFound.size() == deviceIndexToOpen + 1) + const int sourcePort = snd_seq_port_info_get_port (portInfo); + if (sourcePort != -1) { - const int sourcePort = snd_seq_port_info_get_port (portInfo); - - if (sourcePort != -1) - { - const int sourceClient = snd_seq_client_info_get_client (clientInfo); - - port.createPort (seq, portName, forInput); - port.connectWith (sourceClient, sourcePort); - } + port = client->createPort (portName, forInput, false); + jassert (port->isValid()); + port->connectWith (sourceClient, sourcePort); + break; } } } - - snd_seq_port_info_free (portInfo); } return port; } -static AlsaPort iterateMidiDevices (const bool forInput, - StringArray& deviceNamesFound, - const int deviceIndexToOpen) +static AlsaClient::Port* iterateMidiDevices (const bool forInput, + StringArray& deviceNamesFound, + const int deviceIndexToOpen) { - AlsaPort port; - const AlsaClient::Ptr client (AlsaClient::getInstance (forInput)); + AlsaClient::Port* port = nullptr; + const AlsaClient::Ptr client (AlsaClient::getInstance()); if (snd_seq_t* const seqHandle = client->get()) { snd_seq_system_info_t* systemInfo = nullptr; snd_seq_client_info_t* clientInfo = nullptr; - if (snd_seq_system_info_malloc (&systemInfo) == 0) + snd_seq_system_info_alloca (&systemInfo); + jassert(systemInfo); + if (snd_seq_system_info (seqHandle, systemInfo) == 0) { - if (snd_seq_system_info (seqHandle, systemInfo) == 0 - && snd_seq_client_info_malloc (&clientInfo) == 0) - { - int numClients = snd_seq_system_info_get_cur_clients (systemInfo); + snd_seq_client_info_alloca (&clientInfo); + jassert(clientInfo); + int numClients = snd_seq_system_info_get_cur_clients (systemInfo); - while (--numClients >= 0 && ! port.isValid()) - if (snd_seq_query_next_client (seqHandle, clientInfo) == 0) + while (--numClients >= 0) + { + if (snd_seq_query_next_client (seqHandle, clientInfo) == 0) + { + const int sourceClient = snd_seq_client_info_get_client (clientInfo); + if (sourceClient != client->getId() + && sourceClient != SND_SEQ_CLIENT_SYSTEM) + { port = iterateMidiClient (client, clientInfo, forInput, deviceNamesFound, deviceIndexToOpen); - - snd_seq_client_info_free (clientInfo); + if (port) + break; + } + } } - - snd_seq_system_info_free (systemInfo); } - } deviceNamesFound.appendNumbersToDuplicates (true, true); @@ -416,80 +453,6 @@ static AlsaPort iterateMidiDevices (const bool forInput, return port; } - -//============================================================================== -class MidiOutputDevice -{ -public: - MidiOutputDevice (MidiOutput* const output, const AlsaPort& p) - : midiOutput (output), port (p), - maxEventSize (16 * 1024) - { - jassert (port.isValid() && midiOutput != nullptr); - snd_midi_event_new ((size_t) maxEventSize, &midiParser); - } - - ~MidiOutputDevice() - { - snd_midi_event_free (midiParser); - port.deletePort(); - } - - bool sendMessageNow (const MidiMessage& message) - { - if (message.getRawDataSize() > maxEventSize) - { - maxEventSize = message.getRawDataSize(); - snd_midi_event_free (midiParser); - snd_midi_event_new ((size_t) maxEventSize, &midiParser); - } - - snd_seq_event_t event; - snd_seq_ev_clear (&event); - - long numBytes = (long) message.getRawDataSize(); - const uint8* data = message.getRawData(); - - snd_seq_t* seqHandle = port.client->get(); - bool success = true; - - while (numBytes > 0) - { - const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event); - - if (numSent <= 0) - { - success = numSent == 0; - break; - } - - numBytes -= numSent; - data += numSent; - - snd_seq_ev_set_source (&event, port.portId); - snd_seq_ev_set_subs (&event); - snd_seq_ev_set_direct (&event); - - if (snd_seq_event_output_direct (seqHandle, &event) < 0) - { - success = false; - break; - } - } - - snd_midi_event_reset_encode (midiParser); - return success; - } - -private: - MidiOutput* const midiOutput; - AlsaPort port; - snd_midi_event_t* midiParser; - int maxEventSize; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutputDevice) -}; - } // namespace StringArray MidiOutput::getDevices() @@ -509,13 +472,16 @@ MidiOutput* MidiOutput::openDevice (int deviceIndex) MidiOutput* newDevice = nullptr; StringArray devices; - AlsaPort port (iterateMidiDevices (false, devices, deviceIndex)); + AlsaClient::Port* port = iterateMidiDevices (false, devices, deviceIndex); - if (port.isValid()) - { - newDevice = new MidiOutput (devices [deviceIndex]); - newDevice->internal = new MidiOutputDevice (newDevice, port); - } + if (port == nullptr) + return nullptr; + + jassert (port->isValid()); + + newDevice = new MidiOutput (devices [deviceIndex]); + port->setupOutput(); + newDevice->internal = port; return newDevice; } @@ -523,17 +489,16 @@ MidiOutput* MidiOutput::openDevice (int deviceIndex) MidiOutput* MidiOutput::createNewDevice (const String& deviceName) { MidiOutput* newDevice = nullptr; - AlsaPort port; - const AlsaClient::Ptr client (AlsaClient::getInstance (false)); + const AlsaClient::Ptr client (AlsaClient::getInstance()); - port.createPort (client, deviceName, false); + AlsaClient::Port* port = client->createPort (deviceName, false, true); - if (port.isValid()) - { - newDevice = new MidiOutput (deviceName); - newDevice->internal = new MidiOutputDevice (newDevice, port); - } + jassert (port->isValid()); + + newDevice = new MidiOutput (deviceName); + port->setupOutput(); + newDevice->internal = port; return newDevice; } @@ -542,12 +507,13 @@ MidiOutput::~MidiOutput() { stopBackgroundThread(); - delete static_cast (internal); + AlsaClient::Ptr client (AlsaClient::getInstance()); + client->deletePort (static_cast (internal)); } void MidiOutput::sendMessageNow (const MidiMessage& message) { - static_cast (internal)->sendMessageNow (message); + static_cast (internal)->sendMessageNow (message); } //============================================================================== @@ -559,17 +525,18 @@ MidiInput::MidiInput (const String& nm) MidiInput::~MidiInput() { stop(); - delete static_cast (internal); + AlsaClient::Ptr client (AlsaClient::getInstance()); + client->deletePort (static_cast (internal)); } void MidiInput::start() { - static_cast (internal)->enableCallback (true); + static_cast (internal)->enableCallback (true); } void MidiInput::stop() { - static_cast (internal)->enableCallback (false); + static_cast (internal)->enableCallback (false); } int MidiInput::getDefaultDeviceIndex() @@ -589,13 +556,16 @@ MidiInput* MidiInput::openDevice (int deviceIndex, MidiInputCallback* callback) MidiInput* newDevice = nullptr; StringArray devices; - AlsaPort port (iterateMidiDevices (true, devices, deviceIndex)); + AlsaClient::Port* port = iterateMidiDevices (true, devices, deviceIndex); - if (port.isValid()) - { - newDevice = new MidiInput (devices [deviceIndex]); - newDevice->internal = new AlsaPortAndCallback (port, newDevice, callback); - } + if (port == nullptr) + return nullptr; + + jassert (port->isValid()); + + newDevice = new MidiInput (devices [deviceIndex]); + port->setupInput (newDevice, callback); + newDevice->internal = port; return newDevice; } @@ -603,17 +573,16 @@ MidiInput* MidiInput::openDevice (int deviceIndex, MidiInputCallback* callback) MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback) { MidiInput* newDevice = nullptr; - AlsaPort port; - const AlsaClient::Ptr client (AlsaClient::getInstance (true)); + AlsaClient::Ptr client (AlsaClient::getInstance()); - port.createPort (client, deviceName, true); + AlsaClient::Port* port = client->createPort (deviceName, true, true); - if (port.isValid()) - { - newDevice = new MidiInput (deviceName); - newDevice->internal = new AlsaPortAndCallback (port, newDevice, callback); - } + jassert (port->isValid()); + + newDevice = new MidiInput (deviceName); + port->setupInput (newDevice, callback); + newDevice->internal = port; return newDevice; } @@ -624,7 +593,7 @@ MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallba // (These are just stub functions if ALSA is unavailable...) -StringArray MidiOutput::getDevices() { return StringArray(); } +StringArray MidiOutput::getDevices() { return {}; } int MidiOutput::getDefaultDeviceIndex() { return 0; } MidiOutput* MidiOutput::openDevice (int) { return nullptr; } MidiOutput* MidiOutput::createNewDevice (const String&) { return nullptr; } @@ -636,7 +605,7 @@ MidiInput::~MidiInput() {} void MidiInput::start() {} void MidiInput::stop() {} int MidiInput::getDefaultDeviceIndex() { return 0; } -StringArray MidiInput::getDevices() { return StringArray(); } +StringArray MidiInput::getDevices() { return {}; } MidiInput* MidiInput::openDevice (int, MidiInputCallback*) { return nullptr; } MidiInput* MidiInput::createNewDevice (const String&, MidiInputCallback*) { return nullptr; } diff --git a/source/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm b/source/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm deleted file mode 100644 index 3489a8040..000000000 --- a/source/modules/juce_audio_devices/native/juce_mac_AudioCDBurner.mm +++ /dev/null @@ -1,455 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -const int kilobytesPerSecond1x = 176; - -struct AudioTrackProducerClass : public ObjCClass -{ - AudioTrackProducerClass() : ObjCClass ("JUCEAudioTrackProducer_") - { - addIvar ("source"); - - addMethod (@selector (initWithAudioSourceHolder:), initWithAudioSourceHolder, "@@:^v"); - addMethod (@selector (cleanupTrackAfterBurn:), cleanupTrackAfterBurn, "v@:@"); - addMethod (@selector (cleanupTrackAfterVerification:), cleanupTrackAfterVerification, "c@:@"); - addMethod (@selector (estimateLengthOfTrack:), estimateLengthOfTrack, "Q@:@"); - addMethod (@selector (prepareTrack:forBurn:toMedia:), prepareTrack, "c@:@@@"); - addMethod (@selector (prepareTrackForVerification:), prepareTrackForVerification, "c@:@"); - addMethod (@selector (produceDataForTrack:intoBuffer:length:atAddress:blockSize:ioFlags:), - produceDataForTrack, "I@:@^cIQI^I"); - addMethod (@selector (producePreGapForTrack:intoBuffer:length:atAddress:blockSize:ioFlags:), - produceDataForTrack, "I@:@^cIQI^I"); - addMethod (@selector (verifyDataForTrack:intoBuffer:length:atAddress:blockSize:ioFlags:), - produceDataForTrack, "I@:@^cIQI^I"); - - registerClass(); - } - - struct AudioSourceHolder - { - AudioSourceHolder (AudioSource* s, int numFrames) - : source (s), readPosition (0), lengthInFrames (numFrames) - { - } - - ~AudioSourceHolder() - { - if (source != nullptr) - source->releaseResources(); - } - - ScopedPointer source; - int readPosition, lengthInFrames; - }; - -private: - static id initWithAudioSourceHolder (id self, SEL, AudioSourceHolder* source) - { - self = sendSuperclassMessage (self, @selector (init)); - object_setInstanceVariable (self, "source", source); - return self; - } - - static AudioSourceHolder* getSource (id self) - { - return getIvar (self, "source"); - } - - static void dealloc (id self, SEL) - { - delete getSource (self); - sendSuperclassMessage (self, @selector (dealloc)); - } - - static void cleanupTrackAfterBurn (id self, SEL, DRTrack*) {} - static BOOL cleanupTrackAfterVerification (id self, SEL, DRTrack*) { return true; } - - static uint64_t estimateLengthOfTrack (id self, SEL, DRTrack*) - { - return getSource (self)->lengthInFrames; - } - - static BOOL prepareTrack (id self, SEL, DRTrack*, DRBurn*, NSDictionary*) - { - if (AudioSourceHolder* const source = getSource (self)) - { - source->source->prepareToPlay (44100 / 75, 44100); - source->readPosition = 0; - } - - return true; - } - - static BOOL prepareTrackForVerification (id self, SEL, DRTrack*) - { - if (AudioSourceHolder* const source = getSource (self)) - source->source->prepareToPlay (44100 / 75, 44100); - - return true; - } - - static uint32_t produceDataForTrack (id self, SEL, DRTrack*, char* buffer, - uint32_t bufferLength, uint64_t /*address*/, - uint32_t /*blockSize*/, uint32_t* /*flags*/) - { - if (AudioSourceHolder* const source = getSource (self)) - { - const int numSamples = jmin ((int) bufferLength / 4, - (source->lengthInFrames * (44100 / 75)) - source->readPosition); - - if (numSamples > 0) - { - AudioSampleBuffer tempBuffer (2, numSamples); - AudioSourceChannelInfo info (tempBuffer); - - source->source->getNextAudioBlock (info); - - typedef AudioData::Pointer CDSampleFormat; - typedef AudioData::Pointer SourceSampleFormat; - - CDSampleFormat left (buffer, 2); - left.convertSamples (SourceSampleFormat (tempBuffer.getReadPointer (0)), numSamples); - CDSampleFormat right (buffer + 2, 2); - right.convertSamples (SourceSampleFormat (tempBuffer.getReadPointer (1)), numSamples); - - source->readPosition += numSamples; - } - - return numSamples * 4; - } - - return 0; - } - - static uint32_t producePreGapForTrack (id self, SEL, DRTrack*, char* buffer, - uint32_t bufferLength, uint64_t /*address*/, - uint32_t /*blockSize*/, uint32_t* /*flags*/) - { - zeromem (buffer, bufferLength); - return bufferLength; - } - - static BOOL verifyDataForTrack (id self, SEL, DRTrack*, const char*, - uint32_t /*bufferLength*/, uint64_t /*address*/, - uint32_t /*blockSize*/, uint32_t* /*flags*/) - { - return true; - } -}; - -struct OpenDiskDevice -{ - OpenDiskDevice (DRDevice* d) - : device (d), - tracks ([[NSMutableArray alloc] init]), - underrunProtection (true) - { - } - - ~OpenDiskDevice() - { - [tracks release]; - } - - void addSourceTrack (AudioSource* source, int numSamples) - { - if (source != nullptr) - { - const int numFrames = (numSamples + 587) / 588; - - static AudioTrackProducerClass cls; - - NSObject* producer = [cls.createInstance() performSelector: @selector (initWithAudioSourceHolder:) - withObject: (id) new AudioTrackProducerClass::AudioSourceHolder (source, numFrames)]; - DRTrack* track = [[DRTrack alloc] initWithProducer: producer]; - - { - NSMutableDictionary* p = [[track properties] mutableCopy]; - [p setObject: [DRMSF msfWithFrames: numFrames] forKey: DRTrackLengthKey]; - [p setObject: [NSNumber numberWithUnsignedShort: 2352] forKey: DRBlockSizeKey]; - [p setObject: [NSNumber numberWithInt: 0] forKey: DRDataFormKey]; - [p setObject: [NSNumber numberWithInt: 0] forKey: DRBlockTypeKey]; - [p setObject: [NSNumber numberWithInt: 0] forKey: DRTrackModeKey]; - [p setObject: [NSNumber numberWithInt: 0] forKey: DRSessionFormatKey]; - [track setProperties: p]; - [p release]; - } - - [tracks addObject: track]; - - [track release]; - [producer release]; - } - } - - String burn (AudioCDBurner::BurnProgressListener* listener, - bool shouldEject, bool peformFakeBurnForTesting, int burnSpeed) - { - DRBurn* burn = [DRBurn burnForDevice: device]; - - if (! [device acquireExclusiveAccess]) - return "Couldn't open or write to the CD device"; - - [device acquireMediaReservation]; - - NSMutableDictionary* d = [[burn properties] mutableCopy]; - [d autorelease]; - [d setObject: [NSNumber numberWithBool: peformFakeBurnForTesting] forKey: DRBurnTestingKey]; - [d setObject: [NSNumber numberWithBool: false] forKey: DRBurnVerifyDiscKey]; - [d setObject: (shouldEject ? DRBurnCompletionActionEject : DRBurnCompletionActionMount) forKey: DRBurnCompletionActionKey]; - - if (burnSpeed > 0) - [d setObject: [NSNumber numberWithFloat: burnSpeed * kilobytesPerSecond1x] forKey: DRBurnRequestedSpeedKey]; - - if (! underrunProtection) - [d setObject: [NSNumber numberWithBool: false] forKey: DRBurnUnderrunProtectionKey]; - - [burn setProperties: d]; - - [burn writeLayout: tracks]; - - for (;;) - { - Thread::sleep (300); - float progress = [[[burn status] objectForKey: DRStatusPercentCompleteKey] floatValue]; - - if (listener != nullptr && listener->audioCDBurnProgress (progress)) - { - [burn abort]; - return "User cancelled the write operation"; - } - - if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateFailed]) - return "Write operation failed"; - - if ([[[burn status] objectForKey: DRStatusStateKey] isEqualTo: DRStatusStateDone]) - break; - - NSString* err = (NSString*) [[[burn status] objectForKey: DRErrorStatusKey] - objectForKey: DRErrorStatusErrorStringKey]; - if ([err length] > 0) - return nsStringToJuce (err); - } - - [device releaseMediaReservation]; - [device releaseExclusiveAccess]; - return String::empty; - } - - DRDevice* device; - NSMutableArray* tracks; - bool underrunProtection; -}; - -//============================================================================== -class AudioCDBurner::Pimpl : public Timer -{ -public: - Pimpl (AudioCDBurner& b, int deviceIndex) : owner (b) - { - if (DRDevice* dev = [[DRDevice devices] objectAtIndex: deviceIndex]) - { - device = new OpenDiskDevice (dev); - lastState = getDiskState(); - startTimer (1000); - } - } - - ~Pimpl() - { - stopTimer(); - } - - void timerCallback() override - { - const DiskState state = getDiskState(); - - if (state != lastState) - { - lastState = state; - owner.sendChangeMessage(); - } - } - - DiskState getDiskState() const - { - if ([device->device isValid]) - { - NSDictionary* status = [device->device status]; - NSString* state = [status objectForKey: DRDeviceMediaStateKey]; - - if ([state isEqualTo: DRDeviceMediaStateNone]) - { - if ([[status objectForKey: DRDeviceIsTrayOpenKey] boolValue]) - return trayOpen; - - return noDisc; - } - - if ([state isEqualTo: DRDeviceMediaStateMediaPresent]) - { - if ([[[status objectForKey: DRDeviceMediaInfoKey] objectForKey: DRDeviceMediaBlocksFreeKey] intValue] > 0) - return writableDiskPresent; - - return readOnlyDiskPresent; - } - } - - return unknown; - } - - bool openTray() { return [device->device isValid] && [device->device ejectMedia]; } - - Array getAvailableWriteSpeeds() const - { - Array results; - - if ([device->device isValid]) - for (id kbPerSec in [[[device->device status] objectForKey: DRDeviceMediaInfoKey] objectForKey: DRDeviceBurnSpeedsKey]) - results.add ([kbPerSec intValue] / kilobytesPerSecond1x); - - return results; - } - - bool setBufferUnderrunProtection (const bool shouldBeEnabled) - { - if ([device->device isValid]) - { - device->underrunProtection = shouldBeEnabled; - return shouldBeEnabled && [[[device->device status] objectForKey: DRDeviceCanUnderrunProtectCDKey] boolValue]; - } - - return false; - } - - int getNumAvailableAudioBlocks() const - { - return [[[[device->device status] objectForKey: DRDeviceMediaInfoKey] - objectForKey: DRDeviceMediaBlocksFreeKey] intValue]; - } - - ScopedPointer device; - -private: - DiskState lastState; - AudioCDBurner& owner; -}; - -//============================================================================== -AudioCDBurner::AudioCDBurner (const int deviceIndex) -{ - pimpl = new Pimpl (*this, deviceIndex); -} - -AudioCDBurner::~AudioCDBurner() -{ -} - -AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex) -{ - ScopedPointer b (new AudioCDBurner (deviceIndex)); - - if (b->pimpl->device == nil) - b = nullptr; - - return b.release(); -} - -StringArray AudioCDBurner::findAvailableDevices() -{ - StringArray s; - - for (NSDictionary* dic in [DRDevice devices]) - if (NSString* name = [dic valueForKey: DRDeviceProductNameKey]) - s.add (nsStringToJuce (name)); - - return s; -} - -AudioCDBurner::DiskState AudioCDBurner::getDiskState() const -{ - return pimpl->getDiskState(); -} - -bool AudioCDBurner::isDiskPresent() const -{ - return getDiskState() == writableDiskPresent; -} - -bool AudioCDBurner::openTray() -{ - return pimpl->openTray(); -} - -AudioCDBurner::DiskState AudioCDBurner::waitUntilStateChange (int timeOutMilliseconds) -{ - const int64 timeout = Time::currentTimeMillis() + timeOutMilliseconds; - DiskState oldState = getDiskState(); - DiskState newState = oldState; - - while (newState == oldState && Time::currentTimeMillis() < timeout) - { - newState = getDiskState(); - Thread::sleep (100); - } - - return newState; -} - -Array AudioCDBurner::getAvailableWriteSpeeds() const -{ - return pimpl->getAvailableWriteSpeeds(); -} - -bool AudioCDBurner::setBufferUnderrunProtection (const bool shouldBeEnabled) -{ - return pimpl->setBufferUnderrunProtection (shouldBeEnabled); -} - -int AudioCDBurner::getNumAvailableAudioBlocks() const -{ - return pimpl->getNumAvailableAudioBlocks(); -} - -bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamps) -{ - if ([pimpl->device->device isValid]) - { - pimpl->device->addSourceTrack (source, numSamps); - return true; - } - - return false; -} - -String AudioCDBurner::burn (AudioCDBurner::BurnProgressListener* listener, - bool ejectDiscAfterwards, - bool performFakeBurnForTesting, - int writeSpeed) -{ - if ([pimpl->device->device isValid]) - return pimpl->device->burn (listener, ejectDiscAfterwards, performFakeBurnForTesting, writeSpeed); - - return "Couldn't open or write to the CD device"; -} diff --git a/source/modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm b/source/modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm deleted file mode 100644 index 1ef5bd3ec..000000000 --- a/source/modules/juce_audio_devices/native/juce_mac_AudioCDReader.mm +++ /dev/null @@ -1,261 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace CDReaderHelpers -{ - inline const XmlElement* getElementForKey (const XmlElement& xml, const String& key) - { - forEachXmlChildElementWithTagName (xml, child, "key") - if (child->getAllSubText().trim() == key) - return child->getNextElement(); - - return nullptr; - } - - static int getIntValueForKey (const XmlElement& xml, const String& key, int defaultValue = -1) - { - const XmlElement* const block = getElementForKey (xml, key); - return block != nullptr ? block->getAllSubText().trim().getIntValue() : defaultValue; - } - - // Get the track offsets for a CD given an XmlElement representing its TOC.Plist. - // Returns NULL on success, otherwise a const char* representing an error. - static const char* getTrackOffsets (XmlDocument& xmlDocument, Array& offsets) - { - const ScopedPointer xml (xmlDocument.getDocumentElement()); - if (xml == nullptr) - return "Couldn't parse XML in file"; - - const XmlElement* const dict = xml->getChildByName ("dict"); - if (dict == nullptr) - return "Couldn't get top level dictionary"; - - const XmlElement* const sessions = getElementForKey (*dict, "Sessions"); - if (sessions == nullptr) - return "Couldn't find sessions key"; - - const XmlElement* const session = sessions->getFirstChildElement(); - if (session == nullptr) - return "Couldn't find first session"; - - const int leadOut = getIntValueForKey (*session, "Leadout Block"); - if (leadOut < 0) - return "Couldn't find Leadout Block"; - - const XmlElement* const trackArray = getElementForKey (*session, "Track Array"); - if (trackArray == nullptr) - return "Couldn't find Track Array"; - - forEachXmlChildElement (*trackArray, track) - { - const int trackValue = getIntValueForKey (*track, "Start Block"); - if (trackValue < 0) - return "Couldn't find Start Block in the track"; - - offsets.add (trackValue * AudioCDReader::samplesPerFrame - 88200); - } - - offsets.add (leadOut * AudioCDReader::samplesPerFrame - 88200); - return nullptr; - } - - static void findDevices (Array& cds) - { - File volumes ("/Volumes"); - volumes.findChildFiles (cds, File::findDirectories, false); - - for (int i = cds.size(); --i >= 0;) - if (! cds.getReference(i).getChildFile (".TOC.plist").exists()) - cds.remove (i); - } - - struct TrackSorter - { - static int getCDTrackNumber (const File& file) - { - return file.getFileName().initialSectionContainingOnly ("0123456789").getIntValue(); - } - - static int compareElements (const File& first, const File& second) - { - const int firstTrack = getCDTrackNumber (first); - const int secondTrack = getCDTrackNumber (second); - - jassert (firstTrack > 0 && secondTrack > 0); - - return firstTrack - secondTrack; - } - }; -} - -//============================================================================== -StringArray AudioCDReader::getAvailableCDNames() -{ - Array cds; - CDReaderHelpers::findDevices (cds); - - StringArray names; - - for (int i = 0; i < cds.size(); ++i) - names.add (cds.getReference(i).getFileName()); - - return names; -} - -AudioCDReader* AudioCDReader::createReaderForCD (const int index) -{ - Array cds; - CDReaderHelpers::findDevices (cds); - - if (cds[index].exists()) - return new AudioCDReader (cds[index]); - - return nullptr; -} - -AudioCDReader::AudioCDReader (const File& volume) - : AudioFormatReader (0, "CD Audio"), - volumeDir (volume), - currentReaderTrack (-1), - reader (0) -{ - sampleRate = 44100.0; - bitsPerSample = 16; - numChannels = 2; - usesFloatingPointData = false; - - refreshTrackLengths(); -} - -AudioCDReader::~AudioCDReader() -{ -} - -void AudioCDReader::refreshTrackLengths() -{ - tracks.clear(); - trackStartSamples.clear(); - lengthInSamples = 0; - - volumeDir.findChildFiles (tracks, File::findFiles | File::ignoreHiddenFiles, false, "*.aiff"); - - CDReaderHelpers::TrackSorter sorter; - tracks.sort (sorter); - - const File toc (volumeDir.getChildFile (".TOC.plist")); - - if (toc.exists()) - { - XmlDocument doc (toc); - const char* error = CDReaderHelpers::getTrackOffsets (doc, trackStartSamples); - ignoreUnused (error); // could be logged.. - - lengthInSamples = trackStartSamples.getLast() - trackStartSamples.getFirst(); - } -} - -bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) -{ - while (numSamples > 0) - { - int track = -1; - - for (int i = 0; i < trackStartSamples.size() - 1; ++i) - { - if (startSampleInFile < trackStartSamples.getUnchecked (i + 1)) - { - track = i; - break; - } - } - - if (track < 0) - return false; - - if (track != currentReaderTrack) - { - reader = nullptr; - - if (FileInputStream* const in = tracks [track].createInputStream()) - { - BufferedInputStream* const bin = new BufferedInputStream (in, 65536, true); - - AiffAudioFormat format; - reader = format.createReaderFor (bin, true); - - if (reader == nullptr) - currentReaderTrack = -1; - else - currentReaderTrack = track; - } - } - - if (reader == nullptr) - return false; - - const int startPos = (int) (startSampleInFile - trackStartSamples.getUnchecked (track)); - const int numAvailable = (int) jmin ((int64) numSamples, reader->lengthInSamples - startPos); - - reader->readSamples (destSamples, numDestChannels, startOffsetInDestBuffer, startPos, numAvailable); - - numSamples -= numAvailable; - startSampleInFile += numAvailable; - } - - return true; -} - -bool AudioCDReader::isCDStillPresent() const -{ - return volumeDir.exists(); -} - -void AudioCDReader::ejectDisk() -{ - JUCE_AUTORELEASEPOOL - { - [[NSWorkspace sharedWorkspace] unmountAndEjectDeviceAtPath: juceStringToNS (volumeDir.getFullPathName())]; - } -} - -bool AudioCDReader::isTrackAudio (int trackNum) const -{ - return tracks [trackNum].hasFileExtension (".aiff"); -} - -void AudioCDReader::enableIndexScanning (bool) -{ - // any way to do this on a Mac?? -} - -int AudioCDReader::getLastIndex() const -{ - return 0; -} - -Array AudioCDReader::findIndexesInTrack (const int /*trackNumber*/) -{ - return Array(); -} diff --git a/source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp index d6f9c5580..80758de9f 100644 --- a/source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ b/source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -921,7 +913,6 @@ public: isStarted (false) { CoreAudioInternal* device = nullptr; - if (outputDeviceId == 0 || outputDeviceId == inputDeviceId) { jassert (inputDeviceId != 0); @@ -931,9 +922,9 @@ public: { device = new CoreAudioInternal (*this, outputDeviceId, false, true); } + jassert (device != nullptr); internal = device; - jassert (device != nullptr); AudioObjectPropertyAddress pa; pa.mSelector = kAudioObjectPropertySelectorWildcard; @@ -1004,14 +995,6 @@ public: internal->stop (false); } - void restart() - { - JUCE_COREAUDIOLOG ("Restarting"); - AudioIODeviceCallback* oldCallback = internal->callback; - stop(); - start (oldCallback); - } - BigInteger getActiveOutputChannels() const override { return internal->activeOutputChans; } BigInteger getActiveInputChannels() const override { return internal->activeInputChans; } @@ -1074,6 +1057,19 @@ public: deviceType.audioDeviceListChanged(); } + void restart() + { + JUCE_COREAUDIOLOG ("Restarting"); + AudioIODeviceCallback* oldCallback = internal->callback; + stop(); + start (oldCallback); + } + + bool setCurrentSampleRate (double newSampleRate) + { + return internal->setNominalSampleRate (newSampleRate); + } + CoreAudioIODeviceType& deviceType; int inputIndex, outputIndex; @@ -1107,10 +1103,10 @@ class AudioIODeviceCombiner : public AudioIODevice, private Thread { public: - AudioIODeviceCombiner (const String& deviceName) + AudioIODeviceCombiner (const String& deviceName, CoreAudioIODeviceType& deviceType) : AudioIODevice (deviceName, "CoreAudio"), - Thread (deviceName), callback (nullptr), - currentSampleRate (0), currentBufferSize (0), active (false) + Thread (deviceName), + owner (deviceType) { } @@ -1120,7 +1116,7 @@ public: devices.clear(); } - void addDevice (AudioIODevice* device, bool useInputs, bool useOutputs) + void addDevice (CoreAudioIODevice* device, bool useInputs, bool useOutputs) { jassert (device != nullptr); jassert (! isOpen()); @@ -1280,7 +1276,7 @@ public: fifos.clear(); startThread (9); - return String(); + return {}; } void close() override @@ -1370,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 { @@ -1392,11 +1374,12 @@ public: } private: + CoreAudioIODeviceType& owner; CriticalSection callbackLock; - AudioIODeviceCallback* callback; - double currentSampleRate; - int currentBufferSize; - bool active; + AudioIODeviceCallback* callback = nullptr; + double currentSampleRate = 0; + int currentBufferSize = 0; + bool active = false; String lastError; AudioSampleBuffer fifos; @@ -1459,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) @@ -1551,10 +1555,49 @@ private: } } + void handleAudioDeviceAboutToStart (AudioIODevice* device) + { + const ScopedLock sl (callbackLock); + + auto newSampleRate = device->getCurrentSampleRate(); + auto commonRates = getAvailableSampleRates(); + if (! commonRates.contains (newSampleRate)) + { + commonRates.sort(); + if (newSampleRate < commonRates.getFirst() || newSampleRate > commonRates.getLast()) + newSampleRate = jlimit (commonRates.getFirst(), commonRates.getLast(), newSampleRate); + else + for (auto it = commonRates.begin(); it < commonRates.end() - 1; ++it) + if (it[0] < newSampleRate && it[1] > newSampleRate) + { + newSampleRate = newSampleRate - it[0] < it[1] - newSampleRate ? it[0] : it[1]; + break; + } + } + currentSampleRate = newSampleRate; + + bool anySampleRateChanges = false; + for (int i = 0; i < devices.size(); ++i) + if (devices.getUnchecked(i)->getCurrentSampleRate() != currentSampleRate) + { + devices.getUnchecked(i)->setCurrentSampleRate (currentSampleRate); + anySampleRateChanges = true; + } + + if (anySampleRateChanges) + owner.audioDeviceListChanged(); + + if (callback != nullptr) + callback->audioDeviceAboutToStart (device); + } + + void handleAudioDeviceStopped() { shutdown ({}); } + void handleAudioDeviceError (const String& errorMessage) { shutdown (errorMessage.isNotEmpty() ? errorMessage : String ("unknown")); } + //============================================================================== struct DeviceWrapper : private AudioIODeviceCallback { - DeviceWrapper (AudioIODeviceCombiner& cd, AudioIODevice* d, bool useIns, bool useOuts) + DeviceWrapper (AudioIODeviceCombiner& cd, CoreAudioIODevice* d, bool useIns, bool useOuts) : owner (cd), device (d), inputIndex (0), outputIndex (0), useInputs (useIns), useOutputs (useOuts), inputFifo (32), outputFifo (32), done (false) @@ -1732,19 +1775,15 @@ private: owner.notify(); } - void audioDeviceAboutToStart (AudioIODevice*) override {} - void audioDeviceStopped() override {} - - void audioDeviceError (const String& errorMessage) override - { - const ScopedLock sl (owner.callbackLock); + double getCurrentSampleRate() { return device->getCurrentSampleRate(); } + bool setCurrentSampleRate (double newSampleRate) { return device->setCurrentSampleRate (newSampleRate); } - if (owner.callback != nullptr) - owner.callback->audioDeviceError (errorMessage); - } + void audioDeviceAboutToStart (AudioIODevice* d) override { owner.handleAudioDeviceAboutToStart (d); } + void audioDeviceStopped() override { owner.handleAudioDeviceStopped(); } + void audioDeviceError (const String& errorMessage) override { owner.handleAudioDeviceError (errorMessage); } AudioIODeviceCombiner& owner; - ScopedPointer device; + ScopedPointer device; int inputIndex, numInputChans, outputIndex, numOutputChans; bool useInputs, useOutputs; AbstractFifo inputFifo, outputFifo; @@ -1942,7 +1981,7 @@ public: if (in == nullptr) return out.release(); if (out == nullptr) return in.release(); - ScopedPointer combo (new AudioIODeviceCombiner (combinedName)); + ScopedPointer combo (new AudioIODeviceCombiner (combinedName, *this)); combo->addDevice (in.release(), true, false); combo->addDevice (out.release(), false, true); return combo.release(); @@ -1998,7 +2037,7 @@ private: static OSStatus hardwareListenerProc (AudioDeviceID, UInt32, const AudioObjectPropertyAddress*, void* clientData) { - static_cast (clientData)->audioDeviceListChanged(); + static_cast (clientData)->triggerAsyncAudioDeviceListChange(); return noErr; } diff --git a/source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp b/source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp index 5391f23f9..4abff0f09 100644 --- a/source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp +++ b/source/modules/juce_audio_devices/native/juce_mac_CoreMidi.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -74,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)); @@ -181,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; @@ -226,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(); diff --git a/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp b/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp index 66df4f6dd..e6d88aa13 100644 --- a/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp +++ b/source/modules/juce_audio_devices/native/juce_win32_ASIO.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp b/source/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp deleted file mode 100644 index 997484f2f..000000000 --- a/source/modules/juce_audio_devices/native/juce_win32_AudioCDBurner.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace CDBurnerHelpers -{ - IDiscRecorder* enumCDBurners (StringArray* list, int indexToOpen, IDiscMaster** master) - { - CoInitialize (0); - - IDiscMaster* dm; - IDiscRecorder* result = nullptr; - - if (SUCCEEDED (CoCreateInstance (CLSID_MSDiscMasterObj, 0, - CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, - IID_IDiscMaster, - (void**) &dm))) - { - if (SUCCEEDED (dm->Open())) - { - IEnumDiscRecorders* drEnum = nullptr; - - if (SUCCEEDED (dm->EnumDiscRecorders (&drEnum))) - { - IDiscRecorder* dr = nullptr; - DWORD dummy; - int index = 0; - - while (drEnum->Next (1, &dr, &dummy) == S_OK) - { - if (indexToOpen == index) - { - result = dr; - break; - } - else if (list != nullptr) - { - BSTR path; - - if (SUCCEEDED (dr->GetPath (&path))) - list->add ((const WCHAR*) path); - } - - ++index; - dr->Release(); - } - - drEnum->Release(); - } - - if (master == 0) - dm->Close(); - } - - if (master != nullptr) - *master = dm; - else - dm->Release(); - } - - return result; - } -} - -//============================================================================== -class AudioCDBurner::Pimpl : public ComBaseClassHelper , - public Timer -{ -public: - Pimpl (AudioCDBurner& owner_, IDiscMaster* discMaster_, IDiscRecorder* discRecorder_) - : owner (owner_), discMaster (discMaster_), discRecorder (discRecorder_), redbook (0), - listener (0), progress (0), shouldCancel (false) - { - HRESULT hr = discMaster->SetActiveDiscMasterFormat (IID_IRedbookDiscMaster, (void**) &redbook); - jassert (SUCCEEDED (hr)); - hr = discMaster->SetActiveDiscRecorder (discRecorder); - //jassert (SUCCEEDED (hr)); - - lastState = getDiskState(); - startTimer (2000); - } - - ~Pimpl() {} - - void releaseObjects() - { - discRecorder->Close(); - if (redbook != nullptr) - redbook->Release(); - discRecorder->Release(); - discMaster->Release(); - Release(); - } - - JUCE_COMRESULT QueryCancel (boolean* pbCancel) - { - if (listener != nullptr && ! shouldCancel) - shouldCancel = listener->audioCDBurnProgress (progress); - - *pbCancel = shouldCancel; - - return S_OK; - } - - JUCE_COMRESULT NotifyBlockProgress (long nCompleted, long nTotal) - { - progress = nCompleted / (float) nTotal; - shouldCancel = listener != nullptr && listener->audioCDBurnProgress (progress); - - return E_NOTIMPL; - } - - JUCE_COMRESULT NotifyPnPActivity (void) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyAddProgress (long /*nCompletedSteps*/, long /*nTotalSteps*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyTrackProgress (long /*nCurrentTrack*/, long /*nTotalTracks*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyPreparingBurn (long /*nEstimatedSeconds*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyClosingDisc (long /*nEstimatedSeconds*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyBurnComplete (HRESULT /*status*/) { return E_NOTIMPL; } - JUCE_COMRESULT NotifyEraseComplete (HRESULT /*status*/) { return E_NOTIMPL; } - - class ScopedDiscOpener - { - public: - ScopedDiscOpener (Pimpl& p) : pimpl (p) { pimpl.discRecorder->OpenExclusive(); } - ~ScopedDiscOpener() { pimpl.discRecorder->Close(); } - - private: - Pimpl& pimpl; - - JUCE_DECLARE_NON_COPYABLE (ScopedDiscOpener) - }; - - DiskState getDiskState() - { - const ScopedDiscOpener opener (*this); - - long type, flags; - HRESULT hr = discRecorder->QueryMediaType (&type, &flags); - - if (FAILED (hr)) - return unknown; - - if (type != 0 && (flags & MEDIA_WRITABLE) != 0) - return writableDiskPresent; - - if (type == 0) - return noDisc; - - return readOnlyDiskPresent; - } - - int getIntProperty (const LPOLESTR name, const int defaultReturn) const - { - ComSmartPtr prop; - if (FAILED (discRecorder->GetRecorderProperties (prop.resetAndGetPointerAddress()))) - return defaultReturn; - - PROPSPEC iPropSpec; - iPropSpec.ulKind = PRSPEC_LPWSTR; - iPropSpec.lpwstr = name; - - PROPVARIANT iPropVariant; - return FAILED (prop->ReadMultiple (1, &iPropSpec, &iPropVariant)) - ? defaultReturn : (int) iPropVariant.lVal; - } - - bool setIntProperty (const LPOLESTR name, const int value) const - { - ComSmartPtr prop; - if (FAILED (discRecorder->GetRecorderProperties (prop.resetAndGetPointerAddress()))) - return false; - - PROPSPEC iPropSpec; - iPropSpec.ulKind = PRSPEC_LPWSTR; - iPropSpec.lpwstr = name; - - PROPVARIANT iPropVariant; - if (FAILED (prop->ReadMultiple (1, &iPropSpec, &iPropVariant))) - return false; - - iPropVariant.lVal = (long) value; - return SUCCEEDED (prop->WriteMultiple (1, &iPropSpec, &iPropVariant, iPropVariant.vt)) - && SUCCEEDED (discRecorder->SetRecorderProperties (prop)); - } - - void timerCallback() override - { - const DiskState state = getDiskState(); - - if (state != lastState) - { - lastState = state; - owner.sendChangeMessage(); - } - } - - AudioCDBurner& owner; - DiskState lastState; - IDiscMaster* discMaster; - IDiscRecorder* discRecorder; - IRedbookDiscMaster* redbook; - AudioCDBurner::BurnProgressListener* listener; - float progress; - bool shouldCancel; -}; - -//============================================================================== -AudioCDBurner::AudioCDBurner (const int deviceIndex) -{ - IDiscMaster* discMaster = nullptr; - IDiscRecorder* discRecorder = CDBurnerHelpers::enumCDBurners (0, deviceIndex, &discMaster); - - if (discRecorder != nullptr) - pimpl = new Pimpl (*this, discMaster, discRecorder); -} - -AudioCDBurner::~AudioCDBurner() -{ - if (pimpl != nullptr) - pimpl.release()->releaseObjects(); -} - -StringArray AudioCDBurner::findAvailableDevices() -{ - StringArray devs; - CDBurnerHelpers::enumCDBurners (&devs, -1, 0); - return devs; -} - -AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex) -{ - ScopedPointer b (new AudioCDBurner (deviceIndex)); - - if (b->pimpl == 0) - b = nullptr; - - return b.release(); -} - -AudioCDBurner::DiskState AudioCDBurner::getDiskState() const -{ - return pimpl->getDiskState(); -} - -bool AudioCDBurner::isDiskPresent() const -{ - return getDiskState() == writableDiskPresent; -} - -bool AudioCDBurner::openTray() -{ - const Pimpl::ScopedDiscOpener opener (*pimpl); - return SUCCEEDED (pimpl->discRecorder->Eject()); -} - -AudioCDBurner::DiskState AudioCDBurner::waitUntilStateChange (int timeOutMilliseconds) -{ - const int64 timeout = Time::currentTimeMillis() + timeOutMilliseconds; - DiskState oldState = getDiskState(); - DiskState newState = oldState; - - while (newState == oldState && Time::currentTimeMillis() < timeout) - { - newState = getDiskState(); - Thread::sleep (jmin (250, (int) (timeout - Time::currentTimeMillis()))); - } - - return newState; -} - -Array AudioCDBurner::getAvailableWriteSpeeds() const -{ - Array results; - const int maxSpeed = pimpl->getIntProperty (L"MaxWriteSpeed", 1); - const int speeds[] = { 1, 2, 4, 8, 12, 16, 20, 24, 32, 40, 64, 80 }; - - for (int i = 0; i < numElementsInArray (speeds); ++i) - if (speeds[i] <= maxSpeed) - results.add (speeds[i]); - - results.addIfNotAlreadyThere (maxSpeed); - return results; -} - -bool AudioCDBurner::setBufferUnderrunProtection (const bool shouldBeEnabled) -{ - if (pimpl->getIntProperty (L"BufferUnderrunFreeCapable", 0) == 0) - return false; - - pimpl->setIntProperty (L"EnableBufferUnderrunFree", shouldBeEnabled ? -1 : 0); - return pimpl->getIntProperty (L"EnableBufferUnderrunFree", 0) != 0; -} - -int AudioCDBurner::getNumAvailableAudioBlocks() const -{ - long blocksFree = 0; - pimpl->redbook->GetAvailableAudioTrackBlocks (&blocksFree); - return blocksFree; -} - -String AudioCDBurner::burn (AudioCDBurner::BurnProgressListener* listener, bool ejectDiscAfterwards, - bool performFakeBurnForTesting, int writeSpeed) -{ - pimpl->setIntProperty (L"WriteSpeed", writeSpeed > 0 ? writeSpeed : -1); - - pimpl->listener = listener; - pimpl->progress = 0; - pimpl->shouldCancel = false; - - UINT_PTR cookie; - HRESULT hr = pimpl->discMaster->ProgressAdvise ((AudioCDBurner::Pimpl*) pimpl, &cookie); - - hr = pimpl->discMaster->RecordDisc (performFakeBurnForTesting, - ejectDiscAfterwards); - - String error; - if (hr != S_OK) - { - const char* e = "Couldn't open or write to the CD device"; - - if (hr == IMAPI_E_USERABORT) - e = "User cancelled the write operation"; - else if (hr == IMAPI_E_MEDIUM_NOTPRESENT || hr == IMAPI_E_TRACKOPEN) - e = "No Disk present"; - - error = e; - } - - pimpl->discMaster->ProgressUnadvise (cookie); - pimpl->listener = 0; - - return error; -} - -bool AudioCDBurner::addAudioTrack (AudioSource* audioSource, int numSamples) -{ - if (audioSource == 0) - return false; - - ScopedPointer source (audioSource); - - long bytesPerBlock; - HRESULT hr = pimpl->redbook->GetAudioBlockSize (&bytesPerBlock); - - const int samplesPerBlock = bytesPerBlock / 4; - bool ok = true; - - hr = pimpl->redbook->CreateAudioTrack ((long) numSamples / (bytesPerBlock * 4)); - - HeapBlock buffer (bytesPerBlock); - AudioSampleBuffer sourceBuffer (2, samplesPerBlock); - int samplesDone = 0; - - source->prepareToPlay (samplesPerBlock, 44100.0); - - while (ok) - { - { - AudioSourceChannelInfo info (&sourceBuffer, 0, samplesPerBlock); - sourceBuffer.clear(); - - source->getNextAudioBlock (info); - } - - buffer.clear (bytesPerBlock); - - typedef AudioData::Pointer CDSampleFormat; - - typedef AudioData::Pointer SourceSampleFormat; - - CDSampleFormat left (buffer, 2); - left.convertSamples (SourceSampleFormat (sourceBuffer.getReadPointer (0)), samplesPerBlock); - CDSampleFormat right (buffer + 2, 2); - right.convertSamples (SourceSampleFormat (sourceBuffer.getReadPointer (1)), samplesPerBlock); - - hr = pimpl->redbook->AddAudioTrackBlocks (buffer, bytesPerBlock); - - if (FAILED (hr)) - ok = false; - - samplesDone += samplesPerBlock; - - if (samplesDone >= numSamples) - break; - } - - hr = pimpl->redbook->CloseAudioTrack(); - return ok && hr == S_OK; -} diff --git a/source/modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp b/source/modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp deleted file mode 100644 index ea99f80ab..000000000 --- a/source/modules/juce_audio_devices/native/juce_win32_AudioCDReader.cpp +++ /dev/null @@ -1,1309 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -namespace CDReaderHelpers -{ - -#define FILE_ANY_ACCESS 0 -#ifndef FILE_READ_ACCESS - #define FILE_READ_ACCESS 1 -#endif -#ifndef FILE_WRITE_ACCESS - #define FILE_WRITE_ACCESS 2 -#endif - -#define METHOD_BUFFERED 0 -#define IOCTL_SCSI_BASE 4 -#define SCSI_IOCTL_DATA_OUT 0 -#define SCSI_IOCTL_DATA_IN 1 -#define SCSI_IOCTL_DATA_UNSPECIFIED 2 - -#define CTL_CODE2(DevType, Function, Method, Access) (((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) -#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE2( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS ) -#define IOCTL_SCSI_GET_ADDRESS CTL_CODE2( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS ) - -#define SENSE_LEN 14 -#define SRB_ENABLE_RESIDUAL_COUNT 0x04 -#define SRB_DIR_IN 0x08 -#define SRB_DIR_OUT 0x10 -#define SRB_EVENT_NOTIFY 0x40 -#define SC_HA_INQUIRY 0x00 -#define SC_GET_DEV_TYPE 0x01 -#define SC_EXEC_SCSI_CMD 0x02 -#define SS_PENDING 0x00 -#define SS_COMP 0x01 -#define SS_ERR 0x04 - -enum -{ - READTYPE_ANY = 0, - READTYPE_ATAPI1 = 1, - READTYPE_ATAPI2 = 2, - READTYPE_READ6 = 3, - READTYPE_READ10 = 4, - READTYPE_READ_D8 = 5, - READTYPE_READ_D4 = 6, - READTYPE_READ_D4_1 = 7, - READTYPE_READ10_2 = 8 -}; - -struct SCSI_PASS_THROUGH -{ - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - ULONG DataBufferOffset; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -}; - -struct SCSI_PASS_THROUGH_DIRECT -{ - USHORT Length; - UCHAR ScsiStatus; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; - UCHAR CdbLength; - UCHAR SenseInfoLength; - UCHAR DataIn; - ULONG DataTransferLength; - ULONG TimeOutValue; - PVOID DataBuffer; - ULONG SenseInfoOffset; - UCHAR Cdb[16]; -}; - -struct SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER -{ - SCSI_PASS_THROUGH_DIRECT spt; - ULONG Filler; - UCHAR ucSenseBuf[32]; -}; - -struct SCSI_ADDRESS -{ - ULONG Length; - UCHAR PortNumber; - UCHAR PathId; - UCHAR TargetId; - UCHAR Lun; -}; - -#pragma pack(1) - -struct SRB_GDEVBlock -{ - BYTE SRB_Cmd; - BYTE SRB_Status; - BYTE SRB_HaID; - BYTE SRB_Flags; - DWORD SRB_Hdr_Rsvd; - BYTE SRB_Target; - BYTE SRB_Lun; - BYTE SRB_DeviceType; - BYTE SRB_Rsvd1; - BYTE pad[68]; -}; - - -struct SRB_ExecSCSICmd -{ - BYTE SRB_Cmd; - BYTE SRB_Status; - BYTE SRB_HaID; - BYTE SRB_Flags; - DWORD SRB_Hdr_Rsvd; - BYTE SRB_Target; - BYTE SRB_Lun; - WORD SRB_Rsvd1; - DWORD SRB_BufLen; - BYTE *SRB_BufPointer; - BYTE SRB_SenseLen; - BYTE SRB_CDBLen; - BYTE SRB_HaStat; - BYTE SRB_TargStat; - VOID *SRB_PostProc; - BYTE SRB_Rsvd2[20]; - BYTE CDBByte[16]; - BYTE SenseArea[SENSE_LEN + 2]; -}; - -struct SRB -{ - BYTE SRB_Cmd; - BYTE SRB_Status; - BYTE SRB_HaId; - BYTE SRB_Flags; - DWORD SRB_Hdr_Rsvd; -}; - -struct TOCTRACK -{ - BYTE rsvd; - BYTE ADR; - BYTE trackNumber; - BYTE rsvd2; - BYTE addr[4]; -}; - -struct TOC -{ - WORD tocLen; - BYTE firstTrack; - BYTE lastTrack; - TOCTRACK tracks[100]; -}; - -#pragma pack() - -//============================================================================== -struct CDDeviceDescription -{ - CDDeviceDescription() : ha (0), tgt (0), lun (0), scsiDriveLetter (0) - { - } - - void createDescription (const char* data) - { - description << String (data + 8, 8).trim() // vendor - << ' ' << String (data + 16, 16).trim() // product id - << ' ' << String (data + 32, 4).trim(); // rev - } - - String description; - BYTE ha, tgt, lun; - char scsiDriveLetter; // will be 0 if not using scsi -}; - -//============================================================================== -class CDReadBuffer -{ -public: - CDReadBuffer (const int numberOfFrames) - : startFrame (0), numFrames (0), dataStartOffset (0), - dataLength (0), bufferSize (2352 * numberOfFrames), index (0), - buffer (bufferSize), wantsIndex (false) - { - } - - bool isZero() const noexcept - { - for (int i = 0; i < dataLength; ++i) - if (buffer [dataStartOffset + i] != 0) - return false; - - return true; - } - - int startFrame, numFrames, dataStartOffset; - int dataLength, bufferSize, index; - HeapBlock buffer; - bool wantsIndex; -}; - -class CDDeviceHandle; - -//============================================================================== -class CDController -{ -public: - CDController() : initialised (false) {} - virtual ~CDController() {} - - virtual bool read (CDReadBuffer&) = 0; - virtual void shutDown() {} - - bool readAudio (CDReadBuffer& rb, CDReadBuffer* overlapBuffer = 0); - int getLastIndex(); - -public: - CDDeviceHandle* deviceInfo; - int framesToCheck, framesOverlap; - bool initialised; - - void prepare (SRB_ExecSCSICmd& s); - void perform (SRB_ExecSCSICmd& s); - void setPaused (bool paused); -}; - - -//============================================================================== -class CDDeviceHandle -{ -public: - CDDeviceHandle (const CDDeviceDescription& device, HANDLE scsiHandle_) - : info (device), scsiHandle (scsiHandle_), readType (READTYPE_ANY) - { - } - - ~CDDeviceHandle() - { - if (controller != nullptr) - { - controller->shutDown(); - controller = 0; - } - - if (scsiHandle != 0) - CloseHandle (scsiHandle); - } - - bool readTOC (TOC* lpToc); - bool readAudio (CDReadBuffer& buffer, CDReadBuffer* overlapBuffer = 0); - void openDrawer (bool shouldBeOpen); - void performScsiCommand (HANDLE event, SRB_ExecSCSICmd& s); - - CDDeviceDescription info; - HANDLE scsiHandle; - BYTE readType; - -private: - ScopedPointer controller; - - bool testController (int readType, CDController* newController, CDReadBuffer& bufferToUse); -}; - -//============================================================================== -HANDLE createSCSIDeviceHandle (const char driveLetter) -{ - TCHAR devicePath[] = { '\\', '\\', '.', '\\', driveLetter, ':', 0, 0 }; - DWORD flags = GENERIC_READ | GENERIC_WRITE; - HANDLE h = CreateFile (devicePath, flags, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - - if (h == INVALID_HANDLE_VALUE) - { - flags ^= GENERIC_WRITE; - h = CreateFile (devicePath, flags, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - } - - return h; -} - -void findCDDevices (Array& list) -{ - for (char driveLetter = 'b'; driveLetter <= 'z'; ++driveLetter) - { - TCHAR drivePath[] = { driveLetter, ':', '\\', 0, 0 }; - - if (GetDriveType (drivePath) == DRIVE_CDROM) - { - HANDLE h = createSCSIDeviceHandle (driveLetter); - - if (h != INVALID_HANDLE_VALUE) - { - char buffer[100] = { 0 }; - - SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER p = { 0 }; - p.spt.Length = sizeof (SCSI_PASS_THROUGH); - p.spt.CdbLength = 6; - p.spt.SenseInfoLength = 24; - p.spt.DataIn = SCSI_IOCTL_DATA_IN; - p.spt.DataTransferLength = sizeof (buffer); - p.spt.TimeOutValue = 2; - p.spt.DataBuffer = buffer; - p.spt.SenseInfoOffset = offsetof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf); - p.spt.Cdb[0] = 0x12; - p.spt.Cdb[4] = 100; - - DWORD bytesReturned = 0; - - if (DeviceIoControl (h, IOCTL_SCSI_PASS_THROUGH_DIRECT, - &p, sizeof (p), &p, sizeof (p), - &bytesReturned, 0) != 0) - { - CDDeviceDescription dev; - dev.scsiDriveLetter = driveLetter; - dev.createDescription (buffer); - - SCSI_ADDRESS scsiAddr = { 0 }; - scsiAddr.Length = sizeof (scsiAddr); - - if (DeviceIoControl (h, IOCTL_SCSI_GET_ADDRESS, - 0, 0, &scsiAddr, sizeof (scsiAddr), - &bytesReturned, 0) != 0) - { - dev.ha = scsiAddr.PortNumber; - dev.tgt = scsiAddr.TargetId; - dev.lun = scsiAddr.Lun; - list.add (dev); - } - } - - CloseHandle (h); - } - } - } -} - -DWORD performScsiPassThroughCommand (SRB_ExecSCSICmd* const srb, const char driveLetter, - HANDLE& deviceHandle, const bool retryOnFailure) -{ - SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER s = { 0 }; - s.spt.Length = sizeof (SCSI_PASS_THROUGH); - s.spt.CdbLength = srb->SRB_CDBLen; - - s.spt.DataIn = (BYTE) ((srb->SRB_Flags & SRB_DIR_IN) - ? SCSI_IOCTL_DATA_IN - : ((srb->SRB_Flags & SRB_DIR_OUT) - ? SCSI_IOCTL_DATA_OUT - : SCSI_IOCTL_DATA_UNSPECIFIED)); - - s.spt.DataTransferLength = srb->SRB_BufLen; - s.spt.TimeOutValue = 5; - s.spt.DataBuffer = srb->SRB_BufPointer; - s.spt.SenseInfoOffset = offsetof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf); - - memcpy (s.spt.Cdb, srb->CDBByte, srb->SRB_CDBLen); - - srb->SRB_Status = SS_ERR; - srb->SRB_TargStat = 0x0004; - - DWORD bytesReturned = 0; - - if (DeviceIoControl (deviceHandle, IOCTL_SCSI_PASS_THROUGH_DIRECT, - &s, sizeof (s), &s, sizeof (s), &bytesReturned, 0) != 0) - { - srb->SRB_Status = SS_COMP; - } - else if (retryOnFailure) - { - const DWORD error = GetLastError(); - - if ((error == ERROR_MEDIA_CHANGED) || (error == ERROR_INVALID_HANDLE)) - { - if (error != ERROR_INVALID_HANDLE) - CloseHandle (deviceHandle); - - deviceHandle = createSCSIDeviceHandle (driveLetter); - - return performScsiPassThroughCommand (srb, driveLetter, deviceHandle, false); - } - } - - return srb->SRB_Status; -} - - -//============================================================================== -// Controller types.. - -class ControllerType1 : public CDController -{ -public: - ControllerType1() {} - - bool read (CDReadBuffer& rb) - { - if (rb.numFrames * 2352 > rb.bufferSize) - return false; - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = rb.bufferSize; - s.SRB_BufPointer = rb.buffer; - s.SRB_CDBLen = 12; - s.CDBByte[0] = 0xBE; - s.CDBByte[3] = (BYTE) ((rb.startFrame >> 16) & 0xFF); - s.CDBByte[4] = (BYTE) ((rb.startFrame >> 8) & 0xFF); - s.CDBByte[5] = (BYTE) (rb.startFrame & 0xFF); - s.CDBByte[8] = (BYTE) (rb.numFrames & 0xFF); - s.CDBByte[9] = (BYTE) (deviceInfo->readType == READTYPE_ATAPI1 ? 0x10 : 0xF0); - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - - rb.dataLength = rb.numFrames * 2352; - rb.dataStartOffset = 0; - return true; - } -}; - -//============================================================================== -class ControllerType2 : public CDController -{ -public: - ControllerType2() {} - - void shutDown() - { - if (initialised) - { - BYTE bufPointer[] = { 0, 0, 0, 8, 83, 0, 0, 0, 0, 0, 8, 0 }; - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY | SRB_ENABLE_RESIDUAL_COUNT; - s.SRB_BufLen = 0x0C; - s.SRB_BufPointer = bufPointer; - s.SRB_CDBLen = 6; - s.CDBByte[0] = 0x15; - s.CDBByte[4] = 0x0C; - perform (s); - } - } - - bool init() - { - SRB_ExecSCSICmd s; - s.SRB_Status = SS_ERR; - - if (deviceInfo->readType == READTYPE_READ10_2) - { - BYTE bufPointer1[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48, 35, 6, 0, 0, 0, 0, 0, 128 }; - BYTE bufPointer2[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48, 1, 6, 32, 7, 0, 0, 0, 0 }; - - for (int i = 0; i < 2; ++i) - { - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x14; - s.SRB_BufPointer = (i == 0) ? bufPointer1 : bufPointer2; - s.SRB_CDBLen = 6; - s.CDBByte[0] = 0x15; - s.CDBByte[1] = 0x10; - s.CDBByte[4] = 0x14; - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - } - } - else - { - BYTE bufPointer[] = { 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 48 }; - - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x0C; - s.SRB_BufPointer = bufPointer; - s.SRB_CDBLen = 6; - s.CDBByte[0] = 0x15; - s.CDBByte[4] = 0x0C; - perform (s); - } - - return s.SRB_Status == SS_COMP; - } - - bool read (CDReadBuffer& rb) - { - if (rb.numFrames * 2352 > rb.bufferSize) - return false; - - if (! initialised) - { - initialised = init(); - - if (! initialised) - return false; - } - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = rb.bufferSize; - s.SRB_BufPointer = rb.buffer; - s.SRB_CDBLen = 10; - s.CDBByte[0] = 0x28; - s.CDBByte[1] = (BYTE) (deviceInfo->info.lun << 5); - s.CDBByte[3] = (BYTE) ((rb.startFrame >> 16) & 0xFF); - s.CDBByte[4] = (BYTE) ((rb.startFrame >> 8) & 0xFF); - s.CDBByte[5] = (BYTE) (rb.startFrame & 0xFF); - s.CDBByte[8] = (BYTE) (rb.numFrames & 0xFF); - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - - rb.dataLength = rb.numFrames * 2352; - rb.dataStartOffset = 0; - return true; - } -}; - -//============================================================================== -class ControllerType3 : public CDController -{ -public: - ControllerType3() {} - - bool read (CDReadBuffer& rb) - { - if (rb.numFrames * 2352 > rb.bufferSize) - return false; - - if (! initialised) - { - setPaused (false); - initialised = true; - } - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = rb.numFrames * 2352; - s.SRB_BufPointer = rb.buffer; - s.SRB_CDBLen = 12; - s.CDBByte[0] = 0xD8; - s.CDBByte[3] = (BYTE) ((rb.startFrame >> 16) & 0xFF); - s.CDBByte[4] = (BYTE) ((rb.startFrame >> 8) & 0xFF); - s.CDBByte[5] = (BYTE) (rb.startFrame & 0xFF); - s.CDBByte[9] = (BYTE) (rb.numFrames & 0xFF); - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - - rb.dataLength = rb.numFrames * 2352; - rb.dataStartOffset = 0; - return true; - } -}; - -//============================================================================== -class ControllerType4 : public CDController -{ -public: - ControllerType4() {} - - bool selectD4Mode() - { - BYTE bufPointer[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 48 }; - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY; - s.SRB_CDBLen = 6; - s.SRB_BufLen = 12; - s.SRB_BufPointer = bufPointer; - s.CDBByte[0] = 0x15; - s.CDBByte[1] = 0x10; - s.CDBByte[4] = 0x08; - perform (s); - - return s.SRB_Status == SS_COMP; - } - - bool read (CDReadBuffer& rb) - { - if (rb.numFrames * 2352 > rb.bufferSize) - return false; - - if (! initialised) - { - setPaused (true); - - if (deviceInfo->readType == READTYPE_READ_D4_1) - selectD4Mode(); - - initialised = true; - } - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = rb.bufferSize; - s.SRB_BufPointer = rb.buffer; - s.SRB_CDBLen = 10; - s.CDBByte[0] = 0xD4; - s.CDBByte[3] = (BYTE) ((rb.startFrame >> 16) & 0xFF); - s.CDBByte[4] = (BYTE) ((rb.startFrame >> 8) & 0xFF); - s.CDBByte[5] = (BYTE) (rb.startFrame & 0xFF); - s.CDBByte[8] = (BYTE) (rb.numFrames & 0xFF); - perform (s); - - if (s.SRB_Status != SS_COMP) - return false; - - rb.dataLength = rb.numFrames * 2352; - rb.dataStartOffset = 0; - return true; - } -}; - - -//============================================================================== -void CDController::prepare (SRB_ExecSCSICmd& s) -{ - zerostruct (s); - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaID = deviceInfo->info.ha; - s.SRB_Target = deviceInfo->info.tgt; - s.SRB_Lun = deviceInfo->info.lun; - s.SRB_SenseLen = SENSE_LEN; -} - -void CDController::perform (SRB_ExecSCSICmd& s) -{ - s.SRB_PostProc = CreateEvent (0, TRUE, FALSE, 0); - - deviceInfo->performScsiCommand (s.SRB_PostProc, s); -} - -void CDController::setPaused (bool paused) -{ - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_EVENT_NOTIFY; - s.SRB_CDBLen = 10; - s.CDBByte[0] = 0x4B; - s.CDBByte[8] = (BYTE) (paused ? 0 : 1); - perform (s); -} - -bool CDController::readAudio (CDReadBuffer& rb, CDReadBuffer* overlapBuffer) -{ - if (overlapBuffer != nullptr) - { - const bool canDoJitter = (overlapBuffer->bufferSize >= 2352 * framesToCheck); - const bool doJitter = canDoJitter && ! overlapBuffer->isZero(); - - if (doJitter - && overlapBuffer->startFrame > 0 - && overlapBuffer->numFrames > 0 - && overlapBuffer->dataLength > 0) - { - const int numFrames = rb.numFrames; - - if (overlapBuffer->startFrame == (rb.startFrame - framesToCheck)) - { - rb.startFrame -= framesOverlap; - - if (framesToCheck < framesOverlap - && numFrames + framesOverlap <= rb.bufferSize / 2352) - rb.numFrames += framesOverlap; - } - else - { - overlapBuffer->dataLength = 0; - overlapBuffer->startFrame = 0; - overlapBuffer->numFrames = 0; - } - } - - if (! read (rb)) - return false; - - if (doJitter) - { - const int checkLen = framesToCheck * 2352; - const int maxToCheck = rb.dataLength - checkLen; - - if (overlapBuffer->dataLength == 0 || overlapBuffer->isZero()) - return true; - - BYTE* const p = overlapBuffer->buffer + overlapBuffer->dataStartOffset; - bool found = false; - - for (int i = 0; i < maxToCheck; ++i) - { - if (memcmp (p, rb.buffer + i, checkLen) == 0) - { - i += checkLen; - rb.dataStartOffset = i; - rb.dataLength -= i; - rb.startFrame = overlapBuffer->startFrame + framesToCheck; - found = true; - break; - } - } - - rb.numFrames = rb.dataLength / 2352; - rb.dataLength = 2352 * rb.numFrames; - - if (! found) - return false; - } - - if (canDoJitter) - { - memcpy (overlapBuffer->buffer, - rb.buffer + rb.dataStartOffset + 2352 * (rb.numFrames - framesToCheck), - 2352 * framesToCheck); - - overlapBuffer->startFrame = rb.startFrame + rb.numFrames - framesToCheck; - overlapBuffer->numFrames = framesToCheck; - overlapBuffer->dataLength = 2352 * framesToCheck; - overlapBuffer->dataStartOffset = 0; - } - else - { - overlapBuffer->startFrame = 0; - overlapBuffer->numFrames = 0; - overlapBuffer->dataLength = 0; - } - - return true; - } - - return read (rb); -} - -int CDController::getLastIndex() -{ - char qdata[100]; - - SRB_ExecSCSICmd s; - prepare (s); - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = sizeof (qdata); - s.SRB_BufPointer = (BYTE*) qdata; - s.SRB_CDBLen = 12; - s.CDBByte[0] = 0x42; - s.CDBByte[1] = (BYTE) (deviceInfo->info.lun << 5); - s.CDBByte[2] = 64; - s.CDBByte[3] = 1; // get current position - s.CDBByte[7] = 0; - s.CDBByte[8] = (BYTE) sizeof (qdata); - perform (s); - - return s.SRB_Status == SS_COMP ? qdata[7] : 0; -} - -//============================================================================== -bool CDDeviceHandle::readTOC (TOC* lpToc) -{ - SRB_ExecSCSICmd s = { 0 }; - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaID = info.ha; - s.SRB_Target = info.tgt; - s.SRB_Lun = info.lun; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0x324; - s.SRB_BufPointer = (BYTE*) lpToc; - s.SRB_SenseLen = 0x0E; - s.SRB_CDBLen = 0x0A; - s.SRB_PostProc = CreateEvent (0, TRUE, FALSE, 0); - s.CDBByte[0] = 0x43; - s.CDBByte[1] = 0x00; - s.CDBByte[7] = 0x03; - s.CDBByte[8] = 0x24; - - performScsiCommand (s.SRB_PostProc, s); - return (s.SRB_Status == SS_COMP); -} - -void CDDeviceHandle::performScsiCommand (HANDLE event, SRB_ExecSCSICmd& s) -{ - ResetEvent (event); - DWORD status = performScsiPassThroughCommand ((SRB_ExecSCSICmd*) &s, info.scsiDriveLetter, scsiHandle, true); - - if (status == SS_PENDING) - WaitForSingleObject (event, 4000); - - CloseHandle (event); -} - -bool CDDeviceHandle::readAudio (CDReadBuffer& buffer, CDReadBuffer* overlapBuffer) -{ - if (controller == 0) - { - testController (READTYPE_ATAPI2, new ControllerType1(), buffer) - || testController (READTYPE_ATAPI1, new ControllerType1(), buffer) - || testController (READTYPE_READ10_2, new ControllerType2(), buffer) - || testController (READTYPE_READ10, new ControllerType2(), buffer) - || testController (READTYPE_READ_D8, new ControllerType3(), buffer) - || testController (READTYPE_READ_D4, new ControllerType4(), buffer) - || testController (READTYPE_READ_D4_1, new ControllerType4(), buffer); - } - - buffer.index = 0; - - if (controller != nullptr && controller->readAudio (buffer, overlapBuffer)) - { - if (buffer.wantsIndex) - buffer.index = controller->getLastIndex(); - - return true; - } - - return false; -} - -void CDDeviceHandle::openDrawer (bool shouldBeOpen) -{ - if (shouldBeOpen) - { - if (controller != nullptr) - { - controller->shutDown(); - controller = nullptr; - } - - if (scsiHandle != 0) - { - CloseHandle (scsiHandle); - scsiHandle = 0; - } - } - - SRB_ExecSCSICmd s = { 0 }; - s.SRB_Cmd = SC_EXEC_SCSI_CMD; - s.SRB_HaID = info.ha; - s.SRB_Target = info.tgt; - s.SRB_Lun = info.lun; - s.SRB_SenseLen = SENSE_LEN; - s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY; - s.SRB_BufLen = 0; - s.SRB_BufPointer = 0; - s.SRB_CDBLen = 12; - s.CDBByte[0] = 0x1b; - s.CDBByte[1] = (BYTE) (info.lun << 5); - s.CDBByte[4] = (BYTE) (shouldBeOpen ? 2 : 3); - s.SRB_PostProc = CreateEvent (0, TRUE, FALSE, 0); - - performScsiCommand (s.SRB_PostProc, s); -} - -bool CDDeviceHandle::testController (const int type, CDController* const newController, CDReadBuffer& rb) -{ - controller = newController; - readType = (BYTE) type; - - controller->deviceInfo = this; - controller->framesToCheck = 1; - controller->framesOverlap = 3; - - bool passed = false; - memset (rb.buffer, 0xcd, rb.bufferSize); - - if (controller->read (rb)) - { - passed = true; - int* p = (int*) (rb.buffer + rb.dataStartOffset); - int wrong = 0; - - for (int i = rb.dataLength / 4; --i >= 0;) - { - if (*p++ == (int) 0xcdcdcdcd) - { - if (++wrong == 4) - { - passed = false; - break; - } - } - else - { - wrong = 0; - } - } - } - - if (! passed) - { - controller->shutDown(); - controller = nullptr; - } - - return passed; -} - - -//============================================================================== -struct CDDeviceWrapper -{ - CDDeviceWrapper (const CDDeviceDescription& device, HANDLE scsiHandle) - : deviceHandle (device, scsiHandle), overlapBuffer (3), jitter (false) - { - // xxx jitter never seemed to actually be enabled (??) - } - - CDDeviceHandle deviceHandle; - CDReadBuffer overlapBuffer; - bool jitter; -}; - -//============================================================================== -int getAddressOfTrack (const TOCTRACK& t) noexcept -{ - return (((DWORD) t.addr[0]) << 24) + (((DWORD) t.addr[1]) << 16) - + (((DWORD) t.addr[2]) << 8) + ((DWORD) t.addr[3]); -} - -const int samplesPerFrame = 44100 / 75; -const int bytesPerFrame = samplesPerFrame * 4; -const int framesPerIndexRead = 4; - -} - -//============================================================================== -StringArray AudioCDReader::getAvailableCDNames() -{ - using namespace CDReaderHelpers; - StringArray results; - - Array list; - findCDDevices (list); - - for (int i = 0; i < list.size(); ++i) - { - String s; - if (list[i].scsiDriveLetter > 0) - s << String::charToString (list[i].scsiDriveLetter).toUpperCase() << ": "; - - s << list[i].description; - results.add (s); - } - - return results; -} - -AudioCDReader* AudioCDReader::createReaderForCD (const int deviceIndex) -{ - using namespace CDReaderHelpers; - - Array list; - findCDDevices (list); - - if (isPositiveAndBelow (deviceIndex, list.size())) - { - HANDLE h = createSCSIDeviceHandle (list [deviceIndex].scsiDriveLetter); - - if (h != INVALID_HANDLE_VALUE) - { - ScopedPointer cd (new AudioCDReader (new CDDeviceWrapper (list [deviceIndex], h))); - - if (cd->lengthInSamples > 0) - return cd.release(); - } - } - - return nullptr; -} - -AudioCDReader::AudioCDReader (void* handle_) - : AudioFormatReader (0, "CD Audio"), - handle (handle_), - indexingEnabled (false), - lastIndex (0), - firstFrameInBuffer (0), - samplesInBuffer (0) -{ - using namespace CDReaderHelpers; - jassert (handle_ != nullptr); - - refreshTrackLengths(); - - sampleRate = 44100.0; - bitsPerSample = 16; - numChannels = 2; - usesFloatingPointData = false; - - buffer.setSize (4 * bytesPerFrame, true); -} - -AudioCDReader::~AudioCDReader() -{ - using namespace CDReaderHelpers; - CDDeviceWrapper* const device = static_cast (handle); - delete device; -} - -bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) -{ - using namespace CDReaderHelpers; - CDDeviceWrapper* const device = static_cast (handle); - - bool ok = true; - - while (numSamples > 0) - { - const int bufferStartSample = firstFrameInBuffer * samplesPerFrame; - const int bufferEndSample = bufferStartSample + samplesInBuffer; - - if (startSampleInFile >= bufferStartSample - && startSampleInFile < bufferEndSample) - { - const int toDo = (int) jmin ((int64) numSamples, bufferEndSample - startSampleInFile); - - int* const l = destSamples[0] + startOffsetInDestBuffer; - int* const r = numDestChannels > 1 ? (destSamples[1] + startOffsetInDestBuffer) : nullptr; - const short* src = (const short*) buffer.getData(); - src += 2 * (startSampleInFile - bufferStartSample); - - for (int i = 0; i < toDo; ++i) - { - l[i] = src [i << 1] << 16; - - if (r != nullptr) - r[i] = src [(i << 1) + 1] << 16; - } - - startOffsetInDestBuffer += toDo; - startSampleInFile += toDo; - numSamples -= toDo; - } - else - { - const int framesInBuffer = (int) (buffer.getSize() / bytesPerFrame); - const int frameNeeded = (int) (startSampleInFile / samplesPerFrame); - - if (firstFrameInBuffer + framesInBuffer != frameNeeded) - { - device->overlapBuffer.dataLength = 0; - device->overlapBuffer.startFrame = 0; - device->overlapBuffer.numFrames = 0; - device->jitter = false; - } - - firstFrameInBuffer = frameNeeded; - lastIndex = 0; - - CDReadBuffer readBuffer (framesInBuffer + 4); - readBuffer.wantsIndex = indexingEnabled; - - int i; - for (i = 5; --i >= 0;) - { - readBuffer.startFrame = frameNeeded; - readBuffer.numFrames = framesInBuffer; - - if (device->deviceHandle.readAudio (readBuffer, device->jitter ? &device->overlapBuffer : 0)) - break; - else - device->overlapBuffer.dataLength = 0; - } - - if (i >= 0) - { - buffer.copyFrom (readBuffer.buffer + readBuffer.dataStartOffset, 0, readBuffer.dataLength); - samplesInBuffer = readBuffer.dataLength >> 2; - lastIndex = readBuffer.index; - } - else - { - int* l = destSamples[0] + startOffsetInDestBuffer; - int* r = numDestChannels > 1 ? (destSamples[1] + startOffsetInDestBuffer) : nullptr; - - while (--numSamples >= 0) - { - *l++ = 0; - - if (r != nullptr) - *r++ = 0; - } - - // sometimes the read fails for just the very last couple of blocks, so - // we'll ignore and errors in the last half-second of the disk.. - ok = startSampleInFile > (trackStartSamples [getNumTracks()] - 20000); - break; - } - } - } - - return ok; -} - -bool AudioCDReader::isCDStillPresent() const -{ - using namespace CDReaderHelpers; - TOC toc = { 0 }; - return static_cast (handle)->deviceHandle.readTOC (&toc); -} - -void AudioCDReader::refreshTrackLengths() -{ - using namespace CDReaderHelpers; - trackStartSamples.clear(); - zeromem (audioTracks, sizeof (audioTracks)); - - TOC toc = { 0 }; - - if (static_cast (handle)->deviceHandle.readTOC (&toc)) - { - int numTracks = 1 + toc.lastTrack - toc.firstTrack; - - for (int i = 0; i <= numTracks; ++i) - { - trackStartSamples.add (samplesPerFrame * getAddressOfTrack (toc.tracks [i])); - audioTracks [i] = ((toc.tracks[i].ADR & 4) == 0); - } - } - - lengthInSamples = getPositionOfTrackStart (getNumTracks()); -} - -bool AudioCDReader::isTrackAudio (int trackNum) const -{ - return trackNum >= 0 && trackNum < getNumTracks() && audioTracks [trackNum]; -} - -void AudioCDReader::enableIndexScanning (bool b) -{ - indexingEnabled = b; -} - -int AudioCDReader::getLastIndex() const -{ - return lastIndex; -} - -int AudioCDReader::getIndexAt (int samplePos) -{ - using namespace CDReaderHelpers; - CDDeviceWrapper* const device = static_cast (handle); - - const int frameNeeded = samplePos / samplesPerFrame; - - device->overlapBuffer.dataLength = 0; - device->overlapBuffer.startFrame = 0; - device->overlapBuffer.numFrames = 0; - device->jitter = false; - - firstFrameInBuffer = 0; - lastIndex = 0; - - CDReadBuffer readBuffer (4 + framesPerIndexRead); - readBuffer.wantsIndex = true; - - int i; - for (i = 5; --i >= 0;) - { - readBuffer.startFrame = frameNeeded; - readBuffer.numFrames = framesPerIndexRead; - - if (device->deviceHandle.readAudio (readBuffer)) - break; - } - - if (i >= 0) - return readBuffer.index; - - return -1; -} - -Array AudioCDReader::findIndexesInTrack (const int trackNumber) -{ - using namespace CDReaderHelpers; - Array indexes; - - const int trackStart = getPositionOfTrackStart (trackNumber); - const int trackEnd = getPositionOfTrackStart (trackNumber + 1); - - bool needToScan = true; - - if (trackEnd - trackStart > 20 * 44100) - { - // check the end of the track for indexes before scanning the whole thing - needToScan = false; - int pos = jmax (trackStart, trackEnd - 44100 * 5); - bool seenAnIndex = false; - - while (pos <= trackEnd - samplesPerFrame) - { - const int index = getIndexAt (pos); - - if (index == 0) - { - // lead-out, so skip back a bit if we've not found any indexes yet.. - if (seenAnIndex) - break; - - pos -= 44100 * 5; - - if (pos < trackStart) - break; - } - else - { - if (index > 0) - seenAnIndex = true; - - if (index > 1) - { - needToScan = true; - break; - } - - pos += samplesPerFrame * framesPerIndexRead; - } - } - } - - if (needToScan) - { - CDDeviceWrapper* const device = static_cast (handle); - - int pos = trackStart; - int last = -1; - - while (pos < trackEnd - samplesPerFrame * 10) - { - const int frameNeeded = pos / samplesPerFrame; - - device->overlapBuffer.dataLength = 0; - device->overlapBuffer.startFrame = 0; - device->overlapBuffer.numFrames = 0; - device->jitter = false; - - firstFrameInBuffer = 0; - - CDReadBuffer readBuffer (4); - readBuffer.wantsIndex = true; - - int i; - for (i = 5; --i >= 0;) - { - readBuffer.startFrame = frameNeeded; - readBuffer.numFrames = framesPerIndexRead; - - if (device->deviceHandle.readAudio (readBuffer)) - break; - } - - if (i < 0) - break; - - if (readBuffer.index > last && readBuffer.index > 1) - { - last = readBuffer.index; - indexes.add (pos); - } - - pos += samplesPerFrame * framesPerIndexRead; - } - - indexes.removeFirstMatchingValue (trackStart); - } - - return indexes; -} - -void AudioCDReader::ejectDisk() -{ - using namespace CDReaderHelpers; - static_cast (handle)->deviceHandle.openDrawer (true); -} diff --git a/source/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp b/source/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp index 4b09c943f..031be1892 100644 --- a/source/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp +++ b/source/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -358,7 +350,7 @@ public: hr = pOutputBuffer->Play (0, 0, 1 /* DSBPLAY_LOOPING */); if (SUCCEEDED (hr)) - return String(); + return {}; } } } @@ -601,7 +593,7 @@ public: hr = pInputBuffer->Start (1 /* DSCBSTART_LOOPING */); if (SUCCEEDED (hr)) - return String(); + return {}; } } diff --git a/source/modules/juce_audio_devices/native/juce_win32_Midi.cpp b/source/modules/juce_audio_devices/native/juce_win32_Midi.cpp index 7189ff48a..b614f7138 100644 --- a/source/modules/juce_audio_devices/native/juce_win32_Midi.cpp +++ b/source/modules/juce_audio_devices/native/juce_win32_Midi.cpp @@ -2,498 +2,1233 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -class MidiInCollector +struct MidiServiceType { -public: - MidiInCollector (MidiInput* const input_, - MidiInputCallback& callback_) - : deviceHandle (0), - input (input_), - callback (callback_), - concatenator (4096), - isStarted (false), - startTime (0) + struct InputWrapper { - } + virtual ~InputWrapper() {} + + virtual String getDeviceName() = 0; + + virtual void start() = 0; + virtual void stop() = 0; + }; - ~MidiInCollector() + struct OutputWrapper { - stop(); + virtual ~OutputWrapper() {} + + virtual String getDeviceName() = 0; + + virtual void sendMessageNow (const MidiMessage&) = 0; + }; + + MidiServiceType() {} + virtual ~MidiServiceType() {} + + virtual StringArray getDevices (bool) = 0; + virtual int getDefaultDeviceIndex (bool) = 0; + + virtual InputWrapper* createInputWrapper (MidiInput* const, + const int, + MidiInputCallback* const callback) = 0; + virtual OutputWrapper* createOutputWrapper (const int) = 0; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiServiceType) +}; - if (deviceHandle != 0) +//============================================================================== +class WindowsMidiService : public MidiServiceType +{ +private: + struct WindowsInputWrapper : public InputWrapper + { + struct MidiInCollector { - for (int count = 5; --count >= 0;) + MidiInCollector (WindowsMidiService& s, + MidiInput* const inputDevice, + MidiInputCallback& cb) + : midiService (s), + input (inputDevice), + callback (cb) { - if (midiInClose (deviceHandle) == MMSYSERR_NOERROR) - break; + } - Sleep (20); + ~MidiInCollector() + { + stop(); + + if (deviceHandle != 0) + { + for (int count = 5; --count >= 0;) + { + if (midiInClose (deviceHandle) == MMSYSERR_NOERROR) + break; + + Sleep (20); + } + } } + + void handleMessage (const uint8* bytes, const uint32 timeStamp) + { + if (bytes[0] >= 0x80 && isStarted) + { + concatenator.pushMidiData (bytes, + MidiMessage::getMessageLengthFromFirstByte (bytes[0]), + convertTimeStamp (timeStamp), + input, + callback); + writeFinishedBlocks(); + } + } + + void handleSysEx (MIDIHDR* const hdr, const uint32 timeStamp) + { + if (isStarted && hdr->dwBytesRecorded > 0) + { + concatenator.pushMidiData (hdr->lpData, (int) hdr->dwBytesRecorded, + convertTimeStamp (timeStamp), input, callback); + writeFinishedBlocks(); + } + } + + void start() + { + if (deviceHandle != 0 && ! isStarted) + { + midiService.activeMidiCollectors.addIfNotAlreadyThere (this); + + for (int i = 0; i < (int) numHeaders; ++i) + { + headers[i].prepare (deviceHandle); + headers[i].write (deviceHandle); + } + + startTime = Time::getMillisecondCounterHiRes(); + MMRESULT res = midiInStart (deviceHandle); + + if (res == MMSYSERR_NOERROR) + { + concatenator.reset(); + isStarted = true; + } + else + { + unprepareAllHeaders(); + } + } + } + + void stop() + { + if (isStarted) + { + isStarted = false; + midiInReset (deviceHandle); + midiInStop (deviceHandle); + midiService.activeMidiCollectors.removeFirstMatchingValue (this); + unprepareAllHeaders(); + concatenator.reset(); + } + } + + static void CALLBACK midiInCallback (HMIDIIN, UINT uMsg, DWORD_PTR dwInstance, + DWORD_PTR midiMessage, DWORD_PTR timeStamp) + { + auto* collector = reinterpret_cast (dwInstance); + + if (collector->midiService.activeMidiCollectors.contains (collector)) + { + if (uMsg == MIM_DATA) + collector->handleMessage ((const uint8*) &midiMessage, (uint32) timeStamp); + else if (uMsg == MIM_LONGDATA) + collector->handleSysEx ((MIDIHDR*) midiMessage, (uint32) timeStamp); + } + } + + HMIDIIN deviceHandle = 0; + + private: + WindowsMidiService& midiService; + MidiInput* input; + MidiInputCallback& callback; + MidiDataConcatenator concatenator { 4096 }; + bool volatile isStarted = false; + double startTime = 0; + + struct MidiHeader + { + MidiHeader() {} + + void prepare (HMIDIIN device) + { + zerostruct (hdr); + hdr.lpData = data; + hdr.dwBufferLength = (DWORD) numElementsInArray (data); + + midiInPrepareHeader (device, &hdr, sizeof (hdr)); + } + + void unprepare (HMIDIIN device) + { + if ((hdr.dwFlags & WHDR_DONE) != 0) + { + int c = 10; + while (--c >= 0 && midiInUnprepareHeader (device, &hdr, sizeof (hdr)) == MIDIERR_STILLPLAYING) + Thread::sleep (20); + + jassert (c >= 0); + } + } + + void write (HMIDIIN device) + { + hdr.dwBytesRecorded = 0; + midiInAddBuffer (device, &hdr, sizeof (hdr)); + } + + void writeIfFinished (HMIDIIN device) + { + if ((hdr.dwFlags & WHDR_DONE) != 0) + write (device); + } + + MIDIHDR hdr; + char data [256]; + + JUCE_DECLARE_NON_COPYABLE (MidiHeader) + }; + + enum { numHeaders = 32 }; + MidiHeader headers [numHeaders]; + + void writeFinishedBlocks() + { + for (int i = 0; i < (int) numHeaders; ++i) + headers[i].writeIfFinished (deviceHandle); + } + + void unprepareAllHeaders() + { + for (int i = 0; i < (int) numHeaders; ++i) + headers[i].unprepare (deviceHandle); + } + + double convertTimeStamp (uint32 timeStamp) + { + auto t = startTime + timeStamp; + auto now = Time::getMillisecondCounterHiRes(); + + if (t > now) + { + if (t > now + 2.0) + startTime -= 1.0; + + t = now; + } + + return t * 0.001; + } + + 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; + + if (isPositiveAndBelow (index, names.size())) + { + deviceName = names[index]; + deviceId = index; + } + + collector = new MidiInCollector (parentService, input, *callback); + + HMIDIIN h; + MMRESULT err = midiInOpen (&h, deviceId, + (DWORD_PTR) &MidiInCollector::midiInCallback, + (DWORD_PTR) (MidiInCollector*) collector.get(), + CALLBACK_FUNCTION); + + if (err != MMSYSERR_NOERROR) + throw std::runtime_error ("Failed to create Windows input device wrapper"); + + collector->deviceHandle = h; } - } - //============================================================================== - void handleMessage (const uint8* bytes, const uint32 timeStamp) - { - if (bytes[0] >= 0x80 && isStarted) + ~WindowsInputWrapper() {} + + static StringArray getDevices() { - concatenator.pushMidiData (bytes, MidiMessage::getMessageLengthFromFirstByte (bytes[0]), - convertTimeStamp (timeStamp), input, callback); - writeFinishedBlocks(); + StringArray s; + const UINT num = midiInGetNumDevs(); + + for (UINT i = 0; i < num; ++i) + { + MIDIINCAPS mc = { 0 }; + + if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) + s.add (String (mc.szPname, (size_t) numElementsInArray (mc.szPname))); + } + + s.appendNumbersToDuplicates (false, false, CharPointer_UTF8 ("-"), CharPointer_UTF8 ("")); + return s; } - } - void handleSysEx (MIDIHDR* const hdr, const uint32 timeStamp) - { - if (isStarted && hdr->dwBytesRecorded > 0) + static int getDefaultDeviceIndex() { - concatenator.pushMidiData (hdr->lpData, (int) hdr->dwBytesRecorded, - convertTimeStamp (timeStamp), input, callback); - writeFinishedBlocks(); + return 0; } - } - void start() + void start() override { collector->start(); } + void stop() override { collector->stop(); } + + String getDeviceName() override + { + return deviceName; + } + + String deviceName; + ScopedPointer collector; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsInputWrapper) + }; + + //============================================================================== + struct WindowsOutputWrapper : public OutputWrapper { - if (deviceHandle != 0 && ! isStarted) + struct MidiOutHandle + { + int refCount; + UINT deviceId; + HMIDIOUT handle; + + JUCE_LEAK_DETECTOR (MidiOutHandle) + }; + + WindowsOutputWrapper (WindowsMidiService& p, int index) : parent (p) { - activeMidiCollectors.addIfNotAlreadyThere (this); + auto names = getDevices(); + UINT deviceId = MIDI_MAPPER; - for (int i = 0; i < (int) numHeaders; ++i) + if (isPositiveAndBelow (index, names.size())) { - headers[i].prepare (deviceHandle); - headers[i].write (deviceHandle); + deviceName = names[index]; + deviceId = index; } - startTime = Time::getMillisecondCounterHiRes(); - MMRESULT res = midiInStart (deviceHandle); + 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; + } - if (res == MMSYSERR_NOERROR) + for (int i = parent.activeOutputHandles.size(); --i >= 0;) { - concatenator.reset(); - isStarted = true; + auto* activeHandle = parent.activeOutputHandles.getUnchecked (i); + + if (activeHandle->deviceId == deviceId) + { + activeHandle->refCount++; + han = activeHandle; + return; + } } - else + + for (int i = 4; --i >= 0;) { - unprepareAllHeaders(); + HMIDIOUT h = 0; + MMRESULT res = midiOutOpen (&h, deviceId, 0, 0, CALLBACK_NULL); + + if (res == MMSYSERR_NOERROR) + { + han = new MidiOutHandle(); + han->deviceId = deviceId; + han->refCount = 1; + han->handle = h; + parent.activeOutputHandles.add (han); + return; + } + + if (res == MMSYSERR_ALLOCATED) + Sleep (100); + else + break; } + + throw std::runtime_error ("Failed to create Windows output device wrapper"); } - } - void stop() - { - if (isStarted) + ~WindowsOutputWrapper() { - isStarted = false; - midiInReset (deviceHandle); - midiInStop (deviceHandle); - activeMidiCollectors.removeFirstMatchingValue (this); - unprepareAllHeaders(); - concatenator.reset(); + if (parent.activeOutputHandles.contains (han.get()) && --(han->refCount) == 0) + { + midiOutClose (han->handle); + parent.activeOutputHandles.removeFirstMatchingValue (han.get()); + } } - } - - static void CALLBACK midiInCallback (HMIDIIN, UINT uMsg, DWORD_PTR dwInstance, - DWORD_PTR midiMessage, DWORD_PTR timeStamp) - { - MidiInCollector* const collector = reinterpret_cast (dwInstance); - if (activeMidiCollectors.contains (collector)) + void sendMessageNow (const MidiMessage& message) override { - if (uMsg == MIM_DATA) - collector->handleMessage ((const uint8*) &midiMessage, (uint32) timeStamp); - else if (uMsg == MIM_LONGDATA) - collector->handleSysEx ((MIDIHDR*) midiMessage, (uint32) timeStamp); - } - } + if (message.getRawDataSize() > 3 || message.isSysEx()) + { + MIDIHDR h = { 0 }; - HMIDIIN deviceHandle; + h.lpData = (char*) message.getRawData(); + h.dwBytesRecorded = h.dwBufferLength = (DWORD) message.getRawDataSize(); -private: - static Array activeMidiCollectors; + if (midiOutPrepareHeader (han->handle, &h, sizeof (MIDIHDR)) == MMSYSERR_NOERROR) + { + MMRESULT res = midiOutLongMsg (han->handle, &h, sizeof (MIDIHDR)); - MidiInput* input; - MidiInputCallback& callback; - MidiDataConcatenator concatenator; - bool volatile isStarted; - double startTime; + if (res == MMSYSERR_NOERROR) + { + while ((h.dwFlags & MHDR_DONE) == 0) + Sleep (1); - class MidiHeader - { - public: - MidiHeader() {} + int count = 500; // 1 sec timeout - void prepare (HMIDIIN device) - { - zerostruct (hdr); - hdr.lpData = data; - hdr.dwBufferLength = (DWORD) numElementsInArray (data); + while (--count >= 0) + { + res = midiOutUnprepareHeader (han->handle, &h, sizeof (MIDIHDR)); - midiInPrepareHeader (device, &hdr, sizeof (hdr)); + if (res == MIDIERR_STILLPLAYING) + Sleep (2); + else + break; + } + } + } + } + else + { + for (int i = 0; i < 50; ++i) + { + if (midiOutShortMsg (han->handle, *(unsigned int*) message.getRawData()) != MIDIERR_NOTREADY) + break; + + Sleep (1); + } + } } - void unprepare (HMIDIIN device) + static Array getDeviceCaps() { - if ((hdr.dwFlags & WHDR_DONE) != 0) + Array devices; + const UINT num = midiOutGetNumDevs(); + + for (UINT i = 0; i < num; ++i) { - int c = 10; - while (--c >= 0 && midiInUnprepareHeader (device, &hdr, sizeof (hdr)) == MIDIERR_STILLPLAYING) - Thread::sleep (20); + MIDIOUTCAPS mc = { 0 }; - jassert (c >= 0); + if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) + devices.add (mc); } + + return devices; } - void write (HMIDIIN device) + static StringArray getDevices() { - hdr.dwBytesRecorded = 0; - midiInAddBuffer (device, &hdr, sizeof (hdr)); + 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() + { + int n = 0; + + for (auto& mc : getDeviceCaps()) + { + if ((mc.wTechnology & MOD_MAPPER) != 0) + return n; + + ++n; + } + + return 0; } - void writeIfFinished (HMIDIIN device) + String getDeviceName() override { - if ((hdr.dwFlags & WHDR_DONE) != 0) - write (device); + return deviceName; } - private: - MIDIHDR hdr; - char data [256]; + WindowsMidiService& parent; + String deviceName; + + ScopedPointer han; - JUCE_DECLARE_NON_COPYABLE (MidiHeader) + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsOutputWrapper) }; - enum { numHeaders = 32 }; - MidiHeader headers [numHeaders]; +public: + WindowsMidiService() {} - void writeFinishedBlocks() + StringArray getDevices (bool isInput) override { - for (int i = 0; i < (int) numHeaders; ++i) - headers[i].writeIfFinished (deviceHandle); + return isInput ? WindowsInputWrapper::getDevices() + : WindowsOutputWrapper::getDevices(); } - void unprepareAllHeaders() + int getDefaultDeviceIndex (bool isInput) override { - for (int i = 0; i < (int) numHeaders; ++i) - headers[i].unprepare (deviceHandle); + return isInput ? WindowsInputWrapper::getDefaultDeviceIndex() + : WindowsOutputWrapper::getDefaultDeviceIndex(); } - double convertTimeStamp (uint32 timeStamp) + InputWrapper* createInputWrapper (MidiInput* const input, + const int index, + MidiInputCallback* const callback) override { - double t = startTime + timeStamp; - - const double now = Time::getMillisecondCounterHiRes(); - if (t > now) - { - if (t > now + 2.0) - startTime -= 1.0; - - t = now; - } + return new WindowsInputWrapper (*this, input, index, callback); + } - return t * 0.001; + OutputWrapper* createOutputWrapper (const int index) override + { + return new WindowsOutputWrapper (*this, index); } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInCollector) +private: + Array activeMidiCollectors; + Array activeOutputHandles; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsMidiService) }; -Array MidiInCollector::activeMidiCollectors; +//============================================================================== +#if JUCE_USE_WINRT_MIDI +using namespace Microsoft::WRL; -//============================================================================== -StringArray MidiInput::getDevices() -{ - StringArray s; - const UINT num = midiInGetNumDevs(); +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Devices::Midi; +using namespace ABI::Windows::Devices::Enumeration; +using namespace ABI::Windows::Storage::Streams; - for (UINT i = 0; i < num; ++i) +class WinRTMidiService : public MidiServiceType +{ +private: + template + struct MidiIODeviceWatcher { - MIDIINCAPS mc = { 0 }; + struct DeviceInfo + { + String name; + String id; + bool isDefault = false; + }; - if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - s.add (String (mc.szPname, sizeof (mc.szPname))); - } + MidiIODeviceWatcher (ComSmartPtr& comFactory) + : factory (comFactory) + { + } - return s; -} + ~MidiIODeviceWatcher() + { + stop(); + } -int MidiInput::getDefaultDeviceIndex() -{ - return 0; -} + bool start() + { + HSTRING deviceSelector; + HRESULT hr = factory->GetDeviceSelector (&deviceSelector); + if (FAILED (hr)) + return false; -MidiInput* MidiInput::openDevice (const int index, MidiInputCallback* const callback) -{ - if (callback == nullptr) - return nullptr; + auto deviceInformationFactory = WinRTWrapper::getInstance()->getWRLFactory (&RuntimeClass_Windows_Devices_Enumeration_DeviceInformation[0]); + if (deviceInformationFactory == nullptr) + return false; - UINT deviceId = MIDI_MAPPER; - int n = 0; - String name; + hr = deviceInformationFactory->CreateWatcherAqsFilter (deviceSelector, watcher.resetAndGetPointerAddress()); + if (FAILED (hr)) + return false; - const UINT num = midiInGetNumDevs(); + class DeviceEnumerationThread : public Thread + { + public: + DeviceEnumerationThread (String threadName, MidiIODeviceWatcher& p) + : Thread (threadName), parent (p) + {} - for (UINT i = 0; i < num; ++i) - { - MIDIINCAPS mc = { 0 }; + void run() override + { + auto parentPtr = &parent; + + parent.watcher->add_Added ( + Callback> ( + [parentPtr](IDeviceWatcher*, IDeviceInformation* info) { return parentPtr->addDevice (info); } + ).Get(), + &parent.deviceAddedToken); + + parent.watcher->add_Removed ( + Callback> ( + [parentPtr](IDeviceWatcher*, IDeviceInformationUpdate* info) { return parentPtr->removeDevice (info); } + ).Get(), + &parent.deviceRemovedToken); + + EventRegistrationToken deviceEnumerationCompletedToken { 0 }; + parent.watcher->add_EnumerationCompleted ( + Callback> ( + [this](IDeviceWatcher*, IInspectable*) { enumerationCompleted.signal(); return S_OK; } + ).Get(), + &deviceEnumerationCompletedToken); + + parent.watcher->Start(); + enumerationCompleted.wait(); + + if (deviceEnumerationCompletedToken.value != 0) + parent.watcher->remove_EnumerationCompleted (deviceEnumerationCompletedToken); + } - if (midiInGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) + private: + MidiIODeviceWatcher& parent; + WaitableEvent enumerationCompleted; + }; + + DeviceEnumerationThread enumerationThread ("WinRT Device Enumeration Thread", *this); + enumerationThread.startThread(); + enumerationThread.waitForThreadToExit (4000); + + return true; + } + + bool stop() { - if (index == n) + if (watcher == nullptr) + return true; + + if (deviceAddedToken.value != 0) + { + HRESULT hr = watcher->remove_Added (deviceAddedToken); + if (FAILED (hr)) + return false; + + deviceAddedToken.value = 0; + } + + if (deviceRemovedToken.value != 0) { - deviceId = i; - name = String (mc.szPname, (size_t) numElementsInArray (mc.szPname)); - break; + HRESULT hr = watcher->remove_Removed (deviceRemovedToken); + if (FAILED (hr)) + return false; + + deviceRemovedToken.value = 0; } - ++n; + HRESULT hr = watcher->Stop(); + if (FAILED (hr)) + return false; + + watcher = nullptr; + return true; } - } - ScopedPointer in (new MidiInput (name)); - ScopedPointer collector (new MidiInCollector (in, *callback)); + HRESULT addDevice (IDeviceInformation* addedDeviceInfo) + { + boolean isEnabled; + HRESULT hr = addedDeviceInfo->get_IsEnabled (&isEnabled); + if (FAILED (hr)) + return S_OK; - HMIDIIN h; - MMRESULT err = midiInOpen (&h, deviceId, - (DWORD_PTR) &MidiInCollector::midiInCallback, - (DWORD_PTR) (MidiInCollector*) collector, - CALLBACK_FUNCTION); + if (! isEnabled) + return S_OK; - if (err == MMSYSERR_NOERROR) - { - collector->deviceHandle = h; - in->internal = collector.release(); - return in.release(); - } + const ScopedLock lock (deviceChanges); - return nullptr; -} + DeviceInfo info; -MidiInput::MidiInput (const String& name_) - : name (name_), - internal (0) -{ -} + HSTRING name; + hr = addedDeviceInfo->get_Name (&name); + if (FAILED (hr)) + return S_OK; -MidiInput::~MidiInput() -{ - delete static_cast (internal); -} + info.name = WinRTWrapper::getInstance()->hStringToString (name); -void MidiInput::start() { static_cast (internal)->start(); } -void MidiInput::stop() { static_cast (internal)->stop(); } + HSTRING id; + hr = addedDeviceInfo->get_Id (&id); + if (FAILED (hr)) + return S_OK; + info.id = WinRTWrapper::getInstance()->hStringToString (id); -//============================================================================== -struct MidiOutHandle -{ - int refCount; - UINT deviceId; - HMIDIOUT handle; + boolean isDefault; + hr = addedDeviceInfo->get_IsDefault (&isDefault); + if (FAILED (hr)) + return S_OK; - static Array activeHandles; + info.isDefault = isDefault != 0; -private: - JUCE_LEAK_DETECTOR (MidiOutHandle) -}; + connectedDevices.add (info); -Array MidiOutHandle::activeHandles; + return S_OK; + } -//============================================================================== -StringArray MidiOutput::getDevices() -{ - StringArray s; - const UINT num = midiOutGetNumDevs(); + HRESULT removeDevice (IDeviceInformationUpdate* removedDeviceInfo) + { + const ScopedLock lock (deviceChanges); - for (UINT i = 0; i < num; ++i) - { - MIDIOUTCAPS mc = { 0 }; + HSTRING removedDeviceIdHstr; + removedDeviceInfo->get_Id (&removedDeviceIdHstr); + String removedDeviceId = WinRTWrapper::getInstance()->hStringToString (removedDeviceIdHstr); - if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) - s.add (String (mc.szPname, sizeof (mc.szPname))); - } + for (int i = 0; i < connectedDevices.size(); ++i) + { + if (connectedDevices[i].id == removedDeviceId) + { + connectedDevices.remove (i); + break; + } + } - return s; -} + return S_OK; + } -int MidiOutput::getDefaultDeviceIndex() -{ - const UINT num = midiOutGetNumDevs(); - int n = 0; + StringArray getDevices() + { + { + const ScopedLock lock (deviceChanges); + lastQueriedConnectedDevices = connectedDevices; + } + + StringArray result; + for (auto info : lastQueriedConnectedDevices.get()) + result.add (info.name); + + return result; + } + + int getDefaultDeviceIndex() + { + auto& lastDevices = lastQueriedConnectedDevices.get(); + for (int i = 0; i < lastDevices.size(); ++i) + if (lastDevices[i].isDefault) + return i; + + return 0; + } + + String getDeviceNameFromIndex (const int index) + { + if (isPositiveAndBelow (index, lastQueriedConnectedDevices.get().size())) + return lastQueriedConnectedDevices.get()[index].name; + + return {}; + } + + String getDeviceID (const String name) + { + const ScopedLock lock (deviceChanges); + + for (auto info : connectedDevices) + if (info.name == name) + return info.id; + + return {}; + } + + ComSmartPtr& factory; + + EventRegistrationToken deviceAddedToken { 0 }, + deviceRemovedToken { 0 }; + + ComSmartPtr watcher; + + Array connectedDevices; + CriticalSection deviceChanges; + ThreadLocalValue> lastQueriedConnectedDevices; - for (UINT i = 0; i < num; ++i) + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiIODeviceWatcher); + }; + + template + class OpenMidiPortThread : public Thread { - MIDIOUTCAPS mc = { 0 }; + public: + OpenMidiPortThread (String threadName, + String midiDeviceId, + ComSmartPtr& comFactory, + ComSmartPtr& comPort) + : Thread (threadName), + deviceId (midiDeviceId), + factory (comFactory), + port (comPort) + { + } + + ~OpenMidiPortThread() + { + } - if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) + void run() override { - if ((mc.wTechnology & MOD_MAPPER) != 0) - return n; + WinRTWrapper::ScopedHString hDeviceId (deviceId); + ComSmartPtr> asyncOp; + HRESULT hr = factory->FromIdAsync (hDeviceId.get(), asyncOp.resetAndGetPointerAddress()); + if (FAILED (hr)) + return; + + hr = asyncOp->put_Completed (Callback> ( + [this] (IAsyncOperation* asyncOpPtr, AsyncStatus) + { + if (asyncOpPtr == nullptr) + return E_ABORT; - ++n; + HRESULT hr = asyncOpPtr->GetResults (port.resetAndGetPointerAddress()); + if (FAILED (hr)) + return hr; + + portOpened.signal(); + return S_OK; + } + ).Get()); + + // When using Bluetooth the asynchronous port opening operation will occasionally + // hang, so we use a timeout. We will be able to remove this when Microsoft + // improves the Bluetooth MIDI stack. + portOpened.wait (2000); } - } - return 0; -} + const String deviceId; + ComSmartPtr& factory; + ComSmartPtr& port; -MidiOutput* MidiOutput::openDevice (int index) -{ - UINT deviceId = MIDI_MAPPER; - const UINT num = midiOutGetNumDevs(); - int n = 0; - String deviceName; + WaitableEvent portOpened { true }; + }; - for (UINT i = 0; i < num; ++i) + struct WinRTInputWrapper : public InputWrapper { - MIDIOUTCAPS mc = { 0 }; + WinRTInputWrapper (WinRTMidiService& service, + MidiInput* const input, + const int index, + MidiInputCallback& cb) + : inputDevice (input), + callback (cb), + concatenator (4096) + { + const ScopedLock lock (service.inputDeviceWatcher->deviceChanges); + + deviceName = service.inputDeviceWatcher->getDeviceNameFromIndex (index); + if (deviceName.isEmpty()) + throw std::runtime_error ("Invalid device index"); - if (midiOutGetDevCaps (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR) + const auto deviceID = service.inputDeviceWatcher->getDeviceID (deviceName); + if (deviceID.isEmpty()) + throw std::runtime_error ("Device unavailable"); + + OpenMidiPortThread portThread ("Open WinRT MIDI input port", + deviceID, + service.midiInFactory, + midiInPort); + portThread.startThread(); + portThread.waitForThreadToExit (-1); + if (midiInPort == nullptr) + throw std::runtime_error ("Timed out waiting for midi input port creation"); + + startTime = Time::getMillisecondCounterHiRes(); + + HRESULT hr = midiInPort->add_MessageReceived ( + Callback> ( + [this] (IMidiInPort*, IMidiMessageReceivedEventArgs* args) { return midiInMessageReceived (args); } + ).Get(), + &midiInMessageToken); + if (FAILED (hr)) + throw std::runtime_error ("Failed to set midi input callback"); + } + + ~WinRTInputWrapper() { - String name = String (mc.szPname, sizeof (mc.szPname)); + if (midiInMessageToken.value != 0) + midiInPort->remove_MessageReceived (midiInMessageToken); - // 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; + midiInPort = nullptr; + } + + void start() override + { + if (!isStarted) + { + concatenator.reset(); + isStarted = true; + } + } - if (index == n) + void stop() override + { + if (isStarted) { - deviceName = name; - deviceId = i; - break; + isStarted = false; + concatenator.reset(); } + } - ++n; + String getDeviceName() override + { + return deviceName; } - } - for (int i = MidiOutHandle::activeHandles.size(); --i >= 0;) - { - MidiOutHandle* const han = MidiOutHandle::activeHandles.getUnchecked(i); + HRESULT midiInMessageReceived (IMidiMessageReceivedEventArgs* args) + { + if (! isStarted) + return S_OK; + + ComSmartPtr message; + HRESULT hr = args->get_Message (message.resetAndGetPointerAddress()); + if (FAILED (hr)) + return hr; + + ComSmartPtr buffer; + hr = message->get_RawData (buffer.resetAndGetPointerAddress()); + if (FAILED (hr)) + return hr; + + ComSmartPtr bufferByteAccess; + hr = buffer->QueryInterface (bufferByteAccess.resetAndGetPointerAddress()); + if (FAILED (hr)) + return hr; + + uint8_t* bufferData = nullptr; + hr = bufferByteAccess->Buffer (&bufferData); + if (FAILED (hr)) + return hr; + + uint32_t numBytes = 0; + hr = buffer->get_Length (&numBytes); + if (FAILED (hr)) + return hr; + + ABI::Windows::Foundation::TimeSpan timespan; + hr = message->get_Timestamp (×pan); + if (FAILED (hr)) + return hr; + + concatenator.pushMidiData (bufferData, + numBytes, + convertTimeStamp (timespan.Duration), + inputDevice, + callback); + + return S_OK; + } - if (han->deviceId == deviceId) + double convertTimeStamp (int64 timestamp) { - han->refCount++; + const auto millisecondsSinceStart = static_cast (timestamp) / 10000.0; + double t = startTime + millisecondsSinceStart; - MidiOutput* const out = new MidiOutput (deviceName); - out->internal = han; - return out; + const double now = Time::getMillisecondCounterHiRes(); + if (t > now) + { + if (t > now + 2.0) + startTime -= 1.0; + + t = now; + } + + return t * 0.001; } - } - for (int i = 4; --i >= 0;) - { - HMIDIOUT h = 0; - MMRESULT res = midiOutOpen (&h, deviceId, 0, 0, CALLBACK_NULL); + MidiInput* inputDevice; + MidiInputCallback& callback; + String deviceName; + MidiDataConcatenator concatenator; + ComSmartPtr midiInPort; + EventRegistrationToken midiInMessageToken { 0 }; - if (res == MMSYSERR_NOERROR) - { - MidiOutHandle* const han = new MidiOutHandle(); - han->deviceId = deviceId; - han->refCount = 1; - han->handle = h; - MidiOutHandle::activeHandles.add (han); + double startTime = 0; + bool isStarted = false; - MidiOutput* const out = new MidiOutput (deviceName); - out->internal = han; - return out; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WinRTInputWrapper); + }; + + struct WinRTOutputWrapper : public OutputWrapper + { + WinRTOutputWrapper (WinRTMidiService& service, const int index) + { + const ScopedLock lock (service.outputDeviceWatcher->deviceChanges); + + deviceName = service.outputDeviceWatcher->getDeviceNameFromIndex (index); + if (deviceName.isEmpty()) + throw std::runtime_error ("Invalid device index"); + + const auto deviceID = service.outputDeviceWatcher->getDeviceID (deviceName); + if (deviceID.isEmpty()) + throw std::runtime_error ("Device unavailable"); + + OpenMidiPortThread portThread ("Open WinRT MIDI output port", + deviceID, + service.midiOutFactory, + midiOutPort); + portThread.startThread(); + portThread.waitForThreadToExit (-1); + if (midiOutPort == nullptr) + throw std::runtime_error ("Timed out waiting for midi output port creation"); + + auto bufferFactory = WinRTWrapper::getInstance()->getWRLFactory (&RuntimeClass_Windows_Storage_Streams_Buffer[0]); + if (bufferFactory == nullptr) + throw std::runtime_error ("Failed to create output buffer factory"); + + HRESULT hr = bufferFactory->Create (static_cast (256), buffer.resetAndGetPointerAddress()); + if (FAILED (hr)) + throw std::runtime_error ("Failed to create output buffer"); + + hr = buffer->QueryInterface (bufferByteAccess.resetAndGetPointerAddress()); + if (FAILED (hr)) + throw std::runtime_error ("Failed to get buffer byte access"); + + hr = bufferByteAccess->Buffer (&bufferData); + if (FAILED (hr)) + throw std::runtime_error ("Failed to get buffer data pointer"); } - else if (res == MMSYSERR_ALLOCATED) + + ~WinRTOutputWrapper() {} + + void sendMessageNow (const MidiMessage& message) override { - Sleep (100); + const UINT32 numBytes = message.getRawDataSize(); + HRESULT hr = buffer->put_Length (numBytes); + if (FAILED (hr)) + jassertfalse; + + memcpy_s (bufferData, numBytes, message.getRawData(), numBytes); + + midiOutPort->SendBuffer (buffer); } - else + + String getDeviceName() override { - break; + return deviceName; } + + String deviceName; + ComSmartPtr midiOutPort; + ComSmartPtr buffer; + ComSmartPtr bufferByteAccess; + uint8_t* bufferData = nullptr; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WinRTOutputWrapper); + }; + +public: + WinRTMidiService() + { + if (! WinRTWrapper::getInstance()->isInitialised()) + throw std::runtime_error ("Failed to initialise the WinRT wrapper"); + + midiInFactory = WinRTWrapper::getInstance()->getWRLFactory (&RuntimeClass_Windows_Devices_Midi_MidiInPort[0]); + if (midiInFactory == nullptr) + throw std::runtime_error ("Failed to create midi in factory"); + + midiOutFactory = WinRTWrapper::getInstance()->getWRLFactory (&RuntimeClass_Windows_Devices_Midi_MidiOutPort[0]); + if (midiOutFactory == nullptr) + throw std::runtime_error ("Failed to create midi out factory"); + + inputDeviceWatcher = new MidiIODeviceWatcher (midiInFactory); + if (! inputDeviceWatcher->start()) + throw std::runtime_error ("Failed to start midi input device watcher"); + + outputDeviceWatcher = new MidiIODeviceWatcher (midiOutFactory); + if (! outputDeviceWatcher->start()) + throw std::runtime_error ("Failed to start midi output device watcher"); } - return nullptr; -} + ~WinRTMidiService() + { + } -MidiOutput::~MidiOutput() -{ - stopBackgroundThread(); + StringArray getDevices (bool isInput) override + { + return isInput ? inputDeviceWatcher ->getDevices() + : outputDeviceWatcher->getDevices(); + } - MidiOutHandle* const h = static_cast (internal); + int getDefaultDeviceIndex (bool isInput) override + { + return isInput ? inputDeviceWatcher ->getDefaultDeviceIndex() + : outputDeviceWatcher->getDefaultDeviceIndex(); + } + + InputWrapper* createInputWrapper (MidiInput* const input, + const int index, + MidiInputCallback* const callback) override + { + return new WinRTInputWrapper (*this, input, index, *callback); + } - if (MidiOutHandle::activeHandles.contains (h) && --(h->refCount) == 0) + OutputWrapper* createOutputWrapper (const int index) override { - midiOutClose (h->handle); - MidiOutHandle::activeHandles.removeFirstMatchingValue (h); - delete h; + return new WinRTOutputWrapper (*this, index); } + + ComSmartPtr midiInFactory; + ComSmartPtr midiOutFactory; + + ScopedPointer> inputDeviceWatcher; + ScopedPointer> outputDeviceWatcher; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WinRTMidiService) +}; + +#endif // JUCE_USE_WINRT_MIDI + +//============================================================================== +class MidiService : public DeletedAtShutdown +{ +public: + ~MidiService(); + + MidiServiceType* getService(); + + juce_DeclareSingleton (MidiService, false) + +private: + MidiService(); + + ScopedPointer internal; +}; + +juce_ImplementSingleton (MidiService) + +MidiService::~MidiService() +{ + clearSingletonInstance(); } -void MidiOutput::sendMessageNow (const MidiMessage& message) +MidiServiceType* MidiService::getService() { - const MidiOutHandle* const handle = static_cast (internal); + return internal.get(); +} - if (message.getRawDataSize() > 3 || message.isSysEx()) +MidiService::MidiService() +{ + #if JUCE_USE_WINRT_MIDI + try + { + internal = new WinRTMidiService(); + return; + } + catch (std::runtime_error&) { - MIDIHDR h = { 0 }; + } + #endif - h.lpData = (char*) message.getRawData(); - h.dwBytesRecorded = h.dwBufferLength = (DWORD) message.getRawDataSize(); + internal = new WindowsMidiService(); +} - if (midiOutPrepareHeader (handle->handle, &h, sizeof (MIDIHDR)) == MMSYSERR_NOERROR) - { - MMRESULT res = midiOutLongMsg (handle->handle, &h, sizeof (MIDIHDR)); +//============================================================================== +StringArray MidiInput::getDevices() +{ + return MidiService::getInstance()->getService()->getDevices (true); +} - if (res == MMSYSERR_NOERROR) - { - while ((h.dwFlags & MHDR_DONE) == 0) - Sleep (1); +int MidiInput::getDefaultDeviceIndex() +{ + return MidiService::getInstance()->getService()->getDefaultDeviceIndex (true); +} - int count = 500; // 1 sec timeout +MidiInput::MidiInput (const String& deviceName) + : name (deviceName) +{ +} - while (--count >= 0) - { - res = midiOutUnprepareHeader (handle->handle, &h, sizeof (MIDIHDR)); +MidiInput* MidiInput::openDevice (const int index, MidiInputCallback* const callback) +{ + if (callback == nullptr) + return nullptr; - if (res == MIDIERR_STILLPLAYING) - Sleep (2); - else - break; - } - } - } + ScopedPointer in (new MidiInput ("")); + ScopedPointer wrapper; + try + { + wrapper = MidiService::getInstance()->getService()->createInputWrapper (in, index, callback); } - else + catch (std::runtime_error&) { - for (int i = 0; i < 50; ++i) - { - if (midiOutShortMsg (handle->handle, *(unsigned int*) message.getRawData()) != MIDIERR_NOTREADY) - break; + return nullptr; + } - Sleep (1); - } + in->setName (wrapper->getDeviceName()); + in->internal = wrapper.release(); + return in.release(); +} + +MidiInput::~MidiInput() +{ + delete static_cast (internal); +} + +void MidiInput::start() { static_cast (internal)->start(); } +void MidiInput::stop() { static_cast (internal)->stop(); } + +//============================================================================== +StringArray MidiOutput::getDevices() +{ + return MidiService::getInstance()->getService()->getDevices (false); +} + +int MidiOutput::getDefaultDeviceIndex() +{ + return MidiService::getInstance()->getService()->getDefaultDeviceIndex (false); +} + +MidiOutput* MidiOutput::openDevice (const int index) +{ + ScopedPointer wrapper; + try + { + wrapper = MidiService::getInstance()->getService()->createOutputWrapper (index); } + catch (std::runtime_error&) + { + return nullptr; + } + + ScopedPointer out (new MidiOutput (wrapper->getDeviceName())); + out->internal = wrapper.release(); + return out.release(); +} + +MidiOutput::~MidiOutput() +{ + stopBackgroundThread(); + delete static_cast (internal); +} + +void MidiOutput::sendMessageNow (const MidiMessage& message) +{ + auto* const wrapper = static_cast (internal); + wrapper->sendMessageNow (message); } diff --git a/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp b/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp index c2115fa48..52d0235fc 100644 --- a/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp +++ b/source/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -102,18 +94,6 @@ bool check (HRESULT hr) } #if JUCE_MINGW - - #define JUCE_COMCLASS(name, guid) \ - struct name; \ - template<> struct UUIDGetter { static CLSID get() { return uuidFromString (guid); } }; \ - struct name - - #ifdef __uuidof - #undef __uuidof - #endif - - #define __uuidof(cls) UUIDGetter::get() - struct PROPERTYKEY { GUID fmtid; @@ -121,8 +101,6 @@ bool check (HRESULT hr) }; WINOLEAPI PropVariantClear (PROPVARIANT*); -#else - #define JUCE_COMCLASS(name, guid) struct __declspec (uuid (guid)) name #endif #if JUCE_MINGW && defined (KSDATAFORMAT_SUBTYPE_PCM) diff --git a/source/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp b/source/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp index 58139bf46..90525e01b 100644 --- a/source/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp +++ b/source/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h b/source/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h index 099563233..8ef176067 100644 --- a/source/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h +++ b/source/modules/juce_audio_devices/sources/juce_AudioSourcePlayer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOSOURCEPLAYER_H_INCLUDED -#define JUCE_AUDIOSOURCEPLAYER_H_INCLUDED +#pragma once //============================================================================== @@ -116,6 +107,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSourcePlayer) }; - - -#endif // JUCE_AUDIOSOURCEPLAYER_H_INCLUDED diff --git a/source/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp b/source/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp index 03b4adf50..31610633b 100644 --- a/source/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp +++ b/source/modules/juce_audio_devices/sources/juce_AudioTransportSource.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_devices/sources/juce_AudioTransportSource.h b/source/modules/juce_audio_devices/sources/juce_AudioTransportSource.h index 8d61ccb6a..36cb8f5a2 100644 --- a/source/modules/juce_audio_devices/sources/juce_AudioTransportSource.h +++ b/source/modules/juce_audio_devices/sources/juce_AudioTransportSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOTRANSPORTSOURCE_H_INCLUDED -#define JUCE_AUDIOTRANSPORTSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -181,6 +172,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioTransportSource) }; - - -#endif // JUCE_AUDIOTRANSPORTSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c b/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c index a4632e37b..47e07e284 100644 --- a/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c +++ b/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c @@ -90,7 +90,7 @@ struct FLAC__BitReader { static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word) { - register unsigned crc = br->read_crc16; + unsigned crc = br->read_crc16; #if FLAC__BYTES_PER_WORD == 4 switch(br->crc16_align) { case 0: crc = FLAC__CRC16_UPDATE((unsigned)(word >> 24), crc); diff --git a/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c b/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c index 565fbcd36..5658da26c 100644 --- a/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c +++ b/source/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c @@ -303,7 +303,7 @@ inline FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bit inline FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits) { - register unsigned left; + unsigned left; /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); diff --git a/source/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c b/source/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c index d41f6a810..de9ac9dc6 100644 --- a/source/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c +++ b/source/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c @@ -53,7 +53,7 @@ */ static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]) { - register FLAC__uint32 a, b, c, d; + FLAC__uint32 a, b, c, d; a = buf[0]; b = buf[1]; diff --git a/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp b/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp index 0d6a748e7..40619c54c 100644 --- a/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp +++ b/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -197,9 +199,9 @@ namespace AiffFileHelpers { static bool isValidTag (const char* d) noexcept { - return CharacterFunctions::isLetterOrDigit (d[0]) && CharacterFunctions::isUpperCase (d[0]) - && CharacterFunctions::isLetterOrDigit (d[1]) && CharacterFunctions::isLowerCase (d[1]) - && CharacterFunctions::isLetterOrDigit (d[2]) && CharacterFunctions::isLowerCase (d[2]); + return CharacterFunctions::isLetterOrDigit (d[0]) && CharacterFunctions::isUpperCase (static_cast (d[0])) + && CharacterFunctions::isLetterOrDigit (d[1]) && CharacterFunctions::isLowerCase (static_cast (d[1])) + && CharacterFunctions::isLetterOrDigit (d[2]) && CharacterFunctions::isLowerCase (static_cast (d[2])); } static bool isAppleGenre (const String& tag) noexcept @@ -614,7 +616,8 @@ public: case 16: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; case 24: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; case 32: if (usesFloatingPointData) ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); - else ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; + else ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); + break; default: jassertfalse; break; } } @@ -634,10 +637,7 @@ public: AiffAudioFormatWriter (OutputStream* out, double rate, unsigned int numChans, unsigned int bits, const StringPairArray& metadataValues) - : AudioFormatWriter (out, aiffFormatName, rate, numChans, bits), - lengthInSamples (0), - bytesWritten (0), - writeFailed (false) + : AudioFormatWriter (out, aiffFormatName, rate, numChans, bits) { using namespace AiffFileHelpers; @@ -704,9 +704,9 @@ public: private: MemoryBlock tempBlock, markChunk, comtChunk, instChunk; - uint64 lengthInSamples, bytesWritten; - int64 headerPosition; - bool writeFailed; + uint64 lengthInSamples = 0, bytesWritten = 0; + int64 headerPosition = 0; + bool writeFailed = false; void writeHeader() { @@ -867,7 +867,8 @@ public: case 16: ReadHelper::read (dest, 0, 1, source, 1, num); break; case 24: ReadHelper::read (dest, 0, 1, source, 1, num); break; case 32: if (usesFloatingPointData) ReadHelper::read (dest, 0, 1, source, 1, num); - else ReadHelper::read (dest, 0, 1, source, 1, num); break; + else ReadHelper::read (dest, 0, 1, source, 1, num); + break; default: jassertfalse; break; } } @@ -879,7 +880,8 @@ public: case 16: ReadHelper::read (dest, 0, 1, source, 1, num); break; case 24: ReadHelper::read (dest, 0, 1, source, 1, num); break; case 32: if (usesFloatingPointData) ReadHelper::read (dest, 0, 1, source, 1, num); - else ReadHelper::read (dest, 0, 1, source, 1, num); break; + else ReadHelper::read (dest, 0, 1, source, 1, num); + break; default: jassertfalse; break; } } @@ -905,7 +907,8 @@ public: case 16: scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); break; case 24: scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); break; case 32: if (usesFloatingPointData) scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); - else scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); break; + else scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); + break; default: jassertfalse; break; } } @@ -960,7 +963,7 @@ bool AiffAudioFormat::canHandleFile (const File& f) if (AudioFormat::canHandleFile (f)) return true; - const OSType type = f.getMacOSType(); + auto type = f.getMacOSType(); // (NB: written as hex to avoid four-char-constant warnings) return type == 0x41494646 /* AIFF */ || type == 0x41494643 /* AIFC */ @@ -968,7 +971,7 @@ bool AiffAudioFormat::canHandleFile (const File& f) } #endif -AudioFormatReader* AiffAudioFormat::createReaderFor (InputStream* sourceStream, const bool deleteStreamIfOpeningFails) +AudioFormatReader* AiffAudioFormat::createReaderFor (InputStream* sourceStream, bool deleteStreamIfOpeningFails) { ScopedPointer w (new AiffAudioFormatReader (sourceStream)); @@ -1007,7 +1010,8 @@ AudioFormatWriter* AiffAudioFormat::createWriterFor (OutputStream* out, int /*qualityOptionIndex*/) { if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample)) - return new AiffAudioFormatWriter (out, sampleRate, numberOfChannels, (unsigned int) bitsPerSample, metadataValues); + return new AiffAudioFormatWriter (out, sampleRate, numberOfChannels, + (unsigned int) bitsPerSample, metadataValues); return nullptr; } diff --git a/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h b/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h index 9895d1b6e..efafaa73a 100644 --- a/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h +++ b/source/modules/juce_audio_formats/codecs/juce_AiffAudioFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp b/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp index ceb8a5ee2..c408f6af1 100644 --- a/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp +++ b/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.cpp @@ -2,28 +2,32 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ #if JUCE_MAC || JUCE_IOS +#include "../../juce_audio_basics/native/juce_mac_CoreAudioLayouts.h" + //============================================================================== namespace { @@ -374,6 +378,31 @@ public: &sizeOfLengthProperty, &lengthInSamples); + HeapBlock caLayout; + bool hasLayout = false; + UInt32 sizeOfLayout = 0, isWritable = 0; + + status = AudioFileGetPropertyInfo (audioFileID, kAudioFilePropertyChannelLayout, &sizeOfLayout, &isWritable); + + if (status == noErr) + { + caLayout.malloc (1, static_cast (sizeOfLayout)); + + status = AudioFileGetProperty (audioFileID, kAudioFilePropertyChannelLayout, + &sizeOfLayout, caLayout.getData()); + + if (status == noErr) + { + auto fileLayout = CoreAudioLayouts::fromCoreAudio (*caLayout.getData()); + + if (fileLayout.size() == static_cast (numChannels)) + { + hasLayout = true; + channelSet = fileLayout; + } + } + } + destinationAudioFormat.mSampleRate = sampleRate; destinationAudioFormat.mFormatID = kAudioFormatLinearPCM; destinationAudioFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsNonInterleaved | kAudioFormatFlagsNativeEndian; @@ -391,6 +420,26 @@ public: { bufferList.malloc (1, sizeof (AudioBufferList) + numChannels * sizeof (::AudioBuffer)); bufferList->mNumberBuffers = numChannels; + channelMap.malloc (numChannels); + + if (hasLayout && caLayout != nullptr) + { + auto caOrder = CoreAudioLayouts::getCoreAudioLayoutChannels (*caLayout); + + for (int i = 0; i < static_cast (numChannels); ++i) + { + auto idx = channelSet.getChannelIndexForType (caOrder.getReference (i)); + jassert (isPositiveAndBelow (idx, static_cast (numChannels))); + + channelMap[i] = idx; + } + } + else + { + for (int i = 0; i < static_cast (numChannels); ++i) + channelMap[i] = i; + } + ok = true; } } @@ -445,12 +494,14 @@ public: for (int i = numDestChannels; --i >= 0;) { - if (destSamples[i] != nullptr) + int* dest = destSamples[(i < (int) numChannels ? channelMap[i] : i)]; + + if (dest != nullptr) { if (i < (int) numChannels) - memcpy (destSamples[i] + startOffsetInDestBuffer, bufferList->mBuffers[i].mData, numBytes); + memcpy (dest + startOffsetInDestBuffer, bufferList->mBuffers[i].mData, numBytes); else - zeromem (destSamples[i] + startOffsetInDestBuffer, numBytes); + zeromem (dest + startOffsetInDestBuffer, numBytes); } } @@ -462,15 +513,24 @@ public: return true; } + AudioChannelSet getChannelLayout() override + { + if (channelSet.size() == static_cast (numChannels)) return channelSet; + + return AudioFormatReader::getChannelLayout(); + } + bool ok; private: AudioFileID audioFileID; ExtAudioFileRef audioFileRef; + AudioChannelSet channelSet; AudioStreamBasicDescription destinationAudioFormat; MemoryBlock audioDataBlock; HeapBlock bufferList; int64 lastReadPosition; + HeapBlock channelMap; static SInt64 getSizeCallback (void* inClientData) { @@ -534,4 +594,249 @@ AudioFormatWriter* CoreAudioFormat::createWriterFor (OutputStream*, return nullptr; } +//============================================================================== +// Unit tests for Core Audio layout conversions +//============================================================================== +#if JUCE_UNIT_TESTS + +#define DEFINE_CHANNEL_LAYOUT_DFL_ENTRY(x) CoreAudioChannelLayoutTag { x, #x, AudioChannelSet() } +#define DEFINE_CHANNEL_LAYOUT_TAG_ENTRY(x, y) CoreAudioChannelLayoutTag { x, #x, y } + +class CoreAudioLayoutsUnitTest : public UnitTest +{ +public: + CoreAudioLayoutsUnitTest() : UnitTest ("Core Audio Layout <-> JUCE channel layout conversion", "Audio") {} + + void runTest() override + { + auto& knownTags = getAllKnownLayoutTags(); + + { + // Check that all known tags defined in CoreAudio SDK version 10.12.4 are known to JUCE + // Include all defined tags even if there are duplicates as Apple will sometimes change + // definitions + beginTest ("All CA tags handled"); + + for (auto tagEntry : knownTags) + { + AudioChannelLayout layout { tagEntry.tag }; + auto labels = CoreAudioLayouts::fromCoreAudio (layout); + + expect (! labels.isDiscreteLayout(), String ("Tag \"") + String (tagEntry.name) + "\" is not handled by JUCE"); + } + } + + { + beginTest ("Number of speakers"); + + for (auto tagEntry : knownTags) + { + AudioChannelLayout layout { tagEntry.tag }; + auto labels = CoreAudioLayouts::getCoreAudioLayoutChannels (layout); + + expect (labels.size() == (tagEntry.tag & 0xffff), String ("Tag \"") + String (tagEntry.name) + "\" has incorrect channel count"); + } + } + + { + beginTest ("No duplicate speaker"); + + for (auto tagEntry : knownTags) + { + AudioChannelLayout layout { tagEntry.tag }; + auto labels = CoreAudioLayouts::getCoreAudioLayoutChannels (layout); + labels.sort(); + + for (int i = 0; i < (labels.size() - 1); ++i) + expect (labels.getReference (i) != labels.getReference (i + 1), + String ("Tag \"") + String (tagEntry.name) + "\" has the same speaker twice"); + } + } + + { + beginTest ("CA speaker list and juce layouts are consistent"); + + for (auto tagEntry : knownTags) + { + AudioChannelLayout layout { tagEntry.tag }; + + expect (AudioChannelSet::channelSetWithChannels (CoreAudioLayouts::getCoreAudioLayoutChannels (layout)) + == CoreAudioLayouts::fromCoreAudio (layout), + String ("Tag \"") + String (tagEntry.name) + "\" is not converted consistantly by JUCE"); + } + } + + { + beginTest ("AudioChannelSet documentation is correct"); + + for (auto tagEntry : knownTags) + { + if (tagEntry.equivalentChannelSet.isDisabled()) + continue; + + AudioChannelLayout layout { tagEntry.tag }; + + expect (CoreAudioLayouts::fromCoreAudio (layout) == tagEntry.equivalentChannelSet, + String ("Documentation for tag \"") + String (tagEntry.name) + "\" is incorrect"); + } + } + + { + beginTest ("CA tag reverse conversion"); + + for (auto tagEntry : knownTags) + { + if (tagEntry.equivalentChannelSet.isDisabled()) + continue; + + expect (CoreAudioLayouts::toCoreAudio (tagEntry.equivalentChannelSet) == tagEntry.tag, + String ("Incorrect reverse conversion for tag \"") + String (tagEntry.name) + "\""); + } + } + } + +private: + struct CoreAudioChannelLayoutTag + { + AudioChannelLayoutTag tag; + const char* name; + AudioChannelSet equivalentChannelSet; /* referred to this in the AudioChannelSet documentation */ + }; + + //============================================================================== + const Array& getAllKnownLayoutTags() const + { + static Array knownTags ({ + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Mono, AudioChannelSet::mono()), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Stereo, AudioChannelSet::stereo()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_StereoHeadphones), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MatrixStereo), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MidSide), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_XY), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Binaural), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Ambisonic_B_Format, AudioChannelSet::ambisonic()), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Quadraphonic, AudioChannelSet::quadraphonic()), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Pentagonal, AudioChannelSet::pentagonal()), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Hexagonal, AudioChannelSet::hexagonal()), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Octagonal, AudioChannelSet::octagonal()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Cube), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_1_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_2_0), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_3_0_A, AudioChannelSet::createLCR()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_3_0_B), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_4_0_A, AudioChannelSet::createLCRS()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_4_0_B), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_A, AudioChannelSet::create5point0()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_B), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_C), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_D), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_A, AudioChannelSet::create5point1()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_B), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_C), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_D), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_6_1_A, AudioChannelSet::create6point1()), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_A, AudioChannelSet::create7point1SDDS()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_B), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_C, AudioChannelSet::create7point1()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Emagic_Default_7_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_SMPTE_DTV), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_1_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_2_0), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_ITU_2_1, AudioChannelSet::createLRS()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_2_2), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_2), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_2_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_4_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_2), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_3), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_4), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_5), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_6), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_7), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_8), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_9), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_10), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_11), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_12), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_13), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_14), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_15), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_16), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_17), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_18), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_19), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_20), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_4), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_5), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_6), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_8), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_5_0), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_AudioUnit_6_0, AudioChannelSet::create6point0()), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_0, AudioChannelSet::create7point0()), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_0_Front, AudioChannelSet::create7point0SDDS()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_5_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_6_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_1_Front), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_3_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_Quadraphonic), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_4_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_5_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_5_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_6_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_6_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_1_B), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_1_C), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_Octagonal), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_TMH_10_2_std), + // DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_TMH_10_2_full), no indicatoin on how to handle this tag + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_1_0_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_0_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_2_1_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_1_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC_6_0_A), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC_7_0_A), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_6_1_A), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_6_1_B), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_6_1_C), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_A), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_B), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_C), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_D), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_E), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_F), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_G), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_H), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_3_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_4_1), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_DTS_6_0_A, AudioChannelSet::create6point0Music()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_0_B), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_0_C), + DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_DTS_6_1_A, AudioChannelSet::create6point1Music()), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_B), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_C), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_7_0), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_7_1), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_0_A), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_0_B), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_1_A), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_1_B), + DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_D) + }); + + return knownTags; + } +}; + +static CoreAudioLayoutsUnitTest coreAudioLayoutsUnitTest; + +#endif #endif diff --git a/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h b/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h index 8ae56fc6e..dd5b54ab8 100644 --- a/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h +++ b/source/modules/juce_audio_formats/codecs/juce_CoreAudioFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp b/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp index 0cc4d1a1c..0c6b26759 100644 --- a/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp +++ b/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h b/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h index 68f1628ea..8b3c43e4f 100644 --- a/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h +++ b/source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp b/source/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp index 8be87bf68..78b61d904 100644 --- a/source/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp +++ b/source/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h b/source/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h index 77e6be61f..dc0290d94 100644 --- a/source/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h +++ b/source/modules/juce_audio_formats/codecs/juce_LAMEEncoderAudioFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp b/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp index 680933a0c..bfc987db3 100644 --- a/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp +++ b/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -3131,12 +3133,12 @@ private: MP3AudioFormat::MP3AudioFormat() : AudioFormat (MP3Decoder::mp3FormatName, ".mp3") {} MP3AudioFormat::~MP3AudioFormat() {} -Array MP3AudioFormat::getPossibleSampleRates() { return Array(); } -Array MP3AudioFormat::getPossibleBitDepths() { return Array(); } +Array MP3AudioFormat::getPossibleSampleRates() { return {}; } +Array MP3AudioFormat::getPossibleBitDepths() { return {}; } bool MP3AudioFormat::canDoStereo() { return true; } bool MP3AudioFormat::canDoMono() { return true; } bool MP3AudioFormat::isCompressed() { return true; } -StringArray MP3AudioFormat::getQualityOptions() { return StringArray(); } +StringArray MP3AudioFormat::getQualityOptions() { return {}; } AudioFormatReader* MP3AudioFormat::createReaderFor (InputStream* sourceStream, const bool deleteStreamIfOpeningFails) { diff --git a/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h b/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h index d3cd792ea..5d952d42f 100644 --- a/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h +++ b/source/modules/juce_audio_formats/codecs/juce_MP3AudioFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp b/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp index 454156f4f..34a83caba 100644 --- a/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp +++ b/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -34,13 +36,14 @@ namespace OggVorbisNamespace #if JUCE_MSVC #pragma warning (push) #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706 4995 4365 4456 4457 4459) - #endif - - #if JUCE_CLANG + #elif JUCE_CLANG #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wshadow" #pragma clang diagnostic ignored "-Wdeprecated-register" + #elif JUCE_GCC + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wshadow" #endif #include "oggvorbis/vorbisenc.h" @@ -73,10 +76,10 @@ namespace OggVorbisNamespace #if JUCE_MSVC #pragma warning (pop) - #endif - - #if JUCE_CLANG + #elif JUCE_CLANG #pragma clang diagnostic pop + #elif JUCE_GCC + #pragma GCC diagnostic pop #endif #else #include diff --git a/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h b/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h index 9d575e074..416ecad20 100644 --- a/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h +++ b/source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp b/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp deleted file mode 100644 index 1ad2e6f50..000000000 --- a/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_QUICKTIME && ! (JUCE_64BIT || JUCE_IOS) - -} // (juce namespace) - -#if ! JUCE_WINDOWS - #include - #include - #include - #include - #include -#else - #if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable : 4100) - #endif - - /* If you've got an include error here, you probably need to install the QuickTime SDK and - add its header directory to your include path. - - Alternatively, if you don't need any QuickTime services, just set the JUCE_QUICKTIME flag to 0. - */ - #undef SIZE_MAX - #include - #include - #include - #include - #include - #undef SIZE_MAX - - #if JUCE_MSVC - #pragma warning (pop) - #endif -#endif - -namespace juce -{ - -bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); - -static const char* const quickTimeFormatName = "QuickTime file"; - -//============================================================================== -class QTAudioReader : public AudioFormatReader -{ -public: - QTAudioReader (InputStream* const input_, const int trackNum_) - : AudioFormatReader (input_, quickTimeFormatName), - ok (false), - movie (0), - trackNum (trackNum_), - lastSampleRead (0), - lastThreadId (0), - extractor (0), - dataHandle (0) - { - JUCE_AUTORELEASEPOOL - { - bufferList.calloc (256, 1); - - #if JUCE_WINDOWS - if (InitializeQTML (0) != noErr) - return; - #endif - - if (EnterMovies() != noErr) - return; - - bool opened = juce_OpenQuickTimeMovieFromStream (input_, movie, dataHandle); - - if (! opened) - return; - - { - const int numTracks = GetMovieTrackCount (movie); - int trackCount = 0; - - for (int i = 1; i <= numTracks; ++i) - { - track = GetMovieIndTrack (movie, i); - media = GetTrackMedia (track); - - OSType mediaType; - GetMediaHandlerDescription (media, &mediaType, 0, 0); - - if (mediaType == SoundMediaType - && trackCount++ == trackNum_) - { - ok = true; - break; - } - } - } - - if (! ok) - return; - - ok = false; - - lengthInSamples = GetMediaDecodeDuration (media); - usesFloatingPointData = false; - - samplesPerFrame = (int) (GetMediaDecodeDuration (media) / GetMediaSampleCount (media)); - - trackUnitsPerFrame = GetMovieTimeScale (movie) * samplesPerFrame - / GetMediaTimeScale (media); - - MovieAudioExtractionBegin (movie, 0, &extractor); - - unsigned long output_layout_size; - OSStatus err = MovieAudioExtractionGetPropertyInfo (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, - 0, &output_layout_size, 0); - if (err != noErr) - return; - - HeapBlock qt_audio_channel_layout; - qt_audio_channel_layout.calloc (output_layout_size, 1); - - MovieAudioExtractionGetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, - output_layout_size, qt_audio_channel_layout, 0); - - qt_audio_channel_layout[0].mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; - - MovieAudioExtractionSetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, - output_layout_size, - qt_audio_channel_layout); - - err = MovieAudioExtractionGetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription, - sizeof (inputStreamDesc), - &inputStreamDesc, 0); - if (err != noErr) - return; - - inputStreamDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger - | kAudioFormatFlagIsPacked - | kAudioFormatFlagsNativeEndian; - inputStreamDesc.mBitsPerChannel = sizeof (SInt16) * 8; - inputStreamDesc.mChannelsPerFrame = jmin ((UInt32) 2, inputStreamDesc.mChannelsPerFrame); - inputStreamDesc.mBytesPerFrame = sizeof (SInt16) * inputStreamDesc.mChannelsPerFrame; - inputStreamDesc.mBytesPerPacket = inputStreamDesc.mBytesPerFrame; - - err = MovieAudioExtractionSetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Audio, - kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription, - sizeof (inputStreamDesc), - &inputStreamDesc); - if (err != noErr) - return; - - Boolean allChannelsDiscrete = false; - err = MovieAudioExtractionSetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Movie, - kQTMovieAudioExtractionMoviePropertyID_AllChannelsDiscrete, - sizeof (allChannelsDiscrete), - &allChannelsDiscrete); - - if (err != noErr) - return; - - bufferList->mNumberBuffers = 1; - bufferList->mBuffers[0].mNumberChannels = inputStreamDesc.mChannelsPerFrame; - bufferList->mBuffers[0].mDataByteSize = jmax ((UInt32) 4096, (UInt32) (samplesPerFrame * (int) inputStreamDesc.mBytesPerFrame) + 16); - - dataBuffer.malloc (bufferList->mBuffers[0].mDataByteSize); - bufferList->mBuffers[0].mData = dataBuffer; - - sampleRate = inputStreamDesc.mSampleRate; - bitsPerSample = 16; - numChannels = inputStreamDesc.mChannelsPerFrame; - - detachThread(); - ok = true; - } - } - - ~QTAudioReader() - { - JUCE_AUTORELEASEPOOL - { - checkThreadIsAttached(); - - if (dataHandle != nullptr) - DisposeHandle (dataHandle); - - if (extractor != nullptr) - { - MovieAudioExtractionEnd (extractor); - extractor = nullptr; - } - - DisposeMovie (movie); - - #if JUCE_MAC - ExitMoviesOnThread(); - #endif - } - } - - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples) - { - JUCE_AUTORELEASEPOOL - { - checkThreadIsAttached(); - bool readOk = true; - - while (numSamples > 0) - { - if (lastSampleRead != startSampleInFile) - { - TimeRecord time; - time.scale = (TimeScale) inputStreamDesc.mSampleRate; - time.base = 0; - time.value.hi = 0; - time.value.lo = (UInt32) startSampleInFile; - - OSStatus err = MovieAudioExtractionSetProperty (extractor, - kQTPropertyClass_MovieAudioExtraction_Movie, - kQTMovieAudioExtractionMoviePropertyID_CurrentTime, - sizeof (time), &time); - - if (err != noErr) - { - readOk = false; - break; - } - } - - int framesToDo = jmin (numSamples, (int) (bufferList->mBuffers[0].mDataByteSize / inputStreamDesc.mBytesPerFrame)); - bufferList->mBuffers[0].mDataByteSize = inputStreamDesc.mBytesPerFrame * (UInt32) framesToDo; - - UInt32 outFlags = 0; - UInt32 actualNumFrames = (UInt32) framesToDo; - OSStatus err = MovieAudioExtractionFillBuffer (extractor, &actualNumFrames, bufferList, &outFlags); - if (err != noErr) - { - readOk = false; - break; - } - - lastSampleRead = startSampleInFile + actualNumFrames; - const int samplesReceived = (int) actualNumFrames; - - for (int j = numDestChannels; --j >= 0;) - { - if (destSamples[j] != nullptr) - { - const short* src = ((const short*) bufferList->mBuffers[0].mData) + j; - - for (int i = 0; i < samplesReceived; ++i) - { - destSamples[j][startOffsetInDestBuffer + i] = (*src << 16); - src += numChannels; - } - } - } - - startOffsetInDestBuffer += samplesReceived; - startSampleInFile += samplesReceived; - numSamples -= samplesReceived; - - if (((outFlags & kQTMovieAudioExtractionComplete) != 0 || samplesReceived == 0) && numSamples > 0) - { - for (int j = numDestChannels; --j >= 0;) - if (destSamples[j] != nullptr) - zeromem (destSamples[j] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples); - - break; - } - } - - detachThread(); - return readOk; - } - } - - bool ok; - -private: - Movie movie; - Media media; - Track track; - const int trackNum; - double trackUnitsPerFrame; - int samplesPerFrame; - int64 lastSampleRead; - Thread::ThreadID lastThreadId; - MovieAudioExtractionRef extractor; - AudioStreamBasicDescription inputStreamDesc; - HeapBlock bufferList; - HeapBlock dataBuffer; - Handle dataHandle; - - //============================================================================== - void checkThreadIsAttached() - { - #if JUCE_MAC - if (Thread::getCurrentThreadId() != lastThreadId) - EnterMoviesOnThread (0); - AttachMovieToCurrentThread (movie); - #endif - } - - void detachThread() - { - #if JUCE_MAC - DetachMovieFromCurrentThread (movie); - #endif - } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QTAudioReader) -}; - - -//============================================================================== -QuickTimeAudioFormat::QuickTimeAudioFormat() : AudioFormat (quickTimeFormatName, ".mov .mp3 .mp4 .m4a") -{ -} - -QuickTimeAudioFormat::~QuickTimeAudioFormat() -{ -} - -Array QuickTimeAudioFormat::getPossibleSampleRates() { return Array(); } -Array QuickTimeAudioFormat::getPossibleBitDepths() { return Array(); } - -bool QuickTimeAudioFormat::canDoStereo() { return true; } -bool QuickTimeAudioFormat::canDoMono() { return true; } - -//============================================================================== -AudioFormatReader* QuickTimeAudioFormat::createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails) -{ - ScopedPointer r (new QTAudioReader (sourceStream, 0)); - - if (r->ok) - return r.release(); - - if (! deleteStreamIfOpeningFails) - r->input = 0; - - return nullptr; -} - -AudioFormatWriter* QuickTimeAudioFormat::createWriterFor (OutputStream* /*streamToWriteTo*/, - double /*sampleRateToUse*/, - unsigned int /*numberOfChannels*/, - int /*bitsPerSample*/, - const StringPairArray& /*metadataValues*/, - int /*qualityOptionIndex*/) -{ - jassertfalse; // not yet implemented! - return nullptr; -} - -#endif diff --git a/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h b/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h deleted file mode 100644 index a7cd60b7c..000000000 --- a/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#if JUCE_QUICKTIME - -//============================================================================== -/** - Uses QuickTime to read the audio track a movie or media file. - - As well as QuickTime movies, this should also manage to open other audio - files that quicktime can understand, like mp3, m4a, etc. - - @see AudioFormat -*/ -class JUCE_API QuickTimeAudioFormat : public AudioFormat -{ -public: - //============================================================================== - /** Creates a format object. */ - QuickTimeAudioFormat(); - - /** Destructor. */ - ~QuickTimeAudioFormat(); - - //============================================================================== - Array getPossibleSampleRates(); - Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - - //============================================================================== - AudioFormatReader* createReaderFor (InputStream* sourceStream, - bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QuickTimeAudioFormat) -}; - - -#endif diff --git a/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp b/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp index d8e75f242..cbffaff50 100644 --- a/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp +++ b/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -69,6 +71,7 @@ const char* const WavAudioFormat::riffInfoArtist = "IART"; const char* const WavAudioFormat::riffInfoBaseURL = "IBSU"; const char* const WavAudioFormat::riffInfoCinematographer = "ICNM"; const char* const WavAudioFormat::riffInfoComment = "CMNT"; +const char* const WavAudioFormat::riffInfoComment2 = "ICMT"; const char* const WavAudioFormat::riffInfoComments = "COMM"; const char* const WavAudioFormat::riffInfoCommissioned = "ICMS"; const char* const WavAudioFormat::riffInfoCopyright = "ICOP"; @@ -109,6 +112,7 @@ const char* const WavAudioFormat::riffInfoNumberOfParts = "PRT2"; const char* const WavAudioFormat::riffInfoOrganisation = "TORG"; const char* const WavAudioFormat::riffInfoPart = "PRT1"; const char* const WavAudioFormat::riffInfoProducedBy = "IPRO"; +const char* const WavAudioFormat::riffInfoProductName = "IPRD"; const char* const WavAudioFormat::riffInfoProductionDesigner = "IPDS"; const char* const WavAudioFormat::riffInfoProductionStudio = "ISDT"; const char* const WavAudioFormat::riffInfoRate = "RATE"; @@ -134,6 +138,7 @@ const char* const WavAudioFormat::riffInfoTechnician = "ITCH"; const char* const WavAudioFormat::riffInfoThirdLanguage = "IAS3"; const char* const WavAudioFormat::riffInfoTimeCode = "ISMP"; const char* const WavAudioFormat::riffInfoTitle = "INAM"; +const char* const WavAudioFormat::riffInfoTrackNo = "IPRT"; const char* const WavAudioFormat::riffInfoTrackNumber = "TRCK"; const char* const WavAudioFormat::riffInfoURL = "TURL"; const char* const WavAudioFormat::riffInfoVegasVersionMajor = "VMAJ"; @@ -218,11 +223,26 @@ namespace WavFileHelpers return data; } - return MemoryBlock(); + return {}; } } JUCE_PACKED; + //============================================================================== + AudioChannelSet canonicalWavChannelSet (int numChannels) + { + if (numChannels == 1) return AudioChannelSet::mono(); + if (numChannels == 2) return AudioChannelSet::stereo(); + if (numChannels == 3) return AudioChannelSet::createLCR(); + if (numChannels == 4) return AudioChannelSet::quadraphonic(); + if (numChannels == 5) return AudioChannelSet::create5point0(); + if (numChannels == 6) return AudioChannelSet::create5point1(); + if (numChannels == 7) return AudioChannelSet::create7point0SDDS(); + if (numChannels == 8) return AudioChannelSet::create7point1SDDS(); + + return AudioChannelSet::discreteChannels (numChannels); + } + //============================================================================== struct SMPLChunk { @@ -300,32 +320,29 @@ namespace WavFileHelpers MemoryBlock data; const int numLoops = jmin (64, values.getValue ("NumSampleLoops", "0").getIntValue()); - if (numLoops > 0) - { - data.setSize (roundUpSize (sizeof (SMPLChunk) + (size_t) (numLoops - 1) * sizeof (SampleLoop)), true); + data.setSize (roundUpSize (sizeof (SMPLChunk) + (size_t) (jmax (0, numLoops - 1)) * sizeof (SampleLoop)), true); - SMPLChunk* const s = static_cast (data.getData()); + auto s = static_cast (data.getData()); - s->manufacturer = getValue (values, "Manufacturer", "0"); - s->product = getValue (values, "Product", "0"); - s->samplePeriod = getValue (values, "SamplePeriod", "0"); - s->midiUnityNote = getValue (values, "MidiUnityNote", "60"); - s->midiPitchFraction = getValue (values, "MidiPitchFraction", "0"); - s->smpteFormat = getValue (values, "SmpteFormat", "0"); - s->smpteOffset = getValue (values, "SmpteOffset", "0"); - s->numSampleLoops = ByteOrder::swapIfBigEndian ((uint32) numLoops); - s->samplerData = getValue (values, "SamplerData", "0"); + s->manufacturer = getValue (values, "Manufacturer", "0"); + s->product = getValue (values, "Product", "0"); + s->samplePeriod = getValue (values, "SamplePeriod", "0"); + s->midiUnityNote = getValue (values, "MidiUnityNote", "60"); + s->midiPitchFraction = getValue (values, "MidiPitchFraction", "0"); + s->smpteFormat = getValue (values, "SmpteFormat", "0"); + s->smpteOffset = getValue (values, "SmpteOffset", "0"); + s->numSampleLoops = ByteOrder::swapIfBigEndian ((uint32) numLoops); + s->samplerData = getValue (values, "SamplerData", "0"); - for (int i = 0; i < numLoops; ++i) - { - SampleLoop& loop = s->loops[i]; - loop.identifier = getValue (values, i, "Identifier", "0"); - loop.type = getValue (values, i, "Type", "0"); - loop.start = getValue (values, i, "Start", "0"); - loop.end = getValue (values, i, "End", "0"); - loop.fraction = getValue (values, i, "Fraction", "0"); - loop.playCount = getValue (values, i, "PlayCount", "0"); - } + for (int i = 0; i < numLoops; ++i) + { + auto& loop = s->loops[i]; + loop.identifier = getValue (values, i, "Identifier", "0"); + loop.type = getValue (values, i, "Type", "0"); + loop.start = getValue (values, i, "Start", "0"); + loop.end = getValue (values, i, "End", "0"); + loop.fraction = getValue (values, i, "Fraction", "0"); + loop.playCount = getValue (values, i, "PlayCount", "0"); } return data; @@ -367,12 +384,12 @@ namespace WavFileHelpers static MemoryBlock createFrom (const StringPairArray& values) { MemoryBlock data; - const StringArray& keys = values.getAllKeys(); + auto& keys = values.getAllKeys(); if (keys.contains ("LowNote", true) && keys.contains ("HighNote", true)) { data.setSize (8, true); - InstChunk* const inst = static_cast (data.getData()); + auto* inst = static_cast (data.getData()); inst->baseNote = getValue (values, "MidiUnityNote", "60"); inst->detune = getValue (values, "Detune", "0"); @@ -435,7 +452,7 @@ namespace WavFileHelpers { data.setSize (roundUpSize (sizeof (CueChunk) + (size_t) (numCues - 1) * sizeof (Cue)), true); - CueChunk* const c = static_cast (data.getData()); + auto c = static_cast (data.getData()); c->numCues = ByteOrder::swapIfBigEndian ((uint32) numCues); @@ -448,18 +465,18 @@ namespace WavFileHelpers for (int i = 0; i < numCues; ++i) { - const String prefix ("Cue" + String (i)); - const uint32 identifier = (uint32) values.getValue (prefix + "Identifier", "0").getIntValue(); + auto prefix = "Cue" + String (i); + auto identifier = (uint32) values.getValue (prefix + "Identifier", "0").getIntValue(); #if JUCE_DEBUG jassert (! identifiers.contains (identifier)); identifiers.add (identifier); #endif - const int order = values.getValue (prefix + "Order", String (nextOrder)).getIntValue(); + auto order = values.getValue (prefix + "Order", String (nextOrder)).getIntValue(); nextOrder = jmax (nextOrder, order) + 1; - Cue& cue = c->cues[i]; + auto& cue = c->cues[i]; cue.identifier = ByteOrder::swapIfBigEndian ((uint32) identifier); cue.order = ByteOrder::swapIfBigEndian ((uint32) order); cue.chunkID = ByteOrder::swapIfBigEndian ((uint32) values.getValue (prefix + "ChunkID", dataChunkID).getIntValue()); @@ -490,9 +507,9 @@ namespace WavFileHelpers static void appendLabelOrNoteChunk (const StringPairArray& values, const String& prefix, const int chunkType, MemoryOutputStream& out) { - const String label (values.getValue (prefix + "Text", prefix)); - const int labelLength = (int) label.getNumBytesAsUTF8() + 1; - const int chunkLength = 4 + labelLength + (labelLength & 1); + auto label = values.getValue (prefix + "Text", prefix); + auto labelLength = (int) label.getNumBytesAsUTF8() + 1; + auto chunkLength = 4 + labelLength + (labelLength & 1); out.writeInt (chunkType); out.writeInt (chunkLength); @@ -505,9 +522,9 @@ namespace WavFileHelpers static void appendExtraChunk (const StringPairArray& values, const String& prefix, MemoryOutputStream& out) { - const String text (values.getValue (prefix + "Text", prefix)); + auto text = values.getValue (prefix + "Text", prefix); - const int textLength = (int) text.getNumBytesAsUTF8() + 1; // include null terminator + auto textLength = (int) text.getNumBytesAsUTF8() + 1; // include null terminator int chunkLength = textLength + 20 + (textLength & 1); out.writeInt (chunkName ("ltxt")); @@ -527,9 +544,9 @@ namespace WavFileHelpers static MemoryBlock createFrom (const StringPairArray& values) { - const int numCueLabels = getValue (values, "NumCueLabels"); - const int numCueNotes = getValue (values, "NumCueNotes"); - const int numCueRegions = getValue (values, "NumCueRegions"); + auto numCueLabels = getValue (values, "NumCueLabels"); + auto numCueNotes = getValue (values, "NumCueNotes"); + auto numCueRegions = getValue (values, "NumCueRegions"); MemoryOutputStream out; @@ -563,6 +580,7 @@ namespace WavFileHelpers WavAudioFormat::riffInfoCinematographer, WavAudioFormat::riffInfoComment, WavAudioFormat::riffInfoComments, + WavAudioFormat::riffInfoComment2, WavAudioFormat::riffInfoCommissioned, WavAudioFormat::riffInfoCopyright, WavAudioFormat::riffInfoCostumeDesigner, @@ -602,6 +620,7 @@ namespace WavFileHelpers WavAudioFormat::riffInfoOrganisation, WavAudioFormat::riffInfoPart, WavAudioFormat::riffInfoProducedBy, + WavAudioFormat::riffInfoProductName, WavAudioFormat::riffInfoProductionDesigner, WavAudioFormat::riffInfoProductionStudio, WavAudioFormat::riffInfoRate, @@ -627,6 +646,7 @@ namespace WavFileHelpers WavAudioFormat::riffInfoThirdLanguage, WavAudioFormat::riffInfoTimeCode, WavAudioFormat::riffInfoTitle, + WavAudioFormat::riffInfoTrackNo, WavAudioFormat::riffInfoTrackNumber, WavAudioFormat::riffInfoURL, WavAudioFormat::riffInfoVegasVersionMajor, @@ -678,7 +698,7 @@ namespace WavFileHelpers static bool writeValue (const StringPairArray& values, MemoryOutputStream& out, const char* paramName) { - const String value (values.getValue (paramName, String())); + auto value = values.getValue (paramName, {}); if (value.isEmpty()) return false; @@ -831,13 +851,13 @@ namespace WavFileHelpers if (xml != nullptr && xml->hasTagName ("ebucore:ebuCoreMain")) { - if (XmlElement* xml2 = xml->getChildByName ("ebucore:coreMetadata")) + if (auto* xml2 = xml->getChildByName ("ebucore:coreMetadata")) { - if (XmlElement* xml3 = xml2->getChildByName ("ebucore:identifier")) + if (auto* xml3 = xml2->getChildByName ("ebucore:identifier")) { - if (XmlElement* xml4 = xml3->getChildByName ("dc:identifier")) + if (auto* xml4 = xml3->getChildByName ("dc:identifier")) { - const String ISRCCode (xml4->getAllSubText().fromFirstOccurrenceOf ("ISRC:", false, true)); + auto ISRCCode = xml4->getAllSubText().fromFirstOccurrenceOf ("ISRC:", false, true); if (ISRCCode.isNotEmpty()) destValues.set (WavAudioFormat::ISRC, ISRCCode); @@ -849,7 +869,7 @@ namespace WavFileHelpers static MemoryBlock createFrom (const StringPairArray& values) { - const String ISRC (values.getValue (WavAudioFormat::ISRC, String())); + auto ISRC = values.getValue (WavAudioFormat::ISRC, {}); MemoryOutputStream xml; if (ISRC.isNotEmpty()) @@ -912,11 +932,7 @@ class WavAudioFormatReader : public AudioFormatReader { public: WavAudioFormatReader (InputStream* const in) - : AudioFormatReader (in, wavFormatName), - bwavChunkStart (0), - bwavSize (0), - dataLength (0), - isRF64 (false) + : AudioFormatReader (in, wavFormatName) { using namespace WavFileHelpers; uint64 len = 0; @@ -942,7 +958,7 @@ public: return; } - const int64 startOfRIFFChunk = input->getPosition(); + auto startOfRIFFChunk = input->getPosition(); if (input->readInt() == chunkName ("WAVE")) { @@ -969,10 +985,10 @@ public: if (chunkType == chunkName ("fmt ")) { // read the format chunk - const unsigned short format = (unsigned short) input->readShort(); + auto format = (unsigned short) input->readShort(); numChannels = (unsigned int) input->readShort(); sampleRate = input->readInt(); - const int bytesPerSec = input->readInt(); + auto bytesPerSec = input->readInt(); input->skipNextBytes (2); bitsPerSample = (unsigned int) (int) input->readShort(); @@ -999,7 +1015,17 @@ public: else { input->skipNextBytes (4); // skip over size and bitsPerSample - metadataValues.set ("ChannelMask", String (input->readInt())); + auto channelMask = input->readInt(); + metadataValues.set ("ChannelMask", String (channelMask)); + + // AudioChannelSet and wav's dwChannelMask are compatible + BigInteger channelBits (channelMask); + + for (auto bit = channelBits.findNextSetBit (0); bit >= 0; bit = channelBits.findNextSetBit (bit + 1)) + channelLayout.addChannel (static_cast (bit + 1)); + + // channel layout and number of channels do not match + jassert (channelLayout.size() == static_cast (numChannels)); ExtensibleWavSubFormat subFormat; subFormat.data1 = (uint32) input->readInt(); @@ -1198,15 +1224,25 @@ public: case 16: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; case 24: ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; case 32: if (usesFloatingPointData) ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); - else ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); break; + else ReadHelper::read (destSamples, startOffsetInDestBuffer, numDestChannels, sourceData, numChannels, numSamples); + break; default: jassertfalse; break; } } - int64 bwavChunkStart, bwavSize; - int64 dataChunkStart, dataLength; - int bytesPerFrame; - bool isRF64; + AudioChannelSet getChannelLayout() override + { + if (channelLayout.size() == static_cast (numChannels)) + return channelLayout; + + return WavFileHelpers::canonicalWavChannelSet (static_cast (numChannels)); + } + + int64 bwavChunkStart = 0, bwavSize = 0; + int64 dataChunkStart = 0, dataLength = 0; + int bytesPerFrame = 0; + bool isRF64 = false; + AudioChannelSet channelLayout; private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavAudioFormatReader) @@ -1217,12 +1253,9 @@ class WavAudioFormatWriter : public AudioFormatWriter { public: WavAudioFormatWriter (OutputStream* const out, const double rate, - const unsigned int numChans, const unsigned int bits, + const AudioChannelSet& channelLayoutToUse, const unsigned int bits, const StringPairArray& metadataValues) - : AudioFormatWriter (out, wavFormatName, rate, numChans, bits), - lengthInSamples (0), - bytesWritten (0), - writeFailed (false) + : AudioFormatWriter (out, wavFormatName, rate, channelLayoutToUse, bits) { using namespace WavFileHelpers; @@ -1291,7 +1324,7 @@ public: bool flush() override { - const int64 lastWritePos = output->getPosition(); + auto lastWritePos = output->getPosition(); writeHeader(); if (output->setPosition (lastWritePos)) @@ -1305,27 +1338,9 @@ public: private: MemoryBlock tempBlock, bwavChunk, axmlChunk, smplChunk, instChunk, cueChunk, listChunk, listInfoChunk, acidChunk, trckChunk; - uint64 lengthInSamples, bytesWritten; - int64 headerPosition; - bool writeFailed; - - static int getChannelMask (const int numChannels) noexcept - { - switch (numChannels) - { - case 1: return 0; - case 2: return 1 + 2; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT - case 3: return 1 + 2 + 4; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER - case 4: return 1 + 2 + 16 + 32; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT - case 5: return 1 + 2 + 4 + 16 + 32; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT - case 6: return 1 + 2 + 4 + 8 + 16 + 32; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT - case 7: return 1 + 2 + 4 + 16 + 32 + 512 + 1024; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT - case 8: return 1 + 2 + 4 + 8 + 16 + 32 + 512 + 1024; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT - default: break; - } - - return 0; - } + uint64 lengthInSamples = 0, bytesWritten = 0; + int64 headerPosition = 0; + bool writeFailed = false; void writeHeader() { @@ -1344,9 +1359,10 @@ private: const size_t bytesPerFrame = numChannels * bitsPerSample / 8; uint64 audioDataSize = bytesPerFrame * lengthInSamples; + auto channelMask = getChannelMaskFromChannelLayout (channelLayout); const bool isRF64 = (bytesWritten >= 0x100000000LL); - const bool isWaveFmtEx = isRF64 || (numChannels > 2); + const bool isWaveFmtEx = isRF64 || (channelMask != 0); int64 riffChunkSize = (int64) (4 /* 'RIFF' */ + 8 + 40 /* WAVEFORMATEX */ + 8 + audioDataSize + (audioDataSize & 1) @@ -1422,7 +1438,7 @@ private: { output->writeShort (22); // cbSize (size of the extension) output->writeShort ((short) bitsPerSample); // wValidBitsPerSample - output->writeInt (getChannelMask ((int) numChannels)); + output->writeInt (channelMask); const ExtensibleWavSubFormat& subFormat = bitsPerSample < 32 ? pcmFormat : IEEEFloatFormat; @@ -1464,6 +1480,30 @@ private: } } + static int getChannelMaskFromChannelLayout (const AudioChannelSet& channelLayout) + { + if (channelLayout.isDiscreteLayout()) + return 0; + + // Don't add an extended format chunk for mono and stereo. Basically, all wav players + // interpret a wav file with only one or two channels to be mono or stereo anyway. + if (channelLayout == AudioChannelSet::mono() || channelLayout == AudioChannelSet::stereo()) + return 0; + + auto channels = channelLayout.getChannelTypes(); + auto wavChannelMask = 0; + + for (auto channel : channels) + { + int wavChannelBit = static_cast (channel) - 1; + jassert (wavChannelBit >= 0 && wavChannelBit <= 31); + + wavChannelMask |= (1 << wavChannelBit); + } + + return wavChannelMask; + } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavAudioFormatWriter) }; @@ -1497,7 +1537,7 @@ public: void getSample (int64 sample, float* result) const noexcept override { - const int num = (int) numChannels; + auto num = (int) numChannels; if (map == nullptr || ! mappedSection.contains (sample)) { @@ -1507,8 +1547,8 @@ public: return; } - float** dest = &result; - const void* source = sampleToPointer (sample); + auto dest = &result; + auto source = sampleToPointer (sample); switch (bitsPerSample) { @@ -1516,7 +1556,8 @@ public: case 16: ReadHelper::read (dest, 0, 1, source, 1, num); break; case 24: ReadHelper::read (dest, 0, 1, source, 1, num); break; case 32: if (usesFloatingPointData) ReadHelper::read (dest, 0, 1, source, 1, num); - else ReadHelper::read (dest, 0, 1, source, 1, num); break; + else ReadHelper::read (dest, 0, 1, source, 1, num); + break; default: jassertfalse; break; } } @@ -1541,7 +1582,8 @@ public: case 16: scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); break; case 24: scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); break; case 32: if (usesFloatingPointData) scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); - else scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); break; + else scanMinAndMax (startSampleInFile, numSamples, results, numChannelsToRead); + break; default: jassertfalse; break; } } @@ -1579,6 +1621,22 @@ Array WavAudioFormat::getPossibleBitDepths() bool WavAudioFormat::canDoStereo() { return true; } bool WavAudioFormat::canDoMono() { return true; } +bool WavAudioFormat::isChannelLayoutSupported (const AudioChannelSet& channelSet) +{ + auto channelTypes = channelSet.getChannelTypes(); + + // When + if (channelSet.isDiscreteLayout()) + return true; + + // WAV supports all channel types from left ... topRearRight + for (auto channel : channelTypes) + if (channel < AudioChannelSet::left || channel > AudioChannelSet::topRearRight) + return false; + + return true; +} + AudioFormatReader* WavAudioFormat::createReaderFor (InputStream* sourceStream, const bool deleteStreamIfOpeningFails) { @@ -1613,10 +1671,21 @@ MemoryMappedAudioFormatReader* WavAudioFormat::createMemoryMappedReader (FileInp AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out, double sampleRate, unsigned int numChannels, int bitsPerSample, - const StringPairArray& metadataValues, int /*qualityOptionIndex*/) + const StringPairArray& metadataValues, int qualityOptionIndex) +{ + return createWriterFor (out, sampleRate, WavFileHelpers::canonicalWavChannelSet (static_cast (numChannels)), + bitsPerSample, metadataValues, qualityOptionIndex); +} + +AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out, + double sampleRate, + const AudioChannelSet& channelLayout, + int bitsPerSample, + const StringPairArray& metadataValues, + int /*qualityOptionIndex*/) { - if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample)) - return new WavAudioFormatWriter (out, sampleRate, (unsigned int) numChannels, + if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample) && isChannelLayoutSupported (channelLayout)) + return new WavAudioFormatWriter (out, sampleRate, channelLayout, (unsigned int) bitsPerSample, metadataValues); return nullptr; @@ -1627,21 +1696,15 @@ namespace WavFileHelpers static bool slowCopyWavFileWithNewMetadata (const File& file, const StringPairArray& metadata) { TemporaryFile tempFile (file); - WavAudioFormat wav; - ScopedPointer reader (wav.createReaderFor (file.createInputStream(), true)); - if (reader != nullptr) + if (ScopedPointer reader = wav.createReaderFor (file.createInputStream(), true)) { - ScopedPointer outStream (tempFile.getFile().createOutputStream()); - - if (outStream != nullptr) + if (ScopedPointer outStream = tempFile.getFile().createOutputStream()) { - ScopedPointer writer (wav.createWriterFor (outStream, reader->sampleRate, - reader->numChannels, (int) reader->bitsPerSample, - metadata, 0)); - - if (writer != nullptr) + if (ScopedPointer writer = wav.createWriterFor (outStream, reader->sampleRate, + reader->numChannels, (int) reader->bitsPerSample, + metadata, 0)) { outStream.release(); @@ -1661,12 +1724,11 @@ namespace WavFileHelpers bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata) { using namespace WavFileHelpers; - ScopedPointer reader (static_cast (createReaderFor (wavFile.createInputStream(), true))); - if (reader != nullptr) + if (ScopedPointer reader = static_cast (createReaderFor (wavFile.createInputStream(), true))) { - const int64 bwavPos = reader->bwavChunkStart; - const int64 bwavSize = reader->bwavSize; + auto bwavPos = reader->bwavChunkStart; + auto bwavSize = reader->bwavSize; reader = nullptr; if (bwavSize > 0) @@ -1676,7 +1738,7 @@ bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPai if (chunk.getSize() <= (size_t) bwavSize) { // the new one will fit in the space available, so write it directly.. - const int64 oldSize = wavFile.getSize(); + auto oldSize = wavFile.getSize(); { FileOutputStream out (wavFile); @@ -1702,9 +1764,8 @@ bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPai //============================================================================== #if JUCE_UNIT_TESTS -class WaveAudioFormatTests : public UnitTest +struct WaveAudioFormatTests : public UnitTest { -public: WaveAudioFormatTests() : UnitTest ("Wave audio format tests") {} void runTest() override @@ -1725,6 +1786,8 @@ public: if (metadataValues.size() > 0) metadataValues.set ("MetaDataSource", "WAV"); + metadataValues.addArray (createDefaultSMPLMetadata()); + WavAudioFormat format; MemoryBlock memoryBlock; @@ -1759,6 +1822,23 @@ private: numTestAudioBufferSamples = 256 }; + StringPairArray createDefaultSMPLMetadata() const + { + StringPairArray m; + + m.set ("Manufacturer", "0"); + m.set ("Product", "0"); + m.set ("SamplePeriod", "0"); + m.set ("MidiUnityNote", "60"); + m.set ("MidiPitchFraction", "0"); + m.set ("SmpteFormat", "0"); + m.set ("SmpteOffset", "0"); + m.set ("NumSampleLoops", "0"); + m.set ("SamplerData", "0"); + + return m; + } + JUCE_DECLARE_NON_COPYABLE (WaveAudioFormatTests) }; diff --git a/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h b/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h index 479e58bb0..e18e8e207 100644 --- a/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h +++ b/source/modules/juce_audio_formats/codecs/juce_WavAudioFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -92,6 +94,7 @@ public: static const char* const riffInfoBaseURL; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoCinematographer; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoComment; /**< Metadata property name used in INFO chunks. */ + static const char* const riffInfoComment2; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoComments; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoCommissioned; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoCopyright; /**< Metadata property name used in INFO chunks. */ @@ -132,6 +135,7 @@ public: static const char* const riffInfoOrganisation; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoPart; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoProducedBy; /**< Metadata property name used in INFO chunks. */ + static const char* const riffInfoProductName; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoProductionDesigner; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoProductionStudio; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoRate; /**< Metadata property name used in INFO chunks. */ @@ -157,6 +161,7 @@ public: static const char* const riffInfoThirdLanguage; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoTimeCode; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoTitle; /**< Metadata property name used in INFO chunks. */ + static const char* const riffInfoTrackNo; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoTrackNumber; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoURL; /**< Metadata property name used in INFO chunks. */ static const char* const riffInfoVegasVersionMajor; /**< Metadata property name used in INFO chunks. */ @@ -178,6 +183,7 @@ public: Array getPossibleBitDepths() override; bool canDoStereo() override; bool canDoMono() override; + bool isChannelLayoutSupported (const AudioChannelSet& channelSet) override; //============================================================================== AudioFormatReader* createReaderFor (InputStream* sourceStream, @@ -193,6 +199,13 @@ public: const StringPairArray& metadataValues, int qualityOptionIndex) override; + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + const AudioChannelSet& channelLayout, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex) override; + //============================================================================== /** Utility function to replace the metadata in a wav file with a new set of values. diff --git a/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp b/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp index cc22f41a0..6e75610d3 100644 --- a/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp +++ b/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h b/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h index 88cd4380a..39566f9ef 100644 --- a/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h +++ b/source/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h b/source/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h index 621747276..412ca7622 100644 --- a/source/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/os.h +++ b/source/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/source/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c b/source/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c index 83af2e887..3ce1337e7 100644 --- a/source/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c +++ b/source/modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c @@ -15,10 +15,15 @@ ********************************************************************/ -#ifdef JUCE_MSVC +#if JUCE_MSVC #pragma warning (disable: 4456 4457 4459) #endif +#if JUCE_GCC && __GNUC__ > 6 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wmisleading-indentation" +#endif + #include #include #include @@ -1561,7 +1566,7 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ if(op.granulepos!=-1){ vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2]; if(vf->pcm_offset<0)vf->pcm_offset=0; - vf->pcm_offset+=total; + vf->pcm_offset+=total; break; }else result=ogg_stream_packetout(&vf->os,NULL); @@ -1922,9 +1927,16 @@ long ov_read_filter(OggVorbis_File *vf,char *buffer,int length, vorbis_fpu_setround(&fpu); for(j=0;j= -1.0f ? f : -1.0f) : 1.0f); + val = vorbis_ftoi(f * 127.f); + #else val=vorbis_ftoi(pcm[i][j]*128.f); if(val>127)val=127; else if(val<-128)val=-128; + #endif *buffer++=val+off; } vorbis_fpu_restore(fpu); @@ -2340,3 +2352,7 @@ int ov_time_seek_lap(OggVorbis_File *vf,double pos){ int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){ return _ov_d_seek_lap(vf,pos,ov_time_seek_page); } + +#if JUCE_GCC && __GNUC__ > 6 + #pragma GCC diagnostic pop +#endif diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormat.cpp b/source/modules/juce_audio_formats/format/juce_AudioFormat.cpp index 0bbc6e520..a1cacb4b4 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormat.cpp +++ b/source/modules/juce_audio_formats/format/juce_AudioFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -48,7 +50,7 @@ bool AudioFormat::canHandleFile (const File& f) const String& AudioFormat::getFormatName() const { return formatName; } const StringArray& AudioFormat::getFileExtensions() const { return fileExtensions; } bool AudioFormat::isCompressed() { return false; } -StringArray AudioFormat::getQualityOptions() { return StringArray(); } +StringArray AudioFormat::getQualityOptions() { return {}; } MemoryMappedAudioFormatReader* AudioFormat::createMemoryMappedReader (const File&) { @@ -60,3 +62,26 @@ MemoryMappedAudioFormatReader* AudioFormat::createMemoryMappedReader (FileInputS delete fin; return nullptr; } + +bool AudioFormat::isChannelLayoutSupported (const AudioChannelSet& channelSet) +{ + if (channelSet == AudioChannelSet::mono()) return canDoMono(); + if (channelSet == AudioChannelSet::stereo()) return canDoStereo(); + + return false; +} + +AudioFormatWriter* AudioFormat::createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + const AudioChannelSet& channelLayout, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex) +{ + if (isChannelLayoutSupported (channelLayout)) + return createWriterFor (streamToWriteTo, sampleRateToUse, + static_cast (channelLayout.size()), + bitsPerSample, metadataValues, qualityOptionIndex); + + return nullptr; +} diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormat.h b/source/modules/juce_audio_formats/format/juce_AudioFormat.h index 4eb34535c..1db42e979 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormat.h +++ b/source/modules/juce_audio_formats/format/juce_AudioFormat.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOFORMAT_H_INCLUDED -#define JUCE_AUDIOFORMAT_H_INCLUDED +#pragma once //============================================================================== @@ -79,6 +80,9 @@ public: /** Returns true if the format uses compressed data. */ virtual bool isCompressed(); + /** Returns true if the channel layout is supported by this format. */ + virtual bool isChannelLayoutSupported (const AudioChannelSet& channelSet); + /** Returns a list of different qualities that can be used when writing. Non-compressed formats will just return an empty array, but for something @@ -153,6 +157,44 @@ public: const StringPairArray& metadataValues, int qualityOptionIndex) = 0; + /** Tries to create an object that can write to a stream with this audio format. + + The writer object that is returned can be used to write to the stream, and + should then be deleted by the caller. + + If the stream can't be created for some reason (e.g. the parameters passed in + here aren't suitable), this will return nullptr. + + @param streamToWriteTo the stream that the data will go to - this will be + deleted by the AudioFormatWriter object when it's no longer + needed. If no AudioFormatWriter can be created by this method, + the stream will NOT be deleted, so that the caller can re-use it + to try to open a different format, etc + @param sampleRateToUse the sample rate for the file, which must be one of the ones + returned by getPossibleSampleRates() + @param channelLayout the channel layout for the file. Use isChannelLayoutSupported + to check if the writer supports this layout. + @param bitsPerSample the bits per sample to use - this must be one of the values + returned by getPossibleBitDepths() + @param metadataValues a set of metadata values that the writer should try to write + to the stream. Exactly what these are depends on the format, + and the subclass doesn't actually have to do anything with + them if it doesn't want to. Have a look at the specific format + implementation classes to see possible values that can be + used + @param qualityOptionIndex the index of one of compression qualities returned by the + getQualityOptions() method. If there aren't any quality options + for this format, just pass 0 in this parameter, as it'll be + ignored + @see AudioFormatWriter + */ + virtual AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + const AudioChannelSet& channelLayout, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + protected: /** Creates an AudioFormat object. @@ -174,6 +216,3 @@ private: String formatName; StringArray fileExtensions; }; - - -#endif // JUCE_AUDIOFORMAT_H_INCLUDED diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp b/source/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp index 13b94784b..62406fea6 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp +++ b/source/modules/juce_audio_formats/format/juce_AudioFormatManager.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormatManager.h b/source/modules/juce_audio_formats/format/juce_AudioFormatManager.h index 2d30bd63f..7c2f9d4f5 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormatManager.h +++ b/source/modules/juce_audio_formats/format/juce_AudioFormatManager.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOFORMATMANAGER_H_INCLUDED -#define JUCE_AUDIOFORMATMANAGER_H_INCLUDED +#pragma once //============================================================================== @@ -112,8 +113,8 @@ public: /** Searches through the known formats to try to create a suitable reader for this file. - If none of the registered formats can open the file, it'll return 0. If it - returns a reader, it's the caller's responsibility to delete the reader. + If none of the registered formats can open the file, it'll return nullptr. + It's the caller's responsibility to delete the reader that is returned. */ AudioFormatReader* createReaderFor (const File& audioFile); @@ -138,6 +139,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatManager) }; - - -#endif // JUCE_AUDIOFORMATMANAGER_H_INCLUDED diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp b/source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp index 498c79e1e..ccd002a0f 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp +++ b/source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -363,6 +365,11 @@ int64 AudioFormatReader::searchForLevel (int64 startSample, return -1; } +AudioChannelSet AudioFormatReader::getChannelLayout() +{ + return AudioChannelSet::canonicalChannelSet (static_cast (numChannels)); +} + //============================================================================== MemoryMappedAudioFormatReader::MemoryMappedAudioFormatReader (const File& f, const AudioFormatReader& reader, int64 start, int64 length, int frameSize) diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormatReader.h b/source/modules/juce_audio_formats/format/juce_AudioFormatReader.h index 9a972cf27..8af863a8f 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormatReader.h +++ b/source/modules/juce_audio_formats/format/juce_AudioFormatReader.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOFORMATREADER_H_INCLUDED -#define JUCE_AUDIOFORMATREADER_H_INCLUDED +#pragma once //============================================================================== @@ -217,6 +218,9 @@ public: /** The input stream, for use by subclasses. */ InputStream* input; + //============================================================================== + /** Get the channel layout of the audio stream. */ + virtual AudioChannelSet getChannelLayout(); //============================================================================== /** Subclasses must implement this method to perform the low-level read operation. @@ -295,6 +299,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatReader) }; - - -#endif // JUCE_AUDIOFORMATREADER_H_INCLUDED diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp b/source/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp index 35ddeeb64..38c589304 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp +++ b/source/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h b/source/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h index c7f74bbb8..a44709ced 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h +++ b/source/modules/juce_audio_formats/format/juce_AudioFormatReaderSource.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOFORMATREADERSOURCE_H_INCLUDED -#define JUCE_AUDIOFORMATREADERSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -95,6 +96,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatReaderSource) }; - - -#endif // JUCE_AUDIOFORMATREADERSOURCE_H_INCLUDED diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp b/source/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp index 67d7a709f..febf8a325 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp +++ b/source/modules/juce_audio_formats/format/juce_AudioFormatWriter.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,6 +33,22 @@ AudioFormatWriter::AudioFormatWriter (OutputStream* const out, numChannels (numChannels_), bitsPerSample (bitsPerSample_), usesFloatingPointData (false), + channelLayout (AudioChannelSet::canonicalChannelSet(static_cast (numChannels_))), + output (out), + formatName (formatName_) +{ +} + +AudioFormatWriter::AudioFormatWriter (OutputStream* const out, + const String& formatName_, + const double rate, + const AudioChannelSet& channelLayout_, + const unsigned int bitsPerSample_) + : sampleRate (rate), + numChannels (static_cast (channelLayout_.size())), + bitsPerSample (bitsPerSample_), + usesFloatingPointData (false), + channelLayout (channelLayout_), output (out), formatName (formatName_) { diff --git a/source/modules/juce_audio_formats/format/juce_AudioFormatWriter.h b/source/modules/juce_audio_formats/format/juce_AudioFormatWriter.h index dac12af37..de8998931 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioFormatWriter.h +++ b/source/modules/juce_audio_formats/format/juce_AudioFormatWriter.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOFORMATWRITER_H_INCLUDED -#define JUCE_AUDIOFORMATWRITER_H_INCLUDED +#pragma once //============================================================================== @@ -61,6 +62,26 @@ protected: unsigned int numberOfChannels, unsigned int bitsPerSample); + //============================================================================== + /** Creates an AudioFormatWriter object. + + @param destStream the stream to write to - this will be deleted + by this object when it is no longer needed + @param formatName the description that will be returned by the getFormatName() + method + @param sampleRate the sample rate to use - the base class just stores + this value, it doesn't do anything with it + @param audioChannelLayout the channel layout to use for the writer - the base class + just stores this value, it doesn't do anything with it + @param bitsPerSample the bit depth of the stream - the base class just stores + this value, it doesn't do anything with it + */ + AudioFormatWriter (OutputStream* destStream, + const String& formatName, + double sampleRate, + const AudioChannelSet& audioChannelLayout, + unsigned int bitsPerSample); + public: /** Destructor. */ virtual ~AudioFormatWriter(); @@ -234,6 +255,9 @@ protected: /** True if it's a floating-point format, false if it's fixed-point. */ bool usesFloatingPointData; + /** The audio channel layout that the writer should use */ + AudioChannelSet channelLayout; + /** The output stream for use by subclasses. */ OutputStream* output; @@ -270,5 +294,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioFormatWriter) }; - -#endif // JUCE_AUDIOFORMATWRITER_H_INCLUDED diff --git a/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp b/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp index 9ca17249b..2ad71689d 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp +++ b/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h b/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h index 4293c45dc..63936138f 100644 --- a/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h +++ b/source/modules/juce_audio_formats/format/juce_AudioSubsectionReader.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOSUBSECTIONREADER_H_INCLUDED -#define JUCE_AUDIOSUBSECTIONREADER_H_INCLUDED +#pragma once //============================================================================== @@ -79,5 +80,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSubsectionReader) }; - -#endif // JUCE_AUDIOSUBSECTIONREADER_H_INCLUDED diff --git a/source/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp b/source/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp index ca1e6d8ed..da87e650d 100644 --- a/source/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp +++ b/source/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h b/source/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h index a8f595540..5bdd31218 100644 --- a/source/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h +++ b/source/modules/juce_audio_formats/format/juce_BufferingAudioFormatReader.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BUFFERINGAUDIOFORMATREADER_H_INCLUDED -#define JUCE_BUFFERINGAUDIOFORMATREADER_H_INCLUDED +#pragma once //============================================================================== /** @@ -88,6 +89,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferingAudioReader) }; - - -#endif // JUCE_BUFFERINGAUDIOFORMATREADER_H_INCLUDED diff --git a/source/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h b/source/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h index a63869bdd..93deee386 100644 --- a/source/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h +++ b/source/modules/juce_audio_formats/format/juce_MemoryMappedAudioFormatReader.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MEMORYMAPPEDAUDIOFORMATREADER_H_INCLUDED -#define JUCE_MEMORYMAPPEDAUDIOFORMATREADER_H_INCLUDED +#pragma once //============================================================================== @@ -62,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; } @@ -107,6 +108,3 @@ protected: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedAudioFormatReader) }; - - -#endif // JUCE_MEMORYMAPPEDAUDIOFORMATREADER_H_INCLUDED diff --git a/source/modules/juce_audio_formats/juce_audio_formats.cpp b/source/modules/juce_audio_formats/juce_audio_formats.cpp index 2494aa85f..ab3464dfc 100644 --- a/source/modules/juce_audio_formats/juce_audio_formats.cpp +++ b/source/modules/juce_audio_formats/juce_audio_formats.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,8 +33,6 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #define JUCE_CORE_INCLUDE_COM_SMART_PTR 1 #define JUCE_CORE_INCLUDE_JNI_HELPERS 1 #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 @@ -41,9 +41,6 @@ //============================================================================== #if JUCE_MAC - #if JUCE_QUICKTIME - #import - #endif #include #elif JUCE_IOS @@ -51,44 +48,14 @@ #import //============================================================================== -#elif JUCE_WINDOWS - #if JUCE_QUICKTIME - /* If you've got an include error here, you probably need to install the QuickTime SDK and - add its header directory to your include path. - - Alternatively, if you don't need any QuickTime services, just set the JUCE_QUICKTIME flag to 0. - */ - #include - #include - #include - #include - #include - - /* If you've got QuickTime 7 installed, then these COM objects should be found in - the "\Program Files\Quicktime" directory. You'll need to add this directory to - your include search path to make these import statements work. - */ - #import - #import - - #if JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - #pragma comment (lib, "QTMLClient.lib") - #endif - #endif - - #if JUCE_USE_WINDOWS_MEDIA_FORMAT - #include - #endif +#elif JUCE_WINDOWS && JUCE_USE_WINDOWS_MEDIA_FORMAT + #include #endif //============================================================================== namespace juce { -#if JUCE_ANDROID - #undef JUCE_QUICKTIME -#endif - #include "format/juce_AudioFormat.cpp" #include "format/juce_AudioFormatManager.cpp" #include "format/juce_AudioFormatReader.cpp" @@ -102,7 +69,6 @@ namespace juce #include "codecs/juce_FlacAudioFormat.cpp" #include "codecs/juce_MP3AudioFormat.cpp" #include "codecs/juce_OggVorbisAudioFormat.cpp" -#include "codecs/juce_QuickTimeAudioFormat.cpp" #include "codecs/juce_WavAudioFormat.cpp" #include "codecs/juce_LAMEEncoderAudioFormat.cpp" diff --git a/source/modules/juce_audio_formats/juce_audio_formats.h b/source/modules/juce_audio_formats/juce_audio_formats.h index 18d596328..deabf519c 100644 --- a/source/modules/juce_audio_formats/juce_audio_formats.h +++ b/source/modules/juce_audio_formats/juce_audio_formats.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -33,7 +35,7 @@ ID: juce_audio_formats vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE audio file format codecs description: Classes for reading and writing various audio file formats. website: http://www.juce.com/juce @@ -48,7 +50,7 @@ *******************************************************************************/ -#ifndef JUCE_AUDIO_FORMATS_H_INCLUDED +#pragma once #define JUCE_AUDIO_FORMATS_H_INCLUDED #include @@ -126,11 +128,8 @@ class AudioFormat; #include "codecs/juce_LAMEEncoderAudioFormat.h" #include "codecs/juce_MP3AudioFormat.h" #include "codecs/juce_OggVorbisAudioFormat.h" -#include "codecs/juce_QuickTimeAudioFormat.h" #include "codecs/juce_WavAudioFormat.h" #include "codecs/juce_WindowsMediaAudioFormat.h" #include "sampler/juce_Sampler.h" } - -#endif // JUCE_AUDIO_FORMATS_H_INCLUDED diff --git a/source/modules/juce_audio_formats/sampler/juce_Sampler.cpp b/source/modules/juce_audio_formats/sampler/juce_Sampler.cpp index d75989ff8..eab9b01c5 100644 --- a/source/modules/juce_audio_formats/sampler/juce_Sampler.cpp +++ b/source/modules/juce_audio_formats/sampler/juce_Sampler.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_formats/sampler/juce_Sampler.h b/source/modules/juce_audio_formats/sampler/juce_Sampler.h index 74a8afc5f..77df8e891 100644 --- a/source/modules/juce_audio_formats/sampler/juce_Sampler.h +++ b/source/modules/juce_audio_formats/sampler/juce_Sampler.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SAMPLER_H_INCLUDED -#define JUCE_SAMPLER_H_INCLUDED +#pragma once //============================================================================== @@ -141,6 +142,3 @@ private: JUCE_LEAK_DETECTOR (SamplerVoice) }; - - -#endif // JUCE_SAMPLER_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp b/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp index 029bf140e..720260de4 100644 --- a/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp +++ b/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -166,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, @@ -188,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/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.h b/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.h index e59b28c47..f82025789 100644 --- a/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.h +++ b/source/modules/juce_audio_processors/format/juce_AudioPluginFormat.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPLUGINFORMAT_H_INCLUDED -#define JUCE_AUDIOPLUGINFORMAT_H_INCLUDED +#pragma once //============================================================================== @@ -91,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. @@ -165,6 +164,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormat) }; - - -#endif // JUCE_AUDIOPLUGINFORMAT_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp b/source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp index a6f8f1e3b..d9e5551ce 100644 --- a/source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp +++ b/source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -38,7 +40,6 @@ namespace PluginFormatManagerHelpers ScopedPointer callback; }; - #if JUCE_COMPILER_SUPPORTS_LAMBDAS struct ErrorLambdaOnMessageThread : public CallbackMessage { ErrorLambdaOnMessageThread (const String& inError, @@ -52,7 +53,6 @@ namespace PluginFormatManagerHelpers String error; std::function lambda; }; - #endif } AudioPluginFormatManager::AudioPluginFormatManager() {} @@ -137,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, @@ -150,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/source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h b/source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h index 65e563f75..0be2c06b5 100644 --- a/source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h +++ b/source/modules/juce_audio_processors/format/juce_AudioPluginFormatManager.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPLUGINFORMATMANAGER_H_INCLUDED -#define JUCE_AUDIOPLUGINFORMATMANAGER_H_INCLUDED +#pragma once //============================================================================== @@ -113,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. @@ -135,7 +134,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormatManager) }; - - - -#endif // JUCE_AUDIOPLUGINFORMATMANAGER_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format_types/juce_AU_Shared.h b/source/modules/juce_audio_processors/format_types/juce_AU_Shared.h index 1b5602819..71768e3b4 100644 --- a/source/modules/juce_audio_processors/format_types/juce_AU_Shared.h +++ b/source/modules/juce_audio_processors/format_types/juce_AU_Shared.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -29,293 +31,6 @@ struct AudioUnitHelpers { - // maps a channel index into an AU format to an index of a juce format - struct AUChannelStreamOrder - { - AudioChannelLayoutTag auLayoutTag; - AudioChannelSet::ChannelType speakerOrder[8]; - }; - - struct StreamOrder : public AudioChannelSet - { - static AUChannelStreamOrder auChannelStreamOrder[]; - }; - - static AudioChannelSet::ChannelType CoreAudioChannelLabelToJuceType (AudioChannelLabel label) noexcept - { - if (label >= kAudioChannelLabel_Discrete_0 && label <= kAudioChannelLabel_Discrete_65535) - { - const unsigned int discreteChannelNum = label - kAudioChannelLabel_Discrete_0; - return static_cast (AudioChannelSet::discreteChannel0 + discreteChannelNum); - } - - switch (label) - { - case kAudioChannelLabel_Center: - case kAudioChannelLabel_Mono: return AudioChannelSet::centre; - case kAudioChannelLabel_Left: - case kAudioChannelLabel_HeadphonesLeft: return AudioChannelSet::left; - case kAudioChannelLabel_Right: - case kAudioChannelLabel_HeadphonesRight: return AudioChannelSet::right; - case kAudioChannelLabel_LFEScreen: return AudioChannelSet::LFE; - case kAudioChannelLabel_LeftSurround: return AudioChannelSet::leftSurround; - case kAudioChannelLabel_RightSurround: return AudioChannelSet::rightSurround; - case kAudioChannelLabel_LeftCenter: return AudioChannelSet::leftCentre; - case kAudioChannelLabel_RightCenter: return AudioChannelSet::rightCentre; - case kAudioChannelLabel_CenterSurround: return AudioChannelSet::surround; - case kAudioChannelLabel_LeftSurroundDirect: return AudioChannelSet::leftSurroundSide; - case kAudioChannelLabel_RightSurroundDirect: return AudioChannelSet::rightSurroundSide; - case kAudioChannelLabel_TopCenterSurround: return AudioChannelSet::topMiddle; - case kAudioChannelLabel_VerticalHeightLeft: return AudioChannelSet::topFrontLeft; - case kAudioChannelLabel_VerticalHeightRight: return AudioChannelSet::topFrontRight; - case kAudioChannelLabel_VerticalHeightCenter: return AudioChannelSet::topFrontCentre; - case kAudioChannelLabel_TopBackLeft: return AudioChannelSet::topRearLeft; - case kAudioChannelLabel_RearSurroundLeft: return AudioChannelSet::leftSurroundRear; - case kAudioChannelLabel_TopBackRight: return AudioChannelSet::topRearRight; - case kAudioChannelLabel_RearSurroundRight: return AudioChannelSet::rightSurroundRear; - case kAudioChannelLabel_TopBackCenter: return AudioChannelSet::topRearCentre; - case kAudioChannelLabel_LFE2: return AudioChannelSet::LFE2; - case kAudioChannelLabel_LeftWide: return AudioChannelSet::wideLeft; - case kAudioChannelLabel_RightWide: return AudioChannelSet::wideRight; - case kAudioChannelLabel_Ambisonic_W: return AudioChannelSet::ambisonicW; - case kAudioChannelLabel_Ambisonic_X: return AudioChannelSet::ambisonicX; - case kAudioChannelLabel_Ambisonic_Y: return AudioChannelSet::ambisonicY; - case kAudioChannelLabel_Ambisonic_Z: return AudioChannelSet::ambisonicZ; - default: return AudioChannelSet::unknown; - } - } - - static AudioChannelLabel JuceChannelTypeToCoreAudioLabel (const AudioChannelSet::ChannelType& label) noexcept - { - if (label >= AudioChannelSet::discreteChannel0) - { - const unsigned int discreteChannelNum = label - AudioChannelSet::discreteChannel0;; - return static_cast (kAudioChannelLabel_Discrete_0 + discreteChannelNum); - } - - switch (label) - { - case AudioChannelSet::centre: return kAudioChannelLabel_Center; - case AudioChannelSet::left: return kAudioChannelLabel_Left; - case AudioChannelSet::right: return kAudioChannelLabel_Right; - case AudioChannelSet::LFE: return kAudioChannelLabel_LFEScreen; - case AudioChannelSet::leftSurroundRear: return kAudioChannelLabel_RearSurroundLeft; - case AudioChannelSet::rightSurroundRear: return kAudioChannelLabel_RearSurroundRight; - case AudioChannelSet::leftCentre: return kAudioChannelLabel_LeftCenter; - case AudioChannelSet::rightCentre: return kAudioChannelLabel_RightCenter; - case AudioChannelSet::surround: return kAudioChannelLabel_CenterSurround; - case AudioChannelSet::leftSurround: return kAudioChannelLabel_LeftSurround; - case AudioChannelSet::rightSurround: return kAudioChannelLabel_RightSurround; - case AudioChannelSet::topMiddle: return kAudioChannelLabel_TopCenterSurround; - case AudioChannelSet::topFrontLeft: return kAudioChannelLabel_VerticalHeightLeft; - case AudioChannelSet::topFrontRight: return kAudioChannelLabel_VerticalHeightRight; - case AudioChannelSet::topFrontCentre: return kAudioChannelLabel_VerticalHeightCenter; - case AudioChannelSet::topRearLeft: return kAudioChannelLabel_TopBackLeft; - case AudioChannelSet::topRearRight: return kAudioChannelLabel_TopBackRight; - case AudioChannelSet::topRearCentre: return kAudioChannelLabel_TopBackCenter; - case AudioChannelSet::LFE2: return kAudioChannelLabel_LFE2; - case AudioChannelSet::wideLeft: return kAudioChannelLabel_LeftWide; - case AudioChannelSet::wideRight: return kAudioChannelLabel_RightWide; - case AudioChannelSet::ambisonicW: return kAudioChannelLabel_Ambisonic_W; - case AudioChannelSet::ambisonicX: return kAudioChannelLabel_Ambisonic_X; - case AudioChannelSet::ambisonicY: return kAudioChannelLabel_Ambisonic_Y; - case AudioChannelSet::ambisonicZ: return kAudioChannelLabel_Ambisonic_Z; - case AudioChannelSet::leftSurroundSide: return kAudioChannelLabel_LeftSurroundDirect; - case AudioChannelSet::rightSurroundSide: return kAudioChannelLabel_RightSurroundDirect; - case AudioChannelSet::unknown: return kAudioChannelLabel_Unknown; - case AudioChannelSet::discreteChannel0: return kAudioChannelLabel_Discrete_0; - } - - return kAudioChannelLabel_Unknown; - } - - static AudioChannelSet CoreAudioChannelBitmapToJuceType (UInt32 bitmap) noexcept - { - AudioChannelSet set; - - if ((bitmap & kAudioChannelBit_Left) != 0) set.addChannel (AudioChannelSet::left); - if ((bitmap & kAudioChannelBit_Right) != 0) set.addChannel (AudioChannelSet::right); - if ((bitmap & kAudioChannelBit_Center) != 0) set.addChannel (AudioChannelSet::centre); - if ((bitmap & kAudioChannelBit_LFEScreen) != 0) set.addChannel (AudioChannelSet::LFE); - if ((bitmap & kAudioChannelBit_LeftSurroundDirect) != 0) set.addChannel (AudioChannelSet::leftSurroundSide); - if ((bitmap & kAudioChannelBit_RightSurroundDirect) != 0) set.addChannel (AudioChannelSet::rightSurroundSide); - if ((bitmap & kAudioChannelBit_LeftCenter) != 0) set.addChannel (AudioChannelSet::leftCentre); - if ((bitmap & kAudioChannelBit_RightCenter) != 0) set.addChannel (AudioChannelSet::rightCentre); - if ((bitmap & kAudioChannelBit_CenterSurround) != 0) set.addChannel (AudioChannelSet::surround); - if ((bitmap & kAudioChannelBit_LeftSurround) != 0) set.addChannel (AudioChannelSet::leftSurround); - if ((bitmap & kAudioChannelBit_RightSurround) != 0) set.addChannel (AudioChannelSet::rightSurround); - if ((bitmap & kAudioChannelBit_TopCenterSurround) != 0) set.addChannel (AudioChannelSet::topMiddle); - if ((bitmap & kAudioChannelBit_VerticalHeightLeft) != 0) set.addChannel (AudioChannelSet::topFrontLeft); - if ((bitmap & kAudioChannelBit_VerticalHeightCenter) != 0) set.addChannel (AudioChannelSet::topFrontCentre); - if ((bitmap & kAudioChannelBit_VerticalHeightRight) != 0) set.addChannel (AudioChannelSet::topFrontRight); - if ((bitmap & kAudioChannelBit_TopBackLeft) != 0) set.addChannel (AudioChannelSet::topRearLeft); - if ((bitmap & kAudioChannelBit_TopBackCenter) != 0) set.addChannel (AudioChannelSet::topRearCentre); - if ((bitmap & kAudioChannelBit_TopBackRight) != 0) set.addChannel (AudioChannelSet::topRearRight); - - return set; - } - - static AudioChannelSet CoreAudioChannelLayoutToJuceType (const AudioChannelLayout& layout) noexcept - { - const AudioChannelLayoutTag tag = layout.mChannelLayoutTag; - - if (tag == kAudioChannelLayoutTag_UseChannelBitmap) return CoreAudioChannelBitmapToJuceType (layout.mChannelBitmap); - if (tag == kAudioChannelLayoutTag_UseChannelDescriptions) - { - if (layout.mNumberChannelDescriptions <= 8) - { - // first try to convert the layout via the auChannelStreamOrder array - int layoutIndex; - for (layoutIndex = 0; StreamOrder::auChannelStreamOrder[layoutIndex].auLayoutTag != 0; ++layoutIndex) - { - const AUChannelStreamOrder& streamOrder = StreamOrder::auChannelStreamOrder[layoutIndex]; - - int numChannels; - for (numChannels = 0; numChannels < 8 && streamOrder.speakerOrder[numChannels] != 0;) - ++numChannels; - - if (numChannels != (int) layout.mNumberChannelDescriptions) - continue; - - int ch; - for (ch = 0; ch < numChannels; ++ch) - if (JuceChannelTypeToCoreAudioLabel (streamOrder.speakerOrder[ch]) != layout.mChannelDescriptions[ch].mChannelLabel) - break; - - // match! - if (ch == numChannels) - break; - } - - if (StreamOrder::auChannelStreamOrder[layoutIndex].auLayoutTag != 0) - return CALayoutTagToChannelSet (StreamOrder::auChannelStreamOrder[layoutIndex].auLayoutTag); - } - AudioChannelSet set; - for (unsigned int i = 0; i < layout.mNumberChannelDescriptions; ++i) - set.addChannel (CoreAudioChannelLabelToJuceType (layout.mChannelDescriptions[i].mChannelLabel)); - - return set; - } - - return CALayoutTagToChannelSet (tag); - } - - static AudioChannelSet CALayoutTagToChannelSet (AudioChannelLayoutTag tag) noexcept - { - switch (tag) - { - case kAudioChannelLayoutTag_Unknown: return AudioChannelSet::disabled(); - case kAudioChannelLayoutTag_Mono: return AudioChannelSet::mono(); - case kAudioChannelLayoutTag_Stereo: - case kAudioChannelLayoutTag_StereoHeadphones: - case kAudioChannelLayoutTag_Binaural: return AudioChannelSet::stereo(); - case kAudioChannelLayoutTag_Quadraphonic: return AudioChannelSet::quadraphonic(); - case kAudioChannelLayoutTag_Pentagonal: return AudioChannelSet::pentagonal(); - case kAudioChannelLayoutTag_Hexagonal: return AudioChannelSet::hexagonal(); - case kAudioChannelLayoutTag_Octagonal: return AudioChannelSet::octagonal(); - case kAudioChannelLayoutTag_Ambisonic_B_Format: return AudioChannelSet::ambisonic(); - case kAudioChannelLayoutTag_AudioUnit_6_0: return AudioChannelSet::create6point0(); - case kAudioChannelLayoutTag_DTS_6_0_A: return AudioChannelSet::create6point0Music(); - case kAudioChannelLayoutTag_MPEG_6_1_A: return AudioChannelSet::create6point1(); - case kAudioChannelLayoutTag_DTS_6_1_A: return AudioChannelSet::create6point1Music(); - case kAudioChannelLayoutTag_MPEG_5_0_B: - case kAudioChannelLayoutTag_MPEG_5_0_A: - return AudioChannelSet::create5point0(); - case kAudioChannelLayoutTag_MPEG_5_1_A: return AudioChannelSet::create5point1(); - case kAudioChannelLayoutTag_DTS_7_1: - case kAudioChannelLayoutTag_AudioUnit_7_0: return AudioChannelSet::create7point0(); - case kAudioChannelLayoutTag_AudioUnit_7_0_Front: return AudioChannelSet::create7point0SDDS(); - case kAudioChannelLayoutTag_MPEG_7_1_A: return AudioChannelSet::create7point1SDDS(); - case kAudioChannelLayoutTag_MPEG_3_0_A: - case kAudioChannelLayoutTag_MPEG_3_0_B: return AudioChannelSet::createLCR(); - case kAudioChannelLayoutTag_MPEG_4_0_A: - case kAudioChannelLayoutTag_MPEG_4_0_B: return AudioChannelSet::createLCRS(); - case kAudioChannelLayoutTag_ITU_2_1: return AudioChannelSet::createLRS(); - case kAudioChannelLayoutTag_MPEG_7_1_C: return AudioChannelSet::create7point1(); - } - - if (int numChannels = static_cast (tag) & 0xffff) - return AudioChannelSet::discreteChannels (numChannels); - - // Bitmap and channel description array layout tags are currently unsupported :-( - jassertfalse; - return AudioChannelSet(); - } - - static AudioChannelLayoutTag ChannelSetToCALayoutTag (const AudioChannelSet& set) noexcept - { - if (set == AudioChannelSet::mono()) return kAudioChannelLayoutTag_Mono; - if (set == AudioChannelSet::stereo()) return kAudioChannelLayoutTag_Stereo; - if (set == AudioChannelSet::createLCR()) return kAudioChannelLayoutTag_MPEG_3_0_A; - if (set == AudioChannelSet::createLRS()) return kAudioChannelLayoutTag_ITU_2_1; - if (set == AudioChannelSet::createLCRS()) return kAudioChannelLayoutTag_MPEG_4_0_A; - if (set == AudioChannelSet::quadraphonic()) return kAudioChannelLayoutTag_Quadraphonic; - if (set == AudioChannelSet::pentagonal()) return kAudioChannelLayoutTag_Pentagonal; - if (set == AudioChannelSet::hexagonal()) return kAudioChannelLayoutTag_Hexagonal; - if (set == AudioChannelSet::octagonal()) return kAudioChannelLayoutTag_Octagonal; - if (set == AudioChannelSet::ambisonic()) return kAudioChannelLayoutTag_Ambisonic_B_Format; - if (set == AudioChannelSet::create5point0()) return kAudioChannelLayoutTag_MPEG_5_0_A; - if (set == AudioChannelSet::create5point1()) return kAudioChannelLayoutTag_MPEG_5_1_A; - if (set == AudioChannelSet::create6point0()) return kAudioChannelLayoutTag_AudioUnit_6_0; - if (set == AudioChannelSet::create6point0Music()) return kAudioChannelLayoutTag_DTS_6_0_A; - if (set == AudioChannelSet::create6point1Music()) return kAudioChannelLayoutTag_DTS_6_1_A; - if (set == AudioChannelSet::create6point1()) return kAudioChannelLayoutTag_MPEG_6_1_A; - if (set == AudioChannelSet::create7point0()) return kAudioChannelLayoutTag_AudioUnit_7_0; - if (set == AudioChannelSet::create7point1()) return kAudioChannelLayoutTag_MPEG_7_1_C; - if (set == AudioChannelSet::create7point0SDDS()) return kAudioChannelLayoutTag_AudioUnit_7_0_Front; - if (set == AudioChannelSet::create7point1SDDS()) return kAudioChannelLayoutTag_MPEG_7_1_A; - if (set == AudioChannelSet::disabled()) return kAudioChannelLayoutTag_Unknown; - - return static_cast ((int) kAudioChannelLayoutTag_DiscreteInOrder | set.size()); - } - - static int auChannelIndexToJuce (int auIndex, const AudioChannelSet& channelSet) - { - if (auIndex >= 8) return auIndex; - - AudioChannelLayoutTag currentLayout = ChannelSetToCALayoutTag (channelSet); - - int layoutIndex; - for (layoutIndex = 0; StreamOrder::auChannelStreamOrder[layoutIndex].auLayoutTag != currentLayout; ++layoutIndex) - if (StreamOrder::auChannelStreamOrder[layoutIndex].auLayoutTag == 0) return auIndex; - - AudioChannelSet::ChannelType channelType - = StreamOrder::auChannelStreamOrder[layoutIndex].speakerOrder[auIndex]; - - const int juceIndex = channelSet.getChannelTypes().indexOf (channelType); - - jassert (juceIndex >= 0); - return juceIndex >= 0 ? juceIndex : auIndex; - } - - static int juceChannelIndexToAu (int juceIndex, const AudioChannelSet& channelSet) - { - if (channelSet.isDiscreteLayout()) - return juceIndex; - - AudioChannelLayoutTag currentLayout = ChannelSetToCALayoutTag (channelSet); - - int layoutIndex; - for (layoutIndex = 0; StreamOrder::auChannelStreamOrder[layoutIndex].auLayoutTag != currentLayout; ++layoutIndex) - { - if (StreamOrder::auChannelStreamOrder[layoutIndex].auLayoutTag == 0) - { - jassertfalse; - return juceIndex; - } - } - - const AUChannelStreamOrder& channelOrder = StreamOrder::auChannelStreamOrder[layoutIndex]; - AudioChannelSet::ChannelType channelType = channelSet.getTypeOfChannel (juceIndex); - - for (int i = 0; i < 8 && channelOrder.speakerOrder[i] != 0; ++i) - if (channelOrder.speakerOrder[i] == channelType) - return i; - - jassertfalse; - return juceIndex; - } - class ChannelRemapper { public: @@ -382,11 +97,17 @@ struct AudioUnitHelpers void fillLayoutChannelMaps (bool isInput, int busNr) { int* layoutMap = (isInput ? inputLayoutMap : outputLayoutMap)[busNr]; - const AudioChannelSet& channelFormat = processor.getChannelLayoutOfBus (isInput, busNr); + auto channelFormat = processor.getChannelLayoutOfBus (isInput, busNr); + AudioChannelLayout coreAudioLayout; + + zerostruct (coreAudioLayout); + coreAudioLayout.mChannelLayoutTag = CoreAudioLayouts::toCoreAudio (channelFormat); + const int numChannels = channelFormat.size(); + auto coreAudioChannels = CoreAudioLayouts::getCoreAudioLayoutChannels (coreAudioLayout); for (int i = 0; i < numChannels; ++i) - layoutMap[i] = AudioUnitHelpers::juceChannelIndexToAu (i, channelFormat); + layoutMap[i] = coreAudioChannels.indexOf (channelFormat.getTypeOfChannel (i)); } }; @@ -611,8 +332,8 @@ struct AudioUnitHelpers { Array channelInfo; - const bool hasMainInputBus = (AudioUnitHelpers::getBusCount (&processor, true) > 0); - const bool hasMainOutputBus = (AudioUnitHelpers::getBusCount (&processor, false) > 0); + auto hasMainInputBus = (AudioUnitHelpers::getBusCount (&processor, true) > 0); + auto hasMainOutputBus = (AudioUnitHelpers::getBusCount (&processor, false) > 0); if ((! hasMainInputBus) && (! hasMainOutputBus)) { @@ -621,73 +342,48 @@ struct AudioUnitHelpers info.inChannels = 0; info.outChannels = 0; - channelInfo.add (info); - return channelInfo; + return {&info, 1}; } else { - const uint32_t maxNumChanToCheckFor = 9; - - uint32_t defaultInputs = static_cast (processor.getChannelCountOfBus (true, 0)); - uint32_t defaultOutputs = static_cast (processor.getChannelCountOfBus (false, 0)); + auto layout = processor.getBusesLayout(); + auto maxNumChanToCheckFor = 9; - uint32_t lastInputs = defaultInputs; - uint32_t lastOutputs = defaultOutputs; + auto defaultInputs = processor.getChannelCountOfBus (true, 0); + auto defaultOutputs = processor.getChannelCountOfBus (false, 0); - SortedSet supportedChannels; + SortedSet supportedChannels; // add the current configuration - if (lastInputs != 0 || lastOutputs != 0) - supportedChannels.add ((lastInputs << 16) | lastOutputs); + if (defaultInputs != 0 || defaultOutputs != 0) + supportedChannels.add ((defaultInputs << 16) | defaultOutputs); - for (uint32_t inChanNum = hasMainInputBus ? 1 : 0; inChanNum <= (hasMainInputBus ? maxNumChanToCheckFor : 0); ++inChanNum) + for (auto inChanNum = hasMainInputBus ? 1 : 0; inChanNum <= (hasMainInputBus ? maxNumChanToCheckFor : 0); ++inChanNum) { - const AudioProcessor::Bus* inBus = processor.getBus (true, 0); - - if (inBus != nullptr && (! inBus->isNumberOfChannelsSupported ((int) inChanNum))) - continue; + auto inLayout = layout; - for (uint32_t outChanNum = hasMainOutputBus ? 1 : 0; outChanNum <= (hasMainOutputBus ? maxNumChanToCheckFor : 0); ++outChanNum) - { - const AudioProcessor::Bus* outBus = processor.getBus (false, 0); - - if (outBus != nullptr && (! outBus->isNumberOfChannelsSupported ((int) outChanNum))) + if (auto* inBus = processor.getBus (true, 0)) + if (! isNumberOfChannelsSupported (inBus, inChanNum, inLayout)) continue; - uint32_t channelConfiguration = (inChanNum << 16) | outChanNum; - - // did we already try this configuration? - if (supportedChannels.contains (channelConfiguration)) continue; - - if (lastInputs != inChanNum && (inChanNum > 0 && inBus != nullptr)) - { - AudioChannelSet set = inBus->supportedLayoutWithChannels ((int) inChanNum); - AudioProcessor::BusesLayout layouts = inBus->getBusesLayoutForLayoutChangeOfBus (set); - - lastInputs = inChanNum; - lastOutputs = hasMainOutputBus ? static_cast (layouts.outputBuses.getReference (0).size()) : 0; - - supportedChannels.add ((lastInputs << 16) | lastOutputs); - } - - if (lastOutputs != outChanNum && (outChanNum > 0 && outBus != nullptr)) - { - AudioChannelSet set = outBus->supportedLayoutWithChannels ((int) outChanNum); - AudioProcessor::BusesLayout layouts = outBus->getBusesLayoutForLayoutChangeOfBus (set); + for (auto outChanNum = hasMainOutputBus ? 1 : 0; outChanNum <= (hasMainOutputBus ? maxNumChanToCheckFor : 0); ++outChanNum) + { + auto outLayout = inLayout; - lastOutputs = outChanNum; - lastInputs = hasMainInputBus ? static_cast (layouts.inputBuses.getReference (0).size()) : 0; + if (auto* outBus = processor.getBus (false, 0)) + if (! isNumberOfChannelsSupported (outBus, outChanNum, outLayout)) + continue; - supportedChannels.add ((lastInputs << 16) | lastOutputs); - } + supportedChannels.add (((hasMainInputBus ? outLayout.getMainInputChannels() : 0) << 16) + | (hasMainOutputBus ? outLayout.getMainOutputChannels() : 0)); } } - bool hasInOutMismatch = false; - for (int i = 0; i < supportedChannels.size(); ++i) + auto hasInOutMismatch = false; + for (auto supported : supportedChannels) { - const uint32_t numInputs = (supportedChannels[i] >> 16) & 0xffff; - const uint32_t numOutputs = (supportedChannels[i] >> 0) & 0xffff; + auto numInputs = (supported >> 16) & 0xffff; + auto numOutputs = (supported >> 0) & 0xffff; if (numInputs != numOutputs) { @@ -696,10 +392,11 @@ struct AudioUnitHelpers } } - bool hasUnsupportedInput = ! hasMainOutputBus, hasUnsupportedOutput = ! hasMainInputBus; - for (uint32_t inChanNum = hasMainInputBus ? 1 : 0; inChanNum <= (hasMainInputBus ? maxNumChanToCheckFor : 0); ++inChanNum) + auto hasUnsupportedInput = ! hasMainInputBus, hasUnsupportedOutput = ! hasMainOutputBus; + for (auto inChanNum = hasMainInputBus ? 1 : 0; inChanNum <= (hasMainInputBus ? maxNumChanToCheckFor : 0); ++inChanNum) { - uint32_t channelConfiguration = (inChanNum << 16) | (hasInOutMismatch ? defaultOutputs : inChanNum); + auto channelConfiguration = (inChanNum << 16) | (hasInOutMismatch ? defaultOutputs : inChanNum); + if (! supportedChannels.contains (channelConfiguration)) { hasUnsupportedInput = true; @@ -707,9 +404,10 @@ struct AudioUnitHelpers } } - for (uint32_t outChanNum = hasMainOutputBus ? 1 : 0; outChanNum <= (hasMainOutputBus ? maxNumChanToCheckFor : 0); ++outChanNum) + for (auto outChanNum = hasMainOutputBus ? 1 : 0; outChanNum <= (hasMainOutputBus ? maxNumChanToCheckFor : 0); ++outChanNum) { - uint32_t channelConfiguration = ((hasInOutMismatch ? defaultInputs : outChanNum) << 16) | outChanNum; + auto channelConfiguration = ((hasInOutMismatch ? defaultInputs : outChanNum) << 16) | outChanNum; + if (! supportedChannels.contains (channelConfiguration)) { hasUnsupportedOutput = true; @@ -717,10 +415,10 @@ struct AudioUnitHelpers } } - for (int i = 0; i < supportedChannels.size(); ++i) + for (auto supported : supportedChannels) { - const int numInputs = (supportedChannels[i] >> 16) & 0xffff; - const int numOutputs = (supportedChannels[i] >> 0) & 0xffff; + auto numInputs = (supported >> 16) & 0xffff; + auto numOutputs = (supported >> 0) & 0xffff; AUChannelInfo info; @@ -733,7 +431,8 @@ struct AudioUnitHelpers int j; for (j = 0; j < channelInfo.size(); ++j) - if (channelInfo[j].inChannels == info.inChannels && channelInfo[j].outChannels == info.outChannels) + if (info.inChannels == channelInfo.getReference (j).inChannels + && info.outChannels == channelInfo.getReference (j).outChannels) break; if (j >= channelInfo.size()) @@ -744,6 +443,25 @@ struct AudioUnitHelpers return channelInfo; } + static bool isNumberOfChannelsSupported (const AudioProcessor::Bus* b, int numChannels, AudioProcessor::BusesLayout& inOutCurrentLayout) + { + auto potentialSets = AudioChannelSet::channelSetsWithNumberOfChannels (static_cast (numChannels)); + + + for (auto set : potentialSets) + { + auto copy = inOutCurrentLayout; + + if (b->isLayoutSupported (set, ©)) + { + inOutCurrentLayout = copy; + return true; + } + } + + return false; + } + //============================================================================== static int getBusCount (const AudioProcessor* juceFilter, bool isInput) { @@ -811,35 +529,3 @@ struct AudioUnitHelpers #endif } }; - -AudioUnitHelpers::AUChannelStreamOrder AudioUnitHelpers::StreamOrder::auChannelStreamOrder[] = -{ - {kAudioChannelLayoutTag_Mono, {centre, unknown, unknown, unknown, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_Stereo, {left, right, unknown, unknown, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_StereoHeadphones, {left, right, unknown, unknown, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_Binaural, {left, right, unknown, unknown, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_Quadraphonic, {left, right, leftSurround, rightSurround, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_Pentagonal, {left, right, leftSurroundRear, rightSurroundRear, centre, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_Hexagonal, {left, right, leftSurroundRear, rightSurroundRear, centre, centreSurround, unknown, unknown}}, - {kAudioChannelLayoutTag_Octagonal, {left, right, leftSurround, rightSurround, centre, centreSurround, wideLeft, wideRight}}, - {kAudioChannelLayoutTag_Ambisonic_B_Format, {ambisonicW, ambisonicX, ambisonicY, ambisonicZ, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_MPEG_5_0_A, {left, right, centre, leftSurround, rightSurround, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_MPEG_5_0_B, {left, right, leftSurround, rightSurround, centre, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_MPEG_5_1_A, {left, right, centre, LFE, leftSurround, rightSurround, unknown, unknown}}, - {kAudioChannelLayoutTag_AudioUnit_6_0, {left, right, leftSurround, rightSurround, centre, centreSurround, unknown, unknown}}, - {kAudioChannelLayoutTag_DTS_6_0_A, {left, right, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide, unknown, unknown}}, // TODO check this one - {kAudioChannelLayoutTag_MPEG_6_1_A, {left, right, centre, LFE, leftSurround, rightSurround, centre, unknown}}, - {kAudioChannelLayoutTag_DTS_6_1_A, {leftSurroundSide, rightSurroundSide, left, right, leftSurround, rightSurround, LFE, unknown}}, - {kAudioChannelLayoutTag_AudioUnit_7_0, {left, right, leftSurroundSide, rightSurroundSide, centre, leftSurroundRear, rightSurroundRear, unknown}}, - {kAudioChannelLayoutTag_MPEG_7_1_C, {left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear}}, - {kAudioChannelLayoutTag_AudioUnit_7_0_Front,{left, right, leftSurround, rightSurround, centre, leftCentre, rightCentre, unknown}}, - {kAudioChannelLayoutTag_MPEG_7_1_A, {left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre}}, - {kAudioChannelLayoutTag_DTS_7_1, {leftCentre, centre, rightCentre, left, right, leftSurround, rightSurround, LFE}}, - {kAudioChannelLayoutTag_MPEG_3_0_A, {left, right, centre, unknown, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_MPEG_3_0_B, {centre, left, right, unknown, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_MPEG_4_0_A, {left, right, centre, centreSurround, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_MPEG_4_0_B, {centre, left, right, centreSurround, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_ITU_2_1, {left, right, centreSurround, unknown, unknown, unknown, unknown, unknown}}, - {kAudioChannelLayoutTag_EAC3_7_1_C, {left, centre, right, leftSurround, rightSurround, LFE, leftSurroundSide, rightSurroundSide}}, - {unknown, {unknown,unknown,unknown,unknown,unknown,unknown,unknown,unknown}} -}; diff --git a/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h b/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h index 5aed3fe4b..9ade640df 100644 --- a/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h +++ b/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index 6fcd01038..457d10835 100644 --- a/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -64,6 +66,7 @@ namespace juce #include "../../juce_core/native/juce_osx_ObjCHelpers.h" +#include "../../juce_audio_basics/native/juce_mac_CoreAudioLayouts.h" #include "juce_AU_Shared.h" // Change this to disable logging of various activities @@ -556,7 +559,7 @@ public: if (! set.isDiscreteLayout()) { - const AudioChannelLayoutTag requestedTag = AudioUnitHelpers::ChannelSetToCALayoutTag (set); + const AudioChannelLayoutTag requestedTag = CoreAudioLayouts::toCoreAudio (set); AudioChannelLayout layout; const UInt32 minDataSize = sizeof (layout) - sizeof (AudioChannelDescription); @@ -581,7 +584,8 @@ public: if (err != noErr || dataSize < expectedSize) return false; - actualTag = AudioUnitHelpers::ChannelSetToCALayoutTag (AudioUnitHelpers::CoreAudioChannelLayoutToJuceType (layout)); + // try to convert the layout into a tag + actualTag = CoreAudioLayouts::toCoreAudio (CoreAudioLayouts::fromCoreAudio (layout)); } if (actualTag != requestedTag) @@ -882,7 +886,7 @@ public: if (isPositiveAndBelow (index, getTotalNumInputChannels())) return "Input " + String (index + 1); - return String(); + return {}; } const String getOutputChannelName (int index) const override @@ -890,7 +894,7 @@ public: if (isPositiveAndBelow (index, getTotalNumOutputChannels())) return "Output " + String (index + 1); - return String(); + return {}; } bool isInputChannelStereoPair (int index) const override { return isPositiveAndBelow (index, getTotalNumInputChannels()); } @@ -972,17 +976,17 @@ public: const String getParameterName (int index) override { - if (const ParamInfo* p = parameters[index]) + if (auto* p = parameters[index]) return p->name; - return String(); + return {}; } const String getParameterText (int index) override { return String (getParameter (index)); } bool isParameterAutomatable (int index) const override { - if (const ParamInfo* p = parameters[index]) + if (auto* p = parameters[index]) return p->automatable; return false; @@ -1634,7 +1638,7 @@ private: propertySize = sizeof (auLayout); if (AudioUnitGetProperty (comp, kAudioUnitProperty_AudioChannelLayout, scope, static_cast (busIdx), &auLayout, &propertySize) == noErr) - currentLayout = AudioUnitHelpers::CoreAudioChannelLayoutToJuceType (auLayout); + currentLayout = CoreAudioLayouts::fromCoreAudio (auLayout); } if (currentLayout.isDisabled()) @@ -1677,7 +1681,7 @@ private: UInt32 propertySize = sizeof (auLayout); if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_AudioChannelLayout, scope, static_cast (busIdx), &auLayout, &propertySize) == noErr) - currentLayout = AudioUnitHelpers::CoreAudioChannelLayoutToJuceType (auLayout); + currentLayout = CoreAudioLayouts::fromCoreAudio (auLayout); } if (currentLayout.isDisabled()) @@ -1709,7 +1713,12 @@ private: const AudioChannelLayoutTag tag = layoutTags[j]; if (tag != kAudioChannelLayoutTag_UseChannelDescriptions) - supported.addIfNotAlreadyThere (AudioUnitHelpers::CALayoutTagToChannelSet (tag)); + { + AudioChannelLayout caLayout; + + caLayout.mChannelLayoutTag = tag; + supported.addIfNotAlreadyThere (CoreAudioLayouts::fromCoreAudio (caLayout)); + } } if (supported.size() > 0) diff --git a/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp b/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp index 2add8e364..945f27263 100644 --- a/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp +++ b/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -338,7 +340,7 @@ public: if (isPositiveAndBelow (index, getTotalNumInputChannels())) return String (plugin->PortNames [inputs [index]]).trim(); - return String(); + return {}; } const String getOutputChannelName (const int index) const @@ -346,7 +348,7 @@ public: if (isPositiveAndBelow (index, getTotalNumInputChannels())) return String (plugin->PortNames [outputs [index]]).trim(); - return String(); + return {}; } //============================================================================== @@ -390,7 +392,7 @@ public: return String (plugin->PortNames [parameters [index]]).trim(); } - return String(); + return {}; } const String getParameterText (int index) @@ -407,7 +409,7 @@ public: return String (parameterValues[index].scaled, 4); } - return String(); + return {}; } //============================================================================== @@ -424,7 +426,7 @@ public: const String getProgramName (int index) { // XXX - return String(); + return {}; } void changeProgramName (int index, const String& newName) diff --git a/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h b/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h index 4a8a3ce9f..27f91276d 100644 --- a/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h +++ b/source/modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/format_types/juce_VST3Common.h b/source/modules/juce_audio_processors/format_types/juce_VST3Common.h index efc4e337c..02a4b8a83 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VST3Common.h +++ b/source/modules/juce_audio_processors/format_types/juce_VST3Common.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_VST3COMMON_H_INCLUDED -#define JUCE_VST3COMMON_H_INCLUDED +#pragma once //============================================================================== #define JUCE_DECLARE_VST3_COM_REF_METHODS \ @@ -137,7 +138,7 @@ static inline Steinberg::Vst::SpeakerArrangement getArrangementForNumChannels (i return (Steinberg::Vst::SpeakerArrangement) bi.toInt64(); } -static inline Steinberg::Vst::Speaker getSpeakerType (AudioChannelSet::ChannelType type) noexcept +static inline Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set, AudioChannelSet::ChannelType type) noexcept { using namespace Steinberg::Vst; @@ -145,15 +146,16 @@ static inline Steinberg::Vst::Speaker getSpeakerType (AudioChannelSet::ChannelTy { case AudioChannelSet::left: return kSpeakerL; case AudioChannelSet::right: return kSpeakerR; - case AudioChannelSet::centre: return kSpeakerC; + case AudioChannelSet::centre: return (set == AudioChannelSet::mono() ? kSpeakerM : kSpeakerC); + case AudioChannelSet::LFE: return kSpeakerLfe; case AudioChannelSet::leftSurround: return kSpeakerLs; case AudioChannelSet::rightSurround: return kSpeakerRs; case AudioChannelSet::leftCentre: return kSpeakerLc; case AudioChannelSet::rightCentre: return kSpeakerRc; case AudioChannelSet::centreSurround: return kSpeakerCs; - case AudioChannelSet::leftSurroundRear: return kSpeakerSl; - case AudioChannelSet::rightSurroundRear: return kSpeakerSr; + case AudioChannelSet::leftSurroundSide: return (1 << 26); /* kSpeakerLcs */ + case AudioChannelSet::rightSurroundSide: return (1 << 27); /* kSpeakerRcs */ case AudioChannelSet::topMiddle: return (1 << 11); /* kSpeakerTm */ case AudioChannelSet::topFrontLeft: return kSpeakerTfl; case AudioChannelSet::topFrontCentre: return kSpeakerTfc; @@ -162,13 +164,37 @@ static inline Steinberg::Vst::Speaker getSpeakerType (AudioChannelSet::ChannelTy case AudioChannelSet::topRearCentre: return kSpeakerTrc; case AudioChannelSet::topRearRight: return kSpeakerTrr; case AudioChannelSet::LFE2: return kSpeakerLfe2; - default: break; + case AudioChannelSet::leftSurroundRear: return kSpeakerSl; + case AudioChannelSet::rightSurroundRear: return kSpeakerSr; + case AudioChannelSet::wideLeft: return kSpeakerPl; + case AudioChannelSet::wideRight: return kSpeakerPr; + case AudioChannelSet::ambisonicW: return (1 << 20); /* kSpeakerW */ + case AudioChannelSet::ambisonicX: return (1 << 21); /* kSpeakerX */ + case AudioChannelSet::ambisonicY: return (1 << 22); /* kSpeakerY */ + case AudioChannelSet::ambisonicZ: return (1 << 23); /* kSpeakerZ */ + + case AudioChannelSet::discreteChannel0: return kSpeakerM; + default: + break; } - return 0; + + switch (static_cast (type)) + { + case (int) AudioChannelSet::discreteChannel0 + 1: return (1 << 24); /* kSpeakerTsl */ + case (int) AudioChannelSet::discreteChannel0 + 2: return (1 << 25); /* kSpeakerTsr */ + case (int) AudioChannelSet::discreteChannel0 + 3: return (1 << 28); /* kSpeakerBfl */ + case (int) AudioChannelSet::discreteChannel0 + 4: return (1 << 29); /* kSpeakerBfc */ + case (int) AudioChannelSet::discreteChannel0 + 5: return (1 << 30); /* kSpeakerBfr */ + default: + break; + } + + auto channelIndex = static_cast (type) - (static_cast (AudioChannelSet::discreteChannel0) + 6ull); + return (1ull << (channelIndex + 33ull /* last speaker in vst layout + 1 */)); } -static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::Speaker type) noexcept +static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::SpeakerArrangement arr, Steinberg::Vst::Speaker type) noexcept { using namespace Steinberg::Vst; @@ -193,10 +219,29 @@ static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::Speak case kSpeakerTrc: return AudioChannelSet::topRearCentre; case kSpeakerTrr: return AudioChannelSet::topRearRight; case kSpeakerLfe2: return AudioChannelSet::LFE2; + case (1 << 19): return ((arr & kSpeakerC) != 0 ? AudioChannelSet::discreteChannel0 : AudioChannelSet::centre); + case (1 << 20): return AudioChannelSet::ambisonicW; /* kSpeakerW */ + case (1 << 21): return AudioChannelSet::ambisonicX; /* kSpeakerX */ + case (1 << 22): return AudioChannelSet::ambisonicY; /* kSpeakerY */ + case (1 << 23): return AudioChannelSet::ambisonicZ; /* kSpeakerZ */ + case (1 << 24): return static_cast ((int)AudioChannelSet::discreteChannel0 + 1); /* kSpeakerTsl */ + case (1 << 25): return static_cast ((int)AudioChannelSet::discreteChannel0 + 2); /* kSpeakerTsr */ + case (1 << 26): return AudioChannelSet::leftSurroundSide; /* kSpeakerLcs */ + case (1 << 27): return AudioChannelSet::rightSurroundSide; /* kSpeakerRcs */ + case (1 << 28): return static_cast ((int)AudioChannelSet::discreteChannel0 + 3); /* kSpeakerBfl */ + case (1 << 29): return static_cast ((int)AudioChannelSet::discreteChannel0 + 4); /* kSpeakerBfc */ + case (1 << 30): return static_cast ((int)AudioChannelSet::discreteChannel0 + 5); /* kSpeakerBfr */ + case kSpeakerPl: return AudioChannelSet::wideLeft; + case kSpeakerPr: return AudioChannelSet::wideRight; default: break; } - return AudioChannelSet::unknown; + auto channelType = BigInteger (static_cast (type)).findNextSetBit (0); + + // VST3 <-> JUCE layout conversion error: report this bug to the JUCE forum + jassert (channelType >= 33); + + return static_cast (static_cast (AudioChannelSet::discreteChannel0) + 6 + (channelType - 33)); } static inline Steinberg::Vst::SpeakerArrangement getVst3SpeakerArrangement (const AudioChannelSet& channels) noexcept @@ -225,7 +270,7 @@ static inline Steinberg::Vst::SpeakerArrangement getVst3SpeakerArrangement (cons Array types (channels.getChannelTypes()); for (int i = 0; i < types.size(); ++i) - result |= getSpeakerType (types.getReference(i)); + result |= getSpeakerType (channels, types.getReference(i)); return result; } @@ -253,9 +298,16 @@ static inline AudioChannelSet getChannelSetForSpeakerArrangement (Steinberg::Vst AudioChannelSet result; - for (Steinberg::Vst::Speaker speaker = 1; speaker <= Steinberg::Vst::kSpeakerRcs; speaker <<= 1) - if ((arr & speaker) != 0) - result.addChannel (getChannelType (speaker)); + BigInteger vstChannels (static_cast (arr)); + for (auto bit = vstChannels.findNextSetBit (0); bit != -1; bit = vstChannels.findNextSetBit (bit + 1)) + { + AudioChannelSet::ChannelType channelType = getChannelType (arr, 1ull << static_cast (bit)); + if (channelType != AudioChannelSet::unknown) + result.addChannel (channelType); + } + + // VST3 <-> JUCE layout conversion error: report this bug to the JUCE forum + jassert (result.size() == vstChannels.countNumberOfSetBits()); return result; } @@ -495,7 +547,7 @@ struct VST3BufferExchange for (int i = channelStartOffset; i < channelEnd; ++i) bus.add (buffer.getWritePointer (i, sampleOffset)); - assignRawPointer (vstBuffers, bus.getRawDataPointer()); + assignRawPointer (vstBuffers, (numChannels > 0 ? bus.getRawDataPointer() : nullptr)); vstBuffers.numChannels = numChannels; vstBuffers.silenceFlags = 0; } @@ -513,10 +565,9 @@ struct VST3BufferExchange if (index >= busMapToUse.size()) busMapToUse.add (Bus()); - if (numChansForBus > 0) - associateBufferTo (result.getReference (index), - busMapToUse.getReference (index), - source, numChansForBus, channelIndexOffset); + associateBufferTo (result.getReference (index), + busMapToUse.getReference (index), + source, numChansForBus, channelIndexOffset); channelIndexOffset += numChansForBus; } @@ -569,4 +620,3 @@ template <> struct VST3FloatAndDoubleBusMapCompositeHelper { static inline VST3BufferExchange::BusMap& get (VST3FloatAndDoubleBusMapComposite& impl) { return impl.doubleVersion; } }; -#endif // JUCE_VST3COMMON_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format_types/juce_VST3Headers.h b/source/modules/juce_audio_processors/format_types/juce_VST3Headers.h index c549f7b3f..de33170f1 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VST3Headers.h +++ b/source/modules/juce_audio_processors/format_types/juce_VST3Headers.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_VST3HEADERS_H_INCLUDED -#define JUCE_VST3HEADERS_H_INCLUDED +#pragma once // Wow, those Steinberg guys really don't worry too much about compiler warnings. #if _MSC_VER @@ -46,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 @@ -88,20 +90,19 @@ #define _set_abort_behavior(...) #endif #include - #include #include #include #include - #include #include #include - #include + #include #include #include #include #include #include #include + #include #include #include #include @@ -124,6 +125,7 @@ namespace Steinberg DEF_CLASS_IID (IPluginFactory) DEF_CLASS_IID (IPluginFactory2) DEF_CLASS_IID (IPluginFactory3) + DEF_CLASS_IID (IPlugViewContentScaleSupport) } #endif //JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY @@ -180,5 +182,3 @@ namespace Steinberg #undef DEF_CLASS2 #undef DEF_CLASS_W #undef END_FACTORY - -#endif // JUCE_VST3HEADERS_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 9cc4f86b3..7a5d66145 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -51,7 +53,7 @@ struct VST3Classes #endif #if JUCE_DEBUG -static int warnOnFailure (int result) +static int warnOnFailure (int result) noexcept { const char* message = "Unknown result!"; @@ -155,9 +157,9 @@ static int getNumSingleDirectionChannelsFor (Vst::IComponent* component, } static void setStateForAllBusesOfType (Vst::IComponent* component, - bool state, - bool activateInputs, - bool activateAudioChannels) + bool state, + bool activateInputs, + bool activateAudioChannels) { jassert (component != nullptr); @@ -187,6 +189,7 @@ static void toProcessContext (Vst::ProcessContext& context, AudioPlayHead* playH zerostruct (context); context.sampleRate = sampleRate; + auto& fr = context.frameRate; if (playHead != nullptr) { @@ -204,25 +207,16 @@ static void toProcessContext (Vst::ProcessContext& context, AudioPlayHead* playH switch (position.frameRate) { - case AudioPlayHead::fps24: context.frameRate.framesPerSecond = 24; break; - case AudioPlayHead::fps25: context.frameRate.framesPerSecond = 25; break; - case AudioPlayHead::fps30: context.frameRate.framesPerSecond = 30; break; - - case AudioPlayHead::fps2997: - case AudioPlayHead::fps2997drop: - case AudioPlayHead::fps30drop: - { - context.frameRate.framesPerSecond = 30; - context.frameRate.flags = FrameRate::kDropRate; - - if (position.frameRate == AudioPlayHead::fps2997drop) - context.frameRate.flags |= FrameRate::kPullDownRate; - } - break; - - case AudioPlayHead::fpsUnknown: break; - - default: jassertfalse; break; // New frame rate? + case AudioPlayHead::fps24: fr.framesPerSecond = 24; fr.flags = 0; break; + case AudioPlayHead::fps25: fr.framesPerSecond = 25; fr.flags = 0; break; + case AudioPlayHead::fps2997: fr.framesPerSecond = 30; fr.flags = FrameRate::kPullDownRate; break; + case AudioPlayHead::fps2997drop: fr.framesPerSecond = 30; fr.flags = FrameRate::kPullDownRate | FrameRate::kDropRate; break; + case AudioPlayHead::fps30: fr.framesPerSecond = 30; fr.flags = 0; break; + case AudioPlayHead::fps30drop: fr.framesPerSecond = 30; fr.flags = FrameRate::kDropRate; break; + case AudioPlayHead::fps60: fr.framesPerSecond = 60; fr.flags = 0; break; + case AudioPlayHead::fps60drop: fr.framesPerSecond = 60; fr.flags = FrameRate::kDropRate; break; + case AudioPlayHead::fpsUnknown: break; + default: jassertfalse; break; // New frame rate? } if (position.isPlaying) context.state |= ProcessContext::kPlaying; @@ -231,10 +225,11 @@ static void toProcessContext (Vst::ProcessContext& context, AudioPlayHead* playH } else { - context.tempo = 120.0; - context.frameRate.framesPerSecond = 30; - context.timeSigNumerator = 4; - context.timeSigDenominator = 4; + context.tempo = 120.0; + context.timeSigNumerator = 4; + context.timeSigDenominator = 4; + fr.framesPerSecond = 30; + fr.flags = 0; } if (context.projectTimeMusic >= 0.0) context.state |= ProcessContext::kProjectTimeMusicValid; @@ -351,17 +346,16 @@ static StringArray getPluginInstrumentCategories() } //============================================================================== -class VST3PluginInstance; - -class VST3HostContext : public Vst::IComponentHandler, // From VST V3.0.0 - public Vst::IComponentHandler2, // From VST V3.1.0 (a very well named class, of course!) - public Vst::IComponentHandler3, // From VST V3.5.0 (also very well named!) - public Vst::IContextMenuTarget, - public Vst::IHostApplication, - public Vst::IUnitHandler +struct VST3PluginInstance; + +struct VST3HostContext : public Vst::IComponentHandler, // From VST V3.0.0 + public Vst::IComponentHandler2, // From VST V3.1.0 (a very well named class, of course!) + public Vst::IComponentHandler3, // From VST V3.5.0 (also very well named!) + public Vst::IContextMenuTarget, + public Vst::IHostApplication, + public Vst::IUnitHandler { -public: - VST3HostContext() : plugin (nullptr) + VST3HostContext() { appName = File::getSpecialLocation (File::currentApplicationFile).getFileNameWithoutExtension(); attributeList = new AttributeList (this); @@ -383,7 +377,7 @@ public: { if (plugin != nullptr) { - const int index = getIndexOfParamID (paramID); + auto index = getIndexOfParamID (paramID); if (index < 0) return kResultFalse; @@ -398,7 +392,7 @@ public: { if (plugin != nullptr) { - const int index = getIndexOfParamID (paramID); + auto index = getIndexOfParamID (paramID); if (index < 0) return kResultFalse; @@ -422,13 +416,14 @@ public: { if (plugin != nullptr) { - const int index = getIndexOfParamID (paramID); + auto index = getIndexOfParamID (paramID); if (index < 0) return kResultFalse; plugin->endParameterChangeGesture (index); } + return kResultTrue; } @@ -441,11 +436,11 @@ public: if (hasFlag (flags, Vst::kIoChanged)) { - const double sampleRate = plugin->getSampleRate(); - const int blockSize = plugin->getBlockSize(); + auto sampleRate = plugin->getSampleRate(); + auto blockSize = plugin->getBlockSize(); plugin->prepareToPlay (sampleRate >= 8000 ? sampleRate : 44100.0, - blockSize > 0 ? blockSize : 1024); + blockSize > 0 ? blockSize : 1024); } if (hasFlag (flags, Vst::kLatencyChanged)) @@ -492,9 +487,8 @@ public: } //============================================================================== - class ContextMenu : public Vst::IContextMenu + struct ContextMenu : public Vst::IContextMenu { - public: ContextMenu (VST3PluginInstance& pluginInstance) : owner (pluginInstance) {} virtual ~ContextMenu() {} @@ -519,7 +513,7 @@ public: { for (int i = items.size(); --i >= 0;) { - ItemAndTarget& item = items.getReference(i); + auto& item = items.getReference(i); if (item.item.tag == toRemove.tag && item.target == target) items.remove (i); @@ -532,7 +526,7 @@ public: { for (int i = 0; i < items.size(); ++i) { - const ItemAndTarget& item = items.getReference(i); + auto& item = items.getReference(i); if (item.item.tag == tag) { @@ -557,9 +551,8 @@ public: for (int i = 0; i < items.size(); ++i) { - const Item& item = items.getReference (i).item; - - PopupMenu* menuToUse = menuStack.getLast(); + auto& item = items.getReference (i).item; + auto* menuToUse = menuStack.getLast(); if (hasFlag (item.flags, Item::kIsGroupStart & ~Item::kIsDisabled)) { @@ -568,9 +561,9 @@ public: } else if (hasFlag (item.flags, Item::kIsGroupEnd)) { - if (const Item* subItem = subItemStack.getLast()) + if (auto* subItem = subItemStack.getLast()) { - if (PopupMenu* m = menuStack [menuStack.size() - 2]) + if (auto* m = menuStack [menuStack.size() - 2]) m->addSubMenu (toString (subItem->name), *menuToUse, ! hasFlag (subItem->flags, Item::kIsDisabled), nullptr, @@ -595,7 +588,7 @@ public: PopupMenu::Options options; - if (AudioProcessorEditor* ed = owner.getActiveEditor()) + if (auto* ed = owner.getActiveEditor()) options = options.withTargetScreenArea (ed->getScreenBounds().translated ((int) x, (int) y).withSize (1, 1)); #if JUCE_MODAL_LOOPS_PERMITTED @@ -636,7 +629,7 @@ public: for (int i = 0; i < items.size(); ++i) { - const ItemAndTarget& item = items.getReference(i); + auto& item = items.getReference(i); if ((int) item.item.tag == result) { @@ -685,7 +678,7 @@ public: if (doUIDsMatch (cid, Vst::IMessage::iid) && doUIDsMatch (iid, Vst::IMessage::iid)) { - ComSmartPtr m (new Message (*this, attributeList)); + ComSmartPtr m (new Message (attributeList)); messageQueue.add (m); m->addRef(); *obj = m; @@ -741,7 +734,7 @@ public: private: //============================================================================== - VST3PluginInstance* plugin; + VST3PluginInstance* plugin = nullptr; Atomic refCount; String appName; @@ -753,11 +746,11 @@ private: if (plugin == nullptr || plugin->editController == nullptr) return -1; - int result = getMappedParamID (paramID); + auto result = getMappedParamID (paramID); if (result < 0) { - const int numParams = plugin->editController->getParameterCount(); + auto numParams = plugin->editController->getParameterCount(); for (int i = 0; i < numParams; ++i) { @@ -774,26 +767,25 @@ private: int getMappedParamID (Vst::ParamID paramID) { - const ParamMapType::iterator it (paramToIndexMap.find (paramID)); + auto it = paramToIndexMap.find (paramID); return it != paramToIndexMap.end() ? it->second : -1; } //============================================================================== - class Message : public Vst::IMessage + struct Message : public Vst::IMessage { - public: - Message (VST3HostContext& o, Vst::IAttributeList* list) - : owner (o), attributeList (list) + Message (Vst::IAttributeList* list) + : attributeList (list) { } - Message (VST3HostContext& o, Vst::IAttributeList* list, FIDString id) - : owner (o), attributeList (list), messageId (toString (id)) + Message (Vst::IAttributeList* list, FIDString id) + : attributeList (list), messageId (toString (id)) { } - Message (VST3HostContext& o, Vst::IAttributeList* list, FIDString id, const var& v) - : value (v), owner (o), attributeList (list), messageId (toString (id)) + Message (Vst::IAttributeList* list, FIDString id, const var& v) + : value (v), attributeList (list), messageId (toString (id)) { } @@ -809,7 +801,6 @@ private: var value; private: - VST3HostContext& owner; ComSmartPtr attributeList; String messageId; Atomic refCount; @@ -820,9 +811,8 @@ private: Array, CriticalSection> messageQueue; //============================================================================== - class AttributeList : public Vst::IAttributeList + struct AttributeList : public Vst::IAttributeList { - public: AttributeList (VST3HostContext* o) : owner (o) {} virtual ~AttributeList() {} @@ -899,13 +889,11 @@ private: { jassert (id != nullptr); - for (int i = owner->messageQueue.size(); --i >= 0;) + for (auto&& m : owner->messageQueue) { - Message* const message = owner->messageQueue.getReference (i); - - if (std::strcmp (message->getMessageID(), id) == 0) + if (std::strcmp (m->getMessageID(), id) == 0) { - if (MemoryBlock* binaryData = message->value.getBinaryData()) + if (auto* binaryData = m->value.getBinaryData()) { data = binaryData->getData(); size = (Steinberg::uint32) binaryData->getSize(); @@ -927,18 +915,16 @@ private: { jassert (id != nullptr); - for (int i = owner->messageQueue.size(); --i >= 0;) + for (auto&& m : owner->messageQueue) { - VST3HostContext::Message* const message = owner->messageQueue.getReference (i); - - if (std::strcmp (message->getMessageID(), id) == 0) + if (std::strcmp (m->getMessageID(), id) == 0) { - message->value = value; + m->value = value; return; } } - owner->messageQueue.add (ComSmartPtr (new Message (*owner, this, id, value))); + owner->messageQueue.add (ComSmartPtr (new Message (this, id, value))); } template @@ -946,13 +932,11 @@ private: { jassert (id != nullptr); - for (int i = owner->messageQueue.size(); --i >= 0;) + for (auto&& m : owner->messageQueue) { - VST3HostContext::Message* const message = owner->messageQueue.getReference (i); - - if (std::strcmp (message->getMessageID(), id) == 0) + if (std::strcmp (m->getMessageID(), id) == 0) { - value = message->value; + value = m->value; return true; } } @@ -969,9 +953,8 @@ private: }; //============================================================================== -class DescriptionFactory +struct DescriptionFactory { -public: DescriptionFactory (VST3HostContext* host, IPluginFactory* pluginFactory) : vst3HostContext (host), factory (pluginFactory) { @@ -985,11 +968,11 @@ public: StringArray foundNames; PFactoryInfo factoryInfo; factory->getFactoryInfo (&factoryInfo); - const String companyName (toString (factoryInfo.vendor).trim()); + auto companyName = toString (factoryInfo.vendor).trim(); Result result (Result::ok()); - const Steinberg::int32 numClasses = factory->countClasses(); + auto numClasses = factory->countClasses(); for (Steinberg::int32 i = 0; i < numClasses; ++i) { @@ -1035,8 +1018,8 @@ public: { if (component->initialize (vst3HostContext->getFUnknown()) == kResultOk) { - const int numInputs = getNumSingleDirectionChannelsFor (component, true, true); - const int numOutputs = getNumSingleDirectionChannelsFor (component, false, true); + auto numInputs = getNumSingleDirectionChannelsFor (component, true, true); + auto numOutputs = getNumSingleDirectionChannelsFor (component, false, true); createPluginDescription (desc, file, companyName, name, info, info2, infoW, numInputs, numOutputs); @@ -1063,8 +1046,7 @@ public: return result; } -protected: - virtual Result performOnDescription (PluginDescription& description) = 0; + virtual Result performOnDescription (PluginDescription&) = 0; private: ComSmartPtr vst3HostContext; @@ -1073,14 +1055,14 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DescriptionFactory) }; -struct MatchingDescriptionFinder : public DescriptionFactory +struct MatchingDescriptionFinder : public DescriptionFactory { - MatchingDescriptionFinder (VST3HostContext* host, IPluginFactory* pluginFactory, const PluginDescription& desc) - : DescriptionFactory (host, pluginFactory), description (desc) + MatchingDescriptionFinder (VST3HostContext* h, IPluginFactory* f, const PluginDescription& desc) + : DescriptionFactory (h, f), description (desc) { } - static const char* getSuccessString() noexcept { return "Found Description"; } + static const char* getSuccessString() noexcept { return "Found Description"; } Result performOnDescription (PluginDescription& desc) { @@ -1096,7 +1078,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MatchingDescriptionFinder) }; -struct DescriptionLister : public DescriptionFactory +struct DescriptionLister : public DescriptionFactory { DescriptionLister (VST3HostContext* host, IPluginFactory* pluginFactory) : DescriptionFactory (host, pluginFactory) @@ -1119,7 +1101,6 @@ private: struct DLLHandle { DLLHandle (const String& modulePath) - : factory (nullptr) { if (modulePath.trim().isNotEmpty()) open (modulePath); @@ -1130,10 +1111,11 @@ struct DLLHandle typedef bool (PLUGIN_API *ExitModuleFn) (); #if JUCE_WINDOWS - if (ExitModuleFn exitFn = (ExitModuleFn) getFunction ("ExitDll")) + releaseFactory(); + + if (auto exitFn = (ExitModuleFn) getFunction ("ExitDll")) exitFn(); - releaseFactory(); library.close(); #else @@ -1141,7 +1123,7 @@ struct DLLHandle { releaseFactory(); - if (ExitModuleFn exitFn = (ExitModuleFn) getFunction ("bundleExit")) + if (auto exitFn = (ExitModuleFn) getFunction ("bundleExit")) exitFn(); CFRelease (bundleRef); @@ -1172,7 +1154,7 @@ struct DLLHandle IPluginFactory* JUCE_CALLTYPE getPluginFactory() { if (factory == nullptr) - if (GetFactoryProc proc = (GetFactoryProc) getFunction ("GetPluginFactory")) + if (auto proc = (GetFactoryProc) getFunction ("GetPluginFactory")) factory = proc(); // The plugin NEEDS to provide a factory to be able to be called a VST3! @@ -1198,7 +1180,7 @@ struct DLLHandle } private: - IPluginFactory* factory; + IPluginFactory* factory = nullptr; void releaseFactory() { @@ -1215,7 +1197,7 @@ private: { typedef bool (PLUGIN_API *InitModuleProc) (); - if (InitModuleProc proc = (InitModuleProc) getFunction ("InitDll")) + if (auto proc = (InitModuleProc) getFunction ("InitDll")) { if (proc()) return true; @@ -1252,7 +1234,7 @@ private: { typedef bool (*BundleEntryProc)(CFBundleRef); - if (BundleEntryProc proc = (BundleEntryProc) getFunction ("bundleEntry")) + if (auto proc = (BundleEntryProc) getFunction ("bundleEntry")) { if (proc (bundleRef)) return true; @@ -1287,9 +1269,8 @@ private: }; //============================================================================== -class VST3ModuleHandle : public ReferenceCountedObject +struct VST3ModuleHandle : public ReferenceCountedObject { -public: explicit VST3ModuleHandle (const File& pluginFile) : file (pluginFile) { getActiveModules().add (this); @@ -1316,7 +1297,7 @@ public: { ComSmartPtr host (new VST3HostContext()); DescriptionLister lister (host, pluginFactory); - const Result result (lister.findDescriptionsAndPerform (File (fileOrIdentifier))); + auto result = lister.findDescriptionsAndPerform (File (fileOrIdentifier)); results.addCopiesOf (lister.list); @@ -1332,16 +1313,10 @@ public: static VST3ModuleHandle::Ptr findOrCreateModule (const File& file, const PluginDescription& description) { - Array& activeModules = getActiveModules(); - - for (int i = activeModules.size(); --i >= 0;) - { - VST3ModuleHandle* const module = activeModules.getUnchecked (i); - + for (auto* module : getActiveModules()) // VST3s are basically shells, you must therefore check their name along with their file: if (module->file == file && module->name == description.name) return module; - } VST3ModuleHandle::Ptr m (new VST3ModuleHandle (file)); @@ -1379,7 +1354,7 @@ private: ComSmartPtr host (new VST3HostContext()); MatchingDescriptionFinder finder (host, pluginFactory, description); - const Result result (finder.findDescriptionsAndPerform (f)); + auto result = finder.findDescriptionsAndPerform (f); if (result.getErrorMessage() == MatchingDescriptionFinder::getSuccessString() || result.getErrorMessage().isEmpty()) @@ -1396,28 +1371,21 @@ private: }; //============================================================================== -class VST3PluginWindow : public AudioProcessorEditor, - public ComponentMovementWatcher, - public IPlugFrame +struct VST3PluginWindow : public AudioProcessorEditor, + public ComponentMovementWatcher, + public IPlugFrame { -public: VST3PluginWindow (AudioProcessor* owner, IPlugView* pluginView) : AudioProcessorEditor (owner), ComponentMovementWatcher (this), - refCount (1), - view (pluginView, false), - pluginHandle (nullptr), - recursiveResize (false) + view (pluginView, false) { setSize (10, 10); setOpaque (true); setVisible (true); warnOnFailure (view->setFrame (this)); - - ViewRect rect; - warnOnFailure (view->getSize (&rect)); - resizeWithRect (*this, rect); + resizeToFit(); } ~VST3PluginWindow() @@ -1428,7 +1396,7 @@ public: processor.editorBeingDeleted (this); #if JUCE_MAC - dummyComponent.setView (nullptr); + embeddedComponent.setView (nullptr); #endif view = nullptr; @@ -1447,14 +1415,14 @@ public: view->onWheel (wheel.deltaY); } - void focusGained (FocusChangeType) override { view->onFocus (true); } - void focusLost (FocusChangeType) override { view->onFocus (false); } + void focusGained (FocusChangeType) override { view->onFocus (true); } + void focusLost (FocusChangeType) override { view->onFocus (false); } /** It seems that most, if not all, plugins do their own keyboard hooks, but IPlugView does have a set of keyboard related methods... */ - bool keyStateChanged (bool /*isKeyDown*/) override { return true; } - bool keyPressed (const KeyPress& /*key*/) override { return true; } + bool keyStateChanged (bool /*isKeyDown*/) override { return true; } + bool keyPressed (const KeyPress& /*key*/) override { return true; } //============================================================================== void componentMovedOrResized (bool, bool wasResized) override @@ -1462,12 +1430,12 @@ public: if (recursiveResize) return; - Component* const topComp = getTopLevelComponent(); + auto* topComp = getTopLevelComponent(); if (topComp->getPeer() != nullptr) { #if JUCE_WINDOWS - const Point pos (topComp->getLocalPoint (this, Point())); + auto pos = topComp->getLocalPoint (this, Point()); #endif recursiveResize = true; @@ -1480,14 +1448,16 @@ public: rect.bottom = (Steinberg::int32) getHeight(); view->checkSizeConstraint (&rect); - setSize ((int) rect.getWidth(), (int) rect.getHeight()); + auto w = (int) rect.getWidth(); + auto h = (int) rect.getHeight(); + setSize (w, h); #if JUCE_WINDOWS SetWindowPos (pluginHandle, 0, - pos.x, pos.y, rect.getWidth(), rect.getHeight(), + pos.x, pos.y, w, h, isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW); #elif JUCE_MAC - dummyComponent.setBounds (getLocalBounds()); + embeddedComponent.setBounds (getLocalBounds()); #endif view->onSize (&rect); @@ -1501,7 +1471,7 @@ public: pos.x, pos.y, rect.getWidth(), rect.getHeight(), isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW); #elif JUCE_MAC - dummyComponent.setBounds (0, 0, (int) rect.getWidth(), (int) rect.getHeight()); + embeddedComponent.setBounds (0, 0, (int) rect.getWidth(), (int) rect.getHeight()); #endif } @@ -1512,7 +1482,7 @@ public: } } - void componentPeerChanged() override { } + void componentPeerChanged() override {} void componentVisibilityChanged() override { @@ -1520,14 +1490,21 @@ public: componentMovedOrResized (true, true); } + void resizeToFit() + { + ViewRect rect; + warnOnFailure (view->getSize (&rect)); + resizeWithRect (*this, rect); + } + tresult PLUGIN_API resizeView (IPlugView* incomingView, ViewRect* newSize) override { if (incomingView != nullptr && newSize != nullptr && incomingView == view) { - resizeWithRect (dummyComponent, *newSize); - setSize (dummyComponent.getWidth(), dummyComponent.getHeight()); + resizeWithRect (embeddedComponent, *newSize); + setSize (embeddedComponent.getWidth(), embeddedComponent.getHeight()); return kResultTrue; } @@ -1535,37 +1512,47 @@ public: return kInvalidArgument; } + void setScaleFactor (float newScale) override + { + Steinberg::IPlugViewContentScaleSupport* scaleInterface = nullptr; + view->queryInterface (Steinberg::IPlugViewContentScaleSupport::iid, (void**) &scaleInterface); + + if (scaleInterface != nullptr) + { + scaleInterface->setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) newScale); + scaleInterface->release(); + resizeToFit(); + } + } + private: //============================================================================== - Atomic refCount; + Atomic refCount { 1 }; ComSmartPtr view; #if JUCE_WINDOWS - class ChildComponent : public Component + struct ChildComponent : public Component { - public: ChildComponent() {} void paint (Graphics& g) override { g.fillAll (Colours::cornflowerblue); } - using Component::createNewPeer; - private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildComponent) }; - ChildComponent dummyComponent; + ChildComponent embeddedComponent; ScopedPointer peer; typedef HWND HandleFormat; #elif JUCE_MAC - AutoResizingNSViewComponentWithParent dummyComponent; + AutoResizingNSViewComponentWithParent embeddedComponent; typedef NSView* HandleFormat; #else - Component dummyComponent; + Component embeddedComponent; typedef void* HandleFormat; #endif - HandleFormat pluginHandle; - bool recursiveResize; + HandleFormat pluginHandle = {}; + bool recursiveResize = false; //============================================================================== static void resizeWithRect (Component& comp, const ViewRect& rect) @@ -1580,17 +1567,17 @@ private: if (pluginHandle == nullptr) { #if JUCE_WINDOWS - if (Component* topComp = getTopLevelComponent()) - peer = dummyComponent.createNewPeer (0, topComp->getWindowHandle()); + if (auto* topComp = getTopLevelComponent()) + peer = embeddedComponent.createNewPeer (0, topComp->getWindowHandle()); else peer = nullptr; if (peer != nullptr) pluginHandle = (HandleFormat) peer->getNativeHandle(); #elif JUCE_MAC - dummyComponent.setBounds (getLocalBounds()); - addAndMakeVisible (dummyComponent); - pluginHandle = (NSView*) dummyComponent.getView(); + embeddedComponent.setBounds (getLocalBounds()); + addAndMakeVisible (embeddedComponent); + pluginHandle = (NSView*) embeddedComponent.getView(); jassert (pluginHandle != nil); #endif @@ -1610,9 +1597,7 @@ private: //============================================================================== struct VST3ComponentHolder { - VST3ComponentHolder (const VST3ModuleHandle::Ptr& handle) - : module (handle), - isComponentInitialised (false) + VST3ComponentHolder (const VST3ModuleHandle::Ptr& m) : module (m) { host = new VST3HostContext(); } @@ -1644,7 +1629,8 @@ struct VST3ComponentHolder if (editController == nullptr) { // Try finding the IEditController the long way around: - const Steinberg::int32 numClasses = factory->countClasses(); + auto numClasses = factory->countClasses(); + for (Steinberg::int32 i = 0; i < numClasses; ++i) { PClassInfo classInfo; @@ -1669,8 +1655,9 @@ struct VST3ComponentHolder PFactoryInfo factoryInfo; factory->getFactoryInfo (&factoryInfo); - int classIdx; - if ((classIdx = getClassIndex (module->name)) >= 0) + auto classIdx = getClassIndex (module->name); + + if (classIdx >= 0) { PClassInfo info; bool success = (factory->getClassInfo (classIdx, &info) == kResultOk); @@ -1776,8 +1763,8 @@ struct VST3ComponentHolder for (Steinberg::int32 j = 0; j < numClasses; ++j) if (factory->getClassInfo (j, &info) == kResultOk - && std::strcmp (info.category, kVstAudioEffectClass) == 0 - && toString (info.name).trim() == className) + && std::strcmp (info.category, kVstAudioEffectClass) == 0 + && toString (info.name).trim() == className) return j; return -1; @@ -1789,23 +1776,19 @@ struct VST3ComponentHolder ComSmartPtr host; ComSmartPtr component; - bool isComponentInitialised; + bool isComponentInitialised = false; }; //============================================================================== -class VST3PluginInstance : public AudioPluginInstance +struct VST3PluginInstance : public AudioPluginInstance { -public: VST3PluginInstance (VST3ComponentHolder* componentHolder) : AudioPluginInstance (getBusProperties (componentHolder->component)), holder (componentHolder), - programParameterID ((Vst::ParamID) -1), inputParameterChanges (new ParamValueQueueList()), outputParameterChanges (new ParamValueQueueList()), midiInputs (new MidiEventList()), - midiOutputs (new MidiEventList()), - isControllerInitialised (false), - isActive (false) + midiOutputs (new MidiEventList()) { holder->host->setPlugin (this); } @@ -1885,8 +1868,8 @@ public: inputArrangements.clearQuick(); outputArrangements.clearQuick(); - const int numInputAudioBuses = getBusCount (true); - const int numOutputAudioBuses = getBusCount (false); + auto numInputAudioBuses = getBusCount (true); + auto numOutputAudioBuses = getBusCount (false); for (int i = 0; i < numInputAudioBuses; ++i) inputArrangements.add (getArrangementForBus (processor, true, i)); @@ -1900,8 +1883,8 @@ public: inputArrangements.clearQuick(); outputArrangements.clearQuick(); - const int numInputBuses = getBusCount (true); - const int numOutputBuses = getBusCount (false); + auto numInputBuses = getBusCount (true); + auto numOutputBuses = getBusCount (false); for (int i = 0; i < numInputBuses; ++i) inputArrangements.add (getVst3SpeakerArrangement (getBus (true, i)->getLastEnabledLayout())); @@ -1946,8 +1929,8 @@ public: // Needed for having the same sample rate in processBlock(); some plugins need this! setRateAndBufferSizeDetails (newSampleRate, estimatedSamplesPerBlock); - const int numInputBuses = getBusCount (true); - const int numOutputBuses = getBusCount (false); + auto numInputBuses = getBusCount (true); + auto numOutputBuses = getBusCount (false); for (int i = 0; i < numInputBuses; ++i) warnOnFailure (holder->component->activateBus (Vst::kAudio, Vst::kInput, i, getBus (true, i)->isEnabled() ? 1 : 0)); @@ -2006,10 +1989,10 @@ public: Vst::SymbolicSampleSizes sampleSize) { using namespace Vst; - const int numSamples = buffer.getNumSamples(); + auto numSamples = buffer.getNumSamples(); - const int numInputAudioBuses = getBusCount (true); - const int numOutputAudioBuses = getBusCount (false); + auto numInputAudioBuses = getBusCount (true); + auto numOutputAudioBuses = getBusCount (false); ProcessData data; data.processMode = isNonRealtime() ? kOffline : kRealtime; @@ -2050,10 +2033,11 @@ public: // Let's at least check if it is a VST3 compatible layout for (int dir = 0; dir < 2; ++dir) { - const bool isInput = (dir == 0); - const int n = getBusCount (isInput); + bool isInput = (dir == 0); + auto n = getBusCount (isInput); + for (int i = 0; i < n; ++i) - if (getChannelLayoutOfBus(isInput, i).isDiscreteLayout()) + if (getChannelLayoutOfBus (isInput, i).isDiscreteLayout()) return false; } @@ -2064,13 +2048,14 @@ public: { for (int dir = 0; dir < 2; ++dir) { - const bool isInput = (dir == 0); - const int n = getBusCount (isInput); + bool isInput = (dir == 0); + auto n = getBusCount (isInput); const Vst::BusDirection vstDir = (isInput ? Vst::kInput : Vst::kOutput); for (int busIdx = 0; busIdx < n; ++busIdx) { const bool isEnabled = (! layouts.getChannelSet (isInput, busIdx).isDisabled()); + if (holder->component->activateBus (Vst::kAudio, vstDir, busIdx, (isEnabled ? 1 : 0)) != kResultOk) return false; } @@ -2080,13 +2065,13 @@ public: for (int i = 0; i < layouts.inputBuses.size(); ++i) { - const AudioChannelSet& requested = layouts.getChannelSet (true, i); + const auto& requested = layouts.getChannelSet (true, i); inputArrangements.add (getVst3SpeakerArrangement (requested.isDisabled() ? getBus (true, i)->getLastEnabledLayout() : requested)); } for (int i = 0; i < layouts.outputBuses.size(); ++i) { - const AudioChannelSet& requested = layouts.getChannelSet (false, i); + const auto& requested = layouts.getChannelSet (false, i); outputArrangements.add (getVst3SpeakerArrangement (requested.isDisabled() ? getBus (false, i)->getLastEnabledLayout() : requested)); } @@ -2119,12 +2104,12 @@ public: //============================================================================== String getChannelName (int channelIndex, bool forInput, bool forAudioChannel) const { - const int numBuses = getNumSingleDirectionBusesFor (holder->component, forInput, forAudioChannel); + auto numBuses = getNumSingleDirectionBusesFor (holder->component, forInput, forAudioChannel); int numCountedChannels = 0; for (int i = 0; i < numBuses; ++i) { - Vst::BusInfo busInfo (getBusInfo (forInput, forAudioChannel, i)); + auto busInfo = getBusInfo (forInput, forAudioChannel, i); numCountedChannels += busInfo.channelCount; @@ -2132,7 +2117,7 @@ public: return toString (busInfo.name); } - return String(); + return {}; } const String getInputChannelName (int channelIndex) const override { return getChannelName (channelIndex, true, true); } @@ -2159,7 +2144,7 @@ public: { if (processor != nullptr) { - const double sampleRate = getSampleRate(); + auto sampleRate = getSampleRate(); if (sampleRate > 0.0) return jlimit (0, 0x7fffffff, (int) processor->getTailSamples()) / sampleRate; @@ -2171,7 +2156,7 @@ public: //============================================================================== AudioProcessorEditor* createEditor() override { - if (IPlugView* view = tryCreatingView()) + if (auto* view = tryCreatingView()) return new VST3PluginWindow (this, view); return nullptr; @@ -2205,7 +2190,7 @@ public: { if (editController != nullptr) { - const uint32 id = getParameterInfoForIndex (parameterIndex).id; + auto id = getParameterInfoForIndex (parameterIndex).id; return (float) editController->getParamNormalized (id); } @@ -2216,7 +2201,7 @@ public: { if (editController != nullptr) { - const uint32 id = getParameterInfoForIndex (parameterIndex).id; + auto id = getParameterInfoForIndex (parameterIndex).id; Vst::String128 result; warnOnFailure (editController->getParamStringByValue (id, editController->getParamNormalized (id), result)); @@ -2224,14 +2209,14 @@ public: return toString (result); } - return String(); + return {}; } void setParameter (int parameterIndex, float newValue) override { if (editController != nullptr) { - const uint32 paramID = getParameterInfoForIndex (parameterIndex).id; + auto paramID = getParameterInfoForIndex (parameterIndex).id; editController->setParamNormalized (paramID, (double) newValue); Steinberg::int32 index; @@ -2249,8 +2234,7 @@ public: { if (programNames.size() > 0 && editController != nullptr) { - Vst::ParamValue value = - static_cast (program) / static_cast (programNames.size()); + auto value = static_cast (program) / static_cast (programNames.size()); editController->setParamNormalized (programParameterID, value); Steinberg::int32 index; @@ -2331,10 +2315,9 @@ public: //============================================================================== // NB: this class and its subclasses must be public to avoid problems in // DLL builds under MSVC. - class ParamValueQueueList : public Vst::IParameterChanges + struct ParamValueQueueList : public Vst::IParameterChanges { - public: - ParamValueQueueList() : numQueuesUsed (0) {} + ParamValueQueueList() {} virtual ~ParamValueQueueList() {} JUCE_DECLARE_VST3_COM_REF_METHODS @@ -2356,7 +2339,7 @@ public: index = numQueuesUsed++; ParamValueQueue* valueQueue = (index < queues.size() ? queues[index] - : queues.add (new ParamValueQueue)); + : queues.add (new ParamValueQueue())); valueQueue->clear(); valueQueue->setParamID (id); @@ -2371,7 +2354,7 @@ public: struct ParamValueQueue : public Vst::IParamValueQueue { - ParamValueQueue() : paramID (static_cast (-1)) + ParamValueQueue() { points.ensureStorageAllocated (1024); } @@ -2431,7 +2414,7 @@ public: }; Atomic refCount; - Vst::ParamID paramID; + Vst::ParamID paramID = static_cast (-1); Array points; CriticalSection pointLock; @@ -2440,7 +2423,7 @@ public: Atomic refCount; OwnedArray queues; - int numQueuesUsed; + int numQueuesUsed = 0; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParamValueQueueList) }; @@ -2466,8 +2449,7 @@ private: ComSmartPtr unitInfo; ComSmartPtr unitData; ComSmartPtr programListData; - ComSmartPtr componentConnection; - ComSmartPtr editControllerConnection; + ComSmartPtr componentConnection, editControllerConnection; /** The number of IO buses MUST match that of the plugin, even if there aren't enough channels to process, @@ -2478,7 +2460,7 @@ private: AudioProcessor::BusesLayout cachedBusLayouts; StringArray programNames; - Vst::ParamID programParameterID; + Vst::ParamID programParameterID = (Vst::ParamID) -1; //============================================================================== template @@ -2500,7 +2482,7 @@ private: { Steinberg::MemoryStream* stream = nullptr; - if (XmlElement* const state = head.getChildByName (identifier)) + if (auto* state = head.getChildByName (identifier)) { MemoryBlock mem; @@ -2518,7 +2500,7 @@ private: ComSmartPtr inputParameterChanges, outputParameterChanges; ComSmartPtr midiInputs, midiOutputs; Vst::ProcessContext timingInfo; //< Only use this in processBlock()! - bool isControllerInitialised, isActive; + bool isControllerInitialised = false, isActive = false; //============================================================================== /** Some plugins need to be "connected" to intercommunicate between their implemented classes */ @@ -2710,7 +2692,8 @@ private: && (paramInfo.flags & Steinberg::Vst::ParameterInfo::kIsProgramChange) != 0) break; - if (idx >= num) return; + if (idx >= num) + return; programParameterID = paramInfo.id; programUnitID = paramInfo.unitId; @@ -2753,11 +2736,13 @@ private: if (editController != nullptr && paramInfo.stepCount > 0) { - const int numPrograms = paramInfo.stepCount + 1; + auto numPrograms = paramInfo.stepCount + 1; + for (int i = 0; i < numPrograms; ++i) { + auto valueNormalized = static_cast (i) / static_cast (paramInfo.stepCount); + Vst::String128 programName; - Vst::ParamValue valueNormalized = static_cast (i) / static_cast (paramInfo.stepCount); if (editController->getParamStringByValue (paramInfo.id, valueNormalized, programName) == kResultOk) programNames.add (toString (programName)); } @@ -2779,7 +2764,7 @@ AudioPluginInstance* VST3Classes::VST3ComponentHolder::createPluginInstance() if (! initialise()) return nullptr; - VST3PluginInstance* plugin = new VST3PluginInstance (this); + auto* plugin = new VST3PluginInstance (this); host->setPlugin (plugin); return plugin; } @@ -2791,16 +2776,11 @@ VST3PluginFormat::~VST3PluginFormat() {} void VST3PluginFormat::findAllTypesForFile (OwnedArray& results, const String& fileOrIdentifier) { - if (! fileMightContainThisPluginType (fileOrIdentifier)) - return; - - VST3Classes::VST3ModuleHandle::getAllDescriptionsForFile (results, fileOrIdentifier); + if (fileMightContainThisPluginType (fileOrIdentifier)) + VST3Classes::VST3ModuleHandle::getAllDescriptionsForFile (results, fileOrIdentifier); } -void VST3PluginFormat::createPluginInstance (const PluginDescription& description, - double, - int, - void* userData, +void VST3PluginFormat::createPluginInstance (const PluginDescription& description, double, int, void* userData, void (*callback) (void*, AudioPluginInstance*, const String&)) { ScopedPointer result; @@ -2809,15 +2789,17 @@ void VST3PluginFormat::createPluginInstance (const PluginDescription& descriptio { File file (description.fileOrIdentifier); - const File previousWorkingDirectory (File::getCurrentWorkingDirectory()); + auto previousWorkingDirectory = File::getCurrentWorkingDirectory(); file.getParentDirectory().setAsCurrentWorkingDirectory(); if (const VST3Classes::VST3ModuleHandle::Ptr module = VST3Classes::VST3ModuleHandle::findOrCreateModule (file, description)) { ScopedPointer holder = new VST3Classes::VST3ComponentHolder (module); + if (holder->initialise()) { result = new VST3Classes::VST3PluginInstance (holder.release()); + if (! result->initialise()) result = nullptr; } @@ -2841,7 +2823,7 @@ bool VST3PluginFormat::requiresUnblockedMessageThreadDuringCreation (const Plugi bool VST3PluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier) { - const File f (File::createFileWithoutCheckingPath (fileOrIdentifier)); + auto f = File::createFileWithoutCheckingPath (fileOrIdentifier); return f.hasFileExtension (".vst3") #if JUCE_MAC @@ -2882,7 +2864,7 @@ void VST3PluginFormat::recursiveFileSearch (StringArray& results, const File& di while (iter.next()) { - const File f (iter.getFile()); + auto f = iter.getFile(); bool isPlugin = false; if (fileMightContainThisPluginType (f.getFullPathName())) @@ -2899,7 +2881,7 @@ void VST3PluginFormat::recursiveFileSearch (StringArray& results, const File& di FileSearchPath VST3PluginFormat::getDefaultLocationsToSearch() { #if JUCE_WINDOWS - const String programFiles (File::getSpecialLocation (File::globalApplicationsDirectory).getFullPathName()); + auto programFiles = File::getSpecialLocation (File::globalApplicationsDirectory).getFullPathName(); return FileSearchPath (programFiles + "\\Common Files\\VST3"); #elif JUCE_MAC return FileSearchPath ("/Library/Audio/Plug-Ins/VST3;~/Library/Audio/Plug-Ins/VST3"); diff --git a/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h b/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h index e9650e292..4adbcefaf 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h +++ b/source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_VST3PLUGINFORMAT_H_INCLUDED -#define JUCE_VST3PLUGINFORMAT_H_INCLUDED +#pragma once #if (JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS)) || DOXYGEN @@ -65,4 +66,3 @@ private: }; #endif // JUCE_PLUGINHOST_VST3 -#endif // JUCE_VST3PLUGINFORMAT_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format_types/juce_VSTCommon.h b/source/modules/juce_audio_processors/format_types/juce_VSTCommon.h index 1869941d3..7d0a93b95 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VSTCommon.h +++ b/source/modules/juce_audio_processors/format_types/juce_VSTCommon.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_VSTCOMMON_H_INCLUDED -#define JUCE_VSTCOMMON_H_INCLUDED +#pragma once //============================================================================== struct SpeakerMappings : private AudioChannelSet // (inheritance only to give easier access to items in the namespace) @@ -123,19 +124,77 @@ struct SpeakerMappings : private AudioChannelSet // (inheritance only to give e return vstSpeakerConfigTypeUser; } - static void channelSetToVstArrangement (const AudioChannelSet& channels, VstSpeakerConfiguration& result) + class VstSpeakerConfigurationHolder { - result.type = channelSetToVstArrangementType (channels); - result.numberOfChannels = channels.size(); + public: + VstSpeakerConfigurationHolder () { clear(); } + VstSpeakerConfigurationHolder (const VstSpeakerConfiguration& vstConfig) { operator= (vstConfig); } + VstSpeakerConfigurationHolder (const VstSpeakerConfigurationHolder& other) { operator= (other.get()); } + VstSpeakerConfigurationHolder (VstSpeakerConfigurationHolder&& other) : storage (static_cast&&> (other.storage)) { other.clear(); } - for (int i = 0; i < result.numberOfChannels; ++i) + VstSpeakerConfigurationHolder (const AudioChannelSet& channels) { - VstIndividualSpeakerInfo& speaker = result.speakers[i]; + auto numberOfChannels = channels.size(); + VstSpeakerConfiguration& dst = *allocate (numberOfChannels); - zeromem (&speaker, sizeof (VstIndividualSpeakerInfo)); - speaker.type = getSpeakerType (channels.getTypeOfChannel (i)); + dst.type = channelSetToVstArrangementType (channels); + dst.numberOfChannels = numberOfChannels; + + for (int i = 0; i < dst.numberOfChannels; ++i) + { + VstIndividualSpeakerInfo& speaker = dst.speakers[i]; + + zeromem (&speaker, sizeof (VstIndividualSpeakerInfo)); + speaker.type = getSpeakerType (channels.getTypeOfChannel (i)); + } } - } + + VstSpeakerConfigurationHolder& operator= (const VstSpeakerConfigurationHolder& vstConfig) { return operator=(vstConfig.get()); } + VstSpeakerConfigurationHolder& operator= (const VstSpeakerConfiguration& vstConfig) + { + VstSpeakerConfiguration& dst = *allocate (vstConfig.numberOfChannels); + + dst.type = vstConfig.type; + dst.numberOfChannels = vstConfig.numberOfChannels; + + for (int i = 0; i < dst.numberOfChannels; ++i) + dst.speakers[i] = vstConfig.speakers[i]; + + return *this; + } + + VstSpeakerConfigurationHolder& operator= (VstSpeakerConfigurationHolder && vstConfig) + { + storage = static_cast&&> (vstConfig.storage); + vstConfig.clear(); + + return *this; + } + + const VstSpeakerConfiguration& get() const { return *storage.getData(); } + + private: + JUCE_LEAK_DETECTOR (VstSpeakerConfigurationHolder) + + HeapBlock storage; + + VstSpeakerConfiguration* allocate (int numChannels) + { + auto arrangementSize = (sizeof (VstSpeakerConfiguration) - (sizeof(VstIndividualSpeakerInfo) * 8)) + + (sizeof (VstIndividualSpeakerInfo) * static_cast (numChannels)); + + storage.malloc (1, arrangementSize); + return storage.getData(); + } + + void clear() + { + VstSpeakerConfiguration& dst = *allocate (0); + + dst.type = vstSpeakerConfigTypeEmpty; + dst.numberOfChannels = 0; + } + }; static const Mapping* getMappings() noexcept { @@ -234,5 +293,3 @@ struct SpeakerMappings : private AudioChannelSet // (inheritance only to give e return AudioChannelSet::unknown; } }; - -#endif // JUCE_VSTCOMMON_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format_types/juce_VSTInterface.h b/source/modules/juce_audio_processors/format_types/juce_VSTInterface.h index 502f3672b..c8310a002 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VSTInterface.h +++ b/source/modules/juce_audio_processors/format_types/juce_VSTInterface.h @@ -2,27 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. - ============================================================================== + ============================================================================== */ -#ifndef JUCE_VSTINTERFACE_H_INCLUDED +#pragma once #define JUCE_VSTINTERFACE_H_INCLUDED #include "../../juce_core/juce_core.h" @@ -141,7 +143,9 @@ enum VstHostToPlugInOpcodes plugInOpcodeStopProcess, plugInOpcodeSetNumberOfSamplesToProcess, plugInOpcodeSetSampleFloatType = plugInOpcodeSetNumberOfSamplesToProcess + 4, - plugInOpcodeMaximum = plugInOpcodeSetSampleFloatType + pluginOpcodeGetNumMidiInputChannels, + pluginOpcodeGetNumMidiOutputChannels, + plugInOpcodeMaximum = pluginOpcodeGetNumMidiOutputChannels }; @@ -341,7 +345,7 @@ enum VstTimingInformationFlags vstTimingInfoFlagNanosecondsValid = 256, vstTimingInfoFlagMusicalPositionValid = 512, vstTimingInfoFlagTempoValid = 1024, - vstTimingInfoFlagLastBarPositionValid = 2056, + vstTimingInfoFlagLastBarPositionValid = 2048, vstTimingInfoFlagLoopPositionValid = 4096, vstTimingInfoFlagTimeSignatureValid = 8192, vstTimingInfoFlagSmpteValid = 16384, @@ -447,6 +451,34 @@ enum VstSpeakerConfigurationType vstSpeakerConfigTypeLRCLfeLsRsTflTfcTfrTrlTrrLfe2 }; +#if JUCE_BIG_ENDIAN + #define JUCE_MULTICHAR_CONSTANT(a, b, c, d) (a | (((uint32) b) << 8) | (((uint32) c) << 16) | (((uint32) d) << 24)) +#else + #define JUCE_MULTICHAR_CONSTANT(a, b, c, d) (d | (((uint32) c) << 8) | (((uint32) b) << 16) | (((uint32) a) << 24)) +#endif + +enum PresonusExtensionConstants +{ + presonusVendorID = JUCE_MULTICHAR_CONSTANT ('P', 'r', 'e', 'S'), + presonusSetContentScaleFactor = JUCE_MULTICHAR_CONSTANT ('A', 'e', 'C', 's') +}; + +//============================================================================== +struct vst2FxBank +{ + int32 magic1; + int32 size; + int32 magic2; + int32 version1; + int32 fxID; + int32 version2; + int32 elements; + int32 current; + char shouldBeZero[124]; + int32 chunkSize; + char chunk[1]; +}; + #if JUCE_MSVC #pragma pack(pop) #elif JUCE_MAC || JUCE_IOS @@ -454,5 +486,3 @@ enum VstSpeakerConfigurationType #else #pragma pack(pop) #endif - -#endif // JUCE_VSTINTERFACE_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h b/source/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h index 2d486a59b..d78d7e0db 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h +++ b/source/modules/juce_audio_processors/format_types/juce_VSTMidiEventList.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -25,8 +27,7 @@ // NB: this must come first, *before* the header-guard. #ifdef JUCE_VSTINTERFACE_H_INCLUDED -#ifndef JUCE_VSTMIDIEVENTLIST_H_INCLUDED -#define JUCE_VSTMIDIEVENTLIST_H_INCLUDED +#pragma once //============================================================================== /** Holds a set of VSTMidiEvent objects and makes it easy to add @@ -184,5 +185,4 @@ private: } }; -#endif // JUCE_VSTMIDIEVENTLIST_H_INCLUDED -#endif // JUCE_VSTMIDIEVENTLIST_H_INCLUDED +#endif // JUCE_VSTINTERFACE_H_INCLUDED diff --git a/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 9e5418e0f..11e311d68 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -2,27 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS) +#if JUCE_PLUGINHOST_VST //============================================================================== #if JUCE_MAC && JUCE_SUPPORT_CARBON @@ -41,7 +43,7 @@ namespace Vst2 { -#include "juce_VSTInterface.h" + #include "juce_VSTInterface.h" } using namespace Vst2; @@ -142,8 +144,8 @@ namespace || magic == (int32) ByteOrder::bigEndianInt (name); } - static int32 fxbName (const char* name) noexcept { return (int32) ByteOrder::littleEndianInt (name); } - static int32 fxbSwap (const int32 x) noexcept { return (int32) ByteOrder::swapIfLittleEndian ((uint32) x); } + static int32 fxbName (const char* name) noexcept { return (int32) ByteOrder::littleEndianInt (name); } + static int32 fxbSwap (int32 x) noexcept { return (int32) ByteOrder::swapIfLittleEndian ((uint32) x); } static float fxbSwapFloat (const float x) noexcept { @@ -165,7 +167,7 @@ namespace { #if JUCE_WINDOWS return timeGetTime() * 1000000.0; - #elif JUCE_LINUX || JUCE_IOS + #elif JUCE_LINUX || JUCE_IOS || JUCE_ANDROID timeval micro; gettimeofday (µ, 0); return micro.tv_usec * 1000.0; @@ -207,7 +209,7 @@ namespace //============================================================================== typedef VstEffectInterface* (VSTINTERFACECALL *MainCall) (VstHostCallback); -static pointer_sized_int VSTINTERFACECALL audioMaster (VstEffectInterface* effect, int32 opcode, int32 index, pointer_sized_int value, void* ptr, float opt); +static pointer_sized_int VSTINTERFACECALL audioMaster (VstEffectInterface*, int32, int32, pointer_sized_int, void*, float); //============================================================================== // Change this to disable logging of various VST activities @@ -224,14 +226,11 @@ static pointer_sized_int VSTINTERFACECALL audioMaster (VstEffectInterface* effec //============================================================================== #if JUCE_LINUX -extern Display* display; -extern XContext windowHandleXContext; - namespace { static bool xErrorTriggered = false; - static int temporaryErrorHandler (Display*, XErrorEvent*) + static int temporaryErrorHandler (::Display*, XErrorEvent*) { xErrorTriggered = true; return 0; @@ -249,8 +248,12 @@ namespace unsigned char* data; Atom userType; - XGetWindowProperty (display, handle, atom, 0, 1, false, AnyPropertyType, - &userType, &userSize, &userCount, &bytes, &data); + { + ScopedXDisplay xDisplay; + + XGetWindowProperty (xDisplay.display, handle, atom, 0, 1, false, AnyPropertyType, + &userType, &userSize, &userCount, &bytes, &data); + } XSetErrorHandler (oldErrorHandler); @@ -263,7 +266,10 @@ namespace Window* childWindows; unsigned int numChildren = 0; - XQueryTree (display, windowToCheck, &rootWindow, &parentWindow, &childWindows, &numChildren); + { + ScopedXDisplay xDisplay; + XQueryTree (xDisplay.display, windowToCheck, &rootWindow, &parentWindow, &childWindows, &numChildren); + } if (numChildren > 0) return childWindows [0]; @@ -324,12 +330,10 @@ namespace #endif //============================================================================== -class ModuleHandle : public ReferenceCountedObject +struct ModuleHandle : public ReferenceCountedObject { -public: - //============================================================================== File file; - MainCall moduleMain, customMain; + MainCall moduleMain, customMain = {}; String pluginName; ScopedPointer vstXml; @@ -344,13 +348,9 @@ public: //============================================================================== static Ptr findOrCreateModule (const File& file) { - for (int i = getActiveModules().size(); --i >= 0;) - { - ModuleHandle* const module = getActiveModules().getUnchecked(i); - + for (auto* module : getActiveModules()) if (module->file == file) return module; - } const IdleCallRecursionPreventer icrp; shellUIDToCreate = 0; @@ -366,22 +366,16 @@ public: return m; } - return nullptr; + return {}; } //============================================================================== ModuleHandle (const File& f, MainCall customMainCall) - : file (f), moduleMain (customMainCall), customMain (nullptr) - #if JUCE_MAC || JUCE_IOS - , resHandle (0), bundleRef (0) - #if JUCE_MAC - , resFileId (0) - #endif - #endif + : file (f), moduleMain (customMainCall) { getActiveModules().add (this); - #if JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS + #if JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS || JUCE_ANDROID fullParentDirectoryPathName = f.getParentDirectory().getFullPathName(); #elif JUCE_MAC FSRef ref; @@ -401,7 +395,7 @@ public: String fullParentDirectoryPathName; #endif - #if JUCE_WINDOWS || JUCE_LINUX + #if JUCE_WINDOWS || JUCE_LINUX || JUCE_ANDROID DynamicLibrary module; bool open() @@ -449,29 +443,29 @@ public: static String getDLLResource (const File& dllFile, const String& type, int resID) { DynamicLibrary dll (dllFile.getFullPathName()); - HMODULE dllModule = (HMODULE) dll.getNativeHandle(); + auto dllModule = (HMODULE) dll.getNativeHandle(); if (dllModule != INVALID_HANDLE_VALUE) { - if (HRSRC res = FindResource (dllModule, MAKEINTRESOURCE (resID), type.toWideCharPointer())) + if (auto res = FindResource (dllModule, MAKEINTRESOURCE (resID), type.toWideCharPointer())) { - if (HGLOBAL hGlob = LoadResource (dllModule, res)) + if (auto hGlob = LoadResource (dllModule, res)) { - const char* data = static_cast (LockResource (hGlob)); + auto* data = static_cast (LockResource (hGlob)); return String::fromUTF8 (data, SizeofResource (dllModule, res)); } } } - return String(); + return {}; } #endif #else - Handle resHandle; - CFBundleRef bundleRef; + Handle resHandle = {}; + CFBundleRef bundleRef = {}; #if JUCE_MAC - CFBundleRefNum resFileId; + CFBundleRefNum resFileId = {}; FSSpec parentDirFSSpec; #endif @@ -484,7 +478,7 @@ public: if (file.hasFileExtension (".vst")) { - const char* const utf8 = file.getFullPathName().toRawUTF8(); + auto* utf8 = file.getFullPathName().toRawUTF8(); if (CFURLRef url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*) utf8, (CFIndex) strlen (utf8), file.isDirectory())) @@ -588,23 +582,20 @@ static const int defaultVSTBlockSizeValue = 512; //============================================================================== //============================================================================== -class VSTPluginInstance : public AudioPluginInstance, - private Timer, - private AsyncUpdater +struct VSTPluginInstance : public AudioPluginInstance, + private Timer, + private AsyncUpdater { -private: - VSTPluginInstance (const ModuleHandle::Ptr& mh, const BusesProperties& ioConfig, VstEffectInterface* effect) + VSTPluginInstance (const ModuleHandle::Ptr& mh, const BusesProperties& ioConfig, VstEffectInterface* effect, + double sampleRateToUse, int blockSizeToUse) : AudioPluginInstance (ioConfig), vstEffect (effect), vstModule (mh), - usesCocoaNSView (false), - name (mh->pluginName), - wantsMidiMessages (false), - initialised (false), - isPowerOn (false) - {} + name (mh->pluginName) + { + setRateAndBufferSizeDetails (sampleRateToUse, blockSizeToUse); + } -public: ~VSTPluginInstance() { if (vstEffect != nullptr && vstEffect->interfaceIdentifier == juceVstInterfaceIdentifier) @@ -663,23 +654,21 @@ public: double initialSampleRate, int initialBlockSize) { - if (VstEffectInterface* newEffect = constructEffect (newModule)) + if (auto* newEffect = constructEffect (newModule)) { newEffect->hostSpace2 = 0; newEffect->dispatchFunction (newEffect, plugInOpcodeIdentify, 0, 0, 0, 0); + auto blockSize = jmax (32, initialBlockSize); + newEffect->dispatchFunction (newEffect, plugInOpcodeSetSampleRate, 0, 0, 0, static_cast (initialSampleRate)); - newEffect->dispatchFunction (newEffect, plugInOpcodeSetBlockSize, 0, jmax (32, initialBlockSize), 0, 0); + newEffect->dispatchFunction (newEffect, plugInOpcodeSetBlockSize, 0, blockSize, 0, 0); newEffect->dispatchFunction (newEffect, plugInOpcodeOpen, 0, 0, 0, 0); BusesProperties ioConfig = queryBusIO (newEffect); - newEffect->dispatchFunction (newEffect, plugInOpcodeClose, 0, 0, 0, 0); - - newEffect = constructEffect (newModule); - if (newEffect != nullptr) - return new VSTPluginInstance (newModule, ioConfig, newEffect); + return new VSTPluginInstance (newModule, ioConfig, newEffect, initialSampleRate, blockSize); } return nullptr; @@ -816,13 +805,12 @@ public: if (vstEffect == nullptr) return 0.0; - const double sampleRate = getSampleRate(); + auto sampleRate = getSampleRate(); if (sampleRate <= 0) return 0.0; - pointer_sized_int samples = dispatch (plugInOpcodeGetTailSize, 0, 0, 0, 0); - return samples / sampleRate; + return dispatch (plugInOpcodeGetTailSize, 0, 0, 0, 0) / sampleRate; } bool acceptsMidi() const override { return wantsMidiMessages; } @@ -838,16 +826,14 @@ public: { setRateAndBufferSizeDetails (rate, samplesPerBlockExpected); - VstSpeakerConfiguration inArr, outArr; + SpeakerMappings::VstSpeakerConfigurationHolder inArr (getChannelLayoutOfBus (true, 0)); + SpeakerMappings::VstSpeakerConfigurationHolder outArr (getChannelLayoutOfBus (false, 0)); - SpeakerMappings::channelSetToVstArrangement (getChannelLayoutOfBus (true, 0), inArr); - SpeakerMappings::channelSetToVstArrangement (getChannelLayoutOfBus (false, 0), outArr); - - dispatch (plugInOpcodeSetSpeakerConfiguration, 0, reinterpret_cast (&inArr), &outArr, 0.0f); + dispatch (plugInOpcodeSetSpeakerConfiguration, 0, (pointer_sized_int) &inArr.get(), (void*) &outArr.get(), 0.0f); vstHostTime.tempoBPM = 120.0; vstHostTime.timeSignatureNumerator = 4; - vstHostTime.timeSignatureDenominator = 4; + vstHostTime.timeSignatureDenominator = 4; vstHostTime.sampleRate = rate; vstHostTime.samplePosition = 0; vstHostTime.flags = vstTimingInfoFlagNanosecondsValid @@ -878,7 +864,15 @@ public: dispatch (plugInOpcodeSetSampleFloatType, 0, (pointer_sized_int) vstPrecision, 0, 0); } - tempBuffer.setSize (jmax (1, vstEffect->numInputChannels), samplesPerBlockExpected); + auto maxChannels = jmax (1, jmax (vstEffect->numInputChannels, vstEffect->numOutputChannels)); + + tmpBufferFloat .setSize (maxChannels, samplesPerBlockExpected); + tmpBufferDouble.setSize (maxChannels, samplesPerBlockExpected); + + channelBufferFloat .calloc (static_cast (maxChannels)); + channelBufferDouble.calloc (static_cast (maxChannels)); + + outOfPlaceBuffer.setSize (jmax (1, vstEffect->numOutputChannels), samplesPerBlockExpected); if (! isPowerOn) setPower (true); @@ -886,7 +880,7 @@ public: // dodgy hack to force some plugins to initialise the sample rate.. if ((! hasEditor()) && getNumParameters() > 0) { - const float old = getParameter (0); + auto old = getParameter (0); setParameter (0, (old < 0.5f) ? 1.0f : 0.0f); setParameter (0, old); } @@ -905,7 +899,13 @@ public: setPower (false); } - tempBuffer.setSize (1, 1); + channelBufferFloat.free(); + tmpBufferFloat.setSize (0, 0); + + channelBufferDouble.free(); + tmpBufferDouble.setSize (0, 0); + + outOfPlaceBuffer.setSize (1, 1); incomingMidi.clear(); midiEventsToSend.freeEvents(); @@ -923,13 +923,13 @@ public: void processBlock (AudioBuffer& buffer, MidiBuffer& midiMessages) override { jassert (! isUsingDoublePrecision()); - processAudio (buffer, midiMessages); + processAudio (buffer, midiMessages, tmpBufferFloat, channelBufferFloat); } void processBlock (AudioBuffer& buffer, MidiBuffer& midiMessages) override { jassert (isUsingDoublePrecision()); - processAudio (buffer, midiMessages); + processAudio (buffer, midiMessages, tmpBufferDouble, channelBufferDouble); } bool supportsDoublePrecisionProcessing() const override @@ -944,8 +944,8 @@ public: bool isBusesLayoutSupported (const BusesLayout& layouts) const override { - const int numInputBuses = getBusCount (true); - const int numOutputBuses = getBusCount (false); + auto numInputBuses = getBusCount (true); + auto numOutputBuses = getBusCount (false); // it's not possible to change layout if there are sidechains/aux buses if (numInputBuses > 1 || numOutputBuses > 1) @@ -956,7 +956,7 @@ public: } //============================================================================== - #if JUCE_IOS + #if JUCE_IOS || JUCE_ANDROID bool hasEditor() const override { return false; } #else bool hasEditor() const override { return vstEffect != nullptr && (vstEffect->flags & vstEffectFlagHasEditor) != 0; } @@ -974,7 +974,7 @@ public: return String (pinProps.text, sizeof (pinProps.text)); } - return String(); + return {}; } bool isInputChannelStereoPair (int index) const override @@ -998,7 +998,7 @@ public: return String (pinProps.text, sizeof (pinProps.text)); } - return String(); + return {}; } bool isOutputChannelStereoPair (int index) const override @@ -1206,7 +1206,7 @@ public: } //============================================================================== - pointer_sized_int dispatch (const int opcode, const int index, const pointer_sized_int value, void* const ptr, float opt) const + pointer_sized_int dispatch (int opcode, int index, pointer_sized_int value, void* const ptr, float opt) const { pointer_sized_int result = 0; @@ -1218,7 +1218,7 @@ public: try { #if JUCE_MAC - const ResFileRefNum oldResFile = CurResFile(); + auto oldResFile = CurResFile(); if (vstModule->resFileId != 0) UseResFile (vstModule->resFileId); @@ -1227,7 +1227,8 @@ public: result = vstEffect->dispatchFunction (vstEffect, opcode, index, value, ptr, opt); #if JUCE_MAC - const ResFileRefNum newResFile = CurResFile(); + auto newResFile = CurResFile(); + if (newResFile != oldResFile) // avoid confusing the parent app's resource file with the plug-in's { vstModule->resFileId = newResFile; @@ -1247,7 +1248,7 @@ public: if (dataSize < 28) return false; - const fxSet* const set = (const fxSet*) data; + auto set = (const fxSet*) data; if ((! compareMagic (set->chunkMagic, "CcnK")) || fxbSwap (set->version) > fxbVersionNum) return false; @@ -1257,15 +1258,16 @@ public: // bank of programs if (fxbSwap (set->numPrograms) >= 0) { - const int oldProg = getCurrentProgram(); - const int numParams = fxbSwap (((const fxProgram*) (set->programs))->numParams); - const int progLen = (int) sizeof (fxProgram) + (numParams - 1) * (int) sizeof (float); + auto oldProg = getCurrentProgram(); + auto numParams = fxbSwap (((const fxProgram*) (set->programs))->numParams); + auto progLen = (int) sizeof (fxProgram) + (numParams - 1) * (int) sizeof (float); for (int i = 0; i < fxbSwap (set->numPrograms); ++i) { if (i != oldProg) { - const fxProgram* const prog = (const fxProgram*) (((const char*) (set->programs)) + i * progLen); + auto prog = (const fxProgram*) (((const char*) (set->programs)) + i * progLen); + if (((const char*) prog) - ((const char*) set) >= (ssize_t) dataSize) return false; @@ -1280,7 +1282,8 @@ public: if (fxbSwap (set->numPrograms) > 0) setCurrentProgram (oldProg); - const fxProgram* const prog = (const fxProgram*) (((const char*) (set->programs)) + oldProg * progLen); + auto prog = (const fxProgram*) (((const char*) (set->programs)) + oldProg * progLen); + if (((const char*) prog) - ((const char*) set) >= (ssize_t) dataSize) return false; @@ -1291,7 +1294,7 @@ public: else if (compareMagic (set->fxMagic, "FxCk")) { // single program - const fxProgram* const prog = (const fxProgram*) data; + auto prog = (const fxProgram*) data; if (! compareMagic (prog->chunkMagic, "CcnK")) return false; @@ -1304,7 +1307,7 @@ public: else if (compareMagic (set->fxMagic, "FBCh")) { // non-preset chunk - const fxChunkSet* const cset = (const fxChunkSet*) data; + auto cset = (const fxChunkSet*) data; if ((size_t) fxbSwap (cset->chunkSize) + sizeof (fxChunkSet) - 8 > (size_t) dataSize) return false; @@ -1314,7 +1317,7 @@ public: else if (compareMagic (set->fxMagic, "FPCh")) { // preset chunk - const fxProgramSet* const cset = (const fxProgramSet*) data; + auto cset = (const fxProgramSet*) data; if ((size_t) fxbSwap (cset->chunkSize) + sizeof (fxProgramSet) - 8 > (size_t) dataSize) return false; @@ -1333,8 +1336,8 @@ public: bool saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB = 128) { - const int numPrograms = getNumPrograms(); - const int numParams = getNumParameters(); + auto numPrograms = getNumPrograms(); + auto numParams = getNumParameters(); if (usesChunks()) { @@ -1343,10 +1346,10 @@ public: if (isFXB) { - const size_t totalLen = sizeof (fxChunkSet) + chunk.getSize() - 8; + auto totalLen = sizeof (fxChunkSet) + chunk.getSize() - 8; dest.setSize (totalLen, true); - fxChunkSet* const set = (fxChunkSet*) dest.getData(); + auto set = (fxChunkSet*) dest.getData(); set->chunkMagic = fxbName ("CcnK"); set->byteSize = 0; set->fxMagic = fxbName ("FBCh"); @@ -1360,10 +1363,10 @@ public: } else { - const size_t totalLen = sizeof (fxProgramSet) + chunk.getSize() - 8; + auto totalLen = sizeof (fxProgramSet) + chunk.getSize() - 8; dest.setSize (totalLen, true); - fxProgramSet* const set = (fxProgramSet*) dest.getData(); + auto set = (fxProgramSet*) dest.getData(); set->chunkMagic = fxbName ("CcnK"); set->byteSize = 0; set->fxMagic = fxbName ("FPCh"); @@ -1381,11 +1384,11 @@ public: { if (isFXB) { - const int progLen = (int) sizeof (fxProgram) + (numParams - 1) * (int) sizeof (float); - const size_t len = (sizeof (fxSet) - sizeof (fxProgram)) + (size_t) (progLen * jmax (1, numPrograms)); + auto progLen = (int) sizeof (fxProgram) + (numParams - 1) * (int) sizeof (float); + auto len = (sizeof (fxSet) - sizeof (fxProgram)) + (size_t) (progLen * jmax (1, numPrograms)); dest.setSize (len, true); - fxSet* const set = (fxSet*) dest.getData(); + auto set = (fxSet*) dest.getData(); set->chunkMagic = fxbName ("CcnK"); set->byteSize = 0; set->fxMagic = fxbName ("FxBk"); @@ -1397,7 +1400,7 @@ public: MemoryBlock oldSettings; createTempParameterStore (oldSettings); - const int oldProgram = getCurrentProgram(); + auto oldProgram = getCurrentProgram(); if (oldProgram >= 0) setParamsInProgramBlock ((fxProgram*) (((char*) (set->programs)) + oldProgram * progLen)); @@ -1433,7 +1436,7 @@ public: if (usesChunks()) { void* data = nullptr; - const size_t bytes = (size_t) dispatch (plugInOpcodeGetData, isPreset ? 1 : 0, 0, &data, 0.0f); + auto bytes = (size_t) dispatch (plugInOpcodeGetData, isPreset ? 1 : 0, 0, &data, 0.0f); if (data != nullptr && bytes <= (size_t) maxSizeMB * 1024 * 1024) { @@ -1466,19 +1469,26 @@ public: ModuleHandle::Ptr vstModule; ScopedPointer extraFunctions; - bool usesCocoaNSView; + bool usesCocoaNSView = false; private: String name; CriticalSection lock; - bool wantsMidiMessages, initialised, isPowerOn; + bool wantsMidiMessages = false, initialised = false, isPowerOn = false; mutable StringArray programNames; - AudioBuffer tempBuffer; + AudioBuffer outOfPlaceBuffer; + CriticalSection midiInLock; MidiBuffer incomingMidi; VSTMidiEventList midiEventsToSend; VstTimingInformation vstHostTime; + AudioBuffer tmpBufferFloat; + HeapBlock channelBufferFloat; + + AudioBuffer tmpBufferDouble; + HeapBlock channelBufferDouble; + static pointer_sized_int handleCanDo (const char* name) { static const char* canDos[] = { "supplyIdle", @@ -1502,7 +1512,7 @@ private: { String hostName ("Juce VST Host"); - if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance()) + if (auto* app = JUCEApplicationBase::getInstance()) hostName = app->getApplicationName(); hostName.copyToUTF8 (name, (size_t) jmin (vstMaxManufacturerStringLength, vstMaxPlugInNameStringLength) - 1); @@ -1538,14 +1548,14 @@ private: handleUpdateNowIfNeeded(); for (int i = ComponentPeer::getNumPeers(); --i >= 0;) - if (ComponentPeer* p = ComponentPeer::getPeer(i)) + if (auto* p = ComponentPeer::getPeer(i)) p->performAnyPendingRepaintsNow(); } } void setWindowSize (int width, int height) { - if (AudioProcessorEditor* ed = getActiveEditor()) + if (auto* ed = getActiveEditor()) { #if JUCE_LINUX const MessageManagerLock mmLock; @@ -1596,8 +1606,30 @@ private: { BusesProperties returnValue; - VstSpeakerConfiguration* inArr = nullptr, *outArr = nullptr; - if (effect->dispatchFunction (effect, plugInOpcodeGetSpeakerArrangement, 0, reinterpret_cast (&inArr), &outArr, 0.0f) == 0) + if (effect->numInputChannels == 0 && effect->numOutputChannels == 0) + return returnValue; + + // Workaround for old broken JUCE plug-ins which would return an invalid + // speaker arrangement if the host didn't ask for a specific arrangement + // beforehand. + // Check if the plug-in reports any default layouts. If it doesn't, then + // try setting a default layout compatible with the number of pins this + // plug-in is reporting. + if (! pluginHasDefaultChannelLayouts (effect)) + { + SpeakerMappings::VstSpeakerConfigurationHolder canonicalIn (AudioChannelSet::canonicalChannelSet (effect->numInputChannels)); + SpeakerMappings::VstSpeakerConfigurationHolder canonicalOut (AudioChannelSet::canonicalChannelSet (effect->numOutputChannels)); + + effect->dispatchFunction (effect, plugInOpcodeSetSpeakerConfiguration, 0, + (pointer_sized_int) &canonicalIn.get(), (void*) &canonicalOut.get(), 0.0f); + } + + HeapBlock inArrBlock (1, true), outArrBlock (1, true); + + auto* inArr = inArrBlock.getData(); + auto* outArr = outArrBlock.getData(); + + if (! getSpeakerArrangementWrapper (effect, inArr, outArr)) inArr = outArr = nullptr; for (int dir = 0; dir < 2; ++dir) @@ -1610,6 +1642,7 @@ private: VstPinInfo pinProps; AudioChannelSet layout; + for (int ch = 0; ch < maxChannels; ch += layout.size()) { if (effect->dispatchFunction (effect, opcode, ch, 0, &pinProps, 0.0f) == 0) @@ -1618,13 +1651,16 @@ private: if ((pinProps.flags & vstPinInfoFlagValid) != 0) { layout = SpeakerMappings::vstArrangementTypeToChannelSet (pinProps.configurationType, 0); + if (layout.isDisabled()) break; } - else + else if (arr == nullptr) { layout = ((pinProps.flags & vstPinInfoFlagIsStereo) != 0 ? AudioChannelSet::stereo() : AudioChannelSet::mono()); } + else + break; busAdded = true; returnValue.addBus (isInput, pinProps.text, layout, true); @@ -1634,6 +1670,7 @@ private: if (! busAdded && maxChannels > 0) { String busName = (isInput ? "Input" : "Output"); + if (effect->dispatchFunction (effect, opcode, 0, 0, &pinProps, 0.0f) != 0) busName = pinProps.text; @@ -1649,15 +1686,68 @@ private: return returnValue; } + static bool pluginHasDefaultChannelLayouts (VstEffectInterface* effect) + { + HeapBlock inArrBlock (1, true), outArrBlock (1, true); + + auto* inArr = inArrBlock.getData(); + auto* outArr = outArrBlock.getData(); + + if (getSpeakerArrangementWrapper (effect, inArr, outArr)) + return true; + + for (int dir = 0; dir < 2; ++dir) + { + const bool isInput = (dir == 0); + const int opcode = (isInput ? plugInOpcodeGetInputPinProperties : plugInOpcodeGetOutputPinProperties); + const int maxChannels = (isInput ? effect->numInputChannels : effect->numOutputChannels); + + int channels = 1; + + for (int ch = 0; ch < maxChannels; ch += channels) + { + VstPinInfo pinProps; + + if (effect->dispatchFunction (effect, opcode, ch, 0, &pinProps, 0.0f) == 0) + return false; + + if ((pinProps.flags & vstPinInfoFlagValid) != 0) + return true; + + channels = (pinProps.flags & vstPinInfoFlagIsStereo) != 0 ? 2 : 1; + } + } + + return false; + } + + static bool getSpeakerArrangementWrapper (VstEffectInterface* effect, + VstSpeakerConfiguration* inArr, + VstSpeakerConfiguration* outArr) + { + // Workaround: unfortunately old JUCE VST-2 plug-ins had a bug and would crash if + // you try to get the speaker arrangement when there are no input channels present. + // Hopefully, one day (when there are no more old JUCE plug-ins around), we can + // commment out the next two lines. + if (effect->numInputChannels == 0) + return false; + + return (effect->dispatchFunction (effect, plugInOpcodeGetSpeakerArrangement, 0, + reinterpret_cast (&inArr), &outArr, 0.0f) != 0); + } + //============================================================================== template - void processAudio (AudioBuffer& buffer, MidiBuffer& midiMessages) + void processAudio (AudioBuffer& buffer, MidiBuffer& midiMessages, + AudioBuffer& tmpBuffer, + HeapBlock& channelBuffer) { - const int numSamples = buffer.getNumSamples(); + auto numSamples = buffer.getNumSamples(); + auto numChannels = buffer.getNumChannels(); if (initialised) { - if (AudioPlayHead* const currentPlayHead = getPlayHead()) + if (auto* currentPlayHead = getPlayHead()) { AudioPlayHead::CurrentPositionInfo position; @@ -1687,12 +1777,15 @@ private: switch (position.frameRate) { - case AudioPlayHead::fps24: setHostTimeFrameRate (0, 24.0, position.timeInSeconds); break; - case AudioPlayHead::fps25: setHostTimeFrameRate (1, 25.0, position.timeInSeconds); break; - case AudioPlayHead::fps2997: setHostTimeFrameRate (2, 29.97, position.timeInSeconds); break; - case AudioPlayHead::fps30: setHostTimeFrameRate (3, 30.0, position.timeInSeconds); break; - case AudioPlayHead::fps2997drop: setHostTimeFrameRate (4, 29.97, position.timeInSeconds); break; - case AudioPlayHead::fps30drop: setHostTimeFrameRate (5, 29.97, position.timeInSeconds); break; + case AudioPlayHead::fps24: setHostTimeFrameRate (vstSmpteRateFps24, 24.0, position.timeInSeconds); break; + case AudioPlayHead::fps25: setHostTimeFrameRate (vstSmpteRateFps25, 25.0, position.timeInSeconds); break; + case AudioPlayHead::fps30: setHostTimeFrameRate (vstSmpteRateFps30, 30.0, position.timeInSeconds); break; + case AudioPlayHead::fps60: setHostTimeFrameRate (vstSmpteRateFps60, 60.0, position.timeInSeconds); break; + + case AudioPlayHead::fps2997: setHostTimeFrameRateDrop (vstSmpteRateFps2997, 30.0, position.timeInSeconds); break; + case AudioPlayHead::fps2997drop: setHostTimeFrameRateDrop (vstSmpteRateFps2997drop, 30.0, position.timeInSeconds); break; + case AudioPlayHead::fps30drop: setHostTimeFrameRateDrop (vstSmpteRateFps30drop, 30.0, position.timeInSeconds); break; + case AudioPlayHead::fps60drop: setHostTimeFrameRateDrop (vstSmpteRateFps599, 60.0, position.timeInSeconds); break; default: break; } @@ -1721,17 +1814,34 @@ private: int numBytesOfMidiData, samplePosition; while (iter.getNextEvent (midiData, numBytesOfMidiData, samplePosition)) - { midiEventsToSend.addEvent (midiData, numBytesOfMidiData, jlimit (0, numSamples - 1, samplePosition)); - } vstEffect->dispatchFunction (vstEffect, plugInOpcodePreAudioProcessingEvents, 0, 0, midiEventsToSend.events, 0); } _clearfp(); - invokeProcessFunction (buffer, numSamples); + // always ensure that the buffer is at least as large as the maximum number of channels + auto maxChannels = jmax (vstEffect->numInputChannels, vstEffect->numOutputChannels); + auto channels = channelBuffer.getData(); + + if (numChannels < maxChannels) + { + if (numSamples > tmpBuffer.getNumSamples()) + tmpBuffer.setSize (tmpBuffer.getNumChannels(), numSamples); + + tmpBuffer.clear(); + } + + for (int ch = 0; ch < maxChannels; ++ch) + channels[ch] = (ch < numChannels ? buffer.getWritePointer (ch) : tmpBuffer.getWritePointer (ch)); + + { + AudioBuffer processBuffer (channels, maxChannels, numSamples); + + invokeProcessFunction (processBuffer, numSamples); + } } else { @@ -1754,31 +1864,39 @@ private: { if ((vstEffect->flags & vstEffectFlagInplaceAudio) != 0) { - vstEffect->processAudioInplaceFunction (vstEffect, buffer.getArrayOfWritePointers(), buffer.getArrayOfWritePointers(), sampleFrames); + vstEffect->processAudioInplaceFunction (vstEffect, buffer.getArrayOfWritePointers(), + buffer.getArrayOfWritePointers(), sampleFrames); } else { - tempBuffer.setSize (vstEffect->numOutputChannels, sampleFrames); - tempBuffer.clear(); + outOfPlaceBuffer.setSize (vstEffect->numOutputChannels, sampleFrames); + outOfPlaceBuffer.clear(); - vstEffect->processAudioFunction (vstEffect, buffer.getArrayOfWritePointers(), tempBuffer.getArrayOfWritePointers(), sampleFrames); + vstEffect->processAudioFunction (vstEffect, buffer.getArrayOfWritePointers(), + outOfPlaceBuffer.getArrayOfWritePointers(), sampleFrames); for (int i = vstEffect->numOutputChannels; --i >= 0;) - buffer.copyFrom (i, 0, tempBuffer.getReadPointer (i), sampleFrames); + buffer.copyFrom (i, 0, outOfPlaceBuffer.getReadPointer (i), sampleFrames); } } inline void invokeProcessFunction (AudioBuffer& buffer, int32 sampleFrames) { - vstEffect->processDoubleAudioInplaceFunction (vstEffect, buffer.getArrayOfWritePointers(), buffer.getArrayOfWritePointers(), sampleFrames); + vstEffect->processDoubleAudioInplaceFunction (vstEffect, buffer.getArrayOfWritePointers(), + buffer.getArrayOfWritePointers(), sampleFrames); } //============================================================================== void setHostTimeFrameRate (long frameRateIndex, double frameRate, double currentTime) noexcept { vstHostTime.flags |= vstTimingInfoFlagSmpteValid; - vstHostTime.smpteRate = (int32) frameRateIndex; - vstHostTime.smpteOffset = (int32) (currentTime * 80.0 * frameRate + 0.5); + vstHostTime.smpteRate = (int32) frameRateIndex; + vstHostTime.smpteOffset = (int32) (currentTime * 80.0 * frameRate + 0.5); + } + + void setHostTimeFrameRateDrop (long frameRateIndex, double frameRate, double currentTime) noexcept + { + setHostTimeFrameRate (frameRateIndex, frameRate * 1000.0 / 1001.0, currentTime); } bool restoreProgramSettings (const fxProgram* const prog) @@ -1800,7 +1918,7 @@ private: String getTextForOpcode (const int index, const VstHostToPlugInOpcodes opcode) const { if (vstEffect == nullptr) - return String(); + return {}; jassert (index >= 0 && index < vstEffect->numParameters); char nm[256] = { 0 }; @@ -1834,9 +1952,9 @@ private: return progName; } - void setParamsInProgramBlock (fxProgram* const prog) + void setParamsInProgramBlock (fxProgram* prog) { - const int numParams = getNumParameters(); + auto numParams = getNumParameters(); prog->chunkMagic = fxbName ("CcnK"); prog->byteSize = 0; @@ -1861,7 +1979,7 @@ private: // only do this if the plugin can't use indexed names.. if (dispatch (plugInOpcodeGetProgramName, 0, -1, nm, 0) == 0) { - const int oldProgram = getCurrentProgram(); + auto oldProgram = getCurrentProgram(); MemoryBlock oldSettings; createTempParameterStore (oldSettings); @@ -1877,7 +1995,7 @@ private: } } - void handleMidiFromPlugin (const VstEventBlock* const events) + void handleMidiFromPlugin (const VstEventBlock* events) { if (events != nullptr) { @@ -1894,7 +2012,8 @@ private: getCurrentProgramName().copyToUTF8 ((char*) dest.getData(), 63); - float* const p = (float*) (((char*) dest.getData()) + 64); + auto p = (float*) (((char*) dest.getData()) + 64); + for (int i = 0; i < getNumParameters(); ++i) p[i] = getParameter(i); } @@ -1903,7 +2022,8 @@ private: { changeProgramName (getCurrentProgram(), (const char*) m.getData()); - float* p = (float*) (((char*) m.getData()) + 64); + auto p = (float*) (((char*) m.getData()) + 64); + for (int i = 0; i < getNumParameters(); ++i) setParameter (i, p[i]); } @@ -1922,7 +2042,7 @@ private: String getVersion() const { - unsigned int v = (unsigned int) dispatch (plugInOpcodeGetManufacturerVersion, 0, 0, 0, 0); + auto v = (unsigned int) dispatch (plugInOpcodeGetManufacturerVersion, 0, 0, 0, 0); String s; @@ -1934,14 +2054,14 @@ private: int versionBits[32]; int n = 0; - for (unsigned int vv = v; vv != 0; vv /= 10) + for (auto vv = v; vv != 0; vv /= 10) versionBits [n++] = vv % 10; if (n > 4) // if the number ends up silly, it's probably encoded as hex instead of decimal.. { n = 0; - for (unsigned int vv = v; vv != 0; vv >>= 8) + for (auto vv = v; vv != 0; vv >>= 8) versionBits [n++] = vv & 255; } @@ -1991,16 +2111,16 @@ private: }; //============================================================================== -#if ! JUCE_IOS -class VSTPluginWindow; +#if ! (JUCE_IOS || JUCE_ANDROID) +struct VSTPluginWindow; static Array activeVSTWindows; //============================================================================== -class VSTPluginWindow : public AudioProcessorEditor, - #if ! JUCE_MAC - public ComponentMovementWatcher, - #endif - public Timer +struct VSTPluginWindow : public AudioProcessorEditor, + #if ! JUCE_MAC + private ComponentMovementWatcher, + #endif + private Timer { public: VSTPluginWindow (VSTPluginInstance& plug) @@ -2008,20 +2128,11 @@ public: #if ! JUCE_MAC ComponentMovementWatcher (this), #endif - plugin (plug), - isOpen (false), - recursiveResize (false), - pluginWantsKeys (false), - pluginRefusesToResize (false), - alreadyInside (false) + plugin (plug) { - #if JUCE_WINDOWS - pluginHWND = 0; - sizeCheckCount = 0; - - #elif JUCE_LINUX + #if JUCE_LINUX pluginWindow = None; - pluginProc = None; + display = XWindowSystem::getInstance()->displayRef(); #elif JUCE_MAC ignoreUnused (recursiveResize, pluginRefusesToResize, alreadyInside); @@ -2050,6 +2161,8 @@ public: carbonWrapper = nullptr; #endif cocoaWrapper = nullptr; + #elif JUCE_LINUX + display = XWindowSystem::getInstance()->displayUnref(); #endif activeVSTWindows.removeFirstMatchingValue (this); @@ -2063,11 +2176,11 @@ public: if (recursiveResize) return; - Component* const topComp = getTopLevelComponent(); + auto* topComp = getTopLevelComponent(); if (topComp->getPeer() != nullptr) { - const Point pos (topComp->getLocalPoint (this, Point())); + auto pos = topComp->getLocalPoint (this, Point()); recursiveResize = true; @@ -2105,6 +2218,10 @@ public: { closePluginWindow(); openPluginWindow(); + + #if JUCE_LINUX + componentMovedOrResized (true, true); + #endif } #endif @@ -2124,8 +2241,8 @@ public: { if (cocoaWrapper != nullptr) { - int w = cocoaWrapper->getWidth(); - int h = cocoaWrapper->getHeight(); + auto w = cocoaWrapper->getWidth(); + auto h = cocoaWrapper->getHeight(); if (w != getWidth() || h != getHeight()) setSize (w, h); @@ -2151,18 +2268,13 @@ public: #if JUCE_LINUX if (pluginWindow != 0) { - const Rectangle clip (g.getClipBounds()); - - XEvent ev = { 0 }; - ev.xexpose.type = Expose; - ev.xexpose.display = display; - ev.xexpose.window = pluginWindow; - ev.xexpose.x = clip.getX(); - ev.xexpose.y = clip.getY(); - ev.xexpose.width = clip.getWidth(); - ev.xexpose.height = clip.getHeight(); - - sendEventToChild (ev); + auto clip = g.getClipBounds(); + + XClearArea (display, pluginWindow, + clip.getX(), clip.getY(), + static_cast (clip.getWidth()), + static_cast (clip.getHeight()), + True); } #endif } @@ -2212,19 +2324,7 @@ public: { ignoreUnused (e); - #if JUCE_LINUX - if (pluginWindow == 0) - return; - - toFront (true); - - XEvent ev; - prepareXEvent (ev, e); - ev.xbutton.type = ButtonPress; - translateJuceToXButtonModifiers (e, ev); - sendEventToChild (ev); - - #elif JUCE_WINDOWS + #if JUCE_WINDOWS || JUCE_LINUX toFront (true); #endif } @@ -2239,19 +2339,33 @@ public: #endif } + void setScaleFactor (float newScale) override + { + scaleFactor = newScale; + dispatch (plugInOpcodeManufacturerSpecific, presonusVendorID, + presonusSetContentScaleFactor, nullptr, newScale); + } + + void sendScaleFactorIfNotUnity() + { + if (scaleFactor != 1.0f) + setScaleFactor (scaleFactor); + } + //============================================================================== private: VSTPluginInstance& plugin; - bool isOpen, recursiveResize; - bool pluginWantsKeys, pluginRefusesToResize, alreadyInside; + float scaleFactor = 1.0f; + bool isOpen = false, recursiveResize = false; + bool pluginWantsKeys = false, pluginRefusesToResize = false, alreadyInside = false; #if JUCE_WINDOWS - HWND pluginHWND; - void* originalWndProc; - int sizeCheckCount; + HWND pluginHWND = {}; + void* originalWndProc = {}; + int sizeCheckCount = 0; #elif JUCE_LINUX + ::Display* display; Window pluginWindow; - EventProcPtr pluginProc; #endif // This is a workaround for old Mackie plugins that crash if their @@ -2259,7 +2373,7 @@ private: bool shouldAvoidDeletingWindow() const { return plugin.getPluginDescription() - .manufacturerName.containsIgnoreCase ("Loud Technologies"); + .manufacturerName.containsIgnoreCase ("Loud Technologies"); } // This is an old workaround for some plugins that need a repaint when their @@ -2281,6 +2395,7 @@ private: VstEditorBounds* rect = nullptr; dispatch (plugInOpcodeGetEditorBounds, 0, 0, &rect, 0); dispatch (plugInOpcodeOpenEditor, 0, 0, parentWindow, 0); + sendScaleFactorIfNotUnity(); // do this before and after like in the steinberg example dispatch (plugInOpcodeGetEditorBounds, 0, 0, &rect, 0); @@ -2325,6 +2440,7 @@ private: VstEditorBounds* rect = nullptr; dispatch (plugInOpcodeGetEditorBounds, 0, 0, &rect, 0); dispatch (plugInOpcodeOpenEditor, 0, 0, getWindowHandle(), 0); + sendScaleFactorIfNotUnity(); // do this before and after like in the steinberg example dispatch (plugInOpcodeGetEditorBounds, 0, 0, &rect, 0); @@ -2449,7 +2565,6 @@ private: pluginHWND = 0; #elif JUCE_LINUX pluginWindow = 0; - pluginProc = 0; #endif } } @@ -2461,13 +2576,13 @@ private: } //============================================================================== -#if JUCE_WINDOWS + #if JUCE_WINDOWS void checkPluginWindowSize() { RECT r; GetWindowRect (pluginHWND, &r); - const int w = r.right - r.left; - const int h = r.bottom - r.top; + auto w = r.right - r.left; + auto h = r.bottom - r.top; if (isShowing() && w > 0 && h > 0 && (w != getWidth() || h != getHeight()) @@ -2507,139 +2622,21 @@ private: return DefWindowProc (hW, message, wParam, lParam); } -#endif - -#if JUCE_LINUX - //============================================================================== - // overload mouse/keyboard events to forward them to the plugin's inner window.. - void sendEventToChild (XEvent& event) - { - if (pluginProc != 0) - { - // if the plugin publishes an event procedure, pass the event directly.. - pluginProc (&event); - } - else if (pluginWindow != 0) - { - // if the plugin has a window, then send the event to the window so that - // its message thread will pick it up.. - XSendEvent (display, pluginWindow, False, NoEventMask, &event); - XFlush (display); - } - } - - void prepareXEvent (XEvent& ev, const MouseEvent& e) const noexcept - { - zerostruct (ev); - ev.xcrossing.display = display; - ev.xcrossing.window = pluginWindow; - ev.xcrossing.root = RootWindow (display, DefaultScreen (display)); - ev.xcrossing.time = CurrentTime; - ev.xcrossing.x = e.x; - ev.xcrossing.y = e.y; - ev.xcrossing.x_root = e.getScreenX(); - ev.xcrossing.y_root = e.getScreenY(); - } - - void mouseEnter (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xcrossing.type = EnterNotify; - ev.xcrossing.mode = NotifyNormal; - ev.xcrossing.detail = NotifyAncestor; - translateJuceToXCrossingModifiers (e, ev); - sendEventToChild (ev); - } - } - - void mouseExit (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xcrossing.type = LeaveNotify; - ev.xcrossing.mode = NotifyNormal; - ev.xcrossing.detail = NotifyAncestor; - ev.xcrossing.focus = hasKeyboardFocus (true); - translateJuceToXCrossingModifiers (e, ev); - sendEventToChild (ev); - } - } - - void mouseMove (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xmotion.type = MotionNotify; - ev.xmotion.is_hint = NotifyNormal; - sendEventToChild (ev); - } - } - - void mouseDrag (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xmotion.type = MotionNotify; - ev.xmotion.is_hint = NotifyNormal; - translateJuceToXMotionModifiers (e, ev); - sendEventToChild (ev); - } - } - - void mouseUp (const MouseEvent& e) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xbutton.type = ButtonRelease; - translateJuceToXButtonModifiers (e, ev); - sendEventToChild (ev); - } - } - - void mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel) override - { - if (pluginWindow != 0) - { - XEvent ev; - prepareXEvent (ev, e); - ev.xbutton.type = ButtonPress; - translateJuceToXMouseWheelModifiers (e, wheel.deltaY, ev); - sendEventToChild (ev); - - ev.xbutton.type = ButtonRelease; - sendEventToChild (ev); - } - } + #endif + #if JUCE_LINUX void updatePluginWindowHandle() { pluginWindow = getChildWindow ((Window) getWindowHandle()); - - if (pluginWindow != 0) - pluginProc = (EventProcPtr) getPropertyFromXWindow (pluginWindow, - XInternAtom (display, "_XEventProc", False)); } -#endif + #endif //============================================================================== #if JUCE_MAC #if JUCE_SUPPORT_CARBON - class CarbonWrapperComponent : public CarbonViewWrapperComponent + struct CarbonWrapperComponent : public CarbonViewWrapperComponent { - public: - CarbonWrapperComponent (VSTPluginWindow& w) - : owner (w), alreadyInside (false) + CarbonWrapperComponent (VSTPluginWindow& w) : owner (w) { keepPluginWindowWhenHidden = w.shouldAvoidDeletingWindow(); setRepaintsChildHIViewWhenCreated (w.shouldRepaintCarbonWindowWhenCreated()); @@ -2653,7 +2650,7 @@ private: HIViewRef attachView (WindowRef windowRef, HIViewRef /*rootView*/) override { owner.openPluginWindow (windowRef); - return 0; + return {}; } void removeView (HIViewRef) override @@ -2692,9 +2689,9 @@ private: void handlePaint() override { - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) { - const Point pos (peer->globalToLocal (getScreenPosition())); + auto pos = peer->globalToLocal (getScreenPosition()); VstEditorBounds r; r.leftmost = (int16) pos.getX(); r.upper = (int16) pos.getY(); @@ -2707,12 +2704,12 @@ private: private: VSTPluginWindow& owner; - bool alreadyInside; + bool alreadyInside = false; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CarbonWrapperComponent) }; - friend class CarbonWrapperComponent; + friend struct CarbonWrapperComponent; ScopedPointer carbonWrapper; #endif @@ -2740,7 +2737,7 @@ private: //============================================================================== AudioProcessorEditor* VSTPluginInstance::createEditor() { - #if JUCE_IOS + #if JUCE_IOS || JUCE_ANDROID return nullptr; #else return hasEditor() ? new VSTPluginWindow (*this) @@ -2753,7 +2750,7 @@ AudioProcessorEditor* VSTPluginInstance::createEditor() static pointer_sized_int VSTINTERFACECALL audioMaster (VstEffectInterface* effect, int32 opcode, int32 index, pointer_sized_int value, void* ptr, float opt) { if (effect != nullptr) - if (VSTPluginInstance* instance = (VSTPluginInstance*) (effect->hostSpace2)) + if (auto* instance = (VSTPluginInstance*) (effect->hostSpace2)) return instance->handleCallback (opcode, index, value, ptr, opt); return VSTPluginInstance::handleGeneralCallback (opcode, index, value, ptr, opt); @@ -2765,9 +2762,9 @@ VSTPluginFormat::~VSTPluginFormat() {} static VSTPluginInstance* createAndUpdateDesc (VSTPluginFormat& format, PluginDescription& desc) { - if (AudioPluginInstance* p = format.createInstanceFromDescription (desc, 44100.0, 512)) + if (auto* p = format.createInstanceFromDescription (desc, 44100.0, 512)) { - if (VSTPluginInstance* instance = dynamic_cast (p)) + if (auto* instance = dynamic_cast (p)) { #if JUCE_MAC if (instance->vstModule->resFileId != 0) @@ -2812,7 +2809,7 @@ void VSTPluginFormat::findAllTypesForFile (OwnedArray& result for (;;) { char shellEffectName [256] = { 0 }; - const int uid = (int) instance->dispatch (plugInOpcodeNextPlugInUniqueID, 0, 0, shellEffectName, 0); + auto uid = (int) instance->dispatch (plugInOpcodeNextPlugInUniqueID, 0, 0, shellEffectName, 0); if (uid == 0) break; @@ -2849,10 +2846,10 @@ void VSTPluginFormat::createPluginInstance (const PluginDescription& desc, { File file (desc.fileOrIdentifier); - const File previousWorkingDirectory (File::getCurrentWorkingDirectory()); + auto previousWorkingDirectory = File::getCurrentWorkingDirectory(); file.getParentDirectory().setAsCurrentWorkingDirectory(); - if (ModuleHandle::Ptr module = ModuleHandle::findOrCreateModule (file)) + if (auto module = ModuleHandle::findOrCreateModule (file)) { shellUIDToCreate = desc.uid; @@ -2880,13 +2877,13 @@ bool VSTPluginFormat::requiresUnblockedMessageThreadDuringCreation (const Plugin bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier) { - const File f (File::createFileWithoutCheckingPath (fileOrIdentifier)); + auto f = File::createFileWithoutCheckingPath (fileOrIdentifier); #if JUCE_MAC || JUCE_IOS return f.isDirectory() && f.hasFileExtension (".vst"); #elif JUCE_WINDOWS return f.existsAsFile() && f.hasFileExtension (".dll"); - #elif JUCE_LINUX + #elif JUCE_LINUX || JUCE_ANDROID return f.existsAsFile() && f.hasFileExtension (".so"); #endif } @@ -2924,7 +2921,7 @@ void VSTPluginFormat::recursiveFileSearch (StringArray& results, const File& dir while (iter.next()) { - const File f (iter.getFile()); + auto f = iter.getFile(); bool isPlugin = false; if (fileMightContainThisPluginType (f.getFullPathName())) @@ -2942,20 +2939,19 @@ FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch() { #if JUCE_MAC return FileSearchPath ("~/Library/Audio/Plug-Ins/VST;/Library/Audio/Plug-Ins/VST"); - #elif JUCE_LINUX + #elif JUCE_LINUX || JUCE_ANDROID return FileSearchPath (SystemStats::getEnvironmentVariable ("VST_PATH", "/usr/lib/vst;/usr/local/lib/vst;~/.vst") .replace (":", ";")); #elif JUCE_WINDOWS - const String programFiles (File::getSpecialLocation (File::globalApplicationsDirectory).getFullPathName()); + auto programFiles = File::getSpecialLocation (File::globalApplicationsDirectory).getFullPathName(); FileSearchPath paths; - paths.add (WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\Software\\VST\\VSTPluginsPath", - programFiles + "\\Steinberg\\VstPlugins")); + paths.add (WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\Software\\VST\\VSTPluginsPath")); + paths.addIfNotAlreadyThere (programFiles + "\\Steinberg\\VstPlugins"); paths.removeNonExistentPaths(); - - paths.add (WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\Software\\VST\\VSTPluginsPath", - programFiles + "\\VstPlugins")); + paths.addIfNotAlreadyThere (programFiles + "\\VstPlugins"); + paths.removeRedundantPaths(); return paths; #elif JUCE_IOS // on iOS you can only load plug-ins inside the hosts bundle folder @@ -2975,7 +2971,7 @@ FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch() const XmlElement* VSTPluginFormat::getVSTXML (AudioPluginInstance* plugin) { - if (VSTPluginInstance* const vst = dynamic_cast (plugin)) + if (auto* vst = dynamic_cast (plugin)) if (vst->vstModule != nullptr) return vst->vstModule->vstXml.get(); @@ -2984,7 +2980,7 @@ const XmlElement* VSTPluginFormat::getVSTXML (AudioPluginInstance* plugin) bool VSTPluginFormat::loadFromFXBFile (AudioPluginInstance* plugin, const void* data, size_t dataSize) { - if (VSTPluginInstance* vst = dynamic_cast (plugin)) + if (auto* vst = dynamic_cast (plugin)) return vst->loadFromFXBFile (data, dataSize); return false; @@ -2992,7 +2988,7 @@ bool VSTPluginFormat::loadFromFXBFile (AudioPluginInstance* plugin, const void* bool VSTPluginFormat::saveToFXBFile (AudioPluginInstance* plugin, MemoryBlock& dest, bool asFXB) { - if (VSTPluginInstance* vst = dynamic_cast (plugin)) + if (auto* vst = dynamic_cast (plugin)) return vst->saveToFXBFile (dest, asFXB); return false; @@ -3000,7 +2996,7 @@ bool VSTPluginFormat::saveToFXBFile (AudioPluginInstance* plugin, MemoryBlock& d bool VSTPluginFormat::getChunkData (AudioPluginInstance* plugin, MemoryBlock& result, bool isPreset) { - if (VSTPluginInstance* vst = dynamic_cast (plugin)) + if (auto* vst = dynamic_cast (plugin)) return vst->getChunkData (result, isPreset, 128); return false; @@ -3008,7 +3004,7 @@ bool VSTPluginFormat::getChunkData (AudioPluginInstance* plugin, MemoryBlock& re bool VSTPluginFormat::setChunkData (AudioPluginInstance* plugin, const void* data, int size, bool isPreset) { - if (VSTPluginInstance* vst = dynamic_cast (plugin)) + if (auto* vst = dynamic_cast (plugin)) return vst->setChunkData (data, size, isPreset); return false; @@ -3020,12 +3016,9 @@ AudioPluginInstance* VSTPluginFormat::createCustomVSTFromMainCall (void* entryPo ModuleHandle::Ptr module = new ModuleHandle (File(), (MainCall) entryPointFunction); if (module->open()) - { - ScopedPointer result (VSTPluginInstance::create (module, initialSampleRate, initialBufferSize)); - - if (result != nullptr && result->initialiseEffect (initialSampleRate, initialBufferSize)) - return result.release(); - } + if (ScopedPointer result = VSTPluginInstance::create (module, initialSampleRate, initialBufferSize)) + if (result->initialiseEffect (initialSampleRate, initialBufferSize)) + return result.release(); return nullptr; } @@ -3034,14 +3027,14 @@ void VSTPluginFormat::setExtraFunctions (AudioPluginInstance* plugin, ExtraFunct { ScopedPointer f (functions); - if (VSTPluginInstance* vst = dynamic_cast (plugin)) + if (auto* vst = dynamic_cast (plugin)) vst->extraFunctions = f; } AudioPluginInstance* VSTPluginFormat::getPluginInstanceFromVstEffectInterface (void* aEffect) { - if (VstEffectInterface* vstAEffect = reinterpret_cast (aEffect)) - if (VSTPluginInstance* instanceVST = reinterpret_cast (vstAEffect->hostSpace2)) + if (auto* vstAEffect = reinterpret_cast (aEffect)) + if (auto* instanceVST = reinterpret_cast (vstAEffect->hostSpace2)) return dynamic_cast (instanceVST); return nullptr; @@ -3049,10 +3042,10 @@ AudioPluginInstance* VSTPluginFormat::getPluginInstanceFromVstEffectInterface (v pointer_sized_int JUCE_CALLTYPE VSTPluginFormat::dispatcher (AudioPluginInstance* plugin, int32 opcode, int32 index, pointer_sized_int value, void* ptr, float opt) { - if (VSTPluginInstance* vst = dynamic_cast (plugin)) + if (auto* vst = dynamic_cast (plugin)) return vst->dispatch (opcode, index, value, ptr, opt); - return 0; + return {}; } void VSTPluginFormat::aboutToScanVSTShellPlugin (const PluginDescription&) {} diff --git a/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h b/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h index d3b7d9fa8..c6793a20b 100644 --- a/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h +++ b/source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h @@ -2,27 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#if (JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_IOS)) || DOXYGEN +#if (JUCE_PLUGINHOST_VST || DOXYGEN) //============================================================================== /** diff --git a/source/modules/juce_audio_processors/juce_audio_processors.cpp b/source/modules/juce_audio_processors/juce_audio_processors.cpp index 8df41ca98..5d1376f59 100644 --- a/source/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/source/modules/juce_audio_processors/juce_audio_processors.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,8 +33,6 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 #include "juce_audio_processors.h" @@ -47,7 +47,7 @@ #endif #endif -#if JUCE_PLUGINHOST_VST && JUCE_LINUX +#if JUCE_PLUGINHOST_VST && JUCE_LINUX && ! JUCE_AUDIOPROCESSOR_NO_GUI #include #include #undef KeyPress @@ -83,28 +83,29 @@ static inline bool arrayContainsPlugin (const OwnedArray& lis #endif //============================================================================== - -struct AutoResizingNSViewComponent : public NSViewComponent, - private AsyncUpdater { +struct AutoResizingNSViewComponent : public ViewComponentBaseClass, + private AsyncUpdater +{ AutoResizingNSViewComponent(); - void childBoundsChanged(Component*) override; + void childBoundsChanged (Component*) override; void handleAsyncUpdate() override; bool recursive; }; -struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewComponent, - private Timer { +//============================================================================== +struct AutoResizingNSViewComponentWithParent : public AutoResizingNSViewComponent, + private Timer +{ AutoResizingNSViewComponentWithParent(); JUCE_IOS_MAC_VIEW* getChildView() const; void timerCallback() override; }; //============================================================================== - AutoResizingNSViewComponent::AutoResizingNSViewComponent() : recursive (false) {} -void AutoResizingNSViewComponent::childBoundsChanged(Component*) +void AutoResizingNSViewComponent::childBoundsChanged (Component*) override { if (recursive) { @@ -118,40 +119,38 @@ void AutoResizingNSViewComponent::childBoundsChanged(Component*) } } -void AutoResizingNSViewComponent::handleAsyncUpdate() +void AutoResizingNSViewComponent::handleAsyncUpdate() override { resizeToFitView(); } //============================================================================== - AutoResizingNSViewComponentWithParent::AutoResizingNSViewComponentWithParent() { JUCE_IOS_MAC_VIEW* v = [[JUCE_IOS_MAC_VIEW alloc] init]; setView (v); [v release]; - - startTimer(30); + + startTimer (30); } JUCE_IOS_MAC_VIEW* AutoResizingNSViewComponentWithParent::getChildView() const { - if (JUCE_IOS_MAC_VIEW* parent = (JUCE_IOS_MAC_VIEW*)getView()) + if (JUCE_IOS_MAC_VIEW* parent = (JUCE_IOS_MAC_VIEW*) getView()) if ([[parent subviews] count] > 0) return [[parent subviews] objectAtIndex: 0]; - + return nil; } -void AutoResizingNSViewComponentWithParent::timerCallback() +void AutoResizingNSViewComponentWithParent::timerCallback() override { if (JUCE_IOS_MAC_VIEW* child = getChildView()) { stopTimer(); - setView(child); + setView (child); } } - #endif #if JUCE_CLANG @@ -161,9 +160,11 @@ void AutoResizingNSViewComponentWithParent::timerCallback() #include "format/juce_AudioPluginFormat.cpp" #include "format/juce_AudioPluginFormatManager.cpp" #include "processors/juce_AudioProcessor.cpp" -#include "processors/juce_AudioProcessorEditor.cpp" #include "processors/juce_AudioProcessorGraph.cpp" -#include "processors/juce_GenericAudioProcessorEditor.cpp" +#if ! JUCE_AUDIOPROCESSOR_NO_GUI + #include "processors/juce_AudioProcessorEditor.cpp" + #include "processors/juce_GenericAudioProcessorEditor.cpp" +#endif #include "processors/juce_PluginDescription.cpp" #include "format_types/juce_LADSPAPluginFormat.cpp" #include "format_types/juce_VSTPluginFormat.cpp" @@ -172,7 +173,7 @@ void AutoResizingNSViewComponentWithParent::timerCallback() #include "scanning/juce_KnownPluginList.cpp" #include "scanning/juce_PluginDirectoryScanner.cpp" #include "scanning/juce_PluginListComponent.cpp" -#include "utilities/juce_AudioProcessorValueTreeState.cpp" #include "utilities/juce_AudioProcessorParameters.cpp" +#include "utilities/juce_AudioProcessorValueTreeState.cpp" } diff --git a/source/modules/juce_audio_processors/juce_audio_processors.h b/source/modules/juce_audio_processors/juce_audio_processors.h index 118752a9f..fb8e13e0b 100644 --- a/source/modules/juce_audio_processors/juce_audio_processors.h +++ b/source/modules/juce_audio_processors/juce_audio_processors.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -33,7 +35,7 @@ ID: juce_audio_processors vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE audio processor classes description: Classes for loading and playing VST, AU, or internally-generated audio processors. website: http://www.juce.com/juce @@ -48,7 +50,7 @@ *******************************************************************************/ -#ifndef JUCE_AUDIO_PROCESSORS_H_INCLUDED +#pragma once #define JUCE_AUDIO_PROCESSORS_H_INCLUDED #include @@ -102,7 +104,6 @@ namespace juce { class AudioProcessor; -#include "processors/juce_AudioPlayHead.h" #include "processors/juce_AudioProcessorEditor.h" #include "processors/juce_AudioProcessorListener.h" #include "processors/juce_AudioProcessorParameter.h" @@ -121,13 +122,11 @@ class AudioProcessor; #include "format_types/juce_VST3PluginFormat.h" #include "scanning/juce_PluginDirectoryScanner.h" #include "scanning/juce_PluginListComponent.h" -#include "utilities/juce_AudioProcessorValueTreeState.h" #include "utilities/juce_AudioProcessorParameterWithID.h" #include "utilities/juce_AudioParameterFloat.h" #include "utilities/juce_AudioParameterInt.h" #include "utilities/juce_AudioParameterBool.h" #include "utilities/juce_AudioParameterChoice.h" +#include "utilities/juce_AudioProcessorValueTreeState.h" } - -#endif // JUCE_AUDIO_PROCESSORS_H_INCLUDED diff --git a/source/modules/juce_audio_processors/processors/AudioProcessorGraphMultiThreaded.cpp b/source/modules/juce_audio_processors/processors/AudioProcessorGraphMultiThreaded.cpp deleted file mode 100644 index 4d276f069..000000000 --- a/source/modules/juce_audio_processors/processors/AudioProcessorGraphMultiThreaded.cpp +++ /dev/null @@ -1,1096 +0,0 @@ -/* - ============================================================================== - - AudioProcessorGraphMultiThreaded.cpp - Created: 26 Nov 2012 11:35:49am - Author: Christian - - ============================================================================== -*/ - -#include "AudioProcessorGraphMultiThreaded.h" - - -const int AudioProcessorGraphMultiThreaded::midiChannelIndex = 0x1000; - -//============================================================================== -namespace GraphRenderingOpsMultiThreaded -{ - - -//============================================================================== -struct ConnectionSorter -{ - static int compareElements (const AudioProcessorGraphMultiThreaded::Connection* const first, - const AudioProcessorGraphMultiThreaded::Connection* const second) noexcept - { - if (first->sourceNodeId < second->sourceNodeId) return -1; - else if (first->sourceNodeId > second->sourceNodeId) return 1; - else if (first->destNodeId < second->destNodeId) return -1; - else if (first->destNodeId > second->destNodeId) return 1; - else if (first->sourceChannelIndex < second->sourceChannelIndex) return -1; - else if (first->sourceChannelIndex > second->sourceChannelIndex) return 1; - else if (first->destChannelIndex < second->destChannelIndex) return -1; - else if (first->destChannelIndex > second->destChannelIndex) return 1; - - return 0; - } -}; - -} - -//============================================================================== -AudioProcessorGraphMultiThreaded::Connection::Connection (const uint32 sourceNodeId_, const int sourceChannelIndex_, - const uint32 destNodeId_, const int destChannelIndex_) noexcept - : sourceNodeId (sourceNodeId_), sourceChannelIndex (sourceChannelIndex_), - destNodeId (destNodeId_), destChannelIndex (destChannelIndex_) -{ -} - -//============================================================================== -AudioProcessorGraphMultiThreaded::Node::Node (const uint32 nodeId_, AudioProcessor* const processor_, AudioProcessorGraphMultiThreaded& graph_) noexcept - : nodeId (nodeId_), - processingDone(false), - processor (processor_), - isPrepared (false), - graph(graph_) - -{ - AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor* const ioProc - = dynamic_cast (processor.get()); - - if (ioProc != nullptr) - { - ioProc->setParentGraph (&graph); - - } ; - - - -}; - -void AudioProcessorGraphMultiThreaded::Node::prepare (const double sampleRate, const int blockSize ) -{ - if (! isPrepared) - { - isPrepared = true; - - setParentGraph (&graph); // setParentGraph also sets input and outputchannels - - buffer= new AudioSampleBuffer(jmax(processor->getNumInputChannels(),processor->getNumOutputChannels()),blockSize); - buffer->clear(); - - midiBuffer.clear(); - - - processor->setPlayConfigDetails (processor->getNumInputChannels(), - processor->getNumOutputChannels(), - sampleRate, blockSize); - - processor->prepareToPlay (sampleRate, blockSize); - - - } -} - -void AudioProcessorGraphMultiThreaded::Node::unprepare() -{ - if (isPrepared) - { - isPrepared = false; - processor->releaseResources(); - } -} - - - -bool AudioProcessorGraphMultiThreaded::Node::process() -{ - // A node can only by processed by one thread at one time - ScopedTryLock sl(nodeLock); - if (!sl.isLocked()) - { - return false; - } - - if (!graph.nodeProcessingActive) - { - return false; - } - - - if (processingDone) - { - // Already processed - return false; - } - - if (outputNodesToInform.size()==0 && requiredInputs.size()==0) - { - // Has no inputs and no outputs, so do nothing - return false; - } - - if (!hasReachedNumberOfRequiredInputs()) - { - // waiting for other nodes input - return false; - }; - - if (!isPrepared) - { - jassertfalse; - return false; - } - -// DBG("ProcessNode "+ getProcessor()->getName()); - - const int numChans = buffer->getNumChannels(); - const int numSamples = buffer->getNumSamples(); - - bool unwritten; - - for (int o = numChans; --o >= 0;) - { - unwritten = true; - - for (int i = requiredInputs.size(); --i >= 0;) - { - NodeChannel* const ri = requiredInputs[i]; - - if (ri->inputConnection->destChannelIndex != o) - continue; - - if (ri->inputConnection->sourceChannelIndex < ri->node->buffer->getNumChannels()) - { - if (unwritten) - { - buffer->copyFrom(o,0,*ri->node->buffer,ri->inputConnection->sourceChannelIndex,0,numSamples); - unwritten = false; - } - else - { - buffer->addFrom(o,0,*ri->node->buffer,ri->inputConnection->sourceChannelIndex,0,numSamples); - } - } - else - { - DBG("Impossible Connection: Source Channel "+ - String(ri->inputConnection->sourceChannelIndex)+" is higher than available channels "+String(numChans)); - } - } - - if (unwritten) - buffer->clear(o,0,numSamples); - } - - midiBuffer.clear(); - - for (int i = requiredInputs.size(); --i >= 0;) - { - NodeChannel* const ri = requiredInputs[i]; - - //if (ri->inputConnection->sourceChannelIndex == AudioProcessorGraphMultiThreaded::midiChannelIndex) - midiBuffer.addEvents(ri->node->midiBuffer,0,numSamples,0); - } - - processor->processBlock(*buffer, midiBuffer); - - for (int i = outputNodesToInform.size(); --i >= 0;) - { - NodeChannel* const ri = outputNodesToInform[i]; - ++(ri->node->numberOfProcessedInputs); - } - - - processingDone=true; - return true; -} - - -bool AudioProcessorGraphMultiThreaded::Node::hasReachedNumberOfRequiredInputs() -{ - return numberOfProcessedInputs.get()>=requiredInputs.size(); -} - - -void AudioProcessorGraphMultiThreaded::Node::reset() -{ - ScopedLock sl(nodeLock); - numberOfProcessedInputs=0; - processingDone=false; -} - -void AudioProcessorGraphMultiThreaded::Node::updateMyConnections() -{ - ScopedLock sl(graph.getConfigurationLock()); - - requiredInputs.clear(); - outputNodesToInform.clear(); - - - - for (int i = graph.connections.size(); --i >= 0;) - { - if (graph.connections.getUnchecked(i)->destNodeId==nodeId) - { - - NodeChannel* ri = new NodeChannel(); - ri->inputConnection=new Connection(*graph.connections.getUnchecked(i)); - ri->node=graph.getNodeRefPtrForId(graph.connections.getUnchecked(i)->sourceNodeId); - requiredInputs.add(ri); - }; - - if (graph.connections.getUnchecked(i)->sourceNodeId==nodeId) - { - NodeChannel* ri = new NodeChannel(); - ri->inputConnection=new Connection(*graph.connections.getUnchecked(i)); - ri->node=graph.getNodeRefPtrForId(graph.connections.getUnchecked(i)->destNodeId); - outputNodesToInform.add(ri); - }; - - - }; - -} - -void AudioProcessorGraphMultiThreaded::Node::setParentGraph( AudioProcessorGraphMultiThreaded* graph ) const -{ - AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor* const ioProc - = dynamic_cast (processor.get()); - - if (ioProc != nullptr) - ioProc->setParentGraph (graph); -} - -int AudioProcessorGraphMultiThreaded::Node::getNumRequiredInputs() -{ - return requiredInputs.size(); -} - -bool AudioProcessorGraphMultiThreaded::Node::isProcessingDone() -{ - return processingDone; -} - -//============================================================================== -AudioProcessorGraphMultiThreaded::AudioProcessorGraphMultiThreaded() - : nodeProcessingActive(false), - waitEvent(true), - lastNodeId (0), - renderingBuffers (1, 1), - currentAudioOutputBuffer (1, 1) - -{ - nothingHappenedCounter=0; - nextNodeIteritater=0; - - for (int i=0; istartThread(); - } -}; - - -void AudioProcessorGraphMultiThreaded::stopAllThreads() -{ - for (int i=0; isignalThreadShouldExit(); - }; - - for (int i=0; istopThread(1000); - }; -} - - - - -AudioProcessorGraphMultiThreaded::~AudioProcessorGraphMultiThreaded() -{ - stopAllThreads(); - - // Remove Circular References - // yes, the use of ReferenceCountedPointers may not the ideal solution, because nodes refer each other, which result in Circular References - for (int i=0; iclearRef(); - } - nodes_original.clear(); - - // Remove Circular References - for (int i=0; iclearRef(); - } - nodes_workingCopy.clear(); - - - connections.clear(); - outputNode=nullptr; -} - -void AudioProcessorGraphMultiThreaded::clear() -{ - ScopedLock sl(reconfigurationLock); - stopAllThreads(); - - // Remove Circular References - for (int i=0; iclearRef(); - } - nodes_original.clear(); - - - connections.clear(); - triggerAsyncUpdate(); -} - -const String AudioProcessorGraphMultiThreaded::getName() const -{ - return "Audio Graph"; -} - -//============================================================================== - - -AudioProcessorGraphMultiThreaded::Node* AudioProcessorGraphMultiThreaded::getNodeForId (const uint32 nodeId) const -{ - ScopedLock sl(reconfigurationLock); - - for (int i = nodes_original.size(); --i >= 0;) - if (nodes_original.getUnchecked(i)->nodeId == nodeId) - return nodes_original.getUnchecked(i); - - return nullptr; -} - -AudioProcessorGraphMultiThreaded::Node::Ptr AudioProcessorGraphMultiThreaded::getNodeRefPtrForId (const uint32 nodeId) const -{ - ScopedLock sl(reconfigurationLock); - - for (int i = nodes_original.size(); --i >= 0;) - if (nodes_original.getUnchecked(i)->nodeId == nodeId) - return nodes_original.getUnchecked(i); - - return nullptr; -} - - - -AudioProcessorGraphMultiThreaded::Node* AudioProcessorGraphMultiThreaded::addNode (AudioProcessor* const newProcessor, uint32 nodeId) -{ - ScopedLock sl(reconfigurationLock); - - - - if (newProcessor == nullptr) - { - jassertfalse; - return nullptr; - } - - if (nodeId == 0) - { - nodeId = ++lastNodeId; - } - else - { - // you can't add a node with an id that already exists in the graph.. - jassert (getNodeForId (nodeId) == nullptr); - - removeNode (nodeId); - - if (nodeId > lastNodeId) - lastNodeId = nodeId; - } - - Node* const n = new Node (nodeId, newProcessor,*this); - nodes_original.add (n); - triggerAsyncUpdate(); - - - - return n; -} - -bool AudioProcessorGraphMultiThreaded::removeNode (const uint32 nodeId) -{ - ScopedLock sl(reconfigurationLock); - - disconnectNode (nodeId); - - buildRenderingSequence(); // important to remove circular references - - for (int i = nodes_original.size(); --i >= 0;) - { - if (nodes_original.getUnchecked(i)->nodeId == nodeId) - { - nodes_original.remove (i); - triggerAsyncUpdate(); - return true; - } - } - - return false; -} - -//============================================================================== -const AudioProcessorGraphMultiThreaded::Connection* AudioProcessorGraphMultiThreaded::getConnectionBetween (const uint32 sourceNodeId, - const int sourceChannelIndex, - const uint32 destNodeId, - const int destChannelIndex) const -{ - ScopedLock sl(reconfigurationLock); - - const Connection c (sourceNodeId, sourceChannelIndex, destNodeId, destChannelIndex); - GraphRenderingOpsMultiThreaded::ConnectionSorter sorter; - return connections [connections.indexOfSorted (sorter, &c)]; -} - -bool AudioProcessorGraphMultiThreaded::isConnected (const uint32 possibleSourceNodeId, - const uint32 possibleDestNodeId) const -{ - ScopedLock sl(reconfigurationLock); - - for (int i = connections.size(); --i >= 0;) - { - const Connection* const c = connections.getUnchecked(i); - - if (c->sourceNodeId == possibleSourceNodeId - && c->destNodeId == possibleDestNodeId) - { - return true; - } - } - - return false; -} - -bool AudioProcessorGraphMultiThreaded::canConnect (const uint32 sourceNodeId, - const int sourceChannelIndex, - const uint32 destNodeId, - const int destChannelIndex) const -{ - ScopedLock sl(reconfigurationLock); - - if (sourceChannelIndex < 0 - || destChannelIndex < 0 - || sourceNodeId == destNodeId - || (destChannelIndex == midiChannelIndex) != (sourceChannelIndex == midiChannelIndex)) - return false; - - const Node* const source = getNodeForId (sourceNodeId); - - if (source == nullptr - || (sourceChannelIndex != midiChannelIndex && sourceChannelIndex >= source->getProcessor()->getNumOutputChannels()) - || (sourceChannelIndex == midiChannelIndex && ! source->getProcessor()->producesMidi())) - return false; - - const Node* const dest = getNodeForId (destNodeId); - - if (dest == nullptr - || (destChannelIndex != midiChannelIndex && destChannelIndex >= dest->getProcessor()->getNumInputChannels()) - || (destChannelIndex == midiChannelIndex && ! dest->getProcessor()->acceptsMidi())) - return false; - - return getConnectionBetween (sourceNodeId, sourceChannelIndex, - destNodeId, destChannelIndex) == nullptr; -} - -bool AudioProcessorGraphMultiThreaded::addConnection (const uint32 sourceNodeId, - const int sourceChannelIndex, - const uint32 destNodeId, - const int destChannelIndex) -{ - ScopedLock sl(reconfigurationLock); - - if (! canConnect (sourceNodeId, sourceChannelIndex, destNodeId, destChannelIndex)) - return false; - - GraphRenderingOpsMultiThreaded::ConnectionSorter sorter; - connections.addSorted (sorter, new Connection (sourceNodeId, sourceChannelIndex, - destNodeId, destChannelIndex)); - triggerAsyncUpdate(); - return true; -} - -void AudioProcessorGraphMultiThreaded::removeConnection (const int index) -{ - ScopedLock sl(reconfigurationLock); - - connections.remove (index); - triggerAsyncUpdate(); -} - -bool AudioProcessorGraphMultiThreaded::removeConnection (const uint32 sourceNodeId, const int sourceChannelIndex, - const uint32 destNodeId, const int destChannelIndex) -{ - ScopedLock sl(reconfigurationLock); - - bool doneAnything = false; - - for (int i = connections.size(); --i >= 0;) - { - const Connection* const c = connections.getUnchecked(i); - - if (c->sourceNodeId == sourceNodeId - && c->destNodeId == destNodeId - && c->sourceChannelIndex == sourceChannelIndex - && c->destChannelIndex == destChannelIndex) - { - removeConnection (i); - doneAnything = true; - } - } - - return doneAnything; -} - -bool AudioProcessorGraphMultiThreaded::disconnectNode (const uint32 nodeId) -{ - ScopedLock sl(reconfigurationLock); - - bool doneAnything = false; - - for (int i = connections.size(); --i >= 0;) - { - const Connection* const c = connections.getUnchecked(i); - - if (c->sourceNodeId == nodeId || c->destNodeId == nodeId) - { - removeConnection (i); - doneAnything = true; - } - } - - return doneAnything; -} - -bool AudioProcessorGraphMultiThreaded::isConnectionLegal (const Connection* const c) const -{ - ScopedLock sl(reconfigurationLock); - - jassert (c != nullptr); - - const Node* const source = getNodeForId (c->sourceNodeId); - const Node* const dest = getNodeForId (c->destNodeId); - - return source != nullptr - && dest != nullptr - && (c->sourceChannelIndex != midiChannelIndex ? isPositiveAndBelow (c->sourceChannelIndex, source->getProcessor()->getNumOutputChannels()) - : source->getProcessor()->producesMidi()) - && (c->destChannelIndex != midiChannelIndex ? isPositiveAndBelow (c->destChannelIndex, dest->getProcessor()->getNumInputChannels()) - : dest->getProcessor()->acceptsMidi()); -} - -bool AudioProcessorGraphMultiThreaded::removeIllegalConnections() -{ - ScopedLock sl(reconfigurationLock); - - bool doneAnything = false; - - for (int i = connections.size(); --i >= 0;) - { - if (! isConnectionLegal (connections.getUnchecked(i))) - { - removeConnection (i); - doneAnything = true; - } - } - - return doneAnything; -} - - - - -//============================================================================== - - - - -/* -bool AudioProcessorGraphMultiProcessor::isAnInputTo (const uint32 possibleInputId, - const uint32 possibleDestinationId, - const int recursionCheck) const -{ - ScopedLock sl(reconfigurationLock); - - if (recursionCheck > 0) - { - for (int i = connections.size(); --i >= 0;) - { - const AudioProcessorGraphMultiProcessor::Connection* const c = connections.getUnchecked (i); - - if (c->destNodeId == possibleDestinationId - && (c->sourceNodeId == possibleInputId - || isAnInputTo (possibleInputId, c->sourceNodeId, recursionCheck - 1))) - return true; - } - } - - return false; -}*/ - -void AudioProcessorGraphMultiThreaded::buildRenderingSequence() -{ - ScopedLock sl(reconfigurationLock); - - suspendProcessing(true); - stopAllThreads(); - - outputNode=nullptr; - for (int i = 0; i < nodes_original.size(); ++i) - { - Node::Ptr n=nodes_original.getUnchecked(i); - AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor* const ioProc - = dynamic_cast (n->getProcessor()); - - if (ioProc!=nullptr) - { - if (ioProc->isAudioOutputNode()) - { - outputNode=n; - break; - } - } - }; - - - // Remove Cirucal References - for (int i=0; iclearRef(); - } - - - nodes_workingCopy=nodes_original; - - for (int i = 0; i < nodes_original.size(); ++i) - { - Node* const node = nodes_original.getUnchecked(i); - node->prepare (getSampleRate(), getBlockSize()); - } - - for (int i = 0; i < nodes_original.size(); ++i) - { - Node* const node = nodes_original.getUnchecked(i); - - node->updateMyConnections(); - node->reset(); - }; - - if (outputNode==nullptr) - { - jassertfalse; - //No output node found - } else - { - - - startAllThreads(); - suspendProcessing(false); - } - - - - // delete the old ones.. -}; - -void AudioProcessorGraphMultiThreaded::handleAsyncUpdate() -{ - buildRenderingSequence(); -} - -//============================================================================== -void AudioProcessorGraphMultiThreaded::prepareToPlay (double /*sampleRate*/, int estimatedSamplesPerBlock) -{ - currentAudioInputBuffer = nullptr; - currentAudioOutputBuffer.setSize (jmax (1, getNumOutputChannels()), estimatedSamplesPerBlock); - currentMidiInputBuffer = nullptr; - currentMidiOutputBuffer.clear(); - - buildRenderingSequence(); -} - -void AudioProcessorGraphMultiThreaded::releaseResources() -{ - stopAllThreads(); - suspendProcessing(true); - - ScopedLock sl(reconfigurationLock); - - for (int i = 0; i < nodes_original.size(); ++i) - nodes_original.getUnchecked(i)->unprepare(); - - renderingBuffers.setSize (1, 1); - midiBuffers.clear(); - - currentAudioInputBuffer = nullptr; - currentAudioOutputBuffer.setSize (1, 1); - currentMidiInputBuffer = nullptr; - currentMidiOutputBuffer.clear(); - - suspendProcessing(false); -} - -void AudioProcessorGraphMultiThreaded::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) -{ - ScopedLock sl (getCallbackLock()); // Can I trust that my parent has locked this? - - if (isSuspended()) - { - buffer.clear(); - return; - }; - - const int numSamples = buffer.getNumSamples(); - - const ScopedLock rl (renderLock); - - currentAudioInputBuffer = &buffer; - currentAudioOutputBuffer.setSize (jmax (1, buffer.getNumChannels()), numSamples); - currentAudioOutputBuffer.clear(); - currentMidiInputBuffer = &midiMessages; - currentMidiOutputBuffer.clear(); - - - - //DBG("Start Processing"); - // Process - nodeProcessingActive=true; - - // Using this Callback for processing too - if (outputNode->getNumRequiredInputs()>0) - { - while (!outputNode->isProcessingDone()) - { - processOneNode(true); - } - } else - { - buffer.clear(); - } - - // All important Nodes have Processing Done - // Set a flag - - nodeProcessingActive=false; - - // After calling reset, the input-node will immediatly begin processing, nodeProcessingActive=false will prevent this. - // reset locks the node, to be sure - - //DBG("Stop Processing"); - - { - - for (int i = 0; i < nodes_workingCopy.size(); ++i) - { - Node* const node = nodes_workingCopy.getUnchecked(i); - - -// jassert(outputNode->getNumRequiredInputs()==0 || node->isProcessingDone()); - - node->reset(); - }; - } - - - - for (int i = 0; i < buffer.getNumChannels(); ++i) - buffer.copyFrom (i, 0, currentAudioOutputBuffer, i, 0, numSamples); - - midiMessages.clear(); - midiMessages.addEvents (currentMidiOutputBuffer, 0, buffer.getNumSamples(), 0); - -} - -const String AudioProcessorGraphMultiThreaded::getInputChannelName (int channelIndex) const -{ - return "Input " + String (channelIndex + 1); -} - -const String AudioProcessorGraphMultiThreaded::getOutputChannelName (int channelIndex) const -{ - return "Output " + String (channelIndex + 1); -} - -bool AudioProcessorGraphMultiThreaded::isInputChannelStereoPair (int /*index*/) const { return true; } -bool AudioProcessorGraphMultiThreaded::isOutputChannelStereoPair (int /*index*/) const { return true; } -bool AudioProcessorGraphMultiThreaded::silenceInProducesSilenceOut() const { return false; } -bool AudioProcessorGraphMultiThreaded::acceptsMidi() const { return true; } -bool AudioProcessorGraphMultiThreaded::producesMidi() const { return true; } -void AudioProcessorGraphMultiThreaded::getStateInformation (juce::MemoryBlock& /*destData*/) {} -void AudioProcessorGraphMultiThreaded::setStateInformation (const void* /*data*/, int /*sizeInBytes*/) {} - -void AudioProcessorGraphMultiThreaded::processOneNode(bool thisIsAudioCallbackThread) -{ - - AudioProcessorGraphMultiThreaded::Node::Ptr node(nullptr); - - - - // the node Pointer is safe because reference counted - if (nodes_workingCopy.size()!=0) - { - node=nodes_workingCopy[ (++nextNodeIteritater) % nodes_workingCopy.size() ]; - } - - if (node!=nullptr) - { - waitEvent.reset(); - bool doneAnything=node->process(); - if (!doneAnything) - { - nothingHappenedCounter++; - } else - { - waitEvent.signal(); - nothingHappenedCounter=0; - } - } else - { - nothingHappenedCounter++; - }; - - if (nothingHappenedCounter>=nodes_workingCopy.size()) - { - if (!thisIsAudioCallbackThread) - { - waitEvent.wait(1);// Don't waste CPU Power, when nothing is to do - wait a little bit unless another thread has something finished - }; - nothingHappenedCounter=0; - } - -} - -int AudioProcessorGraphMultiThreaded::getNumNodes() const -{ - ScopedLock sl(reconfigurationLock); - return nodes_original.size(); -}; - -AudioProcessorGraphMultiThreaded::Node* AudioProcessorGraphMultiThreaded::getNode( const int index ) const -{ - ScopedLock sl(reconfigurationLock); - return nodes_original [index]; -} - -double AudioProcessorGraphMultiThreaded::getTailLengthSeconds() const -{ - return 0.; -} - - - - - -//============================================================================== -AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::AudioGraphIOProcessor (const IODeviceType type_) - : type (type_), - graph (nullptr) -{ - - - -} - -AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::~AudioGraphIOProcessor() -{ -} - -const String AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getName() const -{ - switch (type) - { - case audioOutputNode: return "Audio Output"; - case audioInputNode: return "Audio Input"; - case midiOutputNode: return "Midi Output"; - case midiInputNode: return "Midi Input"; - default: break; - } - - return String::empty; -} - -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::fillInPluginDescription (PluginDescription& d) const -{ - d.name = getName(); - d.uid = d.name.hashCode(); - d.category = "I/O devices"; - d.pluginFormatName = "Internal"; - d.manufacturerName = "Raw Material Software"; - d.version = "1.0"; - d.isInstrument = false; - - d.numInputChannels = getNumInputChannels(); - if (type == audioOutputNode && graph != nullptr) - d.numInputChannels = graph->getNumInputChannels(); - - d.numOutputChannels = getNumOutputChannels(); - if (type == audioInputNode && graph != nullptr) - d.numOutputChannels = graph->getNumOutputChannels(); -} - -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::prepareToPlay (double, int) -{ - jassert (graph != nullptr); -} - -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::releaseResources() -{ -} - -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::processBlock (AudioSampleBuffer& buffer, - MidiBuffer& midiMessages) -{ - jassert (graph != nullptr); - - switch (type) - { - case audioOutputNode: - { - for (int i = jmin (graph->currentAudioOutputBuffer.getNumChannels(), - buffer.getNumChannels()); --i >= 0;) - { - graph->currentAudioOutputBuffer.addFrom (i, 0, buffer, i, 0, buffer.getNumSamples()); - } - - break; - } - - case audioInputNode: - { - for (int i = jmin (graph->currentAudioInputBuffer->getNumChannels(), - buffer.getNumChannels()); --i >= 0;) - { - buffer.copyFrom (i, 0, *graph->currentAudioInputBuffer, i, 0, buffer.getNumSamples()); - } - - break; - } - - case midiOutputNode: - graph->currentMidiOutputBuffer.addEvents (midiMessages, 0, buffer.getNumSamples(), 0); - break; - - case midiInputNode: - midiMessages.addEvents (*graph->currentMidiInputBuffer, 0, buffer.getNumSamples(), 0); - break; - - default: - break; - } -} - -bool AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::silenceInProducesSilenceOut() const -{ - return isOutput(); -} - -bool AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::acceptsMidi() const -{ - return type == midiOutputNode; -} - -bool AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::producesMidi() const -{ - return type == midiInputNode; -} - -const String AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getInputChannelName (int channelIndex) const -{ - switch (type) - { - case audioOutputNode: return "Output " + String (channelIndex + 1); - case midiOutputNode: return "Midi Output"; - default: break; - } - - return String::empty; -} - -const String AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getOutputChannelName (int channelIndex) const -{ - switch (type) - { - case audioInputNode: return "Input " + String (channelIndex + 1); - case midiInputNode: return "Midi Input"; - default: break; - } - - return String::empty; -} - -bool AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::isInputChannelStereoPair (int /*index*/) const -{ - return type == audioInputNode || type == audioOutputNode; -} - -bool AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::isOutputChannelStereoPair (int index) const -{ - return isInputChannelStereoPair (index); -} - -bool AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::isInput() const { return type == audioInputNode || type == midiInputNode; } -bool AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::isOutput() const { return type == audioOutputNode || type == midiOutputNode; } -bool AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::isAudioOutputNode() const { return type == audioOutputNode; }; - -bool AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::hasEditor() const { return false; } -AudioProcessorEditor* AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::createEditor() { return nullptr; } - -int AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getNumParameters() { return 0; } -const String AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getParameterName (int) { return String::empty; } - -float AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getParameter (int) { return 0.0f; } -const String AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getParameterText (int) { return String::empty; } -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::setParameter (int, float) { } - -int AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getNumPrograms() { return 0; } -int AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getCurrentProgram() { return 0; } -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::setCurrentProgram (int) { } - -const String AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getProgramName (int) { return String::empty; } -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::changeProgramName (int, const String&) {} - -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getStateInformation (juce::MemoryBlock&) {} -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::setStateInformation (const void*, int) {} - -void AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::setParentGraph (AudioProcessorGraphMultiThreaded* const newGraph) -{ - graph = newGraph; - - if (graph != nullptr) - { - setPlayConfigDetails (type == audioOutputNode ? graph->getNumOutputChannels() : 0, - type == audioInputNode ? graph->getNumInputChannels() : 0, - getSampleRate(), - getBlockSize()); - - updateHostDisplay(); - } -} - -double AudioProcessorGraphMultiThreaded::AudioGraphIOProcessor::getTailLengthSeconds() const -{ - return 0.; -} - - - - - diff --git a/source/modules/juce_audio_processors/processors/AudioProcessorGraphMultiThreaded.h b/source/modules/juce_audio_processors/processors/AudioProcessorGraphMultiThreaded.h deleted file mode 100644 index de6e47b8a..000000000 --- a/source/modules/juce_audio_processors/processors/AudioProcessorGraphMultiThreaded.h +++ /dev/null @@ -1,480 +0,0 @@ -/* - ============================================================================== - - AudioProcessorGraphMultiThreaded.h - Created: 26 Nov 2012 11:35:49am - Author: Christian - - ============================================================================== -*/ - -#ifndef __AUDIOPROCESSORGRAPHMULTIMULTITHREADED_H_8E3C7DF3__ -#define __AUDIOPROCESSORGRAPHMULTIMULTITHREADED_H_8E3C7DF3__ - - -class AudioProcessorGraphMultiThreaded : public AudioProcessor, private AsyncUpdater -{ -public: - //============================================================================== - /** Creates an empty graph. */ - AudioProcessorGraphMultiThreaded(); - - /** Destructor. - Any processor objects that have been added to the graph will also be deleted. - */ - ~AudioProcessorGraphMultiThreaded(); - - - void startAllThreads(); - void stopAllThreads(); - - //============================================================================== - /** Represents a connection between two channels of two nodes in an AudioProcessorGraph. - - To create a connection, use AudioProcessorGraph::addConnection(). - */ - struct JUCE_API Connection - { - public: - //============================================================================== - Connection (uint32 sourceNodeId, int sourceChannelIndex, - uint32 destNodeId, int destChannelIndex) noexcept; - - //============================================================================== - /** The ID number of the node which is the input source for this connection. - @see AudioProcessorGraph::getNodeForId - */ - uint32 sourceNodeId; - - /** The index of the output channel of the source node from which this - connection takes its data. - - If this value is the special number AudioProcessorGraph::midiChannelIndex, then - it is referring to the source node's midi output. Otherwise, it is the zero-based - index of an audio output channel in the source node. - */ - int sourceChannelIndex; - - /** The ID number of the node which is the destination for this connection. - @see AudioProcessorGraph::getNodeForId - */ - uint32 destNodeId; - - /** The index of the input channel of the destination node to which this - connection delivers its data. - - If this value is the special number AudioProcessorGraph::midiChannelIndex, then - it is referring to the destination node's midi input. Otherwise, it is the zero-based - index of an audio input channel in the destination node. - */ - int destChannelIndex; - - private: - //============================================================================== - JUCE_LEAK_DETECTOR (Connection); - }; - - - //============================================================================== - /** Represents one of the nodes, or processors, in an AudioProcessorGraph. - - To create a node, call AudioProcessorGraph::addNode(). - */ - class JUCE_API Node : public ReferenceCountedObject - { - public: - //============================================================================== - /** The ID number assigned to this node. - This is assigned by the graph that owns it, and can't be changed. - */ - const uint32 nodeId; - - Node (uint32 nodeId, AudioProcessor*, AudioProcessorGraphMultiThreaded& graph_) noexcept; - virtual ~Node() {}; - - void prepare (double sampleRate, int blockSize); - - void updateMyConnections(); - - bool process(); - - void reset(); - - void unprepare(); - - bool hasReachedNumberOfRequiredInputs(); - - void clearRef() - { - requiredInputs.clear(); - outputNodesToInform.clear(); - } - - - - /** The actual processor object that this node represents. */ - AudioProcessor* getProcessor() const noexcept { return processor; } - - /** A set of user-definable properties that are associated with this node. - - This can be used to attach values to the node for whatever purpose seems - useful. For example, you might store an x and y position if your application - is displaying the nodes on-screen. - */ - NamedValueSet properties; - - //============================================================================== - /** A convenient typedef for referring to a pointer to a node object. */ - typedef ReferenceCountedObjectPtr Ptr; - - void setParentGraph (AudioProcessorGraphMultiThreaded* graph) const; - - int getNumRequiredInputs();; - - bool isProcessingDone();; - - - - - private: - //============================================================================== - - - class NodeChannel - { - public: - ScopedPointer inputConnection; - Node::Ptr node; - }; - - OwnedArray requiredInputs; - OwnedArray outputNodesToInform; - - Atomic numberOfProcessedInputs; - bool processingDone; - CriticalSection nodeLock; - const ScopedPointer processor; - ScopedPointer buffer; - bool isPrepared; - - AudioProcessorGraphMultiThreaded& graph; - MidiBuffer midiBuffer; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Node); - }; - - - - class WorkerThread : public Thread - { - public: - WorkerThread(AudioProcessorGraphMultiThreaded& _graph) : - Thread("AudioProcessingThread"), - graph(_graph) {}; - virtual ~WorkerThread() {}; - void run() - { - while (!threadShouldExit()) - { - graph.processOneNode(false); - } - } - - AudioProcessorGraphMultiThreaded& graph; - }; - - - void processOneNode(bool thisIsAudioCallbackThread); - //============================================================================== - /** Deletes all nodes and connections from this graph. - Any processor objects in the graph will be deleted. - */ - void clear(); - - /** Returns the number of nodes in the graph. */ - int getNumNodes() const; - - /** Returns a pointer to one of the nodes in the graph. - This will return nullptr if the index is out of range. - @see getNodeForId - */ - Node* getNode (const int index) const; - - /** Searches the graph for a node with the given ID number and returns it. - If no such node was found, this returns nullptr. - @see getNode - */ - Node* getNodeForId (const uint32 nodeId) const; - - Node::Ptr getNodeRefPtrForId (const uint32 nodeId) const; - - /** Adds a node to the graph. - - This creates a new node in the graph, for the specified processor. Once you have - added a processor to the graph, the graph owns it and will delete it later when - it is no longer needed. - - The optional nodeId parameter lets you specify an ID to use for the node, but - if the value is already in use, this new node will overwrite the old one. - - If this succeeds, it returns a pointer to the newly-created node. - */ - Node* addNode (AudioProcessor* newProcessor, uint32 nodeId = 0); - - /** Deletes a node within the graph which has the specified ID. - - This will also delete any connections that are attached to this node. - */ - bool removeNode (uint32 nodeId); - - //============================================================================== - /** Returns the number of connections in the graph. */ - int getNumConnections() const { return connections.size(); } - - /** Returns a pointer to one of the connections in the graph. */ - const Connection* getConnection (int index) const { return connections [index]; } - - /** Searches for a connection between some specified channels. - If no such connection is found, this returns nullptr. - */ - const Connection* getConnectionBetween (uint32 sourceNodeId, - int sourceChannelIndex, - uint32 destNodeId, - int destChannelIndex) const; - - int calculateInputConnections(uint32 nodeID) const; - - /** Returns true if there is a connection between any of the channels of - two specified nodes. - */ - bool isConnected (uint32 possibleSourceNodeId, - uint32 possibleDestNodeId) const; - - /** Returns true if it would be legal to connect the specified points. */ - bool canConnect (uint32 sourceNodeId, int sourceChannelIndex, - uint32 destNodeId, int destChannelIndex) const; - - /** Attempts to connect two specified channels of two nodes. - - If this isn't allowed (e.g. because you're trying to connect a midi channel - to an audio one or other such nonsense), then it'll return false. - */ - bool addConnection (uint32 sourceNodeId, int sourceChannelIndex, - uint32 destNodeId, int destChannelIndex); - - /** Deletes the connection with the specified index. */ - void removeConnection (int index); - - /** Deletes any connection between two specified points. - Returns true if a connection was actually deleted. - */ - bool removeConnection (uint32 sourceNodeId, int sourceChannelIndex, - uint32 destNodeId, int destChannelIndex); - - /** Removes all connections from the specified node. */ - bool disconnectNode (uint32 nodeId); - - /** Returns true if the given connection's channel numbers map on to valid - channels at each end. - Even if a connection is valid when created, its status could change if - a node changes its channel config. - */ - bool isConnectionLegal (const Connection* connection) const; - - /** Performs a sanity checks of all the connections. - - This might be useful if some of the processors are doing things like changing - their channel counts, which could render some connections obsolete. - */ - bool removeIllegalConnections(); - - //============================================================================== - /** A special number that represents the midi channel of a node. - - This is used as a channel index value if you want to refer to the midi input - or output instead of an audio channel. - */ - static const int midiChannelIndex; - - - //============================================================================== - /** A special type of AudioProcessor that can live inside an AudioProcessorGraph - in order to use the audio that comes into and out of the graph itself. - - If you create an AudioGraphIOProcessor in "input" mode, it will act as a - node in the graph which delivers the audio that is coming into the parent - graph. This allows you to stream the data to other nodes and process the - incoming audio. - - Likewise, one of these in "output" mode can be sent data which it will add to - the sum of data being sent to the graph's output. - - @see AudioProcessorGraph - */ - class JUCE_API AudioGraphIOProcessor : public AudioPluginInstance - { - public: - /** Specifies the mode in which this processor will operate. - */ - enum IODeviceType - { - audioInputNode, /**< In this mode, the processor has output channels - representing all the audio input channels that are - coming into its parent audio graph. */ - audioOutputNode, /**< In this mode, the processor has input channels - representing all the audio output channels that are - going out of its parent audio graph. */ - midiInputNode, /**< In this mode, the processor has a midi output which - delivers the same midi data that is arriving at its - parent graph. */ - midiOutputNode /**< In this mode, the processor has a midi input and - any data sent to it will be passed out of the parent - graph. */ - }; - - //============================================================================== - /** Returns the mode of this processor. */ - IODeviceType getType() const { return type; } - - /** Returns the parent graph to which this processor belongs, or nullptr if it - hasn't yet been added to one. */ - AudioProcessorGraphMultiThreaded* getParentGraph() const { return graph; } - - /** True if this is an audio or midi input. */ - bool isInput() const; - /** True if this is an audio or midi output. */ - bool isOutput() const; - bool isAudioOutputNode() const; - - //============================================================================== - AudioGraphIOProcessor (const IODeviceType type); - ~AudioGraphIOProcessor(); - - const String getName() const; - void fillInPluginDescription (PluginDescription&) const; - - void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock); - void releaseResources(); - void processBlock (AudioSampleBuffer&, MidiBuffer&); - - const String getInputChannelName (int channelIndex) const; - const String getOutputChannelName (int channelIndex) const; - bool isInputChannelStereoPair (int index) const; - bool isOutputChannelStereoPair (int index) const; - bool silenceInProducesSilenceOut() const; - bool acceptsMidi() const; - bool producesMidi() const; - - bool hasEditor() const; - AudioProcessorEditor* createEditor(); - - int getNumParameters(); - const String getParameterName (int); - float getParameter (int); - const String getParameterText (int); - void setParameter (int, float); - double getTailLengthSeconds() const;; - - int getNumPrograms(); - int getCurrentProgram(); - void setCurrentProgram (int); - const String getProgramName (int); - void changeProgramName (int, const String&); - - void getStateInformation (juce::MemoryBlock& destData); - void setStateInformation (const void* data, int sizeInBytes); - - /** @internal */ - void setParentGraph (AudioProcessorGraphMultiThreaded*); - - private: - const IODeviceType type; - AudioProcessorGraphMultiThreaded* graph; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioGraphIOProcessor); - }; - - //============================================================================== - // AudioProcessor methods: - - const String getName() const; - - void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock); - void releaseResources(); - void processBlock (AudioSampleBuffer&, MidiBuffer&); - - const String getInputChannelName (int channelIndex) const; - const String getOutputChannelName (int channelIndex) const; - bool isInputChannelStereoPair (int index) const; - bool isOutputChannelStereoPair (int index) const; - bool silenceInProducesSilenceOut() const; - - bool acceptsMidi() const; - bool producesMidi() const; - - bool hasEditor() const { return false; } - AudioProcessorEditor* createEditor() { return nullptr; } - - int getNumParameters() { return 0; } - const String getParameterName (int) { return String::empty; } - float getParameter (int) { return 0; } - const String getParameterText (int) { return String::empty; } - void setParameter (int, float) { } - - int getNumPrograms() { return 0; } - int getCurrentProgram() { return 0; } - void setCurrentProgram (int) { } - const String getProgramName (int) { return String::empty; } - void changeProgramName (int, const String&) { } - - void getStateInformation (juce::MemoryBlock&); - void setStateInformation (const void* data, int sizeInBytes); - - double getTailLengthSeconds() const;; - - CriticalSection& getConfigurationLock() - { - return reconfigurationLock; - } - - bool nodeProcessingActive; - -private: - //============================================================================== - Atomic nextNodeIteritater; - int nothingHappenedCounter; // Is not atomic, because integrity isn't so important - - WaitableEvent waitEvent; - - ReferenceCountedArray nodes_original; - ReferenceCountedArray nodes_workingCopy; - - OwnedArray connections; - uint32 lastNodeId; - AudioSampleBuffer renderingBuffers; - OwnedArray midiBuffers; - - CriticalSection renderLock; - CriticalSection reconfigurationLock; - - friend class AudioGraphIOProcessor; - AudioSampleBuffer* currentAudioInputBuffer; - AudioSampleBuffer currentAudioOutputBuffer; - MidiBuffer* currentMidiInputBuffer; - MidiBuffer currentMidiOutputBuffer; - - void handleAsyncUpdate(); - void buildRenderingSequence(); - bool isAnInputTo (uint32 possibleInputId, uint32 possibleDestinationId, int recursionCheck) const; - - OwnedArray workerThreads; - - Node::Ptr outputNode; - - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorGraphMultiThreaded); -}; - - - -#endif // __CK_AUDIOPROCESSORGRAPHMULTIPROCESSOR_H_8E3C7DF3__ diff --git a/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.cpp b/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.cpp deleted file mode 100644 index 118bfc516..000000000 --- a/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -AudioChannelSet::AudioChannelSet (uint32 c) : channels (c) {} - -bool AudioChannelSet::operator== (const AudioChannelSet& other) const noexcept { return channels == other.channels; } -bool AudioChannelSet::operator!= (const AudioChannelSet& other) const noexcept { return channels != other.channels; } -bool AudioChannelSet::operator< (const AudioChannelSet& other) const noexcept { return channels < other.channels; } - -String AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type) -{ - if (type >= discreteChannel0) - return String ("Discrete ") + String (type - discreteChannel0 + 1); - - switch (type) - { - case left: return NEEDS_TRANS("Left"); - case right: return NEEDS_TRANS("Right"); - case centre: return NEEDS_TRANS("Centre"); - case subbass: return NEEDS_TRANS("Subbass"); - case surroundLeft: return NEEDS_TRANS("Left Surround"); - case surroundRight: return NEEDS_TRANS("Right Surround"); - case centreLeft: return NEEDS_TRANS("Centre Left"); - case centreRight: return NEEDS_TRANS("Centre Right"); - case surround: return NEEDS_TRANS("Surround"); - case sideLeft: return NEEDS_TRANS("Side Left"); - case sideRight: return NEEDS_TRANS("Side Right"); - case topMiddle: return NEEDS_TRANS("Top Middle"); - case topFrontLeft: return NEEDS_TRANS("Top Front Left"); - case topFrontCentre: return NEEDS_TRANS("Top Front Centre"); - case topFrontRight: return NEEDS_TRANS("Top Front Right"); - case topRearLeft: return NEEDS_TRANS("Top Rear Left"); - case topRearCentre: return NEEDS_TRANS("Top Rear Centre"); - case topRearRight: return NEEDS_TRANS("Top Rear Right"); - case wideLeft: return NEEDS_TRANS("Wide Left"); - case wideRight: return NEEDS_TRANS("Wide Right"); - case subbass2: return NEEDS_TRANS("Subbass 2"); - case ambisonicW: return NEEDS_TRANS("Ambisonic W"); - case ambisonicX: return NEEDS_TRANS("Ambisonic X"); - case ambisonicY: return NEEDS_TRANS("Ambisonic Y"); - case ambisonicZ: return NEEDS_TRANS("Ambisonic Z"); - default: break; - } - - return "Unknown"; -} - -String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelType type) -{ - if (type >= discreteChannel0) - return String (type - discreteChannel0 + 1); - - switch (type) - { - case left: return "L"; - case right: return "R"; - case centre: return "C"; - case subbass: return "Lfe"; - case surroundLeft: return "Ls"; - case surroundRight: return "Rs"; - case centreLeft: return "Lc"; - case centreRight: return "Rc"; - case surround: return "S"; - case sideLeft: return "Sl"; - case sideRight: return "Sr"; - case topMiddle: return "Tm"; - case topFrontLeft: return "Tfl"; - case topFrontCentre: return "Tfc"; - case topFrontRight: return "Tfr"; - case topRearLeft: return "Trl"; - case topRearCentre: return "Trc"; - case topRearRight: return "Trr"; - case wideLeft: return "Wl"; - case wideRight: return "Wr"; - case subbass2: return "Lfe2"; - case ambisonicW: return "W"; - case ambisonicX: return "X"; - case ambisonicY: return "Y"; - case ambisonicZ: return "Z"; - default: break; - } - - return ""; -} - -String AudioChannelSet::getSpeakerArrangementAsString() const -{ - StringArray speakerTypes; - Array speakers = getChannelTypes(); - - for (int i = 0; i < speakers.size(); ++i) - { - String name = getAbbreviatedChannelTypeName (speakers.getReference (i)); - - if (name.isNotEmpty()) - speakerTypes.add (name); - } - - return speakerTypes.joinIntoString (" "); -} - -int AudioChannelSet::size() const noexcept -{ - return channels.countNumberOfSetBits(); -} - -AudioChannelSet::ChannelType AudioChannelSet::getTypeOfChannel (int index) const noexcept -{ - int bit = channels.findNextSetBit(0); - - for (int i = 0; i < index && bit >= 0; ++i) - bit = channels.findNextSetBit (bit + 1); - - return static_cast (bit); -} - -Array AudioChannelSet::getChannelTypes() const -{ - Array result; - - for (int bit = channels.findNextSetBit(0); bit >= 0; bit = channels.findNextSetBit (bit + 1)) - result.add (static_cast (bit)); - - return result; -} - -void AudioChannelSet::addChannel (ChannelType newChannel) -{ - const int bit = static_cast (newChannel); - jassert (bit >= 0 && bit < 1024); - channels.setBit (bit); -} - -AudioChannelSet AudioChannelSet::disabled() { return AudioChannelSet(); } -AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); } -AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); } -AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); } -AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); } -AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surroundLeft) | (1u << surroundRight)); } -AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centre)); } -AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centre) | (1u << surround)); } -AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centre) | (1u << surround) | (1u << wideLeft) | (1u << wideRight)); } -AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); } -AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << sideLeft) | (1u << sideRight)); } -AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << sideLeft) | (1u << sideRight)); } -AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << sideLeft) | (1u << sideRight) | (1u << surround)); } -AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << sideLeft) | (1u << sideRight) | (1u << surround)); } -AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << sideLeft) | (1u << sideRight) | (1u << surroundLeft) | (1u << surroundRight)); } -AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << sideLeft) | (1u << sideRight) | (1u << surroundLeft) | (1u << surroundRight)); } -AudioChannelSet AudioChannelSet::createFront7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centreLeft) | (1u << centreRight)); } -AudioChannelSet AudioChannelSet::createFront7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << subbass) | (1u << surroundLeft) | (1u << surroundRight) | (1u << centreLeft) | (1u << centreRight)); } - - -AudioChannelSet AudioChannelSet::discreteChannels (int numChannels) -{ - AudioChannelSet s; - s.channels.setRange (discreteChannel0, numChannels, true); - return s; -} - -AudioChannelSet AudioChannelSet::canonicalChannelSet (int numChannels) -{ - if (numChannels == 1) return AudioChannelSet::mono(); - if (numChannels == 2) return AudioChannelSet::stereo(); - if (numChannels == 4) return AudioChannelSet::quadraphonic(); - - return discreteChannels (numChannels); -} diff --git a/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.h b/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.h deleted file mode 100644 index 50be92740..000000000 --- a/source/modules/juce_audio_processors/processors/juce_AudioChannelSet.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_AUDIOCHANNELSET_H_INCLUDED -#define JUCE_AUDIOCHANNELSET_H_INCLUDED - - -//============================================================================== -/** - Represents a set of audio channel types. - - For example, you might have a set of left + right channels, which is a stereo - channel set. It is a collection of values from the AudioChannelSet::ChannelType - enum, where each type may only occur once within the set. - - @see AudioProcessorBus -*/ -class JUCE_API AudioChannelSet -{ -public: - /** Creates an empty channel set. - You can call addChannel to add channels to the set. - */ - AudioChannelSet() noexcept {} - - /** Creates a zero-channel set which can be used to indicate that a - bus is disabled. */ - static AudioChannelSet disabled(); - - /** Creates a one-channel mono set. */ - static AudioChannelSet mono(); - - /** Creates a set containing a left and right channel. */ - static AudioChannelSet stereo(); - - /** Creates a set containing a left, right and centre channels. */ - static AudioChannelSet createLCR(); - - /** Creates a set containing a left, right, centre and surround channels. */ - static AudioChannelSet createLCRS(); - - /** Creates a set for quadraphonic surround setup. */ - static AudioChannelSet quadraphonic(); - - /** Creates a set for pentagonal surround setup. */ - static AudioChannelSet pentagonal(); - - /** Creates a set for hexagonal surround setup. */ - static AudioChannelSet hexagonal(); - - /** Creates a set for octagonal surround setup. */ - static AudioChannelSet octagonal(); - - /** Creates a set for ambisonic surround setups. */ - static AudioChannelSet ambisonic(); - - /** Creates a set for a 5.0 surround setup. */ - static AudioChannelSet create5point0(); - - /** Creates a set for a 5.1 surround setup. */ - static AudioChannelSet create5point1(); - - /** Creates a set for a 6.0 surround setup. */ - static AudioChannelSet create6point0(); - - /** Creates a set for a 6.1 surround setup. */ - static AudioChannelSet create6point1(); - - /** Creates a set for a 7.0 surround setup. */ - static AudioChannelSet create7point0(); - - /** Creates a set for a 7.1 surround setup. */ - static AudioChannelSet create7point1(); - - /** Creates a set for a 7.0 surround setup (with side instead of rear speakers). */ - static AudioChannelSet createFront7point0(); - - /** Creates a set for a 7.1 surround setup (with side instead of rear speakers). */ - static AudioChannelSet createFront7point1(); - - /** Creates a set of untyped discrete channels. */ - static AudioChannelSet discreteChannels (int numChannels); - - /** Create a canonical channel set for a given number of channels. - For example, numChannels = 1 will return mono, numChannels = 2 will return stereo, etc. */ - static AudioChannelSet canonicalChannelSet (int numChannels); - - //============================================================================== - /** Represents different audio channel types. */ - enum ChannelType - { - unknown = 0, - - left = 1, - right = 2, - centre = 3, - - subbass = 4, - surroundLeft = 5, - surroundRight = 6, - centreLeft = 7, - centreRight = 8, - surround = 9, - sideLeft = 10, - sideRight = 11, - topMiddle = 12, - topFrontLeft = 13, - topFrontCentre = 14, - topFrontRight = 15, - topRearLeft = 16, - topRearCentre = 17, - topRearRight = 18, - wideLeft = 19, - wideRight = 20, - subbass2 = 21, - - ambisonicW = 22, - ambisonicX = 23, - ambisonicY = 24, - ambisonicZ = 25, - - - discreteChannel0 = 64 /**< Non-typed individual channels are indexed upwards from this value. */ - }; - - /** Returns the name of a given channel type. For example, this method may return "Surround Left". */ - static String getChannelTypeName (ChannelType); - - /** Returns the abbreviated name of a channel type. For example, this method may return "Ls". */ - static String getAbbreviatedChannelTypeName (ChannelType); - - //============================================================================== - /** Adds a channel to the set. */ - void addChannel (ChannelType newChannelType); - - /** Returns the number of channels in the set. */ - int size() const noexcept; - - /** Returns the number of channels in the set. */ - bool isDisabled() const noexcept { return size() == 0; } - - /** Returns an array of all the types in this channel set. */ - Array getChannelTypes() const; - - /** Returns the type of one of the channels in the set, by index. */ - ChannelType getTypeOfChannel (int channelIndex) const noexcept; - - /** Returns a string containing a whitespace-separated list of speaker types - corresponding to each channel. For example in a 5.1 arrangement, - the string may be "L R C Lfe Ls Rs". If the speaker arrangement is unknown, - the returned string will be empty.*/ - String getSpeakerArrangementAsString() const; - - //============================================================================== - bool operator== (const AudioChannelSet&) const noexcept; - bool operator!= (const AudioChannelSet&) const noexcept; - bool operator< (const AudioChannelSet&) const noexcept; -private: - BigInteger channels; - - explicit AudioChannelSet (uint32); -}; - - - -#endif // JUCE_AUDIOCHANNELSET_H_INCLUDED diff --git a/source/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h b/source/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h index 04308a961..8acc55792 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h +++ b/source/modules/juce_audio_processors/processors/juce_AudioPluginInstance.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPLUGININSTANCE_H_INCLUDED -#define JUCE_AUDIOPLUGININSTANCE_H_INCLUDED +#pragma once //============================================================================== @@ -84,6 +85,3 @@ protected: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginInstance) }; - - -#endif // JUCE_AUDIOPLUGININSTANCE_H_INCLUDED diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 78a5c6a7a..21733c53a 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -74,7 +76,7 @@ void AudioProcessor::initialise (const BusesProperties& ioConfig) AudioProcessor::~AudioProcessor() { - #if ! JUCE_AUDIO_PROCESSOR_NO_GUI + #if ! JUCE_AUDIOPROCESSOR_NO_GUI // ooh, nasty - the editor should have been deleted before the filter // that it refers to is deleted.. jassert (activeEditor == nullptr); @@ -87,17 +89,20 @@ AudioProcessor::~AudioProcessor() #endif } +//============================================================================== +StringArray AudioProcessor::getAlternateDisplayNames() const { return StringArray (getName()); } + //============================================================================== bool AudioProcessor::addBus (bool isInput) { if (! canAddBus (isInput)) return false; - BusProperties BusesProperties; - if (! canApplyBusCountChange (isInput, true, BusesProperties)) + BusProperties busesProps; + if (! canApplyBusCountChange (isInput, true, busesProps)) return false; - createBus (isInput, BusesProperties); + createBus (isInput, busesProps); return true; } @@ -110,8 +115,8 @@ bool AudioProcessor::removeBus (bool inputBus) if (! canRemoveBus (inputBus)) return false; - BusProperties BusesProperties; - if (! canApplyBusCountChange (inputBus, false, BusesProperties)) + BusProperties busesProps; + if (! canApplyBusCountChange (inputBus, false, busesProps)) return false; const int busIdx = numBuses - 1; @@ -426,7 +431,7 @@ int AudioProcessor::getChannelIndexInProcessBlockBuffer (bool isInput, int busIn for (int i = 0; i < ioBus.size() && i < busIndex; ++i) channelIndex += getChannelCountOfBus (isInput, i); - return channelIndex; + return channelIndex; } int AudioProcessor::getOffsetInBusBufferForAbsoluteChannelIndex (bool isInput, int absoluteChannelIndex, /*out*/ int& busIdx) const noexcept @@ -473,7 +478,7 @@ void AudioProcessor::sendParamChangeMessageToListeners (const int parameterIndex if (isPositiveAndBelow (parameterIndex, getNumParameters())) { for (int i = listeners.size(); --i >= 0;) - if (AudioProcessorListener* l = getListenerLocked (i)) + if (auto* l = getListenerLocked (i)) l->audioProcessorParameterChanged (this, parameterIndex, newValue); } else @@ -494,7 +499,7 @@ void AudioProcessor::beginParameterChangeGesture (int parameterIndex) #endif for (int i = listeners.size(); --i >= 0;) - if (AudioProcessorListener* l = getListenerLocked (i)) + if (auto* l = getListenerLocked (i)) l->audioProcessorParameterChangeGestureBegin (this, parameterIndex); } else @@ -544,7 +549,7 @@ int AudioProcessor::getNumParameters() float AudioProcessor::getParameter (int index) { - if (AudioProcessorParameter* p = getParamChecked (index)) + if (auto* p = getParamChecked (index)) return p->getValue(); return 0; @@ -552,13 +557,13 @@ float AudioProcessor::getParameter (int index) void AudioProcessor::setParameter (int index, float newValue) { - if (AudioProcessorParameter* p = getParamChecked (index)) + if (auto* p = getParamChecked (index)) p->setValue (newValue); } float AudioProcessor::getParameterDefaultValue (int index) { - if (AudioProcessorParameter* p = managedParameters[index]) + if (auto* p = managedParameters[index]) return p->getDefaultValue(); return 0; @@ -566,16 +571,16 @@ float AudioProcessor::getParameterDefaultValue (int index) const String AudioProcessor::getParameterName (int index) { - if (AudioProcessorParameter* p = getParamChecked (index)) + if (auto* p = getParamChecked (index)) return p->getName (512); - return String(); + return {}; } String AudioProcessor::getParameterID (int index) { // Don't use getParamChecked here, as this must also work for legacy plug-ins - if (AudioProcessorParameterWithID* p = dynamic_cast (managedParameters[index])) + if (auto* p = dynamic_cast (managedParameters[index])) return p->paramID; return String (index); @@ -583,7 +588,7 @@ String AudioProcessor::getParameterID (int index) String AudioProcessor::getParameterName (int index, int maximumStringLength) { - if (AudioProcessorParameter* p = managedParameters[index]) + if (auto* p = managedParameters[index]) return p->getName (maximumStringLength); return getParameterName (index).substring (0, maximumStringLength); @@ -603,7 +608,7 @@ const String AudioProcessor::getParameterText (int index) String AudioProcessor::getParameterText (int index, int maximumStringLength) { - if (AudioProcessorParameter* p = managedParameters[index]) + if (auto* p = managedParameters[index]) return p->getText (p->getValue(), maximumStringLength); return getParameterText (index).substring (0, maximumStringLength); @@ -611,7 +616,7 @@ String AudioProcessor::getParameterText (int index, int maximumStringLength) int AudioProcessor::getParameterNumSteps (int index) { - if (AudioProcessorParameter* p = managedParameters[index]) + if (auto* p = managedParameters[index]) return p->getNumSteps(); return AudioProcessor::getDefaultNumParameterSteps(); @@ -624,15 +629,15 @@ int AudioProcessor::getDefaultNumParameterSteps() noexcept String AudioProcessor::getParameterLabel (int index) const { - if (AudioProcessorParameter* p = managedParameters[index]) + if (auto* p = managedParameters[index]) return p->getLabel(); - return String(); + return {}; } bool AudioProcessor::isParameterAutomatable (int index) const { - if (AudioProcessorParameter* p = managedParameters[index]) + if (auto* p = managedParameters[index]) return p->isAutomatable(); return true; @@ -640,7 +645,7 @@ bool AudioProcessor::isParameterAutomatable (int index) const bool AudioProcessor::isParameterOrientationInverted (int index) const { - if (AudioProcessorParameter* p = managedParameters[index]) + if (auto* p = managedParameters[index]) return p->isOrientationInverted(); return false; @@ -648,7 +653,7 @@ bool AudioProcessor::isParameterOrientationInverted (int index) const bool AudioProcessor::isMetaParameter (int index) const { - if (AudioProcessorParameter* p = managedParameters[index]) + if (auto* p = managedParameters[index]) return p->isMetaParameter(); return false; @@ -656,7 +661,7 @@ bool AudioProcessor::isMetaParameter (int index) const AudioProcessorParameter::Category AudioProcessor::getParameterCategory (int index) const { - if (AudioProcessorParameter* p = managedParameters[index]) + if (auto* p = managedParameters[index]) return p->getCategory(); return AudioProcessorParameter::genericParameter; @@ -682,6 +687,16 @@ void AudioProcessor::addParameter (AudioProcessorParameter* p) // if you're using parameter objects, then you must not override the // deprecated getNumParameters() method! jassert (getNumParameters() == AudioProcessor::getNumParameters()); + + // check that no two parameters have the same id + #ifdef JUCE_DEBUG + auto paramId = getParameterID (p->parameterIndex); + + for (auto q : managedParameters) + { + jassert (q == nullptr || q == p || paramId != getParameterID (q->parameterIndex)); + } + #endif } void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) @@ -907,6 +922,8 @@ bool AudioProcessor::applyBusLayouts (const BusesLayout& layouts) || layouts.outputBuses.size() != numOutputBuses) return false; + int newNumberOfIns = 0, newNumberOfOuts = 0; + for (int busIdx = 0; busIdx < numInputBuses; ++busIdx) { Bus& bus = *getBus (true, busIdx); @@ -915,6 +932,8 @@ bool AudioProcessor::applyBusLayouts (const BusesLayout& layouts) bus.layout = set; if (! set.isDisabled()) bus.lastLayout = set; + + newNumberOfIns += set.size(); } for (int busIdx = 0; busIdx < numOutputBuses; ++busIdx) @@ -925,9 +944,11 @@ bool AudioProcessor::applyBusLayouts (const BusesLayout& layouts) bus.layout = set; if (! set.isDisabled()) bus.lastLayout = set; + + newNumberOfOuts += set.size(); } - const bool channelNumChanged = (oldNumberOfIns != getTotalNumInputChannels() || oldNumberOfOuts != getTotalNumOutputChannels()); + const bool channelNumChanged = (oldNumberOfIns != newNumberOfIns || oldNumberOfOuts != newNumberOfOuts); audioIOChanged (false, channelNumChanged); return true; @@ -964,7 +985,7 @@ void AudioProcessor::audioIOChanged (bool busNumberChanged, bool channelNumChang processorLayoutsChanged(); } -#if ! JUCE_AUDIO_PROCESSOR_NO_GUI +#if ! JUCE_AUDIOPROCESSOR_NO_GUI //============================================================================== void AudioProcessor::editorBeingDeleted (AudioProcessorEditor* const editor) noexcept { @@ -1306,6 +1327,45 @@ AudioProcessor::BusesProperties AudioProcessor::BusesProperties::withOutput (con return retval; } +//============================================================================== +int32 AudioProcessor::getAAXPluginIDForMainBusConfig (const AudioChannelSet& mainInputLayout, + const AudioChannelSet& mainOutputLayout, + const bool idForAudioSuite) const +{ + int uniqueFormatId = 0; + for (int dir = 0; dir < 2; ++dir) + { + const bool isInput = (dir == 0); + const AudioChannelSet& set = (isInput ? mainInputLayout : mainOutputLayout); + int aaxFormatIndex = 0; + + if (set == AudioChannelSet::disabled()) aaxFormatIndex = 0; + else if (set == AudioChannelSet::mono()) aaxFormatIndex = 1; + else if (set == AudioChannelSet::stereo()) aaxFormatIndex = 2; + else if (set == AudioChannelSet::createLCR()) aaxFormatIndex = 3; + else if (set == AudioChannelSet::createLCRS()) aaxFormatIndex = 4; + else if (set == AudioChannelSet::quadraphonic()) aaxFormatIndex = 5; + else if (set == AudioChannelSet::create5point0()) aaxFormatIndex = 6; + else if (set == AudioChannelSet::create5point1()) aaxFormatIndex = 7; + else if (set == AudioChannelSet::create6point0()) aaxFormatIndex = 8; + else if (set == AudioChannelSet::create6point1()) aaxFormatIndex = 9; + else if (set == AudioChannelSet::create7point0()) aaxFormatIndex = 10; + else if (set == AudioChannelSet::create7point1()) aaxFormatIndex = 11; + else if (set == AudioChannelSet::create7point0SDDS()) aaxFormatIndex = 12; + else if (set == AudioChannelSet::create7point1SDDS()) aaxFormatIndex = 13; + else + { + // AAX does not support this format and the wrapper should not have + // called this method with this layout + jassertfalse; + } + + uniqueFormatId = (uniqueFormatId << 8) | aaxFormatIndex; + } + + return (idForAudioSuite ? 0x6a796161 /* 'jyaa' */ : 0x6a636161 /* 'jcaa' */) + uniqueFormatId; +} + //============================================================================== void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h index ffb182f56..1b817767e 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPROCESSOR_H_INCLUDED -#define JUCE_AUDIOPROCESSOR_H_INCLUDED +#pragma once struct PluginBusUtilities; @@ -95,6 +96,15 @@ public: /** Returns the name of this processor. */ virtual const String getName() const = 0; + /** Returns a list of alternative names to use for this processor. + + Some hosts truncate the name of your AudioProcessor when there isn't enough + space in the GUI to show the full name. Overriding this method, allows the host + to choose an alternative name (such as an abbreviation) to better fit the + available space. + */ + virtual StringArray getAlternateDisplayNames() const; + //============================================================================== /** Called before playback starts, to let the filter prepare itself. @@ -893,7 +903,7 @@ public: */ virtual void setNonRealtime (bool isNonRealtime) noexcept; -#if ! JUCE_AUDIO_PROCESSOR_NO_GUI + #if ! JUCE_AUDIOPROCESSOR_NO_GUI //============================================================================== /** Creates the filter's UI. @@ -939,7 +949,7 @@ public: This may call createEditor() internally to create the component. */ AudioProcessorEditor* createEditorIfNeeded(); -#endif + #endif //============================================================================== /** This must return the correct value immediately after the object has been @@ -1271,11 +1281,25 @@ public: */ void setRateAndBufferSizeDetails (double sampleRate, int blockSize) noexcept; -#if ! JUCE_AUDIO_PROCESSOR_NO_GUI + //============================================================================== + /** AAX plug-ins need to report a unique "plug-in id" for every audio layout + configuration that your AudioProcessor supports on the main bus. Override this + function if you want your AudioProcessor to use a custom "plug-in id" (for example + to stay backward compatible with older versions of JUCE). + + The default implementation will compute a unique integer from the input and output + layout and add this value to the 4 character code 'jcaa' (for native AAX) or 'jyaa' + (for AudioSuite plug-ins). + */ + virtual int32 getAAXPluginIDForMainBusConfig (const AudioChannelSet& mainInputLayout, + const AudioChannelSet& mainOutputLayout, + bool idForAudioSuite) const; + + #if ! JUCE_AUDIOPROCESSOR_NO_GUI //============================================================================== /** Not for public use - this is called before deleting an editor component. */ void editorBeingDeleted (AudioProcessorEditor*) noexcept; -#endif + #endif /** Flags to indicate the type of plugin context in which a processor is being used. */ enum WrapperType @@ -1287,6 +1311,7 @@ public: wrapperType_AudioUnitv3, wrapperType_RTAS, wrapperType_AAX, + wrapperType_LV2, wrapperType_Standalone }; @@ -1305,8 +1330,8 @@ public: These functions are deprecated: use the methods provided in the AudioChannelSet class. */ - JUCE_DEPRECATED_WITH_BODY (const String getInputSpeakerArrangement() const noexcept, { return cachedInputSpeakerArrString; }); - JUCE_DEPRECATED_WITH_BODY (const String getOutputSpeakerArrangement() const noexcept, { return cachedOutputSpeakerArrString; }); + JUCE_DEPRECATED_WITH_BODY (const String getInputSpeakerArrangement() const noexcept, { return cachedInputSpeakerArrString; }) + JUCE_DEPRECATED_WITH_BODY (const String getOutputSpeakerArrangement() const noexcept, { return cachedOutputSpeakerArrString; }) /** Returns the name of one of the processor's input channels. @@ -1519,9 +1544,9 @@ private: //============================================================================== Array listeners; -#if ! JUCE_AUDIO_PROCESSOR_NO_GUI + #if ! JUCE_AUDIOPROCESSOR_NO_GUI Component::SafePointer activeEditor; -#endif + #endif double currentSampleRate; int blockSize, latencySamples; #if JUCE_DEBUG @@ -1556,10 +1581,7 @@ private: void processBypassed (AudioBuffer&, MidiBuffer&); // This method is no longer used - you can delete it from your AudioProcessor classes. - JUCE_DEPRECATED_WITH_BODY (virtual bool silenceInProducesSilenceOut() const, { return false; }); + JUCE_DEPRECATED_WITH_BODY (virtual bool silenceInProducesSilenceOut() const, { return false; }) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessor) }; - - -#endif // JUCE_AUDIOPROCESSOR_H_INCLUDED diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp b/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp index 344d8c4e8..295a64360 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.cpp @@ -2,32 +2,34 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -AudioProcessorEditor::AudioProcessorEditor (AudioProcessor& p) noexcept : processor (p), constrainer (nullptr) +AudioProcessorEditor::AudioProcessorEditor (AudioProcessor& p) noexcept : processor (p) { initialise(); } -AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* p) noexcept : processor (*p), constrainer (nullptr) +AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* p) noexcept : processor (*p) { // the filter must be valid.. jassert (p != nullptr); @@ -36,6 +38,8 @@ AudioProcessorEditor::AudioProcessorEditor (AudioProcessor* p) noexcept : proce AudioProcessorEditor::~AudioProcessorEditor() { + splashScreen.deleteAndZero(); + // if this fails, then the wrapper hasn't called editorBeingDeleted() on the // filter for some reason.. jassert (processor.getActiveEditor() != this); @@ -47,10 +51,27 @@ int AudioProcessorEditor::getControlParameterIndex (Component&) { return -1; } void AudioProcessorEditor::initialise() { + /* + ========================================================================== + In accordance with the terms of the JUCE 5 End-Use License Agreement, the + JUCE Code in SECTION A cannot be removed, changed or otherwise rendered + ineffective unless you have a JUCE Indie or Pro license, or are using + JUCE under the GPL v3 license. + + End User License Agreement: www.juce.com/juce-5-licence + ========================================================================== + */ + + // BEGIN SECTION A + + splashScreen = new JUCESplashScreen (*this); + + // END SECTION A + resizable = false; attachConstrainer (&defaultConstrainer); - addComponentListener (resizeListener = new AudioProcessorEditorListener (this)); + addComponentListener (resizeListener = new AudioProcessorEditorListener (*this)); } //============================================================================== @@ -64,15 +85,19 @@ void AudioProcessorEditor::setResizable (const bool shouldBeResizable, const boo { setConstrainer (&defaultConstrainer); - if (getWidth() > 0 && getHeight() > 0) + if (auto w = getWidth()) { - defaultConstrainer.setSizeLimits (getWidth(), getHeight(), getWidth(), getHeight()); - resized(); + if (auto h = getHeight()) + { + defaultConstrainer.setSizeLimits (w, h, w, h); + resized(); + } } } } - const bool shouldHaveCornerResizer = (useBottomRightCornerResizer && shouldBeResizable); + bool shouldHaveCornerResizer = (useBottomRightCornerResizer && shouldBeResizable); + if (shouldHaveCornerResizer != (resizableCorner != nullptr)) { if (shouldHaveCornerResizer) @@ -81,14 +106,16 @@ void AudioProcessorEditor::setResizable (const bool shouldBeResizable, const boo resizableCorner->setAlwaysOnTop (true); } else + { resizableCorner = nullptr; + } } } -void AudioProcessorEditor::setResizeLimits (const int newMinimumWidth, - const int newMinimumHeight, - const int newMaximumWidth, - const int newMaximumHeight) noexcept +void AudioProcessorEditor::setResizeLimits (int newMinimumWidth, + int newMinimumHeight, + int newMaximumWidth, + int newMaximumHeight) noexcept { // if you've set up a custom constrainer then these settings won't have any effect.. jassert (constrainer == &defaultConstrainer || constrainer == nullptr); @@ -139,12 +166,12 @@ void AudioProcessorEditor::editorResized (bool wasResized) { bool resizerHidden = false; - if (ComponentPeer* peer = getPeer()) + if (auto* peer = getPeer()) resizerHidden = peer->isFullScreen() || peer->isKioskMode(); if (resizableCorner != nullptr) { - resizableCorner->setVisible (! resizerHidden); + resizableCorner->setVisible (! resizerHidden); const int resizerSize = 18; resizableCorner->setBounds (getWidth() - resizerSize, @@ -152,19 +179,22 @@ void AudioProcessorEditor::editorResized (bool wasResized) resizerSize, resizerSize); } - if (! resizable) - { - if (getWidth() > 0 && getHeight() > 0) - defaultConstrainer.setSizeLimits (getWidth(), getHeight(), - getWidth(), getHeight()); - } + if (auto w = getWidth()) + if (auto h = getHeight()) + defaultConstrainer.setSizeLimits (w, h, w, h); } } void AudioProcessorEditor::updatePeer() { if (isOnDesktop()) - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) peer->setConstrainer (constrainer); } + +void AudioProcessorEditor::setScaleFactor (float newScale) +{ + setTransform (AffineTransform::scale (newScale)); + editorResized (true); +} diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h b/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h index e6be249be..a69f77ee3 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPROCESSOREDITOR_H_INCLUDED -#define JUCE_AUDIOPROCESSOREDITOR_H_INCLUDED +#pragma once class AudioProcessorEditorListener; //============================================================================== @@ -84,6 +85,11 @@ public: */ virtual int getControlParameterIndex (Component&); + /** Can be called by a host to tell the editor that it should use a non-unity + GUI scale. + */ + virtual void setScaleFactor (float newScale); + //============================================================================== /** Marks the host's editor window as resizable @@ -150,27 +156,26 @@ private: //============================================================================== struct AudioProcessorEditorListener : ComponentListener { - AudioProcessorEditorListener (AudioProcessorEditor* audioEditor) : e (audioEditor) {} + AudioProcessorEditorListener (AudioProcessorEditor& e) : ed (e) {} + + void componentMovedOrResized (Component&, bool, bool wasResized) override { ed.editorResized (wasResized); } + void componentParentHierarchyChanged (Component&) override { ed.updatePeer(); } - void componentMovedOrResized (Component&, bool, bool wasResized) override { e->editorResized (wasResized); } - void componentParentHierarchyChanged (Component&) override { e->updatePeer(); } - AudioProcessorEditor* e; + AudioProcessorEditor& ed; }; //============================================================================== void initialise(); void editorResized (bool wasResized); void updatePeer(); - void attachConstrainer (ComponentBoundsConstrainer* newConstrainer); + void attachConstrainer (ComponentBoundsConstrainer*); //============================================================================== ScopedPointer resizeListener; bool resizable; ComponentBoundsConstrainer defaultConstrainer; - ComponentBoundsConstrainer* constrainer; + ComponentBoundsConstrainer* constrainer = {}; + Component::SafePointer splashScreen; JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor) }; - - -#endif // JUCE_AUDIOPROCESSOREDITOR_H_INCLUDED diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp b/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp index 5f210446a..663d1b831 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -349,7 +351,7 @@ private: Array channels; Array nodeIds, midiNodeIds; - enum { freeNodeID = 0xffffffff, zeroNodeID = 0xfffffffe }; + enum { freeNodeID = 0xffffffff, zeroNodeID = 0xfffffffe, anonymousNodeID = 0xfffffffd }; static bool isNodeBusy (uint32 nodeID) noexcept { return nodeID != freeNodeID && nodeID != zeroNodeID; } @@ -508,6 +510,8 @@ private: bufIndex = getFreeBuffer (false); jassert (bufIndex != 0); + markBufferAsContaining (bufIndex, static_cast (anonymousNodeID), 0); + const int srcIndex = getBufferContaining (sourceNodes.getUnchecked (0), sourceOutputChans.getUnchecked (0)); if (srcIndex < 0) @@ -1527,7 +1531,7 @@ const String AudioProcessorGraph::AudioGraphIOProcessor::getName() const default: break; } - return String(); + return {}; } void AudioProcessorGraph::AudioGraphIOProcessor::fillInPluginDescription (PluginDescription& d) const @@ -1642,7 +1646,7 @@ bool AudioProcessorGraph::AudioGraphIOProcessor::producesMidi() const bool AudioProcessorGraph::AudioGraphIOProcessor::isInput() const noexcept { return type == audioInputNode || type == midiInputNode; } bool AudioProcessorGraph::AudioGraphIOProcessor::isOutput() const noexcept { return type == audioOutputNode || type == midiOutputNode; } -#if ! JUCE_AUDIO_PROCESSOR_NO_GUI +#if ! JUCE_AUDIOPROCESSOR_NO_GUI bool AudioProcessorGraph::AudioGraphIOProcessor::hasEditor() const { return false; } AudioProcessorEditor* AudioProcessorGraph::AudioGraphIOProcessor::createEditor() { return nullptr; } #endif @@ -1651,7 +1655,7 @@ int AudioProcessorGraph::AudioGraphIOProcessor::getNumPrograms() int AudioProcessorGraph::AudioGraphIOProcessor::getCurrentProgram() { return 0; } void AudioProcessorGraph::AudioGraphIOProcessor::setCurrentProgram (int) { } -const String AudioProcessorGraph::AudioGraphIOProcessor::getProgramName (int) { return String(); } +const String AudioProcessorGraph::AudioGraphIOProcessor::getProgramName (int) { return {}; } void AudioProcessorGraph::AudioGraphIOProcessor::changeProgramName (int, const String&) {} void AudioProcessorGraph::AudioGraphIOProcessor::getStateInformation (juce::MemoryBlock&) {} diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index 690ff7b1e..51df1317f 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPROCESSORGRAPH_H_INCLUDED -#define JUCE_AUDIOPROCESSORGRAPH_H_INCLUDED +#pragma once //============================================================================== /** @@ -104,7 +105,6 @@ public: */ struct JUCE_API Connection { - public: //============================================================================== Connection (uint32 sourceNodeId, int sourceChannelIndex, uint32 destNodeId, int destChannelIndex) noexcept; @@ -178,15 +178,13 @@ public: Node* addNode (AudioProcessor* newProcessor, uint32 nodeId = 0); /** Deletes a node within the graph which has the specified ID. - This will also delete any connections that are attached to this node. */ bool removeNode (uint32 nodeId); - /** Deletes a node within the graph which has the specified ID. - + /** Deletes a node within the graph. This will also delete any connections that are attached to this node. - */ + */ bool removeNode (Node* node); //============================================================================== @@ -321,10 +319,10 @@ public: bool acceptsMidi() const override; bool producesMidi() const override; -#if ! JUCE_AUDIO_PROCESSOR_NO_GUI + #if ! JUCE_AUDIOPROCESSOR_NO_GUI bool hasEditor() const override; AudioProcessorEditor* createEditor() override; -#endif + #endif int getNumPrograms() override; int getCurrentProgram() override; @@ -365,14 +363,14 @@ public: bool acceptsMidi() const override; bool producesMidi() const override; -#if ! JUCE_AUDIO_PROCESSOR_NO_GUI + #if ! JUCE_AUDIOPROCESSOR_NO_GUI bool hasEditor() const override { return false; } AudioProcessorEditor* createEditor() override { return nullptr; } -#endif + #endif int getNumPrograms() override { return 0; } int getCurrentProgram() override { return 0; } void setCurrentProgram (int) override { } - const String getProgramName (int) override { return String(); } + const String getProgramName (int) override { return {}; } void changeProgramName (int, const String&) override { } void getStateInformation (juce::MemoryBlock&) override; void setStateInformation (const void* data, int sizeInBytes) override; @@ -405,6 +403,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorGraph) }; - - -#endif // JUCE_AUDIOPROCESSORGRAPH_H_INCLUDED diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h b/source/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h index a2fe16e14..7b6ef71e5 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessorListener.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPROCESSORLISTENER_H_INCLUDED -#define JUCE_AUDIOPROCESSORLISTENER_H_INCLUDED +#pragma once //============================================================================== @@ -102,5 +103,3 @@ public: virtual void audioProcessorParameterChangeGestureEnd (AudioProcessor* processor, int parameterIndex); }; - -#endif // JUCE_AUDIOPROCESSORLISTENER_H_INCLUDED diff --git a/source/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h b/source/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h index e9ce5c8b0..3abccb795 100644 --- a/source/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h +++ b/source/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPROCESSORPARAMETER_H_INCLUDED -#define JUCE_AUDIOPROCESSORPARAMETER_H_INCLUDED +#pragma once //============================================================================== @@ -175,6 +176,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorParameter) }; - - -#endif // JUCE_AUDIOPROCESSORPARAMETER_H_INCLUDED diff --git a/source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp b/source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp index 3733d3f07..32a2db854 100644 --- a/source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp +++ b/source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h b/source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h index dc5d8fae5..e5d54e5fa 100644 --- a/source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h +++ b/source/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_GENERICAUDIOPROCESSOREDITOR_H_INCLUDED -#define JUCE_GENERICAUDIOPROCESSOREDITOR_H_INCLUDED +#pragma once //============================================================================== @@ -53,6 +54,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GenericAudioProcessorEditor) }; - - -#endif // JUCE_GENERICAUDIOPROCESSOREDITOR_H_INCLUDED diff --git a/source/modules/juce_audio_processors/processors/juce_PluginDescription.cpp b/source/modules/juce_audio_processors/processors/juce_PluginDescription.cpp index c8d8df81d..445ca73f2 100644 --- a/source/modules/juce_audio_processors/processors/juce_PluginDescription.cpp +++ b/source/modules/juce_audio_processors/processors/juce_PluginDescription.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/processors/juce_PluginDescription.h b/source/modules/juce_audio_processors/processors/juce_PluginDescription.h index 488a3c134..046626a50 100644 --- a/source/modules/juce_audio_processors/processors/juce_PluginDescription.h +++ b/source/modules/juce_audio_processors/processors/juce_PluginDescription.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PLUGINDESCRIPTION_H_INCLUDED -#define JUCE_PLUGINDESCRIPTION_H_INCLUDED +#pragma once //============================================================================== @@ -151,6 +152,3 @@ private: //============================================================================== JUCE_LEAK_DETECTOR (PluginDescription) }; - - -#endif // JUCE_PLUGINDESCRIPTION_H_INCLUDED diff --git a/source/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp b/source/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp index 5d45ac6ea..352b6c1c0 100644 --- a/source/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp +++ b/source/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -29,7 +31,7 @@ void KnownPluginList::clear() { ScopedLock lock (typesArrayLock); - if (types.size() > 0) + if (! types.isEmpty()) { types.clear(); sendChangeMessage(); @@ -40,9 +42,9 @@ PluginDescription* KnownPluginList::getTypeForFile (const String& fileOrIdentifi { ScopedLock lock (typesArrayLock); - for (int i = 0; i < types.size(); ++i) - if (types.getUnchecked(i)->fileOrIdentifier == fileOrIdentifier) - return types.getUnchecked(i); + for (auto* desc : types) + if (desc->fileOrIdentifier == fileOrIdentifier) + return desc; return nullptr; } @@ -51,9 +53,9 @@ PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& id { ScopedLock lock (typesArrayLock); - for (int i = 0; i < types.size(); ++i) - if (types.getUnchecked(i)->matchesIdentifierString (identifierString)) - return types.getUnchecked(i); + for (auto* desc : types) + if (desc->matchesIdentifierString (identifierString)) + return desc; return nullptr; } @@ -63,15 +65,15 @@ bool KnownPluginList::addType (const PluginDescription& type) { ScopedLock lock (typesArrayLock); - for (int i = types.size(); --i >= 0;) + for (auto* desc : types) { - if (types.getUnchecked(i)->isDuplicateOf (type)) + if (desc->isDuplicateOf (type)) { // strange - found a duplicate plugin with different info.. - jassert (types.getUnchecked(i)->name == type.name); - jassert (types.getUnchecked(i)->isInstrument == type.isInstrument); + jassert (desc->name == type.name); + jassert (desc->isInstrument == type.isInstrument); - *types.getUnchecked(i) = type; + *desc = type; return false; } } @@ -87,7 +89,6 @@ void KnownPluginList::removeType (const int index) { { ScopedLock lock (typesArrayLock); - types.remove (index); } @@ -102,14 +103,9 @@ bool KnownPluginList::isListingUpToDate (const String& fileOrIdentifier, ScopedLock lock (typesArrayLock); - for (int i = types.size(); --i >= 0;) - { - const PluginDescription* const d = types.getUnchecked(i); - - if (d->fileOrIdentifier == fileOrIdentifier - && formatToUse.pluginNeedsRescanning (*d)) + for (auto* d : types) + if (d->fileOrIdentifier == fileOrIdentifier && formatToUse.pluginNeedsRescanning (*d)) return false; - } return true; } @@ -133,10 +129,8 @@ bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, ScopedLock lock (typesArrayLock); - for (int i = types.size(); --i >= 0;) + for (auto* d : types) { - const PluginDescription* const d = types.getUnchecked(i); - if (d->fileOrIdentifier == fileOrIdentifier && d->pluginFormatName == format.getName()) { if (format.pluginNeedsRescanning (*d)) @@ -169,30 +163,27 @@ bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, } } - for (int i = 0; i < found.size(); ++i) + for (auto* desc : found) { - PluginDescription* const desc = found.getUnchecked(i); jassert (desc != nullptr); - addType (*desc); typesFound.add (new PluginDescription (*desc)); } - return found.size() > 0; + return ! found.isEmpty(); } void KnownPluginList::scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& formatManager, const StringArray& files, OwnedArray& typesFound) { - for (int i = 0; i < files.size(); ++i) + for (const auto& filenameOrID : files) { - const String filenameOrID (files[i]); bool found = false; for (int j = 0; j < formatManager.getNumFormats(); ++j) { - AudioPluginFormat* const format = formatManager.getFormat (j); + auto* format = formatManager.getFormat (j); if (format->fileMightContainThisPluginType (filenameOrID) && scanAndAddFile (filenameOrID, true, typesFound, *format)) @@ -214,8 +205,8 @@ void KnownPluginList::scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& f Array subFiles; f.findChildFiles (subFiles, File::findFilesAndDirectories, false); - for (int j = 0; j < subFiles.size(); ++j) - s.add (subFiles.getReference(j).getFullPathName()); + for (auto& subFile : subFiles) + s.add (subFile.getFullPathName()); } scanAndAddDragAndDroppedFiles (formatManager, s, typesFound); @@ -279,8 +270,8 @@ struct PluginSorter switch (method) { - case KnownPluginList::sortByCategory: diff = first->category.compareNatural (second->category); break; - case KnownPluginList::sortByManufacturer: diff = first->manufacturerName.compareNatural (second->manufacturerName); break; + case KnownPluginList::sortByCategory: diff = first->category.compareNatural (second->category, true); break; + case KnownPluginList::sortByManufacturer: diff = first->manufacturerName.compareNatural (second->manufacturerName, true); break; case KnownPluginList::sortByFormat: diff = first->pluginFormatName.compare (second->pluginFormatName); break; case KnownPluginList::sortByFileSystemLocation: diff = lastPathPart (first->fileOrIdentifier).compare (lastPathPart (second->fileOrIdentifier)); break; case KnownPluginList::sortByInfoUpdateTime: diff = compare (first->lastInfoUpdateTime, second->lastInfoUpdateTime); break; @@ -288,7 +279,7 @@ struct PluginSorter } if (diff == 0) - diff = first->name.compareNatural (second->name); + diff = first->name.compareNatural (second->name, true); return diff * direction; } @@ -338,7 +329,7 @@ void KnownPluginList::sort (const SortMethod method, bool forwards) //============================================================================== XmlElement* KnownPluginList::createXml() const { - XmlElement* const e = new XmlElement ("KNOWNPLUGINS"); + auto e = new XmlElement ("KNOWNPLUGINS"); { ScopedLock lock (typesArrayLock); @@ -347,8 +338,8 @@ XmlElement* KnownPluginList::createXml() const e->prependChildElement (types.getUnchecked(i)->createXml()); } - for (int i = 0; i < blacklist.size(); ++i) - e->createNewChildElement ("BLACKLISTED")->setAttribute ("id", blacklist[i]); + for (auto& b : blacklist) + e->createNewChildElement ("BLACKLISTED")->setAttribute ("id", b); return e; } @@ -379,12 +370,10 @@ struct PluginTreeUtils static void buildTreeByFolder (KnownPluginList::PluginTree& tree, const Array& allPlugins) { - for (int i = 0; i < allPlugins.size(); ++i) + for (auto* pd : allPlugins) { - PluginDescription* const pd = allPlugins.getUnchecked (i); - - String path (pd->fileOrIdentifier.replaceCharacter ('\\', '/') - .upToLastOccurrenceOf ("/", false, false)); + auto path = pd->fileOrIdentifier.replaceCharacter ('\\', '/') + .upToLastOccurrenceOf ("/", false, false); if (path.substring (1, 2) == ":") path = path.substring (2); @@ -399,15 +388,13 @@ struct PluginTreeUtils { for (int i = tree.subFolders.size(); --i >= 0;) { - KnownPluginList::PluginTree& sub = *tree.subFolders.getUnchecked(i); + auto& sub = *tree.subFolders.getUnchecked(i); optimiseFolders (sub, concatenateName || (tree.subFolders.size() > 1)); - if (sub.plugins.size() == 0) + if (sub.plugins.isEmpty()) { - for (int j = 0; j < sub.subFolders.size(); ++j) + for (auto* s : sub.subFolders) { - KnownPluginList::PluginTree* const s = sub.subFolders.getUnchecked(j); - if (concatenateName) s->folder = sub.folder + "/" + s->folder; @@ -427,16 +414,15 @@ struct PluginTreeUtils String lastType; ScopedPointer current (new KnownPluginList::PluginTree()); - for (int i = 0; i < sorted.size(); ++i) + for (auto* pd : sorted) { - const PluginDescription* const pd = sorted.getUnchecked(i); - String thisType (sortMethod == KnownPluginList::sortByCategory ? pd->category + auto thisType = (sortMethod == KnownPluginList::sortByCategory ? pd->category : pd->manufacturerName); if (! thisType.containsNonWhitespaceChars()) thisType = "Other"; - if (thisType != lastType) + if (! thisType.equalsIgnoreCase (lastType)) { if (current->plugins.size() + current->subFolders.size() > 0) { @@ -471,8 +457,8 @@ struct PluginTreeUtils path = path.fromFirstOccurrenceOf (":", false, false); // avoid the special AU formatting nonsense on Mac.. #endif - const String firstSubFolder (path.upToFirstOccurrenceOf ("/", false, false)); - const String remainingPath (path.fromFirstOccurrenceOf ("/", false, false)); + auto firstSubFolder = path.upToFirstOccurrenceOf ("/", false, false); + auto remainingPath = path.fromFirstOccurrenceOf ("/", false, false); for (int i = tree.subFolders.size(); --i >= 0;) { @@ -485,7 +471,7 @@ struct PluginTreeUtils } } - KnownPluginList::PluginTree* const newFolder = new KnownPluginList::PluginTree(); + auto newFolder = new KnownPluginList::PluginTree(); newFolder->folder = firstSubFolder; tree.subFolders.add (newFolder); addPlugin (*newFolder, pd, remainingPath); @@ -510,22 +496,18 @@ struct PluginTreeUtils { bool isTicked = false; - for (int i = 0; i < tree.subFolders.size(); ++i) + for (auto* sub : tree.subFolders) { - const KnownPluginList::PluginTree& sub = *tree.subFolders.getUnchecked(i); - PopupMenu subMenu; - const bool isItemTicked = addToMenu (sub, subMenu, allPlugins, currentlyTickedPluginID); + const bool isItemTicked = addToMenu (*sub, subMenu, allPlugins, currentlyTickedPluginID); isTicked = isTicked || isItemTicked; - m.addSubMenu (sub.folder, subMenu, true, nullptr, isItemTicked, 0); + m.addSubMenu (sub->folder, subMenu, true, nullptr, isItemTicked, 0); } - for (int i = 0; i < tree.plugins.size(); ++i) + for (auto* plugin : tree.plugins) { - const PluginDescription* const plugin = tree.plugins.getUnchecked(i); - - String name (plugin->name); + auto name = plugin->name; if (containsDuplicateNames (tree.plugins, name)) name << " (" << plugin->pluginFormatName << ')'; @@ -548,11 +530,11 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM ScopedLock lock (typesArrayLock); PluginSorter sorter (sortMethod, true); - for (int i = 0; i < types.size(); ++i) - sorted.addSorted (sorter, types.getUnchecked(i)); + for (auto* t : types) + sorted.addSorted (sorter, t); } - PluginTree* tree = new PluginTree(); + auto* tree = new PluginTree(); if (sortMethod == sortByCategory || sortMethod == sortByManufacturer || sortMethod == sortByFormat) { @@ -564,8 +546,8 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM } else { - for (int i = 0; i < sorted.size(); ++i) - tree->plugins.add (sorted.getUnchecked(i)); + for (auto* p : sorted) + tree->plugins.add (p); } return tree; @@ -593,7 +575,7 @@ void KnownPluginList::CustomScanner::scanFinished() {} bool KnownPluginList::CustomScanner::shouldExit() const noexcept { - if (ThreadPoolJob* job = ThreadPoolJob::getCurrentThreadPoolJob()) + if (auto* job = ThreadPoolJob::getCurrentThreadPoolJob()) return job->shouldExit(); return false; diff --git a/source/modules/juce_audio_processors/scanning/juce_KnownPluginList.h b/source/modules/juce_audio_processors/scanning/juce_KnownPluginList.h index 7be3c7617..9095873bd 100644 --- a/source/modules/juce_audio_processors/scanning/juce_KnownPluginList.h +++ b/source/modules/juce_audio_processors/scanning/juce_KnownPluginList.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_KNOWNPLUGINLIST_H_INCLUDED -#define JUCE_KNOWNPLUGINLIST_H_INCLUDED +#pragma once //============================================================================== @@ -220,6 +221,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KnownPluginList) }; - - -#endif // JUCE_KNOWNPLUGINLIST_H_INCLUDED diff --git a/source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp b/source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp index 68405ded3..680e17edd 100644 --- a/source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp +++ b/source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -39,7 +41,6 @@ PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo, : list (listToAddTo), format (formatToLookFor), deadMansPedalFile (deadMansPedal), - progress (0), allowAsync (allowPluginsWhichRequireAsynchronousInstantiation) { directoriesToSearch.removeRedundantPaths(); @@ -48,16 +49,10 @@ PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo, // If any plugins have crashed recently when being loaded, move them to the // end of the list to give the others a chance to load correctly.. - const StringArray crashedPlugins (readDeadMansPedalFile (deadMansPedalFile)); - - for (int i = 0; i < crashedPlugins.size(); ++i) - { - const String f = crashedPlugins[i]; - + for (auto& crashed : readDeadMansPedalFile (deadMansPedalFile)) for (int j = filesOrIdentifiersToScan.size(); --j >= 0;) - if (f == filesOrIdentifiersToScan[j]) + if (crashed == filesOrIdentifiersToScan[j]) filesOrIdentifiersToScan.move (j, -1); - } applyBlacklistingsFromDeadMansPedal (listToAddTo, deadMansPedalFile); nextIndex.set (filesOrIdentifiersToScan.size()); @@ -79,23 +74,23 @@ void PluginDirectoryScanner::updateProgress() progress = (1.0f - nextIndex.get() / (float) filesOrIdentifiersToScan.size()); } -bool PluginDirectoryScanner::scanNextFile (const bool dontRescanIfAlreadyInList, +bool PluginDirectoryScanner::scanNextFile (bool dontRescanIfAlreadyInList, String& nameOfPluginBeingScanned) { const int index = --nextIndex; if (index >= 0) { - const String file (filesOrIdentifiersToScan [index]); + auto file = filesOrIdentifiersToScan [index]; - if (file.isNotEmpty() && ! list.isListingUpToDate (file, format)) + if (file.isNotEmpty() && ! (dontRescanIfAlreadyInList && list.isListingUpToDate (file, format))) { nameOfPluginBeingScanned = format.getNameOfPluginFromIdentifier (file); - OwnedArray typesFound; + OwnedArray typesFound; // Add this plugin to the end of the dead-man's pedal list in case it crashes... - StringArray crashedPlugins (readDeadMansPedalFile (deadMansPedalFile)); + auto crashedPlugins = readDeadMansPedalFile (deadMansPedalFile); crashedPlugins.removeString (file); crashedPlugins.add (file); setDeadMansPedalFile (crashedPlugins); @@ -131,8 +126,6 @@ void PluginDirectoryScanner::applyBlacklistingsFromDeadMansPedal (KnownPluginLis { // If any plugins have crashed recently when being loaded, move them to the // end of the list to give the others a chance to load correctly.. - const StringArray crashedPlugins (readDeadMansPedalFile (file)); - - for (int i = 0; i < crashedPlugins.size(); ++i) - list.addToBlacklist (crashedPlugins[i]); + for (auto& crashedPlugin : readDeadMansPedalFile (file)) + list.addToBlacklist (crashedPlugin); } diff --git a/source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h b/source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h index 4f40981bf..c22ccf300 100644 --- a/source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h +++ b/source/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PLUGINDIRECTORYSCANNER_H_INCLUDED -#define JUCE_PLUGINDIRECTORYSCANNER_H_INCLUDED +#pragma once //============================================================================== @@ -118,14 +119,11 @@ private: File deadMansPedalFile; StringArray failedFiles; Atomic nextIndex; - float progress; - bool allowAsync; + float progress = 0; + const bool allowAsync; void updateProgress(); void setDeadMansPedalFile (const StringArray& newContents); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginDirectoryScanner) }; - - -#endif // JUCE_PLUGINDIRECTORYSCANNER_H_INCLUDED diff --git a/source/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/source/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index 790ee1e17..dd18d45e8 100644 --- a/source/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/source/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -34,8 +36,11 @@ public: void paintRowBackground (Graphics& g, int /*rowNumber*/, int /*width*/, int /*height*/, bool rowIsSelected) override { - if (rowIsSelected) - g.fillAll (owner.findColour (TextEditor::highlightColourId)); + const auto defaultColour = owner.findColour (ListBox::backgroundColourId); + const auto c = rowIsSelected ? defaultColour.interpolatedWith (owner.findColour (ListBox::textColourId), 0.5f) + : defaultColour; + + g.fillAll (c); } enum @@ -75,9 +80,10 @@ public: if (text.isNotEmpty()) { + const auto defaultTextColour = owner.findColour (ListBox::textColourId); g.setColour (isBlacklisted ? Colours::red - : columnId == nameCol ? Colours::black - : Colours::grey); + : columnId == nameCol ? defaultTextColour + : defaultTextColour.interpolatedWith (Colours::transparentBlack, 0.3f)); g.setFont (Font (height * 0.7f, Font::bold)); g.drawFittedText (text, 4, 0, width - 6, height, Justification::centredLeft, 1, 0.9f); } diff --git a/source/modules/juce_audio_processors/scanning/juce_PluginListComponent.h b/source/modules/juce_audio_processors/scanning/juce_PluginListComponent.h index 0d9104ed4..a75387f6e 100644 --- a/source/modules/juce_audio_processors/scanning/juce_PluginListComponent.h +++ b/source/modules/juce_audio_processors/scanning/juce_PluginListComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PLUGINLISTCOMPONENT_H_INCLUDED -#define JUCE_PLUGINLISTCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -127,6 +128,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent) }; - - -#endif // JUCE_PLUGINLISTCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h b/source/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h index 92a2fb20b..ff65cff8b 100644 --- a/source/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h +++ b/source/modules/juce_audio_processors/utilities/juce_AudioParameterBool.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h b/source/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h index aaefd1082..c12432db0 100644 --- a/source/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h +++ b/source/modules/juce_audio_processors/utilities/juce_AudioParameterChoice.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h b/source/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h index 345952dcd..e4c27e2ba 100644 --- a/source/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h +++ b/source/modules/juce_audio_processors/utilities/juce_AudioParameterFloat.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h b/source/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h index e1c0e1497..91f057976 100644 --- a/source/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h +++ b/source/modules/juce_audio_processors/utilities/juce_AudioParameterInt.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h b/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h index f7a6e4165..2569c4d06 100644 --- a/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h +++ b/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameterWithID.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp b/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp index b44ca779c..eecd0cc6d 100644 --- a/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp +++ b/source/modules/juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp index 7506b42eb..4c7fb0054 100644 --- a/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp +++ b/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp @@ -2,28 +2,28 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#if JUCE_COMPILER_SUPPORTS_LAMBDAS - //============================================================================== struct AudioProcessorValueTreeState::Parameter : public AudioProcessorParameterWithID, private ValueTree::Listener @@ -32,11 +32,13 @@ struct AudioProcessorValueTreeState::Parameter : public AudioProcessorParamete const String& parameterID, const String& paramName, const String& labelText, NormalisableRange r, float defaultVal, std::function valueToText, - std::function textToValue) + std::function textToValue, + bool meta) : AudioProcessorParameterWithID (parameterID, paramName, labelText), owner (s), valueToTextFunction (valueToText), textToValueFunction (textToValue), range (r), value (defaultVal), defaultValue (defaultVal), - listenersNeedCalling (true) + listenersNeedCalling (true), + isMeta (meta) { state.addListener (this); needsUpdate.set (1); @@ -144,6 +146,8 @@ struct AudioProcessorValueTreeState::Parameter : public AudioProcessorParamete return nullptr; } + bool isMetaParameter() const override { return isMeta; } + AudioProcessorValueTreeState& owner; ValueTree state; ListenerList listeners; @@ -153,6 +157,7 @@ struct AudioProcessorValueTreeState::Parameter : public AudioProcessorParamete float value, defaultValue; Atomic needsUpdate; bool listenersNeedCalling; + bool isMeta; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Parameter) }; @@ -172,10 +177,11 @@ AudioProcessorValueTreeState::AudioProcessorValueTreeState (AudioProcessor& p, U AudioProcessorValueTreeState::~AudioProcessorValueTreeState() {} -AudioProcessorParameter* AudioProcessorValueTreeState::createAndAddParameter (const String& paramID, const String& paramName, - const String& labelText, NormalisableRange r, - float defaultVal, std::function valueToTextFunction, - std::function textToValueFunction) +AudioProcessorParameterWithID* AudioProcessorValueTreeState::createAndAddParameter (const String& paramID, const String& paramName, + const String& labelText, NormalisableRange r, + float defaultVal, std::function valueToTextFunction, + std::function textToValueFunction, + bool isMetaParameter) { // All parameters must be created before giving this manager a ValueTree state! jassert (! state.isValid()); @@ -184,7 +190,8 @@ AudioProcessorParameter* AudioProcessorValueTreeState::createAndAddParameter (co #endif Parameter* p = new Parameter (*this, paramID, paramName, labelText, r, - defaultVal, valueToTextFunction, textToValueFunction); + defaultVal, valueToTextFunction, textToValueFunction, + isMetaParameter); processor.addParameter (p); return p; } @@ -217,7 +224,7 @@ NormalisableRange AudioProcessorValueTreeState::getParameterRange (String return NormalisableRange(); } -AudioProcessorParameter* AudioProcessorValueTreeState::getParameter (StringRef paramID) const noexcept +AudioProcessorParameterWithID* AudioProcessorValueTreeState::getParameter (StringRef paramID) const noexcept { return Parameter::getParameterForID (processor, paramID); } @@ -554,5 +561,3 @@ AudioProcessorValueTreeState::ButtonAttachment::ButtonAttachment (AudioProcessor } AudioProcessorValueTreeState::ButtonAttachment::~ButtonAttachment() {} - -#endif diff --git a/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h b/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h index d6ec1d303..b3a129fef 100644 --- a/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h +++ b/source/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h @@ -2,30 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AUDIOPROCESSORVALUETREESTATE_H_INCLUDED -#define JUCE_AUDIOPROCESSORVALUETREESTATE_H_INCLUDED - -#if JUCE_COMPILER_SUPPORTS_LAMBDAS +#pragma once /** This class contains a ValueTree which is used to manage an AudioProcessor's entire state. @@ -40,7 +39,7 @@ GUI controls like sliders. To use: - 1) Create an AudioProcessorValueTreeState, and give it some parameters using createParameter(). + 1) Create an AudioProcessorValueTreeState, and give it some parameters using createAndAddParameter(). 2) Initialise the state member variable with a type name. */ class JUCE_API AudioProcessorValueTreeState : private Timer, @@ -76,18 +75,20 @@ public: AudioProcessorParameter::getText() method. This can be nullptr to use the default implementation @param textToValueFunction The inverse of valueToTextFunction + @param isMetaParameter Set this value to true if this should be a meta parameter @returns the parameter object that was created */ - AudioProcessorParameter* createAndAddParameter (const String& parameterID, - const String& parameterName, - const String& labelText, - NormalisableRange valueRange, - float defaultValue, - std::function valueToTextFunction, - std::function textToValueFunction); + AudioProcessorParameterWithID* createAndAddParameter (const String& parameterID, + const String& parameterName, + const String& labelText, + NormalisableRange valueRange, + float defaultValue, + std::function valueToTextFunction, + std::function textToValueFunction, + bool isMetaParameter = false); /** Returns a parameter by its ID string. */ - AudioProcessorParameter* getParameter (StringRef parameterID) const noexcept; + AudioProcessorParameterWithID* getParameter (StringRef parameterID) const noexcept; /** Returns a pointer to a floating point representation of a particular parameter which a realtime process can read to find out its current value. @@ -126,7 +127,7 @@ public: This must be initialised after all calls to createAndAddParameter(). You can replace this with your own ValueTree object, and can add properties and children to the tree. This class will automatically add children for each of the - parameter objects that are created by createParameter(). + parameter objects that are created by createAndAddParameter(). */ ValueTree state; @@ -226,7 +227,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorValueTreeState) }; - -#endif - -#endif // JUCE_AUDIOPROCESSORVALUETREESTATE_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_AbstractFifo.cpp b/source/modules/juce_core/containers/juce_AbstractFifo.cpp index 0b6cd020f..03d61396b 100644 --- a/source/modules/juce_core/containers/juce_AbstractFifo.cpp +++ b/source/modules/juce_core/containers/juce_AbstractFifo.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -138,7 +130,7 @@ void AbstractFifo::finishedRead (int numRead) noexcept class AbstractFifoTests : public UnitTest { public: - AbstractFifoTests() : UnitTest ("Abstract Fifo") {} + AbstractFifoTests() : UnitTest ("Abstract Fifo", "Containers") {} class WriteThread : public Thread { diff --git a/source/modules/juce_core/containers/juce_AbstractFifo.h b/source/modules/juce_core/containers/juce_AbstractFifo.h index edf5464e8..5412a2020 100644 --- a/source/modules/juce_core/containers/juce_AbstractFifo.h +++ b/source/modules/juce_core/containers/juce_AbstractFifo.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ABSTRACTFIFO_H_INCLUDED -#define JUCE_ABSTRACTFIFO_H_INCLUDED +#pragma once //============================================================================== @@ -217,6 +208,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AbstractFifo) }; - - -#endif // JUCE_ABSTRACTFIFO_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_Array.h b/source/modules/juce_core/containers/juce_Array.h index 8d778e37c..4e66a70ea 100644 --- a/source/modules/juce_core/containers/juce_Array.h +++ b/source/modules/juce_core/containers/juce_Array.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ARRAY_H_INCLUDED -#define JUCE_ARRAY_H_INCLUDED +#pragma once //============================================================================== @@ -62,7 +53,7 @@ template ::type ParameterType; public: //============================================================================== @@ -84,14 +75,12 @@ public: new (data.elements + i) ElementType (other.data.elements[i]); } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Array (Array&& other) noexcept : data (static_cast&&> (other.data)), numUsed (other.numUsed) { other.numUsed = 0; } - #endif /** Initalises from a null-terminated C array of values. @@ -146,7 +135,6 @@ public: return *this; } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Array& operator= (Array&& other) noexcept { const ScopedLockType lock (getLock()); @@ -156,7 +144,6 @@ public: other.numUsed = 0; return *this; } - #endif //============================================================================== /** Compares this array to another one. @@ -217,6 +204,15 @@ public: numUsed = 0; } + /** Fills the Array with the provided value. */ + void fill (const ParameterType& newValue) noexcept + { + const ScopedLockType lock (getLock()); + + for (auto& e : *this) + e = newValue; + } + //============================================================================== /** Returns the current number of elements in the array. */ inline int size() const noexcept @@ -392,7 +388,6 @@ public: //============================================================================== /** Appends a new element at the end of the array. - @param newElement the new object to add to the array @see set, insert, addIfNotAlreadyThere, addSorted, addUsingDefaultSort, addArray */ @@ -403,9 +398,7 @@ public: new (data.elements + numUsed++) ElementType (newElement); } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS /** Appends a new element at the end of the array. - @param newElement the new object to add to the array @see set, insert, addIfNotAlreadyThere, addSorted, addUsingDefaultSort, addArray */ @@ -415,7 +408,24 @@ public: data.ensureAllocatedSize (numUsed + 1); new (data.elements + numUsed++) ElementType (static_cast (newElement)); } - #endif + + /** Appends multiple new elements at the end of the array. */ + template + void add (const ElementType& firstNewElement, OtherElements... otherElements) + { + const ScopedLockType lock (getLock()); + data.ensureAllocatedSize (numUsed + 1 + (int) sizeof... (otherElements)); + addAssumingCapacityIsReady (firstNewElement, otherElements...); + } + + /** Appends multiple new elements at the end of the array. */ + template + void add (ElementType&& firstNewElement, OtherElements... otherElements) + { + const ScopedLockType lock (getLock()); + data.ensureAllocatedSize (numUsed + 1 + (int) sizeof... (otherElements)); + addAssumingCapacityIsReady (static_cast (firstNewElement), otherElements...); + } /** Inserts a new element into the array at a given position. @@ -1237,7 +1247,21 @@ private: if (data.numAllocated > jmax (minimumAllocatedSize, numUsed * 2)) data.shrinkToNoMoreThan (jmax (numUsed, jmax (minimumAllocatedSize, 64 / (int) sizeof (ElementType)))); } -}; + void addAssumingCapacityIsReady (const ElementType& e) { new (data.elements + numUsed++) ElementType (e); } + void addAssumingCapacityIsReady (ElementType&& e) { new (data.elements + numUsed++) ElementType (static_cast (e)); } -#endif // JUCE_ARRAY_H_INCLUDED + template + void addAssumingCapacityIsReady (const ElementType& firstNewElement, OtherElements... otherElements) + { + addAssumingCapacityIsReady (firstNewElement); + addAssumingCapacityIsReady (otherElements...); + } + + template + void addAssumingCapacityIsReady (ElementType&& firstNewElement, OtherElements... otherElements) + { + addAssumingCapacityIsReady (static_cast (firstNewElement)); + addAssumingCapacityIsReady (otherElements...); + } +}; diff --git a/source/modules/juce_core/containers/juce_ArrayAllocationBase.h b/source/modules/juce_core/containers/juce_ArrayAllocationBase.h index 40b33a026..a4c3d89f1 100644 --- a/source/modules/juce_core/containers/juce_ArrayAllocationBase.h +++ b/source/modules/juce_core/containers/juce_ArrayAllocationBase.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ARRAYALLOCATIONBASE_H_INCLUDED -#define JUCE_ARRAYALLOCATIONBASE_H_INCLUDED +#pragma once //============================================================================== @@ -60,7 +51,6 @@ public: { } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS ArrayAllocationBase (ArrayAllocationBase&& other) noexcept : elements (static_cast&&> (other.elements)), numAllocated (other.numAllocated) @@ -73,7 +63,6 @@ public: numAllocated = other.numAllocated; return *this; } - #endif //============================================================================== /** Changes the amount of storage allocated. @@ -135,6 +124,3 @@ public: private: JUCE_DECLARE_NON_COPYABLE (ArrayAllocationBase) }; - - -#endif // JUCE_ARRAYALLOCATIONBASE_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_DynamicObject.cpp b/source/modules/juce_core/containers/juce_DynamicObject.cpp index 56d5a83be..56713d3fb 100644 --- a/source/modules/juce_core/containers/juce_DynamicObject.cpp +++ b/source/modules/juce_core/containers/juce_DynamicObject.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -69,10 +61,10 @@ bool DynamicObject::hasMethod (const Identifier& methodName) const var DynamicObject::invokeMethod (Identifier method, const var::NativeFunctionArgs& args) { - if (var::NativeFunction function = properties [method].getNativeFunction()) + if (auto function = properties [method].getNativeFunction()) return function (args); - return var(); + return {}; } void DynamicObject::setMethod (Identifier name, var::NativeFunction function) @@ -88,7 +80,7 @@ void DynamicObject::clear() void DynamicObject::cloneAllProperties() { for (int i = properties.size(); --i >= 0;) - if (var* v = properties.getVarPointerAt (i)) + if (auto* v = properties.getVarPointerAt (i)) *v = v->clone(); } diff --git a/source/modules/juce_core/containers/juce_DynamicObject.h b/source/modules/juce_core/containers/juce_DynamicObject.h index e76ecdbf1..1a8d7af4d 100644 --- a/source/modules/juce_core/containers/juce_DynamicObject.h +++ b/source/modules/juce_core/containers/juce_DynamicObject.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DYNAMICOBJECT_H_INCLUDED -#define JUCE_DYNAMICOBJECT_H_INCLUDED +#pragma once //============================================================================== @@ -135,7 +126,3 @@ private: JUCE_LEAK_DETECTOR (DynamicObject) }; - - - -#endif // JUCE_DYNAMICOBJECT_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_ElementComparator.h b/source/modules/juce_core/containers/juce_ElementComparator.h index 5cfd1f028..3f5881c1d 100644 --- a/source/modules/juce_core/containers/juce_ElementComparator.h +++ b/source/modules/juce_core/containers/juce_ElementComparator.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ELEMENTCOMPARATOR_H_INCLUDED -#define JUCE_ELEMENTCOMPARATOR_H_INCLUDED +#pragma once #ifndef DOXYGEN @@ -184,7 +175,7 @@ template class DefaultElementComparator { private: - typedef PARAMETER_TYPE (ElementType) ParameterType; + typedef typename TypeHelpers::ParameterType::type ParameterType; public: static int compareElements (ParameterType first, ParameterType second) @@ -192,6 +183,3 @@ public: return (first < second) ? -1 : ((second < first) ? 1 : 0); } }; - - -#endif // JUCE_ELEMENTCOMPARATOR_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_HashMap.h b/source/modules/juce_core/containers/juce_HashMap.h index acea1a59e..e44a18249 100644 --- a/source/modules/juce_core/containers/juce_HashMap.h +++ b/source/modules/juce_core/containers/juce_HashMap.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_HASHMAP_H_INCLUDED -#define JUCE_HASHMAP_H_INCLUDED +#pragma once //============================================================================== @@ -102,8 +93,8 @@ template ::type KeyTypeParameter; + typedef typename TypeHelpers::ParameterType::type ValueTypeParameter; public: //============================================================================== @@ -139,9 +130,9 @@ public: { const ScopedLockType sl (getLock()); - for (int i = hashSlots.size(); --i >= 0;) + for (auto i = hashSlots.size(); --i >= 0;) { - HashEntry* h = hashSlots.getUnchecked(i); + auto* h = hashSlots.getUnchecked(i); while (h != nullptr) { @@ -170,24 +161,44 @@ public: { const ScopedLockType sl (getLock()); - for (const HashEntry* entry = hashSlots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry) - if (entry->key == keyToLookFor) - return entry->value; + if (auto* entry = getEntry (getSlot (keyToLookFor), keyToLookFor)) + return entry->value; return ValueType(); } + /** Returns a reference to the value corresponding to a given key. + If the map doesn't contain the key, a default instance of the value type is + added to the map and a reference to this is returned. + @param keyToLookFor the key of the item being requested + */ + inline ValueType& getReference (KeyTypeParameter keyToLookFor) + { + const ScopedLockType sl (getLock()); + auto hashIndex = generateHashFor (keyToLookFor, getNumSlots()); + + auto* firstEntry = hashSlots.getUnchecked (hashIndex); + + if (auto* entry = getEntry (firstEntry, keyToLookFor)) + return entry->value; + + auto* entry = new HashEntry (keyToLookFor, ValueType(), firstEntry); + hashSlots.set (hashIndex, entry); + ++totalNumItems; + + if (totalNumItems > (getNumSlots() * 3) / 2) + remapTable (getNumSlots() * 2); + + return entry->value; + } + //============================================================================== /** Returns true if the map contains an item with the specied key. */ bool contains (KeyTypeParameter keyToLookFor) const { const ScopedLockType sl (getLock()); - for (const HashEntry* entry = hashSlots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry) - if (entry->key == keyToLookFor) - return true; - - return false; + return (getEntry (getSlot (keyToLookFor), keyToLookFor) != nullptr); } /** Returns true if the hash contains at least one occurrence of a given value. */ @@ -195,8 +206,8 @@ public: { const ScopedLockType sl (getLock()); - for (int i = getNumSlots(); --i >= 0;) - for (const HashEntry* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry) + for (auto i = getNumSlots(); --i >= 0;) + for (auto* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry) if (entry->value == valueToLookFor) return true; @@ -208,35 +219,14 @@ public: If there's already an item with the given key, this will replace its value. Otherwise, a new item will be added to the map. */ - void set (KeyTypeParameter newKey, ValueTypeParameter newValue) - { - const ScopedLockType sl (getLock()); - const int hashIndex = generateHashFor (newKey); - - HashEntry* const firstEntry = hashSlots.getUnchecked (hashIndex); - - for (HashEntry* entry = firstEntry; entry != nullptr; entry = entry->nextEntry) - { - if (entry->key == newKey) - { - entry->value = newValue; - return; - } - } - - hashSlots.set (hashIndex, new HashEntry (newKey, newValue, firstEntry)); - ++totalNumItems; - - if (totalNumItems > (getNumSlots() * 3) / 2) - remapTable (getNumSlots() * 2); - } + void set (KeyTypeParameter newKey, ValueTypeParameter newValue) { getReference (newKey) = newValue; } /** Removes an item with the given key. */ void remove (KeyTypeParameter keyToRemove) { const ScopedLockType sl (getLock()); - const int hashIndex = generateHashFor (keyToRemove); - HashEntry* entry = hashSlots.getUnchecked (hashIndex); + auto hashIndex = generateHashFor (keyToRemove, getNumSlots()); + auto* entry = hashSlots.getUnchecked (hashIndex); HashEntry* previous = nullptr; while (entry != nullptr) @@ -267,9 +257,9 @@ public: { const ScopedLockType sl (getLock()); - for (int i = getNumSlots(); --i >= 0;) + for (auto i = getNumSlots(); --i >= 0;) { - HashEntry* entry = hashSlots.getUnchecked(i); + auto* entry = hashSlots.getUnchecked(i); HashEntry* previous = nullptr; while (entry != nullptr) @@ -302,13 +292,27 @@ public: */ void remapTable (int newNumberOfSlots) { - HashMap newTable (newNumberOfSlots); + const ScopedLockType sl (getLock()); + + Array newSlots; + newSlots.insertMultiple (0, nullptr, newNumberOfSlots); + + for (auto i = getNumSlots(); --i >= 0;) + { + HashEntry* nextEntry = nullptr; + + for (auto* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = nextEntry) + { + auto hashIndex = generateHashFor (entry->key, newNumberOfSlots); + + nextEntry = entry->nextEntry; + entry->nextEntry = newSlots.getUnchecked (hashIndex); - for (int i = getNumSlots(); --i >= 0;) - for (const HashEntry* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry) - newTable.set (entry->key, entry->value); + newSlots.set (hashIndex, entry); + } + } - swapWith (newTable); + hashSlots.swapWith (newSlots); } /** Returns the number of slots which are available for hashing. @@ -446,6 +450,9 @@ public: HashEntry* entry; int index; + // using the copy constructor is ok, but you cannot assign iterators + Iterator& operator= (const Iterator&) JUCE_DELETED_FUNCTION; + JUCE_LEAK_DETECTOR (Iterator) }; @@ -465,15 +472,23 @@ private: int totalNumItems; TypeOfCriticalSectionToUse lock; - int generateHashFor (KeyTypeParameter key) const + int generateHashFor (KeyTypeParameter key, int numSlots) const { - const int hash = hashFunctionToUse.generateHash (key, getNumSlots()); - jassert (isPositiveAndBelow (hash, getNumSlots())); // your hash function is generating out-of-range numbers! + const int hash = hashFunctionToUse.generateHash (key, numSlots); + jassert (isPositiveAndBelow (hash, numSlots)); // your hash function is generating out-of-range numbers! return hash; } - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HashMap) -}; + static inline HashEntry* getEntry (HashEntry* firstEntry, KeyType keyToLookFor) noexcept + { + for (auto* entry = firstEntry; entry != nullptr; entry = entry->nextEntry) + if (entry->key == keyToLookFor) + return entry; + + return nullptr; + } + inline HashEntry* getSlot (KeyType key) const noexcept { return hashSlots.getUnchecked (generateHashFor (key, getNumSlots())); } -#endif // JUCE_HASHMAP_H_INCLUDED + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HashMap) +}; diff --git a/source/modules/juce_core/containers/juce_HashMap_test.cpp b/source/modules/juce_core/containers/juce_HashMap_test.cpp new file mode 100644 index 000000000..428bdc807 --- /dev/null +++ b/source/modules/juce_core/containers/juce_HashMap_test.cpp @@ -0,0 +1,271 @@ +/* + ============================================================================== + + 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. + + The code included in this file is provided 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. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +struct HashMapTest : public UnitTest +{ + HashMapTest() : UnitTest ("HashMap", "Containers") {} + + void runTest() override + { + doTest ("AddElementsTest"); + doTest ("AccessTest"); + doTest ("RemoveTest"); + doTest ("PersistantMemoryLocationOfValues"); + } + + //============================================================================== + struct AddElementsTest + { + template + static void run (UnitTest& u) + { + AssociativeMap groundTruth; + HashMap hashMap; + + RandomKeys keyOracle (300, 3827829); + Random valueOracle (48735); + + int totalValues = 0; + for (int i = 0; i < 10000; ++i) + { + auto key = keyOracle.next(); + auto value = valueOracle.nextInt(); + + bool contains = (groundTruth.find (key) != nullptr); + u.expectEquals ((int) contains, (int) hashMap.contains (key)); + + groundTruth.add (key, value); + hashMap.set (key, value); + + if (! contains) totalValues++; + + u.expectEquals (hashMap.size(), totalValues); + } + } + }; + + struct AccessTest + { + template + static void run (UnitTest& u) + { + AssociativeMap groundTruth; + HashMap hashMap; + + fillWithRandomValues (hashMap, groundTruth); + + for (auto pair : groundTruth.pairs) + u.expectEquals (hashMap[pair.key], pair.value); + } + }; + + struct RemoveTest + { + template + static void run (UnitTest& u) + { + AssociativeMap groundTruth; + HashMap hashMap; + + fillWithRandomValues (hashMap, groundTruth); + auto n = groundTruth.size(); + + Random r (3827387); + + for (int i = 0; i < 100; ++i) + { + auto idx = r.nextInt (n-- - 1); + auto key = groundTruth.pairs.getReference (idx).key; + + groundTruth.pairs.remove (idx); + hashMap.remove (key); + + u.expect (! hashMap.contains (key)); + + for (auto pair : groundTruth.pairs) + u.expectEquals (hashMap[pair.key], pair.value); + } + } + }; + + // ensure that the addresses of object references don't change + struct PersistantMemoryLocationOfValues + { + struct AddressAndValue { int value; const int* valueAddress; }; + + template + static void run (UnitTest& u) + { + AssociativeMap groundTruth; + HashMap hashMap; + + RandomKeys keyOracle (300, 3827829); + Random valueOracle (48735); + + for (int i = 0; i < 1000; ++i) + { + auto key = keyOracle.next(); + auto value = valueOracle.nextInt(); + + hashMap.set (key, value); + + if (auto* existing = groundTruth.find (key)) + { + // don't change the address: only the value + existing->value = value; + } + else + { + groundTruth.add (key, { value, &hashMap.getReference (key) }); + } + + for (auto pair : groundTruth.pairs) + { + const auto& hashMapValue = hashMap.getReference (pair.key); + + u.expectEquals (hashMapValue, pair.value.value); + u.expect (&hashMapValue == pair.value.valueAddress); + } + } + + auto n = groundTruth.size(); + Random r (3827387); + + for (int i = 0; i < 100; ++i) + { + auto idx = r.nextInt (n-- - 1); + auto key = groundTruth.pairs.getReference (idx).key; + + groundTruth.pairs.remove (idx); + hashMap.remove (key); + + for (auto pair : groundTruth.pairs) + { + const auto& hashMapValue = hashMap.getReference (pair.key); + + u.expectEquals (hashMapValue, pair.value.value); + u.expect (&hashMapValue == pair.value.valueAddress); + } + } + } + }; + + //============================================================================== + template + void doTest (const String& testName) + { + beginTest (testName); + + Test::template run (*this); + Test::template run (*this); + Test::template run (*this); + } + + //============================================================================== + template + struct AssociativeMap + { + struct KeyValuePair { KeyType key; ValueType value; }; + + ValueType* find (KeyType key) + { + auto n = pairs.size(); + + for (int i = 0; i < n; ++i) + { + auto& pair = pairs.getReference (i); + + if (pair.key == key) + return &pair.value; + } + + return nullptr; + } + + void add (KeyType key, ValueType value) + { + if (ValueType* v = find (key)) + *v = value; + else + pairs.add ({key, value}); + } + + int size() const { return pairs.size(); } + + Array pairs; + }; + + template + static void fillWithRandomValues (HashMap& hashMap, AssociativeMap& groundTruth) + { + RandomKeys keyOracle (300, 3827829); + Random valueOracle (48735); + + for (int i = 0; i < 10000; ++i) + { + auto key = keyOracle.next(); + auto value = valueOracle.nextInt(); + + groundTruth.add (key, value); + hashMap.set (key, value); + } + } + + //============================================================================== + template + class RandomKeys + { + public: + RandomKeys (int maxUniqueKeys, int seed) : r (seed) + { + for (int i = 0; i < maxUniqueKeys; ++i) + keys.add (generateRandomKey (r)); + } + + const KeyType& next() + { + int i = r.nextInt (keys.size() - 1); + return keys.getReference (i); + } + private: + static KeyType generateRandomKey (Random&); + + Random r; + Array keys; + }; +}; + +template <> int HashMapTest::RandomKeys ::generateRandomKey (Random& rnd) { return rnd.nextInt(); } +template <> void* HashMapTest::RandomKeys::generateRandomKey (Random& rnd) { return reinterpret_cast (rnd.nextInt64()); } + +template <> String HashMapTest::RandomKeys::generateRandomKey (Random& rnd) +{ + String str; + + int len = rnd.nextInt (8)+1; + for (int i = 0; i < len; ++i) + str += static_cast (rnd.nextInt (95) + 32); + + return str; +} + +static HashMapTest hashMapTest; diff --git a/source/modules/juce_core/containers/juce_LinkedListPointer.h b/source/modules/juce_core/containers/juce_LinkedListPointer.h index 9581992af..d8ddc7ed0 100644 --- a/source/modules/juce_core/containers/juce_LinkedListPointer.h +++ b/source/modules/juce_core/containers/juce_LinkedListPointer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LINKEDLISTPOINTER_H_INCLUDED -#define JUCE_LINKEDLISTPOINTER_H_INCLUDED +#pragma once //============================================================================== @@ -83,7 +74,6 @@ public: return *this; } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS LinkedListPointer (LinkedListPointer&& other) noexcept : item (other.item) { @@ -98,7 +88,6 @@ public: other.item = nullptr; return *this; } - #endif //============================================================================== /** Returns the item which this pointer points to. */ @@ -368,6 +357,3 @@ private: JUCE_DECLARE_NON_COPYABLE (LinkedListPointer) }; - - -#endif // JUCE_LINKEDLISTPOINTER_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_ListenerList.cpp b/source/modules/juce_core/containers/juce_ListenerList.cpp index bc2f5edc2..f0885171b 100644 --- a/source/modules/juce_core/containers/juce_ListenerList.cpp +++ b/source/modules/juce_core/containers/juce_ListenerList.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -33,7 +25,10 @@ struct ListenerBase { ListenerBase (int& counter) : c (counter) {} - virtual ~ListenerBase () {} + virtual ~ListenerBase() {} + + // Required to supress VS2013 compiler warnings + ListenerBase& operator= (const ListenerBase&) = delete; virtual void f () = 0; virtual void f (void*) = 0; @@ -50,6 +45,9 @@ struct Listener1 : public ListenerBase { Listener1 (int& counter) : ListenerBase (counter) {} + // Required to supress VS2013 compiler warnings + Listener1& operator= (const Listener1&) = delete; + void f () override { c += 1; } void f (void*) override { c += 2; } void f (void*, void*) override { c += 3; } @@ -63,6 +61,9 @@ struct Listener2 : public ListenerBase { Listener2 (int& counter) : ListenerBase (counter) {} + // Required to supress VS2013 compiler warnings + Listener1& operator= (const Listener1&) = delete; + void f () override { c -= 2; } void f (void*) override { c -= 4; } void f (void*, void*) override { c -= 6; } @@ -75,7 +76,7 @@ struct Listener2 : public ListenerBase class ListenerListTests : public UnitTest { public: - ListenerListTests() : UnitTest ("ListenerList") {} + ListenerListTests() : UnitTest ("ListenerList", "Containers") {} template void callHelper (std::vector& expectedCounterValues) @@ -109,7 +110,7 @@ public: } template - void callExcludingHelper (ListenerBase& listenerToExclude, + void callExcludingHelper (ListenerBase* listenerToExclude, std::vector& expectedCounterValues) { counter = 0; @@ -124,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]; @@ -143,6 +144,8 @@ public: void runTest() override { + counter = 0; + beginTest ("Call single listener"); listeners.add (&listener1); std::vector expectedCounterValues; @@ -164,7 +167,10 @@ 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); + + listeners.remove (&listener1); + listeners.remove (&listener2); } int counter = 0; diff --git a/source/modules/juce_core/containers/juce_ListenerList.h b/source/modules/juce_core/containers/juce_ListenerList.h index 6712e9503..36ca27e3c 100644 --- a/source/modules/juce_core/containers/juce_ListenerList.h +++ b/source/modules/juce_core/containers/juce_ListenerList.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LISTENERLIST_H_INCLUDED -#define JUCE_LISTENERLIST_H_INCLUDED +#pragma once //============================================================================== @@ -74,16 +65,10 @@ template > class ListenerList { - // Horrible macros required to support VC7.. - #ifndef DOXYGEN - #if JUCE_VC8_OR_EARLIER - #define LL_TEMPLATE(a) typename P##a, typename Q##a - #define LL_PARAM(a) Q##a& param##a - #else - #define LL_TEMPLATE(a) typename P##a - #define LL_PARAM(a) PARAMETER_TYPE(P##a) param##a - #endif - #endif + #ifndef DOXYGEN + #define LL_TEMPLATE(a) typename P##a + #define LL_PARAM(a) typename TypeHelpers::ParameterType::type param##a + #endif public: //============================================================================== @@ -157,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); @@ -179,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) (); } @@ -201,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); } @@ -226,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); } @@ -250,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); } @@ -276,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); } @@ -300,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); } @@ -326,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); } @@ -350,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); } @@ -376,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); } @@ -400,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); } @@ -426,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); } @@ -450,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); } @@ -476,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); } @@ -555,6 +540,3 @@ private: #undef LL_TEMPLATE #undef LL_PARAM }; - - -#endif // JUCE_LISTENERLIST_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_NamedValueSet.cpp b/source/modules/juce_core/containers/juce_NamedValueSet.cpp index e53943793..b33ea1da9 100644 --- a/source/modules/juce_core/containers/juce_NamedValueSet.cpp +++ b/source/modules/juce_core/containers/juce_NamedValueSet.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -45,7 +37,6 @@ NamedValueSet& NamedValueSet::operator= (const NamedValueSet& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS NamedValueSet::NamedValueSet (NamedValueSet&& other) noexcept : values (static_cast&&> (other.values)) { @@ -56,7 +47,6 @@ NamedValueSet& NamedValueSet::operator= (NamedValueSet&& other) noexcept other.values.swapWith (values); return *this; } -#endif NamedValueSet::~NamedValueSet() noexcept { @@ -122,7 +112,6 @@ var* NamedValueSet::getVarPointer (const Identifier& name) const noexcept return nullptr; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS bool NamedValueSet::set (const Identifier& name, var&& newValue) { if (var* const v = getVarPointer (name)) @@ -137,7 +126,6 @@ bool NamedValueSet::set (const Identifier& name, var&& newValue) values.add (NamedValue (name, static_cast (newValue))); return true; } -#endif bool NamedValueSet::set (const Identifier& name, const var& newValue) { diff --git a/source/modules/juce_core/containers/juce_NamedValueSet.h b/source/modules/juce_core/containers/juce_NamedValueSet.h index 87dec87a4..091605258 100644 --- a/source/modules/juce_core/containers/juce_NamedValueSet.h +++ b/source/modules/juce_core/containers/juce_NamedValueSet.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_NAMEDVALUESET_H_INCLUDED -#define JUCE_NAMEDVALUESET_H_INCLUDED +#pragma once //============================================================================== @@ -50,10 +41,11 @@ public: /** Replaces this set with a copy of another set. */ NamedValueSet& operator= (const NamedValueSet&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ NamedValueSet (NamedValueSet&&) noexcept; + + /** Move assignment operator */ NamedValueSet& operator= (NamedValueSet&&) noexcept; - #endif /** Destructor. */ ~NamedValueSet() noexcept; @@ -68,7 +60,6 @@ public: NamedValue (const Identifier& n, const var& v) : name (n), value (v) {} NamedValue (const NamedValue& other) : name (other.name), value (other.value) {} - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS NamedValue (NamedValue&& other) noexcept : name (static_cast (other.name)), value (static_cast (other.value)) @@ -87,7 +78,6 @@ public: value = static_cast (other.value); return *this; } - #endif bool operator== (const NamedValue& other) const noexcept { return name == other.name && value == other.value; } bool operator!= (const NamedValue& other) const noexcept { return ! operator== (other); } @@ -124,13 +114,11 @@ public: */ bool set (const Identifier& name, const var& newValue); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS /** Changes or adds a named value. @returns true if a value was changed or added; false if the value was already set the value passed-in. */ bool set (const Identifier& name, var&& newValue); - #endif /** Returns true if the set contains an item with the specified name. */ bool contains (const Identifier& name) const noexcept; @@ -183,6 +171,3 @@ private: //============================================================================== Array values; }; - - -#endif // JUCE_NAMEDVALUESET_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_OwnedArray.h b/source/modules/juce_core/containers/juce_OwnedArray.h index a677ae5d9..4bb502814 100644 --- a/source/modules/juce_core/containers/juce_OwnedArray.h +++ b/source/modules/juce_core/containers/juce_OwnedArray.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_OWNEDARRAY_H_INCLUDED -#define JUCE_OWNEDARRAY_H_INCLUDED +#pragma once //============================================================================== @@ -74,7 +65,7 @@ public: deleteAllObjects(); } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ OwnedArray (OwnedArray&& other) noexcept : data (static_cast&&> (other.data)), numUsed (other.numUsed) @@ -82,6 +73,7 @@ public: other.numUsed = 0; } + /** Move assignment operator */ OwnedArray& operator= (OwnedArray&& other) noexcept { const ScopedLockType lock (getLock()); @@ -92,7 +84,6 @@ public: other.numUsed = 0; return *this; } - #endif //============================================================================== /** Clears the array, optionally deleting the objects inside it first. */ @@ -901,6 +892,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OwnedArray) }; - - -#endif // JUCE_OWNEDARRAY_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_PropertySet.cpp b/source/modules/juce_core/containers/juce_PropertySet.cpp index a44f39b48..ce28d140c 100644 --- a/source/modules/juce_core/containers/juce_PropertySet.cpp +++ b/source/modules/juce_core/containers/juce_PropertySet.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/containers/juce_PropertySet.h b/source/modules/juce_core/containers/juce_PropertySet.h index fdd5ad917..b8e934fce 100644 --- a/source/modules/juce_core/containers/juce_PropertySet.h +++ b/source/modules/juce_core/containers/juce_PropertySet.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PROPERTYSET_H_INCLUDED -#define JUCE_PROPERTYSET_H_INCLUDED +#pragma once //============================================================================== @@ -208,6 +199,3 @@ private: JUCE_LEAK_DETECTOR (PropertySet) }; - - -#endif // JUCE_PROPERTYSET_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_ReferenceCountedArray.h b/source/modules/juce_core/containers/juce_ReferenceCountedArray.h index 8702bdbd4..64eb2d531 100644 --- a/source/modules/juce_core/containers/juce_ReferenceCountedArray.h +++ b/source/modules/juce_core/containers/juce_ReferenceCountedArray.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_REFERENCECOUNTEDARRAY_H_INCLUDED -#define JUCE_REFERENCECOUNTEDARRAY_H_INCLUDED +#pragma once //============================================================================== @@ -918,6 +909,3 @@ private: ContainerDeletePolicy::destroy (o); } }; - - -#endif // JUCE_REFERENCECOUNTEDARRAY_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_ScopedValueSetter.h b/source/modules/juce_core/containers/juce_ScopedValueSetter.h index c7240045d..eeb342650 100644 --- a/source/modules/juce_core/containers/juce_ScopedValueSetter.h +++ b/source/modules/juce_core/containers/juce_ScopedValueSetter.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SCOPEDVALUESETTER_H_INCLUDED -#define JUCE_SCOPEDVALUESETTER_H_INCLUDED +#pragma once //============================================================================== @@ -97,6 +88,3 @@ private: JUCE_DECLARE_NON_COPYABLE (ScopedValueSetter) }; - - -#endif // JUCE_SCOPEDVALUESETTER_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_SortedSet.h b/source/modules/juce_core/containers/juce_SortedSet.h index 5b592c292..dfd4fee13 100644 --- a/source/modules/juce_core/containers/juce_SortedSet.h +++ b/source/modules/juce_core/containers/juce_SortedSet.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SORTEDSET_H_INCLUDED -#define JUCE_SORTEDSET_H_INCLUDED +#pragma once #if JUCE_MSVC #pragma warning (push) @@ -498,5 +489,3 @@ private: #if JUCE_MSVC #pragma warning (pop) #endif - -#endif // JUCE_SORTEDSET_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_SparseSet.h b/source/modules/juce_core/containers/juce_SparseSet.h index 7f88f267e..1b4e478e7 100644 --- a/source/modules/juce_core/containers/juce_SparseSet.h +++ b/source/modules/juce_core/containers/juce_SparseSet.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SPARSESET_H_INCLUDED -#define JUCE_SPARSESET_H_INCLUDED +#pragma once //============================================================================== @@ -294,7 +285,3 @@ private: values.removeRange (--i, 2); } }; - - - -#endif // JUCE_SPARSESET_H_INCLUDED diff --git a/source/modules/juce_core/containers/juce_Variant.cpp b/source/modules/juce_core/containers/juce_Variant.cpp index 04a82f8c4..2d79e22bd 100644 --- a/source/modules/juce_core/containers/juce_Variant.cpp +++ b/source/modules/juce_core/containers/juce_Variant.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -51,7 +43,7 @@ public: virtual int toInt (const ValueUnion&) const noexcept { return 0; } virtual int64 toInt64 (const ValueUnion&) const noexcept { return 0; } virtual double toDouble (const ValueUnion&) const noexcept { return 0; } - virtual String toString (const ValueUnion&) const { return String(); } + virtual String toString (const ValueUnion&) const { return {}; } virtual bool toBool (const ValueUnion&) const noexcept { return false; } virtual ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; } virtual Array* toArray (const ValueUnion&) const noexcept { return nullptr; } @@ -113,8 +105,8 @@ public: VariantType_Int() noexcept {} static const VariantType_Int instance; - int toInt (const ValueUnion& data) const noexcept override { return data.intValue; }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.intValue; }; + int toInt (const ValueUnion& data) const noexcept override { return data.intValue; } + int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.intValue; } double toDouble (const ValueUnion& data) const noexcept override { return (double) data.intValue; } String toString (const ValueUnion& data) const override { return String (data.intValue); } bool toBool (const ValueUnion& data) const noexcept override { return data.intValue != 0; } @@ -143,8 +135,8 @@ public: VariantType_Int64() noexcept {} static const VariantType_Int64 instance; - int toInt (const ValueUnion& data) const noexcept override { return (int) data.int64Value; }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return data.int64Value; }; + int toInt (const ValueUnion& data) const noexcept override { return (int) data.int64Value; } + int64 toInt64 (const ValueUnion& data) const noexcept override { return data.int64Value; } double toDouble (const ValueUnion& data) const noexcept override { return (double) data.int64Value; } String toString (const ValueUnion& data) const override { return String (data.int64Value); } bool toBool (const ValueUnion& data) const noexcept override { return data.int64Value != 0; } @@ -173,11 +165,11 @@ public: VariantType_Double() noexcept {} static const VariantType_Double instance; - int toInt (const ValueUnion& data) const noexcept override { return (int) data.doubleValue; }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.doubleValue; }; + int toInt (const ValueUnion& data) const noexcept override { return (int) data.doubleValue; } + int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.doubleValue; } double toDouble (const ValueUnion& data) const noexcept override { return data.doubleValue; } String toString (const ValueUnion& data) const override { return String (data.doubleValue, 20); } - bool toBool (const ValueUnion& data) const noexcept override { return data.doubleValue != 0; } + bool toBool (const ValueUnion& data) const noexcept override { return data.doubleValue != 0.0; } bool isDouble() const noexcept override { return true; } bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override @@ -200,8 +192,8 @@ public: VariantType_Bool() noexcept {} static const VariantType_Bool instance; - int toInt (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; }; + int toInt (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; } + int64 toInt64 (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; } double toDouble (const ValueUnion& data) const noexcept override { return data.boolValue ? 1.0 : 0.0; } String toString (const ValueUnion& data) const override { return String::charToString (data.boolValue ? (juce_wchar) '1' : (juce_wchar) '0'); } bool toBool (const ValueUnion& data) const noexcept override { return data.boolValue; } @@ -230,8 +222,8 @@ public: void createCopy (ValueUnion& dest, const ValueUnion& source) const override { new (dest.stringValue) String (*getString (source)); } bool isString() const noexcept override { return true; } - int toInt (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue(); }; - int64 toInt64 (const ValueUnion& data) const noexcept override { return getString (data)->getLargeIntValue(); }; + int toInt (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue(); } + int64 toInt64 (const ValueUnion& data) const noexcept override { return getString (data)->getLargeIntValue(); } double toDouble (const ValueUnion& data) const noexcept override { return getString (data)->getDoubleValue(); } String toString (const ValueUnion& data) const override { return *getString (data); } bool toBool (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue() != 0 @@ -291,7 +283,7 @@ public: return d->clone().get(); jassertfalse; // can only clone DynamicObjects! - return var(); + return {}; } void writeToStream (const ValueUnion&, OutputStream& output) const override @@ -314,7 +306,7 @@ public: Array* toArray (const ValueUnion& data) const noexcept override { - if (RefCountedArray* a = dynamic_cast (data.objectValue)) + if (auto* a = dynamic_cast (data.objectValue)) return &(a->array); return nullptr; @@ -331,7 +323,7 @@ public: { Array arrayCopy; - if (const Array* array = toArray (original.value)) + if (auto* array = toArray (original.value)) for (int i = 0; i < array->size(); ++i) arrayCopy.add (array->getReference(i).clone()); @@ -340,7 +332,7 @@ public: void writeToStream (const ValueUnion& data, OutputStream& output) const override { - if (const Array* array = toArray (data)) + if (auto* array = toArray (data)) { MemoryOutputStream buffer (512); const int numItems = array->size(); @@ -358,9 +350,7 @@ public: struct RefCountedArray : public ReferenceCountedObject { RefCountedArray (const Array& a) : array (a) { incReferenceCount(); } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS RefCountedArray (Array&& a) : array (static_cast&&> (a)) { incReferenceCount(); } - #endif Array array; }; }; @@ -527,7 +517,6 @@ var& var::operator= (const Array& v) { var v2 (v); swapWith (v2); re var& var::operator= (ReferenceCountedObject* v) { var v2 (v); swapWith (v2); return *this; } var& var::operator= (NativeFunction v) { var v2 (v); swapWith (v2); return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS var::var (var&& other) noexcept : type (other.type), value (other.value) @@ -563,7 +552,6 @@ var& var::operator= (String&& v) new (value.stringValue) String (static_cast (v)); return *this; } -#endif //============================================================================== bool var::equals (const var& other) const noexcept @@ -597,7 +585,7 @@ var var::clone() const noexcept //============================================================================== const var& var::operator[] (const Identifier& propertyName) const { - if (DynamicObject* const o = getDynamicObject()) + if (auto* o = getDynamicObject()) return o->getProperty (propertyName); return getNullVarRef(); @@ -610,7 +598,7 @@ const var& var::operator[] (const char* const propertyName) const var var::getProperty (const Identifier& propertyName, const var& defaultReturnValue) const { - if (DynamicObject* const o = getDynamicObject()) + if (auto* o = getDynamicObject()) return o->getProperties().getWithDefault (propertyName, defaultReturnValue); return defaultReturnValue; @@ -623,10 +611,10 @@ var::NativeFunction var::getNativeFunction() const var var::invoke (const Identifier& method, const var* arguments, int numArguments) const { - if (DynamicObject* const o = getDynamicObject()) + if (auto* o = getDynamicObject()) return o->invokeMethod (method, var::NativeFunctionArgs (*this, arguments, numArguments)); - return var(); + return {}; } var var::call (const Identifier& method) const @@ -666,7 +654,7 @@ var var::call (const Identifier& method, const var& arg1, const var& arg2, const //============================================================================== int var::size() const { - if (const Array* const array = getArray()) + if (auto* array = getArray()) return array->size(); return 0; @@ -674,7 +662,7 @@ int var::size() const const var& var::operator[] (int arrayIndex) const { - const Array* const array = getArray(); + auto* array = getArray(); // When using this method, the var must actually be an array, and the index // must be in-range! @@ -685,7 +673,7 @@ const var& var::operator[] (int arrayIndex) const var& var::operator[] (int arrayIndex) { - const Array* const array = getArray(); + auto* array = getArray(); // When using this method, the var must actually be an array, and the index // must be in-range! @@ -696,7 +684,7 @@ var& var::operator[] (int arrayIndex) Array* var::convertToArray() { - if (Array* array = getArray()) + if (auto* array = getArray()) return array; Array tempVar; @@ -714,7 +702,7 @@ void var::append (const var& n) void var::remove (const int index) { - if (Array* const array = getArray()) + if (auto* const array = getArray()) array->remove (index); } @@ -730,7 +718,7 @@ void var::resize (const int numArrayElementsWanted) int var::indexOf (const var& n) const { - if (const Array* const array = getArray()) + if (auto* const array = getArray()) return array->indexOf (n); return -1; @@ -778,7 +766,7 @@ var var::readFromStream (InputStream& input) case varMarker_Array: { var v; - Array* const destArray = v.convertToArray(); + auto* destArray = v.convertToArray(); for (int i = input.readCompressedInt(); --i >= 0;) destArray->add (readFromStream (input)); @@ -791,7 +779,7 @@ var var::readFromStream (InputStream& input) } } - return var(); + return {}; } var::NativeFunctionArgs::NativeFunctionArgs (const var& t, const var* args, int numArgs) noexcept diff --git a/source/modules/juce_core/containers/juce_Variant.h b/source/modules/juce_core/containers/juce_Variant.h index 071f0a45a..d227a6a04 100644 --- a/source/modules/juce_core/containers/juce_Variant.h +++ b/source/modules/juce_core/containers/juce_Variant.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_VARIANT_H_INCLUDED -#define JUCE_VARIANT_H_INCLUDED +#pragma once //============================================================================== @@ -52,22 +43,19 @@ public: /** This structure is passed to a NativeFunction callback, and contains invocation details about the function's arguments and context. */ - struct NativeFunctionArgs + struct JUCE_API NativeFunctionArgs { 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; - - JUCE_DECLARE_NON_COPYABLE (NativeFunctionArgs) }; - #if JUCE_COMPILER_SUPPORTS_LAMBDAS using NativeFunction = std::function; - #else - typedef var (*NativeFunction) (const NativeFunctionArgs&); - #endif //============================================================================== /** Creates a void variant. */ @@ -109,14 +97,12 @@ public: var& operator= (ReferenceCountedObject* object); var& operator= (NativeFunction method); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS var (var&&) noexcept; var (String&&); var (MemoryBlock&&); var (Array&&); var& operator= (var&&) noexcept; var& operator= (String&&); - #endif void swapWith (var& other) noexcept; @@ -348,6 +334,3 @@ struct VariantConverter static String fromVar (const var& v) { return v.toString(); } static var toVar (const String& s) { return s; } }; - - -#endif // JUCE_VARIANT_H_INCLUDED diff --git a/source/modules/juce_core/files/juce_DirectoryIterator.cpp b/source/modules/juce_core/files/juce_DirectoryIterator.cpp index 8a1169290..c32ae7b51 100644 --- a/source/modules/juce_core/files/juce_DirectoryIterator.cpp +++ b/source/modules/juce_core/files/juce_DirectoryIterator.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -164,5 +156,5 @@ float DirectoryIterator::getEstimatedProgress() const const float detailedIndex = (subIterator != nullptr) ? index + subIterator->getEstimatedProgress() : (float) index; - return detailedIndex / totalNumFiles; + return jlimit (0.0f, 1.0f, detailedIndex / totalNumFiles); } diff --git a/source/modules/juce_core/files/juce_DirectoryIterator.h b/source/modules/juce_core/files/juce_DirectoryIterator.h index c1ed9cb23..83e579bcd 100644 --- a/source/modules/juce_core/files/juce_DirectoryIterator.h +++ b/source/modules/juce_core/files/juce_DirectoryIterator.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DIRECTORYITERATOR_H_INCLUDED -#define JUCE_DIRECTORYITERATOR_H_INCLUDED +#pragma once //============================================================================== @@ -157,5 +148,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectoryIterator) }; - -#endif // JUCE_DIRECTORYITERATOR_H_INCLUDED diff --git a/source/modules/juce_core/files/juce_File.cpp b/source/modules/juce_core/files/juce_File.cpp index 9b99a95c3..c5bd5b8be 100644 --- a/source/modules/juce_core/files/juce_File.cpp +++ b/source/modules/juce_core/files/juce_File.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -57,7 +49,6 @@ File& File::operator= (const File& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS File::File (File&& other) noexcept : fullPath (static_cast (other.fullPath)) { @@ -68,7 +59,6 @@ File& File::operator= (File&& other) noexcept fullPath = static_cast (other.fullPath); return *this; } -#endif #if JUCE_ALLOW_STATIC_NULL_VARIABLES const File File::nonexistent; @@ -113,10 +103,15 @@ static String removeEllipsis (const String& path) return path; } +bool File::isRoot() const +{ + return fullPath.isNotEmpty() && *this == getParentDirectory(); +} + String File::parseAbsolutePath (const String& p) { if (p.isEmpty()) - return String(); + return {}; #if JUCE_WINDOWS // Windows.. @@ -550,7 +545,7 @@ bool File::loadFileAsData (MemoryBlock& destBlock) const String File::loadFileAsString() const { if (! existsAsFile()) - return String(); + return {}; FileInputStream in (*this); return in.openedOk() ? in.readEntireStreamAsString() @@ -669,7 +664,7 @@ String File::getFileExtension() const if (indexOfDot > fullPath.lastIndexOfChar (separator)) return fullPath.substring (indexOfDot); - return String(); + return {}; } bool File::hasFileExtension (StringRef possibleSuffix) const @@ -700,7 +695,7 @@ bool File::hasFileExtension (StringRef possibleSuffix) const File File::withFileExtension (StringRef newExtension) const { if (fullPath.isEmpty()) - return File(); + return {}; String filePart (getFileName()); @@ -772,8 +767,7 @@ bool File::appendText (const String& text, if (out.failedToOpen()) return false; - out.writeText (text, asUnicode, writeUnicodeHeaderBytes); - return true; + return out.writeText (text, asUnicode, writeUnicodeHeaderBytes); } bool File::replaceWithText (const String& textToWrite, @@ -867,7 +861,7 @@ static int countNumberOfSeparators (String::CharPointerType s) for (;;) { - const juce_wchar c = s.getAndAdvance(); + auto c = s.getAndAdvance(); if (c == 0) break; @@ -879,28 +873,31 @@ static int countNumberOfSeparators (String::CharPointerType s) return num; } -String File::getRelativePathFrom (const File& dir) const +String File::getRelativePathFrom (const File& dir) const { - String thisPath (fullPath); + if (dir == *this) + return "."; + + auto thisPath = fullPath; while (thisPath.endsWithChar (separator)) thisPath = thisPath.dropLastCharacters (1); - String dirPath (addTrailingSeparator (dir.existsAsFile() ? dir.getParentDirectory().getFullPathName() - : dir.fullPath)); + auto dirPath = addTrailingSeparator (dir.existsAsFile() ? dir.getParentDirectory().getFullPathName() + : dir.fullPath); int commonBitLength = 0; - String::CharPointerType thisPathAfterCommon (thisPath.getCharPointer()); - String::CharPointerType dirPathAfterCommon (dirPath.getCharPointer()); + auto thisPathAfterCommon = thisPath.getCharPointer(); + auto dirPathAfterCommon = dirPath.getCharPointer(); { - String::CharPointerType thisPathIter (thisPath.getCharPointer()); - String::CharPointerType dirPathIter (dirPath.getCharPointer()); + auto thisPathIter = thisPath.getCharPointer(); + auto dirPathIter = dirPath.getCharPointer(); for (int i = 0;;) { - const juce_wchar c1 = thisPathIter.getAndAdvance(); - const juce_wchar c2 = dirPathIter.getAndAdvance(); + auto c1 = thisPathIter.getAndAdvance(); + auto c2 = dirPathIter.getAndAdvance(); #if NAMES_ARE_CASE_SENSITIVE if (c1 != c2 @@ -925,7 +922,7 @@ String File::getRelativePathFrom (const File& dir) const if (commonBitLength == 0 || (commonBitLength == 1 && thisPath[1] == separator)) return fullPath; - const int numUpDirectoriesNeeded = countNumberOfSeparators (dirPathAfterCommon); + auto numUpDirectoriesNeeded = countNumberOfSeparators (dirPathAfterCommon); if (numUpDirectoriesNeeded == 0) return thisPathAfterCommon; @@ -942,9 +939,9 @@ String File::getRelativePathFrom (const File& dir) const //============================================================================== File File::createTempFile (StringRef fileNameEnding) { - const File tempFile (getSpecialLocation (tempDirectory) - .getChildFile ("temp_" + String::toHexString (Random::getSystemRandom().nextInt())) - .withFileExtension (fileNameEnding)); + auto tempFile = getSpecialLocation (tempDirectory) + .getChildFile ("temp_" + String::toHexString (Random::getSystemRandom().nextInt())) + .withFileExtension (fileNameEnding); if (tempFile.exists()) return createTempFile (fileNameEnding); @@ -1007,7 +1004,7 @@ MemoryMappedFile::MemoryMappedFile (const File& file, const Range& fileRa class FileTests : public UnitTest { public: - FileTests() : UnitTest ("Files") {} + FileTests() : UnitTest ("Files", "Files") {} void runTest() override { diff --git a/source/modules/juce_core/files/juce_File.h b/source/modules/juce_core/files/juce_File.h index f469124ed..de3a7d9e9 100644 --- a/source/modules/juce_core/files/juce_File.h +++ b/source/modules/juce_core/files/juce_File.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILE_H_INCLUDED -#define JUCE_FILE_H_INCLUDED +#pragma once //============================================================================== @@ -90,10 +81,11 @@ public: /** Copies from another file object. */ File& operator= (const File& otherFile); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ File (File&&) noexcept; + + /** Move assignment operator */ File& operator= (File&&) noexcept; - #endif //============================================================================== #if JUCE_ALLOW_STATIC_NULL_VARIABLES @@ -128,6 +120,14 @@ public: */ bool isDirectory() const; + /** Checks whether the path of this file represents the root of a file system, + irrespective of its existance. + + This will return true for "C:", "D:", etc on Windows and "/" on other + platforms. + */ + bool isRoot() const; + /** Returns the size of the file in bytes. @returns the number of bytes in the file, or 0 if it doesn't exist. @@ -810,6 +810,7 @@ public: On Windows, this might be "\Documents and Settings\username\Application Data". On the Mac, it might be "~/Library". If you're going to store your settings in here, always create your own sub-folder to put them in, to avoid making a mess. + On GNU/Linux it is "~/.config". */ userApplicationDataDirectory, @@ -819,6 +820,8 @@ public: On the Mac it'll be "/Library", on Windows, it could be something like "\Documents and Settings\All Users\Application Data". + On GNU/Linux it is "/opt". + Depending on the setup, this folder may be read-only. */ commonApplicationDataDirectory, @@ -874,10 +877,21 @@ public: #endif /** The directory in which applications normally get installed. - So on windows, this would be something like "c:\program files", on the + So on windows, this would be something like "C:\Program Files", on the Mac "/Applications", or "/usr" on linux. */ - globalApplicationsDirectory + globalApplicationsDirectory, + + #if JUCE_WINDOWS + /** On a Windows machine, returns the directory in which 32 bit applications + normally get installed. On a 64 bit machine this would be something like + "C:\Program Files (x86)", whereas for 32 bit machines this would match + globalApplicationsDirectory and be something like "C:\Program Files". + + @see globalApplicationsDirectory + */ + globalApplicationsDirectoryX86 + #endif }; /** Finds the location of a special type of file or directory, such as a home folder or @@ -1029,5 +1043,3 @@ private: bool setFileReadOnlyInternal (bool) const; bool setFileExecutableInternal (bool) const; }; - -#endif // JUCE_FILE_H_INCLUDED diff --git a/source/modules/juce_core/files/juce_FileFilter.cpp b/source/modules/juce_core/files/juce_FileFilter.cpp index 24b656c2a..3fe61708a 100644 --- a/source/modules/juce_core/files/juce_FileFilter.cpp +++ b/source/modules/juce_core/files/juce_FileFilter.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/files/juce_FileFilter.h b/source/modules/juce_core/files/juce_FileFilter.h index 98847bc7f..d40da458c 100644 --- a/source/modules/juce_core/files/juce_FileFilter.h +++ b/source/modules/juce_core/files/juce_FileFilter.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILEFILTER_H_INCLUDED -#define JUCE_FILEFILTER_H_INCLUDED +#pragma once //============================================================================== @@ -74,6 +65,3 @@ protected: //============================================================================== String description; }; - - -#endif // JUCE_FILEFILTER_H_INCLUDED diff --git a/source/modules/juce_core/files/juce_FileInputStream.cpp b/source/modules/juce_core/files/juce_FileInputStream.cpp index 9ec77881c..f136cf090 100644 --- a/source/modules/juce_core/files/juce_FileInputStream.cpp +++ b/source/modules/juce_core/files/juce_FileInputStream.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/files/juce_FileInputStream.h b/source/modules/juce_core/files/juce_FileInputStream.h index 3f7caa27b..8354b20d5 100644 --- a/source/modules/juce_core/files/juce_FileInputStream.h +++ b/source/modules/juce_core/files/juce_FileInputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILEINPUTSTREAM_H_INCLUDED -#define JUCE_FILEINPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -93,6 +84,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileInputStream) }; - - -#endif // JUCE_FILEINPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/files/juce_FileOutputStream.cpp b/source/modules/juce_core/files/juce_FileOutputStream.cpp index c5ef0d5e0..31d013b11 100644 --- a/source/modules/juce_core/files/juce_FileOutputStream.cpp +++ b/source/modules/juce_core/files/juce_FileOutputStream.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/files/juce_FileOutputStream.h b/source/modules/juce_core/files/juce_FileOutputStream.h index 0eee43d6d..75b14bc49 100644 --- a/source/modules/juce_core/files/juce_FileOutputStream.h +++ b/source/modules/juce_core/files/juce_FileOutputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILEOUTPUTSTREAM_H_INCLUDED -#define JUCE_FILEOUTPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -118,5 +109,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileOutputStream) }; - -#endif // JUCE_FILEOUTPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/files/juce_FileSearchPath.cpp b/source/modules/juce_core/files/juce_FileSearchPath.cpp index 2040936ea..8219de13a 100644 --- a/source/modules/juce_core/files/juce_FileSearchPath.cpp +++ b/source/modules/juce_core/files/juce_FileSearchPath.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/files/juce_FileSearchPath.h b/source/modules/juce_core/files/juce_FileSearchPath.h index 3572072c2..94cde68c9 100644 --- a/source/modules/juce_core/files/juce_FileSearchPath.h +++ b/source/modules/juce_core/files/juce_FileSearchPath.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILESEARCHPATH_H_INCLUDED -#define JUCE_FILESEARCHPATH_H_INCLUDED +#pragma once //============================================================================== @@ -166,5 +157,3 @@ private: JUCE_LEAK_DETECTOR (FileSearchPath) }; - -#endif // JUCE_FILESEARCHPATH_H_INCLUDED diff --git a/source/modules/juce_core/files/juce_MemoryMappedFile.h b/source/modules/juce_core/files/juce_MemoryMappedFile.h index 2c1b5a432..cd8a4b3ca 100644 --- a/source/modules/juce_core/files/juce_MemoryMappedFile.h +++ b/source/modules/juce_core/files/juce_MemoryMappedFile.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MEMORYMAPPEDFILE_H_INCLUDED -#define JUCE_MEMORYMAPPEDFILE_H_INCLUDED +#pragma once //============================================================================== @@ -118,6 +109,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryMappedFile) }; - - -#endif // JUCE_MEMORYMAPPEDFILE_H_INCLUDED diff --git a/source/modules/juce_core/files/juce_TemporaryFile.cpp b/source/modules/juce_core/files/juce_TemporaryFile.cpp index 41ea4dcef..a3c17ef63 100644 --- a/source/modules/juce_core/files/juce_TemporaryFile.cpp +++ b/source/modules/juce_core/files/juce_TemporaryFile.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/files/juce_TemporaryFile.h b/source/modules/juce_core/files/juce_TemporaryFile.h index 408b8bfe2..8663f0cde 100644 --- a/source/modules/juce_core/files/juce_TemporaryFile.h +++ b/source/modules/juce_core/files/juce_TemporaryFile.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TEMPORARYFILE_H_INCLUDED -#define JUCE_TEMPORARYFILE_H_INCLUDED +#pragma once //============================================================================== @@ -167,5 +158,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemporaryFile) }; - -#endif // JUCE_TEMPORARYFILE_H_INCLUDED diff --git a/source/modules/juce_core/files/juce_WildcardFileFilter.cpp b/source/modules/juce_core/files/juce_WildcardFileFilter.cpp index f581a58f4..82ffe9645 100644 --- a/source/modules/juce_core/files/juce_WildcardFileFilter.cpp +++ b/source/modules/juce_core/files/juce_WildcardFileFilter.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/files/juce_WildcardFileFilter.h b/source/modules/juce_core/files/juce_WildcardFileFilter.h index b7a145369..5492bdaaa 100644 --- a/source/modules/juce_core/files/juce_WildcardFileFilter.h +++ b/source/modules/juce_core/files/juce_WildcardFileFilter.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_WILDCARDFILEFILTER_H_INCLUDED -#define JUCE_WILDCARDFILEFILTER_H_INCLUDED +#pragma once //============================================================================== @@ -79,6 +70,3 @@ private: JUCE_LEAK_DETECTOR (WildcardFileFilter) }; - - -#endif // JUCE_WILDCARDFILEFILTER_H_INCLUDED diff --git a/source/modules/juce_core/javascript/juce_JSON.cpp b/source/modules/juce_core/javascript/juce_JSON.cpp index 6fa8ec198..fcaace762 100644 --- a/source/modules/juce_core/javascript/juce_JSON.cpp +++ b/source/modules/juce_core/javascript/juce_JSON.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -84,7 +76,7 @@ public: if (digitValue < 0) return createFail ("Syntax error in unicode escape sequence"); - c = (juce_wchar) ((c << 4) + digitValue); + c = (juce_wchar) ((c << 4) + static_cast (digitValue)); } break; @@ -537,7 +529,7 @@ Result JSON::parseQuotedString (String::CharPointerType& t, var& result) class JSONTests : public UnitTest { public: - JSONTests() : UnitTest ("JSON") {} + JSONTests() : UnitTest ("JSON", "JSON") {} static String createRandomWideCharString (Random& r) { @@ -573,24 +565,18 @@ public: return CharPointer_ASCII (buffer); } - // (creates a random double that can be easily stringified, to avoid - // false failures when decimal places are rounded or truncated slightly) + // Creates a random double that can be easily stringified, to avoid + // false failures when decimal places are rounded or truncated slightly static var createRandomDouble (Random& r) { - for (;;) - { - var v (String (r.nextDouble() * 1000.0, 20).getDoubleValue()); - - if (v.toString() == String (static_cast (v), 20)) - return v; - } + return var ((r.nextDouble() * 1000.0) + 0.1); } static var createRandomVar (Random& r, int depth) { switch (r.nextInt (depth > 3 ? 6 : 8)) { - case 0: return var(); + case 0: return {}; case 1: return r.nextInt(); case 2: return r.nextInt64(); case 3: return r.nextBool(); @@ -618,7 +604,7 @@ public: } default: - return var(); + return {}; } } diff --git a/source/modules/juce_core/javascript/juce_JSON.h b/source/modules/juce_core/javascript/juce_JSON.h index 879c90f7d..29affb995 100644 --- a/source/modules/juce_core/javascript/juce_JSON.h +++ b/source/modules/juce_core/javascript/juce_JSON.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_JSON_H_INCLUDED -#define JUCE_JSON_H_INCLUDED +#pragma once //============================================================================== @@ -133,6 +124,3 @@ private: //============================================================================== JSON() JUCE_DELETED_FUNCTION; // This class can't be instantiated - just use its static methods. }; - - -#endif // JUCE_JSON_H_INCLUDED diff --git a/source/modules/juce_core/javascript/juce_Javascript.cpp b/source/modules/juce_core/javascript/juce_Javascript.cpp index 719c2b47c..c04c051bf 100644 --- a/source/modules/juce_core/javascript/juce_Javascript.cpp +++ b/source/modules/juce_core/javascript/juce_Javascript.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -144,41 +136,41 @@ struct JavascriptEngine::RootObject : public DynamicObject var findFunctionCall (const CodeLocation& location, const var& targetObject, const Identifier& functionName) const { - if (DynamicObject* o = targetObject.getDynamicObject()) + if (auto* o = targetObject.getDynamicObject()) { - if (const var* prop = getPropertyPointer (o, functionName)) + if (auto* prop = getPropertyPointer (o, functionName)) return *prop; - for (DynamicObject* p = o->getProperty (getPrototypeIdentifier()).getDynamicObject(); p != nullptr; + for (auto* p = o->getProperty (getPrototypeIdentifier()).getDynamicObject(); p != nullptr; p = p->getProperty (getPrototypeIdentifier()).getDynamicObject()) { - if (const var* prop = getPropertyPointer (p, functionName)) + if (auto* prop = getPropertyPointer (p, functionName)) return *prop; } // if there's a class with an overridden DynamicObject::hasMethod, this avoids an error if (o->hasMethod (functionName)) - return var(); + return {}; } if (targetObject.isString()) - if (var* m = findRootClassProperty (StringClass::getClassName(), functionName)) + if (auto* m = findRootClassProperty (StringClass::getClassName(), functionName)) return *m; if (targetObject.isArray()) - if (var* m = findRootClassProperty (ArrayClass::getClassName(), functionName)) + if (auto* m = findRootClassProperty (ArrayClass::getClassName(), functionName)) return *m; - if (var* m = findRootClassProperty (ObjectClass::getClassName(), functionName)) + if (auto* m = findRootClassProperty (ObjectClass::getClassName(), functionName)) return *m; location.throwError ("Unknown function '" + functionName.toString() + "'"); - return var(); + return {}; } var* findRootClassProperty (const Identifier& className, const Identifier& propName) const { - if (DynamicObject* cls = root->getProperty (className).getDynamicObject()) + if (auto* cls = root->getProperty (className).getDynamicObject()) return getPropertyPointer (cls, propName); return nullptr; @@ -186,7 +178,7 @@ struct JavascriptEngine::RootObject : public DynamicObject var findSymbolInParentScopes (const Identifier& name) const { - if (const var* v = getPropertyPointer (scope, name)) + if (auto* v = getPropertyPointer (scope, name)) return *v; return parent != nullptr ? parent->findSymbolInParentScopes (name) @@ -195,13 +187,13 @@ struct JavascriptEngine::RootObject : public DynamicObject bool findAndInvokeMethod (const Identifier& function, const var::NativeFunctionArgs& args, var& result) const { - DynamicObject* target = args.thisObject.getDynamicObject(); + auto* target = args.thisObject.getDynamicObject(); if (target == nullptr || target == scope) { - if (const var* m = getPropertyPointer (scope, function)) + if (auto* m = getPropertyPointer (scope, function)) { - if (FunctionObject* fo = dynamic_cast (m->getObject())) + if (auto fo = dynamic_cast (m->getObject())) { result = fo->invoke (*this, args); return true; @@ -209,20 +201,39 @@ struct JavascriptEngine::RootObject : public DynamicObject } } - const NamedValueSet& props = scope->getProperties(); + const auto& props = scope->getProperties(); for (int i = 0; i < props.size(); ++i) - if (DynamicObject* o = props.getValueAt (i).getDynamicObject()) + if (auto* o = props.getValueAt (i).getDynamicObject()) if (Scope (this, root, o).findAndInvokeMethod (function, args, result)) return true; return false; } + bool invokeMethod (const var& m, const var::NativeFunctionArgs& args, var& result) const + { + if (isFunction (m)) + { + auto* target = args.thisObject.getDynamicObject(); + + if (target == nullptr || target == scope) + { + if (auto fo = dynamic_cast (m.getObject())) + { + result = fo->invoke (*this, args); + return true; + } + } + } + + return false; + } + void checkTimeOut (const CodeLocation& location) const { if (Time::getCurrentTime() > root->timeout) - location.throwError ("Execution timed-out"); + location.throwError (root->timeout == Time() ? "Interrupted" : "Execution timed-out"); } }; @@ -498,7 +509,7 @@ struct JavascriptEngine::RootObject : public DynamicObject } var throwError (const char* typeName) const - { location.throwError (getTokenName (operation) + " is not allowed on the " + typeName + " type"); return var(); } + { location.throwError (getTokenName (operation) + " is not allowed on the " + typeName + " type"); return {}; } }; struct EqualsOp : public BinaryOperator @@ -578,8 +589,8 @@ struct JavascriptEngine::RootObject : public DynamicObject struct DivideOp : public BinaryOperator { DivideOp (const CodeLocation& l, ExpPtr& a, ExpPtr& b) noexcept : BinaryOperator (l, a, b, TokenTypes::divide) {} - var getWithDoubles (double a, double b) const override { return b != 0 ? a / b : std::numeric_limits::infinity(); } - var getWithInts (int64 a, int64 b) const override { return b != 0 ? var (a / (double) b) : var (std::numeric_limits::infinity()); } + var getWithDoubles (double a, double b) const override { return b != 0.0 ? a / b : std::numeric_limits::infinity(); } + var getWithInts (int64 a, int64 b) const override { return b != 0 ? var (a / (double) b) : var (std::numeric_limits::infinity()); } }; struct ModuloOp : public BinaryOperator @@ -738,7 +749,7 @@ struct JavascriptEngine::RootObject : public DynamicObject if (o->hasMethod (dot->child)) // allow an overridden DynamicObject::invokeMethod to accept a method call. return o->invokeMethod (dot->child, args); - location.throwError ("This expression is not a function!"); return var(); + location.throwError ("This expression is not a function!"); return {}; } ExpPtr object; @@ -1314,10 +1325,12 @@ struct JavascriptEngine::RootObject : public DynamicObject while (currentType != TokenTypes::closeBrace) { - e->names.add (currentValue.toString()); + auto memberName = currentValue.toString(); match ((currentType == TokenTypes::literal && currentValue.isString()) ? TokenTypes::literal : TokenTypes::identifier); match (TokenTypes::colon); + + e->names.add (memberName); e->initialisers.add (parseExpression()); if (currentType != TokenTypes::closeBrace) @@ -1372,7 +1385,7 @@ struct JavascriptEngine::RootObject : public DynamicObject template Expression* parsePreIncDec() { - Expression* e = parseFactor(); // careful - bare pointer is deliberately alised + Expression* e = parseFactor(); // careful - bare pointer is deliberately aliased ExpPtr lhs (e), one (new LiteralValue (location, (int) 1)); return new SelfAssignment (location, e, new OpType (location, lhs, one)); } @@ -1380,7 +1393,7 @@ struct JavascriptEngine::RootObject : public DynamicObject template Expression* parsePostIncDec (ExpPtr& lhs) { - Expression* e = lhs.release(); // careful - bare pointer is deliberately alised + Expression* e = lhs.release(); // careful - bare pointer is deliberately aliased ExpPtr lhs2 (e), one (new LiteralValue (location, (int) 1)); return new PostAssignment (location, e, new OpType (location, lhs2, one)); } @@ -1636,7 +1649,7 @@ struct JavascriptEngine::RootObject : public DynamicObject static Identifier getClassName() { static const Identifier i ("String"); return i; } - static var fromCharCode (Args a) { return String::charToString (getInt (a, 0)); } + static var fromCharCode (Args a) { return String::charToString (static_cast (getInt (a, 0))); } static var substring (Args a) { return a.thisObject.toString().substring (getInt (a, 0), getInt (a, 1)); } static var indexOf (Args a) { return a.thisObject.toString().indexOf (getString (a, 0)); } static var charCodeAt (Args a) { return (int) a.thisObject.toString() [getInt (a, 0)]; } @@ -1794,6 +1807,7 @@ JavascriptEngine::JavascriptEngine() : maximumExecutionTime (15.0), root (new R JavascriptEngine::~JavascriptEngine() {} void JavascriptEngine::prepareTimeout() const noexcept { root->timeout = Time::getCurrentTime() + maximumExecutionTime; } +void JavascriptEngine::stop() noexcept { root->timeout = {}; } void JavascriptEngine::registerNativeObject (const Identifier& name, DynamicObject* object) { @@ -1849,6 +1863,26 @@ var JavascriptEngine::callFunction (const Identifier& function, const var::Nativ return returnVal; } +var JavascriptEngine::callFunctionObject (DynamicObject* objectScope, const var& functionObject, + const var::NativeFunctionArgs& args, Result* result) +{ + var returnVal (var::undefined()); + + try + { + prepareTimeout(); + if (result != nullptr) *result = Result::ok(); + RootObject::Scope rootScope (nullptr, root, root); + RootObject::Scope (&rootScope, root, objectScope).invokeMethod (functionObject, args, returnVal); + } + catch (String& error) + { + if (result != nullptr) *result = Result::fail (error); + } + + return returnVal; +} + const NamedValueSet& JavascriptEngine::getRootObjectProperties() const noexcept { return root->getProperties(); diff --git a/source/modules/juce_core/javascript/juce_Javascript.h b/source/modules/juce_core/javascript/juce_Javascript.h index de605f074..93a55a405 100644 --- a/source/modules/juce_core/javascript/juce_Javascript.h +++ b/source/modules/juce_core/javascript/juce_Javascript.h @@ -2,32 +2,28 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + 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 + + +//============================================================================== /** A simple javascript interpreter! @@ -46,7 +42,7 @@ script creates complex connections between objects, you run the risk of creating cyclic dependencies and hence leaking. */ -class JavascriptEngine +class JUCE_API JavascriptEngine { public: /** Creates an instance of the engine. @@ -84,6 +80,15 @@ public: const var::NativeFunctionArgs& args, Result* errorMessage = nullptr); + /** Calls a function object in the namespace of a dynamic object, and returns the result. + The function arguments are passed in the same format as used by native + methods in the var class. + */ + var callFunctionObject (DynamicObject* objectScope, + const var& functionObject, + const var::NativeFunctionArgs& args, + Result* errorMessage = nullptr); + /** Adds a native object to the root namespace. The object passed-in is reference-counted, and will be retained by the engine until the engine is deleted. The name must be a simple JS identifier, @@ -98,6 +103,9 @@ public: */ RelativeTime maximumExecutionTime; + /** When called from another thread, causes the interpreter to time-out as soon as possible */ + void stop() noexcept; + /** Provides access to the set of properties of the root namespace object. */ const NamedValueSet& getRootObjectProperties() const noexcept; diff --git a/source/modules/juce_core/juce_core.cpp b/source/modules/juce_core/juce_core.cpp index d779f4fc7..7d10dfa25 100644 --- a/source/modules/juce_core/juce_core.cpp +++ b/source/modules/juce_core/juce_core.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -37,8 +29,6 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #define JUCE_CORE_INCLUDE_OBJC_HELPERS 1 #define JUCE_CORE_INCLUDE_COM_SMART_PTR 1 #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 @@ -57,10 +47,6 @@ #if JUCE_WINDOWS #include - #define _WINSOCK_DEPRECATED_NO_WARNINGS 1 - #include - #include - #if ! JUCE_MINGW #pragma warning (push) #pragma warning (disable: 4091) @@ -154,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" @@ -245,6 +232,11 @@ namespace juce #include "network/juce_URL.cpp" #include "network/juce_WebInputStream.cpp" +//============================================================================== +#if JUCE_UNIT_TESTS +#include "containers/juce_HashMap_test.cpp" +#endif + //============================================================================== /* As the very long class names here try to explain, the purpose of this code is to cause diff --git a/source/modules/juce_core/juce_core.h b/source/modules/juce_core/juce_core.h index a6c976d3e..c6aead166 100644 --- a/source/modules/juce_core/juce_core.h +++ b/source/modules/juce_core/juce_core.h @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -40,7 +32,7 @@ ID: juce_core vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE core classes description: The essential set of basic JUCE classes, as required by all the other JUCE modules. Includes text, container, memory, threading and i/o functionality. website: http://www.juce.com/juce @@ -58,7 +50,7 @@ *******************************************************************************/ -#ifndef JUCE_CORE_H_INCLUDED +#pragma once #define JUCE_CORE_H_INCLUDED //============================================================================== @@ -287,7 +279,6 @@ extern JUCE_API void JUCE_CALLTYPE logAssertion (const char* file, int line) noe #include "misc/juce_RuntimePermissions.h" #include "misc/juce_Uuid.h" #include "misc/juce_WindowsRegistry.h" -#include "system/juce_SystemStats.h" #include "threads/juce_ChildProcess.h" #include "threads/juce_DynamicLibrary.h" #include "threads/juce_HighResolutionTimer.h" @@ -308,6 +299,7 @@ extern JUCE_API void JUCE_CALLTYPE logAssertion (const char* file, int line) noe #include "network/juce_Socket.h" #include "network/juce_URL.h" #include "network/juce_WebInputStream.h" +#include "system/juce_SystemStats.h" #include "time/juce_PerformanceCounter.h" #include "unit_tests/juce_UnitTest.h" #include "xml/juce_XmlDocument.h" @@ -361,5 +353,3 @@ extern JUCE_API void JUCE_CALLTYPE logAssertion (const char* file, int line) noe #pragma warning (disable: 4251) #endif #endif - -#endif // JUCE_CORE_H_INCLUDED diff --git a/source/modules/juce_core/logging/juce_FileLogger.cpp b/source/modules/juce_core/logging/juce_FileLogger.cpp index e07de60cf..9a92d383a 100644 --- a/source/modules/juce_core/logging/juce_FileLogger.cpp +++ b/source/modules/juce_core/logging/juce_FileLogger.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/logging/juce_FileLogger.h b/source/modules/juce_core/logging/juce_FileLogger.h index 5102c6743..c9846f81d 100644 --- a/source/modules/juce_core/logging/juce_FileLogger.h +++ b/source/modules/juce_core/logging/juce_FileLogger.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILELOGGER_H_INCLUDED -#define JUCE_FILELOGGER_H_INCLUDED +#pragma once //============================================================================== @@ -136,6 +127,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileLogger) }; - - -#endif // JUCE_FILELOGGER_H_INCLUDED diff --git a/source/modules/juce_core/logging/juce_Logger.cpp b/source/modules/juce_core/logging/juce_Logger.cpp index 7877e5115..b69d69dc6 100644 --- a/source/modules/juce_core/logging/juce_Logger.cpp +++ b/source/modules/juce_core/logging/juce_Logger.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/logging/juce_Logger.h b/source/modules/juce_core/logging/juce_Logger.h index f3b845a6d..45b5949b8 100644 --- a/source/modules/juce_core/logging/juce_Logger.h +++ b/source/modules/juce_core/logging/juce_Logger.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LOGGER_H_INCLUDED -#define JUCE_LOGGER_H_INCLUDED +#pragma once //============================================================================== @@ -94,6 +85,3 @@ protected: private: static Logger* currentLogger; }; - - -#endif // JUCE_LOGGER_H_INCLUDED diff --git a/source/modules/juce_core/maths/juce_BigInteger.cpp b/source/modules/juce_core/maths/juce_BigInteger.cpp index fa973a4be..14a935439 100644 --- a/source/modules/juce_core/maths/juce_BigInteger.cpp +++ b/source/modules/juce_core/maths/juce_BigInteger.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -119,7 +111,6 @@ BigInteger::BigInteger (const BigInteger& other) memcpy (getValues(), other.getValues(), sizeof (uint32) * allocatedSize); } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS BigInteger::BigInteger (BigInteger&& other) noexcept : heapAllocation (static_cast&&> (other.heapAllocation)), allocatedSize (other.allocatedSize), @@ -138,7 +129,6 @@ BigInteger& BigInteger::operator= (BigInteger&& other) noexcept negative = other.negative; return *this; } -#endif BigInteger::~BigInteger() { @@ -1137,7 +1127,7 @@ String BigInteger::toString (const int base, const int minimumNumCharacters) con else { jassertfalse; // can't do the specified base! - return String(); + return {}; } s = s.paddedLeft ('0', minimumNumCharacters); @@ -1301,7 +1291,7 @@ uint32 readLittleEndianBitsInBuffer (const void* buffer, uint32 startBit, uint32 class BigIntegerTests : public UnitTest { public: - BigIntegerTests() : UnitTest ("BigInteger") {} + BigIntegerTests() : UnitTest ("BigInteger", "Maths") {} static BigInteger getBigRandom (Random& r) { diff --git a/source/modules/juce_core/maths/juce_BigInteger.h b/source/modules/juce_core/maths/juce_BigInteger.h index e832377c0..01a0965e3 100644 --- a/source/modules/juce_core/maths/juce_BigInteger.h +++ b/source/modules/juce_core/maths/juce_BigInteger.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BIGINTEGER_H_INCLUDED -#define JUCE_BIGINTEGER_H_INCLUDED +#pragma once //============================================================================== @@ -69,10 +60,11 @@ public: /** Creates a copy of another BigInteger. */ BigInteger (const BigInteger&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ BigInteger (BigInteger&&) noexcept; + + /** Move assignment operator */ BigInteger& operator= (BigInteger&&) noexcept; - #endif /** Destructor. */ ~BigInteger(); @@ -350,6 +342,3 @@ OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& // For backwards compatibility, BitArray is defined as an alias for BigInteger. typedef BigInteger BitArray; #endif - - -#endif // JUCE_BIGINTEGER_H_INCLUDED diff --git a/source/modules/juce_core/maths/juce_Expression.cpp b/source/modules/juce_core/maths/juce_Expression.cpp index 1f190f163..639d85a1d 100644 --- a/source/modules/juce_core/maths/juce_Expression.cpp +++ b/source/modules/juce_core/maths/juce_Expression.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -55,7 +47,7 @@ public: virtual String getName() const { jassertfalse; // You shouldn't call this for an expression that's not actually a function! - return String(); + return {}; } virtual void renameSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope, int recursionDepth) @@ -958,7 +950,6 @@ Expression& Expression::operator= (const Expression& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Expression::Expression (Expression&& other) noexcept : term (static_cast&&> (other.term)) { @@ -969,7 +960,6 @@ Expression& Expression::operator= (Expression&& other) noexcept term = static_cast&&> (other.term); return *this; } -#endif Expression::Expression (const String& stringToParse, String& parseError) { @@ -1175,5 +1165,5 @@ void Expression::Scope::visitRelativeScope (const String& scopeName, Visitor&) c String Expression::Scope::getScopeUID() const { - return String(); + return {}; } diff --git a/source/modules/juce_core/maths/juce_Expression.h b/source/modules/juce_core/maths/juce_Expression.h index a79a3e716..189a4f03d 100644 --- a/source/modules/juce_core/maths/juce_Expression.h +++ b/source/modules/juce_core/maths/juce_Expression.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_EXPRESSION_H_INCLUDED -#define JUCE_EXPRESSION_H_INCLUDED +#pragma once //============================================================================== @@ -63,10 +54,11 @@ public: /** Copies another expression. */ Expression& operator= (const Expression&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ Expression (Expression&&) noexcept; + + /** Move assignment operator */ Expression& operator= (Expression&&) noexcept; - #endif /** Creates a simple expression with a specified constant value. */ explicit Expression (double constant); @@ -257,5 +249,3 @@ private: explicit Expression (Term*); }; - -#endif // JUCE_EXPRESSION_H_INCLUDED diff --git a/source/modules/juce_core/maths/juce_MathsFunctions.h b/source/modules/juce_core/maths/juce_MathsFunctions.h index dd416aeeb..7361ea71f 100644 --- a/source/modules/juce_core/maths/juce_MathsFunctions.h +++ b/source/modules/juce_core/maths/juce_MathsFunctions.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MATHSFUNCTIONS_H_INCLUDED -#define JUCE_MATHSFUNCTIONS_H_INCLUDED +#pragma once //============================================================================== /* @@ -346,15 +337,34 @@ inline int64 abs64 (const int64 n) noexcept #endif //============================================================================== + +/** Commonly used mathematical constants */ +template +struct MathConstants +{ + /** A predefined value for Pi */ + static const FloatType pi; + + /** A predfined value for Euler's number */ + static const FloatType euler; +}; + +template +const FloatType MathConstants::pi = static_cast (3.141592653589793238L); + +template +const FloatType MathConstants::euler = static_cast (2.71828182845904523536L); + + /** A predefined value for Pi, at double-precision. @see float_Pi */ -const double double_Pi = 3.1415926535897932384626433832795; +const double double_Pi = MathConstants::pi; /** A predefined value for Pi, at single-precision. @see double_Pi */ -const float float_Pi = 3.14159265358979323846f; +const float float_Pi = MathConstants::pi; /** Converts an angle in degrees to radians. */ @@ -492,6 +502,22 @@ inline int roundFloatToInt (float value) noexcept return roundToInt (value); } +//============================================================================== +/** Truncates a positive floating-point number to an unsigned int. + + This is generally faster than static_cast (std::floor (x)) + but it only works for positive numbers small enough to be represented as an + unsigned int. +*/ +template +unsigned int truncatePositiveToUnsignedInt (FloatType value) noexcept +{ + jassert (value >= static_cast (0)); + jassert (static_cast (value) <= std::numeric_limits::max()); + + return static_cast (value); +} + //============================================================================== /** Returns true if the specified integer is a power-of-two. */ template @@ -589,18 +615,12 @@ uint32 readLittleEndianBitsInBuffer (const void* sourceBuffer, uint32 startBit, */ namespace TypeHelpers { - #if JUCE_VC8_OR_EARLIER - #define PARAMETER_TYPE(type) const type& - #else /** The ParameterType struct is used to find the best type to use when passing some kind of object as a parameter. Of course, this is only likely to be useful in certain esoteric template situations. - Because "typename TypeHelpers::ParameterType::type" is a bit of a mouthful, there's - a PARAMETER_TYPE(SomeClass) macro that you can use to get the same effect. - - E.g. "myFunction (PARAMETER_TYPE (int), PARAMETER_TYPE (MyObject))" + E.g. "myFunction (typename TypeHelpers::ParameterType::type, typename TypeHelpers::ParameterType::type)" would evaluate to "myfunction (int, const MyObject&)", keeping any primitive types as pass-by-value, but passing objects as a const reference, to avoid copying. */ @@ -624,21 +644,22 @@ namespace TypeHelpers template <> struct ParameterType { typedef double type; }; #endif - /** A helpful macro to simplify the use of the ParameterType template. - @see ParameterType + /** These templates are designed to take a type, and if it's a double, they return a double + type; for anything else, they return a float type. */ - #define PARAMETER_TYPE(a) typename TypeHelpers::ParameterType::type - #endif + template struct SmallestFloatType { typedef float type; }; + template <> struct SmallestFloatType { typedef double type; }; - /** These templates are designed to take a type, and if it's a double, they return a double - type; for anything else, they return a float type. + /** These templates are designed to take an integer type, and return an unsigned int + version with the same size. */ - template struct SmallestFloatType { typedef float type; }; - template <> struct SmallestFloatType { typedef double type; }; + template struct UnsignedTypeWithSize {}; + template <> struct UnsignedTypeWithSize<1> { typedef uint8 type; }; + template <> struct UnsignedTypeWithSize<2> { typedef uint16 type; }; + template <> struct UnsignedTypeWithSize<4> { typedef uint32 type; }; + template <> struct UnsignedTypeWithSize<8> { typedef uint64 type; }; } //============================================================================== - -#endif // JUCE_MATHSFUNCTIONS_H_INCLUDED diff --git a/source/modules/juce_core/maths/juce_NormalisableRange.h b/source/modules/juce_core/maths/juce_NormalisableRange.h index c12b64b76..3f3794e15 100644 --- a/source/modules/juce_core/maths/juce_NormalisableRange.h +++ b/source/modules/juce_core/maths/juce_NormalisableRange.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_NORMALISABLERANGE_H_INCLUDED -#define JUCE_NORMALISABLERANGE_H_INCLUDED +#pragma once //============================================================================== @@ -47,13 +38,19 @@ class NormalisableRange { public: /** Creates a continuous range that performs a dummy mapping. */ - NormalisableRange() noexcept : start(), end (1), interval(), skew (static_cast (1)), symmetricSkew (false) {} + NormalisableRange() noexcept + : start(), end (1), interval(), + skew (static_cast (1)), symmetricSkew (false) + {} /** Creates a copy of another range. */ NormalisableRange (const NormalisableRange& other) noexcept : start (other.start), end (other.end), interval (other.interval), skew (other.skew), - symmetricSkew (other.symmetricSkew) + symmetricSkew (other.symmetricSkew), + convertFrom0To1Function (other.convertFrom0To1Function), + convertTo0To1Function (other.convertTo0To1Function), + snapToLegalValueFunction (other.snapToLegalValueFunction) { checkInvariants(); } @@ -66,7 +63,12 @@ public: interval = other.interval; skew = other.skew; symmetricSkew = other.symmetricSkew; + convertFrom0To1Function = other.convertFrom0To1Function; + convertTo0To1Function = other.convertTo0To1Function; + snapToLegalValueFunction = other.snapToLegalValueFunction; + checkInvariants(); + return *this; } @@ -101,11 +103,42 @@ public: checkInvariants(); } + /** Creates a NormalisableRange with a given range and an injective mapping function. + + @param rangeStart The minimum value in the range. + @param rangeEnd The maximum value in the range. + @param convertFrom0To1Func A function which uses the current start and end of this NormalisableRange + and produces a mapped value from a normalised value. + @param convertTo0To1Func A function which uses the current start and end of this NormalisableRange + and produces a normalised value from a mapped value. + @param snapToLegalValueFunc A function which uses the current start and end of this NormalisableRange + to take a mapped value and snap it to the nearest legal value. + */ + NormalisableRange (ValueType rangeStart, + ValueType rangeEnd, + std::function convertFrom0To1Func, + std::function convertTo0To1Func, + std::function snapToLegalValueFunc = nullptr) noexcept + : start (rangeStart), + end (rangeEnd), + interval(), + skew (static_cast (1)), + symmetricSkew (false), + convertFrom0To1Function (convertFrom0To1Func), + convertTo0To1Function (convertTo0To1Func), + snapToLegalValueFunction (snapToLegalValueFunc) + { + checkInvariants(); + } + /** Uses the properties of this mapping to convert a non-normalised value to its 0->1 representation. */ ValueType convertTo0to1 (ValueType v) const noexcept { + if (convertTo0To1Function != nullptr) + return convertTo0To1Function (start, end, v); + ValueType proportion = (v - start) / (end - start); if (skew == static_cast (1)) @@ -127,12 +160,15 @@ public: */ ValueType convertFrom0to1 (ValueType proportion) const noexcept { + if (convertFrom0To1Function != nullptr) + return convertFrom0To1Function (start, end, proportion); + if (! symmetricSkew) { if (skew != static_cast (1) && proportion > ValueType()) proportion = std::exp (std::log (proportion) / skew); - return start + (end - start) * proportion; + return start + (end - start) * proportion; } ValueType distanceFromMiddle = static_cast (2) * proportion - static_cast (1); @@ -145,10 +181,14 @@ public: return start + (end - start) / static_cast (2) * (static_cast (1) + distanceFromMiddle); } - /** Takes a non-normalised value and snaps it based on the interval property of - this NormalisedRange. */ + /** Takes a non-normalised value and snaps it based on either the interval property of + this NormalisedRange or the lambda function supplied to the constructor. + */ ValueType snapToLegalValue (ValueType v) const noexcept { + if (snapToLegalValueFunction != nullptr) + return snapToLegalValueFunction (start, end, v); + if (interval > ValueType()) v = start + interval * std::floor ((v - start) / interval + static_cast (0.5)); @@ -161,15 +201,40 @@ public: return v; } + /** Returns the extent of the normalisable range. */ Range getRange() const noexcept { return Range (start, end); } - /** The start of the non-normalised range. */ + /** Given a value which is between the start and end points, this sets the skew + such that convertFrom0to1 (0.5) will return this value. + + If you have used lambda functions for convertFrom0to1Func and convertFrom0to1Func in the + constructor of this class then the skew value is ignored. + + @param centrePointValue this must be greater than the start of the range and less than the end. + */ + void setSkewForCentre (ValueType centrePointValue) noexcept + { + jassert (centrePointValue > start); + jassert (centrePointValue < end); + + symmetricSkew = false; + skew = std::log (static_cast (0.5)) + / std::log ((centrePointValue - start) / (end - start)); + checkInvariants(); + } + + /** The minimum value of the non-normalised range. */ ValueType start; - /** The end of the non-normalised range. */ + /** The maximum value of the non-normalised range. */ ValueType end; - /** The snapping interval that should be used (in non-normalised value). Use 0 for a continuous range. */ + /** The snapping interval that should be used (for a non-normalised value). Use 0 for a + continuous range. + + If you have used a lambda function for snapToLegalValueFunction in the constructor of + this class then the interval is ignored. + */ ValueType interval; /** An optional skew factor that alters the way values are distribute across the range. @@ -180,6 +245,9 @@ public: A factor of 1.0 has no skewing effect at all. If the factor is < 1.0, the lower end of the range will fill more of the slider's length; if the factor is > 1.0, the upper end of the range will be expanded. + + If you have used lambda functions for convertFrom0to1Func and convertFrom0to1Func in the + constructor of this class then the skew value is ignored. */ ValueType skew; @@ -193,7 +261,8 @@ private: jassert (interval >= ValueType()); jassert (skew > ValueType()); } -}; - -#endif // JUCE_NORMALISABLERANGE_H_INCLUDED + std::function convertFrom0To1Function = nullptr, + convertTo0To1Function = nullptr, + snapToLegalValueFunction = nullptr; +}; diff --git a/source/modules/juce_core/maths/juce_Random.cpp b/source/modules/juce_core/maths/juce_Random.cpp index ccca0b571..5d83f718a 100644 --- a/source/modules/juce_core/maths/juce_Random.cpp +++ b/source/modules/juce_core/maths/juce_Random.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -162,7 +154,7 @@ void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numB class RandomTests : public UnitTest { public: - RandomTests() : UnitTest ("Random") {} + RandomTests() : UnitTest ("Random", "Maths") {} void runTest() override { diff --git a/source/modules/juce_core/maths/juce_Random.h b/source/modules/juce_core/maths/juce_Random.h index 9aed3fcd0..fa97413f3 100644 --- a/source/modules/juce_core/maths/juce_Random.h +++ b/source/modules/juce_core/maths/juce_Random.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RANDOM_H_INCLUDED -#define JUCE_RANDOM_H_INCLUDED +#pragma once //============================================================================== @@ -140,6 +131,3 @@ private: JUCE_LEAK_DETECTOR (Random) }; - - -#endif // JUCE_RANDOM_H_INCLUDED diff --git a/source/modules/juce_core/maths/juce_Range.h b/source/modules/juce_core/maths/juce_Range.h index 619240ff2..bdb388530 100644 --- a/source/modules/juce_core/maths/juce_Range.h +++ b/source/modules/juce_core/maths/juce_Range.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RANGE_H_INCLUDED -#define JUCE_RANGE_H_INCLUDED +#pragma once //============================================================================== @@ -310,6 +301,3 @@ private: //============================================================================== ValueType start, end; }; - - -#endif // JUCE_RANGE_H_INCLUDED diff --git a/source/modules/juce_core/maths/juce_StatisticsAccumulator.h b/source/modules/juce_core/maths/juce_StatisticsAccumulator.h index e90a6aa6b..31be08e4d 100644 --- a/source/modules/juce_core/maths/juce_StatisticsAccumulator.h +++ b/source/modules/juce_core/maths/juce_StatisticsAccumulator.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STATISTICSACCUMULATOR_H_INCLUDED -#define JUCE_STATISTICSACCUMULATOR_H_INCLUDED +#pragma once //============================================================================== @@ -142,6 +133,3 @@ private: KahanSum sum, sumSquares; FloatType minimum, maximum; }; - - -#endif // JUCE_STATISTICSACCUMULATOR_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_Atomic.h b/source/modules/juce_core/memory/juce_Atomic.h index 5a51f6cf4..65408b4c0 100644 --- a/source/modules/juce_core/memory/juce_Atomic.h +++ b/source/modules/juce_core/memory/juce_Atomic.h @@ -2,439 +2,473 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ATOMIC_H_INCLUDED -#define JUCE_ATOMIC_H_INCLUDED - - -//============================================================================== -/** - Simple class to hold a primitive value and perform atomic operations on it. - - The type used must be a 32 or 64 bit primitive, like an int, pointer, etc. - There are methods to perform most of the basic atomic operations. -*/ -template -class Atomic -{ -public: - /** Creates a new value, initialised to zero. */ - inline Atomic() noexcept - : value (0) - { - } - - /** Creates a new value, with a given initial value. */ - inline explicit Atomic (const Type initialValue) noexcept - : value (initialValue) - { - } - - /** Copies another value (atomically). */ - inline Atomic (const Atomic& other) noexcept - : value (other.get()) - { - } - - /** Destructor. */ - inline ~Atomic() noexcept - { - // This class can only be used for types which are 32 or 64 bits in size. - static_jassert (sizeof (Type) == 4 || sizeof (Type) == 8); - } - - /** Atomically reads and returns the current value. */ - Type get() const noexcept; - - /** Copies another value onto this one (atomically). */ - inline Atomic& operator= (const Atomic& other) noexcept { exchange (other.get()); return *this; } - - /** Copies another value onto this one (atomically). */ - inline Atomic& operator= (const Type newValue) noexcept { exchange (newValue); return *this; } - - /** Atomically sets the current value. */ - void set (Type newValue) noexcept { exchange (newValue); } - - /** Atomically sets the current value, returning the value that was replaced. */ - Type exchange (Type value) noexcept; - - /** Atomically adds a number to this value, returning the new value. */ - Type operator+= (Type amountToAdd) noexcept; - - /** Atomically subtracts a number from this value, returning the new value. */ - Type operator-= (Type amountToSubtract) noexcept; - - /** Atomically increments this value, returning the new value. */ - Type operator++() noexcept; - - /** Atomically decrements this value, returning the new value. */ - Type operator--() noexcept; - - /** Atomically compares this value with a target value, and if it is equal, sets - this to be equal to a new value. - - This operation is the atomic equivalent of doing this: - @code - bool compareAndSetBool (Type newValue, Type valueToCompare) - { - if (get() == valueToCompare) - { - set (newValue); - return true; - } - - return false; - } - @endcode - - @returns true if the comparison was true and the value was replaced; false if - the comparison failed and the value was left unchanged. - @see compareAndSetValue - */ - bool compareAndSetBool (Type newValue, Type valueToCompare) noexcept; - - /** Atomically compares this value with a target value, and if it is equal, sets - this to be equal to a new value. - - This operation is the atomic equivalent of doing this: - @code - Type compareAndSetValue (Type newValue, Type valueToCompare) - { - Type oldValue = get(); - if (oldValue == valueToCompare) - set (newValue); - - return oldValue; - } - @endcode - - @returns the old value before it was changed. - @see compareAndSetBool - */ - Type compareAndSetValue (Type newValue, Type valueToCompare) noexcept; - - /** Implements a memory read/write barrier. */ - static void memoryBarrier() noexcept; - - //============================================================================== - #if JUCE_64BIT - JUCE_ALIGN (8) - #else - JUCE_ALIGN (4) - #endif - - /** The raw value that this class operates on. - This is exposed publicly in case you need to manipulate it directly - for performance reasons. - */ - volatile Type value; - -private: - template - static inline Dest castTo (Source value) noexcept { union { Dest d; Source s; } u; u.s = value; return u.d; } - - static inline Type castFrom32Bit (int32 value) noexcept { return castTo (value); } - static inline Type castFrom64Bit (int64 value) noexcept { return castTo (value); } - static inline int32 castTo32Bit (Type value) noexcept { return castTo (value); } - static inline int64 castTo64Bit (Type value) noexcept { return castTo (value); } - - Type operator++ (int); // better to just use pre-increment with atomics.. - Type operator-- (int); - - /** This templated negate function will negate pointers as well as integers */ - template - inline ValueType negateValue (ValueType n) noexcept - { - return sizeof (ValueType) == 1 ? (ValueType) -(signed char) n - : (sizeof (ValueType) == 2 ? (ValueType) -(short) n - : (sizeof (ValueType) == 4 ? (ValueType) -(int) n - : ((ValueType) -(int64) n))); - } - - /** This templated negate function will negate pointers as well as integers */ - template - inline PointerType* negateValue (PointerType* n) noexcept - { - return reinterpret_cast (-reinterpret_cast (n)); - } -}; - - -//============================================================================== -/* - The following code is in the header so that the atomics can be inlined where possible... -*/ -#if JUCE_MAC && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)) - #define JUCE_ATOMICS_MAC_LEGACY 1 // Older OSX builds using gcc4.1 or earlier +#pragma once -//============================================================================== -#elif JUCE_GCC || JUCE_CLANG - #define JUCE_ATOMICS_GCC 1 // GCC with intrinsics - - #if JUCE_IOS || JUCE_ANDROID // (64-bit ops will compile but not link on these mobile OSes) - #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 - #endif - -//============================================================================== -#else - #define JUCE_ATOMICS_WINDOWS 1 // Windows with intrinsics +#ifndef DOXYGEN + namespace AtomicHelpers + { + template struct DiffTypeHelper { typedef T Type; }; + template struct DiffTypeHelper { typedef std::ptrdiff_t Type; }; + } +#endif - #ifndef __INTEL_COMPILER - #pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \ - _InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier) - #endif - #define juce_InterlockedExchange(a, b) _InterlockedExchange(a, b) - #define juce_InterlockedIncrement(a) _InterlockedIncrement(a) - #define juce_InterlockedDecrement(a) _InterlockedDecrement(a) - #define juce_InterlockedExchangeAdd(a, b) _InterlockedExchangeAdd(a, b) - #define juce_InterlockedCompareExchange(a, b, c) _InterlockedCompareExchange(a, b, c) - #define juce_InterlockedCompareExchange64(a, b, c) _InterlockedCompareExchange64(a, b, c) - #define juce_MemoryBarrier _ReadWriteBarrier - - #if JUCE_64BIT - #ifndef __INTEL_COMPILER - #pragma intrinsic (_InterlockedExchangeAdd64, _InterlockedExchange64, _InterlockedIncrement64, _InterlockedDecrement64) +#if JUCE_ATOMIC_AVAILABLE + //============================================================================== + /** + A simple wrapper around std::atomic. + */ + template + struct Atomic + { + typedef typename AtomicHelpers::DiffTypeHelper::Type DiffType; + + /** Creates a new value, initialised to zero. */ + Atomic() noexcept : value (0) {} + + /** Creates a new value, with a given initial value. */ + Atomic (const Type initialValue) noexcept : value (initialValue) {} + + /** Copies another value (atomically). */ + Atomic (const Atomic& other) noexcept : value (other.get()) {} + + /** Destructor. */ + ~Atomic() noexcept + { + #if __cpp_lib_atomic_is_always_lock_free + static_assert (std::atomic::is_always_lock_free(), + "This class can only be used for lock-free types"); + #endif + } + + /** Atomically reads and returns the current value. */ + Type get() const noexcept { return value.load(); } + + /** Atomically sets the current value. */ + void set (Type newValue) noexcept { value = newValue; } + + /** Atomically sets the current value, returning the value that was replaced. */ + Type exchange (Type newValue) noexcept { return value.exchange (newValue); } + + /** Atomically compares this value with a target value, and if it is equal, sets + this to be equal to a new value. + + This operation is the atomic equivalent of doing this: + @code + bool compareAndSetBool (Type newValue, Type valueToCompare) + { + if (get() == valueToCompare) + { + set (newValue); + return true; + } + + return false; + } + @endcode + + Internally, this method calls std::atomic::compare_exchange_strong with + memory_order_seq_cst (the strictest std::memory_order). + + @returns true if the comparison was true and the value was replaced; false if + the comparison failed and the value was left unchanged. + @see compareAndSetValue + */ + bool compareAndSetBool (Type newValue, Type valueToCompare) noexcept + { + return value.compare_exchange_strong (valueToCompare, newValue); + } + + /** Copies another value into this one (atomically). */ + Atomic& operator= (const Atomic& other) noexcept + { + value = other.value.load(); + return *this; + } + + /** Copies another value into this one (atomically). */ + Atomic& operator= (const Type newValue) noexcept + { + value = newValue; + return *this; + } + + /** Atomically adds a number to this value, returning the new value. */ + Type operator+= (DiffType amountToAdd) noexcept { return value += amountToAdd; } + + /** Atomically subtracts a number from this value, returning the new value. */ + Type operator-= (DiffType amountToSubtract) noexcept { return value -= amountToSubtract; } + + /** Atomically increments this value, returning the new value. */ + Type operator++() noexcept { return ++value; } + + /** Atomically decrements this value, returning the new value. */ + Type operator--() noexcept { return --value; } + + /** Implements a memory read/write barrier. + + Internally this calls std::atomic_thread_fence with + memory_order_seq_cst (the strictest std::memory_order). + */ + void memoryBarrier() noexcept { atomic_thread_fence (std::memory_order_seq_cst); } + + /** The std::atomic object that this class operates on. */ + std::atomic value; + + //============================================================================== + #ifndef DOXYGEN + // This method has been deprecated as there is no equivalent method in std::atomic. + JUCE_DEPRECATED (Type compareAndSetValue (Type, Type) noexcept); #endif - #define juce_InterlockedExchangeAdd64(a, b) _InterlockedExchangeAdd64(a, b) - #define juce_InterlockedExchange64(a, b) _InterlockedExchange64(a, b) - #define juce_InterlockedIncrement64(a) _InterlockedIncrement64(a) - #define juce_InterlockedDecrement64(a) _InterlockedDecrement64(a) - #else - // None of these atomics are available in a 32-bit Windows build!! - template static Type juce_InterlockedExchangeAdd64 (volatile Type* a, Type b) noexcept { jassertfalse; Type old = *a; *a += b; return old; } - template static Type juce_InterlockedExchange64 (volatile Type* a, Type b) noexcept { jassertfalse; Type old = *a; *a = b; return old; } - template static Type juce_InterlockedIncrement64 (volatile Type* a) noexcept { jassertfalse; return ++*a; } - template static Type juce_InterlockedDecrement64 (volatile Type* a) noexcept { jassertfalse; return --*a; } - #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 - #endif + }; - template - struct WindowsInterlockedHelpersBase - {}; +#else + #ifndef DOXYGEN + template class AtomicBase; + #endif + + //============================================================================== + /** + Simple class to hold a primitive value and perform atomic operations on it. + + The type used must be a 32 or 64 bit primitive, like an int, pointer, etc. + There are methods to perform most of the basic atomic operations. + */ + template + class Atomic : public AtomicBase + { + public: + /** Resulting type when subtracting the underlying Type. */ + typedef typename AtomicBase::DiffType DiffType; + + /** Creates a new value, initialised to zero. */ + inline Atomic() noexcept {} + + /** Creates a new value, with a given initial value. */ + inline explicit Atomic (const Type initialValue) noexcept : AtomicBase (initialValue) {} + + /** Copies another value (atomically). */ + inline Atomic (const Atomic& other) noexcept : AtomicBase (other) {} + + /** Destructor. */ + inline ~Atomic() noexcept + { + static_assert (sizeof (Type) == 4 || sizeof (Type) == 8, + "Atomic can only be used for types which are 32 or 64 bits in size"); + } + + /** Atomically reads and returns the current value. */ + inline Type get() const noexcept { return AtomicBase::get(); } + + /** Copies another value into this one (atomically). */ + inline Atomic& operator= (const Atomic& other) noexcept { AtomicBase::operator= (other); return *this; } + + /** Copies another value into this one (atomically). */ + inline Atomic& operator= (const Type newValue) noexcept { AtomicBase::operator= (newValue); return *this; } + + /** Atomically sets the current value. */ + inline void set (Type newValue) noexcept { exchange (newValue); } + + /** Atomically sets the current value, returning the value that was replaced. */ + inline Type exchange (Type v) noexcept { return AtomicBase::exchange (v); } + + /** Atomically adds a number to this value, returning the new value. */ + Type operator+= (DiffType amountToAdd) noexcept; + + /** Atomically subtracts a number from this value, returning the new value. */ + Type operator-= (DiffType amountToSubtract) noexcept; + + /** Atomically increments this value, returning the new value. */ + Type operator++() noexcept; + + /** Atomically decrements this value, returning the new value. */ + Type operator--() noexcept; + + /** Atomically compares this value with a target value, and if it is equal, sets + this to be equal to a new value. + + This operation is the atomic equivalent of doing this: + @code + bool compareAndSetBool (Type newValue, Type valueToCompare) + { + if (get() == valueToCompare) + { + set (newValue); + return true; + } + + return false; + } + @endcode + + @returns true if the comparison was true and the value was replaced; false if + the comparison failed and the value was left unchanged. + @see compareAndSetValue + */ + inline bool compareAndSetBool (Type newValue, Type valueToCompare) noexcept { return AtomicBase::compareAndSetBool (newValue, valueToCompare); } + + /** Atomically compares this value with a target value, and if it is equal, sets + this to be equal to a new value. + + This operation is the atomic equivalent of doing this: + @code + Type compareAndSetValue (Type newValue, Type valueToCompare) + { + Type oldValue = get(); + if (oldValue == valueToCompare) + set (newValue); + + return oldValue; + } + @endcode + + @returns the old value before it was changed. + @see compareAndSetBool + */ + inline Type compareAndSetValue (Type newValue, Type valueToCompare) noexcept { return AtomicBase::compareAndSetValue (newValue, valueToCompare); } + + /** Implements a memory read/write barrier. */ + static inline void memoryBarrier() noexcept { AtomicBase::memoryBarrier (); } + }; + + #ifndef DOXYGEN + + //============================================================================== + // Internal implementation follows + //============================================================================== template - struct WindowsInterlockedHelpersBase + class AtomicBase { - static inline Type exchange (volatile Type* value, Type other) noexcept + public: + typedef typename AtomicHelpers::DiffTypeHelper::Type DiffType; + + inline AtomicBase() noexcept : value (0) {} + inline explicit AtomicBase (const Type v) noexcept : value (v) {} + inline AtomicBase (const AtomicBase& other) noexcept : value (other.get()) {} + Type get() const noexcept; + inline AtomicBase& operator= (const AtomicBase& other) noexcept { exchange (other.get()); return *this; } + inline AtomicBase& operator= (const Type newValue) noexcept { exchange (newValue); return *this; } + void set (Type newValue) noexcept { exchange (newValue); } + Type exchange (Type) noexcept; + bool compareAndSetBool (Type, Type) noexcept; + Type compareAndSetValue (Type, Type) noexcept; + static void memoryBarrier() noexcept; + + //============================================================================== + #if JUCE_64BIT + JUCE_ALIGN (8) + #else + JUCE_ALIGN (4) + #endif + + /** The raw value that this class operates on. + This is exposed publicly in case you need to manipulate it directly + for performance reasons. + */ + volatile Type value; + + protected: + template + static inline Dest castTo (Source value) noexcept { union { Dest d; Source s; } u; u.s = value; return u.d; } + + static inline Type castFrom32Bit (int32 value) noexcept { return castTo (value); } + static inline Type castFrom64Bit (int64 value) noexcept { return castTo (value); } + static inline int32 castTo32Bit (Type value) noexcept { return castTo (value); } + static inline int64 castTo64Bit (Type value) noexcept { return castTo (value); } + + Type operator++ (int); // better to just use pre-increment with atomics.. + Type operator-- (int); + + /** This templated negate function will negate pointers as well as integers */ + template + inline ValueType negateValue (ValueType n) noexcept { - return castFrom (juce_InterlockedExchange (reinterpret_cast (value), castTo (other))); + return sizeof (ValueType) == 1 ? (ValueType) -(signed char) n + : (sizeof (ValueType) == 2 ? (ValueType) -(short) n + : (sizeof (ValueType) == 4 ? (ValueType) -(int) n + : ((ValueType) -(int64) n))); } - static inline Type add (volatile Type* value, Type other) noexcept + /** This templated negate function will negate pointers as well as integers */ + template + inline PointerType* negateValue (PointerType* n) noexcept { - return castFrom (juce_InterlockedExchangeAdd (reinterpret_cast (value), castTo (other)) + castTo (other)); + return reinterpret_cast (-reinterpret_cast (n)); } + }; - static inline Type inc (volatile Type* value) noexcept - { - return castFrom (juce_InterlockedIncrement (reinterpret_cast (value))); - } + //============================================================================== + // Specialisation for void* which does not include the pointer arithmetic + template <> + class Atomic : public AtomicBase + { + public: + inline Atomic() noexcept {} + inline explicit Atomic (void* const initialValue) noexcept : AtomicBase (initialValue) {} + inline Atomic (const Atomic& other) noexcept : AtomicBase (other) {} + inline void* get() const noexcept { return AtomicBase::get(); } + inline Atomic& operator= (const Atomic& other) noexcept { AtomicBase::operator= (other); return *this; } + inline Atomic& operator= (void* const newValue) noexcept { AtomicBase::operator= (newValue); return *this; } + inline void set (void* newValue) noexcept { exchange (newValue); } + inline void* exchange (void* v) noexcept { return AtomicBase::exchange (v); } + inline bool compareAndSetBool (void* newValue, void* valueToCompare) noexcept { return AtomicBase::compareAndSetBool (newValue, valueToCompare); } + inline void* compareAndSetValue (void* newValue, void* valueToCompare) noexcept { return AtomicBase::compareAndSetValue (newValue, valueToCompare); } + static inline void memoryBarrier() noexcept { AtomicBase::memoryBarrier(); } + }; + + //============================================================================== + /* + The following code is in the header so that the atomics can be inlined where possible... + */ + #if JUCE_MAC && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)) + #define JUCE_ATOMICS_MAC_LEGACY 1 // Older OSX builds using gcc4.1 or earlier + #elif JUCE_GCC || JUCE_CLANG + #define JUCE_ATOMICS_GCC 1 // GCC with intrinsics + #if JUCE_IOS || JUCE_ANDROID // (64-bit ops will compile but not link on these mobile OSes) + #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1 + #endif + #endif - static inline Type dec (volatile Type* value) noexcept + template + struct AtomicIncrementDecrement + { + static inline Type inc (AtomicBase& a) noexcept { - return castFrom (juce_InterlockedDecrement (reinterpret_cast (value))); + #if JUCE_ATOMICS_MAC_LEGACY + return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32Barrier ((volatile int32_t*) &a.value) + : (Type) OSAtomicIncrement64Barrier ((volatile int64_t*) &a.value); + #elif JUCE_ATOMICS_GCC + return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (& (a.value), (Type) 1) + : (Type) __sync_add_and_fetch ((int64_t*) & (a.value), 1); + #endif } - static inline Type cmp (volatile Type* value, Type other, Type comparand) noexcept + static inline Type dec (AtomicBase& a) noexcept { - return castFrom (juce_InterlockedCompareExchange (reinterpret_cast (value), castTo (other), castTo (comparand))); + #if JUCE_ATOMICS_MAC_LEGACY + return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32Barrier ((volatile int32_t*) &a.value) + : (Type) OSAtomicDecrement64Barrier ((volatile int64_t*) &a.value); + #elif JUCE_ATOMICS_GCC + return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (& (a.value), (Type) -1) + : (Type) __sync_add_and_fetch ((int64_t*) & (a.value), -1); + #endif } + }; - static inline Type castFrom (long value) { union { long in; Type out; } u; u.in = value; return u.out; } - static inline long castTo (Type value) { union { Type in; long out; } u; u.in = value; return u.out; } + template + struct AtomicIncrementDecrement + { + static inline Type* inc (Atomic& a) noexcept { return a.operator+= (1); } + static inline Type* dec (Atomic& a) noexcept { return a.operator-= (1); } }; + //============================================================================== template - struct WindowsInterlockedHelpersBase + inline Type AtomicBase::get() const noexcept { - static inline Type exchange (volatile Type* value, Type other) noexcept - { - return castFrom (juce_InterlockedExchange64 (reinterpret_cast (value), castTo (other))); - } + #if JUCE_ATOMICS_MAC_LEGACY + return sizeof (Type) == 4 ? castFrom32Bit ((int32) OSAtomicAdd32Barrier ((int32_t) 0, (volatile int32_t*) &value)) + : castFrom64Bit ((int64) OSAtomicAdd64Barrier ((int64_t) 0, (volatile int64_t*) &value)); + #elif JUCE_ATOMICS_GCC + return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_add_and_fetch ((volatile int32*) &value, 0)) + : castFrom64Bit ((int64) __sync_add_and_fetch ((volatile int64*) &value, 0)); + #endif + } - static inline Type add (volatile Type* value, Type other) noexcept - { - return castFrom (juce_InterlockedExchangeAdd64 (reinterpret_cast (value), castTo (other)) + castTo (other)); - } + template + inline Type AtomicBase::exchange (const Type newValue) noexcept + { + #if JUCE_ATOMICS_MAC_LEGACY || JUCE_ATOMICS_GCC + Type currentVal = value; + while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; } + return currentVal; + #endif + } - static inline Type inc (volatile Type* value) noexcept - { - return castFrom (juce_InterlockedIncrement64 (reinterpret_cast (value))); - } + template + inline Type Atomic::operator+= (const DiffType amountToAdd) noexcept + { + Type amount = (Type() + amountToAdd); - static inline Type dec (volatile Type* value) noexcept - { - return castFrom (juce_InterlockedDecrement64 (reinterpret_cast (value))); - } + #if JUCE_ATOMICS_MAC_LEGACY + return sizeof (Type) == 4 ? (Type) OSAtomicAdd32Barrier ((int32_t) castTo32Bit (amount), (volatile int32_t*) &AtomicBase::value) + : (Type) OSAtomicAdd64Barrier ((int64_t) amount, (volatile int64_t*) &AtomicBase::value); + #elif JUCE_ATOMICS_GCC + return (Type) __sync_add_and_fetch (& (AtomicBase::value), amount); + #endif + } - static inline Type cmp (volatile Type* value, Type other, Type comparand) noexcept - { - return castFrom (juce_InterlockedCompareExchange64 (reinterpret_cast (value), castTo (other), castTo (comparand))); - } + template + inline Type Atomic::operator-= (const DiffType amountToSubtract) noexcept + { + return operator+= (AtomicBase::negateValue (amountToSubtract)); + } - static inline Type castFrom (__int64 value) { union { __int64 in; Type out; } u; u.in = value; return u.out; } - static inline __int64 castTo (Type value) { union { Type in; __int64 out; } u; u.in = value; return u.out; } - }; + template + inline Type Atomic::operator++() noexcept { return AtomicIncrementDecrement::inc (*this); } template - struct WindowsInterlockedHelpers : WindowsInterlockedHelpersBase {}; -#endif + inline Type Atomic::operator--() noexcept { return AtomicIncrementDecrement::dec (*this); } + template + inline bool AtomicBase::compareAndSetBool (const Type newValue, const Type valueToCompare) noexcept + { + #if JUCE_ATOMICS_MAC_LEGACY + return sizeof (Type) == 4 ? OSAtomicCompareAndSwap32Barrier ((int32_t) castTo32Bit (valueToCompare), (int32_t) castTo32Bit (newValue), (volatile int32_t*) &value) + : OSAtomicCompareAndSwap64Barrier ((int64_t) castTo64Bit (valueToCompare), (int64_t) castTo64Bit (newValue), (volatile int64_t*) &value); + #elif JUCE_ATOMICS_GCC + return sizeof (Type) == 4 ? __sync_bool_compare_and_swap ((volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue)) + : __sync_bool_compare_and_swap ((volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue)); + #endif + } -#if JUCE_MSVC - #pragma warning (push) - #pragma warning (disable: 4311) // (truncation warning) -#endif + template + inline Type AtomicBase::compareAndSetValue (const Type newValue, const Type valueToCompare) noexcept + { + #if JUCE_ATOMICS_MAC_LEGACY + for (;;) // Annoying workaround for only having a bool CAS operation.. + { + if (compareAndSetBool (newValue, valueToCompare)) + return valueToCompare; -//============================================================================== -template -inline Type Atomic::get() const noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? castFrom32Bit ((int32) OSAtomicAdd32Barrier ((int32_t) 0, (volatile int32_t*) &value)) - : castFrom64Bit ((int64) OSAtomicAdd64Barrier ((int64_t) 0, (volatile int64_t*) &value)); - #elif JUCE_ATOMICS_WINDOWS - return WindowsInterlockedHelpers::add (const_cast (&value), (Type) 0); - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_add_and_fetch ((volatile int32*) &value, 0)) - : castFrom64Bit ((int64) __sync_add_and_fetch ((volatile int64*) &value, 0)); - #endif -} - -template -inline Type Atomic::exchange (const Type newValue) noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY || JUCE_ATOMICS_GCC - Type currentVal = value; - while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; } - return currentVal; - #elif JUCE_ATOMICS_WINDOWS - return WindowsInterlockedHelpers::exchange (&value, newValue); - #endif -} - -template -inline Type Atomic::operator+= (const Type amountToAdd) noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? (Type) OSAtomicAdd32Barrier ((int32_t) castTo32Bit (amountToAdd), (volatile int32_t*) &value) - : (Type) OSAtomicAdd64Barrier ((int64_t) amountToAdd, (volatile int64_t*) &value); - #elif JUCE_ATOMICS_WINDOWS - return WindowsInterlockedHelpers::add (&value, amountToAdd); - #elif JUCE_ATOMICS_GCC - return (Type) __sync_add_and_fetch (&value, amountToAdd); - #endif -} - -template -inline Type Atomic::operator-= (const Type amountToSubtract) noexcept -{ - return operator+= (negateValue (amountToSubtract)); -} - -template -inline Type Atomic::operator++() noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32Barrier ((volatile int32_t*) &value) - : (Type) OSAtomicIncrement64Barrier ((volatile int64_t*) &value); - #elif JUCE_ATOMICS_WINDOWS - return WindowsInterlockedHelpers::inc (&value); - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) 1) - : (Type) __sync_add_and_fetch ((int64_t*) &value, 1); - #endif -} - -template -inline Type Atomic::operator--() noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32Barrier ((volatile int32_t*) &value) - : (Type) OSAtomicDecrement64Barrier ((volatile int64_t*) &value); - #elif JUCE_ATOMICS_WINDOWS - return WindowsInterlockedHelpers::dec (&value); - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) -1) - : (Type) __sync_add_and_fetch ((int64_t*) &value, -1); - #endif -} - -template -inline bool Atomic::compareAndSetBool (const Type newValue, const Type valueToCompare) noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - return sizeof (Type) == 4 ? OSAtomicCompareAndSwap32Barrier ((int32_t) castTo32Bit (valueToCompare), (int32_t) castTo32Bit (newValue), (volatile int32_t*) &value) - : OSAtomicCompareAndSwap64Barrier ((int64_t) castTo64Bit (valueToCompare), (int64_t) castTo64Bit (newValue), (volatile int64_t*) &value); - #elif JUCE_ATOMICS_WINDOWS - return compareAndSetValue (newValue, valueToCompare) == valueToCompare; - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? __sync_bool_compare_and_swap ((volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue)) - : __sync_bool_compare_and_swap ((volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue)); - #endif -} - -template -inline Type Atomic::compareAndSetValue (const Type newValue, const Type valueToCompare) noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - for (;;) // Annoying workaround for only having a bool CAS operation.. - { - if (compareAndSetBool (newValue, valueToCompare)) - return valueToCompare; - - const Type result = value; - if (result != valueToCompare) - return result; - } - - #elif JUCE_ATOMICS_WINDOWS - return WindowsInterlockedHelpers::cmp (&value, newValue, valueToCompare); - #elif JUCE_ATOMICS_GCC - return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_val_compare_and_swap ((volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue))) - : castFrom64Bit ((int64) __sync_val_compare_and_swap ((volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue))); - #endif -} - -template -inline void Atomic::memoryBarrier() noexcept -{ - #if JUCE_ATOMICS_MAC_LEGACY - OSMemoryBarrier(); - #elif JUCE_ATOMICS_GCC - __sync_synchronize(); - #elif JUCE_ATOMICS_WINDOWS - juce_MemoryBarrier(); - #endif -} + const Type result = value; + if (result != valueToCompare) + return result; + } + #elif JUCE_ATOMICS_GCC + return sizeof (Type) == 4 ? castFrom32Bit ((int32) __sync_val_compare_and_swap ((volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue))) + : castFrom64Bit ((int64) __sync_val_compare_and_swap ((volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue))); + #endif + } -#if JUCE_MSVC - #pragma warning (pop) -#endif + template + inline void AtomicBase::memoryBarrier() noexcept + { + #if JUCE_ATOMICS_MAC_LEGACY + OSMemoryBarrier(); + #elif JUCE_ATOMICS_GCC + __sync_synchronize(); + #endif + } -#endif // JUCE_ATOMIC_H_INCLUDED + #endif + +#endif diff --git a/source/modules/juce_core/memory/juce_ByteOrder.h b/source/modules/juce_core/memory/juce_ByteOrder.h index 0440ad2f5..ac08b066e 100644 --- a/source/modules/juce_core/memory/juce_ByteOrder.h +++ b/source/modules/juce_core/memory/juce_ByteOrder.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BYTEORDER_H_INCLUDED -#define JUCE_BYTEORDER_H_INCLUDED +#pragma once //============================================================================== @@ -236,6 +227,3 @@ inline int ByteOrder::littleEndian24Bit (const void* const bytes) noexcept inline int ByteOrder::bigEndian24Bit (const void* const bytes) noexcept { return (((int) static_cast (bytes)[0]) << 16) | (((int) static_cast (bytes)[1]) << 8) | ((int) static_cast (bytes)[2]); } inline void ByteOrder::littleEndian24BitToChars (const int value, void* const destBytes) noexcept { static_cast (destBytes)[0] = (uint8) value; static_cast (destBytes)[1] = (uint8) (value >> 8); static_cast (destBytes)[2] = (uint8) (value >> 16); } inline void ByteOrder::bigEndian24BitToChars (const int value, void* const destBytes) noexcept { static_cast (destBytes)[0] = (uint8) (value >> 16); static_cast (destBytes)[1] = (uint8) (value >> 8); static_cast (destBytes)[2] = (uint8) value; } - - -#endif // JUCE_BYTEORDER_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_ContainerDeletePolicy.h b/source/modules/juce_core/memory/juce_ContainerDeletePolicy.h index 5c2aaec02..156feafa5 100644 --- a/source/modules/juce_core/memory/juce_ContainerDeletePolicy.h +++ b/source/modules/juce_core/memory/juce_ContainerDeletePolicy.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CONTAINERDELETEPOLICY_H_INCLUDED -#define JUCE_CONTAINERDELETEPOLICY_H_INCLUDED +#pragma once //============================================================================== /** @@ -60,6 +51,3 @@ struct ContainerDeletePolicy delete object; } }; - - -#endif // JUCE_CONTAINERDELETEPOLICY_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_HeapBlock.h b/source/modules/juce_core/memory/juce_HeapBlock.h index 5f3a423a8..fdc10c954 100644 --- a/source/modules/juce_core/memory/juce_HeapBlock.h +++ b/source/modules/juce_core/memory/juce_HeapBlock.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_HEAPBLOCK_H_INCLUDED -#define JUCE_HEAPBLOCK_H_INCLUDED +#pragma once #if ! (defined (DOXYGEN) || JUCE_EXCEPTIONS_DISABLED) namespace HeapBlockHelper @@ -137,19 +128,19 @@ public: std::free (data); } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ HeapBlock (HeapBlock&& other) noexcept : data (other.data) { other.data = nullptr; } + /** Move assignment operator */ HeapBlock& operator= (HeapBlock&& other) noexcept { std::swap (data, other.data); return *this; } - #endif //============================================================================== /** Returns a raw pointer to the allocated data. @@ -309,6 +300,3 @@ private: JUCE_PREVENT_HEAP_ALLOCATION // Creating a 'new HeapBlock' would be missing the point! #endif }; - - -#endif // JUCE_HEAPBLOCK_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_LeakedObjectDetector.h b/source/modules/juce_core/memory/juce_LeakedObjectDetector.h index 0c4a438d0..293ab18da 100644 --- a/source/modules/juce_core/memory/juce_LeakedObjectDetector.h +++ b/source/modules/juce_core/memory/juce_LeakedObjectDetector.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LEAKEDOBJECTDETECTOR_H_INCLUDED -#define JUCE_LEAKEDOBJECTDETECTOR_H_INCLUDED +#pragma once //============================================================================== @@ -143,6 +134,3 @@ private: #define JUCE_LEAK_DETECTOR(OwnerClass) #endif #endif - - -#endif // JUCE_LEAKEDOBJECTDETECTOR_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_Memory.h b/source/modules/juce_core/memory/juce_Memory.h index db8d825ab..ab9d83308 100644 --- a/source/modules/juce_core/memory/juce_Memory.h +++ b/source/modules/juce_core/memory/juce_Memory.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MEMORY_H_INCLUDED -#define JUCE_MEMORY_H_INCLUDED +#pragma once //============================================================================== /** Fills a block of memory with zeros. */ @@ -54,6 +45,14 @@ inline void deleteAndZero (Type& pointer) { delete poi template inline Type* addBytesToPointer (Type* basePointer, IntegerType bytes) noexcept { return (Type*) (((char*) basePointer) + bytes); } +/** A handy function to round up a pointer to the nearest multiple of a given number of bytes. + alignmentBytes must be a power of two. */ +template +inline Type* snapPointerToAlignment (Type* basePointer, IntegerType alignmentBytes) noexcept +{ + return (Type*) ((((size_t) basePointer) + (alignmentBytes - 1)) & ~(alignmentBytes - 1)); +} + /** A handy function which returns the difference between any two pointers, in bytes. The address of the second pointer is subtracted from the first, and the difference in bytes is returned. */ @@ -141,6 +140,3 @@ inline void writeUnaligned (void* dstPtr, Type value) noexcept #ifndef juce_UseDebuggingNewOperator #define juce_UseDebuggingNewOperator #endif - - -#endif // JUCE_MEMORY_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_MemoryBlock.cpp b/source/modules/juce_core/memory/juce_MemoryBlock.cpp index 93b025585..85d3e20d9 100644 --- a/source/modules/juce_core/memory/juce_MemoryBlock.cpp +++ b/source/modules/juce_core/memory/juce_MemoryBlock.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -88,21 +80,18 @@ MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS MemoryBlock::MemoryBlock (MemoryBlock&& other) noexcept - : data (static_cast&&> (other.data)), + : data (static_cast (other.data)), size (other.size) { } MemoryBlock& MemoryBlock::operator= (MemoryBlock&& other) noexcept { - data = static_cast&&> (other.data); + data = static_cast (other.data); size = other.size; return *this; } -#endif - //============================================================================== bool MemoryBlock::operator== (const MemoryBlock& other) const noexcept diff --git a/source/modules/juce_core/memory/juce_MemoryBlock.h b/source/modules/juce_core/memory/juce_MemoryBlock.h index 73426569f..ad70739a1 100644 --- a/source/modules/juce_core/memory/juce_MemoryBlock.h +++ b/source/modules/juce_core/memory/juce_MemoryBlock.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MEMORYBLOCK_H_INCLUDED -#define JUCE_MEMORYBLOCK_H_INCLUDED +#pragma once //============================================================================== @@ -70,10 +61,11 @@ public: */ MemoryBlock& operator= (const MemoryBlock&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ MemoryBlock (MemoryBlock&&) noexcept; + + /** Move assignment operator */ MemoryBlock& operator= (MemoryBlock&&) noexcept; - #endif //============================================================================== /** Compares two memory blocks. @@ -103,6 +95,11 @@ public: template char& operator[] (const Type offset) const noexcept { return data [offset]; } + /** Returns an iterator for the data. */ + char* begin() const noexcept { return data; } + + /** Returns an end-iterator for the data. */ + char* end() const noexcept { return begin() + getSize(); } //============================================================================== /** Returns the block's current allocated size, in bytes. */ @@ -253,11 +250,9 @@ public: private: //============================================================================== - HeapBlock data; + typedef HeapBlock HeapBlockType; + HeapBlockType data; size_t size; JUCE_LEAK_DETECTOR (MemoryBlock) }; - - -#endif // JUCE_MEMORYBLOCK_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_OptionalScopedPointer.h b/source/modules/juce_core/memory/juce_OptionalScopedPointer.h index bd3972e10..6d6ad66c3 100644 --- a/source/modules/juce_core/memory/juce_OptionalScopedPointer.h +++ b/source/modules/juce_core/memory/juce_OptionalScopedPointer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_OPTIONALSCOPEDPOINTER_H_INCLUDED -#define JUCE_OPTIONALSCOPEDPOINTER_H_INCLUDED +#pragma once //============================================================================== @@ -189,6 +180,3 @@ private: // myPointer.setOwned (myScopedPointer.release()) void setOwned (const ScopedPointer&) JUCE_DELETED_FUNCTION; }; - - -#endif // JUCE_OPTIONALSCOPEDPOINTER_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_ReferenceCountedObject.h b/source/modules/juce_core/memory/juce_ReferenceCountedObject.h index 485fed90b..ba4b893c6 100644 --- a/source/modules/juce_core/memory/juce_ReferenceCountedObject.h +++ b/source/modules/juce_core/memory/juce_ReferenceCountedObject.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_REFERENCECOUNTEDOBJECT_H_INCLUDED -#define JUCE_REFERENCECOUNTEDOBJECT_H_INCLUDED +#pragma once //============================================================================== @@ -248,13 +239,11 @@ public: incIfNotNull (refCountedObject); } - #if JUCE_COMPILER_SUPPORTS_NULLPTR /** Creates a pointer to a null object. */ ReferenceCountedObjectPtr (decltype (nullptr)) noexcept : referencedObject (nullptr) { } - #endif /** Copies another pointer. This will increment the object's reference-count. @@ -312,7 +301,6 @@ public: return *this; } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS /** Takes-over the object from another pointer. */ ReferenceCountedObjectPtr (ReferenceCountedObjectPtr&& other) noexcept : referencedObject (other.referencedObject) @@ -326,7 +314,6 @@ public: std::swap (referencedObject, other.referencedObject); return *this; } - #endif /** Destructor. This will decrement the object's reference-count, which will cause the @@ -420,6 +407,3 @@ bool operator!= (ReferenceCountedObjectClass* object1, const ReferenceCountedObj { return object1 != object2.get(); } - - -#endif // JUCE_REFERENCECOUNTEDOBJECT_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_ScopedPointer.h b/source/modules/juce_core/memory/juce_ScopedPointer.h index 2dda066c3..d0c5cee70 100644 --- a/source/modules/juce_core/memory/juce_ScopedPointer.h +++ b/source/modules/juce_core/memory/juce_ScopedPointer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SCOPEDPOINTER_H_INCLUDED -#define JUCE_SCOPEDPOINTER_H_INCLUDED +#pragma once //============================================================================== /** @@ -78,12 +69,10 @@ public: { } - #if JUCE_COMPILER_SUPPORTS_NULLPTR /** Creates a ScopedPointer containing a null pointer. */ inline ScopedPointer (decltype (nullptr)) noexcept : object (nullptr) { } - #endif /** Creates a ScopedPointer that owns the specified object. */ inline ScopedPointer (ObjectType* const objectToTakePossessionOf) noexcept @@ -153,13 +142,14 @@ public: return *this; } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Take ownership of another ScopedPointer */ ScopedPointer (ScopedPointer&& other) noexcept : object (other.object) { other.object = nullptr; } + /** Take ownership of another ScopedPointer */ ScopedPointer& operator= (ScopedPointer&& other) noexcept { ContainerDeletePolicy::destroy (object); @@ -167,7 +157,6 @@ public: other.object = nullptr; return *this; } - #endif //============================================================================== /** Returns the object that this ScopedPointer refers to. */ @@ -257,7 +246,6 @@ bool operator!= (const ScopedPointer& pointer1, ObjectType* const po #ifndef DOXYGEN // NB: This is just here to prevent any silly attempts to call deleteAndZero() on a ScopedPointer. template -void deleteAndZero (ScopedPointer&) { static_jassert (sizeof (Type) == 12345); } +void deleteAndZero (ScopedPointer&) { static_assert (sizeof (Type) == 12345, + "Attempt to call deleteAndZero() on a ScopedPointer"); } #endif - -#endif // JUCE_SCOPEDPOINTER_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_SharedResourcePointer.h b/source/modules/juce_core/memory/juce_SharedResourcePointer.h index 4ec69b6a2..181f93fc6 100644 --- a/source/modules/juce_core/memory/juce_SharedResourcePointer.h +++ b/source/modules/juce_core/memory/juce_SharedResourcePointer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SHAREDRESOURCEPOINTER_H_INCLUDED -#define JUCE_SHAREDRESOURCEPOINTER_H_INCLUDED +#pragma once //============================================================================== @@ -110,7 +101,7 @@ public: */ ~SharedResourcePointer() { - SharedObjectHolder& holder = getSharedObjectHolder(); + auto& holder = getSharedObjectHolder(); const SpinLock::ScopedLockType sl (holder.lock); if (--(holder.refCount) == 0) @@ -128,10 +119,14 @@ public: */ SharedObjectType& getObject() const noexcept { return *sharedObject; } + /** Returns the shared object. */ SharedObjectType* operator->() const noexcept { return sharedObject; } + /** Returns the number of SharedResourcePointers that are currently holding the shared object. */ + int getReferenceCount() const noexcept { return getSharedObjectHolder().refCount; } + private: - struct SharedObjectHolder : public ReferenceCountedObject + struct SharedObjectHolder { SpinLock lock; ScopedPointer sharedInstance; @@ -148,7 +143,7 @@ private: void initialise() { - SharedObjectHolder& holder = getSharedObjectHolder(); + auto& holder = getSharedObjectHolder(); const SpinLock::ScopedLockType sl (holder.lock); if (++(holder.refCount) == 1) @@ -159,10 +154,7 @@ private: // There's no need to assign to a SharedResourcePointer because every // instance of the class is exactly the same! - SharedResourcePointer& operator= (const SharedResourcePointer&) JUCE_DELETED_FUNCTION; + SharedResourcePointer& operator= (const SharedResourcePointer&) = delete; JUCE_LEAK_DETECTOR (SharedResourcePointer) }; - - -#endif // JUCE_SHAREDRESOURCEPOINTER_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_Singleton.h b/source/modules/juce_core/memory/juce_Singleton.h index deb9c599e..9bcaa34eb 100644 --- a/source/modules/juce_core/memory/juce_Singleton.h +++ b/source/modules/juce_core/memory/juce_Singleton.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SINGLETON_H_INCLUDED -#define JUCE_SINGLETON_H_INCLUDED +#pragma once //============================================================================== @@ -288,7 +279,3 @@ #define juce_ImplementSingleton_SingleThreaded(classname) \ \ classname* classname::_singletonInstance = nullptr; - - - -#endif // JUCE_SINGLETON_H_INCLUDED diff --git a/source/modules/juce_core/memory/juce_WeakReference.h b/source/modules/juce_core/memory/juce_WeakReference.h index 37e92d31f..1751cecc7 100644 --- a/source/modules/juce_core/memory/juce_WeakReference.h +++ b/source/modules/juce_core/memory/juce_WeakReference.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_WEAKREFERENCE_H_INCLUDED -#define JUCE_WEAKREFERENCE_H_INCLUDED +#pragma once //============================================================================== @@ -93,16 +84,17 @@ public: /** Creates a copy of another WeakReference. */ WeakReference (const WeakReference& other) noexcept : holder (other.holder) {} + /** Move constructor */ + WeakReference (WeakReference&& other) noexcept : holder (static_cast (other.holder)) {} + /** Copies another pointer to this one. */ WeakReference& operator= (const WeakReference& other) { holder = other.holder; return *this; } /** Copies another pointer to this one. */ WeakReference& operator= (ObjectType* const newObject) { holder = getRef (newObject); return *this; } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - WeakReference (WeakReference&& other) noexcept : holder (static_cast (other.holder)) {} + /** Move assignment operator */ WeakReference& operator= (WeakReference&& other) noexcept { holder = static_cast (other.holder); return *this; } - #endif /** Returns the object that this pointer refers to, or null if the object no longer exists. */ ObjectType* get() const noexcept { return holder != nullptr ? holder->get() : nullptr; } @@ -209,6 +201,3 @@ private: return (o != nullptr) ? o->masterReference.getSharedPointer (o) : nullptr; } }; - - -#endif // JUCE_WEAKREFERENCE_H_INCLUDED diff --git a/source/modules/juce_core/misc/juce_Result.cpp b/source/modules/juce_core/misc/juce_Result.cpp index 243f2d1c5..678af8747 100644 --- a/source/modules/juce_core/misc/juce_Result.cpp +++ b/source/modules/juce_core/misc/juce_Result.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -46,7 +38,6 @@ Result& Result::operator= (const Result& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Result::Result (Result&& other) noexcept : errorMessage (static_cast (other.errorMessage)) { @@ -57,7 +48,6 @@ Result& Result::operator= (Result&& other) noexcept errorMessage = static_cast (other.errorMessage); return *this; } -#endif bool Result::operator== (const Result& other) const noexcept { diff --git a/source/modules/juce_core/misc/juce_Result.h b/source/modules/juce_core/misc/juce_Result.h index 4d047dd63..0eda20c38 100644 --- a/source/modules/juce_core/misc/juce_Result.h +++ b/source/modules/juce_core/misc/juce_Result.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RESULT_H_INCLUDED -#define JUCE_RESULT_H_INCLUDED +#pragma once //============================================================================== @@ -101,11 +92,8 @@ public: //============================================================================== Result (const Result&); Result& operator= (const Result&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Result (Result&&) noexcept; Result& operator= (Result&&) noexcept; - #endif bool operator== (const Result& other) const noexcept; bool operator!= (const Result& other) const noexcept; @@ -122,6 +110,3 @@ private: operator int() const; operator void*() const; }; - - -#endif // JUCE_RESULT_H_INCLUDED diff --git a/source/modules/juce_core/misc/juce_RuntimePermissions.cpp b/source/modules/juce_core/misc/juce_RuntimePermissions.cpp index ffa17c068..e15a07193 100644 --- a/source/modules/juce_core/misc/juce_RuntimePermissions.cpp +++ b/source/modules/juce_core/misc/juce_RuntimePermissions.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/misc/juce_RuntimePermissions.h b/source/modules/juce_core/misc/juce_RuntimePermissions.h index 5ad3ccff9..bb170eea3 100644 --- a/source/modules/juce_core/misc/juce_RuntimePermissions.h +++ b/source/modules/juce_core/misc/juce_RuntimePermissions.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RUNTIMEPERMISSIONS_H_INCLUDED -#define JUCE_RUNTIMEPERMISSIONS_H_INCLUDED +#pragma once //============================================================================== /** @@ -84,15 +75,17 @@ public: otherwise no devices will be found. */ bluetoothMidi = 2, + + /** Permission to read from external storage such as SD cards */ + readExternalStorage = 3, + + /** Permission to write to external storage such as SD cards */ + writeExternalStorage = 4 }; //============================================================================== /** 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. @@ -128,6 +121,3 @@ public: */ static bool isGranted (PermissionID permission); }; - - -#endif // JUCE_RUNTIMEPERMISSIONS_H_INCLUDED diff --git a/source/modules/juce_core/misc/juce_StdFunctionCompat.cpp b/source/modules/juce_core/misc/juce_StdFunctionCompat.cpp new file mode 100644 index 000000000..cf548ef60 --- /dev/null +++ b/source/modules/juce_core/misc/juce_StdFunctionCompat.cpp @@ -0,0 +1,254 @@ +/* + ============================================================================== + + 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 BigData + { + BigData() + { + for (auto i = 0; i < bigDataSize; ++i) + content[i] = i + 1; + } + + int sum() const + { + int result = 0; + for (auto i = 0; i < bigDataSize; ++i) + result += content[i]; + + return result; + } + + static const int bigDataSize = 32, + bigDataSum = bigDataSize * (bigDataSize + 1) / 2; + int content[bigDataSize]; + }; + + struct FunctionObject + { + FunctionObject() {} + + FunctionObject (const FunctionObject& other) + { + bigData = new BigData (*other.bigData); + } + + int operator()(int i) const { return bigData->sum() + i; } + + ScopedPointer bigData { new BigData() }; + }; +} + +class FunctionTests : public UnitTest +{ +public: + FunctionTests() : UnitTest ("Function", "Function") {} + + void runTest() override + { + FunctionTestsHelpers::BigData bigData; + + { + 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::FunctionObject(); + expectEquals (f1 (5), FunctionTestsHelpers::BigData::bigDataSum + 5); + } + + { + beginTest ("Lambdas"); + + std::function fStack ([]() { return 3; }); + expectEquals (fStack(), 3); + + std::function fHeap ([=]() { return bigData.sum(); }); + expectEquals (fHeap(), FunctionTestsHelpers::BigData::bigDataSum); + } + + { + 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.sum(); }); + + { + beginTest ("copy constructor"); + + std::function f1 (fStack); + expectEquals (f1(), 3); + + std::function f2 (fHeap); + expectEquals (f2(), FunctionTestsHelpers::BigData::bigDataSum); + + 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(), FunctionTestsHelpers::BigData::bigDataSum); + + f1 = fHeap; + expectEquals (f1(), FunctionTestsHelpers::BigData::bigDataSum); + + 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(), FunctionTestsHelpers::BigData::bigDataSum); + + 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(), FunctionTestsHelpers::BigData::bigDataSum); + + 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(), FunctionTestsHelpers::BigData::bigDataSum); + } + } +}; + +static FunctionTests functionTests; + +#endif diff --git a/source/modules/juce_core/misc/juce_StdFunctionCompat.h b/source/modules/juce_core/misc/juce_StdFunctionCompat.h new file mode 100644 index 000000000..f1b262b76 --- /dev/null +++ b/source/modules/juce_core/misc/juce_StdFunctionCompat.h @@ -0,0 +1,209 @@ +/* + ============================================================================== + + 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 = getFunctorStorage (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 int getSize() const noexcept = 0; + virtual void copy (void*) const = 0; + virtual ReturnType operator()(Args...) = 0; + }; + + template + struct FunctorHolder : FunctorHolderBase + { + FunctorHolder (Functor func) : f (func) {} + + int getSize() const noexcept override final + { + return sizeof (*this); + } + + void copy (void* destination) const override final + { + new (destination) FunctorHolder (f); + } + + ReturnType operator()(Args... args) override final + { + return f (args...); + } + + Functor f; + }; + + FunctorHolderBase* getFunctorStorage (int size) + { + return reinterpret_cast*> + (size > functorHolderStackSize ? new char [size] + : &(stackFunctorStorage[0])); + } + + void copy (function const& other) + { + if (other.functorHolderHelper != nullptr) + { + functorHolderHelper = getFunctorStorage (other.functorHolderHelper->getSize()); + other.functorHolderHelper->copy (functorHolderHelper); + } + } + + void move (function& other) + { + if (other.functorHolderHelper != nullptr) + { + if (other.functorHolderHelper->getSize() > functorHolderStackSize) + { + functorHolderHelper = other.functorHolderHelper; + } + else + { + std::copy (other.stackFunctorStorage, other.stackFunctorStorage + functorHolderStackSize, + stackFunctorStorage); + functorHolderHelper = reinterpret_cast*> (&(stackFunctorStorage[0])); + } + + other.functorHolderHelper = nullptr; + } + } + + void release() + { + if (functorHolderHelper != nullptr) + { + if (functorHolderHelper->getSize() > functorHolderStackSize) + delete[] reinterpret_cast (functorHolderHelper); + else + functorHolderHelper->~FunctorHolderBase(); + + functorHolderHelper = nullptr; + } + } + + static const int functorHolderStackSize = 24; + char stackFunctorStorage[functorHolderStackSize]; + + FunctorHolderBase* functorHolderHelper = nullptr; + }; +} diff --git a/source/modules/juce_core/misc/juce_Uuid.cpp b/source/modules/juce_core/misc/juce_Uuid.cpp index 01b0b011a..03f911cbf 100644 --- a/source/modules/juce_core/misc/juce_Uuid.cpp +++ b/source/modules/juce_core/misc/juce_Uuid.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -56,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); @@ -63,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; @@ -117,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/source/modules/juce_core/misc/juce_Uuid.h b/source/modules/juce_core/misc/juce_Uuid.h index bf5f8c21d..cab55d8dc 100644 --- a/source/modules/juce_core/misc/juce_Uuid.h +++ b/source/modules/juce_core/misc/juce_Uuid.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_UUID_H_INCLUDED -#define JUCE_UUID_H_INCLUDED +#pragma once //============================================================================== @@ -67,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. @@ -94,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. @@ -115,9 +124,7 @@ private: //============================================================================== uint8 uuid[16]; String getHexRegion (int, int) const; + int compare (Uuid) const noexcept; JUCE_LEAK_DETECTOR (Uuid) }; - - -#endif // JUCE_UUID_H_INCLUDED diff --git a/source/modules/juce_core/misc/juce_WindowsRegistry.h b/source/modules/juce_core/misc/juce_WindowsRegistry.h index 460164b01..239849cc7 100644 --- a/source/modules/juce_core/misc/juce_WindowsRegistry.h +++ b/source/modules/juce_core/misc/juce_WindowsRegistry.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_WINDOWSREGISTRY_H_INCLUDED -#define JUCE_WINDOWSREGISTRY_H_INCLUDED +#pragma once #if JUCE_WINDOWS || DOXYGEN @@ -99,10 +90,10 @@ public: static bool JUCE_CALLTYPE keyExists (const String& regValuePath, WoW64Mode mode = WoW64_Default); /** Deletes a registry value. */ - static void JUCE_CALLTYPE deleteValue (const String& regValuePath, WoW64Mode mode = WoW64_Default); + static bool JUCE_CALLTYPE deleteValue (const String& regValuePath, WoW64Mode mode = WoW64_Default); /** Deletes a registry key (which is registry-talk for 'folder'). */ - static void JUCE_CALLTYPE deleteKey (const String& regKeyPath, WoW64Mode mode = WoW64_Default); + static bool JUCE_CALLTYPE deleteKey (const String& regKeyPath, WoW64Mode mode = WoW64_Default); /** Creates a file association in the registry. @@ -140,4 +131,3 @@ private: }; #endif -#endif // JUCE_WINDOWSREGISTRY_H_INCLUDED diff --git a/source/modules/juce_core/native/java/AndroidMidi.java b/source/modules/juce_core/native/java/AndroidMidi.java index 9ad86ecce..9e337be8f 100644 --- a/source/modules/juce_core/native/java/AndroidMidi.java +++ b/source/modules/juce_core/native/java/AndroidMidi.java @@ -3,14 +3,26 @@ { BluetoothManager() { - ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder(); - scanFilterBuilder.setServiceUuid (ParcelUuid.fromString (bluetoothLEMidiServiceUUID)); + } + + public String[] getMidiBluetoothAddresses() + { + return bluetoothMidiDevices.toArray (new String[bluetoothMidiDevices.size()]); + } + + public String getHumanReadableStringForBluetoothAddress (String address) + { + BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice (address); + return btDevice.getName(); + } - ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder(); - scanSettingsBuilder.setCallbackType (ScanSettings.CALLBACK_TYPE_ALL_MATCHES) - .setScanMode (ScanSettings.SCAN_MODE_LOW_POWER) - .setScanMode (ScanSettings.MATCH_MODE_STICKY); + public int getBluetoothDeviceStatus (String address) + { + return getAndroidMidiDeviceManager().getBluetoothDeviceStatus (address); + } + public void startStopScan (boolean shouldStart) + { BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) @@ -27,25 +39,24 @@ return; } - bluetoothLeScanner.startScan (Arrays.asList (scanFilterBuilder.build()), - scanSettingsBuilder.build(), - this); - } - - public String[] getMidiBluetoothAddresses() - { - return bluetoothMidiDevices.toArray (new String[bluetoothMidiDevices.size()]); - } + if (shouldStart) + { + ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder(); + scanFilterBuilder.setServiceUuid (ParcelUuid.fromString (bluetoothLEMidiServiceUUID)); - public String getHumanReadableStringForBluetoothAddress (String address) - { - BluetoothDevice btDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice (address); - return btDevice.getName(); - } + ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder(); + scanSettingsBuilder.setCallbackType (ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .setScanMode (ScanSettings.SCAN_MODE_LOW_POWER) + .setScanMode (ScanSettings.MATCH_MODE_STICKY); - public boolean isBluetoothDevicePaired (String address) - { - return getAndroidMidiDeviceManager().isBluetoothDevicePaired (address); + bluetoothLeScanner.startScan (Arrays.asList (scanFilterBuilder.build()), + scanSettingsBuilder.build(), + this); + } + else + { + bluetoothLeScanner.stopScan (this); + } } public boolean pairBluetoothMidiDevice(String address) @@ -58,17 +69,7 @@ return false; } - MidiManager mm = (MidiManager) getSystemService (MIDI_SERVICE); - - PhysicalMidiDevice midiDevice = PhysicalMidiDevice.fromBluetoothLeDevice (btDevice, mm); - - if (midiDevice != null) - { - getAndroidMidiDeviceManager().addDeviceToList (midiDevice); - return true; - } - - return false; + return getAndroidMidiDeviceManager().pairBluetoothDevice (btDevice); } public void unpairBluetoothMidiDevice (String address) @@ -120,11 +121,20 @@ { private native void handleReceive (long host, byte[] msg, int offset, int count, long timestamp); - public JuceMidiInputPort (PhysicalMidiDevice device, long host, MidiOutputPort midiPort) + public JuceMidiInputPort (MidiDeviceManager mm, MidiOutputPort actualPort, MidiPortPath portPathToUse, long hostToUse) { - parent = device; - juceHost = host; - port = midiPort; + owner = mm; + androidPort = actualPort; + portPath = portPathToUse; + juceHost = hostToUse; + isConnected = false; + } + + @Override + protected void finalize() throws Throwable + { + close(); + super.finalize(); } @Override @@ -136,36 +146,40 @@ @Override public void start() { - port.connect (this); + if (owner != null && androidPort != null && ! isConnected) { + androidPort.connect(this); + isConnected = true; + } } @Override public void stop() { - port.disconnect (this); + if (owner != null && androidPort != null && isConnected) { + androidPort.disconnect(this); + isConnected = false; + } } @Override public void close() { - stop(); - - try - { - port.close(); - } - catch (IOException e) - { - Log.d ("JUCE", "JuceMidiInputPort::close: IOException = " + e.toString()); + if (androidPort != null) { + try { + androidPort.close(); + } catch (IOException exception) { + Log.d("JUCE", "IO Exception while closing port"); + } } - if (parent != null) - { - parent.removePort (port.getPortNumber(), true); - parent = null; - } + if (owner != null) + owner.removePort (portPath); + + owner = null; + androidPort = null; } + @Override public void onSend (byte[] msg, int offset, int count, long timestamp) { if (count > 0) @@ -173,27 +187,35 @@ } @Override - public MidiPortID getPortId() - { - return new MidiPortID (port.getPortNumber(), true); - } + public void onFlush() + {} @Override public void sendMidi (byte[] msg, int offset, int count) { } - private PhysicalMidiDevice parent = null; - private long juceHost = 0; - private MidiOutputPort port; + MidiDeviceManager owner; + MidiOutputPort androidPort; + MidiPortPath portPath; + long juceHost; + boolean isConnected; } public static class JuceMidiOutputPort implements JuceMidiPort { - public JuceMidiOutputPort (PhysicalMidiDevice device, MidiInputPort midiPort) + public JuceMidiOutputPort (MidiDeviceManager mm, MidiInputPort actualPort, MidiPortPath portPathToUse) { - parent = device; - port = midiPort; + owner = mm; + androidPort = actualPort; + portPath = portPathToUse; + } + + @Override + protected void finalize() throws Throwable + { + close(); + super.finalize(); } @Override @@ -215,590 +237,732 @@ @Override public void sendMidi (byte[] msg, int offset, int count) { - try + if (androidPort != null) { - port.send(msg, offset, count); - } - catch (IOException e) - { - Log.d ("JUCE", "JuceMidiOutputPort::sendMidi: IOException = " + e.toString()); + try { + androidPort.send(msg, offset, count); + } catch (IOException exception) + { + Log.d ("JUCE", "send midi had IO exception"); + } } } @Override public void close() { - try - { - port.close(); - } - catch (IOException e) - { - Log.d ("JUCE", "JuceMidiOutputPort::close: IOException = " + e.toString()); + if (androidPort != null) { + try { + androidPort.close(); + } catch (IOException exception) { + Log.d("JUCE", "IO Exception while closing port"); + } } - if (parent != null) - { - parent.removePort (port.getPortNumber(), false); - parent = null; - } + if (owner != null) + owner.removePort (portPath); + + owner = null; + androidPort = null; } + MidiDeviceManager owner; + MidiInputPort androidPort; + MidiPortPath portPath; + } + + private static class MidiPortPath extends Object + { + public MidiPortPath (int deviceIdToUse, boolean direction, int androidIndex) + { + deviceId = deviceIdToUse; + isInput = direction; + portIndex = androidIndex; + + } + + public int deviceId; + public int portIndex; + public boolean isInput; @Override - public MidiPortID getPortId() + public int hashCode() { - return new MidiPortID (port.getPortNumber(), false); + Integer i = new Integer ((deviceId * 128) + (portIndex < 128 ? portIndex : 127)); + return i.hashCode() * (isInput ? -1 : 1); } - private PhysicalMidiDevice parent = null; - private MidiInputPort port; + @Override + public boolean equals (Object obj) + { + if (obj == null) + return false; + + if (getClass() != obj.getClass()) + return false; + + MidiPortPath other = (MidiPortPath) obj; + return (portIndex == other.portIndex && isInput == other.isInput && deviceId == other.deviceId); + } } - public static class PhysicalMidiDevice + //============================================================================== + public class MidiDeviceManager extends MidiManager.DeviceCallback implements MidiManager.OnDeviceOpenedListener { - private static class MidiDeviceThread extends Thread + //============================================================================== + private class DummyBluetoothGattCallback extends BluetoothGattCallback { - public Handler handler = null; - public Object sync = null; - - public MidiDeviceThread (Object syncrhonization) + public DummyBluetoothGattCallback (MidiDeviceManager mm) { - sync = syncrhonization; + super(); + owner = mm; } - public void run() + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { - Looper.prepare(); - - synchronized (sync) + if (newState == BluetoothProfile.STATE_CONNECTED) { - handler = new Handler(); - sync.notifyAll(); + gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH); + owner.pairBluetoothDeviceStepTwo (gatt.getDevice()); } - - Looper.loop(); } + public void onServicesDiscovered(BluetoothGatt gatt, int status) {} + public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {} + public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {} + public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} + public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {} + public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {} + public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {} + public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {} + + private MidiDeviceManager owner; } - private static class MidiDeviceOpenCallback implements MidiManager.OnDeviceOpenedListener + //============================================================================== + private class MidiDeviceOpenTask extends java.util.TimerTask { - public Object sync = null; - public boolean isWaiting = true; - public android.media.midi.MidiDevice theDevice = null; - - public MidiDeviceOpenCallback (Object waiter) + public MidiDeviceOpenTask (MidiDeviceManager deviceManager, MidiDevice device, BluetoothGatt gattToUse) { - sync = waiter; + owner = deviceManager; + midiDevice = device; + btGatt = gattToUse; } - public void onDeviceOpened (MidiDevice device) + @Override + public boolean cancel() { - synchronized (sync) + synchronized (MidiDeviceOpenTask.class) { - theDevice = device; - isWaiting = false; - sync.notifyAll(); + owner = null; + boolean retval = super.cancel(); + + if (btGatt != null) + { + btGatt.disconnect(); + btGatt.close(); + + btGatt = null; + } + + if (midiDevice != null) + { + try + { + midiDevice.close(); + } + catch (IOException e) + {} + + midiDevice = null; + } + + return retval; } } - } - - public static PhysicalMidiDevice fromBluetoothLeDevice (BluetoothDevice bluetoothDevice, MidiManager mm) - { - Object waitForCreation = new Object(); - MidiDeviceThread thread = new MidiDeviceThread (waitForCreation); - thread.start(); - synchronized (waitForCreation) + public String getBluetoothAddress() { - while (thread.handler == null) + synchronized (MidiDeviceOpenTask.class) { - try - { - waitForCreation.wait(); - } - catch (InterruptedException e) + if (midiDevice != null) { - Log.d ("JUCE", "Wait was interrupted but we don't care"); + MidiDeviceInfo info = midiDevice.getInfo(); + if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) + { + BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); + if (btDevice != null) + return btDevice.getAddress(); + } } } - } - Object waitForDevice = new Object(); + return ""; + } - MidiDeviceOpenCallback openCallback = new MidiDeviceOpenCallback (waitForDevice); + public BluetoothGatt getGatt() { return btGatt; } - synchronized (waitForDevice) + public int getID() { - mm.openBluetoothDevice (bluetoothDevice, openCallback, thread.handler); + return midiDevice.getInfo().getId(); + } - while (openCallback.isWaiting) + @Override + public void run() + { + synchronized (MidiDeviceOpenTask.class) { - try - { - waitForDevice.wait(); - } - catch (InterruptedException e) - { - Log.d ("JUCE", "Wait was interrupted but we don't care"); - } + if (owner != null && midiDevice != null) + owner.onDeviceOpenedDelayed (midiDevice); } } - if (openCallback.theDevice == null) + private MidiDeviceManager owner; + private MidiDevice midiDevice; + private BluetoothGatt btGatt; + } + + //============================================================================== + public MidiDeviceManager() + { + manager = (MidiManager) getSystemService (MIDI_SERVICE); + + if (manager == null) { - Log.d ("JUCE", "openBluetoothDevice failed"); - return null; + Log.d ("JUCE", "MidiDeviceManager error: could not get MidiManager system service"); + return; } - PhysicalMidiDevice device = new PhysicalMidiDevice(); + openPorts = new HashMap> (); + midiDevices = new ArrayList>(); + openTasks = new HashMap(); + btDevicesPairing = new HashMap(); - device.handle = openCallback.theDevice; - device.info = device.handle.getInfo(); - device.bluetoothAddress = bluetoothDevice.getAddress(); - device.midiManager = mm; + MidiDeviceInfo[] foundDevices = manager.getDevices(); + for (MidiDeviceInfo info : foundDevices) + onDeviceAdded (info); - return device; + manager.registerDeviceCallback (this, null); } - public void unpair() + protected void finalize() throws Throwable { - if (! bluetoothAddress.equals ("") && handle != null) + manager.unregisterDeviceCallback (this); + + synchronized (MidiDeviceManager.class) { - JuceMidiPort ports[] = new JuceMidiPort[0]; - ports = juceOpenedPorts.values().toArray(ports); + btDevicesPairing.clear(); - for (int i = 0; i < ports.length; ++i) - ports[i].close(); + for (Integer deviceID : openTasks.keySet()) + openTasks.get (deviceID).cancel(); - juceOpenedPorts.clear(); + openTasks = null; + } - try - { - handle.close(); - } - catch (IOException e) + for (MidiPortPath key : openPorts.keySet()) + openPorts.get (key).get().close(); + + openPorts = null; + + for (Pair device : midiDevices) + { + if (device.second != null) { - Log.d ("JUCE", "handle.close(): IOException = " + e.toString()); + device.second.disconnect(); + device.second.close(); } - handle = null; + device.first.close(); } - } - public static PhysicalMidiDevice fromMidiDeviceInfo (MidiDeviceInfo info, MidiManager mm) - { - PhysicalMidiDevice device = new PhysicalMidiDevice(); - device.info = info; - device.midiManager = mm; - return device; + midiDevices.clear(); + + super.finalize(); } - public PhysicalMidiDevice() + public String[] getJuceAndroidMidiInputDevices() { - bluetoothAddress = ""; - juceOpenedPorts = new Hashtable(); - handle = null; + return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_OUTPUT); } - public MidiDeviceInfo.PortInfo[] getPorts() + public String[] getJuceAndroidMidiOutputDevices() { - return info.getPorts(); + return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_INPUT); } - public String getHumanReadableNameForPort (MidiDeviceInfo.PortInfo port, int portIndexToUseInName) + private String[] getJuceAndroidMidiDevices (int portType) { - String portName = port.getName(); + // only update the list when JUCE asks for a new list + synchronized (MidiDeviceManager.class) + { + deviceInfos = getDeviceInfos(); + } + + ArrayList portNames = new ArrayList(); - if (portName.equals ("")) - portName = ((port.getType() == MidiDeviceInfo.PortInfo.TYPE_OUTPUT) ? "Out " : "In ") - + Integer.toString (portIndexToUseInName); + int index = 0; + for (MidiPortPath portInfo = getPortPathForJuceIndex (portType, index); portInfo != null; portInfo = getPortPathForJuceIndex (portType, ++index)) + portNames.add (getPortName (portInfo)); - return getHumanReadableDeviceName() + " " + portName; + String[] names = new String[portNames.size()]; + return portNames.toArray (names); } - public String getHumanReadableNameForPort (int portType, int androidPortID, int portIndexToUseInName) + private JuceMidiPort openMidiPortWithJuceIndex (int index, long host, boolean isInput) { - MidiDeviceInfo.PortInfo[] ports = info.getPorts(); - - for (MidiDeviceInfo.PortInfo port : ports) + synchronized (MidiDeviceManager.class) { - if (port.getType() == portType) + int portTypeToFind = (isInput ? MidiDeviceInfo.PortInfo.TYPE_OUTPUT : MidiDeviceInfo.PortInfo.TYPE_INPUT); + MidiPortPath portInfo = getPortPathForJuceIndex (portTypeToFind, index); + + if (portInfo != null) { - if (port.getPortNumber() == androidPortID) - return getHumanReadableNameForPort (port, portIndexToUseInName); + // ports must be opened exclusively! + if (openPorts.containsKey (portInfo)) + return null; + + Pair devicePair = getMidiDevicePairForId (portInfo.deviceId); + + if (devicePair != null) + { + MidiDevice device = devicePair.first; + if (device != null) + { + JuceMidiPort juceMidiPort = null; + + if (isInput) + { + MidiOutputPort outputPort = device.openOutputPort(portInfo.portIndex); + + if (outputPort != null) + juceMidiPort = new JuceMidiInputPort(this, outputPort, portInfo, host); + } + else + { + MidiInputPort inputPort = device.openInputPort(portInfo.portIndex); + + if (inputPort != null) + juceMidiPort = new JuceMidiOutputPort(this, inputPort, portInfo); + } + + if (juceMidiPort != null) + { + openPorts.put(portInfo, new WeakReference(juceMidiPort)); + + return juceMidiPort; + } + } + } } } - return "Unknown"; + return null; } - public String getHumanReadableDeviceName() + public JuceMidiPort openMidiInputPortWithJuceIndex (int index, long host) { - Bundle bundle = info.getProperties(); - return bundle.getString (MidiDeviceInfo.PROPERTY_NAME , "Unknown device"); + return openMidiPortWithJuceIndex (index, host, true); } - public void checkIfDeviceCanBeClosed() + public JuceMidiPort openMidiOutputPortWithJuceIndex (int index) { - if (juceOpenedPorts.size() == 0) - { - // never close bluetooth LE devices, otherwise they unpair and we have - // no idea how many ports they have. - // Only remove bluetooth devices when we specifically unpair - if (bluetoothAddress.equals ("")) - { - try - { - handle.close(); - handle = null; - } - catch (IOException e) - { - Log.d ("JUCE", "PhysicalMidiDevice::checkIfDeviceCanBeClosed: IOException = " + e.toString()); - } - } - } + return openMidiPortWithJuceIndex (index, 0, false); } - public void removePort (int portIdx, boolean isInput) + /* 0: unpaired, 1: paired, 2: pairing */ + public int getBluetoothDeviceStatus (String address) { - MidiPortID portID = new MidiPortID (portIdx, isInput); - JuceMidiPort port = juceOpenedPorts.get (portID); - - if (port != null) + synchronized (MidiDeviceManager.class) { - juceOpenedPorts.remove (portID); - checkIfDeviceCanBeClosed(); - return; + if (! address.isEmpty()) + { + if (findMidiDeviceForBluetoothAddress (address) != null) + return 1; + + if (btDevicesPairing.containsKey (address)) + return 2; + + if (findOpenTaskForBluetoothAddress (address) != null) + return 2; + } } - // tried to remove a port that was never added - assert false; + return 0; } - public JuceMidiPort openPort (int portIdx, boolean isInput, long host) + public boolean pairBluetoothDevice (BluetoothDevice btDevice) { - open(); - - if (handle == null) - { - Log.d ("JUCE", "PhysicalMidiDevice::openPort: handle = null, device not open"); - return null; - } + String btAddress = btDevice.getAddress(); + if (btAddress.isEmpty()) + return false; - // make sure that the port is not already open - if (findPortForIdx (portIdx, isInput) != null) + synchronized (MidiDeviceManager.class) { - Log.d ("JUCE", "PhysicalMidiDevice::openInputPort: port already open, not opening again!"); - return null; - } + if (getBluetoothDeviceStatus (btAddress) != 0) + return false; - JuceMidiPort retval = null; - if (isInput) - { - MidiOutputPort androidPort = handle.openOutputPort (portIdx); + btDevicesPairing.put (btDevice.getAddress(), null); + BluetoothGatt gatt = btDevice.connectGatt (getApplicationContext(), true, new DummyBluetoothGattCallback (this)); - if (androidPort == null) + if (gatt != null) { - Log.d ("JUCE", "PhysicalMidiDevice::openPort: MidiDevice::openOutputPort (portIdx = " - + Integer.toString (portIdx) + ") failed!"); - return null; + btDevicesPairing.put (btDevice.getAddress(), gatt); } - - retval = new JuceMidiInputPort (this, host, androidPort); - } - else - { - MidiInputPort androidPort = handle.openInputPort (portIdx); - - if (androidPort == null) + else { - Log.d ("JUCE", "PhysicalMidiDevice::openPort: MidiDevice::openInputPort (portIdx = " - + Integer.toString (portIdx) + ") failed!"); - return null; + pairBluetoothDeviceStepTwo (btDevice); } - - retval = new JuceMidiOutputPort (this, androidPort); } - juceOpenedPorts.put (new MidiPortID (portIdx, isInput), retval); - return retval; + return true; } - private JuceMidiPort findPortForIdx (int idx, boolean isInput) + public void pairBluetoothDeviceStepTwo (BluetoothDevice btDevice) { - return juceOpenedPorts.get (new MidiPortID (idx, isInput)); + manager.openBluetoothDevice(btDevice, this, null); } - // opens the device - private synchronized void open() + public void unpairBluetoothDevice (String address) { - if (handle != null) + if (address.isEmpty()) return; - Object waitForCreation = new Object(); - MidiDeviceThread thread = new MidiDeviceThread (waitForCreation); - thread.start(); - - synchronized(waitForCreation) + synchronized (MidiDeviceManager.class) { - while (thread.handler == null) + if (btDevicesPairing.containsKey (address)) { - try - { - waitForCreation.wait(); - } - catch (InterruptedException e) + BluetoothGatt gatt = btDevicesPairing.get (address); + if (gatt != null) { - Log.d ("JUCE", "wait was interrupted but we don't care"); + gatt.disconnect(); + gatt.close(); } - } - } - Object waitForDevice = new Object(); - - MidiDeviceOpenCallback openCallback = new MidiDeviceOpenCallback (waitForDevice); + btDevicesPairing.remove (address); + } - synchronized (waitForDevice) - { - midiManager.openDevice (info, openCallback, thread.handler); + MidiDeviceOpenTask openTask = findOpenTaskForBluetoothAddress (address); + if (openTask != null) + { + int deviceID = openTask.getID(); + openTask.cancel(); + openTasks.remove (deviceID); + } - while (openCallback.isWaiting) + Pair midiDevicePair = findMidiDeviceForBluetoothAddress (address); + if (midiDevicePair != null) { - try - { - waitForDevice.wait(); + MidiDevice midiDevice = midiDevicePair.first; + onDeviceRemoved (midiDevice.getInfo()); + + try { + midiDevice.close(); } - catch (InterruptedException e) + catch (IOException exception) { - Log.d ("JUCE", "wait was interrupted but we don't care"); + Log.d ("JUCE", "IOException while closing midi device"); } } } - - handle = openCallback.theDevice; - } - - private MidiDeviceInfo info; - private Hashtable juceOpenedPorts; - public MidiDevice handle; - public String bluetoothAddress; - private MidiManager midiManager; - } - - //============================================================================== - public class MidiDeviceManager extends MidiManager.DeviceCallback - { - public class MidiPortPath - { - public PhysicalMidiDevice midiDevice; - public int androidMidiPortID; - public int portIndexToUseInName; } - public class JuceDeviceList + private Pair findMidiDeviceForBluetoothAddress (String address) { - public ArrayList inPorts = new ArrayList(); - public ArrayList outPorts = new ArrayList(); - } - - // We need to keep a thread local copy of the devices - // which we returned the last time - // getJuceAndroidMidiIn/OutputDevices() was called - private final ThreadLocal lastDevicesReturned = - new ThreadLocal() + for (Pair midiDevice : midiDevices) { - @Override protected JuceDeviceList initialValue() + MidiDeviceInfo info = midiDevice.first.getInfo(); + if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) { - return new JuceDeviceList(); + BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); + if (btDevice != null && btDevice.getAddress().equals (address)) + return midiDevice; } - }; + } - public MidiDeviceManager() - { - physicalMidiDevices = new ArrayList(); - manager = (MidiManager) getSystemService (MIDI_SERVICE); + return null; + } - if (manager == null) + private MidiDeviceOpenTask findOpenTaskForBluetoothAddress (String address) + { + for (Integer deviceID : openTasks.keySet()) { - Log.d ("JUCE", "MidiDeviceManager error: could not get MidiManager system service"); - return; + MidiDeviceOpenTask openTask = openTasks.get (deviceID); + if (openTask.getBluetoothAddress().equals (address)) + return openTask; } - manager.registerDeviceCallback (this, null); - - MidiDeviceInfo[] foundDevices = manager.getDevices(); - - for (MidiDeviceInfo info : foundDevices) - physicalMidiDevices.add (PhysicalMidiDevice.fromMidiDeviceInfo (info, manager)); + return null; } - // specifically add a device to the list - public void addDeviceToList (PhysicalMidiDevice device) + public void removePort (MidiPortPath path) { - physicalMidiDevices.add (device); + openPorts.remove (path); } - public void unpairBluetoothDevice (String address) + public String getInputPortNameForJuceIndex (int index) { - for (int i = 0; i < physicalMidiDevices.size(); ++i) - { - PhysicalMidiDevice device = physicalMidiDevices.get(i); + MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_OUTPUT, index); + if (portInfo != null) + return getPortName (portInfo); - if (device.bluetoothAddress.equals (address)) - { - physicalMidiDevices.remove (i); - device.unpair(); - return; - } - } + return ""; } - public boolean isBluetoothDevicePaired (String address) + public String getOutputPortNameForJuceIndex (int index) { - for (int i = 0; i < physicalMidiDevices.size(); ++i) - { - PhysicalMidiDevice device = physicalMidiDevices.get(i); + MidiPortPath portInfo = getPortPathForJuceIndex (MidiDeviceInfo.PortInfo.TYPE_INPUT, index); + if (portInfo != null) + return getPortName (portInfo); - if (device.bluetoothAddress.equals (address)) - return true; - } - - return false; + return ""; } - public String[] getJuceAndroidMidiInputDevices() + public void onDeviceAdded (MidiDeviceInfo info) { - return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_INPUT); - } + // only add standard midi devices + if (info.getType() == info.TYPE_BLUETOOTH) + return; - public String[] getJuceAndroidMidiOutputDevices() - { - return getJuceAndroidMidiDevices (MidiDeviceInfo.PortInfo.TYPE_OUTPUT); + manager.openDevice (info, this, null); } - private String[] getJuceAndroidMidiDevices (int portType) + public void onDeviceRemoved (MidiDeviceInfo info) { - ArrayList listOfReturnedDevices = new ArrayList(); - List deviceNames = new ArrayList(); - - for (PhysicalMidiDevice physicalMidiDevice : physicalMidiDevices) + synchronized (MidiDeviceManager.class) { - int portIdx = 0; - MidiDeviceInfo.PortInfo[] ports = physicalMidiDevice.getPorts(); + Pair devicePair = getMidiDevicePairForId (info.getId()); - for (MidiDeviceInfo.PortInfo port : ports) + if (devicePair != null) { - if (port.getType() == portType) + MidiDevice midiDevice = devicePair.first; + BluetoothGatt gatt = devicePair.second; + + // close all ports that use this device + boolean removedPort = true; + + while (removedPort == true) { - MidiPortPath path = new MidiPortPath(); - path.midiDevice = physicalMidiDevice; - path.androidMidiPortID = port.getPortNumber(); - path.portIndexToUseInName = ++portIdx; - listOfReturnedDevices.add (path); - - deviceNames.add (physicalMidiDevice.getHumanReadableNameForPort (port, - path.portIndexToUseInName)); + removedPort = false; + for (MidiPortPath key : openPorts.keySet()) + { + if (key.deviceId == info.getId()) + { + openPorts.get(key).get().close(); + removedPort = true; + break; + } + } } - } - } - String[] deviceNamesArray = new String[deviceNames.size()]; + if (gatt != null) + { + gatt.disconnect(); + gatt.close(); + } - if (portType == MidiDeviceInfo.PortInfo.TYPE_INPUT) - { - lastDevicesReturned.get().inPorts.clear(); - lastDevicesReturned.get().inPorts.addAll (listOfReturnedDevices); - } - else - { - lastDevicesReturned.get().outPorts.clear(); - lastDevicesReturned.get().outPorts.addAll (listOfReturnedDevices); + midiDevices.remove (devicePair); + } } + } - return deviceNames.toArray(deviceNamesArray); + public void onDeviceStatusChanged (MidiDeviceStatus status) + { } - public JuceMidiPort openMidiInputPortWithJuceIndex (int index, long host) + @Override + public void onDeviceOpened (MidiDevice theDevice) { - ArrayList lastDevices = lastDevicesReturned.get().inPorts; + synchronized (MidiDeviceManager.class) + { + MidiDeviceInfo info = theDevice.getInfo(); + int deviceID = info.getId(); + BluetoothGatt gatt = null; + boolean isBluetooth = false; - if (index >= lastDevices.size() || index < 0) - return null; + if (! openTasks.containsKey (deviceID)) + { + if (info.getType() == MidiDeviceInfo.TYPE_BLUETOOTH) + { + isBluetooth = true; + BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); + if (btDevice != null) + { + String btAddress = btDevice.getAddress(); + if (btDevicesPairing.containsKey (btAddress)) + { + gatt = btDevicesPairing.get (btAddress); + btDevicesPairing.remove (btAddress); + } + else + { + // unpair was called in the mean time + try + { + Pair midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); + if (midiDevicePair != null) + { + gatt = midiDevicePair.second; + + if (gatt != null) + { + gatt.disconnect(); + gatt.close(); + } + } + + theDevice.close(); + } + catch (IOException e) + {} + + return; + } + } + } - MidiPortPath path = lastDevices.get (index); - return path.midiDevice.openPort (path.androidMidiPortID, true, host); + MidiDeviceOpenTask openTask = new MidiDeviceOpenTask (this, theDevice, gatt); + openTasks.put (deviceID, openTask); + + new java.util.Timer().schedule (openTask, (isBluetooth ? 2000 : 100)); + } + } } - public JuceMidiPort openMidiOutputPortWithJuceIndex (int index) + public void onDeviceOpenedDelayed (MidiDevice theDevice) { - ArrayList lastDevices = lastDevicesReturned.get().outPorts; + synchronized (MidiDeviceManager.class) + { + int deviceID = theDevice.getInfo().getId(); - if (index >= lastDevices.size() || index < 0) - return null; + if (openTasks.containsKey (deviceID)) + { + if (! midiDevices.contains(theDevice)) + { + BluetoothGatt gatt = openTasks.get (deviceID).getGatt(); + openTasks.remove (deviceID); + midiDevices.add (new Pair (theDevice, gatt)); + } + } + else + { + // unpair was called in the mean time + MidiDeviceInfo info = theDevice.getInfo(); + BluetoothDevice btDevice = (BluetoothDevice) info.getProperties().get (info.PROPERTY_BLUETOOTH_DEVICE); + if (btDevice != null) + { + String btAddress = btDevice.getAddress(); + Pair midiDevicePair = findMidiDeviceForBluetoothAddress (btDevice.getAddress()); + if (midiDevicePair != null) + { + BluetoothGatt gatt = midiDevicePair.second; + + if (gatt != null) + { + gatt.disconnect(); + gatt.close(); + } + } + } - MidiPortPath path = lastDevices.get (index); - return path.midiDevice.openPort (path.androidMidiPortID, false, 0); + try + { + theDevice.close(); + } + catch (IOException e) + {} + } + } } - public String getInputPortNameForJuceIndex (int index) + public String getPortName(MidiPortPath path) { - ArrayList lastDevices = lastDevicesReturned.get().inPorts; + int portTypeToFind = (path.isInput ? MidiDeviceInfo.PortInfo.TYPE_INPUT : MidiDeviceInfo.PortInfo.TYPE_OUTPUT); - if (index >= lastDevices.size() || index < 0) - return ""; - - MidiPortPath path = lastDevices.get (index); + synchronized (MidiDeviceManager.class) + { + for (MidiDeviceInfo info : deviceInfos) + { + int localIndex = 0; + if (info.getId() == path.deviceId) + { + for (MidiDeviceInfo.PortInfo portInfo : info.getPorts()) + { + int portType = portInfo.getType(); + if (portType == portTypeToFind) + { + int portIndex = portInfo.getPortNumber(); + if (portIndex == path.portIndex) + { + String portName = portInfo.getName(); + if (portName.isEmpty()) + portName = (String) info.getProperties().get(info.PROPERTY_NAME); + + return portName; + } + } + } + } + } + } - return path.midiDevice.getHumanReadableNameForPort (MidiDeviceInfo.PortInfo.TYPE_INPUT, - path.androidMidiPortID, - path.portIndexToUseInName); + return ""; } - public String getOutputPortNameForJuceIndex (int index) + public MidiPortPath getPortPathForJuceIndex (int portType, int juceIndex) { - ArrayList lastDevices = lastDevicesReturned.get().outPorts; - - if (index >= lastDevices.size() || index < 0) - return ""; + int portIdx = 0; + for (MidiDeviceInfo info : deviceInfos) + { + for (MidiDeviceInfo.PortInfo portInfo : info.getPorts()) + { + if (portInfo.getType() == portType) + { + if (portIdx == juceIndex) + return new MidiPortPath (info.getId(), + (portType == MidiDeviceInfo.PortInfo.TYPE_INPUT), + portInfo.getPortNumber()); - MidiPortPath path = lastDevices.get (index); + portIdx++; + } + } + } - return path.midiDevice.getHumanReadableNameForPort (MidiDeviceInfo.PortInfo.TYPE_OUTPUT, - path.androidMidiPortID, - path.portIndexToUseInName); + return null; } - public void onDeviceAdded (MidiDeviceInfo info) + private MidiDeviceInfo[] getDeviceInfos() { - PhysicalMidiDevice device = PhysicalMidiDevice.fromMidiDeviceInfo (info, manager); + synchronized (MidiDeviceManager.class) + { + MidiDeviceInfo[] infos = new MidiDeviceInfo[midiDevices.size()]; - // Do not add bluetooth devices as they are already added by the native bluetooth dialog - if (info.getType() != MidiDeviceInfo.TYPE_BLUETOOTH) - physicalMidiDevices.add (device); + int idx = 0; + for (Pair midiDevice : midiDevices) + infos[idx++] = midiDevice.first.getInfo(); + + return infos; + } } - public void onDeviceRemoved (MidiDeviceInfo info) + private Pair getMidiDevicePairForId (int deviceId) { - for (int i = 0; i < physicalMidiDevices.size(); ++i) + synchronized (MidiDeviceManager.class) { - if (physicalMidiDevices.get(i).info.getId() == info.getId()) - { - physicalMidiDevices.remove (i); - return; - } + for (Pair midiDevice : midiDevices) + if (midiDevice.first.getInfo().getId() == deviceId) + return midiDevice; } - // Don't assert here as this may be called again after a bluetooth device is unpaired - } - public void onDeviceStatusChanged (MidiDeviceStatus status) - { + return null; } - private ArrayList physicalMidiDevices; private MidiManager manager; + private HashMap btDevicesPairing; + private HashMap openTasks; + private ArrayList> midiDevices; + private MidiDeviceInfo[] deviceInfos; + private HashMap> openPorts; } public MidiDeviceManager getAndroidMidiDeviceManager() diff --git a/source/modules/juce_core/native/java/AndroidMidiFallback.java b/source/modules/juce_core/native/java/AndroidMidiFallback.java index 416b7348c..5e3d57ff4 100644 --- a/source/modules/juce_core/native/java/AndroidMidiFallback.java +++ b/source/modules/juce_core/native/java/AndroidMidiFallback.java @@ -16,9 +16,13 @@ return address; } - public boolean isBluetoothDevicePaired (String address) + public int getBluetoothDeviceStatus (String address) + { + return 0; + } + + public void startStopScan (boolean shouldStart) { - return false; } public boolean pairBluetoothMidiDevice(String address) diff --git a/source/modules/juce_core/native/java/JuceAppActivity.java b/source/modules/juce_core/native/java/JuceAppActivity.java index 46337f270..aad23e8c9 100644 --- a/source/modules/juce_core/native/java/JuceAppActivity.java +++ b/source/modules/juce_core/native/java/JuceAppActivity.java @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -54,7 +46,10 @@ import android.text.ClipboardManager; import android.text.InputType; import android.util.DisplayMetrics; import android.util.Log; +import android.util.Pair; import java.lang.Runnable; +import java.lang.ref.WeakReference; +import java.lang.reflect.*; import java.util.*; import java.io.*; import java.net.URL; @@ -62,9 +57,17 @@ import java.net.HttpURLConnection; import android.media.AudioManager; import android.media.MediaScannerConnection; import android.media.MediaScannerConnection.MediaScannerConnectionClient; -import android.support.v4.content.ContextCompat; -import android.support.v4.app.ActivityCompat; import android.Manifest; +import java.util.concurrent.CancellationException; +import java.util.concurrent.Future; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.atomic.*; $$JuceAndroidMidiImports$$ // If you get an error here, you need to re-save your project with the Projucer! @@ -104,13 +107,18 @@ public class JuceAppActivity extends Activity // these have to match the values of enum PermissionID in C++ class RuntimePermissions: private static final int JUCE_PERMISSIONS_RECORD_AUDIO = 1; private static final int JUCE_PERMISSIONS_BLUETOOTH_MIDI = 2; + private static final int JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE = 3; + private static final int JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 4; private static String getAndroidPermissionName (int permissionID) { switch (permissionID) { - case JUCE_PERMISSIONS_RECORD_AUDIO: return Manifest.permission.RECORD_AUDIO; - case JUCE_PERMISSIONS_BLUETOOTH_MIDI: return Manifest.permission.ACCESS_COARSE_LOCATION; + case JUCE_PERMISSIONS_RECORD_AUDIO: return Manifest.permission.RECORD_AUDIO; + case JUCE_PERMISSIONS_BLUETOOTH_MIDI: return Manifest.permission.ACCESS_COARSE_LOCATION; + // use string value as this is not defined in SDKs < 16 + case JUCE_PERMISSIONS_READ_EXTERNAL_STORAGE: return "android.permission.READ_EXTERNAL_STORAGE"; + case JUCE_PERMISSIONS_WRITE_EXTERNAL_STORAGE: return Manifest.permission.WRITE_EXTERNAL_STORAGE; } // unknown permission ID! @@ -120,7 +128,7 @@ public class JuceAppActivity extends Activity public boolean isPermissionGranted (int permissionID) { - return ContextCompat.checkSelfPermission (this, getAndroidPermissionName (permissionID)) == PackageManager.PERMISSION_GRANTED; + return getApplicationContext().checkCallingOrSelfPermission (getAndroidPermissionName (permissionID)) == PackageManager.PERMISSION_GRANTED; } private Map permissionCallbackPtrMap; @@ -129,11 +137,11 @@ public class JuceAppActivity extends Activity { String permissionName = getAndroidPermissionName (permissionID); - if (ContextCompat.checkSelfPermission (this, permissionName) != PackageManager.PERMISSION_GRANTED) + if (getApplicationContext().checkCallingOrSelfPermission (permissionName) != PackageManager.PERMISSION_GRANTED) { // remember callbackPtr, request permissions, and let onRequestPermissionResult call callback asynchronously permissionCallbackPtrMap.put (permissionID, ptrToCallback); - ActivityCompat.requestPermissions (this, new String[]{permissionName}, permissionID); + requestPermissionsCompat (new String[]{permissionName}, permissionID); } else { @@ -147,38 +155,6 @@ public class JuceAppActivity extends Activity $$JuceAndroidRuntimePermissionsCode$$ // If you get an error here, you need to re-save your project with the Projucer! //============================================================================== - public static class MidiPortID extends Object - { - public MidiPortID (int index, boolean direction) - { - androidIndex = index; - isInput = direction; - } - - public int androidIndex; - public boolean isInput; - - @Override - public int hashCode() - { - Integer i = new Integer (androidIndex); - return i.hashCode() * (isInput ? -1 : 1); - } - - @Override - public boolean equals (Object obj) - { - if (obj == null) - return false; - - if (getClass() != obj.getClass()) - return false; - - MidiPortID other = (MidiPortID) obj; - return (androidIndex == other.androidIndex && isInput == other.isInput); - } - } - public interface JuceMidiPort { boolean isInputPort(); @@ -188,7 +164,6 @@ public class JuceAppActivity extends Activity void stop(); void close(); - MidiPortID getPortId(); // send will do nothing on an input port void sendMidi (byte[] msg, int offset, int count); @@ -299,6 +274,27 @@ public class JuceAppActivity extends Activity catch (java.lang.reflect.InvocationTargetException e) {} } + void requestPermissionsCompat (String[] permissions, int requestCode) + { + Method requestPermissionsMethod = null; + try + { + requestPermissionsMethod = this.getClass().getMethod ("requestPermissions", + String[].class, int.class); + } + catch (SecurityException e) { return; } + catch (NoSuchMethodException e) { return; } + if (requestPermissionsMethod == null) return; + + try + { + requestPermissionsMethod.invoke (this, permissions, requestCode); + } + catch (java.lang.IllegalArgumentException e) {} + catch (java.lang.IllegalAccessException e) {} + catch (java.lang.reflect.InvocationTargetException e) {} + } + //============================================================================== private native void launchApp (String appFile, String appDataDir); private native void quitApp(); @@ -470,13 +466,14 @@ public class JuceAppActivity extends Activity builder.create().show(); } - public final void showOkCancelBox (String title, String message, final long callback) + public final void showOkCancelBox (String title, String message, final long callback, + String okButtonText, String cancelButtonText) { AlertDialog.Builder builder = new AlertDialog.Builder (this); builder.setTitle (title) .setMessage (message) .setCancelable (true) - .setPositiveButton ("OK", new DialogInterface.OnClickListener() + .setPositiveButton (okButtonText.isEmpty() ? "OK" : okButtonText, new DialogInterface.OnClickListener() { public void onClick (DialogInterface dialog, int id) { @@ -484,7 +481,7 @@ public class JuceAppActivity extends Activity JuceAppActivity.this.alertDismissed (callback, 1); } }) - .setNegativeButton ("Cancel", new DialogInterface.OnClickListener() + .setNegativeButton (cancelButtonText.isEmpty() ? "Cancel" : cancelButtonText, new DialogInterface.OnClickListener() { public void onClick (DialogInterface dialog, int id) { @@ -634,6 +631,7 @@ public class JuceAppActivity extends Activity //============================================================================== private native void handleKeyDown (long host, int keycode, int textchar); private native void handleKeyUp (long host, int keycode, int textchar); + private native void handleBackButton (long host); public void showKeyboard (String type) { @@ -661,8 +659,14 @@ public class JuceAppActivity extends Activity case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: return super.onKeyDown (keyCode, event); + case KeyEvent.KEYCODE_BACK: + { + handleBackButton (host); + return true; + } - default: break; + default: + break; } handleKeyDown (host, keyCode, event.getUnicodeChar()); @@ -735,6 +739,26 @@ public class JuceAppActivity extends Activity public void setViewName (String newName) {} + public void setSystemUiVisibilityCompat (int visibility) + { + Method systemUIVisibilityMethod = null; + try + { + systemUIVisibilityMethod = this.getClass().getMethod ("setSystemUiVisibility", int.class); + } + catch (SecurityException e) { return; } + catch (NoSuchMethodException e) { return; } + if (systemUIVisibilityMethod == null) return; + + try + { + systemUIVisibilityMethod.invoke (this, visibility); + } + catch (java.lang.IllegalArgumentException e) {} + catch (java.lang.IllegalAccessException e) {} + catch (java.lang.reflect.InvocationTargetException e) {} + } + public boolean isVisible() { return getVisibility() == VISIBLE; } public void setVisible (boolean b) { setVisibility (b ? VISIBLE : INVISIBLE); } @@ -822,10 +846,12 @@ public class JuceAppActivity extends Activity } //============================================================================== - public final int[] renderGlyph (char glyph, Paint paint, android.graphics.Matrix matrix, Rect bounds) + public final int[] renderGlyph (char glyph1, char glyph2, Paint paint, android.graphics.Matrix matrix, Rect bounds) { Path p = new Path(); - paint.getTextPath (String.valueOf (glyph), 0, 1, 0.0f, 0.0f, p); + + char[] str = { glyph1, glyph2 }; + paint.getTextPath (str, 0, (glyph2 != 0 ? 2 : 1), 0.0f, 0.0f, p); RectF boundsF = new RectF(); p.computeBounds (boundsF, true); @@ -860,43 +886,136 @@ public class JuceAppActivity extends Activity public static class HTTPStream { public HTTPStream (HttpURLConnection connection_, - int[] statusCode, StringBuffer responseHeaders) throws IOException + int[] statusCode_, + StringBuffer responseHeaders_) { connection = connection_; + statusCode = statusCode_; + responseHeaders = responseHeaders_; + } + + private final InputStream getCancellableStream (final boolean isInput) throws ExecutionException + { + synchronized (createFutureLock) + { + if (hasBeenCancelled.get()) + return null; + + streamFuture = executor.submit (new Callable() + { + @Override + public BufferedInputStream call() throws IOException + { + return new BufferedInputStream (isInput ? connection.getInputStream() + : connection.getErrorStream()); + } + }); + } try { - inputStream = new BufferedInputStream (connection.getInputStream()); + if (connection.getConnectTimeout() > 0) + return streamFuture.get (connection.getConnectTimeout(), TimeUnit.MILLISECONDS); + else + return streamFuture.get(); + } + catch (InterruptedException e) + { + return null; } - catch (IOException e) + catch (TimeoutException e) { - if (connection.getResponseCode() < 400) - throw e; + return null; } - finally + catch (CancellationException e) { - statusCode[0] = connection.getResponseCode(); + return null; } + } - if (statusCode[0] >= 400) - inputStream = connection.getErrorStream(); - else - inputStream = connection.getInputStream(); + public final boolean connect() + { + try + { + try + { + synchronized (createStreamLock) + { + if (hasBeenCancelled.get()) + return false; + + inputStream = getCancellableStream (true); + } + } + catch (ExecutionException e) + { + if (connection.getResponseCode() < 400) + { + statusCode[0] = connection.getResponseCode(); + connection.disconnect(); + return false; + } + } + finally + { + statusCode[0] = connection.getResponseCode(); + } + + synchronized (createStreamLock) + { + if (hasBeenCancelled.get()) + return false; + + try + { + if (statusCode[0] >= 400) + inputStream = getCancellableStream (false); + else + inputStream = getCancellableStream (true); + } + catch (ExecutionException e) + {} + } - for (java.util.Map.Entry> entry : connection.getHeaderFields().entrySet()) - if (entry.getKey() != null && entry.getValue() != null) - responseHeaders.append (entry.getKey() + ": " - + android.text.TextUtils.join (",", entry.getValue()) + "\n"); + for (java.util.Map.Entry> entry : connection.getHeaderFields().entrySet()) + if (entry.getKey() != null && entry.getValue() != null) + responseHeaders.append (entry.getKey() + ": " + + android.text.TextUtils.join (",", entry.getValue()) + "\n"); + + return true; + } + catch (IOException e) + { + return false; + } } public final void release() { + hasBeenCancelled.set (true); + try { - inputStream.close(); + if (! createStreamLock.tryLock()) + { + synchronized (createFutureLock) + { + if (streamFuture != null) + streamFuture.cancel (true); + } + + createStreamLock.lock(); + } + + if (inputStream != null) + inputStream.close(); } catch (IOException e) {} + finally + { + createStreamLock.unlock(); + } connection.disconnect(); } @@ -907,7 +1026,11 @@ public class JuceAppActivity extends Activity try { - num = inputStream.read (buffer, 0, numBytes); + synchronized (createStreamLock) + { + if (inputStream != null) + num = inputStream.read (buffer, 0, numBytes); + } } catch (IOException e) {} @@ -924,8 +1047,16 @@ public class JuceAppActivity extends Activity public final boolean setPosition (long newPos) { return false; } private HttpURLConnection connection; + private int[] statusCode; + private StringBuffer responseHeaders; private InputStream inputStream; private long position; + private final ReentrantLock createStreamLock = new ReentrantLock(); + private final Object createFutureLock = new Object(); + private AtomicBoolean hasBeenCancelled = new AtomicBoolean(); + + private final ExecutorService executor = Executors.newCachedThreadPool (Executors.defaultThreadFactory()); + Future streamFuture; } public static final HTTPStream createHTTPStream (String address, boolean isPost, byte[] postData, @@ -1038,8 +1169,8 @@ public class JuceAppActivity extends Activity { java.util.Locale locale = java.util.Locale.getDefault(); - return isRegion ? locale.getDisplayCountry (java.util.Locale.US) - : locale.getDisplayLanguage (java.util.Locale.US); + return isRegion ? locale.getCountry() + : locale.getLanguage(); } private static final String getFileLocation (String type) @@ -1199,36 +1330,8 @@ public class JuceAppActivity extends Activity return null; } - public final int setCurrentThreadPriority (int priority) - { - android.os.Process.setThreadPriority (android.os.Process.myTid(), priority); - return android.os.Process.getThreadPriority (android.os.Process.myTid()); - } - public final boolean hasSystemFeature (String property) { return getPackageManager().hasSystemFeature (property); } - - private static class JuceThread extends Thread - { - public JuceThread (long host, String threadName, long threadStackSize) - { - super (null, null, threadName, threadStackSize); - _this = host; - } - - public void run() - { - runThread(_this); - } - - private native void runThread (long host); - private long _this; - } - - public final Thread createNewThread(long host, String threadName, long threadStackSize) - { - return new JuceThread(host, threadName, threadStackSize); - } } diff --git a/source/modules/juce_core/native/juce_BasicNativeHeaders.h b/source/modules/juce_core/native/juce_BasicNativeHeaders.h index 477e638ab..9ce110c7e 100644 --- a/source/modules/juce_core/native/juce_BasicNativeHeaders.h +++ b/source/modules/juce_core/native/juce_BasicNativeHeaders.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BASICNATIVEHEADERS_H_INCLUDED -#define JUCE_BASICNATIVEHEADERS_H_INCLUDED +#pragma once #undef T @@ -122,6 +113,7 @@ #define NOMINMAX + #define _WINSOCK_DEPRECATED_NO_WARNINGS 1 #define STRICT 1 #define WIN32_LEAN_AND_MEAN 1 #if JUCE_MINGW @@ -142,6 +134,8 @@ #include #include #include + #include + #include #include #include #include @@ -169,7 +163,7 @@ #if JUCE_MSVC #pragma warning (pop) - #pragma warning (4: 4511 4512 4100 /*4365*/) // (enable some warnings that are turned off in VC8) + #pragma warning (4: 4511 4512 4100) #endif #if JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES @@ -258,6 +252,11 @@ #include #include #include + #include + + // If you are getting include errors here, then you to re-build the Projucer + // and re-save your .jucer file. + #include #endif // Need to clear various moronic redefinitions made by system headers.. @@ -265,5 +264,3 @@ #undef min #undef direct #undef check - -#endif // JUCE_BASICNATIVEHEADERS_H_INCLUDED diff --git a/source/modules/juce_core/native/juce_android_Files.cpp b/source/modules/juce_core/native/juce_android_Files.cpp index 6d5890c0e..a6afc4a09 100644 --- a/source/modules/juce_core/native/juce_android_Files.cpp +++ b/source/modules/juce_core/native/juce_android_Files.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -45,7 +37,7 @@ bool File::isOnRemovableDrive() const String File::getVersion() const { - return String(); + return {}; } static File getSpecialFile (jmethodID type) @@ -86,7 +78,7 @@ File File::getSpecialLocation (const SpecialLocationType type) break; } - return File(); + return {}; } bool File::moveToTrash() const @@ -98,7 +90,7 @@ bool File::moveToTrash() const return false; } -JUCE_API bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String& parameters) +JUCE_API bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String&) { const LocalRef t (javaString (fileName)); android.activity.callVoidMethod (JuceAppActivity.launchURL, t.get()); diff --git a/source/modules/juce_core/native/juce_android_JNIHelpers.h b/source/modules/juce_core/native/juce_android_JNIHelpers.h index dfb637c54..a7742dcd7 100644 --- a/source/modules/juce_core/native/juce_android_JNIHelpers.h +++ b/source/modules/juce_core/native/juce_android_JNIHelpers.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ANDROID_JNIHELPERS_H_INCLUDED -#define JUCE_ANDROID_JNIHELPERS_H_INCLUDED +#pragma once #if ! (defined (JUCE_ANDROID_ACTIVITY_CLASSNAME) && defined (JUCE_ANDROID_ACTIVITY_CLASSPATH)) #error "The JUCE_ANDROID_ACTIVITY_CLASSNAME and JUCE_ANDROID_ACTIVITY_CLASSPATH macros must be set!" @@ -42,6 +33,9 @@ extern JNIEnv* getEnv() noexcept; // on a java thread which you did not create yourself. extern void setEnv (JNIEnv* env) noexcept; +/* @internal */ +extern JNIEnv* attachAndroidJNI() noexcept; + //============================================================================== class GlobalRef { @@ -150,7 +144,7 @@ private: //============================================================================== namespace { - String juceString (JNIEnv* env, jstring s) + inline String juceString (JNIEnv* env, jstring s) { const char* const utf8 = env->GetStringUTFChars (s, nullptr); CharPointer_UTF8 utf8CP (utf8); @@ -159,17 +153,17 @@ namespace return result; } - String juceString (jstring s) + inline String juceString (jstring s) { return juceString (getEnv(), s); } - LocalRef javaString (const String& s) + inline LocalRef javaString (const String& s) { return LocalRef (getEnv()->NewStringUTF (s.toUTF8())); } - LocalRef javaStringFromChar (const juce_wchar c) + inline LocalRef javaStringFromChar (const juce_wchar c) { char utf8[8] = { 0 }; CharPointer_UTF8 (utf8).write (c); @@ -224,10 +218,11 @@ private: \ void initialiseFields (JNIEnv* env) \ { \ + ignoreUnused (env); \ JNI_CLASS_MEMBERS (CREATE_JNI_METHOD, CREATE_JNI_STATICMETHOD, CREATE_JNI_FIELD, CREATE_JNI_STATICFIELD); \ } \ \ - JNI_CLASS_MEMBERS (DECLARE_JNI_METHOD, DECLARE_JNI_METHOD, DECLARE_JNI_FIELD, DECLARE_JNI_FIELD); \ + JNI_CLASS_MEMBERS (DECLARE_JNI_METHOD, DECLARE_JNI_METHOD, DECLARE_JNI_FIELD, DECLARE_JNI_FIELD) \ }; \ static CppClassName ## _Class CppClassName; @@ -272,11 +267,11 @@ extern AndroidSystem android; METHOD (getClipboardContent, "getClipboardContent", "()Ljava/lang/String;") \ METHOD (setClipboardContent, "setClipboardContent", "(Ljava/lang/String;)V") \ METHOD (excludeClipRegion, "excludeClipRegion", "(Landroid/graphics/Canvas;FFFF)V") \ - METHOD (renderGlyph, "renderGlyph", "(CLandroid/graphics/Paint;Landroid/graphics/Matrix;Landroid/graphics/Rect;)[I") \ + METHOD (renderGlyph, "renderGlyph", "(CCLandroid/graphics/Paint;Landroid/graphics/Matrix;Landroid/graphics/Rect;)[I") \ STATICMETHOD (createHTTPStream, "createHTTPStream", "(Ljava/lang/String;Z[BLjava/lang/String;I[ILjava/lang/StringBuffer;ILjava/lang/String;)L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$HTTPStream;") \ METHOD (launchURL, "launchURL", "(Ljava/lang/String;)V") \ METHOD (showMessageBox, "showMessageBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \ - METHOD (showOkCancelBox, "showOkCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \ + METHOD (showOkCancelBox, "showOkCancelBox", "(Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;Ljava/lang/String;)V") \ METHOD (showYesNoCancelBox, "showYesNoCancelBox", "(Ljava/lang/String;Ljava/lang/String;J)V") \ STATICMETHOD (getLocaleValue, "getLocaleValue", "(Z)Ljava/lang/String;") \ STATICMETHOD (getDocumentsFolder, "getDocumentsFolder", "()Ljava/lang/String;") \ @@ -293,12 +288,11 @@ extern AndroidSystem android; METHOD (getAndroidBluetoothManager, "getAndroidBluetoothManager", "()L" JUCE_ANDROID_ACTIVITY_CLASSPATH "$BluetoothManager;") \ METHOD (getAndroidSDKVersion, "getAndroidSDKVersion", "()I") \ METHOD (audioManagerGetProperty, "audioManagerGetProperty", "(Ljava/lang/String;)Ljava/lang/String;") \ - METHOD (setCurrentThreadPriority, "setCurrentThreadPriority", "(I)I") \ METHOD (hasSystemFeature, "hasSystemFeature", "(Ljava/lang/String;)Z" ) \ - METHOD (createNewThread, "createNewThread", "(JLjava/lang/String;J)Ljava/lang/Thread;") \ METHOD (requestRuntimePermission, "requestRuntimePermission", "(IJ)V" ) \ METHOD (isPermissionGranted, "isPermissionGranted", "(I)Z" ) \ METHOD (isPermissionDeclaredInManifest, "isPermissionDeclaredInManifest", "(I)Z" ) \ + METHOD (getSystemService, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;") \ DECLARE_JNI_CLASS (JuceAppActivity, JUCE_ANDROID_ACTIVITY_CLASSPATH); #undef JNI_CLASS_MEMBERS @@ -328,19 +322,6 @@ DECLARE_JNI_CLASS (Paint, "android/graphics/Paint"); DECLARE_JNI_CLASS (Matrix, "android/graphics/Matrix"); #undef JNI_CLASS_MEMBERS -//============================================================================== -#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ - METHOD (start, "start", "()V") \ - METHOD (stop, "stop", "()V") \ - METHOD (setName, "setName", "(Ljava/lang/String;)V") \ - METHOD (getName, "getName", "()Ljava/lang/String;") \ - METHOD (getId, "getId", "()J") \ - STATICMETHOD (currentThread, "currentThread", "()Ljava/lang/Thread;") \ - METHOD (setPriority, "setPriority", "(I)V") \ - -DECLARE_JNI_CLASS (JuceThread, "java/lang/Thread"); -#undef JNI_CLASS_MEMBERS - //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ METHOD (constructor, "", "(IIII)V") \ @@ -351,5 +332,3 @@ DECLARE_JNI_CLASS (JuceThread, "java/lang/Thread"); DECLARE_JNI_CLASS (RectClass, "android/graphics/Rect"); #undef JNI_CLASS_MEMBERS - -#endif // JUCE_ANDROID_JNIHELPERS_H_INCLUDED diff --git a/source/modules/juce_core/native/juce_android_Misc.cpp b/source/modules/juce_core/native/juce_android_Misc.cpp index e49118437..4a0f8189f 100644 --- a/source/modules/juce_core/native/juce_android_Misc.cpp +++ b/source/modules/juce_core/native/juce_android_Misc.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/native/juce_android_Network.cpp b/source/modules/juce_core/native/juce_android_Network.cpp index 83ba4dc9e..76b3780a4 100644 --- a/source/modules/juce_core/native/juce_android_Network.cpp +++ b/source/modules/juce_core/native/juce_android_Network.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -38,6 +30,7 @@ DECLARE_JNI_CLASS (StringBuffer, "java/lang/StringBuffer"); //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ + METHOD (connect, "connect", "()Z") \ METHOD (release, "release", "()V") \ METHOD (read, "read", "([BI)I") \ METHOD (getPosition, "getPosition", "()J") \ @@ -50,35 +43,28 @@ DECLARE_JNI_CLASS (HTTPStream, JUCE_ANDROID_ACTIVITY_CLASSPATH "$HTTPStream"); //============================================================================== -void MACAddress::findAllAddresses (Array& result) +void MACAddress::findAllAddresses (Array& /*result*/) { // TODO } -JUCE_API bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& targetEmailAddress, - const String& emailSubject, - const String& bodyText, - const StringArray& filesToAttach) +JUCE_API bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& /*targetEmailAddress*/, + const String& /*emailSubject*/, + const String& /*bodyText*/, + const StringArray& /*filesToAttach*/) { // TODO return false; } -/* Pimpl (String address, bool isPost, const MemoryBlock& postData, - URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, - const String& headers, int timeOutMs, StringPairArray* responseHeaders, - const int numRedirectsToFollow, const String& httpRequest) - : statusCode (0) - -*/ //============================================================================== class WebInputStream::Pimpl { public: - Pimpl (WebInputStream& pimplOwner, const URL& urlToCopy, bool shouldBePost) - : statusCode (0), owner (pimplOwner), url (urlToCopy), isPost (shouldBePost), - numRedirectsToFollow (5), timeOutMs (0), httpRequest (isPost ? "POST" : "GET") + Pimpl (WebInputStream&, const URL& urlToCopy, bool shouldBePost) + : url (urlToCopy), isPost (shouldBePost), + httpRequest (isPost ? "POST" : "GET") {} ~Pimpl() @@ -88,14 +74,18 @@ public: void cancel() { + const ScopedLock lock (createStreamLock); + if (stream != 0) { stream.callVoidMethod (HTTPStream.release); stream.clear(); } + + hasBeenCancelled = true; } - bool connect (WebInputStream::Listener* listener) + bool connect (WebInputStream::Listener* /*listener*/) { String address = url.toString (! isPost); @@ -112,8 +102,8 @@ public: if (postData.getSize() > 0) { - postDataArray = env->NewByteArray (postData.getSize()); - env->SetByteArrayRegion (postDataArray, 0, postData.getSize(), (const jbyte*) postData.getData()); + postDataArray = env->NewByteArray (static_cast (postData.getSize())); + env->SetByteArrayRegion (postDataArray, 0, static_cast (postData.getSize()), (const jbyte*) postData.getData()); } LocalRef responseHeaderBuffer (env->NewObject (StringBuffer, StringBuffer.constructor)); @@ -125,17 +115,25 @@ public: jintArray statusCodeArray = env->NewIntArray (1); jassert (statusCodeArray != 0); - stream = GlobalRef (env->CallStaticObjectMethod (JuceAppActivity, - JuceAppActivity.createHTTPStream, - javaString (address).get(), - (jboolean) isPost, - postDataArray, - javaString (headers).get(), - (jint) timeOutMs, - statusCodeArray, - responseHeaderBuffer.get(), - (jint) numRedirectsToFollow, - javaString (httpRequest).get())); + { + const ScopedLock lock (createStreamLock); + + if (! hasBeenCancelled) + stream = GlobalRef (env->CallStaticObjectMethod (JuceAppActivity, + JuceAppActivity.createHTTPStream, + javaString (address).get(), + (jboolean) isPost, + postDataArray, + javaString (headers).get(), + (jint) timeOutMs, + statusCodeArray, + responseHeaderBuffer.get(), + (jint) numRedirectsToFollow, + javaString (httpRequest).get())); + } + + if (stream != 0) + stream.callBooleanMethod (HTTPStream.connect); jint* const statusCodeElements = env->GetIntArrayElements (statusCodeArray, 0); statusCode = statusCodeElements[0]; @@ -220,15 +218,16 @@ public: } //============================================================================== - int statusCode; + int statusCode = 0; private: - WebInputStream& owner; const URL url; bool isPost; - int numRedirectsToFollow, timeOutMs; + int numRedirectsToFollow = 5, timeOutMs = 0; String httpRequest, headers; StringPairArray responseHeaders; + CriticalSection createStreamLock; + bool hasBeenCancelled = false; GlobalRef stream; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) @@ -238,3 +237,62 @@ URL::DownloadTask* URL::downloadToFile (const File& targetLocation, String extra { return URL::DownloadTask::createFallbackDownloader (*this, targetLocation, extraHeaders, listener); } + +//============================================================================== +static void addAddress (const sockaddr_in* addr_in, Array& result) +{ + in_addr_t addr = addr_in->sin_addr.s_addr; + + if (addr != INADDR_NONE) + result.addIfNotAlreadyThere (IPAddress (ntohl (addr))); +} + +static void findIPAddresses (int sock, Array& result) +{ + ifconf cfg; + HeapBlock buffer; + int bufferSize = 1024; + + do + { + bufferSize *= 2; + buffer.calloc ((size_t) bufferSize); + + cfg.ifc_len = bufferSize; + cfg.ifc_buf = buffer; + + if (ioctl (sock, SIOCGIFCONF, &cfg) < 0 && errno != EINVAL) + return; + + } while (bufferSize < cfg.ifc_len + 2 * (int) (IFNAMSIZ + sizeof (struct sockaddr_in6))); + + #if JUCE_MAC || JUCE_IOS + while (cfg.ifc_len >= (int) (IFNAMSIZ + sizeof (struct sockaddr_in))) + { + if (cfg.ifc_req->ifr_addr.sa_family == AF_INET) // Skip non-internet addresses + addAddress ((const sockaddr_in*) &cfg.ifc_req->ifr_addr, result); + + cfg.ifc_len -= IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len; + cfg.ifc_buf += IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len; + } + #else + for (size_t i = 0; i < (size_t) cfg.ifc_len / (size_t) sizeof (struct ifreq); ++i) + { + const ifreq& item = cfg.ifc_req[i]; + + if (item.ifr_addr.sa_family == AF_INET) + addAddress ((const sockaddr_in*) &item.ifr_addr, result); + } + #endif +} + +void IPAddress::findAllAddresses (Array& result, bool /*includeIPv6*/) +{ + const int sock = socket (AF_INET, SOCK_DGRAM, 0); // a dummy socket to execute the IO control + + if (sock >= 0) + { + findIPAddresses (sock, result); + ::close (sock); + } +} diff --git a/source/modules/juce_core/native/juce_android_RuntimePermissions.cpp b/source/modules/juce_core/native/juce_android_RuntimePermissions.cpp index 403fdfaeb..155cffc74 100644 --- a/source/modules/juce_core/native/juce_android_RuntimePermissions.cpp +++ b/source/modules/juce_core/native/juce_android_RuntimePermissions.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -40,7 +32,9 @@ namespace } std::unique_ptr uptr (callbackPtr); - (*uptr) (permissionWasGranted); + + if (RuntimePermissions::Callback callbackObj = *uptr) + callbackObj (permissionWasGranted); } } diff --git a/source/modules/juce_core/native/juce_android_SystemStats.cpp b/source/modules/juce_core/native/juce_android_SystemStats.cpp index 711f422a9..8a8e77291 100644 --- a/source/modules/juce_core/native/juce_android_SystemStats.cpp +++ b/source/modules/juce_core/native/juce_android_SystemStats.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -100,23 +92,104 @@ jfieldID JNIClassBase::resolveStaticField (JNIEnv* env, const char* fieldName, c } //============================================================================== -ThreadLocalValue androidJNIEnv; +JavaVM* androidJNIJavaVM = nullptr; -JNIEnv* getEnv() noexcept +class JniEnvThreadHolder { - JNIEnv* env = androidJNIEnv.get(); - jassert (env != nullptr); +public: + static JniEnvThreadHolder& getInstance() noexcept + { + // You cann only use JNI functions AFTER JNI_OnLoad was called + jassert (androidJNIJavaVM != nullptr); + + try + { + if (instance == nullptr) + instance = new JniEnvThreadHolder; + } + catch (...) + { + jassertfalse; + std::terminate(); + } + + return *instance; + } + + static JNIEnv* getEnv() { return reinterpret_cast (pthread_getspecific (getInstance().threadKey)); } + + static void setEnv (JNIEnv* env) + { + // env must not be a nullptr + jassert (env != nullptr); + + #if JUCE_DEBUG + JNIEnv* oldenv = reinterpret_cast (pthread_getspecific (getInstance().threadKey)); + + // This thread is already attached to the JavaVM and you trying to attach + // it to a different instance of the VM. + jassert (oldenv == nullptr || oldenv == env); + #endif + + pthread_setspecific (getInstance().threadKey, env); + } + +private: + pthread_key_t threadKey; + + static void threadDetach (void* p) + { + if (JNIEnv* env = reinterpret_cast (p)) + { + ignoreUnused (env); + + androidJNIJavaVM->DetachCurrentThread(); + } + } + + JniEnvThreadHolder() + { + pthread_key_create (&threadKey, threadDetach); + } + + static JniEnvThreadHolder* instance; +}; + +JniEnvThreadHolder* JniEnvThreadHolder::instance = nullptr; + +//============================================================================== +JNIEnv* attachAndroidJNI() noexcept +{ + auto* env = JniEnvThreadHolder::getEnv(); + + if (env == nullptr) + { + androidJNIJavaVM->AttachCurrentThread (&env, nullptr); + setEnv (env); + } return env; } -void setEnv (JNIEnv* env) noexcept +JNIEnv* getEnv() noexcept { - androidJNIEnv.get() = env; + auto* env = JniEnvThreadHolder::getEnv(); + + // You are trying to use a JUCE function on a thread that was not created by JUCE. + // You need to first call setEnv on this thread before using JUCE + jassert (env != nullptr); + + return env; } -extern "C" jint JNI_OnLoad (JavaVM*, void*) +void setEnv (JNIEnv* env) noexcept { JniEnvThreadHolder::setEnv (env); } + +extern "C" jint JNI_OnLoad (JavaVM* vm, void*) { + // Huh? JNI_OnLoad was called two times! + jassert (androidJNIJavaVM == nullptr); + + androidJNIJavaVM = vm; return JNI_VERSION_1_2; } @@ -127,6 +200,8 @@ AndroidSystem::AndroidSystem() : screenWidth (0), screenHeight (0), dpi (160) void AndroidSystem::initialise (JNIEnv* env, jobject act, jstring file, jstring dataDir) { + setEnv (env); + screenWidth = screenHeight = 0; dpi = 160; JNIClassBase::initialiseAllClasses (env); @@ -154,14 +229,14 @@ namespace AndroidStatsHelpers DECLARE_JNI_CLASS (SystemClass, "java/lang/System"); #undef JNI_CLASS_MEMBERS - String getSystemProperty (const String& name) + static inline String getSystemProperty (const String& name) { return juceString (LocalRef ((jstring) getEnv()->CallStaticObjectMethod (SystemClass, SystemClass.getProperty, javaString (name).get()))); } - String getLocaleValue (bool isRegion) + static inline String getLocaleValue (bool isRegion) { return juceString (LocalRef ((jstring) getEnv()->CallStaticObjectMethod (JuceAppActivity, JuceAppActivity.getLocaleValue, @@ -172,7 +247,7 @@ namespace AndroidStatsHelpers DECLARE_JNI_CLASS (BuildClass, "android/os/Build"); #undef JNI_CLASS_MEMBERS - String getAndroidOsBuildValue (const char* fieldName) + static inline String getAndroidOsBuildValue (const char* fieldName) { return juceString (LocalRef ((jstring) getEnv()->GetStaticObjectField ( BuildClass, getEnv()->GetStaticFieldID (BuildClass, fieldName, "Ljava/lang/String;")))); @@ -210,9 +285,25 @@ String SystemStats::getCpuVendor() return AndroidStatsHelpers::getSystemProperty ("os.arch"); } +String SystemStats::getCpuModel() +{ + return readPosixConfigFileValue ("/proc/cpuinfo", "Hardware"); +} + int SystemStats::getCpuSpeedInMegaherz() { - return 0; // TODO + int maxFreqKHz = 0; + + for (int i = 0; i < getNumCpus(); ++i) + { + int freqKHz = File ("/sys/devices/system/cpu/cpu" + String(i) + "/cpufreq/cpuinfo_max_freq") + .loadFileAsString() + .getIntValue(); + + maxFreqKHz = jmax (freqKHz, maxFreqKHz); + } + + return maxFreqKHz / 1000; } int SystemStats::getMemorySizeInMegabytes() @@ -221,7 +312,7 @@ int SystemStats::getMemorySizeInMegabytes() struct sysinfo sysi; if (sysinfo (&sysi) == 0) - return (sysi.totalram * sysi.mem_unit / (1024 * 1024)); + return (static_cast (sysi.totalram * sysi.mem_unit) / (1024 * 1024)); #endif return 0; @@ -229,7 +320,7 @@ int SystemStats::getMemorySizeInMegabytes() int SystemStats::getPageSize() { - return sysconf (_SC_PAGESIZE); + return static_cast (sysconf (_SC_PAGESIZE)); } //============================================================================== @@ -241,7 +332,7 @@ String SystemStats::getLogonName() if (struct passwd* const pw = getpwuid (getuid())) return CharPointer_UTF8 (pw->pw_name); - return String(); + return {}; } String SystemStats::getFullUserName() @@ -255,7 +346,7 @@ String SystemStats::getComputerName() if (gethostname (name, sizeof (name) - 1) == 0) return name; - return String(); + return {}; } @@ -266,7 +357,36 @@ String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getU //============================================================================== void CPUInformation::initialise() noexcept { - numCpus = jmax ((int) 1, (int) sysconf (_SC_NPROCESSORS_ONLN)); + numPhysicalCPUs = numLogicalCPUs = jmax ((int) 1, (int) android_getCpuCount()); + + auto cpuFamily = android_getCpuFamily(); + auto cpuFeatures = android_getCpuFeatures(); + + if (cpuFamily == ANDROID_CPU_FAMILY_X86 || cpuFamily == ANDROID_CPU_FAMILY_X86_64) + { + hasMMX = hasSSE = hasSSE2 = (cpuFamily == ANDROID_CPU_FAMILY_X86_64); + + hasSSSE3 = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_SSSE3) != 0); + hasSSE41 = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_SSE4_1) != 0); + hasSSE42 = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_SSE4_2) != 0); + hasAVX = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_AVX) != 0); + hasAVX2 = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_AVX2) != 0); + + // Google does not distinguish between MMX, SSE, SSE2, SSE3 and SSSE3. So + // I assume (and quick Google searches seem to confirm this) that there are + // only devices out there that either support all of this or none of this. + if (hasSSSE3) + hasMMX = hasSSE = hasSSE2 = hasSSE3 = true; + } + else if (cpuFamily == ANDROID_CPU_FAMILY_ARM) + { + hasNeon = ((cpuFeatures & ANDROID_CPU_ARM_FEATURE_NEON) != 0); + } + else if (cpuFamily == ANDROID_CPU_FAMILY_ARM64) + { + // all arm 64-bit cpus have neon + hasNeon = true; + } } //============================================================================== @@ -275,7 +395,7 @@ uint32 juce_millisecondsSinceStartup() noexcept timespec t; clock_gettime (CLOCK_MONOTONIC, &t); - return t.tv_sec * 1000 + t.tv_nsec / 1000000; + return static_cast (t.tv_sec) * 1000U + static_cast (t.tv_nsec) / 1000000U; } int64 Time::getHighResolutionTicks() noexcept diff --git a/source/modules/juce_core/native/juce_android_Threads.cpp b/source/modules/juce_core/native/juce_android_Threads.cpp index 1145dbc42..7a526e450 100644 --- a/source/modules/juce_core/native/juce_android_Threads.cpp +++ b/source/modules/juce_core/native/juce_android_Threads.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -66,239 +58,15 @@ JUCE_API void JUCE_CALLTYPE Process::setPriority (ProcessPriority prior) JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() noexcept { + StringArray lines; + File ("/proc/self/status").readLines (lines); + + for (int i = lines.size(); --i >= 0;) // (NB - it's important that this runs in reverse order) + if (lines[i].upToFirstOccurrenceOf (":", false, false).trim().equalsIgnoreCase ("TracerPid")) + return (lines[i].fromFirstOccurrenceOf (":", false, false).trim().getIntValue() > 0); + return false; } JUCE_API void JUCE_CALLTYPE Process::raisePrivilege() {} JUCE_API void JUCE_CALLTYPE Process::lowerPrivilege() {} - -struct AndroidThreadData -{ - AndroidThreadData (Thread* thread) noexcept - : owner (thread), tId (0) - { - } - - Thread* owner; - Thread::ThreadID tId; - WaitableEvent eventSet, eventGet; -}; - -void JUCE_API juce_threadEntryPoint (void*); - -void* threadEntryProc (AndroidThreadData* priv) -{ - priv->tId = (Thread::ThreadID) pthread_self(); - priv->eventSet.signal(); - priv->eventGet.wait (-1); - - juce_threadEntryPoint (priv->owner); - - return nullptr; -} - -JUCE_JNI_CALLBACK (JUCE_JOIN_MACRO (JUCE_ANDROID_ACTIVITY_CLASSNAME, _00024JuceThread), runThread, - void, (JNIEnv* env, jobject device, jlong host)) -{ - // This thread does not have a JNIEnv assigned to it yet. So assign it now. - setEnv (env); - - if (AndroidThreadData* thread = reinterpret_cast (host)) - threadEntryProc (thread); -} - -void Thread::launchThread() -{ - threadHandle = 0; - - ScopedPointer threadPrivateData = new AndroidThreadData (this); - const LocalRef jName (javaString (threadName)); - - jobject juceNewThread = android.activity.callObjectMethod (JuceAppActivity.createNewThread, - (jlong) threadPrivateData.get(), - jName.get(), (jlong) threadStackSize); - - if (jobject juceThread = getEnv()->NewGlobalRef (juceNewThread)) - { - AndroidThreadData* priv = threadPrivateData.release(); - - threadHandle = (void*) juceThread; - getEnv()->CallVoidMethod (juceThread, JuceThread.start); - - priv->eventSet.wait (-1); - threadId = priv->tId; - priv->eventGet.signal(); - } -} - -void Thread::closeThreadHandle() -{ - if (threadHandle != 0) - { - jobject juceThread = reinterpret_cast (threadHandle); - getEnv()->DeleteGlobalRef (juceThread); - threadHandle = 0; - } - - threadId = 0; -} - -void Thread::killThread() -{ - if (threadHandle != 0) - { - jobject juceThread = reinterpret_cast (threadHandle); - getEnv()->CallVoidMethod (juceThread, JuceThread.stop); - } -} - -void JUCE_CALLTYPE Thread::setCurrentThreadName (const String& name) -{ - LocalRef juceThread (getEnv()->CallStaticObjectMethod (JuceThread, JuceThread.currentThread)); - - if (jobject t = juceThread.get()) - getEnv()->CallVoidMethod (t, JuceThread.setName, javaString (name).get()); -} - -bool Thread::setThreadPriority (void* handle, int priority) -{ - if (handle == nullptr) - { - LocalRef juceThread (getEnv()->CallStaticObjectMethod (JuceThread, JuceThread.currentThread)); - - if (jobject t = juceThread.get()) - return setThreadPriority (t, priority); - - return false; - } - - jobject juceThread = reinterpret_cast (handle); - - const int minPriority = 1; - const int maxPriority = 10; - - jint javaPriority = ((maxPriority - minPriority) * priority) / 10 + minPriority; - - getEnv()->CallVoidMethod (juceThread, JuceThread.setPriority, javaPriority); - - return true; -} - -//============================================================================== -struct HighResolutionTimer::Pimpl -{ - struct HighResolutionThread : public Thread - { - HighResolutionThread (HighResolutionTimer::Pimpl& parent) - : Thread ("High Resolution Timer"), pimpl (parent) - { - startThread(); - } - - void run() override - { - pimpl.timerThread(); - } - - private: - HighResolutionTimer::Pimpl& pimpl; - }; - - //============================================================================== - Pimpl (HighResolutionTimer& t) : owner (t) {} - - ~Pimpl() - { - stop(); - } - - void start (int newPeriod) - { - if (periodMs != newPeriod) - { - if (thread.get() == nullptr - || thread->getThreadId() != Thread::getCurrentThreadId() - || thread->threadShouldExit()) - { - stop(); - - periodMs = newPeriod; - - thread = new HighResolutionThread (*this); - } - else - { - periodMs = newPeriod; - } - } - } - - void stop() - { - if (thread.get() != nullptr) - { - thread->signalThreadShouldExit(); - - if (thread->getThreadId() != Thread::getCurrentThreadId()) - { - thread->waitForThreadToExit (-1); - thread = nullptr; - } - } - } - - HighResolutionTimer& owner; - int volatile periodMs; - -private: - ScopedPointer thread; - - void timerThread() - { - jassert (thread.get() != nullptr); - - int lastPeriod = periodMs; - Clock clock (lastPeriod); - - while (! thread->threadShouldExit()) - { - clock.wait(); - owner.hiResTimerCallback(); - - if (lastPeriod != periodMs) - { - lastPeriod = periodMs; - clock = Clock (lastPeriod); - } - } - - periodMs = 0; - } - - struct Clock - { - Clock (double millis) noexcept : delta ((uint64) (millis * 1000000)) - { - } - - void wait() noexcept - { - struct timespec t; - t.tv_sec = (time_t) (delta / 1000000000); - t.tv_nsec = (long) (delta % 1000000000); - nanosleep (&t, nullptr); - } - - uint64 delta; - }; - - static bool setThreadToRealtime (pthread_t thread, uint64 periodMs) - { - ignoreUnused (periodMs); - struct sched_param param; - param.sched_priority = sched_get_priority_max (SCHED_RR); - return pthread_setschedparam (thread, SCHED_RR, ¶m) == 0; - } - - JUCE_DECLARE_NON_COPYABLE (Pimpl) -}; diff --git a/source/modules/juce_core/native/juce_curl_Network.cpp b/source/modules/juce_core/native/juce_curl_Network.cpp index 9b54feaf7..50c192e1c 100644 --- a/source/modules/juce_core/native/juce_curl_Network.cpp +++ b/source/modules/juce_core/native/juce_curl_Network.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -32,16 +24,21 @@ class WebInputStream::Pimpl { public: Pimpl (WebInputStream& ownerStream, const URL& urlToCopy, bool shouldUsePost) - : owner (ownerStream), url (urlToCopy), - multi (nullptr), curl (nullptr), headerList (nullptr), lastError (CURLE_OK), - timeOutMs (0), maxRedirects (5), isPost (shouldUsePost), - httpRequest (isPost ? "POST" : "GET"), - contentLength (-1), streamPos (0), statusCode (-1), - finished (false), skipBytes (0), - postBuffer (nullptr), postPosition (0), listener (nullptr) + : owner (ownerStream), url (urlToCopy), isPost (shouldUsePost), + httpRequest (isPost ? "POST" : "GET") { - if (! init()) - cleanup(); + multi = curl_multi_init(); + + if (multi != nullptr) + { + curl = curl_easy_init(); + + if (curl != nullptr) + if (curl_multi_add_handle (multi, curl) == CURLM_OK) + return; + } + + cleanup(); } ~Pimpl() @@ -97,25 +94,10 @@ public: int getStatusCode() const { return statusCode; } //============================================================================== - bool init() - { - multi = curl_multi_init(); - - if (multi != nullptr) - { - curl = curl_easy_init(); - - if (curl != nullptr) - if (curl_multi_add_handle (multi, curl) == CURLM_OK) - return true; - } - - cleanup(); - return false; - } - void cleanup() { + const ScopedLock lock (cleanupLock); + if (curl != nullptr) { curl_multi_remove_handle (multi, curl); @@ -143,7 +125,7 @@ public: } //============================================================================== - bool setOptions () + bool setOptions() { const String address = url.toString (! isPost); @@ -209,38 +191,45 @@ public: bool connect (WebInputStream::Listener* webInputListener) { - if (! setOptions ()) { - cleanup(); - return false; - } - - listener = webInputListener; + const ScopedLock lock (cleanupLock); - if (requestHeaders.isNotEmpty()) - { - const StringArray headerLines = StringArray::fromLines (requestHeaders); - - // fromLines will always return at least one line if the string is not empty - jassert (headerLines.size() > 0); - headerList = curl_slist_append (headerList, headerLines [0].toRawUTF8()); - - for (int i = 1; (i < headerLines.size() && headerList != nullptr); ++i) - headerList = curl_slist_append (headerList, headerLines [i].toRawUTF8()); + if (curl == nullptr) + return false; - if (headerList == nullptr) + if (! setOptions()) { cleanup(); return false; } - if (curl_easy_setopt (curl, CURLOPT_HTTPHEADER, headerList) != CURLE_OK) + if (requestHeaders.isNotEmpty()) { - cleanup(); - return false; + const StringArray headerLines = StringArray::fromLines (requestHeaders); + + // fromLines will always return at least one line if the string is not empty + jassert (headerLines.size() > 0); + headerList = curl_slist_append (headerList, headerLines [0].toRawUTF8()); + + for (int i = 1; (i < headerLines.size() && headerList != nullptr); ++i) + headerList = curl_slist_append (headerList, headerLines [i].toRawUTF8()); + + if (headerList == nullptr) + { + cleanup(); + return false; + } + + if (curl_easy_setopt (curl, CURLOPT_HTTPHEADER, headerList) != CURLE_OK) + { + cleanup(); + return false; + } } } + listener = webInputListener; + if (isPost) postBuffer = &headersAndPostData; @@ -248,8 +237,15 @@ public: // step until either: 1) there is an error 2) the transaction is complete // or 3) data is in the in buffer - while ((! finished) && curlBuffer.getSize() == 0 && curl != nullptr) + while ((! finished) && curlBuffer.getSize() == 0) { + { + const ScopedLock lock (cleanupLock); + + if (curl == nullptr) + return false; + } + singleStep(); // call callbacks if this is a post request @@ -266,20 +262,29 @@ public: } } - long responseCode; - if (curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &responseCode) == CURLE_OK) - statusCode = static_cast (responseCode); + { + const ScopedLock lock (cleanupLock); + + if (curl == nullptr) + return false; - // get content length size - double curlLength; - if (curl_easy_getinfo (curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &curlLength) == CURLE_OK) - contentLength = static_cast (curlLength); + long responseCode; + if (curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &responseCode) == CURLE_OK) + statusCode = static_cast (responseCode); + + // get content length size + double curlLength; + if (curl_easy_getinfo (curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &curlLength) == CURLE_OK) + contentLength = static_cast (curlLength); + } return true; } void finish() { + const ScopedLock lock (cleanupLock); + if (curl == nullptr) return; @@ -307,15 +312,22 @@ public: //============================================================================== void singleStep() { - if (curl == nullptr || lastError != CURLE_OK) + if (lastError != CURLE_OK) return; fd_set fdread, fdwrite, fdexcep; int maxfd = -1; long curl_timeo; - if ((lastError = (int) curl_multi_timeout (multi, &curl_timeo)) != CURLM_OK) - return; + { + const ScopedLock lock (cleanupLock); + + if (multi == nullptr) + return; + + if ((lastError = (int) curl_multi_timeout (multi, &curl_timeo)) != CURLM_OK) + return; + } // why 980? see http://curl.haxx.se/libcurl/c/curl_multi_timeout.html if (curl_timeo < 0) @@ -329,9 +341,15 @@ public: FD_ZERO (&fdwrite); FD_ZERO (&fdexcep); + { + const ScopedLock lock (cleanupLock); - if ((lastError = (int) curl_multi_fdset (multi, &fdread, &fdwrite, &fdexcep, &maxfd)) != CURLM_OK) - return; + if (multi == nullptr) + return; + + if ((lastError = (int) curl_multi_fdset (multi, &fdread, &fdwrite, &fdexcep, &maxfd)) != CURLM_OK) + return; + } if (maxfd != -1) { @@ -350,8 +368,12 @@ public: int still_running = 0; int curlRet; - while ((curlRet = (int) curl_multi_perform (multi, &still_running)) == CURLM_CALL_MULTI_PERFORM) - {} + { + const ScopedLock lock (cleanupLock); + + while ((curlRet = (int) curl_multi_perform (multi, &still_running)) == CURLM_CALL_MULTI_PERFORM) + {} + } if ((lastError = curlRet) != CURLM_OK) return; @@ -376,8 +398,12 @@ public: if (bufferBytes == 0) { // do not call curl again if we are finished - if (finished || curl == nullptr) - return static_cast (pos); + { + const ScopedLock lock (cleanupLock); + + if (finished || curl == nullptr) + return static_cast (pos); + } skipBytes = skip ? len : 0; singleStep(); @@ -484,38 +510,40 @@ public: //============================================================================== // curl stuff - CURLM* multi; - CURL* curl; - struct curl_slist* headerList; - int lastError; + CURLM* multi = nullptr; + CURL* curl = nullptr; + struct curl_slist* headerList = nullptr; + int lastError = CURLE_OK; //============================================================================== // Options - int timeOutMs; - int maxRedirects; + int timeOutMs = 0; + int maxRedirects = 5; const bool isPost; String httpRequest; //============================================================================== // internal buffers and buffer positions - int64 contentLength, streamPos; + int64 contentLength = -1, streamPos = 0; MemoryBlock curlBuffer; MemoryBlock headersAndPostData; String responseHeaders, requestHeaders; - int statusCode; + int statusCode = -1; //============================================================================== - bool finished; - size_t skipBytes; + bool finished = false; + size_t skipBytes = 0; //============================================================================== // Http POST variables - const MemoryBlock* postBuffer; - size_t postPosition; + const MemoryBlock* postBuffer = nullptr; + size_t postPosition = 0; //============================================================================== - WebInputStream::Listener* listener; + WebInputStream::Listener* listener = nullptr; + //============================================================================== + CriticalSection cleanupLock; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) }; diff --git a/source/modules/juce_core/native/juce_linux_CommonFile.cpp b/source/modules/juce_core/native/juce_linux_CommonFile.cpp index d230f6fc0..1166bd7b7 100644 --- a/source/modules/juce_core/native/juce_linux_CommonFile.cpp +++ b/source/modules/juce_core/native/juce_linux_CommonFile.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/native/juce_linux_Files.cpp b/source/modules/juce_core/native/juce_linux_Files.cpp index 56750ff6a..3b239df28 100644 --- a/source/modules/juce_core/native/juce_linux_Files.cpp +++ b/source/modules/juce_core/native/juce_linux_Files.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -74,7 +66,7 @@ bool File::isOnRemovableDrive() const String File::getVersion() const { - return String(); // xxx not yet implemented + return {}; // xxx not yet implemented } //============================================================================== @@ -114,35 +106,28 @@ File File::getSpecialLocation (const SpecialLocationType type) if (const char* homeDir = getenv ("HOME")) return File (CharPointer_UTF8 (homeDir)); - if (struct passwd* const pw = getpwuid (getuid())) + if (auto* pw = getpwuid (getuid())) return File (CharPointer_UTF8 (pw->pw_dir)); - return File(); + return {}; } - case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~"); - case userMusicDirectory: return resolveXDGFolder ("XDG_MUSIC_DIR", "~"); - case userMoviesDirectory: return resolveXDGFolder ("XDG_VIDEOS_DIR", "~"); - case userPicturesDirectory: return resolveXDGFolder ("XDG_PICTURES_DIR", "~"); + case userDocumentsDirectory: return resolveXDGFolder ("XDG_DOCUMENTS_DIR", "~/Documents"); + case userMusicDirectory: return resolveXDGFolder ("XDG_MUSIC_DIR", "~/Music"); + case userMoviesDirectory: return resolveXDGFolder ("XDG_VIDEOS_DIR", "~/Videos"); + case userPicturesDirectory: return resolveXDGFolder ("XDG_PICTURES_DIR", "~/Pictures"); case userDesktopDirectory: return resolveXDGFolder ("XDG_DESKTOP_DIR", "~/Desktop"); - case userApplicationDataDirectory: return resolveXDGFolder ("XDG_CONFIG_HOME", "~"); + case userApplicationDataDirectory: return resolveXDGFolder ("XDG_CONFIG_HOME", "~/.config"); case commonDocumentsDirectory: - case commonApplicationDataDirectory: return File ("/var"); + case commonApplicationDataDirectory: return File ("/opt"); case globalApplicationsDirectory: return File ("/usr"); case tempDirectory: { - File tmp ("/var/tmp"); - - if (! tmp.isDirectory()) - { - tmp = "/tmp"; - - if (! tmp.isDirectory()) - tmp = File::getCurrentWorkingDirectory(); - } + if (const char* tmpDir = getenv ("TMPDIR")) + return File (CharPointer_UTF8 (tmpDir)); - return tmp; + return File ("/tmp"); } case invokedExecutableFile: @@ -168,7 +153,7 @@ File File::getSpecialLocation (const SpecialLocationType type) break; } - return File(); + return {}; } //============================================================================== diff --git a/source/modules/juce_core/native/juce_linux_Network.cpp b/source/modules/juce_core/native/juce_linux_Network.cpp index 916a0ec5d..c8154f96b 100644 --- a/source/modules/juce_core/native/juce_linux_Network.cpp +++ b/source/modules/juce_core/native/juce_linux_Network.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -55,7 +47,7 @@ void MACAddress::findAllAddresses (Array& result) freeifaddrs (addrs); } - close (s); + ::close (s); } } @@ -74,19 +66,9 @@ bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& /* targetEma class WebInputStream::Pimpl { public: - /* WebInputStream (const String& address_, bool isPost_, const MemoryBlock& postData_, - URL::OpenStreamProgressCallback* progressCallback, void* progressCallbackContext, - const String& headers_, int timeOutMs_, StringPairArray* responseHeaders, - const int maxRedirects, const String& httpRequestCmd_) - : statusCode (0), socketHandle (-1), levelsOfRedirection (0), - address (address_), headers (headers_), postData (postData_), contentLength (-1), position (0), - finished (false), isPost (isPost_), timeOutMs (timeOutMs_), numRedirectsToFollow (maxRedirects), - httpRequestCmd (httpRequestCmd_), chunkEnd (0), isChunked (false), readingChunk (false)*/ Pimpl (WebInputStream& pimplOwner, const URL& urlToCopy, const bool shouldUsePost) - : statusCode (0), owner (pimplOwner), url (urlToCopy), socketHandle (-1), levelsOfRedirection (0), - contentLength (-1), position (0), finished (false), isPost (shouldUsePost), timeOutMs (0), - numRedirectsToFollow (5), httpRequestCmd (shouldUsePost ? "POST" : "GET"), chunkEnd (0), - isChunked (false), readingChunk (false) + : owner (pimplOwner), url (urlToCopy), + isPost (shouldUsePost), httpRequestCmd (shouldUsePost ? "POST" : "GET") {} ~Pimpl() @@ -134,6 +116,13 @@ public: bool connect (WebInputStream::Listener* listener) { + { + const ScopedLock lock (createSocketLock); + + if (hasBeenCancelled) + return false; + } + address = url.toString (! isPost); statusCode = createConnection (listener, numRedirectsToFollow); @@ -142,13 +131,17 @@ public: void cancel() { + const ScopedLock lock (createSocketLock); + + hasBeenCancelled = true; + statusCode = -1; finished = true; closeSocket(); } - //==============================================================================w + //============================================================================== bool isError() const { return socketHandle < 0; } bool isExhausted() { return finished; } int64 getPosition() { return position; } @@ -254,30 +247,38 @@ public: } //============================================================================== - int statusCode; + int statusCode = 0; private: WebInputStream& owner; URL url; - int socketHandle, levelsOfRedirection; + int socketHandle = -1, levelsOfRedirection = 0; StringArray headerLines; String address, headers; MemoryBlock postData; - int64 contentLength, position; - bool finished; + int64 contentLength = -1, position = 0; + bool finished = false; const bool isPost; - int timeOutMs; - int numRedirectsToFollow; + int timeOutMs = 0; + int numRedirectsToFollow = 5; String httpRequestCmd; - int64 chunkEnd; - bool isChunked, readingChunk; + int64 chunkEnd = 0; + bool isChunked = false, readingChunk = false; + CriticalSection closeSocketLock, createSocketLock; + bool hasBeenCancelled = false; void closeSocket (bool resetLevelsOfRedirection = true) { + const ScopedLock lock (closeSocketLock); + if (socketHandle >= 0) - close (socketHandle); + { + ::shutdown (socketHandle, SHUT_RDWR); + ::close (socketHandle); + } socketHandle = -1; + if (resetLevelsOfRedirection) levelsOfRedirection = 0; } @@ -334,7 +335,12 @@ private: if (getaddrinfo (serverName.toUTF8(), String (port).toUTF8(), &hints, &result) != 0 || result == 0) return 0; - socketHandle = socket (result->ai_family, result->ai_socktype, 0); + { + const ScopedLock lock (createSocketLock); + + socketHandle = hasBeenCancelled ? -1 + : socket (result->ai_family, result->ai_socktype, 0); + } if (socketHandle == -1) { @@ -428,7 +434,7 @@ private: { char c = 0; if (read (&c, 1) != 1) - return String(); + return {}; buffer.writeByte (c); @@ -443,7 +449,7 @@ private: if (header.startsWithIgnoreCase ("HTTP/")) return header; - return String(); + return {}; } static void writeValueIfNotPresent (MemoryOutputStream& dest, const String& headers, const String& key, const String& value) @@ -486,7 +492,7 @@ private: if (userHeaders.isNotEmpty()) header << "\r\n" << userHeaders; - header << "\r\n"; + header << "\r\n\r\n"; if (isPost) header << postData; @@ -561,7 +567,7 @@ private: if (lines[i].startsWithIgnoreCase (itemName)) return lines[i].substring (itemName.length()).trim(); - return String(); + return {}; } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) diff --git a/source/modules/juce_core/native/juce_linux_SystemStats.cpp b/source/modules/juce_core/native/juce_linux_SystemStats.cpp index b21d1689f..4b8f4bdfb 100644 --- a/source/modules/juce_core/native/juce_linux_SystemStats.cpp +++ b/source/modules/juce_core/native/juce_linux_SystemStats.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -55,44 +47,34 @@ bool SystemStats::isOperatingSystem64Bit() } //============================================================================== -namespace LinuxStatsHelpers +static inline String getCpuInfo (const char* key) { - String getConfigFileValue (const char* file, const char* const key) - { - StringArray lines; - File (file).readLines (lines); - - for (int i = lines.size(); --i >= 0;) // (NB - it's important that this runs in reverse order) - if (lines[i].upToFirstOccurrenceOf (":", false, false).trim().equalsIgnoreCase (key)) - return lines[i].fromFirstOccurrenceOf (":", false, false).trim(); - - return String(); - } - - String getCpuInfo (const char* key) - { - return getConfigFileValue ("/proc/cpuinfo", key); - } + return readPosixConfigFileValue ("/proc/cpuinfo", key); } String SystemStats::getDeviceDescription() { - return LinuxStatsHelpers::getCpuInfo ("Hardware"); + return getCpuInfo ("Hardware"); } String SystemStats::getCpuVendor() { - String v (LinuxStatsHelpers::getCpuInfo ("vendor_id")); + auto v = getCpuInfo ("vendor_id"); if (v.isEmpty()) - v = LinuxStatsHelpers::getCpuInfo ("model name"); + v = getCpuInfo ("model name"); return v; } +String SystemStats::getCpuModel() +{ + return getCpuInfo ("model name"); +} + int SystemStats::getCpuSpeedInMegaherz() { - return roundToInt (LinuxStatsHelpers::getCpuInfo ("cpu MHz").getFloatValue()); + return roundToInt (getCpuInfo ("cpu MHz").getFloatValue()); } int SystemStats::getMemorySizeInMegabytes() @@ -119,7 +101,7 @@ String SystemStats::getLogonName() if (struct passwd* const pw = getpwuid (getuid())) return CharPointer_UTF8 (pw->pw_name); - return String(); + return {}; } String SystemStats::getFullUserName() @@ -133,7 +115,7 @@ String SystemStats::getComputerName() if (gethostname (name, sizeof (name) - 1) == 0) return name; - return String(); + return {}; } static String getLocaleValue (nl_item key) @@ -151,7 +133,7 @@ String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getU //============================================================================== void CPUInformation::initialise() noexcept { - const String flags (LinuxStatsHelpers::getCpuInfo ("flags")); + auto flags = getCpuInfo ("flags"); hasMMX = flags.contains ("mmx"); hasSSE = flags.contains ("sse"); hasSSE2 = flags.contains ("sse2"); @@ -163,7 +145,13 @@ void CPUInformation::initialise() noexcept hasAVX = flags.contains ("avx"); hasAVX2 = flags.contains ("avx2"); - numCpus = LinuxStatsHelpers::getCpuInfo ("processor").getIntValue() + 1; + numLogicalCPUs = getCpuInfo ("processor").getIntValue() + 1; + + // Assume CPUs in all sockets have the same number of cores + numPhysicalCPUs = getCpuInfo ("cpu cores").getIntValue() * (getCpuInfo ("physical id").getIntValue() + 1); + + if (numPhysicalCPUs <= 0) + numPhysicalCPUs = numLogicalCPUs; } //============================================================================== @@ -207,7 +195,7 @@ JUCE_API bool JUCE_CALLTYPE juce_isRunningUnderDebugger() noexcept #if JUCE_BSD return false; #else - return LinuxStatsHelpers::getConfigFileValue ("/proc/self/status", "TracerPid") + return readPosixConfigFileValue ("/proc/self/status", "TracerPid") .getIntValue() > 0; #endif } diff --git a/source/modules/juce_core/native/juce_linux_Threads.cpp b/source/modules/juce_core/native/juce_linux_Threads.cpp index 938f8af94..d293a76e0 100644 --- a/source/modules/juce_core/native/juce_linux_Threads.cpp +++ b/source/modules/juce_core/native/juce_linux_Threads.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/native/juce_mac_ClangBugWorkaround.h b/source/modules/juce_core/native/juce_mac_ClangBugWorkaround.h index c28184fad..cfb8322bb 100644 --- a/source/modules/juce_core/native/juce_mac_ClangBugWorkaround.h +++ b/source/modules/juce_core/native/juce_mac_ClangBugWorkaround.h @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/native/juce_mac_Files.mm b/source/modules/juce_core/native/juce_mac_Files.mm index c408aadc4..1892af79f 100644 --- a/source/modules/juce_core/native/juce_mac_Files.mm +++ b/source/modules/juce_core/native/juce_mac_Files.mm @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -86,9 +78,8 @@ namespace MacFileHelpers NSNumber* hidden = nil; NSError* err = nil; - return [[NSURL fileURLWithPath: juceStringToNS (path)] - getResourceValue: &hidden forKey: NSURLIsHiddenKey error: &err] - && [hidden boolValue]; + return [createNSURLFromFile (path) getResourceValue: &hidden forKey: NSURLIsHiddenKey error: &err] + && [hidden boolValue]; } #elif JUCE_IOS return File (path).getFileName().startsWithChar ('.'); @@ -219,7 +210,7 @@ File File::getSpecialLocation (const SpecialLocationType type) case invokedExecutableFile: if (juce_argv != nullptr && juce_argc > 0) - return File::getCurrentWorkingDirectory().getChildFile (CharPointer_UTF8 (juce_argv[0])); + return File::getCurrentWorkingDirectory().getChildFile (String (juce_argv[0])); // deliberate fall-through... case currentExecutableFile: @@ -258,7 +249,7 @@ File File::getSpecialLocation (const SpecialLocationType type) return File (resultPath.convertToPrecomposedUnicode()); } - return File(); + return {}; } //============================================================================== @@ -272,7 +263,7 @@ String File::getVersion() const return nsStringToJuce (name); } - return String(); + return {}; } //============================================================================== @@ -305,7 +296,7 @@ bool File::moveToTrash() const #else JUCE_AUTORELEASEPOOL { - NSURL* url = [NSURL fileURLWithPath: juceStringToNS (getFullPathName())]; + NSURL* url = createNSURLFromFile (*this); [[NSWorkspace sharedWorkspace] recycleURLs: [NSArray arrayWithObject: url] completionHandler: nil]; diff --git a/source/modules/juce_core/native/juce_mac_Network.mm b/source/modules/juce_core/native/juce_mac_Network.mm index 3b7b5b5f5..5bfe1e0d2 100644 --- a/source/modules/juce_core/native/juce_mac_Network.mm +++ b/source/modules/juce_core/native/juce_mac_Network.mm @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -36,11 +28,11 @@ void MACAddress::findAllAddresses (Array& result) { for (const ifaddrs* cursor = addrs; cursor != nullptr; cursor = cursor->ifa_next) { - sockaddr_storage* sto = (sockaddr_storage*) cursor->ifa_addr; + auto sto = (sockaddr_storage*) cursor->ifa_addr; if (sto->ss_family == AF_LINK) { - const sockaddr_dl* const sadd = (const sockaddr_dl*) cursor->ifa_addr; + auto sadd = (const sockaddr_dl*) cursor->ifa_addr; #ifndef IFT_ETHER enum { IFT_ETHER = 6 }; @@ -154,12 +146,25 @@ public: void cancel() { + { + const ScopedLock lock (createTaskLock); + + hasBeenCancelled = true; + } + signalThreadShouldExit(); stopThread (10000); } bool start (WebInputStream& inputStream, WebInputStream::Listener* listener) { + { + const ScopedLock lock (createTaskLock); + + if (hasBeenCancelled) + return false; + } + startThread(); while (isThreadRunning() && ! initialised) @@ -240,6 +245,7 @@ public: void didComplete (NSError* error) { const ScopedLock sl (dataLock); + if (isBeingDeleted) return; @@ -256,6 +262,7 @@ public: void didReceiveData (NSData* newData) { const ScopedLock sl (dataLock); + if (isBeingDeleted) return; @@ -272,6 +279,7 @@ public: { { const ScopedLock sl (dataLock); + if (isBeingDeleted) return; } @@ -287,7 +295,12 @@ public: delegate: delegate delegateQueue: [NSOperationQueue currentQueue]] retain]; - task = [session dataTaskWithRequest: request]; + { + const ScopedLock lock (createTaskLock); + + if (! hasBeenCancelled) + task = [session dataTaskWithRequest: request]; + } if (task == nil) return; @@ -315,6 +328,8 @@ public: const int numRedirectsToFollow; int numRedirects = 0; int64 latestTotalBytes = 0; + CriticalSection createTaskLock; + bool hasBeenCancelled = false; private: //============================================================================== @@ -325,15 +340,14 @@ private: addIvar ("state"); addMethod (@selector (URLSession:dataTask:didReceiveResponse:completionHandler:), - didReceiveResponse, "v@:@@@@"); - addMethod (@selector (URLSession:didBecomeInvalidWithError:), didBecomeInvalidWithError, "v@:@@"); - addMethod (@selector (URLSession:dataTask:didReceiveData:), didReceiveData, "v@:@@@"); + didReceiveResponse, "v@:@@@@"); + addMethod (@selector (URLSession:didBecomeInvalidWithError:), didBecomeInvalidWithError, "v@:@@"); + addMethod (@selector (URLSession:dataTask:didReceiveData:), didReceiveData, "v@:@@@"); addMethod (@selector (URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:), - didSendBodyData, "v@:@@qqq"); + didSendBodyData, "v@:@@qqq"); addMethod (@selector (URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:), willPerformHTTPRedirection, "v@:@@@@@"); - - addMethod (@selector (URLSession:task:didCompleteWithError:), didCompleteWithError, "v@:@@@"); + addMethod (@selector (URLSession:task:didCompleteWithError:), didCompleteWithError, "v@:@@@"); registerClass(); } @@ -344,33 +358,39 @@ private: private: static void didReceiveResponse (id self, SEL, NSURLSession*, NSURLSessionDataTask*, NSURLResponse* response, id completionHandler) { - if (auto state = getState (self)) state->didReceiveResponse (response, completionHandler); + if (auto state = getState (self)) + state->didReceiveResponse (response, completionHandler); } static void didBecomeInvalidWithError (id self, SEL, NSURLSession*, NSError* error) { - if (auto state = getState (self)) state->didComplete (error); + if (auto state = getState (self)) + state->didComplete (error); } static void didReceiveData (id self, SEL, NSURLSession*, NSURLSessionDataTask*, NSData* newData) { - if (auto state = getState (self)) state->didReceiveData (newData); + if (auto state = getState (self)) + state->didReceiveData (newData); } static void didSendBodyData (id self, SEL, NSURLSession*, NSURLSessionTask*, int64_t, int64_t totalBytesWritten, int64_t) { - if (auto state = getState (self)) state->didSendBodyData (totalBytesWritten); + if (auto state = getState (self)) + state->didSendBodyData (totalBytesWritten); } static void willPerformHTTPRedirection (id self, SEL, NSURLSession*, NSURLSessionTask*, NSHTTPURLResponse*, NSURLRequest* request, void (^completionHandler)(NSURLRequest *)) { - if (auto state = getState (self)) state->willPerformHTTPRedirection (request, completionHandler); + if (auto state = getState (self)) + state->willPerformHTTPRedirection (request, completionHandler); } static void didCompleteWithError (id self, SEL, NSURLConnection*, NSURLSessionTask*, NSError* error) { - if (auto state = getState (self)) state->didComplete (error); + if (auto state = getState (self)) + state->didComplete (error); } }; @@ -386,8 +406,6 @@ struct BackgroundDownloadTask : public URL::DownloadTask String extraHeadersToUse, URL::DownloadTask::Listener* listenerToUse) : targetLocation (targetLocationToUse), listener (listenerToUse), - delegate (nullptr), session (nullptr), downloadTask (nullptr), - connectFinished (false), hasBeenDestroyed (false), calledComplete (0), uniqueIdentifier (String (urlToUse.toString (true).hashCode64()) + String (Random().nextInt64())) { downloaded = -1; @@ -413,9 +431,9 @@ struct BackgroundDownloadTask : public URL::DownloadTask } session = - [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:juceStringToNS (uniqueIdentifier)] - delegate:delegate - delegateQueue:nullptr]; + [NSURLSession sessionWithConfiguration: [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: juceStringToNS (uniqueIdentifier)] + delegate: delegate + delegateQueue: nullptr]; if (session != nullptr) downloadTask = [session downloadTaskWithRequest:request]; @@ -458,10 +476,10 @@ struct BackgroundDownloadTask : public URL::DownloadTask //============================================================================== File targetLocation; URL::DownloadTask::Listener* listener; - NSObject* delegate; - NSURLSession* session; - NSURLSessionDownloadTask* downloadTask; - bool connectFinished, hasBeenDestroyed; + NSObject* delegate = nil; + NSURLSession* session = nil; + NSURLSessionDownloadTask* downloadTask = nil; + bool connectFinished = false, hasBeenDestroyed = false; Atomic calledComplete; WaitableEvent connectionEvent, destroyEvent; String uniqueIdentifier; @@ -481,62 +499,54 @@ struct BackgroundDownloadTask : public URL::DownloadTask connectionEvent.signal(); } - void didFinishDownloadingToURL (NSURL* location) - { - NSFileManager* fileManager = [[NSFileManager alloc] init]; - error = ([fileManager moveItemAtURL:location - toURL:[NSURL fileURLWithPath:juceStringToNS (targetLocation.getFullPathName())] - error:nullptr] == NO); - httpCode = 200; - finished = true; - - connectionEvent.signal(); - - if (listener != nullptr && calledComplete.exchange (1) == 0) - { - if (contentLength > 0 && downloaded < contentLength) - { - downloaded = contentLength; - listener->progress (this, downloaded, contentLength); - } - - listener->finished (this, !error); - } - } - - void didCompleteWithError (NSError* nsError) - { - if (calledComplete.exchange (1) == 0) - { - httpCode = -1; - - if (nsError != nullptr) - { - // see https://developer.apple.com/reference/foundation/nsurlsessiondownloadtask?language=objc - switch ([nsError code]) - { - case NSURLErrorUserAuthenticationRequired: - httpCode = 401; - break; - case NSURLErrorNoPermissionsToReadFile: - httpCode = 403; - break; - case NSURLErrorFileDoesNotExist: - httpCode = 404; - break; - default: - httpCode = 500; - } - } - - error = true; - finished = true; - - if (listener != nullptr) - listener->finished (this, ! error); - } - - connectionEvent.signal(); + void didFinishDownloadingToURL (NSURL* location) + { + NSFileManager* fileManager = [[NSFileManager alloc] init]; + error = ([fileManager moveItemAtURL: location + toURL: createNSURLFromFile (targetLocation) + error: nil] == NO); + httpCode = 200; + finished = true; + + connectionEvent.signal(); + + if (listener != nullptr && calledComplete.exchange (1) == 0) + { + if (contentLength > 0 && downloaded < contentLength) + { + downloaded = contentLength; + listener->progress (this, downloaded, contentLength); + } + + listener->finished (this, !error); + } + } + + static int getHTTPErrorCode (NSError* nsError) + { + // see https://developer.apple.com/reference/foundation/nsurlsessiondownloadtask?language=objc + switch ([nsError code]) + { + case NSURLErrorUserAuthenticationRequired: return 401; + case NSURLErrorNoPermissionsToReadFile: return 403; + case NSURLErrorFileDoesNotExist: return 404; + default: return 500; + } + } + + void didCompleteWithError (NSError* nsError) + { + if (calledComplete.exchange (1) == 0) + { + httpCode = nsError != nil ? getHTTPErrorCode (nsError) : -1; + error = true; + finished = true; + + if (listener != nullptr) + listener->finished (this, ! error); + } + + connectionEvent.signal(); } void didBecomeInvalidWithError() @@ -569,7 +579,7 @@ struct BackgroundDownloadTask : public URL::DownloadTask { ScopedLock lock (activeSessions.getLock()); - if (BackgroundDownloadTask* task = activeSessions[identifier]) + if (auto* task = activeSessions[identifier]) task->notify(); } @@ -581,13 +591,10 @@ struct BackgroundDownloadTask : public URL::DownloadTask addIvar ("state"); addMethod (@selector (URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:), - didWriteData, "v@:@@qqq"); - addMethod (@selector (URLSession:downloadTask:didFinishDownloadingToURL:), - didFinishDownloadingToURL, "v@:@@@"); - addMethod (@selector (URLSession:task:didCompleteWithError:), - didCompleteWithError, "v@:@@@"); - addMethod (@selector (URLSession:didBecomeInvalidWithError:), - didBecomeInvalidWithError, "v@:@@@"); + didWriteData, "v@:@@qqq"); + addMethod (@selector (URLSession:downloadTask:didFinishDownloadingToURL:), didFinishDownloadingToURL, "v@:@@@"); + addMethod (@selector (URLSession:task:didCompleteWithError:), didCompleteWithError, "v@:@@@"); + addMethod (@selector (URLSession:didBecomeInvalidWithError:), didBecomeInvalidWithError, "v@:@@@"); registerClass(); } @@ -598,22 +605,26 @@ struct BackgroundDownloadTask : public URL::DownloadTask private: static void didWriteData (id self, SEL, NSURLSession*, NSURLSessionDownloadTask*, int64_t, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) { - if (auto state = getState (self)) state->didWriteData (totalBytesWritten, totalBytesExpectedToWrite); + if (auto state = getState (self)) + state->didWriteData (totalBytesWritten, totalBytesExpectedToWrite); } static void didFinishDownloadingToURL (id self, SEL, NSURLSession*, NSURLSessionDownloadTask*, NSURL* location) { - if (auto state = getState (self)) state->didFinishDownloadingToURL (location); + if (auto state = getState (self)) + state->didFinishDownloadingToURL (location); } static void didCompleteWithError (id self, SEL, NSURLSession*, NSURLSessionTask*, NSError* nsError) { - if (auto state = getState (self)) state->didCompleteWithError (nsError); + if (auto state = getState (self)) + state->didCompleteWithError (nsError); } static void didBecomeInvalidWithError (id self, SEL, NSURLSession*, NSURLSessionTask*, NSError*) { - if (auto state = getState (self)) state->didBecomeInvalidWithError (); + if (auto state = getState (self)) + state->didBecomeInvalidWithError(); } }; }; @@ -657,20 +668,9 @@ class URLConnectionState : public Thread public: URLConnectionState (NSURLRequest* req, const int maxRedirects) : Thread ("http connection"), - contentLength (-1), - delegate (nil), request ([req retain]), - connection (nil), data ([[NSMutableData data] retain]), - headers (nil), - nsUrlErrorCode (0), - statusCode (0), - initialised (false), - hasFailed (false), - hasFinished (false), - numRedirectsToFollow (maxRedirects), - numRedirects (0), - latestTotalBytes (0) + numRedirectsToFollow (maxRedirects) { static DelegateClass cls; delegate = [cls.createInstance() init]; @@ -680,6 +680,7 @@ public: ~URLConnectionState() { stop(); + [connection release]; [request release]; [headers release]; @@ -706,8 +707,13 @@ public: void stop() { { - const ScopedLock sl (dataLock); - [connection cancel]; + const ScopedLock dLock (dataLock); + const ScopedLock connectionLock (createConnectionLock); + + hasBeenCancelled = true; + + if (connection != nil) + [connection cancel]; } stopThread (10000); @@ -788,8 +794,7 @@ public: { DBG (nsStringToJuce ([error description])); ignoreUnused (error); nsUrlErrorCode = [error code]; - hasFailed = true; - initialised = true; + hasFailed = initialised = true; signalThreadShouldExit(); } @@ -807,15 +812,22 @@ public: void finishedLoading() { - hasFinished = true; - initialised = true; + hasFinished = initialised = true; signalThreadShouldExit(); } void run() override { - connection = [[NSURLConnection alloc] initWithRequest: request - delegate: delegate]; + { + const ScopedLock lock (createConnectionLock); + + if (hasBeenCancelled) + return; + + connection = [[NSURLConnection alloc] initWithRequest: request + delegate: delegate]; + } + while (! threadShouldExit()) { JUCE_AUTORELEASEPOOL @@ -825,25 +837,27 @@ public: } } - int64 contentLength; + int64 contentLength = -1; CriticalSection dataLock; - NSObject* delegate; - NSURLRequest* request; - NSURLConnection* connection; - NSMutableData* data; - NSDictionary* headers; - NSInteger nsUrlErrorCode; - int statusCode; - bool initialised, hasFailed, hasFinished; + NSObject* delegate = nil; + NSURLRequest* request = nil; + NSURLConnection* connection = nil; + NSMutableData* data = nil; + NSDictionary* headers = nil; + NSInteger nsUrlErrorCode = 0; + int statusCode = 0; + bool initialised = false, hasFailed = false, hasFinished = false; const int numRedirectsToFollow; - int numRedirects; - int latestTotalBytes; + int numRedirects = 0; + int latestTotalBytes = 0; + CriticalSection createConnectionLock; + bool hasBeenCancelled = false; private: //============================================================================== struct DelegateClass : public ObjCClass { - DelegateClass() : ObjCClass ("JUCEAppDelegate_") + DelegateClass() : ObjCClass ("JUCENetworkDelegate_") { addIvar ("state"); @@ -911,9 +925,8 @@ class WebInputStream::Pimpl { public: Pimpl (WebInputStream& pimplOwner, const URL& urlToUse, bool shouldBePost) - : statusCode (0), owner (pimplOwner), url (urlToUse), position (0), - finished (false), isPost (shouldBePost), timeOutMs (0), - numRedirectsToFollow (5), httpRequestCmd (shouldBePost ? "POST" : "GET") + : owner (pimplOwner), url (urlToUse), isPost (shouldBePost), + httpRequestCmd (shouldBePost ? "POST" : "GET") { } @@ -925,7 +938,15 @@ public: bool connect (WebInputStream::Listener* webInputListener, int numRetries = 0) { ignoreUnused (numRetries); - createConnection(); + + { + const ScopedLock lock (createConnectionLock); + + if (hasBeenCancelled) + return false; + + createConnection(); + } if (! connection->start (owner, webInputListener)) { @@ -958,6 +979,18 @@ public: return false; } + void cancel() + { + { + const ScopedLock lock (createConnectionLock); + + if (connection != nullptr) + connection->cancel(); + + hasBeenCancelled = true; + } + } + //============================================================================== // WebInputStream methods void withExtraHeaders (const String& extraHeaders) @@ -1024,27 +1057,23 @@ public: return true; } - void cancel() - { - if (connection != nullptr) - connection->cancel(); - } - - int statusCode; + int statusCode = 0; private: WebInputStream& owner; - const URL& url; + URL url; ScopedPointer connection; String headers; MemoryBlock postData; - int64 position; - bool finished; + int64 position = 0; + bool finished = false; const bool isPost; - int timeOutMs; - int numRedirectsToFollow; + int timeOutMs = 0; + int numRedirectsToFollow = 5; String httpRequestCmd; StringPairArray responseHeaders; + CriticalSection createConnectionLock; + bool hasBeenCancelled = false; void createConnection() { diff --git a/source/modules/juce_core/native/juce_mac_Strings.mm b/source/modules/juce_core/native/juce_mac_Strings.mm index 1dd39a516..62f9d8717 100644 --- a/source/modules/juce_core/native/juce_mac_Strings.mm +++ b/source/modules/juce_core/native/juce_mac_Strings.mm @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,7 +23,7 @@ String String::fromCFString (CFStringRef cfString) { if (cfString == 0) - return String(); + return {}; CFRange range = { 0, CFStringGetLength (cfString) }; CFIndex bytesNeeded = 0; diff --git a/source/modules/juce_core/native/juce_mac_SystemStats.mm b/source/modules/juce_core/native/juce_mac_SystemStats.mm index e6bffb03c..db81b1991 100644 --- a/source/modules/juce_core/native/juce_mac_SystemStats.mm +++ b/source/modules/juce_core/native/juce_mac_SystemStats.mm @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -91,7 +83,16 @@ void CPUInformation::initialise() noexcept hasAVX2 = (b & (1u << 5)) != 0; #endif - numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount]; + numLogicalCPUs = (int) [[NSProcessInfo processInfo] activeProcessorCount]; + + unsigned int physicalcpu = 0; + size_t len = sizeof (physicalcpu); + + if (sysctlbyname ("hw.physicalcpu", &physicalcpu, &len, nullptr, 0) >= 0) + numPhysicalCPUs = (int) physicalcpu; + + if (numPhysicalCPUs <= 0) + numPhysicalCPUs = numLogicalCPUs; } //============================================================================== @@ -138,7 +139,14 @@ String SystemStats::getDeviceDescription() #if JUCE_IOS return nsStringToJuce ([[UIDevice currentDevice] model]); #else - return String(); + size_t size; + if (sysctlbyname ("hw.model", nullptr, &size, nullptr, 0) >= 0) + { + HeapBlock model (size); + if (sysctlbyname ("hw.model", model, &size, nullptr, 0) >= 0) + return model.getData(); + } + return {}; #endif } @@ -172,10 +180,21 @@ String SystemStats::getCpuVendor() return String (reinterpret_cast (vendor), 12); #else - return String(); + return {}; #endif } +String SystemStats::getCpuModel() +{ + char name[65] = { 0 }; + size_t size = sizeof (name) - 1; + + if (sysctlbyname ("machdep.cpu.brand_string", &name, &size, nullptr, 0) >= 0) + return String (name); + + return {}; +} + int SystemStats::getCpuSpeedInMegaherz() { uint64 speedHz = 0; @@ -204,11 +223,11 @@ String SystemStats::getFullUserName() String SystemStats::getComputerName() { - char name [256] = { 0 }; + char name[256] = { 0 }; if (gethostname (name, sizeof (name) - 1) == 0) return String (name).upToLastOccurrenceOf (".local", false, true); - return String(); + return {}; } static String getLocaleValue (CFStringRef key) diff --git a/source/modules/juce_core/native/juce_mac_Threads.mm b/source/modules/juce_core/native/juce_mac_Threads.mm index a762d9fb1..a02403e17 100644 --- a/source/modules/juce_core/native/juce_mac_Threads.mm +++ b/source/modules/juce_core/native/juce_mac_Threads.mm @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/native/juce_osx_ObjCHelpers.h b/source/modules/juce_core/native/juce_osx_ObjCHelpers.h index c0688e62d..767bcf49d 100644 --- a/source/modules/juce_core/native/juce_osx_ObjCHelpers.h +++ b/source/modules/juce_core/native/juce_osx_ObjCHelpers.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_OSX_OBJCHELPERS_H_INCLUDED -#define JUCE_OSX_OBJCHELPERS_H_INCLUDED +#pragma once /* This file contains a few helper functions that are used internally but which @@ -58,6 +49,16 @@ namespace return [NSString string]; } + static inline NSURL* createNSURLFromFile (const String& f) + { + return [NSURL fileURLWithPath: juceStringToNS (f)]; + } + + static inline NSURL* createNSURLFromFile (const File& f) + { + return createNSURLFromFile (f.getFullPathName()); + } + #if JUCE_MAC template static NSRect makeNSRect (const RectangleType& r) noexcept @@ -214,8 +215,8 @@ public: ObjCBlock (C* _this, R (C::*fn)(P...)) : block (CreateObjCBlock (_this, fn)) {} ObjCBlock (BlockType b) : block ([b copy]) {} ObjCBlock& operator= (const BlockType& other) { if (block != nullptr) { [block release]; } block = [other copy]; return *this; } - bool operator== (const void* ptr) const { return (block == ptr); } - bool operator!= (const void* ptr) const { return (block != ptr); } + bool operator== (const void* ptr) const { return ((const void*) block == ptr); } + bool operator!= (const void* ptr) const { return ((const void*) block != ptr); } ~ObjCBlock() { if (block != nullptr) [block release]; } operator BlockType() { return block; } @@ -225,6 +226,3 @@ private: }; #endif - - -#endif // JUCE_OSX_OBJCHELPERS_H_INCLUDED diff --git a/source/modules/juce_core/native/juce_posix_NamedPipe.cpp b/source/modules/juce_core/native/juce_posix_NamedPipe.cpp index d76f5bbea..80bfa2e70 100644 --- a/source/modules/juce_core/native/juce_posix_NamedPipe.cpp +++ b/source/modules/juce_core/native/juce_posix_NamedPipe.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/native/juce_posix_SharedCode.h b/source/modules/juce_core/native/juce_posix_SharedCode.h index 5d2307b8f..00eecfcb8 100644 --- a/source/modules/juce_core/native/juce_posix_SharedCode.h +++ b/source/modules/juce_core/native/juce_posix_SharedCode.h @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -219,6 +211,12 @@ bool File::setAsCurrentWorkingDirectory() const return chdir (getFullPathName().toUTF8()) == 0; } +#if JUCE_ANDROID + typedef unsigned long juce_sigactionflags_type; +#else + typedef int juce_sigactionflags_type; +#endif + //============================================================================== // The unix siginterrupt function is deprecated - this does the same job. int juce_siginterrupt (int sig, int flag) @@ -227,9 +225,9 @@ int juce_siginterrupt (int sig, int flag) (void) ::sigaction (sig, nullptr, &act); if (flag != 0) - act.sa_flags &= ~SA_RESTART; + act.sa_flags &= static_cast (~SA_RESTART); else - act.sa_flags |= SA_RESTART; + act.sa_flags |= static_cast (SA_RESTART); return ::sigaction (sig, &act, nullptr); } @@ -369,7 +367,7 @@ static bool setFileModeFlags (const String& fullPath, mode_t flags, bool shouldS else info.st_mode &= ~flags; - return chmod (fullPath.toUTF8(), info.st_mode) == 0; + return chmod (fullPath.toUTF8(), (mode_t) info.st_mode) == 0; } bool File::setFileReadOnlyInternal (bool shouldBeReadOnly) const @@ -406,8 +404,8 @@ bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 if ((modificationTime != 0 || accessTime != 0) && juce_stat (fullPath, info)) { struct utimbuf times; - times.actime = accessTime != 0 ? (time_t) (accessTime / 1000) : info.st_atime; - times.modtime = modificationTime != 0 ? (time_t) (modificationTime / 1000) : info.st_mtime; + times.actime = accessTime != 0 ? static_cast (accessTime / 1000) : static_cast (info.st_atime); + times.modtime = modificationTime != 0 ? static_cast (modificationTime / 1000) : static_cast (info.st_mtime); return utime (fullPath.toUTF8(), ×) == 0; } @@ -455,7 +453,7 @@ Result File::createDirectoryInternal (const String& fileName) const //============================================================================== int64 juce_fileSetPosition (void* handle, int64 pos) { - if (handle != 0 && lseek (getFD (handle), pos, SEEK_SET) == pos) + if (handle != 0 && lseek (getFD (handle), (off_t) pos, SEEK_SET) == pos) return pos; return -1; @@ -646,8 +644,10 @@ File juce_getExecutableFile() static String getFilename() { Dl_info exeInfo; + void* localSymbol = (void*) juce_getExecutableFile; dladdr (localSymbol, &exeInfo); + const CharPointer_UTF8 filename (exeInfo.dli_fname); // if the filename is absolute simply return it @@ -678,7 +678,7 @@ File juce_getExecutableFile() } }; - static String filename (DLAddrReader::getFilename()); + static String filename = DLAddrReader::getFilename(); return filename; #endif } @@ -734,7 +734,7 @@ String File::getVolumeLabel() const } #endif - return String(); + return {}; } int File::getVolumeSerialNumber() const @@ -925,12 +925,25 @@ void InterProcessLock::exit() } //============================================================================== -#if ! JUCE_ANDROID void JUCE_API juce_threadEntryPoint (void*); +#if JUCE_ANDROID +extern JavaVM* androidJNIJavaVM; +#endif + extern "C" void* threadEntryProc (void*); extern "C" void* threadEntryProc (void* userData) { + #if JUCE_ANDROID + // JNI_OnLoad was not called - make sure you load the JUCE shared library + // using System.load inside of Java + jassert (androidJNIJavaVM != nullptr); + + JNIEnv* env; + androidJNIJavaVM->AttachCurrentThread (&env, nullptr); + setEnv (env); + #endif + JUCE_AUTORELEASEPOOL { juce_threadEntryPoint (userData); @@ -939,8 +952,30 @@ extern "C" void* threadEntryProc (void* userData) return nullptr; } +#if JUCE_ANDROID && JUCE_MODULE_AVAILABLE_juce_audio_devices && (JUCE_USE_ANDROID_OPENSLES || (! defined(JUCE_USE_ANDROID_OPENSLES) && JUCE_ANDROID_API_VERSION > 8)) +#define JUCE_ANDROID_REALTIME_THREAD_AVAILABLE 1 +#endif + +#if JUCE_ANDROID_REALTIME_THREAD_AVAILABLE +extern pthread_t juce_createRealtimeAudioThread (void* (*entry) (void*), void* userPtr); +#endif + void Thread::launchThread() { + #if JUCE_ANDROID + if (isAndroidRealtimeThread) + { + #if JUCE_ANDROID_REALTIME_THREAD_AVAILABLE + threadHandle = (void*) juce_createRealtimeAudioThread (threadEntryProc, this); + threadId = (ThreadID) threadHandle; + + return; + #else + jassertfalse; + #endif + } + #endif + threadHandle = 0; pthread_t handle = 0; pthread_attr_t attr; @@ -989,8 +1024,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); @@ -1018,7 +1054,6 @@ bool Thread::setThreadPriority (void* handle, int priority) param.sched_priority = ((maxPriority - minPriority) * priority) / 10 + minPriority; return pthread_setschedparam ((pthread_t) handle, policy, ¶m) == 0; } -#endif Thread::ThreadID JUCE_CALLTYPE Thread::getCurrentThreadId() { @@ -1051,10 +1086,12 @@ void JUCE_CALLTYPE Thread::setCurrentThreadAffinityMask (const uint32 affinityMa #if (! JUCE_ANDROID) && ((! JUCE_LINUX) || ((__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2004)) pthread_setaffinity_np (pthread_self(), sizeof (cpu_set_t), &affinity); + #elif JUCE_ANDROID + sched_setaffinity (gettid(), sizeof (cpu_set_t), &affinity); #else // NB: this call isn't really correct because it sets the affinity of the process, - // not the thread. But it's included here as a fallback for people who are using - // ridiculously old versions of glibc + // (getpid) not the thread (not gettid). But it's included here as a fallback for + // people who are using ridiculously old versions of glibc sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity); #endif @@ -1091,6 +1128,19 @@ void* DynamicLibrary::getFunction (const String& functionName) noexcept } +//============================================================================== +static inline String readPosixConfigFileValue (const char* file, const char* const key) +{ + StringArray lines; + File (file).readLines (lines); + + for (int i = lines.size(); --i >= 0;) // (NB - it's important that this runs in reverse order) + if (lines[i].upToFirstOccurrenceOf (":", false, false).trim().equalsIgnoreCase (key)) + return lines[i].fromFirstOccurrenceOf (":", false, false).trim(); + + return {}; +} + //============================================================================== class ChildProcess::ActiveProcess @@ -1147,7 +1197,7 @@ public: close (pipeHandles[1]); #endif - if (execvp (exe.toRawUTF8(), argv.getRawDataPointer())) + if (execvp (argv[0], argv.getRawDataPointer()) < 0) _exit (-1); } else @@ -1250,7 +1300,6 @@ bool ChildProcess::start (const StringArray& args, int streamFlags) } //============================================================================== -#if ! JUCE_ANDROID struct HighResolutionTimer::Pimpl { Pimpl (HighResolutionTimer& t) : owner (t), thread (0), destroyThread (false), isRunning (false) @@ -1258,7 +1307,7 @@ struct HighResolutionTimer::Pimpl pthread_condattr_t attr; pthread_condattr_init (&attr); - #if ! (JUCE_MAC || JUCE_IOS) + #if JUCE_LINUX || (JUCE_ANDROID && defined(__ANDROID_API__) && __ANDROID_API__ >= 21) pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); #endif @@ -1337,7 +1386,13 @@ private: static void* timerThread (void* param) { #if JUCE_ANDROID - const AndroidThreadScope androidEnv; + // JNI_OnLoad was not called - make sure you load the JUCE shared library + // using System.load inside of Java + jassert (androidJNIJavaVM != nullptr); + + JNIEnv* env; + androidJNIJavaVM->AttachCurrentThread (&env, nullptr); + setEnv (env); #else int dummy; pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, &dummy); @@ -1486,5 +1541,3 @@ private: JUCE_DECLARE_NON_COPYABLE (Pimpl) }; - -#endif diff --git a/source/modules/juce_core/native/juce_win32_ComSmartPtr.h b/source/modules/juce_core/native/juce_win32_ComSmartPtr.h index 876a9350e..09bfd5b7b 100644 --- a/source/modules/juce_core/native/juce_win32_ComSmartPtr.h +++ b/source/modules/juce_core/native/juce_win32_ComSmartPtr.h @@ -2,70 +2,77 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_WIN32_COMSMARTPTR_H_INCLUDED -#define JUCE_WIN32_COMSMARTPTR_H_INCLUDED +#pragma once #if JUCE_MINGW || (! (defined (_MSC_VER) || defined (__uuidof))) -#ifdef __uuidof - #undef __uuidof -#endif + #ifdef __uuidof + #undef __uuidof + #endif -template struct UUIDGetter { static CLSID get() { jassertfalse; return CLSID(); } }; -#define __uuidof(x) UUIDGetter::get() + template struct UUIDGetter { static CLSID get() { jassertfalse; return {}; } }; + #define __uuidof(x) UUIDGetter::get() template <> struct UUIDGetter<::IUnknown> { - static CLSID get() - { - GUID g = { 0, 0, 0, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; - return g; - } + static CLSID get() { return { 0, 0, 0, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; } }; + + #define JUCE_DECLARE_UUID_GETTER(name, uuid) \ + template<> struct UUIDGetter { static CLSID get() { return uuidFromString (uuid); } }; + + #define JUCE_COMCLASS(name, guid) \ + struct name; \ + JUCE_DECLARE_UUID_GETTER (name, guid) \ + struct name + +#else + #define JUCE_DECLARE_UUID_GETTER(name, uuid) + #define JUCE_COMCLASS(name, guid) struct __declspec (uuid (guid)) name #endif -inline GUID uuidFromString (const char* const s) noexcept +inline GUID uuidFromString (const char* s) noexcept { - unsigned long p0; - unsigned int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10; - - #ifndef _MSC_VER - sscanf - #else - sscanf_s - #endif - (s, "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - &p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10); - - GUID g = { p0, (uint16) p1, (uint16) p2, { (uint8) p3, (uint8) p4, (uint8) p5, (uint8) p6, - (uint8) p7, (uint8) p8, (uint8) p9, (uint8) p10 }}; - return g; + uint32 ints[4] = {}; + + for (uint32 digitIndex = 0; digitIndex < 32;) + { + auto c = *s++; + uint32 digit; + + if (c >= '0' && c <= '9') digit = c - '0'; + else if (c >= 'a' && c <= 'f') digit = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') digit = c - 'A' + 10; + else if (c == '-') continue; + else break; + + ints[digitIndex / 8] |= (digit << 4 * (7 - (digitIndex & 7))); + ++digitIndex; + } + + return { ints[0], + (uint16) (ints[1] >> 16), + (uint16) ints[1], + { (uint8) (ints[2] >> 24), (uint8) (ints[2] >> 16), (uint8) (ints[2] >> 8), (uint8) ints[2], + (uint8) (ints[3] >> 24), (uint8) (ints[3] >> 16), (uint8) (ints[3] >> 8), (uint8) ints[3] }}; } //============================================================================== @@ -75,36 +82,36 @@ template class ComSmartPtr { public: - ComSmartPtr() throw() : p (0) {} - ComSmartPtr (ComClass* const obj) : p (obj) { if (p) p->AddRef(); } - ComSmartPtr (const ComSmartPtr& other) : p (other.p) { if (p) p->AddRef(); } - ~ComSmartPtr() { release(); } + ComSmartPtr() noexcept {} + ComSmartPtr (ComClass* obj) : p (obj) { if (p) p->AddRef(); } + ComSmartPtr (const ComSmartPtr& other) : p (other.p) { if (p) p->AddRef(); } + ~ComSmartPtr() { release(); } - operator ComClass*() const throw() { return p; } - ComClass& operator*() const throw() { return *p; } - ComClass* operator->() const throw() { return p; } + operator ComClass*() const noexcept { return p; } + ComClass& operator*() const noexcept { return *p; } + ComClass* operator->() const noexcept { return p; } ComSmartPtr& operator= (ComClass* const newP) { - if (newP != 0) newP->AddRef(); + if (newP != nullptr) newP->AddRef(); release(); p = newP; return *this; } - ComSmartPtr& operator= (const ComSmartPtr& newP) { return operator= (newP.p); } + ComSmartPtr& operator= (const ComSmartPtr& newP) { return operator= (newP.p); } // Releases and nullifies this pointer and returns its address ComClass** resetAndGetPointerAddress() { release(); - p = 0; + p = nullptr; return &p; } HRESULT CoCreateInstance (REFCLSID classUUID, DWORD dwClsContext = CLSCTX_INPROC_SERVER) { - HRESULT hr = ::CoCreateInstance (classUUID, 0, dwClsContext, __uuidof (ComClass), (void**) resetAndGetPointerAddress()); + auto hr = ::CoCreateInstance (classUUID, 0, dwClsContext, __uuidof (ComClass), (void**) resetAndGetPointerAddress()); jassert (hr != CO_E_NOTINITIALIZED); // You haven't called CoInitialize for the current thread! return hr; } @@ -112,7 +119,7 @@ public: template HRESULT QueryInterface (REFCLSID classUUID, ComSmartPtr& destObject) const { - if (p == 0) + if (p == nullptr) return E_POINTER; return p->QueryInterface (classUUID, (void**) destObject.resetAndGetPointerAddress()); @@ -125,11 +132,11 @@ public: } private: - ComClass* p; + ComClass* p = nullptr; - void release() { if (p != 0) p->Release(); } + void release() { if (p != nullptr) p->Release(); } - ComClass** operator&() throw(); // private to avoid it being used accidentally + ComClass** operator&() noexcept; // private to avoid it being used accidentally }; //============================================================================== @@ -144,7 +151,7 @@ public: virtual ~ComBaseClassHelperBase() {} ULONG __stdcall AddRef() { return ++refCount; } - ULONG __stdcall Release() { const ULONG r = --refCount; if (r == 0) delete this; return r; } + ULONG __stdcall Release() { auto r = --refCount; if (r == 0) delete this; return r; } protected: ULONG refCount; @@ -152,9 +159,9 @@ protected: JUCE_COMRESULT QueryInterface (REFIID refId, void** result) { if (refId == __uuidof (IUnknown)) - return castToType (result); + return castToType (result); - *result = 0; + *result = nullptr; return E_NOINTERFACE; } @@ -168,19 +175,17 @@ protected: /** Handy base class for writing COM objects, providing ref-counting and a basic QueryInterface method. */ template -class ComBaseClassHelper : public ComBaseClassHelperBase +class ComBaseClassHelper : public ComBaseClassHelperBase { public: - ComBaseClassHelper (unsigned int initialRefCount = 1) : ComBaseClassHelperBase (initialRefCount) {} + ComBaseClassHelper (unsigned int initialRefCount = 1) : ComBaseClassHelperBase (initialRefCount) {} ~ComBaseClassHelper() {} JUCE_COMRESULT QueryInterface (REFIID refId, void** result) { if (refId == __uuidof (ComClass)) - return this->template castToType (result); + return this->template castToType (result); - return ComBaseClassHelperBase ::QueryInterface (refId, result); + return ComBaseClassHelperBase::QueryInterface (refId, result); } }; - -#endif // JUCE_WIN32_COMSMARTPTR_H_INCLUDED diff --git a/source/modules/juce_core/native/juce_win32_Files.cpp b/source/modules/juce_core/native/juce_win32_Files.cpp index 50629ad07..5185d1208 100644 --- a/source/modules/juce_core/native/juce_win32_Files.cpp +++ b/source/modules/juce_core/native/juce_win32_Files.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -35,14 +27,28 @@ //============================================================================== namespace WindowsFileHelpers { - DWORD getAtts (const String& path) + DWORD getAtts (const String& path) noexcept { return GetFileAttributes (path.toWideCharPointer()); } - int64 fileTimeToTime (const FILETIME* const ft) + bool changeAtts (const String& path, DWORD bitsToSet, DWORD bitsToClear) noexcept { - static_jassert (sizeof (ULARGE_INTEGER) == sizeof (FILETIME)); // tell me if this fails! + auto oldAtts = getAtts (path); + + if (oldAtts == INVALID_FILE_ATTRIBUTES) + return false; + + auto newAtts = ((oldAtts | bitsToSet) & ~bitsToClear); + + return newAtts == oldAtts + || SetFileAttributes (path.toWideCharPointer(), newAtts) != FALSE; + } + + int64 fileTimeToTime (const FILETIME* const ft) noexcept + { + static_assert (sizeof (ULARGE_INTEGER) == sizeof (FILETIME), + "ULARGE_INTEGER is too small to hold FILETIME: please report!"); return (int64) ((reinterpret_cast (ft)->QuadPart - 116444736000000000LL) / 10000); } @@ -95,7 +101,7 @@ namespace WindowsFileHelpers if (SHGetSpecialFolderPath (0, path, type, FALSE)) return File (String (path)); - return File(); + return {}; } File getModuleFileName (HINSTANCE moduleHandle) @@ -148,7 +154,7 @@ bool File::hasWriteAccess() const if (fullPath.isEmpty()) return true; - const DWORD attr = WindowsFileHelpers::getAtts (fullPath); + auto attr = WindowsFileHelpers::getAtts (fullPath); // NB: According to MS, the FILE_ATTRIBUTE_READONLY attribute doesn't work for // folders, and can be incorrectly set for some special folders, so we'll just say @@ -158,17 +164,11 @@ bool File::hasWriteAccess() const || (attr & FILE_ATTRIBUTE_READONLY) == 0; } -bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const +bool File::setFileReadOnlyInternal (bool shouldBeReadOnly) const { - const DWORD oldAtts = WindowsFileHelpers::getAtts (fullPath); - - if (oldAtts == INVALID_FILE_ATTRIBUTES) - return false; - - const DWORD newAtts = shouldBeReadOnly ? (oldAtts | FILE_ATTRIBUTE_READONLY) - : (oldAtts & ~FILE_ATTRIBUTE_READONLY); - return newAtts == oldAtts - || SetFileAttributes (fullPath.toWideCharPointer(), newAtts) != FALSE; + return WindowsFileHelpers::changeAtts (fullPath, + shouldBeReadOnly ? FILE_ATTRIBUTE_READONLY : 0, + shouldBeReadOnly ? 0 : FILE_ATTRIBUTE_READONLY); } bool File::setFileExecutableInternal (bool /*shouldBeExecutable*/) const @@ -568,6 +568,7 @@ File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType type) case commonApplicationDataDirectory: csidlType = CSIDL_COMMON_APPDATA; break; case commonDocumentsDirectory: csidlType = CSIDL_COMMON_DOCUMENTS; break; case globalApplicationsDirectory: csidlType = CSIDL_PROGRAM_FILES; break; + case globalApplicationsDirectoryX86: csidlType = CSIDL_PROGRAM_FILESX86; break; case userMusicDirectory: csidlType = 0x0d; /*CSIDL_MYMUSIC*/ break; case userMoviesDirectory: csidlType = 0x0e; /*CSIDL_MYVIDEO*/ break; case userPicturesDirectory: csidlType = 0x27; /*CSIDL_MYPICTURES*/ break; @@ -598,7 +599,7 @@ File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType type) default: jassertfalse; // unknown type? - return File(); + return {}; } return WindowsFileHelpers::getSpecialFolderPath (csidlType); diff --git a/source/modules/juce_core/native/juce_win32_Network.cpp b/source/modules/juce_core/native/juce_win32_Network.cpp index 58cc18448..3aa2e2a7a 100644 --- a/source/modules/juce_core/native/juce_win32_Network.cpp +++ b/source/modules/juce_core/native/juce_win32_Network.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -41,14 +33,13 @@ class WebInputStream::Pimpl { public: Pimpl (WebInputStream& pimplOwner, const URL& urlToCopy, bool shouldBePost) - : statusCode (0), owner (pimplOwner), url (urlToCopy), connection (0), request (0), - position (0), finished (false), isPost (shouldBePost), timeOutMs (0), - httpRequestCmd (isPost ? "POST" : "GET"), numRedirectsToFollow (5) + : statusCode (0), owner (pimplOwner), url (urlToCopy), isPost (shouldBePost), + httpRequestCmd (isPost ? "POST" : "GET") {} ~Pimpl() { - close(); + closeConnection(); } //============================================================================== @@ -74,6 +65,13 @@ public: //============================================================================== bool connect (WebInputStream::Listener* listener) { + { + const ScopedLock lock (createConnectionLock); + + if (hasBeenCancelled) + return false; + } + String address = url.toString (! isPost); while (numRedirectsToFollow-- >= 0) @@ -189,7 +187,13 @@ public: void cancel() { - close(); + { + const ScopedLock lock (createConnectionLock); + + hasBeenCancelled = true; + + closeConnection(); + } } bool setPosition (int64 wantedPos) @@ -225,22 +229,25 @@ private: //============================================================================== WebInputStream& owner; const URL url; - HINTERNET connection, request; + HINTERNET connection = 0, request = 0; String headers; MemoryBlock postData; - int64 position; - bool finished; + int64 position = 0; + bool finished = false; const bool isPost; - int timeOutMs; + int timeOutMs = 0; String httpRequestCmd; - int numRedirectsToFollow; + int numRedirectsToFollow = 5; StringPairArray responseHeaders; + CriticalSection createConnectionLock; + bool hasBeenCancelled = false; - void close() + void closeConnection() { HINTERNET requestCopy = request; request = 0; + if (requestCopy != 0) InternetCloseHandle (requestCopy); @@ -255,7 +262,7 @@ private: { static HINTERNET sessionHandle = InternetOpen (_T("juce"), INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); - close(); + closeConnection(); if (sessionHandle != 0) { @@ -306,11 +313,18 @@ private: const bool isFtp = address.startsWithIgnoreCase ("ftp:"); - connection = InternetConnect (sessionHandle, uc.lpszHostName, uc.nPort, - uc.lpszUserName, uc.lpszPassword, - isFtp ? (DWORD) INTERNET_SERVICE_FTP - : (DWORD) INTERNET_SERVICE_HTTP, - 0, 0); + { + const ScopedLock lock (createConnectionLock); + + connection = hasBeenCancelled ? 0 + : InternetConnect (sessionHandle, + uc.lpszHostName, uc.nPort, + uc.lpszUserName, uc.lpszPassword, + isFtp ? (DWORD) INTERNET_SERVICE_FTP + : (DWORD) INTERNET_SERVICE_HTTP, + 0, 0); + } + if (connection != 0) { if (isFtp) @@ -331,19 +345,22 @@ private: const TCHAR* mimeTypes[] = { _T("*/*"), nullptr }; DWORD flags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES - | INTERNET_FLAG_NO_AUTO_REDIRECT | SECURITY_SET_MASK; + | INTERNET_FLAG_NO_AUTO_REDIRECT; if (address.startsWithIgnoreCase ("https:")) flags |= INTERNET_FLAG_SECURE; // (this flag only seems necessary if the OS is running IE6 - // IE7 seems to automatically work out when it's https) - request = HttpOpenRequest (connection, httpRequestCmd.toWideCharPointer(), - uc.lpszUrlPath, 0, 0, mimeTypes, flags, 0); + { + const ScopedLock lock (createConnectionLock); + + request = hasBeenCancelled ? 0 + : HttpOpenRequest (connection, httpRequestCmd.toWideCharPointer(), + uc.lpszUrlPath, 0, 0, mimeTypes, flags, 0); + } if (request != 0) { - setSecurityFlags(); - INTERNET_BUFFERS buffers = { 0 }; buffers.dwStructSize = sizeof (INTERNET_BUFFERS); buffers.lpcszHeader = headers.toWideCharPointer(); @@ -384,15 +401,7 @@ private: } } - close(); - } - - void setSecurityFlags() - { - DWORD dwFlags = 0, dwBuffLen = sizeof (DWORD); - InternetQueryOption (request, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, &dwBuffLen); - dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_SET_MASK; - InternetSetOption (request, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags)); + closeConnection(); } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) @@ -400,26 +409,26 @@ private: //============================================================================== -struct GetAdaptersInfoHelper +struct GetAdaptersAddressesHelper { - bool callGetAdaptersInfo() + bool callGetAdaptersAddresses() { DynamicLibrary dll ("iphlpapi.dll"); - JUCE_LOAD_WINAPI_FUNCTION (dll, GetAdaptersInfo, getAdaptersInfo, DWORD, (PIP_ADAPTER_INFO, PULONG)) + JUCE_LOAD_WINAPI_FUNCTION (dll, GetAdaptersAddresses, getAdaptersAddresses, DWORD, (ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG)) - if (getAdaptersInfo == nullptr) + if (getAdaptersAddresses == nullptr) return false; - adapterInfo.malloc (1); - ULONG len = sizeof (IP_ADAPTER_INFO); + adaptersAddresses.malloc (1); + ULONG len = sizeof (IP_ADAPTER_ADDRESSES); - if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW) - adapterInfo.malloc (len, 1); + if (getAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adaptersAddresses, &len) == ERROR_BUFFER_OVERFLOW) + adaptersAddresses.malloc (len, 1); - return getAdaptersInfo (adapterInfo, &len) == NO_ERROR; + return getAdaptersAddresses (AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adaptersAddresses, &len) == NO_ERROR; } - HeapBlock adapterInfo; + HeapBlock adaptersAddresses; }; namespace MACAddressHelpers @@ -430,15 +439,17 @@ namespace MACAddressHelpers result.addIfNotAlreadyThere (ma); } - static void getViaGetAdaptersInfo (Array& result) + static void getViaGetAdaptersAddresses (Array& result) { - GetAdaptersInfoHelper gah; + GetAdaptersAddressesHelper addressesHelper; - if (gah.callGetAdaptersInfo()) + if (addressesHelper.callGetAdaptersAddresses()) { - for (PIP_ADAPTER_INFO adapter = gah.adapterInfo; adapter != nullptr; adapter = adapter->Next) - if (adapter->AddressLength >= 6) - addAddress (result, MACAddress (adapter->Address)); + for (PIP_ADAPTER_ADDRESSES adapter = addressesHelper.adaptersAddresses; adapter != nullptr; adapter = adapter->Next) + { + if (adapter->PhysicalAddressLength >= 6) + addAddress (result, MACAddress (adapter->PhysicalAddress)); + } } } @@ -493,24 +504,108 @@ namespace MACAddressHelpers void MACAddress::findAllAddresses (Array& result) { - MACAddressHelpers::getViaGetAdaptersInfo (result); + MACAddressHelpers::getViaGetAdaptersAddresses (result); MACAddressHelpers::getViaNetBios (result); } -void IPAddress::findAllAddresses (Array& result) +void IPAddress::findAllAddresses (Array& result, bool includeIPv6) { result.addIfNotAlreadyThere (IPAddress::local()); - GetAdaptersInfoHelper gah; + if (includeIPv6) + result.addIfNotAlreadyThere (IPAddress::local (true)); - if (gah.callGetAdaptersInfo()) + GetAdaptersAddressesHelper addressesHelper; + if (addressesHelper.callGetAdaptersAddresses()) { - for (PIP_ADAPTER_INFO adapter = gah.adapterInfo; adapter != nullptr; adapter = adapter->Next) + for (PIP_ADAPTER_ADDRESSES adapter = addressesHelper.adaptersAddresses; adapter != nullptr; adapter = adapter->Next) { - IPAddress ip (adapter->IpAddressList.IpAddress.String); + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = nullptr; + for (pUnicast = adapter->FirstUnicastAddress; pUnicast != nullptr; pUnicast = pUnicast->Next) + { + if (pUnicast->Address.lpSockaddr->sa_family == AF_INET) + { + const sockaddr_in* sa_in = (sockaddr_in*)pUnicast->Address.lpSockaddr; + IPAddress ip ((uint8*)&sa_in->sin_addr.s_addr, false); + result.addIfNotAlreadyThere (ip); + } + else if (pUnicast->Address.lpSockaddr->sa_family == AF_INET6 && includeIPv6) + { + const sockaddr_in6* sa_in6 = (sockaddr_in6*)pUnicast->Address.lpSockaddr; + + ByteUnion temp; + uint16 arr[8]; + + for (int i = 0; i < 8; ++i) + { + temp.split[0] = sa_in6->sin6_addr.u.Byte[i * 2 + 1]; + temp.split[1] = sa_in6->sin6_addr.u.Byte[i * 2]; - if (ip != IPAddress::any()) - result.addIfNotAlreadyThere (ip); + arr[i] = temp.combined; + } + + IPAddress ip (arr); + result.addIfNotAlreadyThere (ip); + } + } + + PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = nullptr; + for (pAnycast = adapter->FirstAnycastAddress; pAnycast != nullptr; pAnycast = pAnycast->Next) + { + if (pAnycast->Address.lpSockaddr->sa_family == AF_INET) + { + const sockaddr_in* sa_in = (sockaddr_in*)pAnycast->Address.lpSockaddr; + IPAddress ip ((uint8*)&sa_in->sin_addr.s_addr, false); + result.addIfNotAlreadyThere (ip); + } + else if (pAnycast->Address.lpSockaddr->sa_family == AF_INET6 && includeIPv6) + { + const sockaddr_in6* sa_in6 = (sockaddr_in6*)pAnycast->Address.lpSockaddr; + + ByteUnion temp; + uint16 arr[8]; + + for (int i = 0; i < 8; ++i) + { + temp.split[0] = sa_in6->sin6_addr.u.Byte[i * 2 + 1]; + temp.split[1] = sa_in6->sin6_addr.u.Byte[i * 2]; + + arr[i] = temp.combined; + } + + IPAddress ip (arr); + result.addIfNotAlreadyThere (ip); + } + } + + PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = nullptr; + for (pMulticast = adapter->FirstMulticastAddress; pMulticast != nullptr; pMulticast = pMulticast->Next) + { + if (pMulticast->Address.lpSockaddr->sa_family == AF_INET) + { + const sockaddr_in* sa_in = (sockaddr_in*)pMulticast->Address.lpSockaddr; + IPAddress ip ((uint8*)&sa_in->sin_addr.s_addr, false); + result.addIfNotAlreadyThere (ip); + } + else if (pMulticast->Address.lpSockaddr->sa_family == AF_INET6 && includeIPv6) + { + const sockaddr_in6* sa_in6 = (sockaddr_in6*)pMulticast->Address.lpSockaddr; + + ByteUnion temp; + uint16 arr[8]; + + for (int i = 0; i < 8; ++i) + { + temp.split[0] = sa_in6->sin6_addr.u.Byte[i * 2 + 1]; + temp.split[1] = sa_in6->sin6_addr.u.Byte[i * 2]; + + arr[i] = temp.combined; + } + + IPAddress ip (arr); + result.addIfNotAlreadyThere (ip); + } + } } } } diff --git a/source/modules/juce_core/native/juce_win32_Registry.cpp b/source/modules/juce_core/native/juce_win32_Registry.cpp index 0f2864d57..91b2c1257 100644 --- a/source/modules/juce_core/native/juce_win32_Registry.cpp +++ b/source/modules/juce_core/native/juce_win32_Registry.cpp @@ -2,47 +2,38 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ struct RegistryKeyWrapper { - RegistryKeyWrapper (String name, const bool createForWriting, const DWORD wow64Flags) - : key (0), wideCharValueName (nullptr) + RegistryKeyWrapper (String name, bool createForWriting, DWORD wow64Flags) { if (HKEY rootKey = getRootKey (name)) { name = name.substring (name.indexOfChar ('\\') + 1); - const int lastSlash = name.lastIndexOfChar ('\\'); + auto lastSlash = name.lastIndexOfChar ('\\'); valueName = name.substring (lastSlash + 1); wideCharValueName = valueName.toWideCharPointer(); name = name.substring (0, lastSlash); - const wchar_t* const wideCharName = name.toWideCharPointer(); + auto wideCharName = name.toWideCharPointer(); DWORD result; if (createForWriting) @@ -96,8 +87,8 @@ struct RegistryKeyWrapper result.setSize (bufferSize, false); DWORD type = REG_NONE; - const LONG err = RegQueryValueEx (key.key, key.wideCharValueName, 0, &type, - (LPBYTE) result.getData(), &bufferSize); + auto err = RegQueryValueEx (key.key, key.wideCharValueName, 0, &type, + (LPBYTE) result.getData(), &bufferSize); if (err == ERROR_SUCCESS) { @@ -116,6 +107,7 @@ struct RegistryKeyWrapper static String getValue (const String& regValuePath, const String& defaultValue, DWORD wow64Flags) { MemoryBlock buffer; + switch (getBinaryValue (regValuePath, buffer, wow64Flags)) { case REG_SZ: return static_cast (buffer.getData()); @@ -142,14 +134,14 @@ struct RegistryKeyWrapper unsigned long bufferSize = sizeof (buffer); DWORD type = 0; - const LONG result = RegQueryValueEx (key.key, key.wideCharValueName, - 0, &type, buffer, &bufferSize); + auto result = RegQueryValueEx (key.key, key.wideCharValueName, + 0, &type, buffer, &bufferSize); return result == ERROR_SUCCESS || result == ERROR_MORE_DATA; } - HKEY key; - const wchar_t* wideCharValueName; + HKEY key = 0; + const wchar_t* wideCharValueName = nullptr; String valueName; JUCE_DECLARE_NON_COPYABLE (RegistryKeyWrapper) @@ -196,20 +188,36 @@ bool JUCE_CALLTYPE WindowsRegistry::keyExists (const String& regValuePath, WoW64 return RegistryKeyWrapper::keyExists (regValuePath, (DWORD) mode); } -void JUCE_CALLTYPE WindowsRegistry::deleteValue (const String& regValuePath, WoW64Mode mode) +bool JUCE_CALLTYPE WindowsRegistry::deleteValue (const String& regValuePath, WoW64Mode mode) { const RegistryKeyWrapper key (regValuePath, true, (DWORD) mode); - if (key.key != 0) - RegDeleteValue (key.key, key.wideCharValueName); + return key.key != 0 && RegDeleteValue (key.key, key.wideCharValueName) == ERROR_SUCCESS; } -void JUCE_CALLTYPE WindowsRegistry::deleteKey (const String& regKeyPath, WoW64Mode mode) +static bool deleteKeyNonRecursive (const String& regKeyPath, WindowsRegistry::WoW64Mode mode) { const RegistryKeyWrapper key (regKeyPath, true, (DWORD) mode); - if (key.key != 0) - RegDeleteKey (key.key, key.wideCharValueName); + return key.key != 0 && RegDeleteKey (key.key, key.wideCharValueName) == ERROR_SUCCESS; +} + +bool JUCE_CALLTYPE WindowsRegistry::deleteKey (const String& regKeyPath, WoW64Mode mode) +{ + if (deleteKeyNonRecursive (regKeyPath, mode)) + return true; + + for (const RegistryKeyWrapper key (regKeyPath + "\\", false, (DWORD) mode);;) + { + wchar_t subKey[MAX_PATH + 1] = {}; + DWORD subKeySize = MAX_PATH; + + if (RegEnumKeyEx (key.key, 0, subKey, &subKeySize, nullptr, nullptr, nullptr, nullptr) != ERROR_SUCCESS + || ! deleteKey (regKeyPath + "\\" + String (subKey), mode)) + break; + } + + return deleteKeyNonRecursive (regKeyPath, mode); } bool JUCE_CALLTYPE WindowsRegistry::registerFileAssociation (const String& fileExtension, @@ -220,9 +228,9 @@ bool JUCE_CALLTYPE WindowsRegistry::registerFileAssociation (const String& fileE const bool registerForCurrentUserOnly, WoW64Mode mode) { - const char* const root = registerForCurrentUserOnly ? "HKEY_CURRENT_USER\\Software\\Classes\\" - : "HKEY_CLASSES_ROOT\\"; - const String key (root + symbolicDescription); + auto root = registerForCurrentUserOnly ? "HKEY_CURRENT_USER\\Software\\Classes\\" + : "HKEY_CLASSES_ROOT\\"; + auto key = root + symbolicDescription; return setValue (root + fileExtension + "\\", symbolicDescription, mode) && setValue (key + "\\", fullDescription, mode) diff --git a/source/modules/juce_core/native/juce_win32_SystemStats.cpp b/source/modules/juce_core/native/juce_win32_SystemStats.cpp index 702fd7c03..7931d9cba 100644 --- a/source/modules/juce_core/native/juce_win32_SystemStats.cpp +++ b/source/modules/juce_core/native/juce_win32_SystemStats.cpp @@ -2,32 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ +#if ! JUCE_MINGW + #pragma intrinsic (__cpuid) + #pragma intrinsic (__rdtsc) +#endif + void Logger::outputDebugString (const String& text) { OutputDebugString ((text + "\n").toWideCharPointer()); @@ -40,8 +37,6 @@ void Logger::outputDebugString (const String& text) #endif //============================================================================== -#pragma intrinsic (__cpuid) -#pragma intrinsic (__rdtsc) #if JUCE_MINGW static void callCPUID (int result[4], uint32 type) @@ -62,7 +57,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 @@ -79,6 +78,49 @@ String SystemStats::getCpuVendor() return String (v, 12); } +String SystemStats::getCpuModel() +{ + char name[65] = { 0 }; + int info[4] = { 0 }; + + callCPUID (info, 0x80000000); + + const int numExtIDs = info[0]; + + if ((unsigned) numExtIDs < 0x80000004) // if brand string is unsupported + return {}; + + callCPUID (info, 0x80000002); + memcpy (name, info, sizeof (info)); + + callCPUID (info, 0x80000003); + memcpy (name + 16, info, sizeof (info)); + + callCPUID (info, 0x80000004); + memcpy (name + 32, info, sizeof (info)); + + return String (name).trim(); +} + +static int findNumberOfPhysicalCores() noexcept +{ + int numPhysicalCores = 0; + DWORD bufferSize = 0; + GetLogicalProcessorInformation (nullptr, &bufferSize); + + if (auto numBuffers = (size_t) (bufferSize / sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION))) + { + HeapBlock buffer (numBuffers); + + if (GetLogicalProcessorInformation (buffer, &bufferSize)) + for (size_t i = 0; i < numBuffers; ++i) + if (buffer[i].Relationship == RelationProcessorCore) + ++numPhysicalCores; + } + + return numPhysicalCores; +} + //============================================================================== void CPUInformation::initialise() noexcept { @@ -102,7 +144,11 @@ void CPUInformation::initialise() noexcept SYSTEM_INFO systemInfo; GetNativeSystemInfo (&systemInfo); - numCpus = (int) systemInfo.dwNumberOfProcessors; + numLogicalCPUs = (int) systemInfo.dwNumberOfProcessors; + numPhysicalCPUs = findNumberOfPhysicalCores(); + + if (numPhysicalCPUs <= 0) + numPhysicalCPUs = numLogicalCPUs; } #if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS @@ -118,59 +164,45 @@ static DebugFlagsInitialiser debugFlagsInitialiser; #endif //============================================================================== -static bool isWindowsVersionOrLater (SystemStats::OperatingSystemType target) +static uint32 getWindowsVersion() { - OSVERSIONINFOEX info; - zerostruct (info); - info.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); + auto filename = _T("kernel32.dll"); + DWORD handle = 0; - if (target >= SystemStats::Windows10) + if (auto size = GetFileVersionInfoSize (filename, &handle)) { - info.dwMajorVersion = 10; - info.dwMinorVersion = 0; - } - else if (target >= SystemStats::WinVista) - { - info.dwMajorVersion = 6; + HeapBlock data (size); - switch (target) + if (GetFileVersionInfo (filename, handle, size, data)) { - case SystemStats::WinVista: break; - case SystemStats::Windows7: info.dwMinorVersion = 1; break; - case SystemStats::Windows8_0: info.dwMinorVersion = 2; break; - case SystemStats::Windows8_1: info.dwMinorVersion = 3; break; - default: jassertfalse; break; + VS_FIXEDFILEINFO* info = nullptr; + UINT verSize = 0; + + if (VerQueryValue (data, (LPCTSTR) _T("\\"), (void**) &info, &verSize)) + if (size > 0 && info != nullptr && info->dwSignature == 0xfeef04bd) + return (uint32) info->dwFileVersionMS; } } - else - { - info.dwMajorVersion = 5; - info.dwMinorVersion = target >= SystemStats::WinXP ? 1 : 0; - } - - DWORDLONG mask = 0; - VER_SET_CONDITION (mask, VER_MAJORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION (mask, VER_MINORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION (mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - VER_SET_CONDITION (mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); - - return VerifyVersionInfo (&info, - VER_MAJORVERSION | VER_MINORVERSION - | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - mask) != FALSE; + return 0; } SystemStats::OperatingSystemType SystemStats::getOperatingSystemType() { - const SystemStats::OperatingSystemType types[] - = { Windows10, Windows8_1, Windows8_0, Windows7, WinVista, WinXP, Win2000 }; + auto v = getWindowsVersion(); + auto major = (v >> 16); + + jassert (major <= 10); // need to add support for new version! - for (int i = 0; i < numElementsInArray (types); ++i) - if (isWindowsVersionOrLater (types[i])) - return types[i]; + if (major == 10) return Windows10; + if (v == 0x00060003) return Windows8_1; + if (v == 0x00060002) return Windows8_0; + if (v == 0x00060001) return Windows7; + if (v == 0x00060000) return WinVista; + if (v == 0x00050000) return Win2000; + if (major == 5) return WinXP; - jassertfalse; // need to support whatever new version is running! + jassertfalse; return UnknownOS; } @@ -195,7 +227,7 @@ String SystemStats::getOperatingSystemName() String SystemStats::getDeviceDescription() { - return String(); + return {}; } bool SystemStats::isOperatingSystem64Bit() diff --git a/source/modules/juce_core/native/juce_win32_Threads.cpp b/source/modules/juce_core/native/juce_win32_Threads.cpp index 063c5b918..d38b733b8 100644 --- a/source/modules/juce_core/native/juce_win32_Threads.cpp +++ b/source/modules/juce_core/native/juce_win32_Threads.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -41,7 +33,8 @@ void* getUser32Function (const char* functionName) CriticalSection::CriticalSection() noexcept { // (just to check the MS haven't changed this structure and broken things...) - static_jassert (sizeof (CRITICAL_SECTION) <= sizeof (lock)); + static_assert (sizeof (CRITICAL_SECTION) <= sizeof (lock), + "win32 lock array too small to hold CRITICAL_SECTION: please report this JUCE bug!"); InitializeCriticalSection ((CRITICAL_SECTION*) lock); } diff --git a/source/modules/juce_core/network/juce_IPAddress.cpp b/source/modules/juce_core/network/juce_IPAddress.cpp index 5fcfd3f6d..92c68bab6 100644 --- a/source/modules/juce_core/network/juce_IPAddress.cpp +++ b/source/modules/juce_core/network/juce_IPAddress.cpp @@ -2,87 +2,240 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -IPAddress::IPAddress() noexcept +IPAddress::IPAddress (bool IPv6) noexcept : isIPv6 (IPv6) +{ + for (int i = 0; i < 16; ++i) + address[i] = 0; +} + +IPAddress::IPAddress (const uint8 bytes[], bool IPv6) noexcept : isIPv6 (IPv6) { - address[0] = 0; address[1] = 0; - address[2] = 0; address[3] = 0; + for (int i = 0; i < (isIPv6 ? 16 : 4); ++i) + address[i] = bytes[i]; + + if (! isIPv6) + zeroUnusedBytes(); } -IPAddress::IPAddress (const uint8 bytes[4]) noexcept +IPAddress::IPAddress (const uint16 bytes[8]) noexcept : isIPv6 (true) { - address[0] = bytes[0]; address[1] = bytes[1]; - address[2] = bytes[2]; address[3] = bytes[3]; + ByteUnion temp; + + for (int i = 0; i < 8; ++i) + { + temp.combined = bytes[i]; + + address[i * 2] = temp.split[0]; + address[i * 2 + 1] = temp.split[1]; + } } -IPAddress::IPAddress (uint8 a0, uint8 a1, uint8 a2, uint8 a3) noexcept +IPAddress::IPAddress (uint8 a0, uint8 a1, uint8 a2, uint8 a3) noexcept : isIPv6 (false) { address[0] = a0; address[1] = a1; address[2] = a2; address[3] = a3; + + zeroUnusedBytes(); +} + +IPAddress::IPAddress (uint16 a1, uint16 a2, uint16 a3, uint16 a4, + uint16 a5, uint16 a6, uint16 a7, uint16 a8) noexcept : isIPv6 (true) + +{ + uint16 array[8] = { a1, a2, a3, a4, a5, a6, a7, a8 }; + + ByteUnion temp; + + for (int i = 0; i < 8; ++i) + { + temp.combined = array[i]; + address[i * 2] = temp.split[0]; + address[i * 2 + 1] = temp.split[1]; + } } -IPAddress::IPAddress (uint32 n) noexcept +IPAddress::IPAddress (uint32 n) noexcept : isIPv6 (false) { address[0] = (n >> 24); address[1] = (n >> 16) & 255; - address[2] = (n >> 8) & 255; + address[2] = (n >> 8) & 255; address[3] = (n & 255); + + zeroUnusedBytes(); } IPAddress::IPAddress (const String& adr) { - StringArray tokens; - tokens.addTokens (adr, ".", String()); + isIPv6 = adr.contains (":"); + + if (! isIPv6) + { + StringArray tokens; + tokens.addTokens (adr, ".", String()); + + for (int i = 0; i < 4; ++i) + address[i] = (uint8) tokens[i].getIntValue(); + } + else + { + StringArray tokens; + tokens.addTokens (adr.removeCharacters ("[]"), ":", String()); + + if (tokens.contains (StringRef())) // if :: shorthand has been used + { + int idx = tokens.indexOf (StringRef()); + tokens.set (idx, "0"); + + while (tokens.size() < 8) + tokens.insert (idx, "0"); + } - for (int i = 0; i < 4; ++i) - address[i] = (uint8) tokens[i].getIntValue(); + for (int i = 0; i < 8; ++i) + { + ByteUnion temp; + temp.combined = (uint16) CharacterFunctions::HexParser::parse (tokens[i].getCharPointer()); + + address[i * 2] = temp.split[0]; + address[i * 2 + 1] = temp.split[1]; + } + } } String IPAddress::toString() const { - String s ((int) address[0]); + if (! isIPv6) + { + String s ((int) address[0]); - for (int i = 1; i < 4; ++i) - s << '.' << (int) address[i]; + for (int i = 1; i < 4; ++i) + s << '.' << (int) address[i]; + + return s; + } - return s; + String addressString; + ByteUnion temp; + + temp.split[0] = address[0]; + temp.split[1] = address[1]; + + addressString = String (String::toHexString (temp.combined)); + + for (int i = 1; i < 8; ++i) + { + temp.split[0] = address[i * 2]; + temp.split[1] = address[i * 2 + 1]; + + addressString << ':' << String (String::toHexString (temp.combined)); + } + + return getFormattedAddress (addressString); } -IPAddress IPAddress::any() noexcept { return IPAddress(); } -IPAddress IPAddress::broadcast() noexcept { return IPAddress (255, 255, 255, 255); } -IPAddress IPAddress::local() noexcept { return IPAddress (127, 0, 0, 1); } +IPAddress IPAddress::any (bool IPv6) noexcept { return IPAddress (IPv6); } +IPAddress IPAddress::broadcast() noexcept { return IPAddress (255, 255, 255, 255); } +IPAddress IPAddress::local (bool IPv6) noexcept { return IPv6 ? IPAddress (0, 0, 0, 0, 0, 0, 0, 1) + : IPAddress (127, 0, 0, 1); } + +String IPAddress::getFormattedAddress (const String& unformattedAddress) +{ + jassert (unformattedAddress.contains (":") && ! unformattedAddress.contains ("::")); // needs to be an unformatted IPv6 address! + + String portString = unformattedAddress.fromFirstOccurrenceOf ("]", false, true); + String addressString = unformattedAddress.dropLastCharacters (portString.length()).removeCharacters ("[]"); + + StringArray tokens; + tokens.addTokens (addressString, ":", String()); + + int numZeros = 0; + int numZerosTemp = 0; + bool isFirst = false; + bool isLast = false; + + for (int i = 0; i < tokens.size(); ++i) + { + String t = tokens.getReference (i); + + if (t.getHexValue32() == 0x0000) + { + ++numZeros; + + if (i == 0) + isFirst = true; + else if (i == tokens.size() - 1 && numZeros > numZerosTemp) + isLast = true; + + if (t.length() > 1) + addressString = addressString.replace (String::repeatedString ("0", t.length()), "0"); + + if (isFirst && numZerosTemp != 0 && numZeros > numZerosTemp) + isFirst = false; + } + else + { + addressString = addressString.replace (t, t.trimCharactersAtStart ("0").toLowerCase()); + + if (numZeros > 0) + { + if (numZeros > numZerosTemp) + numZerosTemp = numZeros; + + numZeros = 0; + } + } + } + + if (numZerosTemp > numZeros) + numZeros = numZerosTemp; + + if (numZeros > 1) + { + if (numZeros == tokens.size()) + addressString = "::,"; + else + { + String zeroString = isFirst ? String ("0") + String::repeatedString (":0", numZeros - 1) + : String::repeatedString (":0", numZeros); + + addressString = addressString.replaceFirstOccurrenceOf (zeroString, ":"); + + if (isLast) + addressString += String (":"); + } + } + + if (portString.isNotEmpty()) + addressString = String ("[") + addressString + String ("]") + portString; + + return addressString; +} bool IPAddress::operator== (const IPAddress& other) const noexcept { - return address[0] == other.address[0] - && address[1] == other.address[1] - && address[2] == other.address[2] - && address[3] == other.address[3]; + for (int i = 0; i < (isIPv6 ? 16 : 4); ++i) + if (address[i] != other.address[i]) + return false; + + return true; + } bool IPAddress::operator!= (const IPAddress& other) const noexcept @@ -90,7 +243,7 @@ bool IPAddress::operator!= (const IPAddress& other) const noexcept return ! operator== (other); } -#if ! JUCE_WINDOWS +#if (! JUCE_WINDOWS) && (! JUCE_ANDROID) static void addAddress (const sockaddr_in* addr_in, Array& result) { in_addr_t addr = addr_in->sin_addr.s_addr; @@ -99,53 +252,47 @@ static void addAddress (const sockaddr_in* addr_in, Array& result) result.addIfNotAlreadyThere (IPAddress (ntohl (addr))); } -static void findIPAddresses (int sock, Array& result) +static void addAddress (const sockaddr_in6* addr_in, Array& result) { - ifconf cfg; - HeapBlock buffer; - int bufferSize = 1024; + in6_addr addr = addr_in->sin6_addr; - do + typedef union { - bufferSize *= 2; - buffer.calloc ((size_t) bufferSize); - - cfg.ifc_len = bufferSize; - cfg.ifc_buf = buffer; + uint16 combined; + uint8 split[2]; + } ByteUnion; - if (ioctl (sock, SIOCGIFCONF, &cfg) < 0 && errno != EINVAL) - return; + ByteUnion temp; + uint16 arr[8]; - } while (bufferSize < cfg.ifc_len + 2 * (int) (IFNAMSIZ + sizeof (struct sockaddr_in6))); - - #if JUCE_MAC || JUCE_IOS - while (cfg.ifc_len >= (int) (IFNAMSIZ + sizeof (struct sockaddr_in))) + for (int i = 0; i < 8; ++i) // Swap bytes from network to host order { - if (cfg.ifc_req->ifr_addr.sa_family == AF_INET) // Skip non-internet addresses - addAddress ((const sockaddr_in*) &cfg.ifc_req->ifr_addr, result); + temp.split[0] = addr.s6_addr[i * 2 + 1]; + temp.split[1] = addr.s6_addr[i * 2]; - cfg.ifc_len -= IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len; - cfg.ifc_buf += IFNAMSIZ + cfg.ifc_req->ifr_addr.sa_len; + arr[i] = temp.combined; } - #else - for (size_t i = 0; i < (size_t) cfg.ifc_len / (size_t) sizeof (struct ifreq); ++i) - { - const ifreq& item = cfg.ifc_req[i]; - if (item.ifr_addr.sa_family == AF_INET) - addAddress ((const sockaddr_in*) &item.ifr_addr, result); - } - #endif + IPAddress ip (arr); + result.addIfNotAlreadyThere (ip); } -void IPAddress::findAllAddresses (Array& result) +void IPAddress::findAllAddresses (Array& result, bool includeIPv6) { - const int sock = socket (AF_INET, SOCK_DGRAM, 0); // a dummy socket to execute the IO control + struct ifaddrs *ifaddr, *ifa; + + if (getifaddrs (&ifaddr) == -1) + return; - if (sock >= 0) + for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { - findIPAddresses (sock, result); - ::close (sock); + if (ifa->ifa_addr == nullptr) + continue; + + if (ifa->ifa_addr->sa_family == AF_INET) addAddress ((const sockaddr_in*) ifa->ifa_addr, result); + else if (ifa->ifa_addr->sa_family == AF_INET6 && includeIPv6) addAddress ((const sockaddr_in6*) ifa->ifa_addr, result); } + + freeifaddrs (ifaddr); } #endif diff --git a/source/modules/juce_core/network/juce_IPAddress.h b/source/modules/juce_core/network/juce_IPAddress.h index e1cb38709..a450ff7d1 100644 --- a/source/modules/juce_core/network/juce_IPAddress.h +++ b/source/modules/juce_core/network/juce_IPAddress.h @@ -2,83 +2,109 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IPADDRESS_H_INCLUDED -#define JUCE_IPADDRESS_H_INCLUDED +#pragma once //============================================================================== /** - An IPV4 address. + Represents an IP address. */ class JUCE_API IPAddress { public: //============================================================================== /** Populates a list of all the IP addresses that this machine is using. */ - static void findAllAddresses (Array& results); + static void findAllAddresses (Array& results, bool includeIPv6 = false); //============================================================================== - /** Creates a null address (0.0.0.0). */ - IPAddress() noexcept; + /** Creates a null address - 0.0.0.0 (IPv4) or ::, (IPv6) + @param IPv6 if true indicates that this is an IPv6 address + */ + IPAddress (bool IPv6 = false) noexcept; - /** Creates an address from 4 bytes. */ - explicit IPAddress (const uint8 bytes[4]) noexcept; + /** Creates an IPv4 or IPv6 address by reading 4 or 16 bytes from an array. + @param bytes The array containing the bytes to read. + @param IPv6 if true indicates that 16 bytes should be read instead of 4. + */ + explicit IPAddress (const uint8 bytes[], bool IPv6 = false) noexcept; + + /** Creates an IPv6 address from an array of 8 16-bit integers + @param bytes The array containing the bytes to read. + */ + explicit IPAddress (const uint16 bytes[8]) noexcept; - /** Creates an address from 4 bytes. */ + /** Creates an IPv4 address from 4 bytes. */ IPAddress (uint8 address1, uint8 address2, uint8 address3, uint8 address4) noexcept; - /** Creates an address from a packed 32-bit integer, where the MSB is - the first number in the address, and the LSB is the last. + /** Creates an IPv6 address from 8 16-bit integers */ + IPAddress (uint16 address1, uint16 address2, uint16 address3, uint16 address4, + uint16 address5, uint16 address6, uint16 address7, uint16 address8) noexcept; + + /** Creates an IPv4 address from a packed 32-bit integer, where the + MSB is the first number in the address, and the LSB is the last. */ explicit IPAddress (uint32 asNativeEndian32Bit) noexcept; - /** Parses a string IP address of the form "a.b.c.d". */ + /** Parses a string IP address of the form "1.2.3.4" (IPv4) or "1:2:3:4:5:6:7:8" (IPv6). */ explicit IPAddress (const String& address); - /** Returns a dot-separated string in the form "1.2.3.4" */ + /** Returns a dot- or colon-separated string in the form "1.2.3.4" (IPv4) or "1:2:3:4:5:6:7:8" (IPv6). */ String toString() const; - /** Returns an address meaning "any" (0.0.0.0) */ - static IPAddress any() noexcept; + /** Returns an IPv4 or IPv6 address meaning "any", equivalent to 0.0.0.0 (IPv4) or ::, (IPv6) */ + static IPAddress any (bool IPv6 = false) noexcept; - /** Returns an address meaning "broadcast" (255.255.255.255) */ + /** Returns an IPv4 address meaning "broadcast" (255.255.255.255) */ static IPAddress broadcast() noexcept; - /** Returns an address meaning "localhost" (127.0.0.1) */ - static IPAddress local() noexcept; + /** Returns an IPv4 or IPv6 address meaning "localhost", equivalent to 127.0.0.1 (IPv4) or ::1 (IPv6) */ + static IPAddress local (bool IPv6 = false) noexcept; + + /** Returns a formatted version of the provided IPv6 address conforming to RFC 5952 with leading zeros suppressed, + lower case characters, and double-colon notation used to represent contiguous 16-bit fields of zeros. + + @param unformattedAddress the IPv6 address to be formatted + */ + static String getFormattedAddress (const String& unformattedAddress); bool operator== (const IPAddress& other) const noexcept; bool operator!= (const IPAddress& other) const noexcept; /** The elements of the IP address. */ - uint8 address[4]; + uint8 address[16]; + + bool isIPv6; + +private: + /** Union used to split a 16-bit unsigned integer into 2 8-bit unsigned integers or vice-versa */ + typedef union + { + uint16 combined; + uint8 split[2]; + } ByteUnion; + + /** Method used to zero the remaining bytes of the address array when creating IPv4 addresses */ + void zeroUnusedBytes() + { + for (int i = 4; i < 16; ++i) + address[i] = 0; + } }; - - -#endif // JUCE_IPADDRESS_H_INCLUDED diff --git a/source/modules/juce_core/network/juce_MACAddress.cpp b/source/modules/juce_core/network/juce_MACAddress.cpp index 60a55589d..62b0e24ea 100644 --- a/source/modules/juce_core/network/juce_MACAddress.cpp +++ b/source/modules/juce_core/network/juce_MACAddress.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/network/juce_MACAddress.h b/source/modules/juce_core/network/juce_MACAddress.h index 3466c00d7..7a709b01c 100644 --- a/source/modules/juce_core/network/juce_MACAddress.h +++ b/source/modules/juce_core/network/juce_MACAddress.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MACADDRESS_H_INCLUDED -#define JUCE_MACADDRESS_H_INCLUDED +#pragma once //============================================================================== @@ -88,6 +79,3 @@ public: private: uint8 address[6]; }; - - -#endif // JUCE_MACADDRESS_H_INCLUDED diff --git a/source/modules/juce_core/network/juce_NamedPipe.cpp b/source/modules/juce_core/network/juce_NamedPipe.cpp index 5ca4f57f3..434fdb606 100644 --- a/source/modules/juce_core/network/juce_NamedPipe.cpp +++ b/source/modules/juce_core/network/juce_NamedPipe.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/network/juce_NamedPipe.h b/source/modules/juce_core/network/juce_NamedPipe.h index 266d1df4d..af09f4900 100644 --- a/source/modules/juce_core/network/juce_NamedPipe.h +++ b/source/modules/juce_core/network/juce_NamedPipe.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_NAMEDPIPE_H_INCLUDED -#define JUCE_NAMEDPIPE_H_INCLUDED +#pragma once //============================================================================== @@ -103,6 +94,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NamedPipe) }; - - -#endif // JUCE_NAMEDPIPE_H_INCLUDED diff --git a/source/modules/juce_core/network/juce_Socket.cpp b/source/modules/juce_core/network/juce_Socket.cpp index a3d1ad851..19723b69b 100644 --- a/source/modules/juce_core/network/juce_Socket.cpp +++ b/source/modules/juce_core/network/juce_Socket.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -39,10 +31,17 @@ #if JUCE_WINDOWS typedef int juce_socklen_t; + typedef int juce_recvsend_size_t; typedef SOCKET SocketHandle; static const SocketHandle invalidSocket = INVALID_SOCKET; +#elif JUCE_ANDROID + typedef socklen_t juce_socklen_t; + typedef size_t juce_recvsend_size_t; + typedef int SocketHandle; + static const SocketHandle invalidSocket = -1; #else typedef socklen_t juce_socklen_t; + typedef socklen_t juce_recvsend_size_t; typedef int SocketHandle; static const SocketHandle invalidSocket = -1; #endif @@ -101,7 +100,7 @@ namespace SocketHelpers #if JUCE_WINDOWS ignoreUnused (portNumber, isListener, readLock); - if (h != SOCKET_ERROR || connected) + if (h != (unsigned) SOCKET_ERROR || connected) closesocket (h); // make sure any read process finishes before we delete the socket @@ -198,7 +197,7 @@ namespace SocketHelpers { long bytesThisTime = -1; char* const buffer = static_cast (destBuffer) + bytesRead; - const juce_socklen_t numToRead = (juce_socklen_t) (maxBytesToRead - bytesRead); + const juce_recvsend_size_t numToRead = (juce_recvsend_size_t) (maxBytesToRead - bytesRead); { // avoid race-condition @@ -467,7 +466,7 @@ int StreamingSocket::write (const void* sourceBuffer, const int numBytesToWrite) if (isListener || ! connected) return -1; - return (int) ::send (handle, (const char*) sourceBuffer, (juce_socklen_t) numBytesToWrite, 0); + return (int) ::send (handle, (const char*) sourceBuffer, (juce_recvsend_size_t) numBytesToWrite, 0); } //============================================================================== @@ -730,7 +729,7 @@ int DatagramSocket::write (const String& remoteHostname, int remotePortNumber, } return (int) ::sendto (handle, (const char*) sourceBuffer, - (juce_socklen_t) numBytesToWrite, 0, + (juce_recvsend_size_t) numBytesToWrite, 0, info->ai_addr, (socklen_t) info->ai_addrlen); } @@ -752,7 +751,9 @@ bool DatagramSocket::leaveMulticast (const String& multicastIPAddress) bool DatagramSocket::setEnablePortReuse (bool enabled) { - #if ! JUCE_ANDROID + #if JUCE_ANDROID + ignoreUnused (enabled); + #else if (handle >= 0) return SocketHelpers::setOption (handle, #if JUCE_WINDOWS || JUCE_LINUX diff --git a/source/modules/juce_core/network/juce_Socket.h b/source/modules/juce_core/network/juce_Socket.h index 299263ae7..66d259fdb 100644 --- a/source/modules/juce_core/network/juce_Socket.h +++ b/source/modules/juce_core/network/juce_Socket.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SOCKET_H_INCLUDED -#define JUCE_SOCKET_H_INCLUDED +#pragma once //============================================================================== @@ -357,6 +348,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DatagramSocket) }; - - -#endif // JUCE_SOCKET_H_INCLUDED diff --git a/source/modules/juce_core/network/juce_URL.cpp b/source/modules/juce_core/network/juce_URL.cpp index 96e052e86..05ace9426 100644 --- a/source/modules/juce_core/network/juce_URL.cpp +++ b/source/modules/juce_core/network/juce_URL.cpp @@ -2,33 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -//============================================================================== struct FallbackDownloadTask : public URL::DownloadTask, public Thread { @@ -38,15 +29,18 @@ struct FallbackDownloadTask : public URL::DownloadTask, URL::DownloadTask::Listener* listenerToUse) : Thread ("DownloadTask thread"), fileStream (outputStreamToUse), + stream (streamToUse), bufferSize (bufferSizeToUse), buffer (bufferSize), - stream (streamToUse), listener (listenerToUse) { + jassert (fileStream != nullptr); + jassert (stream != nullptr); + contentLength = stream->getTotalLength(); httpCode = stream->getStatusCode(); - startThread (); + startThread(); } ~FallbackDownloadTask() @@ -59,7 +53,7 @@ struct FallbackDownloadTask : public URL::DownloadTask, //============================================================================== void run() override { - while (! stream->isExhausted() && ! stream->isError() && ! threadShouldExit()) + while (! (stream->isExhausted() || stream->isError() || threadShouldExit())) { if (listener != nullptr) listener->progress (this, downloaded, contentLength); @@ -69,7 +63,7 @@ struct FallbackDownloadTask : public URL::DownloadTask, const int actual = stream->read (buffer.getData(), max); - if (threadShouldExit() || stream->isError()) + if (actual < 0 || threadShouldExit() || stream->isError()) break; if (! fileStream->write (buffer.getData(), static_cast (actual))) @@ -83,7 +77,7 @@ struct FallbackDownloadTask : public URL::DownloadTask, fileStream->flush(); - if (threadShouldExit() || (stream != nullptr && stream->isError())) + if (threadShouldExit() || stream->isError()) error = true; if (contentLength > 0 && downloaded < contentLength) @@ -96,11 +90,13 @@ struct FallbackDownloadTask : public URL::DownloadTask, } //============================================================================== - ScopedPointer fileStream; - size_t bufferSize; + const ScopedPointer fileStream; + const ScopedPointer stream; + const size_t bufferSize; HeapBlock buffer; - ScopedPointer stream; - URL::DownloadTask::Listener* listener; + URL::DownloadTask::Listener* const listener; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FallbackDownloadTask) }; void URL::DownloadTask::Listener::progress (DownloadTask*, int64, int64) {} @@ -146,18 +142,15 @@ URL::URL (const String& u) : url (u) const int nextAmp = url.indexOfChar (i + 1, '&'); const int equalsPos = url.indexOfChar (i + 1, '='); - if (equalsPos > i + 1) + if (nextAmp < 0) + { + addParameter (removeEscapeChars (equalsPos < 0 ? url.substring (i + 1) : url.substring (i + 1, equalsPos)), + equalsPos < 0 ? String() : removeEscapeChars (url.substring (equalsPos + 1))); + } + else if (nextAmp > 0 && equalsPos < nextAmp) { - if (nextAmp < 0) - { - addParameter (removeEscapeChars (url.substring (i + 1, equalsPos)), - removeEscapeChars (url.substring (equalsPos + 1))); - } - else if (nextAmp > 0 && equalsPos < nextAmp) - { - addParameter (removeEscapeChars (url.substring (i + 1, equalsPos)), - removeEscapeChars (url.substring (equalsPos + 1, nextAmp))); - } + addParameter (removeEscapeChars (equalsPos < 0 ? url.substring (i + 1, nextAmp) : url.substring (i + 1, equalsPos)), + equalsPos < 0 ? String() : removeEscapeChars (url.substring (equalsPos + 1, nextAmp))); } i = nextAmp; @@ -225,9 +218,12 @@ namespace URLHelpers if (i > 0) p << '&'; - p << URL::addEscapeChars (url.getParameterNames()[i], true) - << '=' - << URL::addEscapeChars (url.getParameterValues()[i], true); + auto val = url.getParameterValues()[i]; + + p << URL::addEscapeChars (url.getParameterNames()[i], true); + + if (val.isNotEmpty()) + p << '=' << URL::addEscapeChars (val, true); } return p; @@ -522,7 +518,7 @@ String URL::readEntireTextStream (const bool usePostCommand) const if (in != nullptr) return in->readEntireStreamAsString(); - return String(); + return {}; } XmlElement* URL::readEntireXmlStream (const bool usePostCommand) const diff --git a/source/modules/juce_core/network/juce_URL.h b/source/modules/juce_core/network/juce_URL.h index b69a25bff..80430bbe1 100644 --- a/source/modules/juce_core/network/juce_URL.h +++ b/source/modules/juce_core/network/juce_URL.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_URL_H_INCLUDED -#define JUCE_URL_H_INCLUDED +#pragma once class WebInputStream; //============================================================================== @@ -241,10 +232,10 @@ public: URL withPOSTData (const MemoryBlock& postData) const; /** Returns the data that was set using withPOSTData(). */ - String getPostData() const noexcept { return postData.toString(); } + String getPostData() const noexcept { return postData.toString(); } /** Returns the data that was set using withPOSTData() as MemoryBlock. */ - const MemoryBlock& getPostDataAsMemoryBlock() const noexcept { return postData; } + const MemoryBlock& getPostDataAsMemoryBlock() const noexcept { return postData; } //============================================================================== /** Tries to launch the system's default browser to open the URL. @@ -376,7 +367,7 @@ public: bool finished, error; int httpCode; - DownloadTask (); + DownloadTask(); private: friend class URL; @@ -394,14 +385,14 @@ public: /** Download the URL to a file. - This method attempts to download the URL to a given file location. + This method attempts to download the URL to a given file location. - Using this method to download files on mobile is less flexible but more reliable - than using createInputStream or WebInputStreams as it will attempt to download the file - using a native OS background network task. Such tasks automatically deal with - network re-connections and continuing your download while your app is suspended but are - limited to simple GET requests. - */ + Using this method to download files on mobile is less flexible but more reliable + than using createInputStream or WebInputStreams as it will attempt to download the file + using a native OS background network task. Such tasks automatically deal with + network re-connections and continuing your download while your app is suspended but are + limited to simple GET requests. + */ DownloadTask* downloadToFile (const File& targetLocation, String extraHeaders = String(), DownloadTask::Listener* listener = nullptr); @@ -442,7 +433,7 @@ public: /** Tries to download the entire contents of this URL and parse it as XML. If it fails, or if the text that it reads can't be parsed as XML, this will - return 0. + return nullptr. When it returns a valid XmlElement object, the caller is responsibile for deleting this object when no longer needed. @@ -525,5 +516,3 @@ private: JUCE_LEAK_DETECTOR (URL) }; - -#endif // JUCE_URL_H_INCLUDED diff --git a/source/modules/juce_core/network/juce_WebInputStream.cpp b/source/modules/juce_core/network/juce_WebInputStream.cpp index 40673444d..4a7aafc1f 100644 --- a/source/modules/juce_core/network/juce_WebInputStream.cpp +++ b/source/modules/juce_core/network/juce_WebInputStream.cpp @@ -2,34 +2,26 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ WebInputStream::WebInputStream (const URL& url, const bool usePost) - : pimpl (new Pimpl(*this, url, usePost)), hasCalledConnect (false) + : pimpl (new Pimpl (*this, url, usePost)), hasCalledConnect (false) {} WebInputStream::~WebInputStream() @@ -37,7 +29,7 @@ WebInputStream::~WebInputStream() delete pimpl; } -WebInputStream& WebInputStream::withExtraHeaders (const String& extra) { pimpl->withExtraHeaders (extra); return *this; } +WebInputStream& WebInputStream::withExtraHeaders (const String& extra) { pimpl->withExtraHeaders (extra); return *this; } WebInputStream& WebInputStream::withCustomRequestCommand (const String& cmd) { pimpl->withCustomRequestCommand(cmd); return *this; } WebInputStream& WebInputStream::withConnectionTimeout (int t) { pimpl->withConnectionTimeout (t); return *this; } WebInputStream& WebInputStream::withNumRedirectsToFollow (int num) { pimpl->withNumRedirectsToFollow (num); return *this; } @@ -73,7 +65,7 @@ StringPairArray WebInputStream::parseHttpHeaders (const String& headerData) if (headersEntry.isNotEmpty()) { - const String key (headersEntry.upToFirstOccurrenceOf (": ", false, false)); + const String key (headersEntry.upToFirstOccurrenceOf (": ", false, false)); const String value (headersEntry.fromFirstOccurrenceOf (": ", false, false)); const String previousValue (headerPairs [key]); headerPairs.set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); diff --git a/source/modules/juce_core/network/juce_WebInputStream.h b/source/modules/juce_core/network/juce_WebInputStream.h index 083993aa1..5d013ea4a 100644 --- a/source/modules/juce_core/network/juce_WebInputStream.h +++ b/source/modules/juce_core/network/juce_WebInputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_WEBINPUTSTREAM_H_INCLUDED -#define JUCE_WEBINPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== /** @@ -131,7 +122,7 @@ class JUCE_API WebInputStream : public InputStream an error has occurred. Note that most methods will call connect internally if they are called without - an established connection. Therefore, it is not necessary to explicitely + an established connection. Therefore, it is not necessary to explicitly call connect unless you would like to use a custom listener. After a successful call to connect, getResponseHeaders, getTotalLength and @@ -144,10 +135,10 @@ class JUCE_API WebInputStream : public InputStream */ bool connect (Listener* listener); - /** Returns true if there was an error during the connection attempt */ + /** Returns true if there was an error during the connection attempt. */ bool isError() const; - /** Will cancel a blocking read. */ + /** Will cancel a blocking read and prevent any subsequent connection attempts. */ void cancel(); //============================================================================== @@ -217,5 +208,3 @@ class JUCE_API WebInputStream : public InputStream JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WebInputStream) }; - -#endif // JUCE_WEBINPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/streams/juce_BufferedInputStream.cpp b/source/modules/juce_core/streams/juce_BufferedInputStream.cpp index cd38911f5..b17c52691 100644 --- a/source/modules/juce_core/streams/juce_BufferedInputStream.cpp +++ b/source/modules/juce_core/streams/juce_BufferedInputStream.cpp @@ -2,71 +2,51 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -namespace +static inline int calcBufferStreamBufferSize (int requestedSize, InputStream* source) noexcept { - int calcBufferStreamBufferSize (int requestedSize, InputStream* const source) noexcept - { - // You need to supply a real stream when creating a BufferedInputStream - jassert (source != nullptr); + // You need to supply a real stream when creating a BufferedInputStream + jassert (source != nullptr); - requestedSize = jmax (256, requestedSize); + requestedSize = jmax (256, requestedSize); + auto sourceSize = source->getTotalLength(); - const int64 sourceSize = source->getTotalLength(); - if (sourceSize >= 0 && sourceSize < requestedSize) - requestedSize = jmax (32, (int) sourceSize); + if (sourceSize >= 0 && sourceSize < requestedSize) + return jmax (32, (int) sourceSize); - return requestedSize; - } + return requestedSize; } //============================================================================== -BufferedInputStream::BufferedInputStream (InputStream* const sourceStream, const int bufferSize_, - const bool deleteSourceWhenDestroyed) - : source (sourceStream, deleteSourceWhenDestroyed), - bufferSize (calcBufferStreamBufferSize (bufferSize_, sourceStream)), +BufferedInputStream::BufferedInputStream (InputStream* sourceStream, int size, bool takeOwnership) + : source (sourceStream, takeOwnership), + bufferSize (calcBufferStreamBufferSize (size, sourceStream)), position (sourceStream->getPosition()), - lastReadPos (0), - bufferStart (position), - bufferOverlap (128) + bufferStart (position) { buffer.malloc ((size_t) bufferSize); } -BufferedInputStream::BufferedInputStream (InputStream& sourceStream, const int bufferSize_) - : source (&sourceStream, false), - bufferSize (calcBufferStreamBufferSize (bufferSize_, &sourceStream)), - position (sourceStream.getPosition()), - lastReadPos (0), - bufferStart (position), - bufferOverlap (128) +BufferedInputStream::BufferedInputStream (InputStream& sourceStream, int size) + : BufferedInputStream (&sourceStream, size, false) { - buffer.malloc ((size_t) bufferSize); } BufferedInputStream::~BufferedInputStream() @@ -74,6 +54,12 @@ BufferedInputStream::~BufferedInputStream() } //============================================================================== +char BufferedInputStream::peekByte() +{ + ensureBuffered(); + return position < lastReadPos ? *(buffer + (int) (position - bufferStart)) : 0; +} + int64 BufferedInputStream::getTotalLength() { return source->getTotalLength(); @@ -97,7 +83,7 @@ bool BufferedInputStream::isExhausted() void BufferedInputStream::ensureBuffered() { - const int64 bufferEndOverlap = lastReadPos - bufferOverlap; + auto bufferEndOverlap = lastReadPos - bufferOverlap; if (position < bufferStart || position >= bufferEndOverlap) { @@ -107,7 +93,7 @@ void BufferedInputStream::ensureBuffered() && position >= bufferEndOverlap && position >= bufferStart) { - const int bytesToKeep = (int) (lastReadPos - position); + auto bytesToKeep = (int) (lastReadPos - position); memmove (buffer, buffer + (int) (position - bufferStart), (size_t) bytesToKeep); bufferStart = position; @@ -140,41 +126,38 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead) { memcpy (destBuffer, buffer + (int) (position - bufferStart), (size_t) maxBytesToRead); position += maxBytesToRead; - return maxBytesToRead; } - else - { - if (position < bufferStart || position >= lastReadPos) - ensureBuffered(); - int bytesRead = 0; + if (position < bufferStart || position >= lastReadPos) + ensureBuffered(); - while (maxBytesToRead > 0) - { - const int bytesAvailable = jmin (maxBytesToRead, (int) (lastReadPos - position)); + int bytesRead = 0; - if (bytesAvailable > 0) - { - memcpy (destBuffer, buffer + (int) (position - bufferStart), (size_t) bytesAvailable); - maxBytesToRead -= bytesAvailable; - bytesRead += bytesAvailable; - position += bytesAvailable; - destBuffer = static_cast (destBuffer) + bytesAvailable; - } + while (maxBytesToRead > 0) + { + auto numToRead = jmin (maxBytesToRead, (int) (lastReadPos - position)); - const int64 oldLastReadPos = lastReadPos; - ensureBuffered(); + if (numToRead > 0) + { + memcpy (destBuffer, buffer + (int) (position - bufferStart), (size_t) numToRead); + maxBytesToRead -= numToRead; + bytesRead += numToRead; + position += numToRead; + destBuffer = static_cast (destBuffer) + numToRead; + } - if (oldLastReadPos == lastReadPos) - break; // if ensureBuffered() failed to read any more data, bail out + auto oldLastReadPos = lastReadPos; + ensureBuffered(); - if (isExhausted()) - break; - } + if (oldLastReadPos == lastReadPos) + break; // if ensureBuffered() failed to read any more data, bail out - return bytesRead; + if (isExhausted()) + break; } + + return bytesRead; } String BufferedInputStream::readString() @@ -182,9 +165,8 @@ String BufferedInputStream::readString() if (position >= bufferStart && position < lastReadPos) { - const int maxChars = (int) (lastReadPos - position); - - const char* const src = buffer + (int) (position - bufferStart); + auto maxChars = (int) (lastReadPos - position); + auto* src = buffer + (int) (position - bufferStart); for (int i = 0; i < maxChars; ++i) { diff --git a/source/modules/juce_core/streams/juce_BufferedInputStream.h b/source/modules/juce_core/streams/juce_BufferedInputStream.h index 778103689..5a5105385 100644 --- a/source/modules/juce_core/streams/juce_BufferedInputStream.h +++ b/source/modules/juce_core/streams/juce_BufferedInputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BUFFEREDINPUTSTREAM_H_INCLUDED -#define JUCE_BUFFEREDINPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -72,6 +63,9 @@ public: //============================================================================== + /** Returns the next byte that would be read by a call to readByte() */ + char peekByte(); + int64 getTotalLength() override; int64 getPosition() override; bool setPosition (int64 newPosition) override; @@ -84,11 +78,9 @@ private: //============================================================================== OptionalScopedPointer source; int bufferSize; - int64 position, lastReadPos, bufferStart, bufferOverlap; + int64 position, lastReadPos = 0, bufferStart, bufferOverlap = 128; HeapBlock buffer; void ensureBuffered(); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferedInputStream) }; - -#endif // JUCE_BUFFEREDINPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/streams/juce_FileInputSource.cpp b/source/modules/juce_core/streams/juce_FileInputSource.cpp index ee9cb0bd1..ab777793e 100644 --- a/source/modules/juce_core/streams/juce_FileInputSource.cpp +++ b/source/modules/juce_core/streams/juce_FileInputSource.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/streams/juce_FileInputSource.h b/source/modules/juce_core/streams/juce_FileInputSource.h index 33421037f..00f8bee36 100644 --- a/source/modules/juce_core/streams/juce_FileInputSource.h +++ b/source/modules/juce_core/streams/juce_FileInputSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILEINPUTSOURCE_H_INCLUDED -#define JUCE_FILEINPUTSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -63,6 +54,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileInputSource) }; - - -#endif // JUCE_FILEINPUTSOURCE_H_INCLUDED diff --git a/source/modules/juce_core/streams/juce_InputSource.h b/source/modules/juce_core/streams/juce_InputSource.h index c5153af02..14f3d96b4 100644 --- a/source/modules/juce_core/streams/juce_InputSource.h +++ b/source/modules/juce_core/streams/juce_InputSource.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_INPUTSOURCE_H_INCLUDED -#define JUCE_INPUTSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -75,6 +66,3 @@ private: //============================================================================== JUCE_LEAK_DETECTOR (InputSource) }; - - -#endif // JUCE_INPUTSOURCE_H_INCLUDED diff --git a/source/modules/juce_core/streams/juce_InputStream.cpp b/source/modules/juce_core/streams/juce_InputStream.cpp index f0b8390c3..eb6bc57a7 100644 --- a/source/modules/juce_core/streams/juce_InputStream.cpp +++ b/source/modules/juce_core/streams/juce_InputStream.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -134,8 +126,7 @@ int64 InputStream::readInt64BigEndian() float InputStream::readFloat() { - // the union below relies on these types being the same size... - static_jassert (sizeof (int32) == sizeof (float)); + static_assert (sizeof (int32) == sizeof (float), "Union assumes float has the same size as an int32"); union { int32 asInt; float asFloat; } n; n.asInt = (int32) readInt(); return n.asFloat; diff --git a/source/modules/juce_core/streams/juce_InputStream.h b/source/modules/juce_core/streams/juce_InputStream.h index fcce077e9..3db0e9d71 100644 --- a/source/modules/juce_core/streams/juce_InputStream.h +++ b/source/modules/juce_core/streams/juce_InputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_INPUTSTREAM_H_INCLUDED -#define JUCE_INPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -264,5 +255,3 @@ protected: private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InputStream) }; - -#endif // JUCE_INPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/streams/juce_MemoryInputStream.cpp b/source/modules/juce_core/streams/juce_MemoryInputStream.cpp index 76cefa96b..3dfb1237c 100644 --- a/source/modules/juce_core/streams/juce_MemoryInputStream.cpp +++ b/source/modules/juce_core/streams/juce_MemoryInputStream.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -106,7 +98,7 @@ int64 MemoryInputStream::getPosition() class MemoryStreamTests : public UnitTest { public: - MemoryStreamTests() : UnitTest ("MemoryInputStream & MemoryOutputStream") {} + MemoryStreamTests() : UnitTest ("MemoryInputStream & MemoryOutputStream", "Memory Streams") {} void runTest() override { diff --git a/source/modules/juce_core/streams/juce_MemoryInputStream.h b/source/modules/juce_core/streams/juce_MemoryInputStream.h index d0c9054da..3bfa985ac 100644 --- a/source/modules/juce_core/streams/juce_MemoryInputStream.h +++ b/source/modules/juce_core/streams/juce_MemoryInputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MEMORYINPUTSTREAM_H_INCLUDED -#define JUCE_MEMORYINPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -95,5 +86,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryInputStream) }; - -#endif // JUCE_MEMORYINPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/streams/juce_MemoryOutputStream.cpp b/source/modules/juce_core/streams/juce_MemoryOutputStream.cpp index cb1b47a34..57226cb2a 100644 --- a/source/modules/juce_core/streams/juce_MemoryOutputStream.cpp +++ b/source/modules/juce_core/streams/juce_MemoryOutputStream.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/streams/juce_MemoryOutputStream.h b/source/modules/juce_core/streams/juce_MemoryOutputStream.h index 595d6035e..794d78f86 100644 --- a/source/modules/juce_core/streams/juce_MemoryOutputStream.h +++ b/source/modules/juce_core/streams/juce_MemoryOutputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MEMORYOUTPUTSTREAM_H_INCLUDED -#define JUCE_MEMORYOUTPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -136,6 +127,3 @@ private: /** Copies all the data that has been written to a MemoryOutputStream into another stream. */ OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead); - - -#endif // JUCE_MEMORYOUTPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/streams/juce_OutputStream.cpp b/source/modules/juce_core/streams/juce_OutputStream.cpp index 7db6532fe..a87e5b2fc 100644 --- a/source/modules/juce_core/streams/juce_OutputStream.cpp +++ b/source/modules/juce_core/streams/juce_OutputStream.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/streams/juce_OutputStream.h b/source/modules/juce_core/streams/juce_OutputStream.h index bfcb6d0f3..2b53107aa 100644 --- a/source/modules/juce_core/streams/juce_OutputStream.h +++ b/source/modules/juce_core/streams/juce_OutputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_OUTPUTSTREAM_H_INCLUDED -#define JUCE_OUTPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -274,6 +265,3 @@ JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, InputStre @see OutputStream::setNewLineString */ JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const NewLine&); - - -#endif // JUCE_OUTPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/streams/juce_SubregionStream.cpp b/source/modules/juce_core/streams/juce_SubregionStream.cpp index fddefb7c3..5e74c2894 100644 --- a/source/modules/juce_core/streams/juce_SubregionStream.cpp +++ b/source/modules/juce_core/streams/juce_SubregionStream.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/streams/juce_SubregionStream.h b/source/modules/juce_core/streams/juce_SubregionStream.h index 2bf967e9c..624d6b8a7 100644 --- a/source/modules/juce_core/streams/juce_SubregionStream.h +++ b/source/modules/juce_core/streams/juce_SubregionStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SUBREGIONSTREAM_H_INCLUDED -#define JUCE_SUBREGIONSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -86,5 +77,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SubregionStream) }; - -#endif // JUCE_SUBREGIONSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/system/juce_CompilerSupport.h b/source/modules/juce_core/system/juce_CompilerSupport.h index 5864ceb88..3a9dda815 100644 --- a/source/modules/juce_core/system/juce_CompilerSupport.h +++ b/source/modules/juce_core/system/juce_CompilerSupport.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMPILERSUPPORT_H_INCLUDED -#define JUCE_COMPILERSUPPORT_H_INCLUDED +#pragma once /* This file has some checks to see whether the compiler supports various C++11/14 features, When these aren't available, the code defines a few workarounds, so that we can still use @@ -40,11 +31,8 @@ // GCC #if (__cplusplus >= 201103L || defined (__GXX_EXPERIMENTAL_CXX0X__)) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 #define JUCE_COMPILER_SUPPORTS_NOEXCEPT 1 - #define JUCE_COMPILER_SUPPORTS_NULLPTR 1 - #define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 #define JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS 1 #define JUCE_COMPILER_SUPPORTS_VARIADIC_TEMPLATES 1 - #define JUCE_COMPILER_SUPPORTS_STATIC_ASSERT 1 #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && ! defined (JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL) #define JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1 @@ -54,8 +42,9 @@ #define JUCE_DELETED_FUNCTION = delete #endif - #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && ! defined (JUCE_COMPILER_SUPPORTS_LAMBDAS) - #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 + #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 + #define JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT 1 + #define JUCE_COMPILER_SUPPORTS_THREAD_LOCAL 1 #endif #ifndef JUCE_EXCEPTIONS_DISABLED @@ -68,24 +57,21 @@ //============================================================================== // Clang #if JUCE_CLANG && defined (__has_feature) - #if __has_feature (cxx_nullptr) - #define JUCE_COMPILER_SUPPORTS_NULLPTR 1 - #endif #if __has_feature (cxx_noexcept) #define JUCE_COMPILER_SUPPORTS_NOEXCEPT 1 #endif - #if __has_feature (cxx_rvalue_references) - #define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 - #endif - #if __has_feature (cxx_deleted_functions) #define JUCE_DELETED_FUNCTION = delete #endif - #if __has_feature (cxx_lambdas) && (defined (_LIBCPP_VERSION) || ! (JUCE_MAC || JUCE_IOS)) - #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 + #if (defined (_LIBCPP_VERSION) || ! (JUCE_MAC || JUCE_IOS)) + #define JUCE_STDLIB_HAS_STD_FUNCTION_SUPPORT 1 + + #if ! JUCE_PROJUCER_LIVE_BUILD + #define JUCE_COMPILER_SUPPORTS_THREAD_LOCAL 1 + #endif #endif #if __has_feature (cxx_generalized_initializers) && (defined (_LIBCPP_VERSION) || ! (JUCE_MAC || JUCE_IOS)) @@ -96,10 +82,6 @@ #define JUCE_COMPILER_SUPPORTS_VARIADIC_TEMPLATES 1 #endif - #if __has_feature (cxx_static_assert) - #define JUCE_COMPILER_SUPPORTS_STATIC_ASSERT 1 - #endif - #if __has_feature (cxx_override_control) && (! defined (JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL)) #define JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1 #endif @@ -119,21 +101,17 @@ //============================================================================== // MSVC #ifdef _MSC_VER - #if _MSC_VER >= 1600 - #define JUCE_COMPILER_SUPPORTS_NULLPTR 1 - #define JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 - #define JUCE_COMPILER_SUPPORTS_STATIC_ASSERT 1 - #endif #if _MSC_VER >= 1700 #define JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1 - #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 #endif #if _MSC_VER >= 1800 #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 + #define JUCE_COMPILER_SUPPORTS_THREAD_LOCAL 1 #endif #if _MSC_VER >= 1900 @@ -170,17 +148,21 @@ #endif #endif - #if ! JUCE_COMPILER_SUPPORTS_NULLPTR - #ifdef nullptr - #undef nullptr - #endif - #define nullptr (0) - #endif - #if ! JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL #undef override #define override #endif #endif -#endif // JUCE_COMPILERSUPPORT_H_INCLUDED +//============================================================================== +#if JUCE_ANDROID + #define JUCE_ATOMIC_AVAILABLE 0 +#elif defined(_LIBCPP_VERSION) + #define JUCE_ATOMIC_AVAILABLE (_LIBCPP_VERSION >= 3700) +#elif defined (__GLIBCXX__) + #define JUCE_ATOMIC_AVAILABLE (__GLIBCXX__ >= 20130322) // GCC versions 4.8 and later +#elif defined (_MSC_VER) + #define JUCE_ATOMIC_AVAILABLE 1 // Visual Studio 2013 and later +#else + #define JUCE_ATOMIC_AVAILABLE 0 +#endif diff --git a/source/modules/juce_core/system/juce_PlatformDefs.h b/source/modules/juce_core/system/juce_PlatformDefs.h index 21d1a5b1c..d29b49237 100644 --- a/source/modules/juce_core/system/juce_PlatformDefs.h +++ b/source/modules/juce_core/system/juce_PlatformDefs.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PLATFORMDEFS_H_INCLUDED -#define JUCE_PLATFORMDEFS_H_INCLUDED +#pragma once //============================================================================== /* This file defines miscellaneous macros for debugging, assertions, etc. @@ -63,7 +54,7 @@ #endif //============================================================================== -#if JUCE_IOS || JUCE_LINUX || JUCE_ANDROID +#if JUCE_IOS || JUCE_LINUX /** This will try to break into the debugger if the app is currently being debugged. If called by an app that's not being debugged, the behaviour isn't defined - it may crash or not, depending on the platform. @@ -81,6 +72,8 @@ #else #define JUCE_BREAK_IN_DEBUGGER { asm ("int $3"); } #endif +#elif JUCE_ANDROID + #define JUCE_BREAK_IN_DEBUGGER { __builtin_trap(); } #else #define JUCE_BREAK_IN_DEBUGGER { __asm int 3 } #endif @@ -172,30 +165,6 @@ #define JUCE_STRINGIFY(item) JUCE_STRINGIFY_MACRO_HELPER (item) //============================================================================== -#if JUCE_COMPILER_SUPPORTS_STATIC_ASSERT - /** A compile-time assertion macro. - If the expression parameter is false, the macro will cause a compile error. (The actual error - message that the compiler generates may be completely bizarre and seem to have no relation to - the place where you put the static_assert though!) - */ - #define static_jassert(expression) static_assert(expression, #expression); -#else - #ifndef DOXYGEN - namespace juce - { - template struct JuceStaticAssert; - template <> struct JuceStaticAssert { static void dummy() {} }; - } - #endif - - /** A compile-time assertion macro. - If the expression parameter is false, the macro will cause a compile error. (The actual error - message that the compiler generates may be completely bizarre and seem to have no relation to - the place where you put the static_assert though!) - */ - #define static_jassert(expression) juce::JuceStaticAssert::dummy(); -#endif - /** This is a shorthand macro for declaring stubs for a class's copy constructor and operator=. For example, instead of @@ -324,5 +293,3 @@ #else #define JUCE_NO_ASSOCIATIVE_MATH_OPTIMISATIONS #endif - -#endif // JUCE_PLATFORMDEFS_H_INCLUDED diff --git a/source/modules/juce_core/system/juce_StandardHeader.h b/source/modules/juce_core/system/juce_StandardHeader.h index da92a55d6..6a884a951 100644 --- a/source/modules/juce_core/system/juce_StandardHeader.h +++ b/source/modules/juce_core/system/juce_StandardHeader.h @@ -2,42 +2,33 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STANDARDHEADER_H_INCLUDED -#define JUCE_STANDARDHEADER_H_INCLUDED +#pragma once //============================================================================== /** Current JUCE version number. See also SystemStats::getJUCEVersion() for a string version. */ -#define JUCE_MAJOR_VERSION 4 -#define JUCE_MINOR_VERSION 3 +#define JUCE_MAJOR_VERSION 5 +#define JUCE_MINOR_VERSION 1 #define JUCE_BUILDNUMBER 1 /** Current Juce version number. @@ -116,6 +107,17 @@ #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 + +// Include std::atomic if it's supported by the compiler +#if JUCE_ATOMIC_AVAILABLE + #include +#endif + //============================================================================== // DLL building settings on Windows #if JUCE_MSVC @@ -157,5 +159,3 @@ #ifndef DOXYGEN #define JUCE_NAMESPACE juce // This old macro is deprecated: you should just use the juce namespace directly. #endif - -#endif // JUCE_STANDARDHEADER_H_INCLUDED diff --git a/source/modules/juce_core/system/juce_SystemStats.cpp b/source/modules/juce_core/system/juce_SystemStats.cpp index b67c44470..7e0527742 100644 --- a/source/modules/juce_core/system/juce_SystemStats.cpp +++ b/source/modules/juce_core/system/juce_SystemStats.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -32,15 +24,15 @@ String SystemStats::getJUCEVersion() { // Some basic tests, to keep an eye on things and make sure these types work ok // on all platforms. Let me know if any of these assertions fail on your system! - static_jassert (sizeof (pointer_sized_int) == sizeof (void*)); - static_jassert (sizeof (int8) == 1); - static_jassert (sizeof (uint8) == 1); - static_jassert (sizeof (int16) == 2); - static_jassert (sizeof (uint16) == 2); - static_jassert (sizeof (int32) == 4); - static_jassert (sizeof (uint32) == 4); - static_jassert (sizeof (int64) == 8); - static_jassert (sizeof (uint64) == 8); + static_assert (sizeof (pointer_sized_int) == sizeof (void*), "Basic sanity test failed: please report!"); + static_assert (sizeof (int8) == 1, "Basic sanity test failed: please report!"); + static_assert (sizeof (uint8) == 1, "Basic sanity test failed: please report!"); + static_assert (sizeof (int16) == 2, "Basic sanity test failed: please report!"); + static_assert (sizeof (uint16) == 2, "Basic sanity test failed: please report!"); + static_assert (sizeof (int32) == 4, "Basic sanity test failed: please report!"); + static_assert (sizeof (uint32) == 4, "Basic sanity test failed: please report!"); + static_assert (sizeof (int64) == 8, "Basic sanity test failed: please report!"); + static_assert (sizeof (uint64) == 8, "Basic sanity test failed: please report!"); return "JUCE v" JUCE_STRINGIFY(JUCE_MAJOR_VERSION) "." JUCE_STRINGIFY(JUCE_MINOR_VERSION) @@ -63,23 +55,43 @@ String SystemStats::getJUCEVersion() static JuceVersionPrinter juceVersionPrinter; #endif +StringArray SystemStats::getDeviceIdentifiers() +{ + StringArray ids; + + #if JUCE_WINDOWS + File f (File::getSpecialLocation (File::windowsSystemDirectory)); + #else + File f ("~"); + #endif + if (auto num = f.getFileIdentifier()) + { + ids.add (String::toHexString ((int64) num)); + } + else + { + Array addresses; + MACAddress::findAllAddresses (addresses); + for (auto& address : addresses) + ids.add (address.toString()); + } + + jassert (ids.size() > 0); // Failed to create any IDs! + return ids; +} //============================================================================== struct CPUInformation { - CPUInformation() noexcept - : numCpus (0), hasMMX (false), hasSSE (false), - hasSSE2 (false), hasSSE3 (false), has3DNow (false), - hasSSSE3 (false), hasSSE41 (false), hasSSE42 (false), - hasAVX (false), hasAVX2 (false) - { - initialise(); - } + CPUInformation() noexcept { initialise(); } void initialise() noexcept; - int numCpus; - bool hasMMX, hasSSE, hasSSE2, hasSSE3, has3DNow, hasSSSE3, hasSSE41, hasSSE42, hasAVX, hasAVX2; + int numLogicalCPUs = 0, numPhysicalCPUs = 0; + + bool hasMMX = false, hasSSE = false, hasSSE2 = false, hasSSE3 = false, + has3DNow = false, hasSSSE3 = false, hasSSE41 = false, + hasSSE42 = false, hasAVX = false, hasAVX2 = false, hasNeon = false; }; static const CPUInformation& getCPUInformation() noexcept @@ -88,17 +100,19 @@ static const CPUInformation& getCPUInformation() noexcept return info; } -int SystemStats::getNumCpus() noexcept { return getCPUInformation().numCpus; } -bool SystemStats::hasMMX() noexcept { return getCPUInformation().hasMMX; } -bool SystemStats::has3DNow() noexcept { return getCPUInformation().has3DNow; } -bool SystemStats::hasSSE() noexcept { return getCPUInformation().hasSSE; } -bool SystemStats::hasSSE2() noexcept { return getCPUInformation().hasSSE2; } -bool SystemStats::hasSSE3() noexcept { return getCPUInformation().hasSSE3; } -bool SystemStats::hasSSSE3() noexcept { return getCPUInformation().hasSSSE3; } -bool SystemStats::hasSSE41() noexcept { return getCPUInformation().hasSSE41; } -bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; } -bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; } -bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; } +int SystemStats::getNumCpus() noexcept { return getCPUInformation().numLogicalCPUs; } +int SystemStats::getNumPhysicalCpus() noexcept { return getCPUInformation().numPhysicalCPUs; } +bool SystemStats::hasMMX() noexcept { return getCPUInformation().hasMMX; } +bool SystemStats::has3DNow() noexcept { return getCPUInformation().has3DNow; } +bool SystemStats::hasSSE() noexcept { return getCPUInformation().hasSSE; } +bool SystemStats::hasSSE2() noexcept { return getCPUInformation().hasSSE2; } +bool SystemStats::hasSSE3() noexcept { return getCPUInformation().hasSSE3; } +bool SystemStats::hasSSSE3() noexcept { return getCPUInformation().hasSSSE3; } +bool SystemStats::hasSSE41() noexcept { return getCPUInformation().hasSSE41; } +bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; } +bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; } +bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; } +bool SystemStats::hasNeon() noexcept { return getCPUInformation().hasNeon; } //============================================================================== @@ -158,15 +172,15 @@ String SystemStats::getStackBacktrace() static SystemStats::CrashHandlerFunction globalCrashHandler = nullptr; #if JUCE_WINDOWS -static LONG WINAPI handleCrash (LPEXCEPTION_POINTERS) +static LONG WINAPI handleCrash (LPEXCEPTION_POINTERS ep) { - globalCrashHandler(); + globalCrashHandler (ep); return EXCEPTION_EXECUTE_HANDLER; } #else -static void handleCrash (int) +static void handleCrash (int signum) { - globalCrashHandler(); + globalCrashHandler ((void*) (pointer_sized_int) signum); kill (getpid(), SIGKILL); } diff --git a/source/modules/juce_core/system/juce_SystemStats.h b/source/modules/juce_core/system/juce_SystemStats.h index 6ae5b47b0..4bf4e0e13 100644 --- a/source/modules/juce_core/system/juce_SystemStats.h +++ b/source/modules/juce_core/system/juce_SystemStats.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SYSTEMSTATS_H_INCLUDED -#define JUCE_SYSTEMSTATS_H_INCLUDED +#pragma once //============================================================================== @@ -138,12 +129,22 @@ public: */ static String getDeviceDescription(); + /** This method calculates some IDs to uniquely identify the device. + + The first choice for an ID is a filesystem ID for the user's home folder or + windows directory. If that fails then this function returns the MAC addresses. + */ + static StringArray getDeviceIdentifiers(); + //============================================================================== // CPU and memory information.. - /** Returns the number of CPU cores. */ + /** Returns the number of logical CPU cores. */ static int getNumCpus() noexcept; + /** Returns the number of physical CPU cores. */ + static int getNumPhysicalCpus() noexcept; + /** Returns the approximate CPU speed. @returns the speed in megahertz, e.g. 1500, 2500, 32000 (depending on what year you're reading this...) @@ -155,6 +156,11 @@ public: */ static String getCpuVendor(); + /** Attempts to return a string describing the CPU model. + May not be available on some systems. + */ + static String getCpuModel(); + static bool hasMMX() noexcept; /**< Returns true if Intel MMX instructions are available. */ static bool has3DNow() noexcept; /**< Returns true if AMD 3DNOW instructions are available. */ static bool hasSSE() noexcept; /**< Returns true if Intel SSE instructions are available. */ @@ -165,6 +171,7 @@ public: static bool hasSSE42() noexcept; /**< Returns true if Intel SSE4.2 instructions are available. */ static bool hasAVX() noexcept; /**< Returns true if Intel AVX instructions are available. */ static bool hasAVX2() noexcept; /**< Returns true if Intel AVX2 instructions are available. */ + static bool hasNeon() noexcept; /**< Returns true if ARM NEON instructions are available. */ //============================================================================== /** Finds out how much RAM is in the machine. @@ -185,8 +192,10 @@ public: */ static String getStackBacktrace(); - /** A void() function type, used by setApplicationCrashHandler(). */ - typedef void (*CrashHandlerFunction)(); + /** A function type for use in setApplicationCrashHandler(). The parameter will contain + platform-specific data about the crash. + */ + typedef void (*CrashHandlerFunction) (void*); /** Sets up a global callback function that will be called if the application executes some kind of illegal instruction. @@ -208,6 +217,3 @@ private: JUCE_DECLARE_NON_COPYABLE (SystemStats) }; - - -#endif // JUCE_SYSTEMSTATS_H_INCLUDED diff --git a/source/modules/juce_core/system/juce_TargetPlatform.h b/source/modules/juce_core/system/juce_TargetPlatform.h index 1f898cab0..ae9d7e194 100644 --- a/source/modules/juce_core/system/juce_TargetPlatform.h +++ b/source/modules/juce_core/system/juce_TargetPlatform.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TARGETPLATFORM_H_INCLUDED -#define JUCE_TARGETPLATFORM_H_INCLUDED +#pragma once //============================================================================== /* This file figures out which platform is being built, and defines some macros @@ -193,20 +184,22 @@ #ifdef __clang__ #define JUCE_CLANG 1 + + #if ((! __has_feature (cxx_nullptr)) || (! __has_feature (cxx_rvalue_references)) || (! __has_feature (cxx_static_assert))) + #error "Clang 3.2 and earlier are no longer supported!" + #endif #elif defined (__GNUC__) #define JUCE_GCC 1 + + #if (__cplusplus < 201103L && (! defined (__GXX_EXPERIMENTAL_CXX0X__))) || ((__GNUC__ * 100 + __GNUC_MINOR__) < 406) + #error "GCC 4.5 and earlier are no longer supported!" + #endif #elif defined (_MSC_VER) #define JUCE_MSVC 1 - #if _MSC_VER < 1500 - #define JUCE_VC8_OR_EARLIER 1 - - #if _MSC_VER < 1400 - #error "Visual Studio 2003 and earlier are no longer supported!" - #endif + #if _MSC_VER < 1600 + #error "Visual Studio 2008 and earlier are no longer supported!" #endif #else #error unknown compiler #endif - -#endif // JUCE_TARGETPLATFORM_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_Base64.cpp b/source/modules/juce_core/text/juce_Base64.cpp index de167ab2d..bda7c3b66 100644 --- a/source/modules/juce_core/text/juce_Base64.cpp +++ b/source/modules/juce_core/text/juce_Base64.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -132,7 +124,7 @@ String Base64::toBase64 (const String& text) class Base64Tests : public UnitTest { public: - Base64Tests() : UnitTest ("Base64 class") {} + Base64Tests() : UnitTest ("Base64 class", "Text") {} static MemoryBlock createRandomData (Random& r) { diff --git a/source/modules/juce_core/text/juce_Base64.h b/source/modules/juce_core/text/juce_Base64.h index 55fb1b924..169c0e2eb 100644 --- a/source/modules/juce_core/text/juce_Base64.h +++ b/source/modules/juce_core/text/juce_Base64.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BASE64_H_INCLUDED -#define JUCE_BASE64_H_INCLUDED +#pragma once /** @@ -56,6 +47,3 @@ struct JUCE_API Base64 /** Converts a string's UTF-8 representation to a base-64 string. */ static String toBase64 (const String& textToEncode); }; - - -#endif // JUCE_BASE64_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_CharPointer_ASCII.h b/source/modules/juce_core/text/juce_CharPointer_ASCII.h index ae0183e31..0c9ed44ac 100644 --- a/source/modules/juce_core/text/juce_CharPointer_ASCII.h +++ b/source/modules/juce_core/text/juce_CharPointer_ASCII.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHARPOINTER_ASCII_H_INCLUDED -#define JUCE_CHARPOINTER_ASCII_H_INCLUDED +#pragma once //============================================================================== @@ -46,7 +37,7 @@ class CharPointer_ASCII public: typedef char CharType; - inline explicit CharPointer_ASCII (const CharType* const rawPointer) noexcept + inline explicit CharPointer_ASCII (const CharType* rawPointer) noexcept : data (const_cast (rawPointer)) { } @@ -85,6 +76,9 @@ public: /** Returns true if this pointer is pointing to a null character. */ inline bool isEmpty() const noexcept { return *data == 0; } + /** Returns true if this pointer is not pointing to a null character. */ + inline bool isNotEmpty() const noexcept { return *data != 0; } + /** Returns the unicode character that this pointer is pointing to. */ inline juce_wchar operator*() const noexcept { return (juce_wchar) (uint8) *data; } @@ -109,7 +103,7 @@ public: /** Moves this pointer along to the next character in the string. */ CharPointer_ASCII operator++ (int) noexcept { - CharPointer_ASCII temp (*this); + auto temp (*this); ++data; return temp; } @@ -128,7 +122,7 @@ public: /** Returns the character at a given character index from the start of the string. */ inline juce_wchar operator[] (const int characterIndex) const noexcept { - return (juce_wchar) (unsigned char) data [characterIndex]; + return (juce_wchar) (uint8) data [characterIndex]; } /** Returns a pointer which is moved forwards from this one by the specified number of characters. */ @@ -319,25 +313,25 @@ public: } /** Returns true if the first character of this string is whitespace. */ - bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; } + bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; } /** Returns true if the first character of this string is a digit. */ - bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; } + bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; } /** Returns true if the first character of this string is a letter. */ - bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; } + bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; } /** Returns true if the first character of this string is a letter or digit. */ - bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; } + bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; } /** Returns true if the first character of this string is upper-case. */ - bool isUpperCase() const { return CharacterFunctions::isUpperCase ((juce_wchar) (uint8) *data) != 0; } + bool isUpperCase() const { return CharacterFunctions::isUpperCase ((juce_wchar) (uint8) *data) != 0; } /** Returns true if the first character of this string is lower-case. */ - bool isLowerCase() const { return CharacterFunctions::isLowerCase ((juce_wchar) (uint8) *data) != 0; } + bool isLowerCase() const { return CharacterFunctions::isLowerCase ((juce_wchar) (uint8) *data) != 0; } /** Returns an upper-case version of the first character of this string. */ - juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase ((juce_wchar) (uint8) *data); } + juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase ((juce_wchar) (uint8) *data); } /** Returns a lower-case version of the first character of this string. */ - juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase ((juce_wchar) (uint8) *data); } + juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase ((juce_wchar) (uint8) *data); } /** Parses this string as a 32-bit integer. */ - int getIntValue32() const noexcept { return atoi (data); } + int getIntValue32() const noexcept { return atoi (data); } /** Parses this string as a 64-bit integer. */ int64 getIntValue64() const noexcept @@ -352,10 +346,10 @@ public: } /** Parses this string as a floating point double. */ - double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } + double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } /** Returns the first non-whitespace character in the string. */ - CharPointer_ASCII findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } + CharPointer_ASCII findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } /** Returns true if the given unicode character can be represented in this encoding. */ static bool canRepresent (juce_wchar character) noexcept @@ -380,6 +374,3 @@ public: private: CharType* data; }; - - -#endif // JUCE_CHARPOINTER_ASCII_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_CharPointer_UTF16.h b/source/modules/juce_core/text/juce_CharPointer_UTF16.h index a982f7f99..7d45f9520 100644 --- a/source/modules/juce_core/text/juce_CharPointer_UTF16.h +++ b/source/modules/juce_core/text/juce_CharPointer_UTF16.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHARPOINTER_UTF16_H_INCLUDED -#define JUCE_CHARPOINTER_UTF16_H_INCLUDED +#pragma once //============================================================================== @@ -47,7 +38,7 @@ public: typedef int16 CharType; #endif - inline explicit CharPointer_UTF16 (const CharType* const rawPointer) noexcept + inline explicit CharPointer_UTF16 (const CharType* rawPointer) noexcept : data (const_cast (rawPointer)) { } @@ -86,10 +77,13 @@ public: /** Returns true if this pointer is pointing to a null character. */ inline bool isEmpty() const noexcept { return *data == 0; } + /** Returns true if this pointer is not pointing to a null character. */ + inline bool isNotEmpty() const noexcept { return *data != 0; } + /** Returns the unicode character that this pointer is pointing to. */ juce_wchar operator*() const noexcept { - uint32 n = (uint32) (uint16) *data; + auto n = (uint32) (uint16) *data; if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) data[1]) >= 0xdc00) n = 0x10000 + (((n - 0xd800) << 10) | (((uint32) (uint16) data[1]) - 0xdc00)); @@ -100,7 +94,7 @@ public: /** Moves this pointer along to the next character in the string. */ CharPointer_UTF16 operator++() noexcept { - const juce_wchar n = *data++; + auto n = (uint32) (uint16) *data++; if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) *data) >= 0xdc00) ++data; @@ -111,7 +105,7 @@ public: /** Moves this pointer back to the previous character in the string. */ CharPointer_UTF16 operator--() noexcept { - const juce_wchar n = *--data; + auto n = (uint32) (uint16) (*--data); if (n >= 0xdc00 && n <= 0xdfff) --data; @@ -123,7 +117,7 @@ public: advances the pointer to point to the next character. */ juce_wchar getAndAdvance() noexcept { - uint32 n = (uint32) (uint16) *data++; + auto n = (uint32) (uint16) *data++; if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) *data) >= 0xdc00) n = 0x10000 + ((((n - 0xd800) << 10) | (((uint32) (uint16) *data++) - 0xdc00))); @@ -134,7 +128,7 @@ public: /** Moves this pointer along to the next character in the string. */ CharPointer_UTF16 operator++ (int) noexcept { - CharPointer_UTF16 temp (*this); + auto temp (*this); ++*this; return temp; } @@ -161,25 +155,25 @@ public: } /** Returns the character at a given character index from the start of the string. */ - juce_wchar operator[] (const int characterIndex) const noexcept + juce_wchar operator[] (int characterIndex) const noexcept { - CharPointer_UTF16 p (*this); + auto p (*this); p += characterIndex; return *p; } /** Returns a pointer which is moved forwards from this one by the specified number of characters. */ - CharPointer_UTF16 operator+ (const int numToSkip) const noexcept + CharPointer_UTF16 operator+ (int numToSkip) const noexcept { - CharPointer_UTF16 p (*this); + auto p (*this); p += numToSkip; return p; } /** Returns a pointer which is moved backwards from this one by the specified number of characters. */ - CharPointer_UTF16 operator- (const int numToSkip) const noexcept + CharPointer_UTF16 operator- (int numToSkip) const noexcept { - CharPointer_UTF16 p (*this); + auto p (*this); p += -numToSkip; return p; } @@ -208,12 +202,12 @@ public: /** Returns the number of characters in this string. */ size_t length() const noexcept { - const CharType* d = data; + auto* d = data; size_t count = 0; for (;;) { - const int n = *d++; + auto n = (uint32) (uint16) *d++; if (n >= 0xd800 && n <= 0xdfff) { @@ -230,13 +224,13 @@ public: } /** Returns the number of characters in this string, or the given value, whichever is lower. */ - size_t lengthUpTo (const size_t maxCharsToCount) const noexcept + size_t lengthUpTo (size_t maxCharsToCount) const noexcept { return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); } /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ - size_t lengthUpTo (const CharPointer_UTF16 end) const noexcept + size_t lengthUpTo (CharPointer_UTF16 end) const noexcept { return CharacterFunctions::lengthUpTo (*this, end); } @@ -252,7 +246,7 @@ public: /** Returns the number of bytes that would be needed to represent the given unicode character in this encoding format. */ - static size_t getBytesRequiredFor (const juce_wchar charToWrite) noexcept + static size_t getBytesRequiredFor (juce_wchar charToWrite) noexcept { return (charToWrite >= 0x10000) ? (sizeof (CharType) * 2) : sizeof (CharType); } @@ -276,7 +270,7 @@ public: /** Returns a pointer to the null character that terminates this string. */ CharPointer_UTF16 findTerminatingNull() const noexcept { - const CharType* t = data; + auto* t = data; while (*t != 0) ++t; @@ -286,15 +280,15 @@ public: /** Copies a source string to this pointer, advancing this pointer as it goes. */ template - void writeAll (const CharPointer src) noexcept + void writeAll (CharPointer src) noexcept { CharacterFunctions::copyAll (*this, src); } /** Copies a source string to this pointer, advancing this pointer as it goes. */ - void writeAll (const CharPointer_UTF16 src) noexcept + void writeAll (CharPointer_UTF16 src) noexcept { - const CharType* s = src.data; + auto* s = src.data; while ((*data = *s) != 0) { @@ -308,7 +302,7 @@ public: to the destination buffer before stopping. */ template - size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept + size_t writeWithDestByteLimit (CharPointer src, size_t maxDestBytes) noexcept { return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes); } @@ -318,51 +312,51 @@ public: written to the destination buffer before stopping (including the terminating null). */ template - void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept + void writeWithCharLimit (CharPointer src, int maxChars) noexcept { CharacterFunctions::copyWithCharLimit (*this, src, maxChars); } /** Compares this string with another one. */ template - int compare (const CharPointer other) const noexcept + int compare (CharPointer other) const noexcept { return CharacterFunctions::compare (*this, other); } /** Compares this string with another one, up to a specified number of characters. */ template - int compareUpTo (const CharPointer other, const int maxChars) const noexcept + int compareUpTo (CharPointer other, int maxChars) const noexcept { return CharacterFunctions::compareUpTo (*this, other, maxChars); } /** Compares this string with another one. */ template - int compareIgnoreCase (const CharPointer other) const noexcept + int compareIgnoreCase (CharPointer other) const noexcept { return CharacterFunctions::compareIgnoreCase (*this, other); } /** Compares this string with another one, up to a specified number of characters. */ template - int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept + int compareIgnoreCaseUpTo (CharPointer other, int maxChars) const noexcept { return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars); } #if JUCE_MSVC && ! DOXYGEN - int compareIgnoreCase (const CharPointer_UTF16 other) const noexcept + int compareIgnoreCase (CharPointer_UTF16 other) const noexcept { return _wcsicmp (data, other.data); } - int compareIgnoreCaseUpTo (const CharPointer_UTF16 other, int maxChars) const noexcept + int compareIgnoreCaseUpTo (CharPointer_UTF16 other, int maxChars) const noexcept { return _wcsnicmp (data, other.data, (size_t) maxChars); } - int indexOf (const CharPointer_UTF16 stringToFind) const noexcept + int indexOf (CharPointer_UTF16 stringToFind) const noexcept { const CharType* const t = wcsstr (data, stringToFind.getAddress()); return t == nullptr ? -1 : (int) (t - data); @@ -371,41 +365,41 @@ public: /** Returns the character index of a substring, or -1 if it isn't found. */ template - int indexOf (const CharPointer stringToFind) const noexcept + int indexOf (CharPointer stringToFind) const noexcept { return CharacterFunctions::indexOf (*this, stringToFind); } /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind) const noexcept + int indexOf (juce_wchar charToFind) const noexcept { return CharacterFunctions::indexOfChar (*this, charToFind); } /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind, const bool ignoreCase) const noexcept + int indexOf (juce_wchar charToFind, bool ignoreCase) const noexcept { return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind) : CharacterFunctions::indexOfChar (*this, charToFind); } /** Returns true if the first character of this string is whitespace. */ - bool isWhitespace() const noexcept { return CharacterFunctions::isWhitespace (operator*()) != 0; } + bool isWhitespace() const noexcept { return CharacterFunctions::isWhitespace (operator*()) != 0; } /** Returns true if the first character of this string is a digit. */ - bool isDigit() const noexcept { return CharacterFunctions::isDigit (operator*()) != 0; } + bool isDigit() const noexcept { return CharacterFunctions::isDigit (operator*()) != 0; } /** Returns true if the first character of this string is a letter. */ - bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; } + bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; } /** Returns true if the first character of this string is a letter or digit. */ - bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; } + bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; } /** Returns true if the first character of this string is upper-case. */ - bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; } + bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; } /** Returns true if the first character of this string is lower-case. */ - bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; } + bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; } /** Returns an upper-case version of the first character of this string. */ - juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (operator*()); } + juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (operator*()); } /** Returns a lower-case version of the first character of this string. */ - juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (operator*()); } + juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (operator*()); } /** Parses this string as a 32-bit integer. */ int getIntValue32() const noexcept @@ -413,7 +407,7 @@ public: #if JUCE_MSVC return _wtoi (data); #else - return CharacterFunctions::getIntValue (*this); + return CharacterFunctions::getIntValue (*this); #endif } @@ -423,21 +417,21 @@ public: #if JUCE_MSVC return _wtoi64 (data); #else - return CharacterFunctions::getIntValue (*this); + return CharacterFunctions::getIntValue (*this); #endif } /** Parses this string as a floating point double. */ - double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } + double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } /** Returns the first non-whitespace character in the string. */ - CharPointer_UTF16 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } + CharPointer_UTF16 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } /** Returns true if the given unicode character can be represented in this encoding. */ static bool canRepresent (juce_wchar character) noexcept { - return ((unsigned int) character) < (unsigned int) 0x10ffff - && (((unsigned int) character) < 0xd800 || ((unsigned int) character) > 0xdfff); + auto n = (uint32) character; + return n < 0x10ffff && (n < 0xd800 || n > 0xdfff); } /** Returns true if this data contains a valid string in this encoding. */ @@ -447,7 +441,7 @@ public: while (--maxBytesToRead >= 0 && *dataToTest != 0) { - const uint32 n = (uint32) (uint16) *dataToTest++; + auto n = (uint32) (uint16) *dataToTest++; if (n >= 0xd800) { @@ -459,7 +453,7 @@ public: if (n > 0xdc00) return false; - const uint32 nextChar = (uint32) (uint16) *dataToTest++; + auto nextChar = (uint32) (uint16) *dataToTest++; if (nextChar < 0xdc00 || nextChar > 0xdfff) return false; @@ -471,7 +465,7 @@ public: } /** Atomically swaps this pointer for a new value, returning the previous value. */ - CharPointer_UTF16 atomicSwap (const CharPointer_UTF16 newValue) + CharPointer_UTF16 atomicSwap (CharPointer_UTF16 newValue) { return CharPointer_UTF16 (reinterpret_cast&> (data).exchange (newValue.data)); } @@ -491,7 +485,7 @@ public: static bool isByteOrderMarkBigEndian (const void* possibleByteOrder) noexcept { jassert (possibleByteOrder != nullptr); - const uint8* const c = static_cast (possibleByteOrder); + auto c = static_cast (possibleByteOrder); return c[0] == (uint8) byteOrderMarkBE1 && c[1] == (uint8) byteOrderMarkBE2; @@ -503,7 +497,7 @@ public: static bool isByteOrderMarkLittleEndian (const void* possibleByteOrder) noexcept { jassert (possibleByteOrder != nullptr); - const uint8* const c = static_cast (possibleByteOrder); + auto c = static_cast (possibleByteOrder); return c[0] == (uint8) byteOrderMarkLE1 && c[1] == (uint8) byteOrderMarkLE2; @@ -512,7 +506,7 @@ public: private: CharType* data; - static unsigned int findNullIndex (const CharType* const t) noexcept + static unsigned int findNullIndex (const CharType* t) noexcept { unsigned int n = 0; @@ -522,6 +516,3 @@ private: return n; } }; - - -#endif // JUCE_CHARPOINTER_UTF16_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_CharPointer_UTF32.h b/source/modules/juce_core/text/juce_CharPointer_UTF32.h index 426aec87e..5367fbec8 100644 --- a/source/modules/juce_core/text/juce_CharPointer_UTF32.h +++ b/source/modules/juce_core/text/juce_CharPointer_UTF32.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHARPOINTER_UTF32_H_INCLUDED -#define JUCE_CHARPOINTER_UTF32_H_INCLUDED +#pragma once //============================================================================== @@ -43,7 +34,7 @@ class CharPointer_UTF32 public: typedef juce_wchar CharType; - inline explicit CharPointer_UTF32 (const CharType* const rawPointer) noexcept + inline explicit CharPointer_UTF32 (const CharType* rawPointer) noexcept : data (const_cast (rawPointer)) { } @@ -82,6 +73,9 @@ public: /** Returns true if this pointer is pointing to a null character. */ inline bool isEmpty() const noexcept { return *data == 0; } + /** Returns true if this pointer is not pointing to a null character. */ + inline bool isNotEmpty() const noexcept { return *data != 0; } + /** Returns the unicode character that this pointer is pointing to. */ inline juce_wchar operator*() const noexcept { return *data; } @@ -106,47 +100,47 @@ public: /** Moves this pointer along to the next character in the string. */ CharPointer_UTF32 operator++ (int) noexcept { - CharPointer_UTF32 temp (*this); + auto temp (*this); ++data; return temp; } /** Moves this pointer forwards by the specified number of characters. */ - inline void operator+= (const int numToSkip) noexcept + inline void operator+= (int numToSkip) noexcept { data += numToSkip; } - inline void operator-= (const int numToSkip) noexcept + inline void operator-= (int numToSkip) noexcept { data -= numToSkip; } /** Returns the character at a given character index from the start of the string. */ - inline juce_wchar& operator[] (const int characterIndex) const noexcept + inline juce_wchar& operator[] (int characterIndex) const noexcept { return data [characterIndex]; } /** Returns a pointer which is moved forwards from this one by the specified number of characters. */ - CharPointer_UTF32 operator+ (const int numToSkip) const noexcept + CharPointer_UTF32 operator+ (int numToSkip) const noexcept { return CharPointer_UTF32 (data + numToSkip); } /** Returns a pointer which is moved backwards from this one by the specified number of characters. */ - CharPointer_UTF32 operator- (const int numToSkip) const noexcept + CharPointer_UTF32 operator- (int numToSkip) const noexcept { return CharPointer_UTF32 (data - numToSkip); } /** Writes a unicode character to this string, and advances this pointer to point to the next position. */ - inline void write (const juce_wchar charToWrite) noexcept + inline void write (juce_wchar charToWrite) noexcept { *data++ = charToWrite; } - inline void replaceChar (const juce_wchar newChar) noexcept + inline void replaceChar (juce_wchar newChar) noexcept { *data = newChar; } @@ -171,13 +165,13 @@ public: } /** Returns the number of characters in this string, or the given value, whichever is lower. */ - size_t lengthUpTo (const size_t maxCharsToCount) const noexcept + size_t lengthUpTo (size_t maxCharsToCount) const noexcept { return CharacterFunctions::lengthUpTo (*this, maxCharsToCount); } /** Returns the number of characters in this string, or up to the given end pointer, whichever is lower. */ - size_t lengthUpTo (const CharPointer_UTF32 end) const noexcept + size_t lengthUpTo (CharPointer_UTF32 end) const noexcept { return CharacterFunctions::lengthUpTo (*this, end); } @@ -193,7 +187,7 @@ public: /** Returns the number of bytes that would be needed to represent the given unicode character in this encoding format. */ - static inline size_t getBytesRequiredFor (const juce_wchar) noexcept + static inline size_t getBytesRequiredFor (juce_wchar) noexcept { return sizeof (CharType); } @@ -203,7 +197,7 @@ public: The value returned does NOT include the terminating null character. */ template - static size_t getBytesRequiredFor (const CharPointer text) noexcept + static size_t getBytesRequiredFor (CharPointer text) noexcept { return sizeof (CharType) * text.length(); } @@ -216,15 +210,15 @@ public: /** Copies a source string to this pointer, advancing this pointer as it goes. */ template - void writeAll (const CharPointer src) noexcept + void writeAll (CharPointer src) noexcept { CharacterFunctions::copyAll (*this, src); } /** Copies a source string to this pointer, advancing this pointer as it goes. */ - void writeAll (const CharPointer_UTF32 src) noexcept + void writeAll (CharPointer_UTF32 src) noexcept { - const CharType* s = src.data; + auto* s = src.data; while ((*data = *s) != 0) { @@ -238,7 +232,7 @@ public: to the destination buffer before stopping. */ template - size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept + size_t writeWithDestByteLimit (CharPointer src, size_t maxDestBytes) noexcept { return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes); } @@ -248,21 +242,21 @@ public: written to the destination buffer before stopping (including the terminating null). */ template - void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept + void writeWithCharLimit (CharPointer src, int maxChars) noexcept { CharacterFunctions::copyWithCharLimit (*this, src, maxChars); } /** Compares this string with another one. */ template - int compare (const CharPointer other) const noexcept + int compare (CharPointer other) const noexcept { return CharacterFunctions::compare (*this, other); } #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID /** Compares this string with another one. */ - int compare (const CharPointer_UTF32 other) const noexcept + int compare (CharPointer_UTF32 other) const noexcept { return wcscmp (data, other.data); } @@ -270,34 +264,34 @@ public: /** Compares this string with another one, up to a specified number of characters. */ template - int compareUpTo (const CharPointer other, const int maxChars) const noexcept + int compareUpTo (CharPointer other, int maxChars) const noexcept { return CharacterFunctions::compareUpTo (*this, other, maxChars); } /** Compares this string with another one. */ template - int compareIgnoreCase (const CharPointer other) const + int compareIgnoreCase (CharPointer other) const { return CharacterFunctions::compareIgnoreCase (*this, other); } /** Compares this string with another one, up to a specified number of characters. */ template - int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept + int compareIgnoreCaseUpTo (CharPointer other, int maxChars) const noexcept { return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars); } /** Returns the character index of a substring, or -1 if it isn't found. */ template - int indexOf (const CharPointer stringToFind) const noexcept + int indexOf (CharPointer stringToFind) const noexcept { return CharacterFunctions::indexOf (*this, stringToFind); } /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind) const noexcept + int indexOf (juce_wchar charToFind) const noexcept { int i = 0; @@ -313,37 +307,37 @@ public: } /** Returns the character index of a unicode character, or -1 if it isn't found. */ - int indexOf (const juce_wchar charToFind, const bool ignoreCase) const noexcept + int indexOf (juce_wchar charToFind, bool ignoreCase) const noexcept { return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind) : CharacterFunctions::indexOfChar (*this, charToFind); } /** Returns true if the first character of this string is whitespace. */ - bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; } + bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; } /** Returns true if the first character of this string is a digit. */ - bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; } + bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; } /** Returns true if the first character of this string is a letter. */ - bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; } + bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; } /** Returns true if the first character of this string is a letter or digit. */ - bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; } + bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; } /** Returns true if the first character of this string is upper-case. */ - bool isUpperCase() const { return CharacterFunctions::isUpperCase (*data) != 0; } + bool isUpperCase() const { return CharacterFunctions::isUpperCase (*data) != 0; } /** Returns true if the first character of this string is lower-case. */ - bool isLowerCase() const { return CharacterFunctions::isLowerCase (*data) != 0; } + bool isLowerCase() const { return CharacterFunctions::isLowerCase (*data) != 0; } /** Returns an upper-case version of the first character of this string. */ - juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (*data); } + juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (*data); } /** Returns a lower-case version of the first character of this string. */ - juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (*data); } + juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (*data); } /** Parses this string as a 32-bit integer. */ - int getIntValue32() const noexcept { return CharacterFunctions::getIntValue (*this); } + int getIntValue32() const noexcept { return CharacterFunctions::getIntValue (*this); } /** Parses this string as a 64-bit integer. */ - int64 getIntValue64() const noexcept { return CharacterFunctions::getIntValue (*this); } + int64 getIntValue64() const noexcept { return CharacterFunctions::getIntValue (*this); } /** Parses this string as a floating point double. */ - double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } + double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } /** Returns the first non-whitespace character in the string. */ CharPointer_UTF32 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } @@ -351,7 +345,7 @@ public: /** Returns true if the given unicode character can be represented in this encoding. */ static bool canRepresent (juce_wchar character) noexcept { - return ((unsigned int) character) < (unsigned int) 0x10ffff; + return ((uint32) character) < (uint32) 0x10ffff; } /** Returns true if this data contains a valid string in this encoding. */ @@ -367,7 +361,7 @@ public: } /** Atomically swaps this pointer for a new value, returning the previous value. */ - CharPointer_UTF32 atomicSwap (const CharPointer_UTF32 newValue) + CharPointer_UTF32 atomicSwap (CharPointer_UTF32 newValue) { return CharPointer_UTF32 (reinterpret_cast&> (data).exchange (newValue.data)); } @@ -375,6 +369,3 @@ public: private: CharType* data; }; - - -#endif // JUCE_CHARPOINTER_UTF32_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_CharPointer_UTF8.h b/source/modules/juce_core/text/juce_CharPointer_UTF8.h index 357010735..1fe844e09 100644 --- a/source/modules/juce_core/text/juce_CharPointer_UTF8.h +++ b/source/modules/juce_core/text/juce_CharPointer_UTF8.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHARPOINTER_UTF8_H_INCLUDED -#define JUCE_CHARPOINTER_UTF8_H_INCLUDED +#pragma once //============================================================================== /** @@ -42,7 +33,7 @@ class CharPointer_UTF8 public: typedef char CharType; - inline explicit CharPointer_UTF8 (const CharType* const rawPointer) noexcept + inline explicit CharPointer_UTF8 (const CharType* rawPointer) noexcept : data (const_cast (rawPointer)) { } @@ -81,10 +72,13 @@ public: /** Returns true if this pointer is pointing to a null character. */ inline bool isEmpty() const noexcept { return *data == 0; } + /** Returns true if this pointer is not pointing to a null character. */ + inline bool isNotEmpty() const noexcept { return *data != 0; } + /** Returns the unicode character that this pointer is pointing to. */ juce_wchar operator*() const noexcept { - const signed char byte = (signed char) *data; + auto byte = (signed char) *data; if (byte >= 0) return (juce_wchar) (uint8) byte; @@ -105,7 +99,7 @@ public: for (int i = 1; i <= numExtraValues; ++i) { - const uint32 nextByte = (uint32) (uint8) data[i]; + auto nextByte = (uint32) (uint8) data[i]; if ((nextByte & 0xc0) != 0x80) break; @@ -121,13 +115,13 @@ public: CharPointer_UTF8& operator++() noexcept { jassert (*data != 0); // trying to advance past the end of the string? - const signed char n = (signed char) *data++; + auto n = (signed char) *data++; if (n < 0) { juce_wchar bit = 0x40; - while ((n & bit) != 0 && bit > 0x8) + while ((static_cast (n) & bit) != 0 && bit > 0x8) { ++data; bit >>= 1; @@ -152,7 +146,7 @@ public: advances the pointer to point to the next character. */ juce_wchar getAndAdvance() noexcept { - const signed char byte = (signed char) *data++; + auto byte = (signed char) *data++; if (byte >= 0) return (juce_wchar) (uint8) byte; @@ -173,7 +167,7 @@ public: while (--numExtraValues >= 0) { - const uint32 nextByte = (uint32) (uint8) *data; + auto nextByte = (uint32) (uint8) *data; if ((nextByte & 0xc0) != 0x80) break; @@ -218,7 +212,7 @@ public: /** Returns the character at a given character index from the start of the string. */ juce_wchar operator[] (int characterIndex) const noexcept { - CharPointer_UTF8 p (*this); + auto p (*this); p += characterIndex; return *p; } @@ -226,7 +220,7 @@ public: /** Returns a pointer which is moved forwards from this one by the specified number of characters. */ CharPointer_UTF8 operator+ (int numToSkip) const noexcept { - CharPointer_UTF8 p (*this); + auto p (*this); p += numToSkip; return p; } @@ -234,7 +228,7 @@ public: /** Returns a pointer which is moved backwards from this one by the specified number of characters. */ CharPointer_UTF8 operator- (int numToSkip) const noexcept { - CharPointer_UTF8 p (*this); + auto p (*this); p += -numToSkip; return p; } @@ -242,12 +236,12 @@ public: /** Returns the number of characters in this string. */ size_t length() const noexcept { - const CharType* d = data; + auto* d = data; size_t count = 0; for (;;) { - const uint32 n = (uint32) (uint8) *d++; + auto n = (uint32) (uint8) *d++; if ((n & 0x80) != 0) { @@ -290,7 +284,7 @@ public: static size_t getBytesRequiredFor (const juce_wchar charToWrite) noexcept { size_t num = 1; - const uint32 c = (uint32) charToWrite; + auto c = (uint32) charToWrite; if (c >= 0x80) { @@ -315,7 +309,7 @@ public: { size_t count = 0; - while (juce_wchar n = text.getAndAdvance()) + while (auto n = text.getAndAdvance()) count += getBytesRequiredFor (n); return count; @@ -330,7 +324,7 @@ public: /** Writes a unicode character to this string, and advances this pointer to point to the next position. */ void write (const juce_wchar charToWrite) noexcept { - const uint32 c = (uint32) charToWrite; + auto c = (uint32) charToWrite; if (c >= 0x80) { @@ -369,7 +363,7 @@ public: /** Copies a source string to this pointer, advancing this pointer as it goes. */ void writeAll (const CharPointer_UTF8 src) noexcept { - const CharType* s = src.data; + auto* s = src.data; while ((*data = *s) != 0) { @@ -453,25 +447,25 @@ public: } /** Returns true if the first character of this string is whitespace. */ - bool isWhitespace() const noexcept { const CharType c = *data; return c == ' ' || (c <= 13 && c >= 9); } + bool isWhitespace() const noexcept { const CharType c = *data; return c == ' ' || (c <= 13 && c >= 9); } /** Returns true if the first character of this string is a digit. */ - bool isDigit() const noexcept { const CharType c = *data; return c >= '0' && c <= '9'; } + bool isDigit() const noexcept { const CharType c = *data; return c >= '0' && c <= '9'; } /** Returns true if the first character of this string is a letter. */ - bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; } + bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; } /** Returns true if the first character of this string is a letter or digit. */ - bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; } + bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; } /** Returns true if the first character of this string is upper-case. */ - bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; } + bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; } /** Returns true if the first character of this string is lower-case. */ - bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; } + bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; } /** Returns an upper-case version of the first character of this string. */ - juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (operator*()); } + juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (operator*()); } /** Returns a lower-case version of the first character of this string. */ - juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (operator*()); } + juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (operator*()); } /** Parses this string as a 32-bit integer. */ - int getIntValue32() const noexcept { return atoi (data); } + int getIntValue32() const noexcept { return atoi (data); } /** Parses this string as a 64-bit integer. */ int64 getIntValue64() const noexcept @@ -486,15 +480,15 @@ public: } /** Parses this string as a floating point double. */ - double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } + double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); } /** Returns the first non-whitespace character in the string. */ - CharPointer_UTF8 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } + CharPointer_UTF8 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); } /** Returns true if the given unicode character can be represented in this encoding. */ static bool canRepresent (juce_wchar character) noexcept { - return ((unsigned int) character) < (unsigned int) 0x10ffff; + return ((uint32) character) < (uint32) 0x10ffff; } /** Returns true if this data contains a valid string in this encoding. */ @@ -502,7 +496,7 @@ public: { while (--maxBytesToRead >= 0 && *dataToTest != 0) { - const signed char byte = (signed char) *dataToTest++; + auto byte = (signed char) *dataToTest++; if (byte < 0) { @@ -558,7 +552,7 @@ public: static bool isByteOrderMark (const void* possibleByteOrder) noexcept { jassert (possibleByteOrder != nullptr); - const uint8* const c = static_cast (possibleByteOrder); + auto c = static_cast (possibleByteOrder); return c[0] == (uint8) byteOrderMark1 && c[1] == (uint8) byteOrderMark2 @@ -568,5 +562,3 @@ public: private: CharType* data; }; - -#endif // JUCE_CHARPOINTER_UTF8_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_CharacterFunctions.cpp b/source/modules/juce_core/text/juce_CharacterFunctions.cpp index 7a0152adc..cd81957d9 100644 --- a/source/modules/juce_core/text/juce_CharacterFunctions.cpp +++ b/source/modules/juce_core/text/juce_CharacterFunctions.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -122,15 +114,18 @@ bool CharacterFunctions::isPrintable (const juce_wchar character) noexcept int CharacterFunctions::getHexDigitValue (const juce_wchar digit) noexcept { - unsigned int d = (unsigned int) digit - '0'; + auto d = (unsigned int) (digit - '0'); + if (d < (unsigned int) 10) return (int) d; d += (unsigned int) ('0' - 'a'); + if (d < (unsigned int) 6) return (int) d + 10; d += (unsigned int) ('a' - 'A'); + if (d < (unsigned int) 6) return (int) d + 10; @@ -142,23 +137,27 @@ double CharacterFunctions::mulexp10 (const double value, int exponent) noexcept if (exponent == 0) return value; - if (value == 0) + if (value == 0.0) return 0; const bool negative = (exponent < 0); + if (negative) exponent = -exponent; double result = 1.0, power = 10.0; + for (int bit = 1; exponent != 0; bit <<= 1) { if ((exponent & bit) != 0) { exponent ^= bit; result *= power; + if (exponent == 0) break; } + power *= power; } @@ -177,3 +176,107 @@ juce_wchar CharacterFunctions::getUnicodeCharFromWindows1252Codepage (const uint return (juce_wchar) lookup[c - 0x80]; } + +//============================================================================== +#if JUCE_UNIT_TESTS + +#define QUOTE(x) #x +#define STR(value) QUOTE(value) +#define ASYM_STRING_DOUBLE_PAIR(str, value) std::pair (STR(str), value) +#define STRING_DOUBLE_PAIR(value) ASYM_STRING_DOUBLE_PAIR(value, value) +#define STRING_DOUBLE_PAIR_COMBOS(value) \ + STRING_DOUBLE_PAIR(value), \ + STRING_DOUBLE_PAIR(-value), \ + ASYM_STRING_DOUBLE_PAIR(+value, value), \ + ASYM_STRING_DOUBLE_PAIR(000000 ## value, value), \ + ASYM_STRING_DOUBLE_PAIR(+000 ## value, value), \ + ASYM_STRING_DOUBLE_PAIR(-0 ## value, -value) + +class CharacterFunctionsTests : public UnitTest +{ +public: + CharacterFunctionsTests() : UnitTest ("CharacterFunctions", "Text") {} + + void runTest() override + { + beginTest ("readDoubleValue"); + + static const std::pair testValues[] = + { + // Integers + STRING_DOUBLE_PAIR_COMBOS (0), + STRING_DOUBLE_PAIR_COMBOS (3), + STRING_DOUBLE_PAIR_COMBOS (4931), + STRING_DOUBLE_PAIR_COMBOS (5000), + STRING_DOUBLE_PAIR_COMBOS (9862097), + + // Floating point numbers + STRING_DOUBLE_PAIR_COMBOS (7.000), + STRING_DOUBLE_PAIR_COMBOS (0.2), + STRING_DOUBLE_PAIR_COMBOS (.298630), + STRING_DOUBLE_PAIR_COMBOS (1.118), + STRING_DOUBLE_PAIR_COMBOS (0.9000), + STRING_DOUBLE_PAIR_COMBOS (0.0000001), + STRING_DOUBLE_PAIR_COMBOS (500.0000001), + STRING_DOUBLE_PAIR_COMBOS (9862098.2398604), + + // Exponents + STRING_DOUBLE_PAIR_COMBOS (0e0), + STRING_DOUBLE_PAIR_COMBOS (0.e0), + STRING_DOUBLE_PAIR_COMBOS (0.00000e0), + STRING_DOUBLE_PAIR_COMBOS (.0e7), + STRING_DOUBLE_PAIR_COMBOS (0e-5), + STRING_DOUBLE_PAIR_COMBOS (2E0), + STRING_DOUBLE_PAIR_COMBOS (4.E0), + STRING_DOUBLE_PAIR_COMBOS (1.2000000E0), + STRING_DOUBLE_PAIR_COMBOS (1.2000000E6), + STRING_DOUBLE_PAIR_COMBOS (.398e3), + STRING_DOUBLE_PAIR_COMBOS (10e10), + STRING_DOUBLE_PAIR_COMBOS (1.4962e+2), + STRING_DOUBLE_PAIR_COMBOS (3198693.0973e4), + STRING_DOUBLE_PAIR_COMBOS (10973097.2087e-4), + STRING_DOUBLE_PAIR_COMBOS (1.3986e00006), + STRING_DOUBLE_PAIR_COMBOS (2087.3087e+00006), + STRING_DOUBLE_PAIR_COMBOS (6.0872e-00006), + + // Too many sig figs + STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890), + STRING_DOUBLE_PAIR_COMBOS (1.23456789012345678901234567890e-111) + + #if ! JUCE_LINUX + // Limits + , STRING_DOUBLE_PAIR (DBL_MAX), + STRING_DOUBLE_PAIR (-DBL_MAX), + STRING_DOUBLE_PAIR (DBL_MIN) + #endif + }; + + for (auto trial : testValues) + { + auto charPtr = trial.first.getCharPointer(); + expectEquals (CharacterFunctions::readDoubleValue (charPtr), trial.second); + } + + { + String nans[] = { "NaN", "-nan", "+NAN", "1.0E1024", "-1.0E-999", "1.23456789012345678901234567890e123456789"}; + for (auto nan : nans) + { + auto charPtr = nan.getCharPointer(); + expect (std::isnan (CharacterFunctions::readDoubleValue (charPtr))); + } + } + + { + String infs[] = { "Inf", "-inf", "INF"}; + for (auto inf : infs) + { + auto charPtr = inf.getCharPointer(); + expect (std::isinf (CharacterFunctions::readDoubleValue (charPtr))); + } + } + } +}; + +static CharacterFunctionsTests characterFunctionsTests; + +#endif diff --git a/source/modules/juce_core/text/juce_CharacterFunctions.h b/source/modules/juce_core/text/juce_CharacterFunctions.h index c4920072e..77f4dcd74 100644 --- a/source/modules/juce_core/text/juce_CharacterFunctions.h +++ b/source/modules/juce_core/text/juce_CharacterFunctions.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHARACTERFUNCTIONS_H_INCLUDED -#define JUCE_CHARACTERFUNCTIONS_H_INCLUDED +#pragma once //============================================================================== @@ -136,19 +127,19 @@ public: template static double readDoubleValue (CharPointerType& text) noexcept { - double result[3] = { 0 }, accumulator[2] = { 0 }; - int exponentAdjustment[2] = { 0 }, exponentAccumulator[2] = { -1, -1 }; - int exponent = 0, decPointIndex = 0, digit = 0; - int lastDigit = 0, numSignificantDigits = 0; - bool isNegative = false, digitsFound = false; - const int maxSignificantDigits = 15 + 2; + const int maxSignificantDigits = 17 + 1; // An additional digit for rounding + const int bufferSize = maxSignificantDigits + 7 + 1; // -.E-XXX and a trailing null-terminator + char buffer[bufferSize] = {}; + char* currentCharacter = &(buffer[0]); + int numSigFigs = 0; + bool decimalPointFound = false; text = text.findEndOfWhitespace(); - juce_wchar c = *text; + auto c = *text; switch (c) { - case '-': isNegative = true; // fall-through.. + case '-': *currentCharacter++ = '-'; // Fall-through.. case '+': c = *++text; } @@ -171,61 +162,20 @@ public: { if (text.isDigit()) { - lastDigit = digit; - digit = (int) text.getAndAdvance() - '0'; - digitsFound = true; + int digit = (int) text.getAndAdvance() - '0'; - if (decPointIndex != 0) - exponentAdjustment[1]++; - - if (numSignificantDigits == 0 && digit == 0) + if (numSigFigs >= maxSignificantDigits + || ((numSigFigs == 0 && (! decimalPointFound)) && digit == 0)) continue; - if (++numSignificantDigits > maxSignificantDigits) - { - if (digit > 5) - ++accumulator [decPointIndex]; - else if (digit == 5 && (lastDigit & 1) != 0) - ++accumulator [decPointIndex]; - - if (decPointIndex > 0) - exponentAdjustment[1]--; - else - exponentAdjustment[0]++; - - while (text.isDigit()) - { - ++text; - if (decPointIndex == 0) - exponentAdjustment[0]++; - } - } - else - { - const double maxAccumulatorValue = (double) ((std::numeric_limits::max() - 9) / 10); - if (accumulator [decPointIndex] > maxAccumulatorValue) - { - result [decPointIndex] = mulexp10 (result [decPointIndex], exponentAccumulator [decPointIndex]) - + accumulator [decPointIndex]; - accumulator [decPointIndex] = 0; - exponentAccumulator [decPointIndex] = 0; - } - - accumulator [decPointIndex] = accumulator[decPointIndex] * 10 + digit; - exponentAccumulator [decPointIndex]++; - } + *currentCharacter++ = '0' + (char) digit; + numSigFigs++; } - else if (decPointIndex == 0 && *text == '.') + else if ((! decimalPointFound) && *text == '.') { ++text; - decPointIndex = 1; - - if (numSignificantDigits > maxSignificantDigits) - { - while (text.isDigit()) - ++text; - break; - } + *currentCharacter++ = '.'; + decimalPointFound = true; } else { @@ -233,34 +183,39 @@ public: } } - result[0] = mulexp10 (result[0], exponentAccumulator[0]) + accumulator[0]; - - if (decPointIndex != 0) - result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1]; - c = *text; - if ((c == 'e' || c == 'E') && digitsFound) + + if ((c == 'e' || c == 'E') && numSigFigs > 0) { - bool negativeExponent = false; + *currentCharacter++ = 'e'; switch (*++text) { - case '-': negativeExponent = true; // fall-through.. + case '-': *currentCharacter++ = '-'; // Fall-through.. case '+': ++text; } + int exponentMagnitude = 0; + while (text.isDigit()) - exponent = (exponent * 10) + ((int) text.getAndAdvance() - '0'); + { + if (currentCharacter == &buffer[bufferSize - 1]) + return std::numeric_limits::quiet_NaN(); - if (negativeExponent) - exponent = -exponent; - } + auto digit = (int) text.getAndAdvance() - '0'; - double r = mulexp10 (result[0], exponent + exponentAdjustment[0]); - if (decPointIndex != 0) - r += mulexp10 (result[1], exponent - exponentAdjustment[1]); + if (digit != 0 || exponentMagnitude != 0) + { + *currentCharacter++ = '0' + (char) digit; + exponentMagnitude = (exponentMagnitude * 10) + digit; + } + } + + if (exponentMagnitude > std::numeric_limits::max_exponent10) + return std::numeric_limits::quiet_NaN(); + } - return isNegative ? -r : r; + return strtod (&buffer[0], nullptr); } /** Parses a character string, to read a floating-point value. */ @@ -276,15 +231,15 @@ public: static IntType getIntValue (const CharPointerType text) noexcept { IntType v = 0; - CharPointerType s (text.findEndOfWhitespace()); - + auto s = text.findEndOfWhitespace(); const bool isNeg = *s == '-'; + if (isNeg) ++s; for (;;) { - const juce_wchar c = s.getAndAdvance(); + auto c = s.getAndAdvance(); if (c >= '0' && c <= '9') v = v * 10 + (IntType) (c - '0'); @@ -305,7 +260,7 @@ public: while (! t.isEmpty()) { - const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); + auto hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance()); if (hexValue >= 0) result = (result << 4) | hexValue; @@ -357,16 +312,16 @@ public: template static size_t copyWithDestByteLimit (DestCharPointerType& dest, SrcCharPointerType src, size_t maxBytesToWrite) noexcept { - typename DestCharPointerType::CharType const* const startAddress = dest.getAddress(); - ssize_t maxBytes = (ssize_t) maxBytesToWrite; + auto startAddress = dest.getAddress(); + auto maxBytes = (ssize_t) maxBytesToWrite; maxBytes -= sizeof (typename DestCharPointerType::CharType); // (allow for a terminating null) for (;;) { - const juce_wchar c = src.getAndAdvance(); - const size_t bytesNeeded = DestCharPointerType::getBytesRequiredFor (c); - + auto c = src.getAndAdvance(); + auto bytesNeeded = DestCharPointerType::getBytesRequiredFor (c); maxBytes -= bytesNeeded; + if (c == 0 || maxBytes < 0) break; @@ -386,7 +341,8 @@ public: { while (--maxChars > 0) { - const juce_wchar c = src.getAndAdvance(); + auto c = src.getAndAdvance(); + if (c == 0) break; @@ -399,7 +355,7 @@ public: /** Compares two characters. */ static inline int compare (juce_wchar char1, juce_wchar char2) noexcept { - if (int diff = static_cast (char1) - static_cast (char2)) + if (auto diff = static_cast (char1) - static_cast (char2)) return diff < 0 ? -1 : 1; return 0; @@ -411,9 +367,9 @@ public: { for (;;) { - const juce_wchar c1 = s1.getAndAdvance(); + auto c1 = s1.getAndAdvance(); - if (int diff = compare (c1, s2.getAndAdvance())) + if (auto diff = compare (c1, s2.getAndAdvance())) return diff; if (c1 == 0) @@ -429,9 +385,9 @@ public: { while (--maxChars >= 0) { - const juce_wchar c1 = s1.getAndAdvance(); + auto c1 = s1.getAndAdvance(); - if (int diff = compare (c1, s2.getAndAdvance())) + if (auto diff = compare (c1, s2.getAndAdvance())) return diff; if (c1 == 0) @@ -453,9 +409,9 @@ public: { for (;;) { - const juce_wchar c1 = s1.getAndAdvance(); + auto c1 = s1.getAndAdvance(); - if (int diff = compareIgnoreCase (c1, s2.getAndAdvance())) + if (auto diff = compareIgnoreCase (c1, s2.getAndAdvance())) return diff; if (c1 == 0) @@ -471,9 +427,9 @@ public: { while (--maxChars >= 0) { - const juce_wchar c1 = s1.getAndAdvance(); + auto c1 = s1.getAndAdvance(); - if (int diff = compareIgnoreCase (c1, s2.getAndAdvance())) + if (auto diff = compareIgnoreCase (c1, s2.getAndAdvance())) return diff; if (c1 == 0) @@ -490,7 +446,7 @@ public: static int indexOf (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept { int index = 0; - const int substringLength = (int) substringToLookFor.length(); + auto substringLength = (int) substringToLookFor.length(); for (;;) { @@ -511,7 +467,7 @@ public: template static CharPointerType1 find (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept { - const int substringLength = (int) substringToLookFor.length(); + auto substringLength = (int) substringToLookFor.length(); while (textToSearch.compareUpTo (substringToLookFor, substringLength) != 0 && ! textToSearch.isEmpty()) @@ -529,7 +485,7 @@ public: { for (;; ++textToSearch) { - const juce_wchar c = *textToSearch; + auto c = *textToSearch; if (c == charToLookFor || c == 0) break; @@ -546,7 +502,7 @@ public: static int indexOfIgnoreCase (CharPointerType1 haystack, const CharPointerType2 needle) noexcept { int index = 0; - const int needleLength = (int) needle.length(); + auto needleLength = (int) needle.length(); for (;;) { @@ -618,13 +574,13 @@ public: the breakCharacters string. */ template - static Type findEndOfToken (Type text, const BreakType breakCharacters, const Type quoteCharacters) + static Type findEndOfToken (Type text, BreakType breakCharacters, Type quoteCharacters) { juce_wchar currentQuoteChar = 0; while (! text.isEmpty()) { - const juce_wchar c = text.getAndAdvance(); + auto c = text.getAndAdvance(); if (currentQuoteChar == 0 && breakCharacters.indexOf (c) >= 0) { @@ -645,8 +601,5 @@ public: } private: - static double mulexp10 (const double value, int exponent) noexcept; + static double mulexp10 (double value, int exponent) noexcept; }; - - -#endif // JUCE_CHARACTERFUNCTIONS_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_Identifier.cpp b/source/modules/juce_core/text/juce_Identifier.cpp index a16d68caa..513b921e5 100644 --- a/source/modules/juce_core/text/juce_Identifier.cpp +++ b/source/modules/juce_core/text/juce_Identifier.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -33,7 +25,6 @@ Identifier::~Identifier() noexcept {} Identifier::Identifier (const Identifier& other) noexcept : name (other.name) {} -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Identifier::Identifier (Identifier&& other) noexcept : name (static_cast (other.name)) {} Identifier& Identifier::operator= (Identifier&& other) noexcept @@ -41,7 +32,6 @@ Identifier& Identifier::operator= (Identifier&& other) noexcept name = static_cast (other.name); return *this; } -#endif Identifier& Identifier::operator= (const Identifier& other) noexcept { diff --git a/source/modules/juce_core/text/juce_Identifier.h b/source/modules/juce_core/text/juce_Identifier.h index 24b02375e..1d960e586 100644 --- a/source/modules/juce_core/text/juce_Identifier.h +++ b/source/modules/juce_core/text/juce_Identifier.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IDENTIFIER_H_INCLUDED -#define JUCE_IDENTIFIER_H_INCLUDED +#pragma once //============================================================================== @@ -72,13 +63,11 @@ public: /** Creates a copy of another identifier. */ Identifier& operator= (const Identifier& other) noexcept; - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS /** Creates a copy of another identifier. */ Identifier (Identifier&& other) noexcept; /** Creates a copy of another identifier. */ Identifier& operator= (Identifier&& other) noexcept; - #endif /** Destructor */ ~Identifier() noexcept; @@ -137,6 +126,3 @@ public: private: String name; }; - - -#endif // JUCE_IDENTIFIER_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_LocalisedStrings.cpp b/source/modules/juce_core/text/juce_LocalisedStrings.cpp index 72009564e..58533de91 100644 --- a/source/modules/juce_core/text/juce_LocalisedStrings.cpp +++ b/source/modules/juce_core/text/juce_LocalisedStrings.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/text/juce_LocalisedStrings.h b/source/modules/juce_core/text/juce_LocalisedStrings.h index 465ffa3ab..71b6423fd 100644 --- a/source/modules/juce_core/text/juce_LocalisedStrings.h +++ b/source/modules/juce_core/text/juce_LocalisedStrings.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LOCALISEDSTRINGS_H_INCLUDED -#define JUCE_LOCALISEDSTRINGS_H_INCLUDED +#pragma once //============================================================================== @@ -244,6 +235,3 @@ JUCE_API String translate (CharPointer_UTF8 stringLiteral); @see LocalisedStrings */ JUCE_API String translate (const String& stringLiteral, const String& resultIfNotFound); - - -#endif // JUCE_LOCALISEDSTRINGS_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_NewLine.h b/source/modules/juce_core/text/juce_NewLine.h index fef928344..885618a7a 100644 --- a/source/modules/juce_core/text/juce_NewLine.h +++ b/source/modules/juce_core/text/juce_NewLine.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_NEWLINE_H_INCLUDED -#define JUCE_NEWLINE_H_INCLUDED +#pragma once //============================================================================== @@ -85,6 +76,3 @@ inline String& operator+= (String& s1, const NewLine&) { return s1 += NewLi inline String operator+ (const NewLine&, const NewLine&) { return String (NewLine::getDefault()) + NewLine::getDefault(); } inline String operator+ (String s1, const NewLine&) { return s1 += NewLine::getDefault(); } inline String operator+ (const NewLine&, const char* s2) { return String (NewLine::getDefault()) + s2; } - - -#endif // JUCE_NEWLINE_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_String.cpp b/source/modules/juce_core/text/juce_String.cpp index 798f46f70..d835bfc26 100644 --- a/source/modules/juce_core/text/juce_String.cpp +++ b/source/modules/juce_core/text/juce_String.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -226,16 +218,17 @@ private: { // Let me know if any of these assertions fail on your system! #if JUCE_NATIVE_WCHAR_IS_UTF8 - static_jassert (sizeof (wchar_t) == 1); + static_assert (sizeof (wchar_t) == 1, "JUCE_NATIVE_WCHAR_IS_* macro has incorrect value"); #elif JUCE_NATIVE_WCHAR_IS_UTF16 - static_jassert (sizeof (wchar_t) == 2); + static_assert (sizeof (wchar_t) == 2, "JUCE_NATIVE_WCHAR_IS_* macro has incorrect value"); #elif JUCE_NATIVE_WCHAR_IS_UTF32 - static_jassert (sizeof (wchar_t) == 4); + static_assert (sizeof (wchar_t) == 4, "JUCE_NATIVE_WCHAR_IS_* macro has incorrect value"); #else #error "native wchar_t size is unknown" #endif - static_jassert (sizeof (EmptyString) == sizeof (StringHolder)); + static_assert (sizeof (EmptyString) == sizeof (StringHolder), + "StringHolder is not large enough to hold an empty String"); } }; @@ -276,7 +269,6 @@ String& String::operator= (const String& other) noexcept return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS String::String (String&& other) noexcept : text (other.text) { other.text = &(emptyString.text); @@ -287,7 +279,6 @@ String& String::operator= (String&& other) noexcept std::swap (text, other.text); return *this; } -#endif inline String::PreallocationBytes::PreallocationBytes (const size_t num) noexcept : numBytes (num) {} @@ -1180,7 +1171,7 @@ bool String::matchesWildcard (StringRef wildcard, const bool ignoreCase) const n String String::repeatedString (StringRef stringToRepeat, int numberOfTimesToRepeat) { if (numberOfTimesToRepeat <= 0) - return String(); + return {}; String result (PreallocationBytes (findByteOffsetOfEnd (stringToRepeat) * (size_t) numberOfTimesToRepeat)); CharPointerType n (result.text); @@ -1292,7 +1283,7 @@ String String::replaceSection (int index, int numCharsToReplace, StringRef strin const size_t newTotalBytes = initialBytes + newStringBytes + remainderBytes; if (newTotalBytes <= 0) - return String(); + return {}; String result (PreallocationBytes ((size_t) newTotalBytes)); @@ -1326,6 +1317,18 @@ String String::replace (StringRef stringToReplace, StringRef stringToInsert, con return result; } +String String::replaceFirstOccurrenceOf (StringRef stringToReplace, StringRef stringToInsert, const bool ignoreCase) const +{ + const int stringToReplaceLen = stringToReplace.length(); + const int index = ignoreCase ? indexOfIgnoreCase (stringToReplace) + : indexOf (stringToReplace); + + if (index >= 0) + return replaceSection (index, stringToReplaceLen, stringToInsert); + + return *this; +} + class StringCreationHelper { public: @@ -1526,7 +1529,7 @@ String String::substring (int start, const int end) const start = 0; if (end <= start) - return String(); + return {}; int i = 0; CharPointerType t1 (text); @@ -1534,7 +1537,7 @@ String String::substring (int start, const int end) const while (i < start) { if (t1.isEmpty()) - return String(); + return {}; ++i; ++t1; @@ -1568,7 +1571,7 @@ String String::substring (int start) const while (--start >= 0) { if (t.isEmpty()) - return String(); + return {}; ++t; } @@ -1593,7 +1596,7 @@ String String::fromFirstOccurrenceOf (StringRef sub, const int i = ignoreCase ? indexOfIgnoreCase (sub) : indexOf (sub); if (i < 0) - return String(); + return {}; return substring (includeSubString ? i : i + sub.length()); } @@ -1634,26 +1637,23 @@ String String::upToLastOccurrenceOf (StringRef sub, return substring (0, includeSubString ? i + sub.length() : i); } -bool String::isQuotedString() const +static bool isQuoteCharacter (juce_wchar c) noexcept { - const juce_wchar trimmedStart = trimStart()[0]; + return c == '"' || c == '\''; +} - return trimmedStart == '"' - || trimmedStart == '\''; +bool String::isQuotedString() const +{ + return isQuoteCharacter (*text.findEndOfWhitespace()); } String String::unquoted() const { - const int len = length(); - - if (len == 0) - return String(); - - const juce_wchar lastChar = text [len - 1]; - const int dropAtStart = (*text == '"' || *text == '\'') ? 1 : 0; - const int dropAtEnd = (lastChar == '"' || lastChar == '\'') ? 1 : 0; + if (! isQuoteCharacter (*text)) + return *this; - return substring (dropAtStart, len - dropAtEnd); + auto len = length(); + return substring (1, len - (isQuoteCharacter (text[len - 1]) ? 1 : 0)); } String String::quoted (const juce_wchar quoteCharacter) const @@ -1698,7 +1698,7 @@ String String::trim() const CharPointerType trimmedEnd (findTrimmedEnd (start, end)); if (trimmedEnd <= start) - return String(); + return {}; if (text < start || trimmedEnd < end) return String (start, trimmedEnd); @@ -1771,7 +1771,7 @@ String String::trimCharactersAtEnd (StringRef charactersToTrim) const String String::retainCharacters (StringRef charactersToRetain) const { if (isEmpty()) - return String(); + return {}; StringCreationHelper builder (text); @@ -1793,7 +1793,7 @@ String String::retainCharacters (StringRef charactersToRetain) const String String::removeCharacters (StringRef charactersToRemove) const { if (isEmpty()) - return String(); + return {}; StringCreationHelper builder (text); @@ -1856,8 +1856,7 @@ bool String::containsNonWhitespaceChars() const noexcept return false; } -// Note! The format parameter here MUST NOT be a reference, otherwise MS's va_start macro fails to work (but still compiles). -String String::formatted (const String pf, ... ) +String String::formattedRaw (const char* pf, ...) { size_t bufferSize = 256; @@ -1866,19 +1865,22 @@ String String::formatted (const String pf, ... ) va_list args; va_start (args, pf); - #if JUCE_WINDOWS - HeapBlock temp (bufferSize); - const int num = (int) _vsnwprintf (temp.getData(), bufferSize - 1, pf.toWideCharPointer(), args); - #elif JUCE_ANDROID + #if JUCE_ANDROID HeapBlock temp (bufferSize); - int num = (int) vsnprintf (temp.getData(), bufferSize - 1, pf.toUTF8(), args); - if (num >= bufferSize) + int num = (int) vsnprintf (temp.getData(), bufferSize - 1, pf, args); + if (num >= static_cast (bufferSize)) num = -1; - #else + #else + String wideCharVersion (pf); HeapBlock temp (bufferSize); - const int num = (int) vswprintf (temp.getData(), bufferSize - 1, pf.toWideCharPointer(), args); + const int num = (int) + #if JUCE_WINDOWS + _vsnwprintf + #else + vswprintf #endif - + (temp.getData(), bufferSize - 1, wideCharVersion.toWideCharPointer(), args); + #endif va_end (args); if (num > 0) @@ -1890,7 +1892,7 @@ String String::formatted (const String pf, ... ) break; // returns -1 because of an error rather than because it needs more space. } - return String(); + return {}; } //============================================================================== @@ -1915,7 +1917,7 @@ int String::getTrailingIntValue() const noexcept break; } - n += mult * (*t - '0'); + n += static_cast (mult) * (*t - '0'); mult *= 10; } @@ -1928,8 +1930,8 @@ template static String hexToString (Type v) { String::CharPointerType::CharType buffer[32]; - String::CharPointerType::CharType* const end = buffer + numElementsInArray (buffer) - 1; - String::CharPointerType::CharType* t = end; + auto* end = buffer + numElementsInArray (buffer) - 1; + auto* t = end; *t = 0; do @@ -1943,14 +1945,15 @@ static String hexToString (Type v) String::CharPointerType (end)); } -String String::toHexString (int number) { return hexToString ((unsigned int) number); } -String String::toHexString (int64 number) { return hexToString ((uint64) number); } -String String::toHexString (short number) { return toHexString ((int) (unsigned short) number); } +String String::createHex (uint8 n) { return hexToString (n); } +String String::createHex (uint16 n) { return hexToString (n); } +String String::createHex (uint32 n) { return hexToString (n); } +String String::createHex (uint64 n) { return hexToString (n); } String String::toHexString (const void* const d, const int size, const int groupSize) { if (size <= 0) - return String(); + return {}; int numChars = (size * 2) + 2; if (groupSize > 0) @@ -1958,7 +1961,7 @@ String String::toHexString (const void* const d, const int size, const int group String s (PreallocationBytes (sizeof (CharPointerType::CharType) * (size_t) numChars)); - const unsigned char* data = static_cast (d); + auto* data = static_cast (d); CharPointerType dest (s.text); for (int i = 0; i < size; ++i) @@ -1992,10 +1995,10 @@ static String getStringFromWindows1252Codepage (const char* data, size_t num) String String::createStringFromData (const void* const unknownData, int size) { - const uint8* const data = static_cast (unknownData); + auto* data = static_cast (unknownData); if (size <= 0 || data == nullptr) - return String(); + return {}; if (size == 1) return charToString ((juce_wchar) data[0]); @@ -2024,7 +2027,7 @@ String String::createStringFromData (const void* const unknownData, int size) return builder.result; } - const char* start = (const char*) data; + auto* start = (const char*) data; if (size >= 3 && CharPointer_UTF8::isByteOrderMark (data)) { @@ -2047,7 +2050,7 @@ struct StringEncodingConverter { static CharPointerType_Dest convert (const String& s) { - String& source = const_cast (s); + auto& source = const_cast (s); typedef typename CharPointerType_Dest::CharType DestChar; @@ -2161,7 +2164,7 @@ String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) } } - return String(); + return {}; } #if JUCE_MSVC @@ -2220,7 +2223,7 @@ StringRef::StringRef (const String& string) noexcept : text (string.getCharPoin class StringTests : public UnitTest { public: - StringTests() : UnitTest ("String class") {} + StringTests() : UnitTest ("String class", "Text") {} template struct TestUTFConversion @@ -2499,6 +2502,12 @@ public: expect (String::toHexString (0x1234abcd).equalsIgnoreCase ("1234abcd")); expect (String::toHexString ((int64) 0x1234abcd).equalsIgnoreCase ("1234abcd")); expect (String::toHexString ((short) 0x12ab).equalsIgnoreCase ("12ab")); + expect (String::toHexString ((size_t) 0x12ab).equalsIgnoreCase ("12ab")); + expect (String::toHexString ((long) 0x12ab).equalsIgnoreCase ("12ab")); + expect (String::toHexString ((int8) -1).equalsIgnoreCase ("ff")); + expect (String::toHexString ((int16) -1).equalsIgnoreCase ("ffff")); + expect (String::toHexString ((int32) -1).equalsIgnoreCase ("ffffffff")); + expect (String::toHexString ((int64) -1).equalsIgnoreCase ("ffffffffffffffff")); unsigned char data[] = { 1, 2, 3, 4, 0xa, 0xb, 0xc, 0xd }; expect (String::toHexString (data, 8, 0).equalsIgnoreCase ("010203040a0b0c0d")); diff --git a/source/modules/juce_core/text/juce_String.h b/source/modules/juce_core/text/juce_String.h index 088025453..9b561d529 100644 --- a/source/modules/juce_core/text/juce_String.h +++ b/source/modules/juce_core/text/juce_String.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STRING_H_INCLUDED -#define JUCE_STRING_H_INCLUDED +#pragma once //============================================================================== @@ -54,9 +45,8 @@ public: /** Creates a copy of another string. */ String (const String& other) noexcept; - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ String (String&& other) noexcept; - #endif /** Creates a string from a zero-terminated ascii text string. @@ -200,9 +190,8 @@ public: /** Replaces this string's contents with another string. */ String& operator= (const String& other) noexcept; - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Moves the contents of another string to the receiver */ String& operator= (String&& other) noexcept; - #endif /** Appends another string at the end of this one. */ String& operator+= (const String& stringToAppend); @@ -257,12 +246,12 @@ public: size_t extraBytesNeeded = 0, numChars = 1; - for (CharPointer t (startOfTextToAppend); t != endOfTextToAppend && ! t.isEmpty(); ++numChars) + for (auto t = startOfTextToAppend; t != endOfTextToAppend && ! t.isEmpty(); ++numChars) extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance()); if (extraBytesNeeded > 0) { - const size_t byteOffsetOfNull = getByteOffsetOfEnd(); + auto byteOffsetOfNull = getByteOffsetOfEnd(); preallocateBytes (byteOffsetOfNull + extraBytesNeeded); CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)) @@ -285,12 +274,12 @@ public: { size_t extraBytesNeeded = 0, numChars = 1; - for (CharPointer t (textToAppend); numChars <= maxCharsToTake && ! t.isEmpty(); ++numChars) + for (auto t = textToAppend; numChars <= maxCharsToTake && ! t.isEmpty(); ++numChars) extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance()); if (extraBytesNeeded > 0) { - const size_t byteOffsetOfNull = getByteOffsetOfEnd(); + auto byteOffsetOfNull = getByteOffsetOfEnd(); preallocateBytes (byteOffsetOfNull + extraBytesNeeded); CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)) @@ -782,6 +771,17 @@ public: StringRef stringToInsertInstead, bool ignoreCase = false) const; + /** Replaces the first occurrence of a substring with another string. + + Returns a copy of this string, with the first occurrence of stringToReplace + swapped for stringToInsertInstead. + + Note that this is a const method, and won't alter the string itself. + */ + String replaceFirstOccurrenceOf (StringRef stringToReplace, + StringRef stringToInsertInstead, + bool ignoreCase = false) const; + /** Returns a string with all occurrences of a character replaced with a different one. */ String replaceCharacter (juce_wchar characterToReplace, juce_wchar characterToInsertInstead) const; @@ -911,7 +911,8 @@ public: on the platform, it may be using wchar_t or char character types, so that even string literals can't be safely used as parameters if you're writing portable code. */ - static String formatted (const String formatString, ... ); + template + static String formatted (const String& formatStr, Args... args) { return formattedRaw (formatStr.toRawUTF8(), args...); } //============================================================================== // Numeric conversions.. @@ -1045,16 +1046,11 @@ public: */ int64 getHexValue64() const noexcept; - /** Creates a string representing this 32-bit value in hexadecimal. */ - static String toHexString (int number); + /** Returns a string representing this numeric value in hexadecimal. */ + template + static String toHexString (IntegerType number) { return createHex (number); } - /** Creates a string representing this 64-bit value in hexadecimal. */ - static String toHexString (int64 number); - - /** Creates a string representing this 16-bit value in hexadecimal. */ - static String toHexString (short number); - - /** Creates a string containing a hex dump of a block of binary data. + /** Returns a string containing a hex dump of a block of binary data. @param data the binary data to use as input @param size how many bytes of data to use @@ -1266,6 +1262,17 @@ private: // to bools (this is possible because the compiler can add an implicit cast // via a const char*) operator bool() const noexcept { return false; } + + //============================================================================== + static String formattedRaw (const char*, ...); + + static String createHex (uint8); + static String createHex (uint16); + static String createHex (uint32); + static String createHex (uint64); + + template + static String createHex (Type n) { return createHex (static_cast::type> (n)); } }; //============================================================================== @@ -1323,6 +1330,8 @@ JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int number); /** Appends a decimal number at the end of a string. */ JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, long number); /** Appends a decimal number at the end of a string. */ +JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, unsigned long number); +/** Appends a decimal number at the end of a string. */ JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int64 number); /** Appends a decimal number at the end of a string. */ JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, uint64 number); @@ -1391,6 +1400,3 @@ JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const Str /** Writes a string to an OutputStream as UTF8. */ JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, StringRef stringToWrite); - - -#endif // JUCE_STRING_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_StringArray.cpp b/source/modules/juce_core/text/juce_StringArray.cpp index 5db0b9d24..2ce830f71 100644 --- a/source/modules/juce_core/text/juce_StringArray.cpp +++ b/source/modules/juce_core/text/juce_StringArray.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -37,12 +29,10 @@ StringArray::StringArray (const StringArray& other) { } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS StringArray::StringArray (StringArray&& other) noexcept : strings (static_cast&&> (other.strings)) { } -#endif StringArray::StringArray (const String& firstValue) { @@ -80,13 +70,11 @@ StringArray& StringArray::operator= (const StringArray& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS StringArray& StringArray::operator= (StringArray&& other) noexcept { strings = static_cast&&> (other.strings); return *this; } -#endif #if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS StringArray::StringArray (const std::initializer_list& stringList) @@ -147,12 +135,10 @@ void StringArray::add (const String& newString) strings.add (newString); } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS void StringArray::add (String&& stringToAdd) { strings.add (static_cast (stringToAdd)); } -#endif void StringArray::insert (const int index, const String& newString) { @@ -326,7 +312,7 @@ String StringArray::joinIntoString (StringRef separator, int start, int numberTo start = 0; if (start >= last) - return String(); + return {}; if (start == last - 1) return strings.getReference (start); @@ -340,7 +326,7 @@ String StringArray::joinIntoString (StringRef separator, int start, int numberTo String result; result.preallocateBytes (bytesNeeded); - String::CharPointerType dest (result.getCharPointer()); + auto dest = result.getCharPointer(); while (start < last) { diff --git a/source/modules/juce_core/text/juce_StringArray.h b/source/modules/juce_core/text/juce_StringArray.h index 8dd64c310..a49c65f6b 100644 --- a/source/modules/juce_core/text/juce_StringArray.h +++ b/source/modules/juce_core/text/juce_StringArray.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STRINGARRAY_H_INCLUDED -#define JUCE_STRINGARRAY_H_INCLUDED +#pragma once //============================================================================== @@ -48,9 +39,8 @@ public: /** Creates a copy of another string array */ StringArray (const StringArray&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ StringArray (StringArray&&) noexcept; - #endif /** Creates an array containing a single string. */ explicit StringArray (const String& firstValue); @@ -98,9 +88,8 @@ public: /** Copies the contents of another string array into this one */ StringArray& operator= (const StringArray&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move assignment operator */ StringArray& operator= (StringArray&&) noexcept; - #endif /** Swaps the contents of this and another StringArray. */ void swapWith (StringArray&) noexcept; @@ -177,10 +166,8 @@ public: /** Appends a string at the end of the array. */ void add (const String& stringToAdd); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS /** Appends a string at the end of the array. */ void add (String&& stringToAdd); - #endif /** Inserts a string into the array. @@ -436,6 +423,3 @@ public: private: JUCE_LEAK_DETECTOR (StringArray) }; - - -#endif // JUCE_STRINGARRAY_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_StringPairArray.cpp b/source/modules/juce_core/text/juce_StringPairArray.cpp index 7f8b4b7df..5ae706fbc 100644 --- a/source/modules/juce_core/text/juce_StringPairArray.cpp +++ b/source/modules/juce_core/text/juce_StringPairArray.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/text/juce_StringPairArray.h b/source/modules/juce_core/text/juce_StringPairArray.h index fd1eb7c33..7d9f3afef 100644 --- a/source/modules/juce_core/text/juce_StringPairArray.h +++ b/source/modules/juce_core/text/juce_StringPairArray.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STRINGPAIRARRAY_H_INCLUDED -#define JUCE_STRINGPAIRARRAY_H_INCLUDED +#pragma once //============================================================================== @@ -97,7 +88,7 @@ public: const StringArray& getAllValues() const noexcept { return values; } /** Returns the number of strings in the array */ - inline int size() const noexcept { return keys.size(); }; + inline int size() const noexcept { return keys.size(); } //============================================================================== @@ -154,6 +145,3 @@ private: JUCE_LEAK_DETECTOR (StringPairArray) }; - - -#endif // JUCE_STRINGPAIRARRAY_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_StringPool.cpp b/source/modules/juce_core/text/juce_StringPool.cpp index d88820cee..65bde3535 100644 --- a/source/modules/juce_core/text/juce_StringPool.cpp +++ b/source/modules/juce_core/text/juce_StringPool.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -106,7 +98,7 @@ static String addPooledString (Array& strings, const NewStringType& newS String StringPool::getPooledString (const char* const newString) { if (newString == nullptr || *newString == 0) - return String(); + return {}; const ScopedLock sl (lock); garbageCollectIfNeeded(); @@ -116,7 +108,7 @@ String StringPool::getPooledString (const char* const newString) String StringPool::getPooledString (String::CharPointerType start, String::CharPointerType end) { if (start.isEmpty() || start == end) - return String(); + return {}; const ScopedLock sl (lock); garbageCollectIfNeeded(); @@ -126,7 +118,7 @@ String StringPool::getPooledString (String::CharPointerType start, String::CharP String StringPool::getPooledString (StringRef newString) { if (newString.isEmpty()) - return String(); + return {}; const ScopedLock sl (lock); garbageCollectIfNeeded(); @@ -136,7 +128,7 @@ String StringPool::getPooledString (StringRef newString) String StringPool::getPooledString (const String& newString) { if (newString.isEmpty()) - return String(); + return {}; const ScopedLock sl (lock); garbageCollectIfNeeded(); diff --git a/source/modules/juce_core/text/juce_StringPool.h b/source/modules/juce_core/text/juce_StringPool.h index 25d5baa7a..26240ca03 100644 --- a/source/modules/juce_core/text/juce_StringPool.h +++ b/source/modules/juce_core/text/juce_StringPool.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STRINGPOOL_H_INCLUDED -#define JUCE_STRINGPOOL_H_INCLUDED +#pragma once //============================================================================== @@ -93,6 +84,3 @@ private: JUCE_DECLARE_NON_COPYABLE (StringPool) }; - - -#endif // JUCE_STRINGPOOL_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_StringRef.h b/source/modules/juce_core/text/juce_StringRef.h index f34268c83..77919b63b 100644 --- a/source/modules/juce_core/text/juce_StringRef.h +++ b/source/modules/juce_core/text/juce_StringRef.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STRINGREF_H_INCLUDED -#define JUCE_STRINGREF_H_INCLUDED +#pragma once //============================================================================== /** @@ -137,6 +128,3 @@ inline String operator+ (String s1, StringRef s2) { return s1 += Strin inline String operator+ (StringRef s1, const String& s2) { return String (s1.text) + s2; } inline String operator+ (const char* s1, StringRef s2) { return String (s1) + String (s2.text); } inline String operator+ (StringRef s1, const char* s2) { return String (s1.text) + String (s2); } - - -#endif // JUCE_STRINGREF_H_INCLUDED diff --git a/source/modules/juce_core/text/juce_TextDiff.cpp b/source/modules/juce_core/text/juce_TextDiff.cpp index 4503ca2ae..35b13f7a4 100644 --- a/source/modules/juce_core/text/juce_TextDiff.cpp +++ b/source/modules/juce_core/text/juce_TextDiff.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -228,7 +220,7 @@ String TextDiff::Change::appliedTo (const String& text) const noexcept class DiffTests : public UnitTest { public: - DiffTests() : UnitTest ("TextDiff class") {} + DiffTests() : UnitTest ("TextDiff class", "Text") {} static String createString (Random& r) { diff --git a/source/modules/juce_core/text/juce_TextDiff.h b/source/modules/juce_core/text/juce_TextDiff.h index a1d6a6e2c..a0b9c29ba 100644 --- a/source/modules/juce_core/text/juce_TextDiff.h +++ b/source/modules/juce_core/text/juce_TextDiff.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TEXTDIFF_H_INCLUDED -#define JUCE_TEXTDIFF_H_INCLUDED +#pragma once /** @@ -77,6 +68,3 @@ public: */ Array changes; }; - - -#endif // JUCE_TEXTDIFF_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_ChildProcess.cpp b/source/modules/juce_core/threads/juce_ChildProcess.cpp index 03ae3c867..262882bb9 100644 --- a/source/modules/juce_core/threads/juce_ChildProcess.cpp +++ b/source/modules/juce_core/threads/juce_ChildProcess.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -94,7 +86,7 @@ uint32 ChildProcess::getPID() const noexcept class ChildProcessTests : public UnitTest { public: - ChildProcessTests() : UnitTest ("ChildProcess") {} + ChildProcessTests() : UnitTest ("ChildProcess", "Threads") {} void runTest() override { diff --git a/source/modules/juce_core/threads/juce_ChildProcess.h b/source/modules/juce_core/threads/juce_ChildProcess.h index 42d346ffb..cbc380dfe 100644 --- a/source/modules/juce_core/threads/juce_ChildProcess.h +++ b/source/modules/juce_core/threads/juce_ChildProcess.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHILDPROCESS_H_INCLUDED -#define JUCE_CHILDPROCESS_H_INCLUDED +#pragma once //============================================================================== @@ -118,6 +109,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcess) }; - - -#endif // JUCE_CHILDPROCESS_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_CriticalSection.h b/source/modules/juce_core/threads/juce_CriticalSection.h index 05dfb8f8c..60a240923 100644 --- a/source/modules/juce_core/threads/juce_CriticalSection.h +++ b/source/modules/juce_core/threads/juce_CriticalSection.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CRITICALSECTION_H_INCLUDED -#define JUCE_CRITICALSECTION_H_INCLUDED +#pragma once //============================================================================== @@ -263,6 +254,3 @@ typedef CriticalSection::ScopedUnlockType ScopedUnlock; @see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock */ typedef CriticalSection::ScopedTryLockType ScopedTryLock; - - -#endif // JUCE_CRITICALSECTION_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_DynamicLibrary.h b/source/modules/juce_core/threads/juce_DynamicLibrary.h index 59912ecd9..0d0783999 100644 --- a/source/modules/juce_core/threads/juce_DynamicLibrary.h +++ b/source/modules/juce_core/threads/juce_DynamicLibrary.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DYNAMICLIBRARY_H_INCLUDED -#define JUCE_DYNAMICLIBRARY_H_INCLUDED +#pragma once /** Handles the opening and closing of DLLs. @@ -50,6 +41,12 @@ public: */ DynamicLibrary (const String& name) : handle (nullptr) { open (name); } + /** Move constructor */ + DynamicLibrary (DynamicLibrary&& other) noexcept : handle (nullptr) + { + std::swap (handle, other.handle); + } + /** Destructor. If a library is currently open, it will be closed when this object is destroyed. */ @@ -82,6 +79,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DynamicLibrary) }; - - -#endif // JUCE_DYNAMICLIBRARY_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_HighResolutionTimer.cpp b/source/modules/juce_core/threads/juce_HighResolutionTimer.cpp index e4cb4c12b..9e7550d7f 100644 --- a/source/modules/juce_core/threads/juce_HighResolutionTimer.cpp +++ b/source/modules/juce_core/threads/juce_HighResolutionTimer.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/threads/juce_HighResolutionTimer.h b/source/modules/juce_core/threads/juce_HighResolutionTimer.h index 0e8f2ba6d..d90f59737 100644 --- a/source/modules/juce_core/threads/juce_HighResolutionTimer.h +++ b/source/modules/juce_core/threads/juce_HighResolutionTimer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_HIGHRESOLUTIONTIMER_H_INCLUDED -#define JUCE_HIGHRESOLUTIONTIMER_H_INCLUDED +#pragma once /** A high-resolution periodic timer. @@ -106,6 +97,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HighResolutionTimer) }; - - -#endif // JUCE_HIGHRESOLUTIONTIMER_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_InterProcessLock.h b/source/modules/juce_core/threads/juce_InterProcessLock.h index 10957cb0a..effcf26e9 100644 --- a/source/modules/juce_core/threads/juce_InterProcessLock.h +++ b/source/modules/juce_core/threads/juce_InterProcessLock.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_INTERPROCESSLOCK_H_INCLUDED -#define JUCE_INTERPROCESSLOCK_H_INCLUDED +#pragma once //============================================================================== @@ -125,6 +116,3 @@ private: JUCE_DECLARE_NON_COPYABLE (InterProcessLock) }; - - -#endif // JUCE_INTERPROCESSLOCK_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_Process.h b/source/modules/juce_core/threads/juce_Process.h index b55d38488..656f88acb 100644 --- a/source/modules/juce_core/threads/juce_Process.h +++ b/source/modules/juce_core/threads/juce_Process.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PROCESS_H_INCLUDED -#define JUCE_PROCESS_H_INCLUDED +#pragma once //============================================================================== @@ -159,6 +150,3 @@ private: Process(); JUCE_DECLARE_NON_COPYABLE (Process) }; - - -#endif // JUCE_PROCESS_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_ReadWriteLock.cpp b/source/modules/juce_core/threads/juce_ReadWriteLock.cpp index 5fa58c9a2..7a7efe439 100644 --- a/source/modules/juce_core/threads/juce_ReadWriteLock.cpp +++ b/source/modules/juce_core/threads/juce_ReadWriteLock.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/threads/juce_ReadWriteLock.h b/source/modules/juce_core/threads/juce_ReadWriteLock.h index 22263333a..cb5e4cddd 100644 --- a/source/modules/juce_core/threads/juce_ReadWriteLock.h +++ b/source/modules/juce_core/threads/juce_ReadWriteLock.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_READWRITELOCK_H_INCLUDED -#define JUCE_READWRITELOCK_H_INCLUDED +#pragma once //============================================================================== @@ -149,6 +140,3 @@ private: JUCE_DECLARE_NON_COPYABLE (ReadWriteLock) }; - - -#endif // JUCE_READWRITELOCK_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_ScopedLock.h b/source/modules/juce_core/threads/juce_ScopedLock.h index 043b91a6c..c1b5795be 100644 --- a/source/modules/juce_core/threads/juce_ScopedLock.h +++ b/source/modules/juce_core/threads/juce_ScopedLock.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SCOPEDLOCK_H_INCLUDED -#define JUCE_SCOPEDLOCK_H_INCLUDED +#pragma once //============================================================================== @@ -234,6 +225,3 @@ private: JUCE_DECLARE_NON_COPYABLE (GenericScopedTryLock) }; - - -#endif // JUCE_SCOPEDLOCK_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_ScopedReadLock.h b/source/modules/juce_core/threads/juce_ScopedReadLock.h index 391c22854..c459c29d0 100644 --- a/source/modules/juce_core/threads/juce_ScopedReadLock.h +++ b/source/modules/juce_core/threads/juce_ScopedReadLock.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SCOPEDREADLOCK_H_INCLUDED -#define JUCE_SCOPEDREADLOCK_H_INCLUDED +#pragma once //============================================================================== @@ -87,6 +78,3 @@ private: JUCE_DECLARE_NON_COPYABLE (ScopedReadLock) }; - - -#endif // JUCE_SCOPEDREADLOCK_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_ScopedWriteLock.h b/source/modules/juce_core/threads/juce_ScopedWriteLock.h index 13e490ebd..52539fb7b 100644 --- a/source/modules/juce_core/threads/juce_ScopedWriteLock.h +++ b/source/modules/juce_core/threads/juce_ScopedWriteLock.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SCOPEDWRITELOCK_H_INCLUDED -#define JUCE_SCOPEDWRITELOCK_H_INCLUDED +#pragma once //============================================================================== @@ -87,6 +78,3 @@ private: JUCE_DECLARE_NON_COPYABLE (ScopedWriteLock) }; - - -#endif // JUCE_SCOPEDWRITELOCK_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_SpinLock.h b/source/modules/juce_core/threads/juce_SpinLock.h index 35e388e80..5454006ad 100644 --- a/source/modules/juce_core/threads/juce_SpinLock.h +++ b/source/modules/juce_core/threads/juce_SpinLock.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SPINLOCK_H_INCLUDED -#define JUCE_SPINLOCK_H_INCLUDED +#pragma once //============================================================================== @@ -88,6 +79,3 @@ private: JUCE_DECLARE_NON_COPYABLE (SpinLock) }; - - -#endif // JUCE_SPINLOCK_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_Thread.cpp b/source/modules/juce_core/threads/juce_Thread.cpp index fbe6e7c13..28b7cf40b 100644 --- a/source/modules/juce_core/threads/juce_Thread.cpp +++ b/source/modules/juce_core/threads/juce_Thread.cpp @@ -2,40 +2,26 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -Thread::Thread (const String& threadName_, const size_t stackSize) - : threadName (threadName_), - threadHandle (nullptr), - threadId (0), - threadPriority (5), - threadStackSize (stackSize), - affinityMask (0), - shouldExit (false) +Thread::Thread (const String& name, const size_t stackSize) + : threadName (name), threadStackSize (stackSize) { } @@ -134,12 +120,21 @@ void Thread::startThread() } } -void Thread::startThread (const int priority) +void Thread::startThread (int priority) { const ScopedLock sl (startStopLock); if (threadHandle == nullptr) { + auto isRealtime = (priority == realtimeAudioPriority); + + #if JUCE_ANDROID + isAndroidRealtimeThread = isRealtime; + #endif + + if (isRealtime) + priority = 9; + threadPriority = priority; startThread(); } @@ -226,8 +221,13 @@ bool Thread::stopThread (const int timeOutMilliseconds) } //============================================================================== -bool Thread::setPriority (const int newPriority) +bool Thread::setPriority (int newPriority) { + bool isRealtime = (newPriority == realtimeAudioPriority); + + if (isRealtime) + newPriority = 9; + // NB: deadlock possible if you try to set the thread prio from the thread itself, // so using setCurrentThreadPriority instead in that case. if (getCurrentThreadId() == getThreadId()) @@ -235,6 +235,14 @@ bool Thread::setPriority (const int newPriority) const ScopedLock sl (startStopLock); + #if JUCE_ANDROID + // you cannot switch from or to an Android realtime thread once the + // thread is already running! + jassert (isThreadRunning() && (isRealtime == isAndroidRealtimeThread)); + + isAndroidRealtimeThread = isRealtime; + #endif + if ((! isThreadRunning()) || setThreadPriority (threadHandle, newPriority)) { threadPriority = newPriority; @@ -285,13 +293,13 @@ bool JUCE_CALLTYPE Process::isRunningUnderDebugger() noexcept return juce_isRunningUnderDebugger(); } -//============================================================================== #if JUCE_UNIT_TESTS +//============================================================================== class AtomicTests : public UnitTest { public: - AtomicTests() : UnitTest ("Atomics") {} + AtomicTests() : UnitTest ("Atomics", "Threads") {} void runTest() override { @@ -316,8 +324,6 @@ public: AtomicTester ::testInteger (*this); beginTest ("Atomic long"); AtomicTester ::testInteger (*this); - beginTest ("Atomic void*"); - AtomicTester ::testInteger (*this); beginTest ("Atomic int*"); AtomicTester ::testInteger (*this); beginTest ("Atomic float"); @@ -330,6 +336,21 @@ public: beginTest ("Atomic double"); AtomicTester ::testFloat (*this); #endif + beginTest ("Atomic pointer increment/decrement"); + Atomic a (a2); int* b (a2); + expect (++a == ++b); + + { + beginTest ("Atomic void*"); + Atomic atomic; + void* c; + + atomic.set ((void*) 10); + c = (void*) 10; + + expect (atomic.value == c); + expect (atomic.get() == c); + } } template @@ -341,36 +362,44 @@ public: static void testInteger (UnitTest& test) { Atomic a, b; + Type c; + a.set ((Type) 10); - test.expect (a.value == (Type) 10); - test.expect (a.get() == (Type) 10); - a += (Type) 15; - test.expect (a.get() == (Type) 25); + c = (Type) 10; + + test.expect (a.value == c); + test.expect (a.get() == c); + + a += 15; + c += 15; + test.expect (a.get() == c); a.memoryBarrier(); - a -= (Type) 5; - test.expect (a.get() == (Type) 20); - test.expect (++a == (Type) 21); + + a -= 5; + c -= 5; + test.expect (a.get() == c); + + test.expect (++a == ++c); ++a; - test.expect (--a == (Type) 21); - test.expect (a.get() == (Type) 21); + ++c; + test.expect (--a == --c); + test.expect (a.get() == c); a.memoryBarrier(); testFloat (test); } + + static void testFloat (UnitTest& test) { Atomic a, b; - a = (Type) 21; + a = (Type) 101; a.memoryBarrier(); /* These are some simple test cases to check the atomics - let me know if any of these assertions fail on your system! */ - test.expect (a.get() == (Type) 21); - test.expect (a.compareAndSetValue ((Type) 100, (Type) 50) == (Type) 21); - test.expect (a.get() == (Type) 21); - test.expect (a.compareAndSetValue ((Type) 101, a.get()) == (Type) 21); test.expect (a.get() == (Type) 101); test.expect (! a.compareAndSetBool ((Type) 300, (Type) 200)); test.expect (a.get() == (Type) 101); @@ -388,4 +417,60 @@ public: static AtomicTests atomicUnitTests; +//============================================================================== +class ThreadLocalValueUnitTest : public UnitTest, private Thread +{ +public: + ThreadLocalValueUnitTest() + : UnitTest ("ThreadLocalValue", "Threads"), + Thread ("ThreadLocalValue Thread") + {} + + void runTest() override + { + beginTest ("values are thread local"); + + { + ThreadLocalValue threadLocal; + + sharedThreadLocal = &threadLocal; + + sharedThreadLocal.get()->get() = 1; + + startThread(); + signalThreadShouldExit(); + waitForThreadToExit (-1); + + mainThreadResult = sharedThreadLocal.get()->get(); + + expectEquals (mainThreadResult.get(), 1); + expectEquals (auxThreadResult.get(), 2); + } + + beginTest ("values are per-instance"); + + { + ThreadLocalValue a, b; + + a.get() = 1; + b.get() = 2; + + expectEquals (a.get(), 1); + expectEquals (b.get(), 2); + } + } + +private: + Atomic mainThreadResult, auxThreadResult; + Atomic*> sharedThreadLocal; + + void run() override + { + sharedThreadLocal.get()->get() = 2; + auxThreadResult = sharedThreadLocal.get()->get(); + } +}; + +ThreadLocalValueUnitTest threadLocalValueUnitTest; + #endif diff --git a/source/modules/juce_core/threads/juce_Thread.h b/source/modules/juce_core/threads/juce_Thread.h index 76f8e374a..e3f177c58 100644 --- a/source/modules/juce_core/threads/juce_Thread.h +++ b/source/modules/juce_core/threads/juce_Thread.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_THREAD_H_INCLUDED -#define JUCE_THREAD_H_INCLUDED +#pragma once //============================================================================== @@ -101,7 +92,7 @@ public: Launches the thread with a given priority, where 0 = lowest, 10 = highest. If the thread is already running, its priority will be changed. - @see startThread, setPriority + @see startThread, setPriority, realtimeAudioPriority */ void startThread (int priority); @@ -173,11 +164,38 @@ public: bool waitForThreadToExit (int timeOutMilliseconds) const; //============================================================================== + /** Special realtime audio thread priority + + This priority will create a high-priority thread which is best suited + for realtime audio processing. + + Currently, this priority is identical to priority 9, except when building + for Android with OpenSL support. + + In this case, JUCE will ask OpenSL to consturct a super high priority thread + specifically for realtime audio processing. + + Note that this priority can only be set **before** the thread has + started. Switching to this priority, or from this priority to a different + priority, is not supported under Android and will assert. + + For best performance this thread should yield at regular intervals + and not call any blocking APIS. + + @see startThread, setPriority, sleep, WaitableEvent + */ + enum + { + realtimeAudioPriority = -1 + }; + /** Changes the thread's priority. May return false if for some reason the priority can't be changed. @param priority the new priority, in the range 0 (lowest) to 10 (highest). A priority of 5 is normal. + + @see realtimeAudioPriority */ bool setPriority (int priority); @@ -281,14 +299,18 @@ public: private: //============================================================================== const String threadName; - void* volatile threadHandle; - ThreadID threadId; + void* volatile threadHandle = nullptr; + ThreadID threadId = {}; CriticalSection startStopLock; WaitableEvent startSuspensionEvent, defaultEvent; - int threadPriority; + int threadPriority = 5; size_t threadStackSize; - uint32 affinityMask; - bool volatile shouldExit; + uint32 affinityMask = 0; + bool volatile shouldExit = false; + + #if JUCE_ANDROID + bool isAndroidRealtimeThread = false; + #endif #ifndef DOXYGEN friend void JUCE_API juce_threadEntryPoint (void*); @@ -302,5 +324,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Thread) }; - -#endif // JUCE_THREAD_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_ThreadLocalValue.h b/source/modules/juce_core/threads/juce_ThreadLocalValue.h index af7f21edc..2b6d4fe02 100644 --- a/source/modules/juce_core/threads/juce_ThreadLocalValue.h +++ b/source/modules/juce_core/threads/juce_ThreadLocalValue.h @@ -2,41 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_THREADLOCALVALUE_H_INCLUDED -#define JUCE_THREADLOCALVALUE_H_INCLUDED - -// (NB: on win32, native thread-locals aren't possible in a dynamically loaded DLL in XP). -#if ! ((JUCE_MSVC && (JUCE_64BIT || ! defined (JucePlugin_PluginCode))) \ - || (JUCE_MAC && JUCE_CLANG && defined (MAC_OS_X_VERSION_10_7) \ - && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7)) - #define JUCE_NO_COMPILER_THREAD_LOCAL 1 -#endif +#pragma once //============================================================================== /** @@ -70,14 +54,12 @@ public: */ ~ThreadLocalValue() { - #if JUCE_NO_COMPILER_THREAD_LOCAL - for (ObjectHolder* o = first.value; o != nullptr;) + for (auto* o = first.get(); o != nullptr;) { - ObjectHolder* const next = o->next; + auto* next = o->next; delete o; o = next; } - #endif } /** Returns a reference to this thread's instance of the value. @@ -111,47 +93,25 @@ public: */ Type& get() const noexcept { - #if JUCE_NO_COMPILER_THREAD_LOCAL - const Thread::ThreadID threadId = Thread::getCurrentThreadId(); + auto threadId = Thread::getCurrentThreadId(); + ObjectHolder* o = nullptr; - for (ObjectHolder* o = first.get(); o != nullptr; o = o->next) - if (o->threadId == threadId) + for (o = first.get(); o != nullptr; o = o->next) + if (o->threadId.get() == threadId) return o->object; - for (ObjectHolder* o = first.get(); o != nullptr; o = o->next) - { - if (o->threadId == nullptr) - { - { - SpinLock::ScopedLockType sl (lock); - - if (o->threadId != nullptr) - continue; - - o->threadId = threadId; - } + for (o = first.get(); o != nullptr; o = o->next) + if (o->threadId.compareAndSetBool (threadId, nullptr)) + break; - o->object = Type(); - return o->object; - } - } + if (o != nullptr) + o->object = Type(); + else + for (o = new ObjectHolder (threadId, first.get()); + ! first.compareAndSetBool (o, o->next); + o->next = first.get()); - ObjectHolder* const newObject = new ObjectHolder (threadId); - - do - { - newObject->next = first.get(); - } - while (! first.compareAndSetBool (newObject, newObject->next)); - - return newObject->object; - #elif JUCE_MAC - static __thread Type object; - return object; - #elif JUCE_MSVC - static __declspec(thread) Type object; - return object; - #endif + return o->object; } /** Called by a thread before it terminates, to allow this class to release @@ -159,30 +119,20 @@ public: */ void releaseCurrentThreadStorage() { - #if JUCE_NO_COMPILER_THREAD_LOCAL - const Thread::ThreadID threadId = Thread::getCurrentThreadId(); + auto threadId = Thread::getCurrentThreadId(); - for (ObjectHolder* o = first.get(); o != nullptr; o = o->next) - { - if (o->threadId == threadId) - { - SpinLock::ScopedLockType sl (lock); - o->threadId = nullptr; - } - } - #endif + for (auto* o = first.get(); o != nullptr; o = o->next) + if (o->threadId.compareAndSetBool (nullptr, threadId)) + return; } private: //============================================================================== - #if JUCE_NO_COMPILER_THREAD_LOCAL struct ObjectHolder { - ObjectHolder (const Thread::ThreadID& tid) - : threadId (tid), next (nullptr), object() - {} + ObjectHolder (Thread::ThreadID idToUse, ObjectHolder* n) : threadId (idToUse), next (n), object() {} - Thread::ThreadID threadId; + Atomic threadId; ObjectHolder* next; Type object; @@ -190,11 +140,6 @@ private: }; mutable Atomic first; - SpinLock lock; - #endif JUCE_DECLARE_NON_COPYABLE (ThreadLocalValue) }; - - -#endif // JUCE_THREADLOCALVALUE_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_ThreadPool.cpp b/source/modules/juce_core/threads/juce_ThreadPool.cpp index fa3f9fc22..b9b0fb995 100644 --- a/source/modules/juce_core/threads/juce_ThreadPool.cpp +++ b/source/modules/juce_core/threads/juce_ThreadPool.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/threads/juce_ThreadPool.h b/source/modules/juce_core/threads/juce_ThreadPool.h index 1a0a5fc4e..5c92dd976 100644 --- a/source/modules/juce_core/threads/juce_ThreadPool.h +++ b/source/modules/juce_core/threads/juce_ThreadPool.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_THREADPOOL_H_INCLUDED -#define JUCE_THREADPOOL_H_INCLUDED +#pragma once class ThreadPool; class ThreadPoolThread; @@ -324,6 +315,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadPool) }; - - -#endif // JUCE_THREADPOOL_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_TimeSliceThread.cpp b/source/modules/juce_core/threads/juce_TimeSliceThread.cpp index 7dea438a3..94ecca528 100644 --- a/source/modules/juce_core/threads/juce_TimeSliceThread.cpp +++ b/source/modules/juce_core/threads/juce_TimeSliceThread.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -72,6 +64,17 @@ void TimeSliceThread::removeTimeSliceClient (TimeSliceClient* const client) } } +void TimeSliceThread::removeAllClients() +{ + for (;;) + { + if (auto* c = getClient (0)) + removeTimeSliceClient (c); + else + break; + } +} + void TimeSliceThread::moveToFrontOfQueue (TimeSliceClient* client) { const ScopedLock sl (listLock); @@ -91,7 +94,7 @@ int TimeSliceThread::getNumClients() const TimeSliceClient* TimeSliceThread::getClient (const int i) const { const ScopedLock sl (listLock); - return clients [i]; + return clients[i]; } //============================================================================== @@ -102,7 +105,7 @@ TimeSliceClient* TimeSliceThread::getNextClient (int index) const for (int i = clients.size(); --i >= 0;) { - TimeSliceClient* const c = clients.getUnchecked ((i + index) % clients.size()); + auto* c = clients.getUnchecked ((i + index) % clients.size()); if (client == nullptr || c->nextCallTime < soonest) { @@ -132,13 +135,13 @@ void TimeSliceThread::run() numClients = clients.size(); index = numClients > 0 ? ((index + 1) % numClients) : 0; - if (TimeSliceClient* const firstClient = getNextClient (index)) + if (auto* firstClient = getNextClient (index)) nextClientTime = firstClient->nextCallTime; } if (numClients > 0) { - const Time now (Time::getCurrentTime()); + auto now = Time::getCurrentTime(); if (nextClientTime > now) { diff --git a/source/modules/juce_core/threads/juce_TimeSliceThread.h b/source/modules/juce_core/threads/juce_TimeSliceThread.h index d5bb31a90..7a3ad7791 100644 --- a/source/modules/juce_core/threads/juce_TimeSliceThread.h +++ b/source/modules/juce_core/threads/juce_TimeSliceThread.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TIMESLICETHREAD_H_INCLUDED -#define JUCE_TIMESLICETHREAD_H_INCLUDED +#pragma once class TimeSliceThread; @@ -106,24 +97,28 @@ public: //============================================================================== /** Adds a client to the list. - The client's callbacks will start after the number of milliseconds specified by millisecondsBeforeStarting (and this may happen before this method has returned). */ - void addTimeSliceClient (TimeSliceClient* client, int millisecondsBeforeStarting = 0); + void addTimeSliceClient (TimeSliceClient* clientToAdd, int millisecondsBeforeStarting = 0); - /** Removes a client from the list. + /** If the given client is waiting in the queue, it will be moved to the front + and given a time-slice as soon as possible. + If the specified client has not been added, nothing will happen. + */ + void moveToFrontOfQueue (TimeSliceClient* clientToMove); + /** Removes a client from the list. This method will make sure that all callbacks to the client have completely finished before the method returns. */ - void removeTimeSliceClient (TimeSliceClient* client); + void removeTimeSliceClient (TimeSliceClient* clientToRemove); - /** If the given client is waiting in the queue, it will be moved to the front - and given a time-slice as soon as possible. - If the specified client has not been added, nothing will happen. + /** Removes all the active and pending clients from the list. + This method will make sure that all callbacks to clients have finished before the + method returns. */ - void moveToFrontOfQueue (TimeSliceClient* client); + void removeAllClients(); /** Returns the number of registered clients. */ int getNumClients() const; @@ -146,6 +141,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimeSliceThread) }; - - -#endif // JUCE_TIMESLICETHREAD_H_INCLUDED diff --git a/source/modules/juce_core/threads/juce_WaitableEvent.h b/source/modules/juce_core/threads/juce_WaitableEvent.h index 6c9b9ed49..55900a268 100644 --- a/source/modules/juce_core/threads/juce_WaitableEvent.h +++ b/source/modules/juce_core/threads/juce_WaitableEvent.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_WAITABLEEVENT_H_INCLUDED -#define JUCE_WAITABLEEVENT_H_INCLUDED +#pragma once //============================================================================== @@ -115,6 +106,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WaitableEvent) }; - - -#endif // JUCE_WAITABLEEVENT_H_INCLUDED diff --git a/source/modules/juce_core/time/juce_PerformanceCounter.cpp b/source/modules/juce_core/time/juce_PerformanceCounter.cpp index 4a37596a5..6c3c3bbdd 100644 --- a/source/modules/juce_core/time/juce_PerformanceCounter.cpp +++ b/source/modules/juce_core/time/juce_PerformanceCounter.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/time/juce_PerformanceCounter.h b/source/modules/juce_core/time/juce_PerformanceCounter.h index 5463a00a8..ed908e5e3 100644 --- a/source/modules/juce_core/time/juce_PerformanceCounter.h +++ b/source/modules/juce_core/time/juce_PerformanceCounter.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PERFORMANCECOUNTER_H_INCLUDED -#define JUCE_PERFORMANCECOUNTER_H_INCLUDED +#pragma once //============================================================================== @@ -126,4 +117,41 @@ private: }; -#endif // JUCE_PERFORMANCECOUNTER_H_INCLUDED +//============================================================================== +/** + Simple RAII class for measuring the time spent in a scope. + + Example: + + { + double timeSec; + + { + ScopedTimeMeasurement m (timeSec); + doSomething(); + } + + Logger::writeToLog (String ("doSomething() took ") + String (timeSec) + "seconds"); + } + + @param resultInSeconds The result of the measurement will be stored in this variable. +*/ +class JUCE_API ScopedTimeMeasurement +{ +public: + ScopedTimeMeasurement (double& resultInSeconds) + : result (resultInSeconds) + { + result = 0.0; + } + + ~ScopedTimeMeasurement() + { + static auto scaler = 1.0 / static_cast (Time::getHighResolutionTicksPerSecond()); + result = static_cast (Time::getHighResolutionTicks() - startTimeTicks) * scaler; + } + +private: + int64 startTimeTicks = Time::getHighResolutionTicks(); + double& result; +}; diff --git a/source/modules/juce_core/time/juce_RelativeTime.cpp b/source/modules/juce_core/time/juce_RelativeTime.cpp index 336e98d6d..013a1fc26 100644 --- a/source/modules/juce_core/time/juce_RelativeTime.cpp +++ b/source/modules/juce_core/time/juce_RelativeTime.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -56,15 +48,15 @@ RelativeTime RelativeTime::operator-= (RelativeTime t) noexcept { numSeconds RelativeTime RelativeTime::operator+= (const double secs) noexcept { numSeconds += secs; return *this; } RelativeTime RelativeTime::operator-= (const double secs) noexcept { numSeconds -= secs; return *this; } -RelativeTime operator+ (RelativeTime t1, RelativeTime t2) noexcept { return t1 += t2; } -RelativeTime operator- (RelativeTime t1, RelativeTime t2) noexcept { return t1 -= t2; } +JUCE_API RelativeTime JUCE_CALLTYPE operator+ (RelativeTime t1, RelativeTime t2) noexcept { return t1 += t2; } +JUCE_API RelativeTime JUCE_CALLTYPE operator- (RelativeTime t1, RelativeTime t2) noexcept { return t1 -= t2; } -bool operator== (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() == t2.inSeconds(); } -bool operator!= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() != t2.inSeconds(); } -bool operator> (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() > t2.inSeconds(); } -bool operator< (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() < t2.inSeconds(); } -bool operator>= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() >= t2.inSeconds(); } -bool operator<= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() <= t2.inSeconds(); } +JUCE_API bool JUCE_CALLTYPE operator== (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() == t2.inSeconds(); } +JUCE_API bool JUCE_CALLTYPE operator!= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() != t2.inSeconds(); } +JUCE_API bool JUCE_CALLTYPE operator> (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() > t2.inSeconds(); } +JUCE_API bool JUCE_CALLTYPE operator< (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() < t2.inSeconds(); } +JUCE_API bool JUCE_CALLTYPE operator>= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() >= t2.inSeconds(); } +JUCE_API bool JUCE_CALLTYPE operator<= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() <= t2.inSeconds(); } //============================================================================== static void translateTimeField (String& result, int n, const char* singular, const char* plural) diff --git a/source/modules/juce_core/time/juce_RelativeTime.h b/source/modules/juce_core/time/juce_RelativeTime.h index ba942cbcc..9700d9aa2 100644 --- a/source/modules/juce_core/time/juce_RelativeTime.h +++ b/source/modules/juce_core/time/juce_RelativeTime.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RELATIVETIME_H_INCLUDED -#define JUCE_RELATIVETIME_H_INCLUDED +#pragma once //============================================================================== @@ -163,24 +154,20 @@ private: //============================================================================== /** Compares two RelativeTimes. */ -bool operator== (RelativeTime t1, RelativeTime t2) noexcept; +JUCE_API bool JUCE_CALLTYPE operator== (RelativeTime t1, RelativeTime t2) noexcept; /** Compares two RelativeTimes. */ -bool operator!= (RelativeTime t1, RelativeTime t2) noexcept; +JUCE_API bool JUCE_CALLTYPE operator!= (RelativeTime t1, RelativeTime t2) noexcept; /** Compares two RelativeTimes. */ -bool operator> (RelativeTime t1, RelativeTime t2) noexcept; +JUCE_API bool JUCE_CALLTYPE operator> (RelativeTime t1, RelativeTime t2) noexcept; /** Compares two RelativeTimes. */ -bool operator< (RelativeTime t1, RelativeTime t2) noexcept; +JUCE_API bool JUCE_CALLTYPE operator< (RelativeTime t1, RelativeTime t2) noexcept; /** Compares two RelativeTimes. */ -bool operator>= (RelativeTime t1, RelativeTime t2) noexcept; +JUCE_API bool JUCE_CALLTYPE operator>= (RelativeTime t1, RelativeTime t2) noexcept; /** Compares two RelativeTimes. */ -bool operator<= (RelativeTime t1, RelativeTime t2) noexcept; +JUCE_API bool JUCE_CALLTYPE operator<= (RelativeTime t1, RelativeTime t2) noexcept; //============================================================================== /** Adds two RelativeTimes together. */ -RelativeTime operator+ (RelativeTime t1, RelativeTime t2) noexcept; +JUCE_API RelativeTime JUCE_CALLTYPE operator+ (RelativeTime t1, RelativeTime t2) noexcept; /** Subtracts two RelativeTimes. */ -RelativeTime operator- (RelativeTime t1, RelativeTime t2) noexcept; - - - -#endif // JUCE_RELATIVETIME_H_INCLUDED +JUCE_API RelativeTime JUCE_CALLTYPE operator- (RelativeTime t1, RelativeTime t2) noexcept; diff --git a/source/modules/juce_core/time/juce_Time.cpp b/source/modules/juce_core/time/juce_Time.cpp index 71e6eaa3a..2e78b58ed 100644 --- a/source/modules/juce_core/time/juce_Time.cpp +++ b/source/modules/juce_core/time/juce_Time.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -108,7 +100,7 @@ namespace TimeHelpers #ifdef JUCE_MSVC if (tm->tm_year < -1900 || tm->tm_year > 8099) - return String(); // Visual Studio's library can only handle 0 -> 9999 AD + return {}; // Visual Studio's library can only handle 0 -> 9999 AD #endif for (size_t bufferSize = 256; ; bufferSize += 256) @@ -491,15 +483,15 @@ Time Time::fromISO8601 (StringRef iso) noexcept const int year = parseFixedSizeIntAndSkip (t, 4, '-'); if (year < 0) - return Time(); + return {}; const int month = parseFixedSizeIntAndSkip (t, 2, '-'); if (month < 0) - return Time(); + return {}; const int day = parseFixedSizeIntAndSkip (t, 2, 0); if (day < 0) - return Time(); + return {}; int hours = 0, minutes = 0, milliseconds = 0; @@ -508,13 +500,25 @@ Time Time::fromISO8601 (StringRef iso) noexcept ++t; hours = parseFixedSizeIntAndSkip (t, 2, ':'); if (hours < 0) - return Time(); + return {}; minutes = parseFixedSizeIntAndSkip (t, 2, ':'); if (minutes < 0) - return Time(); + return {}; + + auto seconds = parseFixedSizeIntAndSkip (t, 2, 0); + if (seconds < 0) + return {}; + + if (*t == '.') + { + ++t; + milliseconds = parseFixedSizeIntAndSkip (t, 3, 0); + if (milliseconds < 0) + return {}; + } - milliseconds = (int) (1000.0 * CharacterFunctions::readDoubleValue (t)); + milliseconds += 1000 * seconds; } const juce_wchar nextChar = t.getAndAdvance(); @@ -523,18 +527,18 @@ Time Time::fromISO8601 (StringRef iso) noexcept { const int offsetHours = parseFixedSizeIntAndSkip (t, 2, ':'); if (offsetHours < 0) - return Time(); + return {}; const int offsetMinutes = parseFixedSizeIntAndSkip (t, 2, 0); if (offsetMinutes < 0) - return Time(); + return {}; const int offsetMs = (offsetHours * 60 + offsetMinutes) * 60 * 1000; milliseconds += nextChar == '-' ? offsetMs : -offsetMs; // NB: this seems backwards but is correct! } else if (nextChar != 0 && nextChar != 'Z') { - return Time(); + return {}; } return Time (year, month - 1, day, hours, minutes, 0, milliseconds, false); @@ -624,7 +628,7 @@ Time Time::getCompilationDate() class TimeTests : public UnitTest { public: - TimeTests() : UnitTest ("Time") {} + TimeTests() : UnitTest ("Time", "Time") {} void runTest() override { diff --git a/source/modules/juce_core/time/juce_Time.h b/source/modules/juce_core/time/juce_Time.h index c1345cb5c..c38321b5a 100644 --- a/source/modules/juce_core/time/juce_Time.h +++ b/source/modules/juce_core/time/juce_Time.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TIME_H_INCLUDED -#define JUCE_TIME_H_INCLUDED +#pragma once //============================================================================== @@ -309,7 +300,7 @@ public: /** Returns the number of millisecs since a fixed event (usually system startup). - This returns a monotonically increasing value which it unaffected by changes to the + This returns a monotonically increasing value which is unaffected by changes to the system clock. It should be accurate to within a few millisecs, depending on platform, hardware, etc. @@ -412,6 +403,3 @@ JUCE_API bool operator<= (Time time1, Time time2) noexcept; JUCE_API bool operator> (Time time1, Time time2) noexcept; /** Compares two Time objects. */ JUCE_API bool operator>= (Time time1, Time time2) noexcept; - - -#endif // JUCE_TIME_H_INCLUDED diff --git a/source/modules/juce_core/unit_tests/juce_UnitTest.cpp b/source/modules/juce_core/unit_tests/juce_UnitTest.cpp index f48daf751..2ed41b981 100644 --- a/source/modules/juce_core/unit_tests/juce_UnitTest.cpp +++ b/source/modules/juce_core/unit_tests/juce_UnitTest.cpp @@ -2,34 +2,26 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -UnitTest::UnitTest (const String& nm) - : name (nm), runner (nullptr) +UnitTest::UnitTest (const String& nm, const String& ctg) + : name (nm), category (ctg), runner (nullptr) { getAllTests().add (this); } @@ -45,6 +37,31 @@ Array& UnitTest::getAllTests() return tests; } +Array UnitTest::getTestsInCategory (const String& category) +{ + if (category.isEmpty()) + return getAllTests(); + + Array unitTests; + + for (auto* test : getAllTests()) + if (test->getCategory() == category) + unitTests.add (test); + + return unitTests; +} + +StringArray UnitTest::getAllCategories() +{ + StringArray categories; + + for (auto* test : getAllTests()) + if (test->getCategory().isNotEmpty()) + categories.addIfNotAlreadyThere (test->getCategory()); + + return categories; +} + void UnitTest::initialise() {} void UnitTest::shutdown() {} @@ -167,6 +184,11 @@ void UnitTestRunner::runAllTests (int64 randomSeed) runTests (UnitTest::getAllTests(), randomSeed); } +void UnitTestRunner::runTestsInCategory (const String& category, int64 randomSeed) +{ + runTests (UnitTest::getTestsInCategory (category), randomSeed); +} + void UnitTestRunner::logMessage (const String& message) { Logger::writeToLog (message); diff --git a/source/modules/juce_core/unit_tests/juce_UnitTest.h b/source/modules/juce_core/unit_tests/juce_UnitTest.h index 9029e94d7..68c445981 100644 --- a/source/modules/juce_core/unit_tests/juce_UnitTest.h +++ b/source/modules/juce_core/unit_tests/juce_UnitTest.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_UNITTEST_H_INCLUDED -#define JUCE_UNITTEST_H_INCLUDED +#pragma once class UnitTestRunner; @@ -76,8 +67,8 @@ class JUCE_API UnitTest { public: //============================================================================== - /** Creates a test with the given name. */ - explicit UnitTest (const String& name); + /** Creates a test with the given name and optionally places it in a category. */ + explicit UnitTest (const String& name, const String& category = String()); /** Destructor. */ virtual ~UnitTest(); @@ -85,6 +76,9 @@ public: /** Returns the name of the test. */ const String& getName() const noexcept { return name; } + /** Returns the category of the test. */ + const String& getCategory() const noexcept { return category; } + /** Runs the test, using the specified UnitTestRunner. You shouldn't need to call this method directly - use UnitTestRunner::runTests() instead. @@ -94,6 +88,12 @@ public: /** Returns the set of all UnitTest objects that currently exist. */ static Array& getAllTests(); + /** Returns the set of UnitTests in a specified category. */ + static Array getTestsInCategory (const String& category); + + /** Returns a StringArray containing all of the categories of UnitTests that have been registered. */ + static StringArray getAllCategories(); + //============================================================================== /** You can optionally implement this method to set up your test. This method will be called before runTest(). @@ -298,6 +298,7 @@ private: //============================================================================== const String name; + const String category; UnitTestRunner* runner; JUCE_DECLARE_NON_COPYABLE (UnitTest) @@ -344,6 +345,14 @@ public: */ void runAllTests (int64 randomSeed = 0); + /** Runs all the UnitTest objects within a specified category. + This calls runTests() for all the objects listed in UnitTest::getTestsInCategory(). + + If you want to run the tests with a predetermined seed, you can pass that into + the randomSeed argument, or pass 0 to have a randomly-generated seed chosen. + */ + void runTestsInCategory (const String& category, int64 randomSeed = 0); + /** Sets a flag to indicate whether an assertion should be triggered if a test fails. This is true by default. */ @@ -422,6 +431,3 @@ private: JUCE_DECLARE_NON_COPYABLE (UnitTestRunner) }; - - -#endif // JUCE_UNITTEST_H_INCLUDED diff --git a/source/modules/juce_core/xml/juce_XmlDocument.cpp b/source/modules/juce_core/xml/juce_XmlDocument.cpp index 09ddb1033..e522a45a8 100644 --- a/source/modules/juce_core/xml/juce_XmlDocument.cpp +++ b/source/modules/juce_core/xml/juce_XmlDocument.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -174,7 +166,7 @@ String XmlDocument::getFileContents (const String& filename) const return in->readEntireStreamAsString(); } - return String(); + return {}; } juce_wchar XmlDocument::readNextChar() noexcept diff --git a/source/modules/juce_core/xml/juce_XmlDocument.h b/source/modules/juce_core/xml/juce_XmlDocument.h index fad2a38d9..6d0bd6217 100644 --- a/source/modules/juce_core/xml/juce_XmlDocument.h +++ b/source/modules/juce_core/xml/juce_XmlDocument.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_XMLDOCUMENT_H_INCLUDED -#define JUCE_XMLDOCUMENT_H_INCLUDED +#pragma once //============================================================================== @@ -178,6 +169,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XmlDocument) }; - - -#endif // JUCE_XMLDOCUMENT_H_INCLUDED diff --git a/source/modules/juce_core/xml/juce_XmlElement.cpp b/source/modules/juce_core/xml/juce_XmlElement.cpp index 7cdcb7b52..04e81b6da 100644 --- a/source/modules/juce_core/xml/juce_XmlElement.cpp +++ b/source/modules/juce_core/xml/juce_XmlElement.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -134,7 +126,6 @@ XmlElement& XmlElement::operator= (const XmlElement& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS XmlElement::XmlElement (XmlElement&& other) noexcept : nextListItem (static_cast&&> (other.nextListItem)), firstChildElement (static_cast&&> (other.firstChildElement)), @@ -157,7 +148,6 @@ XmlElement& XmlElement::operator= (XmlElement&& other) noexcept return *this; } -#endif void XmlElement::copyChildrenAndAttributesFrom (const XmlElement& other) { diff --git a/source/modules/juce_core/xml/juce_XmlElement.h b/source/modules/juce_core/xml/juce_XmlElement.h index 1d9da108f..5c1b90fe3 100644 --- a/source/modules/juce_core/xml/juce_XmlElement.h +++ b/source/modules/juce_core/xml/juce_XmlElement.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_XMLELEMENT_H_INCLUDED -#define JUCE_XMLELEMENT_H_INCLUDED +#pragma once //============================================================================== @@ -166,18 +157,19 @@ public: /** Creates a (deep) copy of another element. */ XmlElement& operator= (const XmlElement&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - XmlElement (XmlElement&&) noexcept; + /** Move assignment operator */ XmlElement& operator= (XmlElement&&) noexcept; - #endif + + /** Move constructor */ + XmlElement (XmlElement&&) noexcept; /** Deleting an XmlElement will also delete all of its child elements. */ ~XmlElement() noexcept; //============================================================================== - /** Compares two XmlElements to see if they contain the same text and attiributes. + /** Compares two XmlElements to see if they contain the same text and attributes. - The elements are only considered equivalent if they contain the same attiributes + The elements are only considered equivalent if they contain the same attributes with the same values, and have the same sub-nodes. @param other the other element to compare to @@ -654,7 +646,7 @@ public: //============================================================================== /** Returns true if this element is a section of text. - Elements can either be an XML tag element or a secton of text, so this + Elements can either be an XML tag element or a section of text, so this is used to find out what kind of element this one is. @see getAllText, addTextElement, deleteAllTextElements @@ -770,6 +762,3 @@ private: JUCE_LEAK_DETECTOR (XmlElement) }; - - -#endif // JUCE_XMLELEMENT_H_INCLUDED diff --git a/source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp b/source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp index dbf45c220..d8c46bc00 100644 --- a/source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp +++ b/source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -166,7 +158,7 @@ bool GZIPCompressorOutputStream::setPosition (int64 /*newPosition*/) class GZIPTests : public UnitTest { public: - GZIPTests() : UnitTest ("GZIP") {} + GZIPTests() : UnitTest ("GZIP", "Compression") {} void runTest() override { diff --git a/source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h b/source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h index 411ec37f5..ff14f9fcc 100644 --- a/source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h +++ b/source/modules/juce_core/zip/juce_GZIPCompressorOutputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_GZIPCOMPRESSOROUTPUTSTREAM_H_INCLUDED -#define JUCE_GZIPCOMPRESSOROUTPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -99,5 +90,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GZIPCompressorOutputStream) }; - -#endif // JUCE_GZIPCOMPRESSOROUTPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp b/source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp index 04d326602..35e7a1504 100644 --- a/source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp +++ b/source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -41,6 +33,9 @@ namespace zlibNamespace #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wshadow" #pragma clang diagnostic ignored "-Wdeprecated-register" + #if __has_warning("-Wcomma") + #pragma clang diagnostic ignored "-Wcomma" + #endif #endif #undef OS_CODE diff --git a/source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h b/source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h index fa1e5dfcf..be0e28731 100644 --- a/source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h +++ b/source/modules/juce_core/zip/juce_GZIPDecompressorInputStream.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_GZIPDECOMPRESSORINPUTSTREAM_H_INCLUDED -#define JUCE_GZIPDECOMPRESSORINPUTSTREAM_H_INCLUDED +#pragma once //============================================================================== @@ -107,5 +98,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GZIPDecompressorInputStream) }; - -#endif // JUCE_GZIPDECOMPRESSORINPUTSTREAM_H_INCLUDED diff --git a/source/modules/juce_core/zip/juce_ZipFile.cpp b/source/modules/juce_core/zip/juce_ZipFile.cpp index 9ba7634bc..77b2e8300 100644 --- a/source/modules/juce_core/zip/juce_ZipFile.cpp +++ b/source/modules/juce_core/zip/juce_ZipFile.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_core/zip/juce_ZipFile.h b/source/modules/juce_core/zip/juce_ZipFile.h index 441f814f8..d8d95da56 100644 --- a/source/modules/juce_core/zip/juce_ZipFile.h +++ b/source/modules/juce_core/zip/juce_ZipFile.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ZIPFILE_H_INCLUDED -#define JUCE_ZIPFILE_H_INCLUDED +#pragma once //============================================================================== @@ -263,5 +254,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ZipFile) }; - -#endif // JUCE_ZIPFILE_H_INCLUDED diff --git a/source/modules/juce_core/zip/zlib/crc32.c b/source/modules/juce_core/zip/zlib/crc32.c index 500d5364e..9314d7eb6 100644 --- a/source/modules/juce_core/zip/zlib/crc32.c +++ b/source/modules/juce_core/zip/zlib/crc32.c @@ -258,8 +258,8 @@ unsigned long ZEXPORT crc32 (unsigned long crc, const unsigned char FAR *buf, un /* ========================================================================= */ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, unsigned len) { - register u4 c; - register const u4 FAR *buf4; + u4 c; + const u4 FAR *buf4; c = (u4)crc; c = ~c; @@ -295,8 +295,8 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf /* ========================================================================= */ local unsigned long crc32_big (unsigned long crc, const unsigned char FAR *buf, unsigned len) { - register u4 c; - register const u4 FAR *buf4; + u4 c; + const u4 FAR *buf4; c = REV((u4)crc); c = ~c; diff --git a/source/modules/juce_core/zip/zlib/deflate.c b/source/modules/juce_core/zip/zlib/deflate.c index 4b8bda58a..ce87dd918 100644 --- a/source/modules/juce_core/zip/zlib/deflate.c +++ b/source/modules/juce_core/zip/zlib/deflate.c @@ -984,9 +984,9 @@ local void lm_init (deflate_state *s) local uInt longest_match(deflate_state *s, IPos cur_match) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ + Bytef *scan = s->window + s->strstart; /* current string */ + Bytef *match; /* matched string */ + int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? @@ -1001,13 +1001,13 @@ local uInt longest_match(deflate_state *s, IPos cur_match) /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); + Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + ush scan_start = *(ushf*)scan; + ush scan_end = *(ushf*)(scan+best_len-1); #else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; + Bytef *strend = s->window + s->strstart + MAX_MATCH; + Byte scan_end1 = scan[best_len-1]; + Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. @@ -1129,10 +1129,10 @@ local uInt longest_match(deflate_state *s, IPos cur_match) */ local uInt longest_match_fast (deflate_state *s, IPos cur_match) { - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; + Bytef *scan = s->window + s->strstart; /* current string */ + Bytef *match; /* matched string */ + int len; /* length of current match */ + Bytef *strend = s->window + s->strstart + MAX_MATCH; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. @@ -1215,8 +1215,8 @@ local void check_match(deflate_state *s, IPos start, IPos match, int length) */ local void fill_window (deflate_state *s) { - register unsigned n, m; - register Posf *p; + unsigned n, m; + Posf *p; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; diff --git a/source/modules/juce_core/zip/zlib/trees.c b/source/modules/juce_core/zip/zlib/trees.c index 463bfc26e..bcb2670c5 100644 --- a/source/modules/juce_core/zip/zlib/trees.c +++ b/source/modules/juce_core/zip/zlib/trees.c @@ -1122,7 +1122,7 @@ local void set_data_type (deflate_state *s) */ local unsigned bi_reverse (unsigned code_, int len) { - register unsigned res = 0; + unsigned res = 0; do { res |= code_ & 1; code_ >>= 1, res <<= 1; diff --git a/source/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp b/source/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp index 53ff45360..e120a1469 100644 --- a/source/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp +++ b/source/modules/juce_data_structures/app_properties/juce_ApplicationProperties.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h b/source/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h index fa201313d..b65e5854d 100644 --- a/source/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h +++ b/source/modules/juce_data_structures/app_properties/juce_ApplicationProperties.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_APPLICATIONPROPERTIES_H_INCLUDED -#define JUCE_APPLICATIONPROPERTIES_H_INCLUDED +#pragma once //============================================================================== @@ -127,6 +128,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationProperties) }; - - -#endif // JUCE_APPLICATIONPROPERTIES_H_INCLUDED diff --git a/source/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp b/source/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp index 10a43dbca..812b2b7a4 100644 --- a/source/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp +++ b/source/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -92,7 +94,7 @@ File PropertiesFile::Options::getDefaultFile() const : File::userApplicationDataDirectory)); if (dir == File()) - return File(); + return {}; dir = dir.getChildFile (folderName.isNotEmpty() ? folderName : applicationName); diff --git a/source/modules/juce_data_structures/app_properties/juce_PropertiesFile.h b/source/modules/juce_data_structures/app_properties/juce_PropertiesFile.h index 40ad28e7e..bc29a1365 100644 --- a/source/modules/juce_data_structures/app_properties/juce_PropertiesFile.h +++ b/source/modules/juce_data_structures/app_properties/juce_PropertiesFile.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PROPERTIESFILE_H_INCLUDED -#define JUCE_PROPERTIESFILE_H_INCLUDED +#pragma once //============================================================================== @@ -247,5 +248,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertiesFile) }; - -#endif // JUCE_PROPERTIESFILE_H_INCLUDED diff --git a/source/modules/juce_data_structures/juce_data_structures.cpp b/source/modules/juce_data_structures/juce_data_structures.cpp index 67b3640a1..7b3a3c497 100644 --- a/source/modules/juce_data_structures/juce_data_structures.cpp +++ b/source/modules/juce_data_structures/juce_data_structures.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,8 +33,6 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #include "juce_data_structures.h" namespace juce diff --git a/source/modules/juce_data_structures/juce_data_structures.h b/source/modules/juce_data_structures/juce_data_structures.h index d0fd5a8c1..0692f4682 100644 --- a/source/modules/juce_data_structures/juce_data_structures.h +++ b/source/modules/juce_data_structures/juce_data_structures.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -33,7 +35,7 @@ ID: juce_data_structures vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE data model helper classes description: Classes for undo/redo management, and smart data structures. website: http://www.juce.com/juce @@ -46,7 +48,7 @@ *******************************************************************************/ -#ifndef JUCE_DATA_STRUCTURES_H_INCLUDED +#pragma once #define JUCE_DATA_STRUCTURES_H_INCLUDED //============================================================================== @@ -65,5 +67,3 @@ namespace juce #include "app_properties/juce_ApplicationProperties.h" } - -#endif // JUCE_DATA_STRUCTURES_H_INCLUDED diff --git a/source/modules/juce_data_structures/undomanager/juce_UndoManager.cpp b/source/modules/juce_data_structures/undomanager/juce_UndoManager.cpp index 819d55a10..5c0fb525f 100644 --- a/source/modules/juce_data_structures/undomanager/juce_UndoManager.cpp +++ b/source/modules/juce_data_structures/undomanager/juce_UndoManager.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -286,31 +288,31 @@ bool UndoManager::redo() String UndoManager::getUndoDescription() const { - if (const ActionSet* const s = getCurrentSet()) + if (auto* s = getCurrentSet()) return s->name; - return String(); + return {}; } String UndoManager::getRedoDescription() const { - if (const ActionSet* const s = getNextSet()) + if (auto* s = getNextSet()) return s->name; - return String(); + return {}; } Time UndoManager::getTimeOfUndoTransaction() const { - if (const ActionSet* const s = getCurrentSet()) + if (auto* s = getCurrentSet()) return s->time; - return Time(); + return {}; } Time UndoManager::getTimeOfRedoTransaction() const { - if (const ActionSet* const s = getNextSet()) + if (auto* s = getNextSet()) return s->time; return Time::getCurrentTime(); diff --git a/source/modules/juce_data_structures/undomanager/juce_UndoManager.h b/source/modules/juce_data_structures/undomanager/juce_UndoManager.h index 4bb9cf997..1cca8518a 100644 --- a/source/modules/juce_data_structures/undomanager/juce_UndoManager.h +++ b/source/modules/juce_data_structures/undomanager/juce_UndoManager.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_UNDOMANAGER_H_INCLUDED -#define JUCE_UNDOMANAGER_H_INCLUDED +#pragma once //============================================================================== @@ -241,6 +242,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager) }; - - -#endif // JUCE_UNDOMANAGER_H_INCLUDED diff --git a/source/modules/juce_data_structures/undomanager/juce_UndoableAction.h b/source/modules/juce_data_structures/undomanager/juce_UndoableAction.h index c2bdd81e9..b5447210e 100644 --- a/source/modules/juce_data_structures/undomanager/juce_UndoableAction.h +++ b/source/modules/juce_data_structures/undomanager/juce_UndoableAction.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_UNDOABLEACTION_H_INCLUDED -#define JUCE_UNDOABLEACTION_H_INCLUDED +#pragma once //============================================================================== @@ -94,6 +95,3 @@ public: */ virtual UndoableAction* createCoalescedAction (UndoableAction* nextAction) { ignoreUnused (nextAction); return nullptr; } }; - - -#endif // JUCE_UNDOABLEACTION_H_INCLUDED diff --git a/source/modules/juce_data_structures/values/juce_CachedValue.cpp b/source/modules/juce_data_structures/values/juce_CachedValue.cpp index 5ef337349..b8ecbcc34 100644 --- a/source/modules/juce_data_structures/values/juce_CachedValue.cpp +++ b/source/modules/juce_data_structures/values/juce_CachedValue.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -27,7 +29,7 @@ class CachedValueTests : public UnitTest { public: - CachedValueTests() : UnitTest ("CachedValues") {} + CachedValueTests() : UnitTest ("CachedValues", "Values") {} void runTest() override { diff --git a/source/modules/juce_data_structures/values/juce_CachedValue.h b/source/modules/juce_data_structures/values/juce_CachedValue.h index 3e9e476a8..f2725b6a8 100644 --- a/source/modules/juce_data_structures/values/juce_CachedValue.h +++ b/source/modules/juce_data_structures/values/juce_CachedValue.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CACHEDVALUE_H_INCLUDED -#define JUCE_CACHEDVALUE_H_INCLUDED +#pragma once //============================================================================== @@ -307,5 +308,3 @@ inline void CachedValue::valueTreePropertyChanged (ValueTree& changedTree, if (changedProperty == targetProperty && targetTree == changedTree) forceUpdateOfCachedValue(); } - -#endif // JUCE_CACHEDVALUE_H_INCLUDED diff --git a/source/modules/juce_data_structures/values/juce_Value.cpp b/source/modules/juce_data_structures/values/juce_Value.cpp index 1034381fb..19e678871 100644 --- a/source/modules/juce_data_structures/values/juce_Value.cpp +++ b/source/modules/juce_data_structures/values/juce_Value.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -111,7 +113,6 @@ Value::Value (const Value& other) : value (other.value) { } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Value::Value (Value&& other) noexcept { // moving a Value with listeners will lose those listeners, which @@ -132,7 +133,6 @@ Value& Value::operator= (Value&& other) noexcept value = static_cast&&> (other.value); return *this; } -#endif Value::~Value() { diff --git a/source/modules/juce_data_structures/values/juce_Value.h b/source/modules/juce_data_structures/values/juce_Value.h index da032f267..d470a9da7 100644 --- a/source/modules/juce_data_structures/values/juce_Value.h +++ b/source/modules/juce_data_structures/values/juce_Value.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_VALUE_H_INCLUDED -#define JUCE_VALUE_H_INCLUDED +#pragma once //============================================================================== @@ -63,10 +64,8 @@ public: /** Creates a Value that is set to the specified value. */ explicit Value (const var& initialValue); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ Value (Value&&) noexcept; - Value& operator= (Value&&) noexcept; - #endif /** Destructor. */ ~Value(); @@ -101,6 +100,9 @@ public: */ Value& operator= (const var& newValue); + /** Move assignment operator */ + Value& operator= (Value&&) noexcept; + /** Makes this object refer to the same underlying ValueSource as another one. Once this object has been connected to another one, changing either one @@ -237,5 +239,3 @@ OutputStream& JUCE_CALLTYPE operator<< (OutputStream&, const Value&); /** This typedef is just for compatibility with old code - newer code should use the Value::Listener class directly. */ typedef Value::Listener ValueListener; - -#endif // JUCE_VALUE_H_INCLUDED diff --git a/source/modules/juce_data_structures/values/juce_ValueTree.cpp b/source/modules/juce_data_structures/values/juce_ValueTree.cpp index a2f9b14c2..afe068d16 100644 --- a/source/modules/juce_data_structures/values/juce_ValueTree.cpp +++ b/source/modules/juce_data_structures/values/juce_ValueTree.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -27,18 +29,16 @@ class ValueTree::SharedObject : public ReferenceCountedObject public: typedef ReferenceCountedObjectPtr Ptr; - explicit SharedObject (const Identifier& t) noexcept - : type (t), parent (nullptr) + explicit SharedObject (const Identifier& t) noexcept : type (t) { } SharedObject (const SharedObject& other) - : ReferenceCountedObject(), - type (other.type), properties (other.properties), parent (nullptr) + : ReferenceCountedObject(), type (other.type), properties (other.properties) { for (int i = 0; i < other.children.size(); ++i) { - SharedObject* const child = new SharedObject (*other.children.getObjectPointerUnchecked(i)); + auto child = new SharedObject (*other.children.getObjectPointerUnchecked(i)); child->parent = this; children.add (child); } @@ -62,132 +62,59 @@ public: return parent == nullptr ? this : parent->getRoot(); } - template - void callListeners (Method method, ValueTree& tree) const + template + void callListeners (Function fn) const { - const int numListeners = valueTreesWithListeners.size(); + auto numListeners = valueTreesWithListeners.size(); if (numListeners == 1) { - valueTreesWithListeners.getUnchecked(0)->listeners.call (method, tree); + fn (valueTreesWithListeners.getUnchecked(0)->listeners); } else if (numListeners > 0) { - const SortedSet listenersCopy (valueTreesWithListeners); + auto listenersCopy = valueTreesWithListeners; for (int i = 0; i < numListeners; ++i) { - ValueTree* const v = listenersCopy.getUnchecked(i); + auto* v = listenersCopy.getUnchecked(i); if (i == 0 || valueTreesWithListeners.contains (v)) - v->listeners.call (method, tree); + fn (v->listeners); } } } - template - void callListeners (Method method, ValueTree& tree, ParamType& param2) const + template + void callListenersForAllParents (Function fn) const { - const int numListeners = valueTreesWithListeners.size(); - - if (numListeners == 1) - { - valueTreesWithListeners.getUnchecked(0)->listeners.call (method, tree, param2); - } - else if (numListeners > 0) - { - const SortedSet listenersCopy (valueTreesWithListeners); - - for (int i = 0; i < numListeners; ++i) - { - ValueTree* const v = listenersCopy.getUnchecked(i); - - if (i == 0 || valueTreesWithListeners.contains (v)) - v->listeners.call (method, tree, param2); - } - } - } - - template - void callListenersExcluding (ValueTree::Listener* listenerToExclude, - Method method, ValueTree& tree, ParamType& param2) const - { - const int numListeners = valueTreesWithListeners.size(); - - if (numListeners == 1) - { - valueTreesWithListeners.getUnchecked(0)->listeners.callExcluding (*listenerToExclude, method, tree, param2); - } - else if (numListeners > 0) - { - const SortedSet listenersCopy (valueTreesWithListeners); - - for (int i = 0; i < numListeners; ++i) - { - ValueTree* const v = listenersCopy.getUnchecked(i); - - if (i == 0 || valueTreesWithListeners.contains (v)) - v->listeners.callExcluding (*listenerToExclude, method, tree, param2); - } - } - } - - template - void callListeners (Method method, ValueTree& tree, ParamType1& param2, ParamType2& param3) const - { - const int numListeners = valueTreesWithListeners.size(); - - if (numListeners == 1) - { - valueTreesWithListeners.getUnchecked(0)->listeners.call (method, tree, param2, param3); - } - else if (numListeners > 0) - { - const SortedSet listenersCopy (valueTreesWithListeners); - - for (int i = 0; i < numListeners; ++i) - { - ValueTree* const v = listenersCopy.getUnchecked(i); - - if (i == 0 || valueTreesWithListeners.contains (v)) - v->listeners.call (method, tree, param2, param3); - } - } + for (auto* t = this; t != nullptr; t = t->parent) + t->callListeners (fn); } void sendPropertyChangeMessage (const Identifier& property, ValueTree::Listener* listenerToExclude = nullptr) { ValueTree tree (this); - for (ValueTree::SharedObject* t = this; t != nullptr; t = t->parent) - if (listenerToExclude == nullptr) - t->callListeners (&ValueTree::Listener::valueTreePropertyChanged, tree, property); - else - t->callListenersExcluding (listenerToExclude, &ValueTree::Listener::valueTreePropertyChanged, tree, property); + callListenersForAllParents ([&] (ListenerList& list) { list.callExcluding (listenerToExclude, &ValueTree::Listener::valueTreePropertyChanged, tree, property); }); } void sendChildAddedMessage (ValueTree child) { ValueTree tree (this); - - for (ValueTree::SharedObject* t = this; t != nullptr; t = t->parent) - t->callListeners (&ValueTree::Listener::valueTreeChildAdded, tree, child); + callListenersForAllParents ([&] (ListenerList& list) { list.call (&ValueTree::Listener::valueTreeChildAdded, tree, child); }); } void sendChildRemovedMessage (ValueTree child, int index) { ValueTree tree (this); - - for (ValueTree::SharedObject* t = this; t != nullptr; t = t->parent) - t->callListeners (&ValueTree::Listener::valueTreeChildRemoved, tree, child, index); + callListenersForAllParents ([=, &tree, &child] (ListenerList& list) { list.call (&ValueTree::Listener::valueTreeChildRemoved, tree, child, index); }); } void sendChildOrderChangedMessage (int oldIndex, int newIndex) { ValueTree tree (this); - - for (ValueTree::SharedObject* t = this; t != nullptr; t = t->parent) - t->callListeners (&ValueTree::Listener::valueTreeChildOrderChanged, tree, oldIndex, newIndex); + callListenersForAllParents ([=, &tree] (ListenerList& list) { list.call (&ValueTree::Listener::valueTreeChildOrderChanged, tree, oldIndex, newIndex); }); } void sendParentChangeMessage() @@ -195,10 +122,10 @@ public: ValueTree tree (this); for (int j = children.size(); --j >= 0;) - if (SharedObject* const child = children.getObjectPointer (j)) + if (auto* child = children.getObjectPointer (j)) child->sendParentChangeMessage(); - callListeners (&ValueTree::Listener::valueTreeParentChanged, tree); + callListeners ([&] (ListenerList& list) { list.call (&ValueTree::Listener::valueTreeParentChanged, tree); }); } void setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager, @@ -211,14 +138,14 @@ public: } else { - if (const var* const existingValue = properties.getVarPointer (name)) + if (auto* existingValue = properties.getVarPointer (name)) { if (*existingValue != newValue) undoManager->perform (new SetPropertyAction (this, name, newValue, *existingValue, false, false, listenerToExclude)); } else { - undoManager->perform (new SetPropertyAction (this, name, newValue, var(), true, false, listenerToExclude)); + undoManager->perform (new SetPropertyAction (this, name, newValue, {}, true, false, listenerToExclude)); } } } @@ -238,7 +165,7 @@ public: else { if (properties.contains (name)) - undoManager->perform (new SetPropertyAction (this, name, var(), properties [name], false, true)); + undoManager->perform (new SetPropertyAction (this, name, {}, properties [name], false, true)); } } @@ -248,7 +175,7 @@ public: { while (properties.size() > 0) { - const Identifier name (properties.getName (properties.size() - 1)); + auto name = properties.getName (properties.size() - 1); properties.remove (name); sendPropertyChangeMessage (name); } @@ -256,7 +183,7 @@ public: else { for (int i = properties.size(); --i >= 0;) - undoManager->perform (new SetPropertyAction (this, properties.getName(i), var(), + undoManager->perform (new SetPropertyAction (this, properties.getName(i), {}, properties.getValueAt(i), false, true)); } } @@ -273,26 +200,20 @@ public: ValueTree getChildWithName (const Identifier& typeToMatch) const { - for (int i = 0; i < children.size(); ++i) - { - SharedObject* const s = children.getObjectPointerUnchecked (i); + for (auto* s : children) if (s->type == typeToMatch) return ValueTree (s); - } - return ValueTree(); + return {}; } ValueTree getOrCreateChildWithName (const Identifier& typeToMatch, UndoManager* undoManager) { - for (int i = 0; i < children.size(); ++i) - { - SharedObject* const s = children.getObjectPointerUnchecked (i); + for (auto* s : children) if (s->type == typeToMatch) return ValueTree (s); - } - SharedObject* const newObject = new SharedObject (typeToMatch); + auto newObject = new SharedObject (typeToMatch); addChild (newObject, -1, undoManager); return ValueTree (newObject); @@ -300,19 +221,16 @@ public: ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const { - for (int i = 0; i < children.size(); ++i) - { - SharedObject* const s = children.getObjectPointerUnchecked (i); + for (auto* s : children) if (s->properties[propertyName] == propertyValue) return ValueTree (s); - } - return ValueTree(); + return {}; } bool isAChildOf (const SharedObject* const possibleParent) const noexcept { - for (const SharedObject* p = parent; p != nullptr; p = p->parent) + for (auto* p = parent; p != nullptr; p = p->parent) if (p == possibleParent) return true; @@ -418,7 +336,7 @@ public: for (int i = 0; i < children.size(); ++i) { - SharedObject* const child = newOrder.getUnchecked(i)->object; + auto* child = newOrder.getUnchecked(i)->object.get(); if (children.getObjectPointerUnchecked (i) != child) { @@ -446,7 +364,7 @@ public: XmlElement* createXml() const { - XmlElement* const xml = new XmlElement (type); + auto xml = new XmlElement (type); properties.copyToXmlAttributes (*xml); // (NB: it's faster to add nodes to XML elements in reverse order) @@ -629,7 +547,7 @@ public: UndoableAction* createCoalescedAction (UndoableAction* nextAction) override { - if (MoveChildAction* next = dynamic_cast (nextAction)) + if (auto* next = dynamic_cast (nextAction)) if (next->parent == parent && next->startIndex == endIndex) return new MoveChildAction (parent, startIndex, next->endIndex); @@ -648,7 +566,7 @@ public: NamedValueSet properties; ReferenceCountedArray children; SortedSet valueTreesWithListeners; - SharedObject* parent; + SharedObject* parent = nullptr; private: SharedObject& operator= (const SharedObject&); @@ -702,12 +620,10 @@ ValueTree& ValueTree::operator= (const ValueTree& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS ValueTree::ValueTree (ValueTree&& other) noexcept : object (static_cast (other.object)) { } -#endif ValueTree::~ValueTree() { @@ -762,7 +678,7 @@ ValueTree ValueTree::getRoot() const noexcept ValueTree ValueTree::getSibling (const int delta) const noexcept { if (object == nullptr || object->parent == nullptr) - return ValueTree(); + return {}; const int index = object->parent->indexOf (*this) + delta; return ValueTree (object->parent->children.getObjectPointer (index)); @@ -1056,7 +972,7 @@ ValueTree ValueTree::fromXml (const XmlElement& xml) // ValueTrees don't have any equivalent to XML text elements! jassertfalse; - return ValueTree(); + return {}; } String ValueTree::toXmlString() const @@ -1073,10 +989,10 @@ void ValueTree::writeToStream (OutputStream& output) const ValueTree ValueTree::readFromStream (InputStream& input) { - const String type (input.readString()); + auto type = input.readString(); if (type.isEmpty()) - return ValueTree(); + return {}; ValueTree v (type); @@ -1141,7 +1057,7 @@ void ValueTree::Listener::valueTreeRedirected (ValueTree&) {} class ValueTreeTests : public UnitTest { public: - ValueTreeTests() : UnitTest ("ValueTrees") {} + ValueTreeTests() : UnitTest ("ValueTrees", "Values") {} static String createRandomIdentifier (Random& r) { diff --git a/source/modules/juce_data_structures/values/juce_ValueTree.h b/source/modules/juce_data_structures/values/juce_ValueTree.h index e48a83f3f..7c3e3eccf 100644 --- a/source/modules/juce_data_structures/values/juce_ValueTree.h +++ b/source/modules/juce_data_structures/values/juce_ValueTree.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_VALUETREE_H_INCLUDED -#define JUCE_VALUETREE_H_INCLUDED +#pragma once //============================================================================== @@ -75,8 +76,6 @@ public: A ValueTree that is created with this constructor can't actually be used for anything, it's just a default 'null' ValueTree that can be returned to indicate some sort of failure. To create a real one, use the constructor that takes a string. - - @see ValueTree::invalid */ ValueTree() noexcept; @@ -92,9 +91,8 @@ public: /** Makes this object reference another node. */ ValueTree& operator= (const ValueTree&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ ValueTree (ValueTree&&) noexcept; - #endif /** Destructor. */ ~ValueTree(); @@ -329,7 +327,7 @@ public: The delta specifies how far to move through the list, so a value of 1 would return the node that follows this one, -1 would return the node before it, 0 will return this node itself, etc. - If the requested position is beyond the range of available nodes, this will return ValueTree::invalid. + If the requested position is beyond the range of available nodes, this will return an empty ValueTree(). */ ValueTree getSibling (int delta) const noexcept; @@ -576,6 +574,3 @@ private: explicit ValueTree (SharedObject*) noexcept; }; - - -#endif // JUCE_VALUETREE_H_INCLUDED diff --git a/source/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp b/source/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp index e0d2b21f4..d29b692b4 100644 --- a/source/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp +++ b/source/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -30,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) @@ -71,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); } @@ -108,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()); + value->writeToStream (m); + } + else + { + ValueTreeSynchroniserHelpers::writeHeader (*this, m, ValueTreeSynchroniserHelpers::propertyRemoved, vt); + m.writeString (property.toString()); + } + stateChanged (m.getData(), m.getDataSize()); } @@ -171,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(); diff --git a/source/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h b/source/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h index 3773faf70..0867a56e9 100644 --- a/source/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h +++ b/source/modules/juce_data_structures/values/juce_ValueTreeSynchroniser.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_VALUETREESYNCHRONISER_H_INCLUDED -#define JUCE_VALUETREESYNCHRONISER_H_INCLUDED +#pragma once //============================================================================== @@ -92,7 +93,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueTreeSynchroniser) }; - - - -#endif // JUCE_VALUETREESYNCHRONISER_H_INCLUDED diff --git a/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp b/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp index 5b773bd6e..76253f347 100644 --- a/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp +++ b/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.h b/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.h index 7ed55575c..8a2d55901 100644 --- a/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.h +++ b/source/modules/juce_events/broadcasters/juce_ActionBroadcaster.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ACTIONBROADCASTER_H_INCLUDED -#define JUCE_ACTIONBROADCASTER_H_INCLUDED +#pragma once //============================================================================== @@ -84,6 +75,3 @@ private: JUCE_DECLARE_NON_COPYABLE (ActionBroadcaster) }; - - -#endif // JUCE_ACTIONBROADCASTER_H_INCLUDED diff --git a/source/modules/juce_events/broadcasters/juce_ActionListener.h b/source/modules/juce_events/broadcasters/juce_ActionListener.h index a5ba45c19..0571eaf05 100644 --- a/source/modules/juce_events/broadcasters/juce_ActionListener.h +++ b/source/modules/juce_events/broadcasters/juce_ActionListener.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ACTIONLISTENER_H_INCLUDED -#define JUCE_ACTIONLISTENER_H_INCLUDED +#pragma once //============================================================================== @@ -51,6 +42,3 @@ public: */ virtual void actionListenerCallback (const String& message) = 0; }; - - -#endif // JUCE_ACTIONLISTENER_H_INCLUDED diff --git a/source/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp b/source/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp index f9e579c3a..15659057f 100644 --- a/source/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp +++ b/source/modules/juce_events/broadcasters/juce_AsyncUpdater.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_events/broadcasters/juce_AsyncUpdater.h b/source/modules/juce_events/broadcasters/juce_AsyncUpdater.h index 5c430d302..6b207a87c 100644 --- a/source/modules/juce_events/broadcasters/juce_AsyncUpdater.h +++ b/source/modules/juce_events/broadcasters/juce_AsyncUpdater.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ASYNCUPDATER_H_INCLUDED -#define JUCE_ASYNCUPDATER_H_INCLUDED +#pragma once //============================================================================== @@ -110,6 +101,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncUpdater) }; - - -#endif // JUCE_ASYNCUPDATER_H_INCLUDED diff --git a/source/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp b/source/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp index cbcf85a7c..c7b4cbfae 100644 --- a/source/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp +++ b/source/modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -48,7 +40,7 @@ void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) { - // Listeners can only be safely added when the event thread is locked + // Listeners can only be safely removed when the event thread is locked // You can use a MessageManagerLock if you need to call this from another thread. jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); @@ -57,7 +49,7 @@ void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) void ChangeBroadcaster::removeAllChangeListeners() { - // Listeners can only be safely added when the event thread is locked + // Listeners can only be safely removed when the event thread is locked // You can use a MessageManagerLock if you need to call this from another thread. jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); diff --git a/source/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h b/source/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h index 5670e86c1..7750e1278 100644 --- a/source/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h +++ b/source/modules/juce_events/broadcasters/juce_ChangeBroadcaster.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHANGEBROADCASTER_H_INCLUDED -#define JUCE_CHANGEBROADCASTER_H_INCLUDED +#pragma once //============================================================================== @@ -106,6 +97,3 @@ private: JUCE_DECLARE_NON_COPYABLE (ChangeBroadcaster) }; - - -#endif // JUCE_CHANGEBROADCASTER_H_INCLUDED diff --git a/source/modules/juce_events/broadcasters/juce_ChangeListener.h b/source/modules/juce_events/broadcasters/juce_ChangeListener.h index e8e8e425c..37aabd0d6 100644 --- a/source/modules/juce_events/broadcasters/juce_ChangeListener.h +++ b/source/modules/juce_events/broadcasters/juce_ChangeListener.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHANGELISTENER_H_INCLUDED -#define JUCE_CHANGELISTENER_H_INCLUDED +#pragma once class ChangeBroadcaster; @@ -65,6 +56,3 @@ public: private: virtual int changeListenerCallback (void*) { return 0; } #endif }; - - -#endif // JUCE_CHANGELISTENER_H_INCLUDED diff --git a/source/modules/juce_events/broadcasters/juce_ListenerList.h b/source/modules/juce_events/broadcasters/juce_ListenerList.h deleted file mode 100644 index c68858f26..000000000 --- a/source/modules/juce_events/broadcasters/juce_ListenerList.h +++ /dev/null @@ -1,359 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -#ifndef JUCE_LISTENERLIST_H_INCLUDED -#define JUCE_LISTENERLIST_H_INCLUDED - - -//============================================================================== -/** - Holds a set of objects and can invoke a member function callback on each object - in the set with a single call. - - Use a ListenerList to manage a set of objects which need a callback, and you - can invoke a member function by simply calling call() or callChecked(). - - E.g. - @code - class MyListenerType - { - public: - void myCallbackMethod (int foo, bool bar); - }; - - ListenerList listeners; - listeners.add (someCallbackObjects...); - - // This will invoke myCallbackMethod (1234, true) on each of the objects - // in the list... - listeners.call (&MyListenerType::myCallbackMethod, 1234, true); - @endcode - - If you add or remove listeners from the list during one of the callbacks - i.e. while - it's in the middle of iterating the listeners, then it's guaranteed that no listeners - will be mistakenly called after they've been removed, but it may mean that some of the - listeners could be called more than once, or not at all, depending on the list's order. - - Sometimes, there's a chance that invoking one of the callbacks might result in the - list itself being deleted while it's still iterating - to survive this situation, you can - use callChecked() instead of call(), passing it a local object to act as a "BailOutChecker". - The BailOutChecker must implement a method of the form "bool shouldBailOut()", and - the list will check this after each callback to determine whether it should abort the - operation. For an example of a bail-out checker, see the Component::BailOutChecker class, - which can be used to check when a Component has been deleted. See also - ListenerList::DummyBailOutChecker, which is a dummy checker that always returns false. -*/ -template > -class ListenerList -{ - // Horrible macros required to support VC7.. - #ifndef DOXYGEN - #if JUCE_VC8_OR_EARLIER - #define LL_TEMPLATE(a) typename P##a, typename Q##a - #define LL_PARAM(a) Q##a& param##a - #else - #define LL_TEMPLATE(a) typename P##a - #define LL_PARAM(a) PARAMETER_TYPE(P##a) param##a - #endif - #endif - -public: - //============================================================================== - /** Creates an empty list. */ - ListenerList() - { - } - - /** Destructor. */ - ~ListenerList() - { - } - - //============================================================================== - /** Adds a listener to the list. - A listener can only be added once, so if the listener is already in the list, - this method has no effect. - @see remove - */ - void add (ListenerClass* const listenerToAdd) - { - // Listeners can't be null pointers! - jassert (listenerToAdd != nullptr); - - if (listenerToAdd != nullptr) - listeners.addIfNotAlreadyThere (listenerToAdd); - } - - /** Removes a listener from the list. - If the listener wasn't in the list, this has no effect. - */ - void remove (ListenerClass* const listenerToRemove) - { - // Listeners can't be null pointers! - jassert (listenerToRemove != nullptr); - - listeners.removeFirstMatchingValue (listenerToRemove); - } - - /** Returns the number of registered listeners. */ - int size() const noexcept - { - return listeners.size(); - } - - /** Returns true if any listeners are registered. */ - bool isEmpty() const noexcept - { - return listeners.size() == 0; - } - - /** Clears the list. */ - void clear() - { - listeners.clear(); - } - - /** Returns true if the specified listener has been added to the list. */ - bool contains (ListenerClass* const listener) const noexcept - { - return listeners.contains (listener); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with no parameters. */ - void call (void (ListenerClass::*callbackFunction) ()) - { - callChecked (static_cast (DummyBailOutChecker()), callbackFunction); - } - - /** Calls a member function on each listener in the list, with no parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) ()) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 1 parameter. */ - template - void call (void (ListenerClass::*callbackFunction) (P1), LL_PARAM(1)) - { - for (Iterator iter (*this); iter.next();) - (iter.getListener()->*callbackFunction) (param1); - } - - /** Calls a member function on each listener in the list, with one parameter and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) (P1), - LL_PARAM(1)) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (param1); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 2 parameters. */ - template - void call (void (ListenerClass::*callbackFunction) (P1, P2), - LL_PARAM(1), LL_PARAM(2)) - { - for (Iterator iter (*this); iter.next();) - (iter.getListener()->*callbackFunction) (param1, param2); - } - - /** Calls a member function on each listener in the list, with 2 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (const BailOutCheckerType& bailOutChecker, - void (ListenerClass::*callbackFunction) (P1, P2), - LL_PARAM(1), LL_PARAM(2)) - { - for (Iterator iter (*this); iter.next (bailOutChecker);) - (iter.getListener()->*callbackFunction) (param1, param2); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 3 parameters. */ - template - void call (void (ListenerClass::*callbackFunction) (P1, P2, P3), - LL_PARAM(1), LL_PARAM(2), LL_PARAM(3)) - { - for (Iterator iter (*this); iter.next();) - (iter.getListener()->*callbackFunction) (param1, param2, param3); - } - - /** Calls a member function on each listener in the list, with 3 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (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);) - (iter.getListener()->*callbackFunction) (param1, param2, param3); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 4 parameters. */ - template - void call (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();) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); - } - - /** Calls a member function on each listener in the list, with 4 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (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);) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 5 parameters. */ - template - void call (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();) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); - } - - /** Calls a member function on each listener in the list, with 5 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (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);) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); - } - - //============================================================================== - /** Calls a member function on each listener in the list, with 5 parameters. */ - template - void call (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();) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5, param6); - } - - /** Calls a member function on each listener in the list, with 5 parameters and a bail-out-checker. - See the class description for info about writing a bail-out checker. */ - template - void callChecked (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);) - (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5, param6); - } - - - //============================================================================== - /** A dummy bail-out checker that always returns false. - See the ListenerList notes for more info about bail-out checkers. - */ - class DummyBailOutChecker - { - public: - inline bool shouldBailOut() const noexcept { return false; } - }; - - //============================================================================== - /** Iterates the listeners in a ListenerList. */ - template - class Iterator - { - public: - //============================================================================== - Iterator (const ListType& listToIterate) noexcept - : list (listToIterate), index (listToIterate.size()) - {} - - ~Iterator() noexcept {} - - //============================================================================== - bool next() noexcept - { - if (index <= 0) - return false; - - const int listSize = list.size(); - - if (--index < listSize) - return true; - - index = listSize - 1; - return index >= 0; - } - - bool next (const BailOutCheckerType& bailOutChecker) noexcept - { - return (! bailOutChecker.shouldBailOut()) && next(); - } - - typename ListType::ListenerType* getListener() const noexcept - { - return list.getListeners().getUnchecked (index); - } - - //============================================================================== - private: - const ListType& list; - int index; - - JUCE_DECLARE_NON_COPYABLE (Iterator) - }; - - typedef ListenerList ThisType; - typedef ListenerClass ListenerType; - - const ArrayType& getListeners() const noexcept { return listeners; } - -private: - //============================================================================== - ArrayType listeners; - - JUCE_DECLARE_NON_COPYABLE (ListenerList) - - #undef LL_TEMPLATE - #undef LL_PARAM -}; - - -#endif // JUCE_LISTENERLIST_H_INCLUDED diff --git a/source/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp b/source/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp index a5a424573..a0e69161b 100644 --- a/source/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp +++ b/source/modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_events/interprocess/juce_ConnectedChildProcess.h b/source/modules/juce_events/interprocess/juce_ConnectedChildProcess.h index 80c953d11..d1eaadc29 100644 --- a/source/modules/juce_events/interprocess/juce_ConnectedChildProcess.h +++ b/source/modules/juce_events/interprocess/juce_ConnectedChildProcess.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CONNECTEDCHILDPROCESS_H_INCLUDED -#define JUCE_CONNECTEDCHILDPROCESS_H_INCLUDED +#pragma once //============================================================================== /** @@ -193,6 +184,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcessMaster) }; - - -#endif // JUCE_CONNECTEDCHILDPROCESS_H_INCLUDED diff --git a/source/modules/juce_events/interprocess/juce_InterprocessConnection.cpp b/source/modules/juce_events/interprocess/juce_InterprocessConnection.cpp index 8f5cbeb86..353beeaac 100644 --- a/source/modules/juce_events/interprocess/juce_InterprocessConnection.cpp +++ b/source/modules/juce_events/interprocess/juce_InterprocessConnection.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -151,7 +143,7 @@ String InterprocessConnection::getConnectedHostName() const const ScopedLock sl (pipeAndSocketLock); if (pipe == nullptr && socket == nullptr) - return String(); + return {}; if (socket != nullptr && ! socket->isLocal()) return socket->getHostName(); diff --git a/source/modules/juce_events/interprocess/juce_InterprocessConnection.h b/source/modules/juce_events/interprocess/juce_InterprocessConnection.h index ed8fc6da7..6f9048bc7 100644 --- a/source/modules/juce_events/interprocess/juce_InterprocessConnection.h +++ b/source/modules/juce_events/interprocess/juce_InterprocessConnection.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_INTERPROCESSCONNECTION_H_INCLUDED -#define JUCE_INTERPROCESSCONNECTION_H_INCLUDED +#pragma once class InterprocessConnectionServer; class MemoryBlock; @@ -212,5 +203,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InterprocessConnection) }; - -#endif // JUCE_INTERPROCESSCONNECTION_H_INCLUDED diff --git a/source/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp b/source/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp index 1eca65791..d972d9794 100644 --- a/source/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp +++ b/source/modules/juce_events/interprocess/juce_InterprocessConnectionServer.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h b/source/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h index f871dd953..8afd71ae3 100644 --- a/source/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h +++ b/source/modules/juce_events/interprocess/juce_InterprocessConnectionServer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_INTERPROCESSCONNECTIONSERVER_H_INCLUDED -#define JUCE_INTERPROCESSCONNECTIONSERVER_H_INCLUDED +#pragma once //============================================================================== @@ -101,6 +92,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InterprocessConnectionServer) }; - - -#endif // JUCE_INTERPROCESSCONNECTIONSERVER_H_INCLUDED diff --git a/source/modules/juce_events/juce_events.cpp b/source/modules/juce_events/juce_events.cpp index 729a78f2c..50d8fdd69 100644 --- a/source/modules/juce_events/juce_events.cpp +++ b/source/modules/juce_events/juce_events.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -37,13 +29,16 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #define JUCE_CORE_INCLUDE_OBJC_HELPERS 1 #define JUCE_CORE_INCLUDE_JNI_HELPERS 1 #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 +#define JUCE_CORE_INCLUDE_COM_SMART_PTR 1 #define JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW 1 +#if JUCE_USE_WINRT_MIDI + #define JUCE_EVENTS_INCLUDE_WINRT_WRAPPER 1 +#endif + #include "juce_events.h" //============================================================================== @@ -55,10 +50,6 @@ #import #elif JUCE_LINUX - #include - #include - #include - #undef KeyPress #include #endif @@ -80,19 +71,32 @@ 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" + #if JUCE_EVENTS_INCLUDE_WINRT_WRAPPER + #include "native/juce_win32_WinRTWrapper.cpp" + #endif #elif JUCE_LINUX - #include "native/juce_ScopedXLock.h" #include "native/juce_linux_Messaging.cpp" #elif JUCE_ANDROID diff --git a/source/modules/juce_events/juce_events.h b/source/modules/juce_events/juce_events.h index bdddd8b99..a09ece17d 100644 --- a/source/modules/juce_events/juce_events.h +++ b/source/modules/juce_events/juce_events.h @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -39,26 +31,37 @@ ID: juce_events vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE message and event handling classes description: Classes for running an application's main event loop and sending/receiving messages, timers, etc. website: http://www.juce.com/juce license: ISC dependencies: juce_core - linuxPackages: x11 END_JUCE_MODULE_DECLARATION *******************************************************************************/ -#ifndef JUCE_EVENTS_H_INCLUDED +#pragma once #define JUCE_EVENTS_H_INCLUDED -//============================================================================== #include +//============================================================================== +/** Config: JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK + Will execute your application's suspend method on an iOS background task, giving + you extra time to save your applications state. +*/ +#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK + #define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 +#endif + +#if JUCE_EVENTS_INCLUDE_WINRT_WRAPPER && JUCE_WINDOWS + #include +#endif + namespace juce { @@ -81,12 +84,19 @@ namespace juce #include "interprocess/juce_InterprocessConnection.h" #include "interprocess/juce_InterprocessConnectionServer.h" #include "interprocess/juce_ConnectedChildProcess.h" -#include "native/juce_ScopedXLock.h" -#if JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW && JUCE_WINDOWS - #include "native/juce_win32_HiddenMessageWindow.h" +#if JUCE_LINUX + #include "native/juce_linux_EventLoop.h" #endif -} -#endif // JUCE_EVENTS_H_INCLUDED +#if JUCE_WINDOWS + #if JUCE_EVENTS_INCLUDE_WIN32_MESSAGE_WINDOW + #include "native/juce_win32_HiddenMessageWindow.h" + #endif + #if JUCE_EVENTS_INCLUDE_WINRT_WRAPPER + #include "native/juce_win32_WinRTWrapper.h" + #endif +#endif + +} diff --git a/source/modules/juce_events/messages/juce_ApplicationBase.cpp b/source/modules/juce_events/messages/juce_ApplicationBase.cpp index 5779dc602..be929bee3 100644 --- a/source/modules/juce_events/messages/juce_ApplicationBase.cpp +++ b/source/modules/juce_events/messages/juce_ApplicationBase.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,6 +23,10 @@ JUCEApplicationBase::CreateInstanceFunction JUCEApplicationBase::createInstance = 0; JUCEApplicationBase* JUCEApplicationBase::appInstance = nullptr; +#if JUCE_IOS +void* JUCEApplicationBase::iOSCustomDelegate = nullptr; +#endif + JUCEApplicationBase::JUCEApplicationBase() : appReturnValue (0), stillInitialising (true) @@ -77,7 +73,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); + } } //============================================================================== @@ -139,8 +143,8 @@ struct JUCEApplicationBase::MultipleInstanceHandler {}; //============================================================================== #if JUCE_ANDROID -StringArray JUCEApplicationBase::getCommandLineParameterArray() { return StringArray(); } -String JUCEApplicationBase::getCommandLineParameters() { return String(); } +StringArray JUCEApplicationBase::getCommandLineParameterArray() { return {}; } +String JUCEApplicationBase::getCommandLineParameters() { return {}; } #else @@ -177,6 +181,10 @@ StringArray JUCE_CALLTYPE JUCEApplicationBase::getCommandLineParameterArray() extern void initialiseNSApplication(); #endif +#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 + #if JUCE_WINDOWS const char* const* juce_argv = nullptr; int juce_argc = 0; @@ -207,7 +215,7 @@ StringArray JUCEApplicationBase::getCommandLineParameterArray() return StringArray (juce_argv + 1, juce_argc - 1); } -int JUCEApplicationBase::main (int argc, const char* argv[], void* customDelegate) +int JUCEApplicationBase::main (int argc, const char* argv[]) { JUCE_AUTORELEASEPOOL { @@ -218,10 +226,14 @@ int JUCEApplicationBase::main (int argc, const char* argv[], void* customDelegat initialiseNSApplication(); #endif + #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 + #if JUCE_IOS - return juce_iOSMain (argc, argv, customDelegate); + return juce_iOSMain (argc, argv, iOSCustomDelegate); #else - ignoreUnused (customDelegate); return JUCEApplicationBase::main(); #endif diff --git a/source/modules/juce_events/messages/juce_ApplicationBase.h b/source/modules/juce_events/messages/juce_ApplicationBase.h index 748b86a44..c9ffc5f0b 100644 --- a/source/modules/juce_events/messages/juce_ApplicationBase.h +++ b/source/modules/juce_events/messages/juce_ApplicationBase.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_APPLICATIONBASE_H_INCLUDED -#define JUCE_APPLICATIONBASE_H_INCLUDED +#pragma once //============================================================================== @@ -197,6 +188,13 @@ public: const String& sourceFilename, int lineNumber) = 0; + //============================================================================== + /** Override this method to be informed when the back button is pressed on a device. + + This is currently only implemented on Android devices. + */ + virtual void backButtonPressed() { } + //============================================================================== /** Signals that the main message loop should stop and the application should terminate. @@ -258,12 +256,16 @@ public: #ifndef DOXYGEN // The following methods are for internal use only... static int main(); - static int main (int argc, const char* argv[], void*); + static int main (int argc, const char* argv[]); static void appWillTerminateByForce(); typedef JUCEApplicationBase* (*CreateInstanceFunction)(); static CreateInstanceFunction createInstance; + #if JUCE_IOS + static void* iOSCustomDelegate; + #endif + virtual bool initialiseApp(); int shutdownApp(); static void JUCE_CALLTYPE sendUnhandledException (const std::exception*, const char* sourceFile, int lineNumber); @@ -306,6 +308,3 @@ private: #define JUCE_TRY #define JUCE_CATCH_EXCEPTION #endif - - -#endif // JUCE_APPLICATIONBASE_H_INCLUDED diff --git a/source/modules/juce_events/messages/juce_CallbackMessage.h b/source/modules/juce_events/messages/juce_CallbackMessage.h index 23c70621b..249b204c0 100644 --- a/source/modules/juce_events/messages/juce_CallbackMessage.h +++ b/source/modules/juce_events/messages/juce_CallbackMessage.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CALLBACKMESSAGE_H_INCLUDED -#define JUCE_CALLBACKMESSAGE_H_INCLUDED +#pragma once //============================================================================== @@ -47,7 +38,10 @@ Always create a new instance of a CallbackMessage on the heap, as it will be deleted automatically after the message has been delivered. - @see MessageManager, MessageListener, ActionListener, ChangeListener + Note that this class was essential back in the days before C++11, but in modern + times you may prefer to use MessageManager::callAsync() with a lambda. + + @see MessageManager::callAsync, MessageListener, ActionListener, ChangeListener */ class JUCE_API CallbackMessage : public MessageManager::MessageBase { @@ -74,6 +68,3 @@ private: // messages still in the system event queue. These aren't harmful, but can cause annoying assertions. JUCE_DECLARE_NON_COPYABLE (CallbackMessage) }; - - -#endif // JUCE_CALLBACKMESSAGE_H_INCLUDED diff --git a/source/modules/juce_events/messages/juce_DeletedAtShutdown.cpp b/source/modules/juce_events/messages/juce_DeletedAtShutdown.cpp index 76d68107d..897632a28 100644 --- a/source/modules/juce_events/messages/juce_DeletedAtShutdown.cpp +++ b/source/modules/juce_events/messages/juce_DeletedAtShutdown.cpp @@ -2,67 +2,73 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -static SpinLock deletedAtShutdownLock; +static SpinLock deletedAtShutdownLock; // use a spin lock because it can be statically initialised + +static Array& getDeletedAtShutdownObjects() +{ + static Array objects; + return objects; +} DeletedAtShutdown::DeletedAtShutdown() { const SpinLock::ScopedLockType sl (deletedAtShutdownLock); - getObjects().add (this); + getDeletedAtShutdownObjects().add (this); } DeletedAtShutdown::~DeletedAtShutdown() { const SpinLock::ScopedLockType sl (deletedAtShutdownLock); - getObjects().removeFirstMatchingValue (this); + getDeletedAtShutdownObjects().removeFirstMatchingValue (this); } +#if JUCE_MSVC + // Disable unreachable code warning, in case the compiler manages to figure out that + // you have no classes of DeletedAtShutdown that could throw an exception in their destructor. + #pragma warning (push) + #pragma warning (disable: 4702) +#endif + void DeletedAtShutdown::deleteAll() { // make a local copy of the array, so it can't get into a loop if something // creates another DeletedAtShutdown object during its destructor. - Array localCopy; + Array localCopy; { const SpinLock::ScopedLockType sl (deletedAtShutdownLock); - localCopy = getObjects(); + localCopy = getDeletedAtShutdownObjects(); } for (int i = localCopy.size(); --i >= 0;) { JUCE_TRY { - DeletedAtShutdown* deletee = localCopy.getUnchecked(i); + auto* deletee = localCopy.getUnchecked(i); // double-check that it's not already been deleted during another object's destructor. { const SpinLock::ScopedLockType sl (deletedAtShutdownLock); - if (! getObjects().contains (deletee)) + + if (! getDeletedAtShutdownObjects().contains (deletee)) deletee = nullptr; } @@ -71,15 +77,13 @@ void DeletedAtShutdown::deleteAll() JUCE_CATCH_EXCEPTION } - // if no objects got re-created during shutdown, this should have been emptied by their - // destructors - jassert (getObjects().size() == 0); + // if this fails, then it's likely that some new DeletedAtShutdown objects were + // created while executing the destructors of the other ones. + jassert (getDeletedAtShutdownObjects().isEmpty()); - getObjects().clear(); // just to make sure the array doesn't have any memory still allocated + getDeletedAtShutdownObjects().clear(); // just to make sure the array doesn't have any memory still allocated } -Array & DeletedAtShutdown::getObjects() -{ - static Array objects; - return objects; -} +#if JUCE_MSVC + #pragma warning (pop) +#endif diff --git a/source/modules/juce_events/messages/juce_DeletedAtShutdown.h b/source/modules/juce_events/messages/juce_DeletedAtShutdown.h index e1563229c..a0284f80d 100644 --- a/source/modules/juce_events/messages/juce_DeletedAtShutdown.h +++ b/source/modules/juce_events/messages/juce_DeletedAtShutdown.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DELETEDATSHUTDOWN_H_INCLUDED -#define JUCE_DELETEDATSHUTDOWN_H_INCLUDED +#pragma once //============================================================================== @@ -66,9 +57,5 @@ public: static void deleteAll(); private: - static Array & getObjects(); - JUCE_DECLARE_NON_COPYABLE (DeletedAtShutdown) }; - -#endif // JUCE_DELETEDATSHUTDOWN_H_INCLUDED diff --git a/source/modules/juce_events/messages/juce_Initialisation.h b/source/modules/juce_events/messages/juce_Initialisation.h index f80710628..e911807bd 100644 --- a/source/modules/juce_events/messages/juce_Initialisation.h +++ b/source/modules/juce_events/messages/juce_Initialisation.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_INITIALISATION_H_INCLUDED -#define JUCE_INITIALISATION_H_INCLUDED +#pragma once //============================================================================== @@ -93,76 +84,115 @@ public: */ #ifdef DOXYGEN #define START_JUCE_APPLICATION(AppClass) -#elif JUCE_ANDROID - #define START_JUCE_APPLICATION(AppClass) \ - juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } - #else #if JUCE_WINDOWS && ! defined (_CONSOLE) #define JUCE_MAIN_FUNCTION int __stdcall WinMain (struct HINSTANCE__*, struct HINSTANCE__*, char*, int) #define JUCE_MAIN_FUNCTION_ARGS #else #define JUCE_MAIN_FUNCTION int main (int argc, char* argv[]) - #define JUCE_MAIN_FUNCTION_ARGS argc, (const char**) argv, nullptr + #define JUCE_MAIN_FUNCTION_ARGS argc, (const char**) argv #endif - #define START_JUCE_APPLICATION(AppClass) \ - static juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } \ + #if JUCE_IOS + + #define JUCE_CREATE_APPLICATION_DEFINE(AppClass) \ + juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } \ + void* juce_GetIOSCustomDelegateClass() { return nullptr; } + + #define JUCE_CREATE_APPLICATION_DEFINE_CUSTOM_DELEGATE(AppClass, DelegateClass) \ + juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } \ + void* juce_GetIOSCustomDelegateClass() { return [DelegateClass class]; } + + #define JUCE_MAIN_FUNCTION_DEFINITION \ extern "C" JUCE_MAIN_FUNCTION \ { \ - juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; \ - return juce::JUCEApplicationBase::main (JUCE_MAIN_FUNCTION_ARGS); \ + juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; \ + juce::JUCEApplicationBase::iOSCustomDelegate = juce_GetIOSCustomDelegateClass(); \ + return juce::JUCEApplicationBase::main (JUCE_MAIN_FUNCTION_ARGS); \ + } + + #elif JUCE_ANDROID + + #define JUCE_CREATE_APPLICATION_DEFINE(AppClass) \ + juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } + + #define JUCE_MAIN_FUNCTION_DEFINITION + + #else + + #define JUCE_CREATE_APPLICATION_DEFINE(AppClass) \ + juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } + + #define JUCE_MAIN_FUNCTION_DEFINITION \ + extern "C" JUCE_MAIN_FUNCTION \ + { \ + juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; \ + return juce::JUCEApplicationBase::main (JUCE_MAIN_FUNCTION_ARGS); \ } - #if JUCE_IOS - /** - You can instruct JUCE to use a custom iOS app delegate class instaed of JUCE's default - app delegate. For JUCE to work you must pass all messages to JUCE's internal app delegate. - Below is an example of minimal forwarding custom delegate. Note that you are at your own - risk if you decide to use your own delegate an subtle, hard to debug bugs may occur. - - @interface MyCustomDelegate : NSObject { NSObject* juceDelegate; } @end - @implementation MyCustomDelegate - -(id) init - { - self = [super init]; - juceDelegate = reinterpret_cast*> ([[NSClassFromString (@"JuceAppStartupDelegate") alloc] init]); - - return self; - } - - -(void)dealloc - { - [juceDelegate release]; - [super dealloc]; - } - - - (void)forwardInvocation:(NSInvocation *)anInvocation - { - if (juceDelegate != nullptr && [juceDelegate respondsToSelector:[anInvocation selector]]) - [anInvocation invokeWithTarget:juceDelegate]; - else - [super forwardInvocation:anInvocation]; - } - - -(BOOL)respondsToSelector:(SEL)aSelector - { - if (juceDelegate != nullptr && [juceDelegate respondsToSelector:aSelector]) - return YES; - - return [super respondsToSelector:aSelector]; - } - @end - */ - #define START_JUCE_APPLICATION_WITH_CUSTOM_DELEGATE(AppClass, DelegateClass) \ - static juce::JUCEApplicationBase* juce_CreateApplication() { return new AppClass(); } \ - extern "C" JUCE_MAIN_FUNCTION \ - { \ - juce::JUCEApplicationBase::createInstance = &juce_CreateApplication; \ - return juce::JUCEApplicationBase::main (argc, (const char**) argv, [DelegateClass class]); \ - } #endif -#endif + #if JucePlugin_Build_Standalone + #if JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP + #define START_JUCE_APPLICATION(AppClass) JUCE_CREATE_APPLICATION_DEFINE(AppClass) + #if JUCE_IOS + #define START_JUCE_APPLICATION_WITH_CUSTOM_DELEGATE(AppClass, DelegateClass) JUCE_CREATE_APPLICATION_DEFINE_CUSTOM_DELEGATE(AppClass, DelegateClass) + #endif + #else + #define START_JUCE_APPLICATION(AppClass) static_assert(false, "You are trying to use START_JUCE_APPLICATION in an audio plug-in. Define JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP=1 if you want to use a custom standalone target app."); + #if JUCE_IOS + #define START_JUCE_APPLICATION_WITH_CUSTOM_DELEGATE(AppClass, DelegateClass) static_assert(false, "You are trying to use START_JUCE_APPLICATION in an audio plug-in. Define JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP=1 if you want to use a custom standalone target app."); + #endif + #endif + #else -#endif // JUCE_INITIALISATION_H_INCLUDED + #define START_JUCE_APPLICATION(AppClass) \ + JUCE_CREATE_APPLICATION_DEFINE(AppClass) \ + JUCE_MAIN_FUNCTION_DEFINITION + + #if JUCE_IOS + /** + You can instruct JUCE to use a custom iOS app delegate class instaed of JUCE's default + app delegate. For JUCE to work you must pass all messages to JUCE's internal app delegate. + Below is an example of minimal forwarding custom delegate. Note that you are at your own + risk if you decide to use your own delegate an subtle, hard to debug bugs may occur. + + @interface MyCustomDelegate : NSObject { NSObject* juceDelegate; } @end + @implementation MyCustomDelegate + -(id) init + { + self = [super init]; + juceDelegate = reinterpret_cast*> ([[NSClassFromString (@"JuceAppStartupDelegate") alloc] init]); + + return self; + } + + -(void)dealloc + { + [juceDelegate release]; + [super dealloc]; + } + + - (void)forwardInvocation:(NSInvocation *)anInvocation + { + if (juceDelegate != nullptr && [juceDelegate respondsToSelector:[anInvocation selector]]) + [anInvocation invokeWithTarget:juceDelegate]; + else + [super forwardInvocation:anInvocation]; + } + + -(BOOL)respondsToSelector:(SEL)aSelector + { + if (juceDelegate != nullptr && [juceDelegate respondsToSelector:aSelector]) + return YES; + + return [super respondsToSelector:aSelector]; + } + @end + */ + #define START_JUCE_APPLICATION_WITH_CUSTOM_DELEGATE(AppClass, DelegateClass) \ + JUCE_CREATE_APPLICATION_DEFINE_CUSTOM_DELEGATE(AppClass, DelegateClass) \ + JUCE_MAIN_FUNCTION_DEFINITION + #endif + #endif +#endif diff --git a/source/modules/juce_events/messages/juce_Message.h b/source/modules/juce_events/messages/juce_Message.h index a3aa82469..52033be77 100644 --- a/source/modules/juce_events/messages/juce_Message.h +++ b/source/modules/juce_events/messages/juce_Message.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MESSAGE_H_INCLUDED -#define JUCE_MESSAGE_H_INCLUDED +#pragma once class MessageListener; @@ -66,6 +57,3 @@ private: // messages still in the system event queue. These aren't harmful, but can cause annoying assertions. JUCE_DECLARE_NON_COPYABLE (Message) }; - - -#endif // JUCE_MESSAGE_H_INCLUDED diff --git a/source/modules/juce_events/messages/juce_MessageListener.cpp b/source/modules/juce_events/messages/juce_MessageListener.cpp index 01a66d97b..671cbe27d 100644 --- a/source/modules/juce_events/messages/juce_MessageListener.cpp +++ b/source/modules/juce_events/messages/juce_MessageListener.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_events/messages/juce_MessageListener.h b/source/modules/juce_events/messages/juce_MessageListener.h index 2d8ddfcdf..9e787864e 100644 --- a/source/modules/juce_events/messages/juce_MessageListener.h +++ b/source/modules/juce_events/messages/juce_MessageListener.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MESSAGELISTENER_H_INCLUDED -#define JUCE_MESSAGELISTENER_H_INCLUDED +#pragma once //============================================================================== @@ -73,6 +64,3 @@ private: WeakReference::Master masterReference; friend class WeakReference; }; - - -#endif // JUCE_MESSAGELISTENER_H_INCLUDED diff --git a/source/modules/juce_events/messages/juce_MessageManager.cpp b/source/modules/juce_events/messages/juce_MessageManager.cpp index de042358c..2d9fb60d7 100644 --- a/source/modules/juce_events/messages/juce_MessageManager.cpp +++ b/source/modules/juce_events/messages/juce_MessageManager.cpp @@ -2,37 +2,26 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ MessageManager::MessageManager() noexcept - : quitMessagePosted (false), - quitMessageReceived (false), - messageThreadId (Thread::getCurrentThreadId()), - threadWithLock (0) + : messageThreadId (Thread::getCurrentThreadId()) { if (JUCEApplicationBase::isStandaloneApp()) Thread::setCurrentThreadName ("Juce Message Thread"); @@ -74,7 +63,7 @@ void MessageManager::deleteInstance() //============================================================================== bool MessageManager::MessageBase::post() { - MessageManager* const mm = MessageManager::instance; + auto* mm = MessageManager::instance; if (mm == nullptr || mm->quitMessagePosted || ! postMessageToSystemQueue (this)) { @@ -118,7 +107,7 @@ public: void messageCallback() override { - if (MessageManager* const mm = MessageManager::instance) + if (auto* mm = MessageManager::instance) mm->quitMessageReceived = true; } @@ -148,31 +137,12 @@ void MessageManager::stopDispatchLoop() #endif -//============================================================================== -#if JUCE_COMPILER_SUPPORTS_LAMBDAS -struct AsyncFunction : private MessageManager::MessageBase -{ - AsyncFunction (std::function f) : fn (f) { post(); } - -private: - std::function fn; - void messageCallback() override { fn(); } - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncFunction) -}; - -void MessageManager::callAsync (std::function f) -{ - new AsyncFunction (f); -} -#endif - //============================================================================== class AsyncFunctionCallback : public MessageManager::MessageBase { public: AsyncFunctionCallback (MessageCallbackFunction* const f, void* const param) - : result (nullptr), func (f), parameter (param) + : func (f), parameter (param) {} void messageCallback() override @@ -182,7 +152,7 @@ public: } WaitableEvent finished; - void* volatile result; + void* volatile result = nullptr; private: MessageCallbackFunction* const func; @@ -287,18 +257,26 @@ public: //============================================================================== MessageManagerLock::MessageManagerLock (Thread* const threadToCheck) - : blockingMessage(), locked (attemptLock (threadToCheck, nullptr)) + : blockingMessage(), checker (threadToCheck, nullptr), + locked (attemptLock (threadToCheck != nullptr ? &checker : nullptr)) { } MessageManagerLock::MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) - : blockingMessage(), locked (attemptLock (nullptr, jobToCheckForExitSignal)) + : blockingMessage(), checker (nullptr, jobToCheckForExitSignal), + locked (attemptLock (jobToCheckForExitSignal != nullptr ? &checker : nullptr)) +{ +} + +MessageManagerLock::MessageManagerLock (BailOutChecker& bailOutChecker) + : blockingMessage(), checker (nullptr, nullptr), + locked (attemptLock (&bailOutChecker)) { } -bool MessageManagerLock::attemptLock (Thread* const threadToCheck, ThreadPoolJob* const job) +bool MessageManagerLock::attemptLock (BailOutChecker* bailOutChecker) { - MessageManager* const mm = MessageManager::instance; + auto* mm = MessageManager::instance; if (mm == nullptr) return false; @@ -306,7 +284,7 @@ bool MessageManagerLock::attemptLock (Thread* const threadToCheck, ThreadPoolJob if (mm->currentThreadHasLockedMessageManager()) return true; - if (threadToCheck == nullptr && job == nullptr) + if (bailOutChecker == nullptr) { mm->lockingLock.enter(); } @@ -314,8 +292,7 @@ bool MessageManagerLock::attemptLock (Thread* const threadToCheck, ThreadPoolJob { while (! mm->lockingLock.tryEnter()) { - if ((threadToCheck != nullptr && threadToCheck->threadShouldExit()) - || (job != nullptr && job->shouldExit())) + if (bailOutChecker->shouldAbortAcquiringLock()) return false; Thread::yield(); @@ -332,8 +309,7 @@ bool MessageManagerLock::attemptLock (Thread* const threadToCheck, ThreadPoolJob while (! blockingMessage->lockedEvent.wait (20)) { - if ((threadToCheck != nullptr && threadToCheck->threadShouldExit()) - || (job != nullptr && job->shouldExit())) + if (bailOutChecker != nullptr && bailOutChecker->shouldAbortAcquiringLock()) { blockingMessage->releaseEvent.signal(); blockingMessage = nullptr; @@ -352,7 +328,7 @@ MessageManagerLock::~MessageManagerLock() noexcept { if (blockingMessage != nullptr) { - MessageManager* const mm = MessageManager::instance; + auto* mm = MessageManager::instance; jassert (mm == nullptr || mm->currentThreadHasLockedMessageManager()); @@ -367,6 +343,19 @@ MessageManagerLock::~MessageManagerLock() noexcept } } +//============================================================================== +MessageManagerLock::ThreadChecker::ThreadChecker (Thread* const threadToUse, + ThreadPoolJob* const threadJobToUse) + : threadToCheck (threadToUse), job (threadJobToUse) +{ +} + +bool MessageManagerLock::ThreadChecker::shouldAbortAcquiringLock() +{ + return (threadToCheck != nullptr && threadToCheck->threadShouldExit()) + || (job != nullptr && job->shouldExit()); +} + //============================================================================== JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI(); JUCE_API void JUCE_CALLTYPE initialiseJuce_GUI() diff --git a/source/modules/juce_events/messages/juce_MessageManager.h b/source/modules/juce_events/messages/juce_MessageManager.h index fa7893d1a..e0734f8e3 100644 --- a/source/modules/juce_events/messages/juce_MessageManager.h +++ b/source/modules/juce_events/messages/juce_MessageManager.h @@ -2,40 +2,35 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MESSAGEMANAGER_H_INCLUDED -#define JUCE_MESSAGEMANAGER_H_INCLUDED +#pragma once class MessageManagerLock; class ThreadPoolJob; class ActionListener; class ActionBroadcaster; +//============================================================================== +#if JUCE_MODULE_AVAILABLE_juce_opengl +class OpenGLContext; +#endif //============================================================================== /** See MessageManager::callFunctionOnMessageThread() for use of this function type. */ @@ -96,12 +91,12 @@ public: #endif //============================================================================== - #if JUCE_COMPILER_SUPPORTS_LAMBDAS - /** Asynchronously invokes a function or C++11 lambda on the message thread. - Internally this uses the CallbackMessage class to invoke the callback. - */ - static void callAsync (std::function); - #endif + /** Asynchronously invokes a function or C++11 lambda on the message thread. */ + template + static void callAsync (FunctionType functionToCall) + { + new AsyncCallInvoker (functionToCall); + } /** Calls a function using the message-thread. @@ -208,9 +203,9 @@ private: friend class MessageManagerLock; ScopedPointer broadcaster; - bool quitMessagePosted, quitMessageReceived; + bool quitMessagePosted = false, quitMessageReceived = false; Thread::ThreadID messageThreadId; - Thread::ThreadID volatile threadWithLock; + Thread::ThreadID volatile threadWithLock = {}; CriticalSection lockingLock; static bool postMessageToSystemQueue (MessageBase*); @@ -219,6 +214,16 @@ private: static void doPlatformSpecificShutdown(); static bool dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages); + template + struct AsyncCallInvoker : public MessageBase + { + AsyncCallInvoker (FunctionType f) : callback (f) { post(); } + void messageCallback() override { callback(); } + FunctionType callback; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncCallInvoker) + }; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessageManager) }; @@ -313,6 +318,22 @@ public: */ MessageManagerLock (ThreadPoolJob* jobToCheckForExitSignal); + //============================================================================== + struct BailOutChecker + { + virtual ~BailOutChecker() {} + + /** Return true if acquiring the lock should be aborted. */ + virtual bool shouldAbortAcquiringLock() = 0; + }; + + /** This is an abstraction of the other constructors. You can pass this constructor + a functor which is periodically checked if attempting the lock should be aborted. + + See the MessageManagerLock (Thread*) constructor for details on how this works. + */ + MessageManagerLock (BailOutChecker&); + //============================================================================== /** Releases the current thread's lock on the message manager. @@ -332,12 +353,26 @@ private: class BlockingMessage; friend class ReferenceCountedObjectPtr; ReferenceCountedObjectPtr blockingMessage; + + struct ThreadChecker : BailOutChecker + { + ThreadChecker (Thread* const, ThreadPoolJob* const); + + // Required to supress VS2013 compiler warnings + ThreadChecker& operator= (const ThreadChecker&) = delete; + + bool shouldAbortAcquiringLock() override; + + Thread* const threadToCheck; + ThreadPoolJob* const job; + }; + + //============================================================================== + ThreadChecker checker; bool locked; - bool attemptLock (Thread*, ThreadPoolJob*); + //============================================================================== + bool attemptLock (BailOutChecker*); JUCE_DECLARE_NON_COPYABLE (MessageManagerLock) }; - - -#endif // JUCE_MESSAGEMANAGER_H_INCLUDED diff --git a/source/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h b/source/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h index 6d60bd483..37d181e01 100644 --- a/source/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h +++ b/source/modules/juce_events/messages/juce_MountedVolumeListChangeDetector.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MOUNTEDVOLUMELISTCHANGEDETECTOR_H_INCLUDED -#define JUCE_MOUNTEDVOLUMELISTCHANGEDETECTOR_H_INCLUDED +#pragma once #if JUCE_MAC || JUCE_WINDOWS || defined (DOXYGEN) @@ -61,5 +52,3 @@ private: }; #endif - -#endif // JUCE_MOUNTEDVOLUMELISTCHANGEDETECTOR_H_INCLUDED diff --git a/source/modules/juce_events/messages/juce_NotificationType.h b/source/modules/juce_events/messages/juce_NotificationType.h index c8fdbabde..1ad3f35db 100644 --- a/source/modules/juce_events/messages/juce_NotificationType.h +++ b/source/modules/juce_events/messages/juce_NotificationType.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_NOTIFICATIONTYPE_H_INCLUDED -#define JUCE_NOTIFICATIONTYPE_H_INCLUDED +#pragma once //============================================================================== /** @@ -43,6 +34,3 @@ enum NotificationType sendNotificationSync, /**< Requests a synchronous notification. */ sendNotificationAsync, /**< Requests an asynchronous notification. */ }; - - -#endif // JUCE_NOTIFICATIONTYPE_H_INCLUDED diff --git a/source/modules/juce_events/native/juce_ScopedXLock.h b/source/modules/juce_events/native/juce_ScopedXLock.h deleted file mode 100644 index c48bd2379..000000000 --- a/source/modules/juce_events/native/juce_ScopedXLock.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2016 - 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. - - ============================================================================== -*/ - -#ifndef JUCE_SCOPEDXLOCK_H_INCLUDED -#define JUCE_SCOPEDXLOCK_H_INCLUDED - - -//============================================================================== -#if JUCE_LINUX || DOXYGEN - -/** A handy class that uses XLockDisplay and XUnlockDisplay to lock the X server - using RAII (Only available in Linux!). -*/ -class ScopedXLock -{ -public: - /** Creating a ScopedXLock object locks the X display. - This uses XLockDisplay() to grab the display that Juce is using. - */ - ScopedXLock(); - - /** Deleting a ScopedXLock object unlocks the X display. - This calls XUnlockDisplay() to release the lock. - */ - ~ScopedXLock(); -}; - -#endif -#endif // JUCE_SCOPEDXLOCK_H_INCLUDED diff --git a/source/modules/juce_events/native/juce_android_Messaging.cpp b/source/modules/juce_events/native/juce_android_Messaging.cpp index e4bc45251..35a2be5af 100644 --- a/source/modules/juce_events/native/juce_android_Messaging.cpp +++ b/source/modules/juce_events/native/juce_android_Messaging.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -32,7 +24,7 @@ void MessageManager::doPlatformSpecificInitialisation() {} void MessageManager::doPlatformSpecificShutdown() {} //============================================================================== -bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages) +bool MessageManager::dispatchNextMessageOnSystemQueue (const bool) { Logger::outputDebugString ("*** Modal loops are not possible in Android!! Exiting..."); exit (1); @@ -48,7 +40,7 @@ bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* cons return true; } -JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (JNIEnv* env, jobject activity, jlong value)) +JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (JNIEnv* env, jobject, jlong value)) { setEnv (env); diff --git a/source/modules/juce_events/native/juce_ios_MessageManager.mm b/source/modules/juce_events/native/juce_ios_MessageManager.mm index ba088bef0..cf5ce1b5a 100644 --- a/source/modules/juce_events/native/juce_ios_MessageManager.mm +++ b/source/modules/juce_events/native/juce_ios_MessageManager.mm @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_events/native/juce_linux_EventLoop.h b/source/modules/juce_events/native/juce_linux_EventLoop.h new file mode 100644 index 000000000..46df2bdfd --- /dev/null +++ b/source/modules/juce_events/native/juce_linux_EventLoop.h @@ -0,0 +1,52 @@ +/* + ============================================================================== + + 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. + + The code included in this file is provided 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. + + 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 + +namespace LinuxEventLoop +{ + struct CallbackFunctionBase + { + virtual ~CallbackFunctionBase() {} + virtual bool operator()(int fd) = 0; + bool active = true; + }; + + template + struct CallbackFunction : public CallbackFunctionBase + { + FdCallbackFunction callback; + + CallbackFunction (FdCallbackFunction c) : callback (c) {} + + bool operator() (int fd) override { return callback (fd); } + }; + + template + void setWindowSystemFd (int fd, FdCallbackFunction readCallback) + { + setWindowSystemFdInternal (fd, new CallbackFunction (readCallback)); + } + void removeWindowSystemFd() noexcept; + + void setWindowSystemFdInternal (int fd, CallbackFunctionBase* readCallback) noexcept; +} diff --git a/source/modules/juce_events/native/juce_linux_Messaging.cpp b/source/modules/juce_events/native/juce_linux_Messaging.cpp index ad18da391..0a8834975 100644 --- a/source/modules/juce_events/native/juce_linux_Messaging.cpp +++ b/source/modules/juce_events/native/juce_linux_Messaging.cpp @@ -2,138 +2,133 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#if JUCE_DEBUG && ! defined (JUCE_DEBUG_XERRORS) - #define JUCE_DEBUG_XERRORS 1 -#endif - -Display* display = nullptr; -Window juce_messageWindowHandle = None; -XContext windowHandleXContext; // This is referenced from Windowing.cpp - -typedef bool (*WindowMessageReceiveCallback) (XEvent&); -WindowMessageReceiveCallback dispatchWindowMessage = nullptr; +#include -typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&); -SelectionRequestCallback handleSelectionRequest = nullptr; - -//============================================================================== -ScopedXLock::ScopedXLock() { if (display != nullptr) XLockDisplay (display); } -ScopedXLock::~ScopedXLock() { if (display != nullptr) XUnlockDisplay (display); } +enum FdType { + INTERNAL_QUEUE_FD, + WINDOW_SYSTEM_FD, + FD_COUNT, +}; //============================================================================== class InternalMessageQueue { public: InternalMessageQueue() - : bytesInSocket (0), - totalEventCount (0) + : fdCount (1), + loopCount (0), + bytesInSocket (0) { int ret = ::socketpair (AF_LOCAL, SOCK_STREAM, 0, fd); ignoreUnused (ret); jassert (ret == 0); + + auto internalQueueCb = [this] (int _fd) + { + if (const MessageManager::MessageBase::Ptr msg = this->popNextMessage (_fd)) + { + JUCE_TRY + { + msg->messageCallback(); + return true; + } + JUCE_CATCH_EXCEPTION + } + return false; + }; + + pfds[INTERNAL_QUEUE_FD].fd = getReadHandle(); + pfds[INTERNAL_QUEUE_FD].events = POLLIN; + readCallback[INTERNAL_QUEUE_FD] = new LinuxEventLoop::CallbackFunction (internalQueueCb); } ~InternalMessageQueue() { - close (fd[0]); - close (fd[1]); + close (getReadHandle()); + close (getWriteHandle()); clearSingletonInstance(); } //============================================================================== - void postMessage (MessageManager::MessageBase* const msg) + void postMessage (MessageManager::MessageBase* const msg) noexcept { - const int maxBytesInSocketQueue = 128; - ScopedLock sl (lock); queue.add (msg); + const int maxBytesInSocketQueue = 128; + if (bytesInSocket < maxBytesInSocketQueue) { - ++bytesInSocket; + bytesInSocket++; ScopedUnlock ul (lock); const unsigned char x = 0xff; - ssize_t bytesWritten = write (fd[0], &x, 1); + ssize_t bytesWritten = write (getWriteHandle(), &x, 1); ignoreUnused (bytesWritten); } } - bool isEmpty() const + void setWindowSystemFd (int _fd, LinuxEventLoop::CallbackFunctionBase* _readCallback) { + jassert (fdCount == 1); + ScopedLock sl (lock); - return queue.size() == 0; + + fdCount = 2; + pfds[WINDOW_SYSTEM_FD].fd = _fd; + pfds[WINDOW_SYSTEM_FD].events = POLLIN; + readCallback[WINDOW_SYSTEM_FD] = _readCallback; + readCallback[WINDOW_SYSTEM_FD]->active = true; } - bool dispatchNextEvent() + void removeWindowSystemFd() { - // This alternates between giving priority to XEvents or internal messages, - // to keep everything running smoothly.. - if ((++totalEventCount & 1) != 0) - return dispatchNextXEvent() || dispatchNextInternalMessage(); + jassert (fdCount == FD_COUNT); - return dispatchNextInternalMessage() || dispatchNextXEvent(); + ScopedLock sl (lock); + + fdCount = 1; + readCallback[WINDOW_SYSTEM_FD]->active = false; } - // Wait for an event (either XEvent, or an internal Message) - bool sleepUntilEvent (const int timeoutMs) + bool dispatchNextEvent() noexcept { - if (! isEmpty()) - return true; - - if (display != nullptr) + for (int counter = 0; counter < fdCount; counter++) { - ScopedXLock xlock; - if (XPending (display)) - return true; + const int i = loopCount++; + loopCount %= fdCount; + if (readCallback[i] != nullptr && readCallback[i]->active) + { + if ((*readCallback[i]) (pfds[i].fd)) + return true; + } } - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = timeoutMs * 1000; - int fd0 = getWaitHandle(); - int fdmax = fd0; - - fd_set readset; - FD_ZERO (&readset); - FD_SET (fd0, &readset); - - if (display != nullptr) - { - ScopedXLock xlock; - int fd1 = XConnectionNumber (display); - FD_SET (fd1, &readset); - fdmax = jmax (fd0, fd1); - } + return false; + } - const int ret = select (fdmax + 1, &readset, 0, 0, &tv); - return (ret > 0); // ret <= 0 if error or timeout + bool sleepUntilEvent (const int timeoutMs) + { + const int pnum = poll (pfds, static_cast (fdCount), timeoutMs); + return (pnum > 0); } //============================================================================== @@ -143,46 +138,16 @@ private: CriticalSection lock; ReferenceCountedArray queue; int fd[2]; + pollfd pfds[FD_COUNT]; + ScopedPointer readCallback[FD_COUNT]; + int fdCount; + int loopCount; int bytesInSocket; - int totalEventCount; - - int getWaitHandle() const noexcept { return fd[1]; } - - static bool setNonBlocking (int handle) - { - int socketFlags = fcntl (handle, F_GETFL, 0); - if (socketFlags == -1) - return false; - - socketFlags |= O_NONBLOCK; - return fcntl (handle, F_SETFL, socketFlags) == 0; - } - - static bool dispatchNextXEvent() - { - if (display == nullptr) - return false; - - XEvent evt; - - { - ScopedXLock xlock; - if (! XPending (display)) - return false; - - XNextEvent (display, &evt); - } - - if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle - && handleSelectionRequest != nullptr) - handleSelectionRequest (evt.xselectionrequest); - else if (evt.xany.window != juce_messageWindowHandle && dispatchWindowMessage != nullptr) - dispatchWindowMessage (evt); - return true; - } + int getWriteHandle() const noexcept { return fd[0]; } + int getReadHandle() const noexcept { return fd[1]; } - MessageManager::MessageBase::Ptr popNextMessage() + MessageManager::MessageBase::Ptr popNextMessage (int _fd) noexcept { const ScopedLock sl (lock); @@ -192,27 +157,12 @@ private: const ScopedUnlock ul (lock); unsigned char x; - ssize_t numBytes = read (fd[1], &x, 1); + ssize_t numBytes = read (_fd, &x, 1); ignoreUnused (numBytes); } return queue.removeAndReturn (0); } - - bool dispatchNextInternalMessage() - { - if (const MessageManager::MessageBase::Ptr msg = popNextMessage()) - { - JUCE_TRY - { - msg->messageCallback(); - return true; - } - JUCE_CATCH_EXCEPTION - } - - return false; - } }; juce_ImplementSingleton_SingleThreaded (InternalMessageQueue) @@ -221,57 +171,7 @@ juce_ImplementSingleton_SingleThreaded (InternalMessageQueue) //============================================================================== namespace LinuxErrorHandling { - static bool errorOccurred = false; static bool keyboardBreakOccurred = false; - static XErrorHandler oldErrorHandler = (XErrorHandler) 0; - static XIOErrorHandler oldIOErrorHandler = (XIOErrorHandler) 0; - - //============================================================================== - // Usually happens when client-server connection is broken - int ioErrorHandler (Display*) - { - DBG ("ERROR: connection to X server broken.. terminating."); - - if (JUCEApplicationBase::isStandaloneApp()) - MessageManager::getInstance()->stopDispatchLoop(); - - errorOccurred = true; - return 0; - } - - int errorHandler (Display* display, XErrorEvent* event) - { - ignoreUnused (display, event); - - #if JUCE_DEBUG_XERRORS - char errorStr[64] = { 0 }; - char requestStr[64] = { 0 }; - - XGetErrorText (display, event->error_code, errorStr, 64); - XGetErrorDatabaseText (display, "XRequest", String (event->request_code).toUTF8(), "Unknown", requestStr, 64); - DBG ("ERROR: X returned " << errorStr << " for operation " << requestStr); - #endif - - return 0; - } - - void installXErrorHandlers() - { - oldIOErrorHandler = XSetIOErrorHandler (ioErrorHandler); - oldErrorHandler = XSetErrorHandler (errorHandler); - } - - void removeXErrorHandlers() - { - if (JUCEApplicationBase::isStandaloneApp()) - { - XSetIOErrorHandler (oldIOErrorHandler); - oldIOErrorHandler = 0; - - XSetErrorHandler (oldErrorHandler); - oldErrorHandler = 0; - } - } //============================================================================== void keyboardBreakSignalHandler (int sig) @@ -297,78 +197,25 @@ void MessageManager::doPlatformSpecificInitialisation() { if (JUCEApplicationBase::isStandaloneApp()) { - // Initialise xlib for multiple thread support - static bool initThreadCalled = false; - - if (! initThreadCalled) - { - if (! XInitThreads()) - { - // This is fatal! Print error and closedown - Logger::outputDebugString ("Failed to initialise xlib thread support."); - Process::terminate(); - return; - } - - initThreadCalled = true; - } - - LinuxErrorHandling::installXErrorHandlers(); LinuxErrorHandling::installKeyboardBreakHandler(); } // Create the internal message queue - InternalMessageQueue::getInstance(); - - // Try to connect to a display - String displayName (getenv ("DISPLAY")); - if (displayName.isEmpty()) - displayName = ":0.0"; - - display = XOpenDisplay (displayName.toUTF8()); - - if (display != nullptr) // This is not fatal! we can run headless. - { - // Create a context to store user data associated with Windows we create - windowHandleXContext = XUniqueContext(); - - // We're only interested in client messages for this window, which are always sent - XSetWindowAttributes swa; - swa.event_mask = NoEventMask; - - // Create our message window (this will never be mapped) - const int screen = DefaultScreen (display); - juce_messageWindowHandle = XCreateWindow (display, RootWindow (display, screen), - 0, 0, 1, 1, 0, 0, InputOnly, - DefaultVisual (display, screen), - CWEventMask, &swa); - } + InternalMessageQueue* queue = InternalMessageQueue::getInstance(); + ignoreUnused (queue); } void MessageManager::doPlatformSpecificShutdown() { InternalMessageQueue::deleteInstance(); - - if (display != nullptr && ! LinuxErrorHandling::errorOccurred) - { - XDestroyWindow (display, juce_messageWindowHandle); - - juce_messageWindowHandle = 0; - display = nullptr; - - LinuxErrorHandling::removeXErrorHandlers(); - } } bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message) { - if (! LinuxErrorHandling::errorOccurred) + if (InternalMessageQueue* queue = InternalMessageQueue::getInstanceWithoutCreating()) { - if (InternalMessageQueue* queue = InternalMessageQueue::getInstanceWithoutCreating()) - { - queue->postMessage (message); - return true; - } + queue->postMessage (message); + return true; } return false; @@ -382,29 +229,38 @@ void MessageManager::broadcastMessage (const String& /* value */) // this function expects that it will NEVER be called simultaneously for two concurrent threads bool MessageManager::dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages) { - while (! LinuxErrorHandling::errorOccurred) + for (;;) { if (LinuxErrorHandling::keyboardBreakOccurred) - { - LinuxErrorHandling::errorOccurred = true; - - if (JUCEApplicationBase::isStandaloneApp()) - Process::terminate(); - - break; - } + JUCEApplicationBase::getInstance()->quit(); if (InternalMessageQueue* queue = InternalMessageQueue::getInstanceWithoutCreating()) { if (queue->dispatchNextEvent()) - return true; - - if (returnIfNoPendingMessages) break; + else if (returnIfNoPendingMessages) + return false; + + // wait for 2000ms for next events if necessary queue->sleepUntilEvent (2000); } } - return false; + return true; +} + +//============================================================================== + + +void LinuxEventLoop::setWindowSystemFdInternal (int fd, LinuxEventLoop::CallbackFunctionBase* readCallback) noexcept +{ + if (InternalMessageQueue* queue = InternalMessageQueue::getInstanceWithoutCreating()) + queue->setWindowSystemFd (fd, readCallback); +} + +void LinuxEventLoop::removeWindowSystemFd() noexcept +{ + if (InternalMessageQueue* queue = InternalMessageQueue::getInstanceWithoutCreating()) + queue->removeWindowSystemFd(); } diff --git a/source/modules/juce_events/native/juce_mac_MessageManager.mm b/source/modules/juce_events/native/juce_mac_MessageManager.mm index a0f63cc50..95e9a59dc 100644 --- a/source/modules/juce_events/native/juce_mac_MessageManager.mm +++ b/source/modules/juce_events/native/juce_mac_MessageManager.mm @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -60,7 +52,8 @@ public: [[NSDistributedNotificationCenter defaultCenter] addObserver: delegate selector: @selector (broadcastMessageCallback:) name: getBroadcastEventName() - object: nil]; + object: nil + suspensionBehavior: NSNotificationSuspensionBehaviorDeliverImmediately]; } else { @@ -134,7 +127,7 @@ private: static NSApplicationTerminateReply applicationShouldTerminate (id /*self*/, SEL, NSApplication*) { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + if (auto* app = JUCEApplicationBase::getInstance()) { app->systemRequestedQuit(); @@ -152,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; @@ -163,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; @@ -208,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])); } @@ -261,7 +254,6 @@ void MessageManager::runDispatchLoop() static void shutdownNSApp() { [NSApp stop: nil]; - [NSApp activateIgnoringOtherApps: YES]; // (if the app is inactive, it sits there and ignores the quit request until the next time it gets activated) [NSEvent startPeriodicEventsAfterDelay: 0 withPeriod: 0.1]; } diff --git a/source/modules/juce_events/native/juce_osx_MessageQueue.h b/source/modules/juce_events/native/juce_osx_MessageQueue.h index 076135b3c..9a23c15c4 100644 --- a/source/modules/juce_events/native/juce_osx_MessageQueue.h +++ b/source/modules/juce_events/native/juce_osx_MessageQueue.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_OSX_MESSAGEQUEUE_H_INCLUDED -#define JUCE_OSX_MESSAGEQUEUE_H_INCLUDED +#pragma once //============================================================================== /* An internal message pump class used in OSX and iOS. */ @@ -109,5 +100,3 @@ private: static_cast (info)->runLoopCallback(); } }; - -#endif // JUCE_OSX_MESSAGEQUEUE_H_INCLUDED diff --git a/source/modules/juce_events/native/juce_win32_HiddenMessageWindow.h b/source/modules/juce_events/native/juce_win32_HiddenMessageWindow.h index 41f176651..80328fb20 100644 --- a/source/modules/juce_events/native/juce_win32_HiddenMessageWindow.h +++ b/source/modules/juce_events/native/juce_win32_HiddenMessageWindow.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_WIN32_HIDDENMESSAGEWINDOW_H_INCLUDED -#define JUCE_WIN32_HIDDENMESSAGEWINDOW_H_INCLUDED +#pragma once //============================================================================== class HiddenMessageWindow @@ -139,5 +130,3 @@ private: systemDeviceChanged(); } }; - -#endif // JUCE_WIN32_HIDDENMESSAGEWINDOW_H_INCLUDED diff --git a/source/modules/juce_events/native/juce_win32_Messaging.cpp b/source/modules/juce_events/native/juce_win32_Messaging.cpp index f7e8a0576..f55e5401a 100644 --- a/source/modules/juce_events/native/juce_win32_Messaging.cpp +++ b/source/modules/juce_events/native/juce_win32_Messaging.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -112,6 +104,10 @@ namespace WindowsMessageHelpers } } +#if JUCE_MODULE_AVAILABLE_juce_gui_extra +LRESULT juce_offerEventToActiveXControl (::MSG&); +#endif + //============================================================================== bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages) { @@ -123,6 +119,11 @@ bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPend if (GetMessage (&m, (HWND) 0, 0, 0) >= 0) { + #if JUCE_MODULE_AVAILABLE_juce_gui_extra + if (juce_offerEventToActiveXControl (m) != S_FALSE) + return true; + #endif + if (m.message == customMessageID && m.hwnd == juce_messageWindowHandle) { dispatchMessageFromLParam (m.lParam); @@ -174,7 +175,7 @@ void MessageManager::broadcastMessage (const String& value) data.lpData = (void*) localCopy.toUTF32().getAddress(); DWORD_PTR result; - SendMessageTimeout (windows.getUnchecked(i), WM_COPYDATA, + SendMessageTimeout (windows.getUnchecked (i), WM_COPYDATA, (WPARAM) juce_messageWindowHandle, (LPARAM) &data, SMTO_BLOCK | SMTO_ABORTIFHUNG, 8000, &result); diff --git a/source/modules/juce_events/native/juce_win32_WinRTWrapper.cpp b/source/modules/juce_events/native/juce_win32_WinRTWrapper.cpp new file mode 100644 index 000000000..39cb99cae --- /dev/null +++ b/source/modules/juce_events/native/juce_win32_WinRTWrapper.cpp @@ -0,0 +1,23 @@ +/* + ============================================================================== + + 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. + + The code included in this file is provided 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. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +juce_ImplementSingleton (WinRTWrapper) diff --git a/source/modules/juce_events/native/juce_win32_WinRTWrapper.h b/source/modules/juce_events/native/juce_win32_WinRTWrapper.h new file mode 100644 index 000000000..8f2503daa --- /dev/null +++ b/source/modules/juce_events/native/juce_win32_WinRTWrapper.h @@ -0,0 +1,132 @@ +/* + ============================================================================== + + 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. + + The code included in this file is provided 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. + + 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 WinRTWrapper : public DeletedAtShutdown +{ +public: + juce_DeclareSingleton (WinRTWrapper, true) + + class ScopedHString + { + public: + ScopedHString (String str) + { + if (WinRTWrapper::getInstance()->isInitialised()) + WinRTWrapper::getInstance()->createHString (str.toWideCharPointer(), + static_cast (str.length()), + &hstr); + } + + ~ScopedHString() + { + if (WinRTWrapper::getInstance()->isInitialised() && hstr != nullptr) + WinRTWrapper::getInstance()->deleteHString (hstr); + } + + HSTRING get() const noexcept + { + return hstr; + } + + private: + HSTRING hstr = nullptr; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScopedHString) + }; + + ~WinRTWrapper() + { + if (winRTHandle != nullptr) + ::FreeLibrary (winRTHandle); + } + + String hStringToString (HSTRING hstr) + { + const wchar_t* str = nullptr; + if (isInitialised()) + { + str = getHStringRawBuffer (hstr, nullptr); + if (str != nullptr) + return String (str); + } + + return {}; + } + + bool isInitialised() const noexcept + { + return initialised; + } + + template + ComSmartPtr getWRLFactory (const wchar_t* runtimeClassID) + { + ComSmartPtr comPtr; + + if (isInitialised()) + { + ScopedHString classID (runtimeClassID); + if (classID.get() != nullptr) + roGetActivationFactory (classID.get(), __uuidof (ComClass), (void**) comPtr.resetAndGetPointerAddress()); + } + + return comPtr; + } + +private: + WinRTWrapper() + { + winRTHandle = ::LoadLibraryA ("api-ms-win-core-winrt-l1-1-0"); + if (winRTHandle == nullptr) + return; + + roInitialize = (RoInitializeFuncPtr) ::GetProcAddress (winRTHandle, "RoInitialize"); + createHString = (WindowsCreateStringFuncPtr) ::GetProcAddress (winRTHandle, "WindowsCreateString"); + deleteHString = (WindowsDeleteStringFuncPtr) ::GetProcAddress (winRTHandle, "WindowsDeleteString"); + getHStringRawBuffer = (WindowsGetStringRawBufferFuncPtr) ::GetProcAddress (winRTHandle, "WindowsGetStringRawBuffer"); + roGetActivationFactory = (RoGetActivationFactoryFuncPtr) ::GetProcAddress (winRTHandle, "RoGetActivationFactory"); + + if (roInitialize == nullptr || createHString == nullptr || deleteHString == nullptr + || getHStringRawBuffer == nullptr || roGetActivationFactory == nullptr) + return; + + HRESULT status = roInitialize (1); + initialised = ! (status != S_OK && status != S_FALSE && status != 0x80010106L); + } + + HMODULE winRTHandle = nullptr; + bool initialised = false; + + typedef HRESULT (WINAPI* RoInitializeFuncPtr) (int); + typedef HRESULT (WINAPI* WindowsCreateStringFuncPtr) (LPCWSTR, UINT32, HSTRING*); + typedef HRESULT (WINAPI* WindowsDeleteStringFuncPtr) (HSTRING); + typedef PCWSTR (WINAPI* WindowsGetStringRawBufferFuncPtr) (HSTRING, UINT32*); + typedef HRESULT (WINAPI* RoGetActivationFactoryFuncPtr) (HSTRING, REFIID, void**); + + RoInitializeFuncPtr roInitialize = nullptr; + WindowsCreateStringFuncPtr createHString = nullptr; + WindowsDeleteStringFuncPtr deleteHString = nullptr; + WindowsGetStringRawBufferFuncPtr getHStringRawBuffer = nullptr; + RoGetActivationFactoryFuncPtr roGetActivationFactory = nullptr; +}; diff --git a/source/modules/juce_events/timers/juce_MultiTimer.cpp b/source/modules/juce_events/timers/juce_MultiTimer.cpp index 82639da4e..e9ace0a9d 100644 --- a/source/modules/juce_events/timers/juce_MultiTimer.cpp +++ b/source/modules/juce_events/timers/juce_MultiTimer.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_events/timers/juce_MultiTimer.h b/source/modules/juce_events/timers/juce_MultiTimer.h index 52152d2c3..87848458d 100644 --- a/source/modules/juce_events/timers/juce_MultiTimer.h +++ b/source/modules/juce_events/timers/juce_MultiTimer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MULTITIMER_H_INCLUDED -#define JUCE_MULTITIMER_H_INCLUDED +#pragma once //============================================================================== @@ -128,5 +119,3 @@ private: Timer* getCallback (int) const noexcept; MultiTimer& operator= (const MultiTimer&); }; - -#endif // JUCE_MULTITIMER_H_INCLUDED diff --git a/source/modules/juce_events/timers/juce_Timer.cpp b/source/modules/juce_events/timers/juce_Timer.cpp index 60035de97..da2ea738e 100644 --- a/source/modules/juce_events/timers/juce_Timer.cpp +++ b/source/modules/juce_events/timers/juce_Timer.cpp @@ -2,28 +2,20 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -348,3 +340,27 @@ void JUCE_CALLTYPE Timer::callPendingTimersSynchronously() if (TimerThread::instance != nullptr) TimerThread::instance->callTimersSynchronously(); } + +struct LambdaInvoker : private Timer +{ + LambdaInvoker (int milliseconds, std::function f) : function (f) + { + startTimer (milliseconds); + } + + void timerCallback() override + { + auto f = function; + delete this; + f(); + } + + std::function function; + + JUCE_DECLARE_NON_COPYABLE (LambdaInvoker) +}; + +void JUCE_CALLTYPE Timer::callAfterDelay (int milliseconds, std::function f) +{ + new LambdaInvoker (milliseconds, f); +} diff --git a/source/modules/juce_events/timers/juce_Timer.h b/source/modules/juce_events/timers/juce_Timer.h index f8b9e4701..8a2d52054 100644 --- a/source/modules/juce_events/timers/juce_Timer.h +++ b/source/modules/juce_events/timers/juce_Timer.h @@ -2,34 +2,25 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2016 - ROLI Ltd. + 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/ + JUCE is an open source library subject to commercial or open-source + licensing. - 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 code included in this file is provided 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. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TIMER_H_INCLUDED -#define JUCE_TIMER_H_INCLUDED +#pragma once //============================================================================== @@ -122,6 +113,9 @@ public: */ int getTimerInterval() const noexcept { return timerPeriodMs; } + //============================================================================== + /** Invokes a lambda after a given number of milliseconds. */ + static void JUCE_CALLTYPE callAfterDelay (int milliseconds, std::function functionToCall); //============================================================================== /** For internal use only: invokes any timers that need callbacks. @@ -137,5 +131,3 @@ private: Timer& operator= (const Timer&) JUCE_DELETED_FUNCTION; }; - -#endif // JUCE_TIMER_H_INCLUDED diff --git a/source/modules/juce_graphics/colour/juce_Colour.cpp b/source/modules/juce_graphics/colour/juce_Colour.cpp index 43d99e7cf..ae73b0761 100644 --- a/source/modules/juce_graphics/colour/juce_Colour.cpp +++ b/source/modules/juce_graphics/colour/juce_Colour.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -101,7 +103,7 @@ namespace ColourHelpers if (h < 3.0f) return PixelARGB (alpha, x, intV, (uint8) roundToInt (v * (1.0f - (s * (1.0f - f))))); if (h < 4.0f) return PixelARGB (alpha, x, (uint8) roundToInt (v * (1.0f - s * f)), intV); if (h < 5.0f) return PixelARGB (alpha, (uint8) roundToInt (v * (1.0f - (s * (1.0f - f)))), x, intV); - return PixelARGB (alpha, intV, x, (uint8) roundToInt (v * (1.0f - s * f))); + return PixelARGB (alpha, intV, x, (uint8) roundToInt (v * (1.0f - s * f))); } float hue, saturation, brightness; diff --git a/source/modules/juce_graphics/colour/juce_Colour.h b/source/modules/juce_graphics/colour/juce_Colour.h index 85abc04ef..c72eeeecf 100644 --- a/source/modules/juce_graphics/colour/juce_Colour.h +++ b/source/modules/juce_graphics/colour/juce_Colour.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COLOUR_H_INCLUDED -#define JUCE_COLOUR_H_INCLUDED +#pragma once //============================================================================== @@ -362,6 +363,3 @@ private: //============================================================================== PixelARGB argb; }; - - -#endif // JUCE_COLOUR_H_INCLUDED diff --git a/source/modules/juce_graphics/colour/juce_ColourGradient.cpp b/source/modules/juce_graphics/colour/juce_ColourGradient.cpp index e06e9970b..7e8a63a1b 100644 --- a/source/modules/juce_graphics/colour/juce_ColourGradient.cpp +++ b/source/modules/juce_graphics/colour/juce_ColourGradient.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -43,6 +45,17 @@ ColourGradient::ColourGradient (Colour colour1, const float x1, const float y1, colours.add (ColourPoint (1.0, colour2)); } +ColourGradient::ColourGradient (Colour colour1, Point p1, + Colour colour2, Point p2, + const bool radial) + : point1 (p1), + point2 (p2), + isRadial (radial) +{ + colours.add (ColourPoint (0.0, colour1)); + colours.add (ColourPoint (1.0, colour2)); +} + ColourGradient::~ColourGradient() { } @@ -132,7 +145,7 @@ void ColourGradient::setColour (int index, Colour newColour) noexcept Colour ColourGradient::getColourAtPosition (const double position) const noexcept { - jassert (colours.getReference(0).position == 0); // the first colour specified has to go at position 0 + jassert (colours.getReference(0).position == 0.0); // the first colour specified has to go at position 0 if (position <= 0 || colours.size() <= 1) return colours.getReference(0).colour; @@ -141,12 +154,12 @@ Colour ColourGradient::getColourAtPosition (const double position) const noexcep while (position < colours.getReference(i).position) --i; - const ColourPoint& p1 = colours.getReference (i); + auto& p1 = colours.getReference (i); if (i >= colours.size() - 1) return p1.colour; - const ColourPoint& p2 = colours.getReference (i + 1); + auto& p2 = colours.getReference (i + 1); return p1.colour.interpolatedWith (p2.colour, (float) ((position - p1.position) / (p2.position - p1.position))); } @@ -157,7 +170,7 @@ void ColourGradient::createLookupTable (PixelARGB* const lookupTable, const int JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED // Trying to use this object without setting its coordinates? jassert (colours.size() >= 2); jassert (numEntries > 0); - jassert (colours.getReference(0).position == 0); // The first colour specified has to go at position 0 + jassert (colours.getReference(0).position == 0.0); // The first colour specified has to go at position 0 PixelARGB pix1 (colours.getReference (0).colour.getPixelARGB()); int index = 0; diff --git a/source/modules/juce_graphics/colour/juce_ColourGradient.h b/source/modules/juce_graphics/colour/juce_ColourGradient.h index 542985b9c..455c6c626 100644 --- a/source/modules/juce_graphics/colour/juce_ColourGradient.h +++ b/source/modules/juce_graphics/colour/juce_ColourGradient.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COLOURGRADIENT_H_INCLUDED -#define JUCE_COLOURGRADIENT_H_INCLUDED +#pragma once //============================================================================== @@ -57,6 +58,27 @@ public: Colour colour2, float x2, float y2, bool isRadial); + /** Creates a gradient object. + + point1 is the location to draw with colour1. Likewise point2 is where + colour2 should be. In between them there's a gradient. + + If isRadial is true, the colours form a circular gradient with point1 at + its centre. + + The alpha transparencies of the colours are used, so note that + if you blend from transparent to a solid colour, the RGB of the transparent + colour will become visible in parts of the gradient. e.g. blending + from Colour::transparentBlack to Colours::white will produce a + muddy grey colour midway, but Colour::transparentWhite to Colours::white + will be white all the way across. + + @see ColourGradient + */ + ColourGradient (Colour colour1, Point point1, + Colour colour2, Point point2, + bool isRadial); + /** Creates an uninitialised gradient. If you use this constructor instead of the other one, be sure to set all the @@ -176,6 +198,3 @@ private: JUCE_LEAK_DETECTOR (ColourGradient) }; - - -#endif // JUCE_COLOURGRADIENT_H_INCLUDED diff --git a/source/modules/juce_graphics/colour/juce_Colours.cpp b/source/modules/juce_graphics/colour/juce_Colours.cpp index f79d52852..375ab4e3e 100644 --- a/source/modules/juce_graphics/colour/juce_Colours.cpp +++ b/source/modules/juce_graphics/colour/juce_Colours.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/colour/juce_Colours.h b/source/modules/juce_graphics/colour/juce_Colours.h index 86f382879..1c8db415f 100644 --- a/source/modules/juce_graphics/colour/juce_Colours.h +++ b/source/modules/juce_graphics/colour/juce_Colours.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COLOURS_H_INCLUDED -#define JUCE_COLOURS_H_INCLUDED +#pragma once //============================================================================== @@ -103,5 +104,3 @@ private: JUCE_DECLARE_NON_COPYABLE (Colours) }; - -#endif // JUCE_COLOURS_H_INCLUDED diff --git a/source/modules/juce_graphics/colour/juce_FillType.cpp b/source/modules/juce_graphics/colour/juce_FillType.cpp index 6c166689e..ec565aad6 100644 --- a/source/modules/juce_graphics/colour/juce_FillType.cpp +++ b/source/modules/juce_graphics/colour/juce_FillType.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -63,7 +65,6 @@ FillType& FillType::operator= (const FillType& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS FillType::FillType (FillType&& other) noexcept : colour (other.colour), gradient (other.gradient.release()), @@ -82,7 +83,6 @@ FillType& FillType::operator= (FillType&& other) noexcept transform = other.transform; return *this; } -#endif FillType::~FillType() noexcept { diff --git a/source/modules/juce_graphics/colour/juce_FillType.h b/source/modules/juce_graphics/colour/juce_FillType.h index 28effc0f4..eecb9a44f 100644 --- a/source/modules/juce_graphics/colour/juce_FillType.h +++ b/source/modules/juce_graphics/colour/juce_FillType.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILLTYPE_H_INCLUDED -#define JUCE_FILLTYPE_H_INCLUDED +#pragma once //============================================================================== @@ -64,10 +65,11 @@ public: /** Makes a copy of another FillType. */ FillType& operator= (const FillType&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ FillType (FillType&&) noexcept; + + /** Move assignment operator */ FillType& operator= (FillType&&) noexcept; - #endif /** Destructor. */ ~FillType() noexcept; @@ -144,6 +146,3 @@ public: private: JUCE_LEAK_DETECTOR (FillType) }; - - -#endif // JUCE_FILLTYPE_H_INCLUDED diff --git a/source/modules/juce_graphics/colour/juce_PixelFormats.h b/source/modules/juce_graphics/colour/juce_PixelFormats.h index 0666dd79f..9be9ba09c 100644 --- a/source/modules/juce_graphics/colour/juce_PixelFormats.h +++ b/source/modules/juce_graphics/colour/juce_PixelFormats.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PIXELFORMATS_H_INCLUDED -#define JUCE_PIXELFORMATS_H_INCLUDED +#pragma once //============================================================================== @@ -752,5 +753,3 @@ private: #if JUCE_MSVC #pragma pack (pop) #endif - -#endif // JUCE_PIXELFORMATS_H_INCLUDED diff --git a/source/modules/juce_graphics/contexts/juce_GraphicsContext.cpp b/source/modules/juce_graphics/contexts/juce_GraphicsContext.cpp index 4f3df5245..cf527a6ef 100644 --- a/source/modules/juce_graphics/contexts/juce_GraphicsContext.cpp +++ b/source/modules/juce_graphics/contexts/juce_GraphicsContext.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -365,8 +367,8 @@ void Graphics::fillRectList (const RectangleList& rectangles) const void Graphics::fillRectList (const RectangleList& rects) const { - for (const Rectangle* r = rects.begin(), * const e = rects.end(); r != e; ++r) - context.fillRect (*r, false); + for (auto& r : rects) + context.fillRect (r, false); } void Graphics::setPixel (int x, int y) const diff --git a/source/modules/juce_graphics/contexts/juce_GraphicsContext.h b/source/modules/juce_graphics/contexts/juce_GraphicsContext.h index cb9f92e8d..ac2c9ce1b 100644 --- a/source/modules/juce_graphics/contexts/juce_GraphicsContext.h +++ b/source/modules/juce_graphics/contexts/juce_GraphicsContext.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_GRAPHICSCONTEXT_H_INCLUDED -#define JUCE_GRAPHICSCONTEXT_H_INCLUDED +#pragma once //============================================================================== @@ -100,10 +101,6 @@ public: //============================================================================== /** Changes the font to use for subsequent text-drawing functions. - - Note there's also a setFont (float, int) method to quickly change the size and - style of the current font. - @see drawSingleLineText, drawMultiLineText, drawText, drawFittedText */ void setFont (const Font& newFont); @@ -751,6 +748,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Graphics) }; - - -#endif // JUCE_GRAPHICSCONTEXT_H_INCLUDED diff --git a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h index 30a305e38..92ca19439 100644 --- a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h +++ b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsContext.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LOWLEVELGRAPHICSCONTEXT_H_INCLUDED -#define JUCE_LOWLEVELGRAPHICSCONTEXT_H_INCLUDED +#pragma once //============================================================================== @@ -96,6 +97,3 @@ public: virtual void drawGlyph (int glyphNumber, const AffineTransform&) = 0; virtual bool drawTextLayout (const AttributedString&, const Rectangle&) { return false; } }; - - -#endif // JUCE_LOWLEVELGRAPHICSCONTEXT_H_INCLUDED diff --git a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp index 3b7c1cf72..a9900f03a 100644 --- a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp +++ b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -200,7 +202,7 @@ void LowLevelGraphicsPostScriptRenderer::writeClip() int itemsOnLine = 0; - for (const Rectangle* i = stateStack.getLast()->clip.begin(), * const e = stateStack.getLast()->clip.end(); i != e; ++i) + for (auto& i : stateStack.getLast()->clip) { if (++itemsOnLine == 6) { @@ -208,8 +210,8 @@ void LowLevelGraphicsPostScriptRenderer::writeClip() out << '\n'; } - out << i->getX() << ' ' << -i->getY() << ' ' - << i->getWidth() << ' ' << -i->getHeight() << " pr "; + out << i.getX() << ' ' << -i.getY() << ' ' + << i.getWidth() << ' ' << -i.getHeight() << " pr "; } out << "endclip\n"; @@ -482,7 +484,7 @@ void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, co out << "newpath "; int itemsOnLine = 0; - for (const Rectangle* i = imageClip.begin(), * const e = imageClip.end(); i != e; ++i) + for (auto& i : imageClip) { if (++itemsOnLine == 6) { @@ -490,7 +492,7 @@ void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, co itemsOnLine = 0; } - out << i->getX() << ' ' << i->getY() << ' ' << i->getWidth() << ' ' << i->getHeight() << " pr "; + out << i.getX() << ' ' << i.getY() << ' ' << i.getWidth() << ' ' << i.getHeight() << " pr "; } out << " clip newpath\n"; diff --git a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h index 94364f6ba..463df4dba 100644 --- a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h +++ b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_H_INCLUDED -#define JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_H_INCLUDED +#pragma once //============================================================================== @@ -115,7 +116,3 @@ protected: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LowLevelGraphicsPostScriptRenderer) }; - - - -#endif // JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_H_INCLUDED diff --git a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index 535f74e78..c88411371 100644 --- a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h index 14f14a628..648970f91 100644 --- a/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h +++ b/source/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_H_INCLUDED -#define JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_H_INCLUDED +#pragma once //============================================================================== @@ -51,6 +52,3 @@ public: private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LowLevelGraphicsSoftwareRenderer) }; - - -#endif // JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_H_INCLUDED diff --git a/source/modules/juce_graphics/effects/juce_DropShadowEffect.cpp b/source/modules/juce_graphics/effects/juce_DropShadowEffect.cpp index 2a2eaa0c4..5e68ac0df 100644 --- a/source/modules/juce_graphics/effects/juce_DropShadowEffect.cpp +++ b/source/modules/juce_graphics/effects/juce_DropShadowEffect.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/effects/juce_DropShadowEffect.h b/source/modules/juce_graphics/effects/juce_DropShadowEffect.h index f8b0d8c68..9fefe9a36 100644 --- a/source/modules/juce_graphics/effects/juce_DropShadowEffect.h +++ b/source/modules/juce_graphics/effects/juce_DropShadowEffect.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DROPSHADOWEFFECT_H_INCLUDED -#define JUCE_DROPSHADOWEFFECT_H_INCLUDED +#pragma once //============================================================================== @@ -96,7 +97,7 @@ public: //============================================================================== /** @internal */ - void applyEffect (Image& sourceImage, Graphics& destContext, float scaleFactor, float alpha); + void applyEffect (Image& sourceImage, Graphics& destContext, float scaleFactor, float alpha) override; private: @@ -105,6 +106,3 @@ private: JUCE_LEAK_DETECTOR (DropShadowEffect) }; - - -#endif // JUCE_DROPSHADOWEFFECT_H_INCLUDED diff --git a/source/modules/juce_graphics/effects/juce_GlowEffect.cpp b/source/modules/juce_graphics/effects/juce_GlowEffect.cpp index 83a8d7578..e3af9ed03 100644 --- a/source/modules/juce_graphics/effects/juce_GlowEffect.cpp +++ b/source/modules/juce_graphics/effects/juce_GlowEffect.cpp @@ -2,41 +2,36 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -GlowEffect::GlowEffect() - : radius (2.0f), - colour (Colours::white) -{ -} - -GlowEffect::~GlowEffect() -{ -} +GlowEffect::GlowEffect() {} +GlowEffect::~GlowEffect() {} -void GlowEffect::setGlowProperties (const float newRadius, - Colour newColour) +void GlowEffect::setGlowProperties (float newRadius, Colour newColour, Point pos) { radius = newRadius; colour = newColour; + offset = pos; } void GlowEffect::applyEffect (Image& image, Graphics& g, float scaleFactor, float alpha) @@ -51,8 +46,8 @@ void GlowEffect::applyEffect (Image& image, Graphics& g, float scaleFactor, floa blurKernel.applyToImage (temp, image, image.getBounds()); g.setColour (colour.withMultipliedAlpha (alpha)); - g.drawImageAt (temp, 0, 0, true); + g.drawImageAt (temp, offset.x, offset.y, true); g.setOpacity (alpha); - g.drawImageAt (image, 0, 0, false); + g.drawImageAt (image, offset.x, offset.y, false); } diff --git a/source/modules/juce_graphics/effects/juce_GlowEffect.h b/source/modules/juce_graphics/effects/juce_GlowEffect.h index df2fa3edf..248951682 100644 --- a/source/modules/juce_graphics/effects/juce_GlowEffect.h +++ b/source/modules/juce_graphics/effects/juce_GlowEffect.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_GLOWEFFECT_H_INCLUDED -#define JUCE_GLOWEFFECT_H_INCLUDED +#pragma once //============================================================================== @@ -39,7 +40,6 @@ class JUCE_API GlowEffect : public ImageEffectFilter public: //============================================================================== /** Creates a default 'glow' effect. - To customise its appearance, use the setGlowProperties() method. */ GlowEffect(); @@ -55,20 +55,19 @@ public: opacity). */ void setGlowProperties (float newRadius, - Colour newColour); + Colour newColour, + Point offset = {}); //============================================================================== /** @internal */ - void applyEffect (Image& sourceImage, Graphics& destContext, float scaleFactor, float alpha); + void applyEffect (Image&, Graphics&, float scaleFactor, float alpha) override; private: //============================================================================== - float radius; - Colour colour; + float radius = 2.0f; + Colour colour { Colours::white }; + Point offset; JUCE_LEAK_DETECTOR (GlowEffect) }; - - -#endif // JUCE_GLOWEFFECT_H_INCLUDED diff --git a/source/modules/juce_graphics/effects/juce_ImageEffectFilter.h b/source/modules/juce_graphics/effects/juce_ImageEffectFilter.h index 84a5aaa03..3d5d11afd 100644 --- a/source/modules/juce_graphics/effects/juce_ImageEffectFilter.h +++ b/source/modules/juce_graphics/effects/juce_ImageEffectFilter.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IMAGEEFFECTFILTER_H_INCLUDED -#define JUCE_IMAGEEFFECTFILTER_H_INCLUDED +#pragma once //============================================================================== @@ -65,5 +66,3 @@ public: virtual ~ImageEffectFilter() {} }; - -#endif // JUCE_IMAGEEFFECTFILTER_H_INCLUDED diff --git a/source/modules/juce_graphics/fonts/juce_AttributedString.cpp b/source/modules/juce_graphics/fonts/juce_AttributedString.cpp index 990e5d9a4..944a9be92 100644 --- a/source/modules/juce_graphics/fonts/juce_AttributedString.cpp +++ b/source/modules/juce_graphics/fonts/juce_AttributedString.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -136,7 +138,6 @@ namespace AttributedString::Attribute::Attribute() noexcept : colour (0xff000000) {} AttributedString::Attribute::~Attribute() noexcept {} -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS AttributedString::Attribute::Attribute (Attribute&& other) noexcept : range (other.range), font (static_cast (other.font)), @@ -151,7 +152,6 @@ AttributedString::Attribute& AttributedString::Attribute::operator= (Attribute&& colour = other.colour; return *this; } -#endif AttributedString::Attribute::Attribute (const Attribute& other) noexcept : range (other.range), @@ -216,7 +216,6 @@ AttributedString& AttributedString::operator= (const AttributedString& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS AttributedString::AttributedString (AttributedString&& other) noexcept : text (static_cast (other.text)), lineSpacing (other.lineSpacing), @@ -237,7 +236,6 @@ AttributedString& AttributedString::operator= (AttributedString&& other) noexcep attributes = static_cast&&> (other.attributes); return *this; } -#endif AttributedString::~AttributedString() noexcept {} diff --git a/source/modules/juce_graphics/fonts/juce_AttributedString.h b/source/modules/juce_graphics/fonts/juce_AttributedString.h index d32010304..98d15a99f 100644 --- a/source/modules/juce_graphics/fonts/juce_AttributedString.h +++ b/source/modules/juce_graphics/fonts/juce_AttributedString.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ATTRIBUTEDSTRING_H_INCLUDED -#define JUCE_ATTRIBUTEDSTRING_H_INCLUDED +#pragma once //============================================================================== @@ -47,10 +48,8 @@ public: AttributedString (const AttributedString&); AttributedString& operator= (const AttributedString&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS AttributedString (AttributedString&&) noexcept; AttributedString& operator= (AttributedString&&) noexcept; - #endif /** Destructor. */ ~AttributedString() noexcept; @@ -154,10 +153,8 @@ public: ~Attribute() noexcept; Attribute (const Attribute&) noexcept; Attribute& operator= (const Attribute&) noexcept; - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Attribute (Attribute&&) noexcept; Attribute& operator= (Attribute&&) noexcept; - #endif /** Creates an attribute that specifies the font and colour for a range of characters. */ Attribute (Range range, const Font& font, Colour colour) noexcept; @@ -206,5 +203,3 @@ private: JUCE_LEAK_DETECTOR (AttributedString) }; - -#endif // JUCE_ATTRIBUTEDSTRING_H_INCLUDED diff --git a/source/modules/juce_graphics/fonts/juce_CustomTypeface.cpp b/source/modules/juce_graphics/fonts/juce_CustomTypeface.cpp index bb869b01e..26d5d9506 100644 --- a/source/modules/juce_graphics/fonts/juce_CustomTypeface.cpp +++ b/source/modules/juce_graphics/fonts/juce_CustomTypeface.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -189,9 +191,9 @@ void CustomTypeface::addGlyph (const juce_wchar character, const Path& path, con void CustomTypeface::addKerningPair (const juce_wchar char1, const juce_wchar char2, const float extraAmount) noexcept { - if (extraAmount != 0) + if (extraAmount != 0.0f) { - if (GlyphInfo* const g = findGlyph (char1, true)) + if (auto* g = findGlyph (char1, true)) g->addKerningPair (char2, extraAmount); else jassertfalse; // can only add kerning pairs for characters that exist! @@ -227,7 +229,7 @@ void CustomTypeface::addGlyphsFromOtherTypeface (Typeface& typefaceToCopy, juce_ for (int i = 0; i < numCharacters; ++i) { - const juce_wchar c = (juce_wchar) (characterStartIndex + i); + const juce_wchar c = (juce_wchar) (characterStartIndex + static_cast (i)); Array glyphIndexes; Array offsets; diff --git a/source/modules/juce_graphics/fonts/juce_CustomTypeface.h b/source/modules/juce_graphics/fonts/juce_CustomTypeface.h index ff365fd66..0de1862f9 100644 --- a/source/modules/juce_graphics/fonts/juce_CustomTypeface.h +++ b/source/modules/juce_graphics/fonts/juce_CustomTypeface.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CUSTOMTYPEFACE_H_INCLUDED -#define JUCE_CUSTOMTYPEFACE_H_INCLUDED +#pragma once //============================================================================== @@ -160,5 +161,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomTypeface) }; - -#endif // JUCE_CUSTOMTYPEFACE_H_INCLUDED diff --git a/source/modules/juce_graphics/fonts/juce_Font.cpp b/source/modules/juce_graphics/fonts/juce_Font.cpp index 7b7632fb8..8d4360025 100644 --- a/source/modules/juce_graphics/fonts/juce_Font.cpp +++ b/source/modules/juce_graphics/fonts/juce_Font.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -38,14 +40,14 @@ namespace FontValues typedef Typeface::Ptr (*GetTypefaceForFont) (const Font&); GetTypefaceForFont juce_getTypefaceForFont = nullptr; -float Font::getDefaultMinimumHorizontalScaleFactor() noexcept { return FontValues::minimumHorizontalScale; } +float Font::getDefaultMinimumHorizontalScaleFactor() noexcept { return FontValues::minimumHorizontalScale; } void Font::setDefaultMinimumHorizontalScaleFactor (float newValue) noexcept { FontValues::minimumHorizontalScale = newValue; } //============================================================================== class TypefaceCache : private DeletedAtShutdown { public: - TypefaceCache() : counter (0) + TypefaceCache() { setSize (10); } @@ -77,8 +79,8 @@ public: { const ScopedReadLock slr (lock); - const String faceName (font.getTypefaceName()); - const String faceStyle (font.getTypefaceStyle()); + auto faceName = font.getTypefaceName(); + auto faceStyle = font.getTypefaceStyle(); jassert (faceName.isNotEmpty()); @@ -98,11 +100,11 @@ public: const ScopedWriteLock slw (lock); int replaceIndex = 0; - size_t bestLastUsageCount = std::numeric_limits::max(); + auto bestLastUsageCount = std::numeric_limits::max(); for (int i = faces.size(); --i >= 0;) { - const size_t lu = faces.getReference(i).lastUsageCount; + auto lu = faces.getReference(i).lastUsageCount; if (bestLastUsageCount > lu) { @@ -111,7 +113,7 @@ public: } } - CachedFace& face = faces.getReference (replaceIndex); + auto& face = faces.getReference (replaceIndex); face.typefaceName = faceName; face.typefaceStyle = faceStyle; face.lastUsageCount = ++counter; @@ -147,7 +149,7 @@ private: ReadWriteLock lock; Array faces; - size_t counter; + size_t counter = 0; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TypefaceCache) }; @@ -179,8 +181,7 @@ public: : typeface (TypefaceCache::getInstance()->defaultFace), typefaceName (Font::getDefaultSansSerifFontName()), typefaceStyle (Font::getDefaultStyle()), - height (FontValues::defaultFontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline (false) + height (FontValues::defaultFontHeight) { } @@ -188,7 +189,7 @@ public: : typefaceName (Font::getDefaultSansSerifFontName()), typefaceStyle (FontStyleHelpers::getStyleName (styleFlags)), height (fontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline ((styleFlags & underlined) != 0) + underline ((styleFlags & underlined) != 0) { if (styleFlags == plain) typeface = TypefaceCache::getInstance()->defaultFace; @@ -198,15 +199,14 @@ public: : typefaceName (name), typefaceStyle (FontStyleHelpers::getStyleName (styleFlags)), height (fontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline ((styleFlags & underlined) != 0) + underline ((styleFlags & underlined) != 0) { if (styleFlags == plain && typefaceName.isEmpty()) typeface = TypefaceCache::getInstance()->defaultFace; } SharedFontInternal (const String& name, const String& style, float fontHeight) noexcept - : typefaceName (name), typefaceStyle (style), height (fontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline (false) + : typefaceName (name), typefaceStyle (style), height (fontHeight) { if (typefaceName.isEmpty()) typefaceName = Font::getDefaultSansSerifFontName(); @@ -216,8 +216,7 @@ public: : typeface (face), typefaceName (face->getName()), typefaceStyle (face->getStyle()), - height (FontValues::defaultFontHeight), - horizontalScale (1.0f), kerning (0), ascent (0), underline (false) + height (FontValues::defaultFontHeight) { jassert (typefaceName.isNotEmpty()); } @@ -247,8 +246,8 @@ public: Typeface::Ptr typeface; String typefaceName, typefaceStyle; - float height, horizontalScale, kerning, ascent; - bool underline; + float height, horizontalScale = 1.0f, kerning = 0, ascent = 0; + bool underline = false; }; //============================================================================== @@ -277,7 +276,6 @@ Font& Font::operator= (const Font& other) noexcept return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Font::Font (Font&& other) noexcept : font (static_cast&&> (other.font)) { @@ -288,7 +286,6 @@ Font& Font::operator= (Font&& other) noexcept font = static_cast&&> (other.font); return *this; } -#endif Font::~Font() noexcept { @@ -320,15 +317,10 @@ void Font::checkTypefaceSuitability() //============================================================================== struct FontPlaceholderNames { - FontPlaceholderNames() - : sans (""), - serif (""), - mono (""), - regular ("") - { - } - - String sans, serif, mono, regular; + String sans { "" }, + serif { "" }, + mono { "" }, + regular { "" }; }; const FontPlaceholderNames& getFontPlaceholderNames() @@ -592,14 +584,14 @@ bool Font::isUnderlined() const noexcept { return font->underline; } void Font::setBold (const bool shouldBeBold) { - const int flags = getStyleFlags(); + auto flags = getStyleFlags(); setStyleFlags (shouldBeBold ? (flags | bold) : (flags & ~bold)); } void Font::setItalic (const bool shouldBeItalic) { - const int flags = getStyleFlags(); + auto flags = getStyleFlags(); setStyleFlags (shouldBeItalic ? (flags | italic) : (flags & ~italic)); } @@ -613,7 +605,7 @@ void Font::setUnderline (const bool shouldBeUnderlined) float Font::getAscent() const { - if (font->ascent == 0) + if (font->ascent == 0.0f) font->ascent = getTypeface()->getAscent(); return font->height * font->ascent; @@ -633,9 +625,13 @@ int Font::getStringWidth (const String& text) const float Font::getStringWidthFloat (const String& text) const { - float w = getTypeface()->getStringWidth (text); + // This call isn't thread-safe when there's a message thread running + jassert (MessageManager::getInstanceWithoutCreating() == nullptr + || MessageManager::getInstanceWithoutCreating()->currentThreadHasLockedMessageManager()); - if (font->kerning != 0) + auto w = getTypeface()->getStringWidth (text); + + if (font->kerning != 0.0f) w += font->kerning * text.length(); return w * font->height * font->horizontalScale; @@ -643,16 +639,18 @@ float Font::getStringWidthFloat (const String& text) const void Font::getGlyphPositions (const String& text, Array& glyphs, Array& xOffsets) const { - getTypeface()->getGlyphPositions (text, glyphs, xOffsets); + // This call isn't thread-safe when there's a message thread running + jassert (MessageManager::getInstanceWithoutCreating() == nullptr + || MessageManager::getInstanceWithoutCreating()->currentThreadHasLockedMessageManager()); - const int num = xOffsets.size(); + getTypeface()->getGlyphPositions (text, glyphs, xOffsets); - if (num > 0) + if (auto num = xOffsets.size()) { - const float scale = font->height * font->horizontalScale; - float* const x = xOffsets.getRawDataPointer(); + auto scale = font->height * font->horizontalScale; + auto* x = xOffsets.getRawDataPointer(); - if (font->kerning != 0) + if (font->kerning != 0.0f) { for (int i = 0; i < num; ++i) x[i] = (x[i] + i * font->kerning) * scale; @@ -667,18 +665,16 @@ void Font::getGlyphPositions (const String& text, Array& glyphs, Array& destArray) { - const StringArray names (findAllTypefaceNames()); - - for (int i = 0; i < names.size(); ++i) + for (auto& name : findAllTypefaceNames()) { - const StringArray styles (findAllTypefaceStyles (names[i])); + auto styles = findAllTypefaceStyles (name); String style ("Regular"); if (! styles.contains (style, true)) style = styles[0]; - destArray.add (Font (names[i], style, FontValues::defaultFontHeight)); + destArray.add (Font (name, style, FontValues::defaultFontHeight)); } } diff --git a/source/modules/juce_graphics/fonts/juce_Font.h b/source/modules/juce_graphics/fonts/juce_Font.h index 3fc11bbde..27fb61a97 100644 --- a/source/modules/juce_graphics/fonts/juce_Font.h +++ b/source/modules/juce_graphics/fonts/juce_Font.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FONT_H_INCLUDED -#define JUCE_FONT_H_INCLUDED +#pragma once //============================================================================== @@ -95,10 +96,11 @@ public: */ Font(); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ Font (Font&& other) noexcept; + + /** Move assignment operator */ Font& operator= (Font&& other) noexcept; - #endif /** Copies this font from another one. */ Font& operator= (const Font& other) noexcept; @@ -472,5 +474,3 @@ private: JUCE_LEAK_DETECTOR (Font) }; - -#endif // JUCE_FONT_H_INCLUDED diff --git a/source/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp b/source/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp index c62ef39c8..adf8d7e03 100644 --- a/source/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp +++ b/source/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -40,7 +42,6 @@ PositionedGlyph::PositionedGlyph (const PositionedGlyph& other) { } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS PositionedGlyph::PositionedGlyph (PositionedGlyph&& other) noexcept : font (static_cast (other.font)), character (other.character), glyph (other.glyph), @@ -59,7 +60,6 @@ PositionedGlyph& PositionedGlyph::operator= (PositionedGlyph&& other) noexcept whitespace = other.whitespace; return *this; } -#endif PositionedGlyph::~PositionedGlyph() {} @@ -98,7 +98,7 @@ void PositionedGlyph::createPath (Path& path) const { if (! isWhitespace()) { - if (Typeface* const t = font.getTypeface()) + if (auto* t = font.getTypeface()) { Path p; t->getOutlineForGlyph (glyph, p); @@ -113,7 +113,7 @@ bool PositionedGlyph::hitTest (float px, float py) const { if (getBounds().contains (px, py) && ! isWhitespace()) { - if (Typeface* const t = font.getTypeface()) + if (auto* t = font.getTypeface()) { Path p; t->getOutlineForGlyph (glyph, p); @@ -209,7 +209,7 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font, const int textLen = newGlyphs.size(); glyphs.ensureStorageAllocated (glyphs.size() + textLen); - String::CharPointerType t (text.getCharPointer()); + auto t = text.getCharPointer(); for (int i = 0; i < textLen; ++i) { @@ -251,7 +251,7 @@ int GlyphArrangement::insertEllipsis (const Font& font, const float maxXPos, while (endIndex > startIndex) { - const PositionedGlyph& pg = glyphs.getReference (--endIndex); + auto& pg = glyphs.getReference (--endIndex); xOffset = pg.x; yOffset = pg.y; @@ -301,7 +301,7 @@ void GlyphArrangement::addJustifiedText (const Font& font, while (i < glyphs.size()) { - const PositionedGlyph& pg = glyphs.getReference (i); + auto& pg = glyphs.getReference (i); const juce_wchar c = pg.getCharacter(); if (c == '\r' || c == '\n') @@ -435,7 +435,7 @@ void GlyphArrangement::addLinesWithLineBreaks (const String& text, const Font& f GlyphArrangement ga; ga.addJustifiedText (f, text, x, y, width, layout); - const Rectangle bb (ga.getBoundingBox (0, -1, false)); + auto bb = ga.getBoundingBox (0, -1, false); float dy = y - bb.getY(); @@ -487,7 +487,7 @@ void GlyphArrangement::stretchRangeOfGlyphs (int startIndex, int num, while (--num >= 0) { - PositionedGlyph& pg = glyphs.getReference (startIndex++); + auto& pg = glyphs.getReference (startIndex++); pg.x = xAnchor + (pg.x - xAnchor) * horizontalScaleFactor; pg.font.setHorizontalScale (pg.font.getHorizontalScale() * horizontalScaleFactor); @@ -507,7 +507,7 @@ Rectangle GlyphArrangement::getBoundingBox (int startIndex, int num, cons while (--num >= 0) { - const PositionedGlyph& pg = glyphs.getReference (startIndex++); + auto& pg = glyphs.getReference (startIndex++); if (includeWhitespace || ! pg.isWhitespace()) result = result.getUnion (pg.getBounds()); @@ -524,8 +524,8 @@ void GlyphArrangement::justifyGlyphs (const int startIndex, const int num, if (glyphs.size() > 0 && num > 0) { - const Rectangle bb (getBoundingBox (startIndex, num, ! justification.testFlags (Justification::horizontallyJustified - | Justification::horizontallyCentred))); + auto bb = getBoundingBox (startIndex, num, ! justification.testFlags (Justification::horizontallyJustified + | Justification::horizontallyCentred)); float deltaX = 0.0f, deltaY = 0.0f; if (justification.testFlags (Justification::horizontallyJustified)) deltaX = x - bb.getX(); @@ -593,8 +593,7 @@ void GlyphArrangement::spreadOutLine (const int start, const int num, const floa const float startX = glyphs.getReference (start).getLeft(); const float endX = glyphs.getReference (start + num - 1 - spacesAtEnd).getRight(); - const float extraPaddingBetweenWords - = (targetWidth - (endX - startX)) / (float) numSpaces; + const float extraPaddingBetweenWords = (targetWidth - (endX - startX)) / (float) numSpaces; float deltaX = 0.0f; @@ -766,13 +765,13 @@ void GlyphArrangement::draw (const Graphics& g) const void GlyphArrangement::draw (const Graphics& g, const AffineTransform& transform) const { - LowLevelGraphicsContext& context = g.getInternalContext(); + auto& context = g.getInternalContext(); Font lastFont (context.getFont()); bool needToRestore = false; for (int i = 0; i < glyphs.size(); ++i) { - const PositionedGlyph& pg = glyphs.getReference(i); + auto& pg = glyphs.getReference(i); if (pg.font.isUnderlined()) drawGlyphUnderline (g, pg, i, transform); @@ -802,8 +801,8 @@ void GlyphArrangement::draw (const Graphics& g, const AffineTransform& transform void GlyphArrangement::createPath (Path& path) const { - for (int i = 0; i < glyphs.size(); ++i) - glyphs.getReference (i).createPath (path); + for (auto& g : glyphs) + g.createPath (path); } int GlyphArrangement::findGlyphIndexAt (const float x, const float y) const diff --git a/source/modules/juce_graphics/fonts/juce_GlyphArrangement.h b/source/modules/juce_graphics/fonts/juce_GlyphArrangement.h index 3e3def239..42bcde4ef 100644 --- a/source/modules/juce_graphics/fonts/juce_GlyphArrangement.h +++ b/source/modules/juce_graphics/fonts/juce_GlyphArrangement.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_GLYPHARRANGEMENT_H_INCLUDED -#define JUCE_GLYPHARRANGEMENT_H_INCLUDED +#pragma once //============================================================================== @@ -47,10 +48,11 @@ public: PositionedGlyph (const PositionedGlyph&); PositionedGlyph& operator= (const PositionedGlyph&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ PositionedGlyph (PositionedGlyph&&) noexcept; + + /** Move assignment operator */ PositionedGlyph& operator= (PositionedGlyph&&) noexcept; - #endif ~PositionedGlyph(); @@ -321,6 +323,3 @@ private: JUCE_LEAK_DETECTOR (GlyphArrangement) }; - - -#endif // JUCE_GLYPHARRANGEMENT_H_INCLUDED diff --git a/source/modules/juce_graphics/fonts/juce_TextLayout.cpp b/source/modules/juce_graphics/fonts/juce_TextLayout.cpp index 5d7a4524d..895316607 100644 --- a/source/modules/juce_graphics/fonts/juce_TextLayout.cpp +++ b/source/modules/juce_graphics/fonts/juce_TextLayout.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -48,7 +50,7 @@ TextLayout::Run::Run() noexcept { } -TextLayout::Run::Run (Range range, const int numGlyphsToPreallocate) +TextLayout::Run::Run (Range range, int numGlyphsToPreallocate) : colour (0xff000000), stringRange (range) { glyphs.ensureStorageAllocated (numGlyphsToPreallocate); @@ -94,31 +96,20 @@ Range TextLayout::Line::getLineBoundsX() const noexcept Range range; bool isFirst = true; - for (int i = runs.size(); --i >= 0;) + for (auto* run : runs) { - const Run& run = *runs.getUnchecked(i); - - if (run.glyphs.size() > 0) + for (auto& glyph : run->glyphs) { - float minX = run.glyphs.getReference(0).anchor.x; - float maxX = minX; - - for (int j = run.glyphs.size(); --j >= 0;) - { - const Glyph& glyph = run.glyphs.getReference (j); - const float x = glyph.anchor.x; - minX = jmin (minX, x); - maxX = jmax (maxX, x + glyph.width); - } + Range runRange (glyph.anchor.x, glyph.anchor.x + glyph.width); if (isFirst) { isFirst = false; - range = Range (minX, maxX); + range = runRange; } else { - range = range.getUnionWith (Range (minX, maxX)); + range = range.getUnionWith (runRange); } } } @@ -134,10 +125,10 @@ Range TextLayout::Line::getLineBoundsY() const noexcept Rectangle TextLayout::Line::getLineBounds() const noexcept { - const Range x (getLineBoundsX()), - y (getLineBoundsY()); + auto x = getLineBoundsX(); + auto y = getLineBoundsY(); - return Rectangle (x.getStart(), y.getStart(), x.getLength(), y.getLength()); + return { x.getStart(), y.getStart(), x.getLength(), y.getLength() }; } //============================================================================== @@ -153,7 +144,6 @@ TextLayout::TextLayout (const TextLayout& other) lines.addCopiesOf (other.lines); } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS TextLayout::TextLayout (TextLayout&& other) noexcept : lines (static_cast&&> (other.lines)), width (other.width), height (other.height), @@ -169,7 +159,6 @@ TextLayout& TextLayout::operator= (TextLayout&& other) noexcept justification = other.justification; return *this; } -#endif TextLayout& TextLayout::operator= (const TextLayout& other) { @@ -200,28 +189,40 @@ void TextLayout::addLine (Line* line) lines.add (line); } -void TextLayout::draw (Graphics& g, const Rectangle& area) const +void TextLayout::draw (Graphics& g, Rectangle area) const { - const Point origin (justification.appliedToRectangle (Rectangle (width, getHeight()), area).getPosition()); + auto origin = justification.appliedToRectangle (Rectangle (width, getHeight()), area).getPosition(); - LowLevelGraphicsContext& context = g.getInternalContext(); + auto& context = g.getInternalContext(); - for (int i = 0; i < lines.size(); ++i) + for (auto* line : lines) { - const Line& line = getLine (i); - const Point lineOrigin (origin + line.lineOrigin); + auto lineOrigin = origin + line->lineOrigin; - for (int j = 0; j < line.runs.size(); ++j) + for (auto* run : line->runs) { - const Run& run = *line.runs.getUnchecked (j); - context.setFont (run.font); - context.setFill (run.colour); + context.setFont (run->font); + context.setFill (run->colour); - for (int k = 0; k < run.glyphs.size(); ++k) - { - const Glyph& glyph = run.glyphs.getReference (k); + for (auto& glyph : run->glyphs) context.drawGlyph (glyph.glyphCode, AffineTransform::translation (lineOrigin.x + glyph.anchor.x, lineOrigin.y + glyph.anchor.y)); + + if (run->font.isUnderlined()) + { + Range runExtent; + + for (auto& glyph : run->glyphs) + { + Range glyphRange (glyph.anchor.x, glyph.anchor.x + glyph.width); + + runExtent = runExtent.isEmpty() ? glyphRange + : runExtent.getUnionWith (glyphRange); + } + + const float lineThickness = run->font.getDescent() * 0.3f; + context.fillRect ({ runExtent.getStart() + lineOrigin.x, lineOrigin.y + lineThickness * 2.0f, + runExtent.getLength(), lineThickness }); } } } @@ -289,7 +290,7 @@ namespace TextLayoutHelpers { struct Token { - Token (const String& t, const Font& f, Colour c, const bool whitespace) + Token (const String& t, const Font& f, Colour c, bool whitespace) : text (t), font (f), colour (c), area (font.getStringWidthFloat (t), f.getHeight()), isWhitespace (whitespace), @@ -310,14 +311,14 @@ namespace TextLayoutHelpers struct TokenList { - TokenList() noexcept : totalLines (0) {} + TokenList() noexcept {} void createLayout (const AttributedString& text, TextLayout& layout) { layout.ensureStorageAllocated (totalLines); addTextRuns (text); - layoutRuns (layout.getWidth(), text.getLineSpacing()); + layoutRuns (layout.getWidth(), text.getLineSpacing(), text.getWordWrap()); int charPosition = 0; int lineStartPosition = 0; @@ -330,7 +331,7 @@ namespace TextLayoutHelpers for (int i = 0; i < tokens.size(); ++i) { - const Token& t = *tokens.getUnchecked (i); + auto& t = *tokens.getUnchecked (i); Array newGlyphs; Array xOffsets; @@ -366,19 +367,7 @@ namespace TextLayoutHelpers if (t.isWhitespace || t.isNewLine) ++charPosition; - const Token* const nextToken = tokens [i + 1]; - - if (nextToken == nullptr) // this is the last token - { - addRun (*currentLine, currentRun.release(), t, runStartPosition, charPosition); - currentLine->stringRange = Range (lineStartPosition, charPosition); - - if (! needToSetLineOrigin) - layout.addLine (currentLine.release()); - - needToSetLineOrigin = true; - } - else + if (auto* nextToken = tokens [i + 1]) { if (t.font != nextToken->font || t.colour != nextToken->colour) { @@ -402,6 +391,16 @@ namespace TextLayoutHelpers needToSetLineOrigin = true; } } + else + { + addRun (*currentLine, currentRun.release(), t, runStartPosition, charPosition); + currentLine->stringRange = Range (lineStartPosition, charPosition); + + if (! needToSetLineOrigin) + layout.addLine (currentLine.release()); + + needToSetLineOrigin = true; + } } if ((text.getJustification().getFlags() & (Justification::right | Justification::horizontallyCentred)) != 0) @@ -425,7 +424,7 @@ namespace TextLayoutHelpers static void addRun (TextLayout::Line& glyphLine, TextLayout::Run* glyphRun, const Token& t, const int start, const int end) { - glyphRun->stringRange = Range (start, end); + glyphRun->stringRange = { start, end }; glyphRun->font = t.font; glyphRun->colour = t.colour; glyphLine.ascent = jmax (glyphLine.ascent, t.font.getAscent()); @@ -443,7 +442,7 @@ namespace TextLayoutHelpers void appendText (const String& stringText, const Font& font, Colour colour) { - String::CharPointerType t (stringText.getCharPointer()); + auto t = stringText.getCharPointer(); String currentString; int lastCharType = 0; @@ -478,25 +477,27 @@ namespace TextLayoutHelpers tokens.add (new Token (currentString, font, colour, lastCharType == 2)); } - void layoutRuns (const float maxWidth, const float extraLineSpacing) + void layoutRuns (const float maxWidth, const float extraLineSpacing, const AttributedString::WordWrap wordWrap) { float x = 0, y = 0, h = 0; int i; for (i = 0; i < tokens.size(); ++i) { - Token& t = *tokens.getUnchecked(i); + auto& t = *tokens.getUnchecked(i); t.area.setPosition (x, y); t.line = totalLines; x += t.area.getWidth(); h = jmax (h, t.area.getHeight() + extraLineSpacing); - const Token* const nextTok = tokens[i + 1]; + auto* nextTok = tokens[i + 1]; if (nextTok == nullptr) break; - if (t.isNewLine || ((! nextTok->isWhitespace) && x + nextTok->area.getWidth() > maxWidth)) + const bool tokenTooLarge = (x + nextTok->area.getWidth() > maxWidth); + + if (t.isNewLine || ((! nextTok->isWhitespace) && (tokenTooLarge && wordWrap != AttributedString::none))) { setLastLineHeight (i + 1, h); x = 0; @@ -514,7 +515,7 @@ namespace TextLayoutHelpers { while (--i >= 0) { - Token& tok = *tokens.getUnchecked (i); + auto& tok = *tokens.getUnchecked (i); if (tok.line == totalLines) tok.lineHeight = height; @@ -530,7 +531,7 @@ namespace TextLayoutHelpers for (int i = 0; i < numAttributes; ++i) { - const AttributedString::Attribute& attr = text.getAttribute (i); + auto& attr = text.getAttribute (i); appendText (text.getText().substring (attr.range.getStart(), attr.range.getEnd()), attr.font, attr.colour); @@ -539,7 +540,8 @@ namespace TextLayoutHelpers static String getTrimmedEndIfNotAllWhitespace (const String& s) { - String trimmed (s.trimEnd()); + auto trimmed = s.trimEnd(); + if (trimmed.isEmpty() && s.isNotEmpty()) trimmed = s.replaceCharacters ("\r\n\t", " "); @@ -547,7 +549,7 @@ namespace TextLayoutHelpers } OwnedArray tokens; - int totalLines; + int totalLines = 0; JUCE_DECLARE_NON_COPYABLE (TokenList) }; @@ -562,15 +564,15 @@ void TextLayout::createStandardLayout (const AttributedString& text) void TextLayout::recalculateSize() { - if (lines.size() > 0) + if (! lines.isEmpty()) { - Rectangle bounds (lines.getFirst()->getLineBounds()); + auto bounds = lines.getFirst()->getLineBounds(); - for (int i = lines.size(); --i > 0;) - bounds = bounds.getUnion (lines.getUnchecked(i)->getLineBounds()); + for (auto* line : lines) + bounds = bounds.getUnion (line->getLineBounds()); - for (int i = lines.size(); --i >= 0;) - lines.getUnchecked(i)->lineOrigin.x -= bounds.getX(); + for (auto* line : lines) + line->lineOrigin.x -= bounds.getX(); width = bounds.getWidth(); height = bounds.getHeight(); diff --git a/source/modules/juce_graphics/fonts/juce_TextLayout.h b/source/modules/juce_graphics/fonts/juce_TextLayout.h index 08c5ca182..5a1510e65 100644 --- a/source/modules/juce_graphics/fonts/juce_TextLayout.h +++ b/source/modules/juce_graphics/fonts/juce_TextLayout.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TEXTLAYOUT_H_INCLUDED -#define JUCE_TEXTLAYOUT_H_INCLUDED +#pragma once //============================================================================== @@ -45,10 +46,8 @@ public: TextLayout(); TextLayout (const TextLayout&); TextLayout& operator= (const TextLayout&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS TextLayout (TextLayout&&) noexcept; TextLayout& operator= (TextLayout&&) noexcept; - #endif /** Destructor. */ ~TextLayout(); @@ -84,7 +83,7 @@ public: The position of the text within the rectangle is controlled by the justification flags set in the original AttributedString that was used to create this layout. */ - void draw (Graphics&, const Rectangle& area) const; + void draw (Graphics&, Rectangle area) const; //============================================================================== /** A positioned glyph. */ @@ -192,5 +191,3 @@ private: JUCE_LEAK_DETECTOR (TextLayout) }; - -#endif // JUCE_TEXTLAYOUT_H_INCLUDED diff --git a/source/modules/juce_graphics/fonts/juce_Typeface.cpp b/source/modules/juce_graphics/fonts/juce_Typeface.cpp index 2077cd72c..1ce9a78fd 100644 --- a/source/modules/juce_graphics/fonts/juce_Typeface.cpp +++ b/source/modules/juce_graphics/fonts/juce_Typeface.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/fonts/juce_Typeface.h b/source/modules/juce_graphics/fonts/juce_Typeface.h index e39fa6761..3669fc16a 100644 --- a/source/modules/juce_graphics/fonts/juce_Typeface.h +++ b/source/modules/juce_graphics/fonts/juce_Typeface.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TYPEFACE_H_INCLUDED -#define JUCE_TYPEFACE_H_INCLUDED +#pragma once //============================================================================== @@ -156,6 +157,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Typeface) }; - - -#endif // JUCE_TYPEFACE_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_AffineTransform.cpp b/source/modules/juce_graphics/geometry/juce_AffineTransform.cpp index f58fe3156..b111ed5b1 100644 --- a/source/modules/juce_graphics/geometry/juce_AffineTransform.cpp +++ b/source/modules/juce_graphics/geometry/juce_AffineTransform.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -71,10 +73,10 @@ bool AffineTransform::operator!= (const AffineTransform& other) const noexcept //============================================================================== bool AffineTransform::isIdentity() const noexcept { - return (mat01 == 0) - && (mat02 == 0) - && (mat10 == 0) - && (mat12 == 0) + return (mat01 == 0.0f) + && (mat02 == 0.0f) + && (mat10 == 0.0f) + && (mat12 == 0.0f) && (mat00 == 1.0f) && (mat11 == 1.0f); } @@ -228,7 +230,7 @@ AffineTransform AffineTransform::inverted() const noexcept bool AffineTransform::isSingularity() const noexcept { - return (mat00 * mat11 - mat10 * mat01) == 0; + return (mat00 * mat11 - mat10 * mat01) == 0.0f; } AffineTransform AffineTransform::fromTargetPoints (const float x00, const float y00, @@ -250,8 +252,8 @@ AffineTransform AffineTransform::fromTargetPoints (const float sx1, const float bool AffineTransform::isOnlyTranslation() const noexcept { - return (mat01 == 0) - && (mat10 == 0) + return (mat01 == 0.0f) + && (mat10 == 0.0f) && (mat00 == 1.0f) && (mat11 == 1.0f); } diff --git a/source/modules/juce_graphics/geometry/juce_AffineTransform.h b/source/modules/juce_graphics/geometry/juce_AffineTransform.h index 7562aedbe..24fcf5156 100644 --- a/source/modules/juce_graphics/geometry/juce_AffineTransform.h +++ b/source/modules/juce_graphics/geometry/juce_AffineTransform.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_AFFINETRANSFORM_H_INCLUDED -#define JUCE_AFFINETRANSFORM_H_INCLUDED +#pragma once //============================================================================== @@ -274,5 +275,3 @@ public: float mat00, mat01, mat02; float mat10, mat11, mat12; }; - -#endif // JUCE_AFFINETRANSFORM_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_BorderSize.h b/source/modules/juce_graphics/geometry/juce_BorderSize.h index 1d2436f4c..7dbfb8ce5 100644 --- a/source/modules/juce_graphics/geometry/juce_BorderSize.h +++ b/source/modules/juce_graphics/geometry/juce_BorderSize.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BORDERSIZE_H_INCLUDED -#define JUCE_BORDERSIZE_H_INCLUDED +#pragma once //============================================================================== @@ -148,6 +149,3 @@ private: //============================================================================== ValueType top, left, bottom, right; }; - - -#endif // JUCE_BORDERSIZE_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_EdgeTable.cpp b/source/modules/juce_graphics/geometry/juce_EdgeTable.cpp index edefa73c6..ea35e4752 100644 --- a/source/modules/juce_graphics/geometry/juce_EdgeTable.cpp +++ b/source/modules/juce_graphics/geometry/juce_EdgeTable.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -133,13 +135,13 @@ EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) allocate(); clearLineSizes(); - for (const Rectangle* r = rectanglesToAdd.begin(), * const e = rectanglesToAdd.end(); r != e; ++r) + for (auto& r : rectanglesToAdd) { - const int x1 = r->getX() << 8; - const int x2 = r->getRight() << 8; - int y = r->getY() - bounds.getY(); + const int x1 = r.getX() << 8; + const int x2 = r.getRight() << 8; + int y = r.getY() - bounds.getY(); - for (int j = r->getHeight(); --j >= 0;) + for (int j = r.getHeight(); --j >= 0;) addEdgePointPair (x1, x2, y++, 255); } @@ -156,13 +158,13 @@ EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) allocate(); clearLineSizes(); - for (const Rectangle* r = rectanglesToAdd.begin(), * const e = rectanglesToAdd.end(); r != e; ++r) + for (auto& r : rectanglesToAdd) { - const int x1 = roundToInt (r->getX() * 256.0f); - const int x2 = roundToInt (r->getRight() * 256.0f); + const int x1 = roundToInt (r.getX() * 256.0f); + const int x2 = roundToInt (r.getRight() * 256.0f); - const int y1 = roundToInt (r->getY() * 256.0f) - (bounds.getY() << 8); - const int y2 = roundToInt (r->getBottom() * 256.0f) - (bounds.getY() << 8); + const int y1 = roundToInt (r.getY() * 256.0f) - (bounds.getY() << 8); + const int y2 = roundToInt (r.getBottom() * 256.0f) - (bounds.getY() << 8); if (x2 <= x1 || y2 <= y1) continue; diff --git a/source/modules/juce_graphics/geometry/juce_EdgeTable.h b/source/modules/juce_graphics/geometry/juce_EdgeTable.h index 9f3d5eb63..f32e61e12 100644 --- a/source/modules/juce_graphics/geometry/juce_EdgeTable.h +++ b/source/modules/juce_graphics/geometry/juce_EdgeTable.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_EDGETABLE_H_INCLUDED -#define JUCE_EDGETABLE_H_INCLUDED +#pragma once //============================================================================== @@ -215,6 +216,3 @@ private: JUCE_LEAK_DETECTOR (EdgeTable) }; - - -#endif // JUCE_EDGETABLE_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_Line.h b/source/modules/juce_graphics/geometry/juce_Line.h index dfd95cadd..7143fe308 100644 --- a/source/modules/juce_graphics/geometry/juce_Line.h +++ b/source/modules/juce_graphics/geometry/juce_Line.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LINE_H_INCLUDED -#define JUCE_LINE_H_INCLUDED +#pragma once //============================================================================== @@ -61,8 +62,7 @@ public: } /** Creates a line from its start and end points. */ - Line (Point startPoint, - Point endPoint) noexcept + Line (Point startPoint, Point endPoint) noexcept : start (startPoint), end (endPoint) { } @@ -110,7 +110,7 @@ public: void setEnd (const Point newEnd) noexcept { end = newEnd; } /** Returns a line that is the same as this one, but with the start and end reversed, */ - Line reversed() const noexcept { return Line (end, start); } + Line reversed() const noexcept { return { end, start }; } /** Applies an affine transform to the line's start and end points. */ void applyTransform (const AffineTransform& transform) noexcept @@ -146,15 +146,15 @@ public: */ static Line fromStartAndAngle (Point startPoint, ValueType length, ValueType angle) noexcept { - return Line (startPoint, startPoint.getPointOnCircumference (length, angle)); + return { startPoint, startPoint.getPointOnCircumference (length, angle) }; } //============================================================================== /** Casts this line to float coordinates. */ - Line toFloat() const noexcept { return Line (start.toFloat(), end.toFloat()); } + Line toFloat() const noexcept { return { start.toFloat(), end.toFloat() }; } /** Casts this line to double coordinates. */ - Line toDouble() const noexcept { return Line (start.toDouble(), end.toDouble()); } + Line toDouble() const noexcept { return { start.toDouble(), end.toDouble() }; } //============================================================================== /** Compares two lines. */ @@ -229,14 +229,14 @@ public: Point getPointAlongLine (ValueType distanceFromStart, ValueType perpendicularDistance) const noexcept { - const Point delta (end - start); - const double length = juce_hypot ((double) delta.x, - (double) delta.y); + auto delta = end - start; + auto length = juce_hypot ((double) delta.x, + (double) delta.y); if (length <= 0) return start; - return Point (start.x + static_cast ((delta.x * distanceFromStart - delta.y * perpendicularDistance) / length), - start.y + static_cast ((delta.y * distanceFromStart + delta.x * perpendicularDistance) / length)); + return { start.x + static_cast ((delta.x * distanceFromStart - delta.y * perpendicularDistance) / length), + start.y + static_cast ((delta.y * distanceFromStart + delta.x * perpendicularDistance) / length) }; } /** Returns the location of the point which is a given distance along this line @@ -251,7 +251,7 @@ public: */ Point getPointAlongLineProportionally (typename Point::FloatType proportionOfLength) const noexcept { - return start + Point ((end - start) * proportionOfLength); + return start + (end - start) * proportionOfLength; } /** Returns the smallest distance between this line segment and a given point. @@ -268,34 +268,32 @@ public: ValueType getDistanceFromPoint (Point targetPoint, Point& pointOnLine) const noexcept { - const Point delta (end - start); - const double length = delta.x * delta.x + delta.y * delta.y; + auto delta = end - start; + auto length = delta.x * delta.x + delta.y * delta.y; if (length > 0) { - const double prop = ((targetPoint.x - start.x) * delta.x - + (targetPoint.y - start.y) * delta.y) / length; + auto prop = ((targetPoint.x - start.x) * delta.x + + (targetPoint.y - start.y) * delta.y) / (double) length; if (prop >= 0 && prop <= 1.0) { - pointOnLine = start + delta * static_cast (prop); + pointOnLine = start + delta * prop; return targetPoint.getDistanceFrom (pointOnLine); } } - const float fromStart = targetPoint.getDistanceFrom (start); - const float fromEnd = targetPoint.getDistanceFrom (end); + auto fromStart = targetPoint.getDistanceFrom (start); + auto fromEnd = targetPoint.getDistanceFrom (end); if (fromStart < fromEnd) { pointOnLine = start; return fromStart; } - else - { - pointOnLine = end; - return fromEnd; - } + + pointOnLine = end; + return fromEnd; } /** Finds the point on this line which is nearest to a given point, and @@ -308,8 +306,8 @@ public: */ ValueType findNearestProportionalPositionTo (Point point) const noexcept { - const Point delta (end - start); - const double length = delta.x * delta.x + delta.y * delta.y; + auto delta = end - start; + auto length = delta.x * delta.x + delta.y * delta.y; return length <= 0 ? 0 : jlimit (ValueType(), static_cast (1), @@ -334,8 +332,7 @@ public: bool isPointAbove (Point point) const noexcept { return start.x != end.x - && point.y < ((end.y - start.y) - * (point.x - start.x)) / (end.x - start.x) + start.y; + && point.y < ((end.y - start.y) * (point.x - start.x)) / (end.x - start.x) + start.y; } //============================================================================== @@ -346,7 +343,7 @@ public: */ Line withShortenedStart (ValueType distanceToShortenBy) const noexcept { - return Line (getPointAlongLine (jmin (distanceToShortenBy, getLength())), end); + return { getPointAlongLine (jmin (distanceToShortenBy, getLength())), end }; } /** Returns a shortened copy of this line. @@ -356,14 +353,16 @@ public: */ Line withShortenedEnd (ValueType distanceToShortenBy) const noexcept { - const ValueType length = getLength(); - return Line (start, getPointAlongLine (length - jmin (distanceToShortenBy, length))); + auto length = getLength(); + return { start, getPointAlongLine (length - jmin (distanceToShortenBy, length)) }; } private: //============================================================================== Point start, end; + static bool isZeroToOne (ValueType v) noexcept { return v >= 0 && v <= static_cast (1); } + static bool findIntersection (const Point p1, const Point p2, const Point p3, const Point p4, Point& intersection) noexcept @@ -374,9 +373,9 @@ private: return true; } - const Point d1 (p2 - p1); - const Point d2 (p4 - p3); - const ValueType divisor = d1.x * d2.y - d2.x * d1.y; + auto d1 = p2 - p1; + auto d2 = p4 - p3; + auto divisor = d1.x * d2.y - d2.x * d1.y; if (divisor == 0) { @@ -384,30 +383,30 @@ private: { if (d1.y == 0 && d2.y != 0) { - const ValueType along = (p1.y - p3.y) / d2.y; + auto along = (p1.y - p3.y) / d2.y; intersection = p1.withX (p3.x + along * d2.x); - return along >= 0 && along <= static_cast (1); + return isZeroToOne (along); } if (d2.y == 0 && d1.y != 0) { - const ValueType along = (p3.y - p1.y) / d1.y; + auto along = (p3.y - p1.y) / d1.y; intersection = p3.withX (p1.x + along * d1.x); - return along >= 0 && along <= static_cast (1); + return isZeroToOne (along); } if (d1.x == 0 && d2.x != 0) { - const ValueType along = (p1.x - p3.x) / d2.x; + auto along = (p1.x - p3.x) / d2.x; intersection = p1.withY (p3.y + along * d2.y); - return along >= 0 && along <= static_cast (1); + return isZeroToOne (along); } if (d2.x == 0 && d1.x != 0) { - const ValueType along = (p3.x - p1.x) / d1.x; + auto along = (p3.x - p1.x) / d1.x; intersection = p3.withY (p1.y + along * d1.y); - return along >= 0 && along <= static_cast (1); + return isZeroToOne (along); } } @@ -415,16 +414,13 @@ private: return false; } - const ValueType along1 = ((p1.y - p3.y) * d2.x - (p1.x - p3.x) * d2.y) / divisor; + auto along1 = ((p1.y - p3.y) * d2.x - (p1.x - p3.x) * d2.y) / divisor; intersection = p1 + d1 * along1; - if (along1 < 0 || along1 > static_cast (1)) + if (! isZeroToOne (along1)) return false; - const ValueType along2 = ((p1.y - p3.y) * d1.x - (p1.x - p3.x) * d1.y) / divisor; - return along2 >= 0 && along2 <= static_cast (1); + auto along2 = ((p1.y - p3.y) * d1.x - (p1.x - p3.x) * d1.y) / divisor; + return isZeroToOne (along2); } }; - - -#endif // JUCE_LINE_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_Path.cpp b/source/modules/juce_graphics/geometry/juce_Path.cpp index e11cff543..9466776ce 100644 --- a/source/modules/juce_graphics/geometry/juce_Path.cpp +++ b/source/modules/juce_graphics/geometry/juce_Path.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -35,7 +37,7 @@ namespace PathHelpers { t = t.findEndOfWhitespace(); - String::CharPointerType start (t); + auto start = t; size_t numChars = 0; while (! (t.isEmpty() || t.isWhitespace())) @@ -44,7 +46,7 @@ namespace PathHelpers ++numChars; } - return String (start, numChars); + return { start, numChars }; } inline double lengthOf (float x1, float y1, float x2, float y2) noexcept @@ -63,15 +65,19 @@ const float Path::closeSubPathMarker = 100005.0f; const float Path::defaultToleranceForTesting = 1.0f; const float Path::defaultToleranceForMeasurement = 0.6f; +static inline bool isMarker (float value, float marker) noexcept +{ + return value == marker; +} + //============================================================================== Path::PathBounds::PathBounds() noexcept - : pathXMin (0), pathXMax (0), pathYMin (0), pathYMax (0) { } Rectangle Path::PathBounds::getRectangle() const noexcept { - return Rectangle (pathXMin, pathYMin, pathXMax - pathXMin, pathYMax - pathYMin); + return { pathXMin, pathYMin, pathXMax - pathXMin, pathYMax - pathYMin }; } void Path::PathBounds::reset() noexcept @@ -120,7 +126,6 @@ void Path::PathBounds::extend (const float x1, const float y1, const float x2, c //============================================================================== Path::Path() - : numElements (0), useNonZeroWinding (true) { } @@ -157,7 +162,6 @@ Path& Path::operator= (const Path& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Path::Path (Path&& other) noexcept : data (static_cast&&> (other.data)), numElements (other.numElements), @@ -174,7 +178,6 @@ Path& Path::operator= (Path&& other) noexcept useNonZeroWinding = other.useNonZeroWinding; return *this; } -#endif bool Path::operator== (const Path& other) const noexcept { @@ -216,8 +219,7 @@ void Path::setUsingNonZeroWinding (const bool isNonZero) noexcept useNonZeroWinding = isNonZero; } -void Path::scaleToFit (const float x, const float y, const float w, const float h, - const bool preserveProportions) noexcept +void Path::scaleToFit (float x, float y, float w, float h, bool preserveProportions) noexcept { applyTransform (getTransformToScaleToFit (x, y, w, h, preserveProportions)); } @@ -229,15 +231,15 @@ bool Path::isEmpty() const noexcept while (i < numElements) { - const float type = data.elements [i++]; + auto type = data.elements[i++]; - if (type == moveMarker) + if (isMarker (type, moveMarker)) { i += 2; } - else if (type == lineMarker - || type == quadMarker - || type == cubicMarker) + else if (isMarker (type, lineMarker) + || isMarker (type, quadMarker) + || isMarker (type, cubicMarker)) { return false; } @@ -273,9 +275,9 @@ void Path::startNewSubPath (const float x, const float y) preallocateSpace (3); - data.elements [numElements++] = moveMarker; - data.elements [numElements++] = x; - data.elements [numElements++] = y; + data.elements[numElements++] = moveMarker; + data.elements[numElements++] = x; + data.elements[numElements++] = y; } void Path::startNewSubPath (const Point start) @@ -292,9 +294,9 @@ void Path::lineTo (const float x, const float y) preallocateSpace (3); - data.elements [numElements++] = lineMarker; - data.elements [numElements++] = x; - data.elements [numElements++] = y; + data.elements[numElements++] = lineMarker; + data.elements[numElements++] = x; + data.elements[numElements++] = y; bounds.extend (x, y); } @@ -315,11 +317,11 @@ void Path::quadraticTo (const float x1, const float y1, preallocateSpace (5); - data.elements [numElements++] = quadMarker; - data.elements [numElements++] = x1; - data.elements [numElements++] = y1; - data.elements [numElements++] = x2; - data.elements [numElements++] = y2; + data.elements[numElements++] = quadMarker; + data.elements[numElements++] = x1; + data.elements[numElements++] = y1; + data.elements[numElements++] = x2; + data.elements[numElements++] = y2; bounds.extend (x1, y1, x2, y2); } @@ -344,13 +346,13 @@ void Path::cubicTo (const float x1, const float y1, preallocateSpace (7); - data.elements [numElements++] = cubicMarker; - data.elements [numElements++] = x1; - data.elements [numElements++] = y1; - data.elements [numElements++] = x2; - data.elements [numElements++] = y2; - data.elements [numElements++] = x3; - data.elements [numElements++] = y3; + data.elements[numElements++] = cubicMarker; + data.elements[numElements++] = x1; + data.elements[numElements++] = y1; + data.elements[numElements++] = x2; + data.elements[numElements++] = y2; + data.elements[numElements++] = x3; + data.elements[numElements++] = y3; bounds.extend (x1, y1, x2, y2); bounds.extend (x3, y3); @@ -367,11 +369,10 @@ void Path::cubicTo (const Point controlPoint1, void Path::closeSubPath() { - if (numElements > 0 - && data.elements [numElements - 1] != closeSubPathMarker) + if (numElements > 0 && ! isMarker (data.elements[numElements - 1], closeSubPathMarker)) { preallocateSpace (1); - data.elements [numElements++] = closeSubPathMarker; + data.elements[numElements++] = closeSubPathMarker; } } @@ -379,11 +380,11 @@ Point Path::getCurrentPosition() const { int i = (int) numElements - 1; - if (i > 0 && data.elements[i] == closeSubPathMarker) + if (i > 0 && isMarker (data.elements[i], closeSubPathMarker)) { while (i >= 0) { - if (data.elements[i] == moveMarker) + if (isMarker (data.elements[i], moveMarker)) { i += 2; break; @@ -394,9 +395,9 @@ Point Path::getCurrentPosition() const } if (i > 0) - return Point (data.elements [i - 1], data.elements [i]); + return { data.elements[i - 1], data.elements[i] }; - return Point(); + return {}; } void Path::addRectangle (const float x, const float y, @@ -424,19 +425,19 @@ void Path::addRectangle (const float x, const float y, bounds.pathYMax = jmax (bounds.pathYMax, y2); } - data.elements [numElements++] = moveMarker; - data.elements [numElements++] = x1; - data.elements [numElements++] = y2; - data.elements [numElements++] = lineMarker; - data.elements [numElements++] = x1; - data.elements [numElements++] = y1; - data.elements [numElements++] = lineMarker; - data.elements [numElements++] = x2; - data.elements [numElements++] = y1; - data.elements [numElements++] = lineMarker; - data.elements [numElements++] = x2; - data.elements [numElements++] = y2; - data.elements [numElements++] = closeSubPathMarker; + data.elements[numElements++] = moveMarker; + data.elements[numElements++] = x1; + data.elements[numElements++] = y2; + data.elements[numElements++] = lineMarker; + data.elements[numElements++] = x1; + data.elements[numElements++] = y1; + data.elements[numElements++] = lineMarker; + data.elements[numElements++] = x2; + data.elements[numElements++] = y1; + data.elements[numElements++] = lineMarker; + data.elements[numElements++] = x2; + data.elements[numElements++] = y2; + data.elements[numElements++] = closeSubPathMarker; } void Path::addRoundedRectangle (float x, float y, float w, float h, float csx, float csy) @@ -451,10 +452,10 @@ void Path::addRoundedRectangle (const float x, const float y, const float w, con { csx = jmin (csx, w * 0.5f); csy = jmin (csy, h * 0.5f); - const float cs45x = csx * 0.45f; - const float cs45y = csy * 0.45f; - const float x2 = x + w; - const float y2 = y + h; + auto cs45x = csx * 0.45f; + auto cs45y = csy * 0.45f; + auto x2 = x + w; + auto y2 = y + h; if (curveTopLeft) { @@ -540,12 +541,12 @@ void Path::addEllipse (float x, float y, float w, float h) void Path::addEllipse (Rectangle area) { - const float hw = area.getWidth() * 0.5f; - const float hw55 = hw * 0.55f; - const float hh = area.getHeight() * 0.5f; - const float hh55 = hh * 0.55f; - const float cx = area.getX() + hw; - const float cy = area.getY() + hh; + auto hw = area.getWidth() * 0.5f; + auto hw55 = hw * 0.55f; + auto hh = area.getHeight() * 0.5f; + auto hh55 = hh * 0.55f; + auto cx = area.getX() + hw; + auto cy = area.getY() + hh; startNewSubPath (cx, cy - hh); cubicTo (cx + hw55, cy - hh, cx + hw, cy - hh55, cx + hw, cy); @@ -561,8 +562,8 @@ void Path::addArc (const float x, const float y, const float toRadians, const bool startAsNewSubPath) { - const float radiusX = w / 2.0f; - const float radiusY = h / 2.0f; + auto radiusX = w / 2.0f; + auto radiusY = h / 2.0f; addCentredArc (x + radiusX, y + radiusY, @@ -582,8 +583,8 @@ void Path::addCentredArc (const float centreX, const float centreY, if (radiusX > 0.0f && radiusY > 0.0f) { const Point centre (centreX, centreY); - const AffineTransform rotation (AffineTransform::rotation (rotationOfEllipse, centreX, centreY)); - float angle = fromRadians; + auto rotation = AffineTransform::rotation (rotationOfEllipse, centreX, centreY); + auto angle = fromRadians; if (startAsNewSubPath) startNewSubPath (centre.getPointOnCircumference (radiusX, radiusY, angle).transformedBy (rotation)); @@ -676,7 +677,7 @@ void Path::addPieSegment (Rectangle segmentBounds, //============================================================================== void Path::addLineSegment (const Line& line, float lineThickness) { - const Line reversed (line.reversed()); + auto reversed = line.reversed(); lineThickness *= 0.5f; startNewSubPath (line.getPointAlongLine (0, lineThickness)); @@ -689,7 +690,7 @@ void Path::addLineSegment (const Line& line, float lineThickness) void Path::addArrow (const Line& line, float lineThickness, float arrowheadWidth, float arrowheadLength) { - const Line reversed (line.reversed()); + auto reversed = line.reversed(); lineThickness *= 0.5f; arrowheadWidth *= 0.5f; arrowheadLength = jmin (arrowheadLength, 0.8f * line.getLength()); @@ -711,12 +712,12 @@ void Path::addPolygon (const Point centre, const int numberOfSides, if (numberOfSides > 1) { - const float angleBetweenPoints = float_Pi * 2.0f / numberOfSides; + auto angleBetweenPoints = float_Pi * 2.0f / numberOfSides; for (int i = 0; i < numberOfSides; ++i) { - const float angle = startAngle + i * angleBetweenPoints; - const Point p (centre.getPointOnCircumference (radius, angle)); + auto angle = startAngle + i * angleBetweenPoints; + auto p = centre.getPointOnCircumference (radius, angle); if (i == 0) startNewSubPath (p); @@ -735,12 +736,12 @@ void Path::addStar (const Point centre, const int numberOfPoints, if (numberOfPoints > 1) { - const float angleBetweenPoints = float_Pi * 2.0f / numberOfPoints; + auto angleBetweenPoints = float_Pi * 2.0f / numberOfPoints; for (int i = 0; i < numberOfPoints; ++i) { - const float angle = startAngle + i * angleBetweenPoints; - const Point p (centre.getPointOnCircumference (outerRadius, angle)); + auto angle = startAngle + i * angleBetweenPoints; + auto p = centre.getPointOnCircumference (outerRadius, angle); if (i == 0) startNewSubPath (p); @@ -760,12 +761,12 @@ void Path::addBubble (const Rectangle& bodyArea, const float cornerSize, const float arrowBaseWidth) { - const float halfW = bodyArea.getWidth() / 2.0f; - const float halfH = bodyArea.getHeight() / 2.0f; - const float cornerSizeW = jmin (cornerSize, halfW); - const float cornerSizeH = jmin (cornerSize, halfH); - const float cornerSizeW2 = 2.0f * cornerSizeW; - const float cornerSizeH2 = 2.0f * cornerSizeH; + auto halfW = bodyArea.getWidth() / 2.0f; + auto halfH = bodyArea.getHeight() / 2.0f; + auto cornerSizeW = jmin (cornerSize, halfW); + auto cornerSizeH = jmin (cornerSize, halfH); + auto cornerSizeW2 = 2.0f * cornerSizeW; + auto cornerSizeH2 = 2.0f * cornerSizeH; startNewSubPath (bodyArea.getX() + cornerSizeW, bodyArea.getY()); @@ -822,33 +823,33 @@ void Path::addBubble (const Rectangle& bodyArea, void Path::addPath (const Path& other) { size_t i = 0; - const float* const d = other.data.elements; + const float* d = other.data.elements; while (i < other.numElements) { - const float type = d[i++]; + auto type = d[i++]; - if (type == moveMarker) + if (isMarker (type, moveMarker)) { startNewSubPath (d[i], d[i + 1]); i += 2; } - else if (type == lineMarker) + else if (isMarker (type, lineMarker)) { lineTo (d[i], d[i + 1]); i += 2; } - else if (type == quadMarker) + else if (isMarker (type, quadMarker)) { quadraticTo (d[i], d[i + 1], d[i + 2], d[i + 3]); i += 4; } - else if (type == cubicMarker) + else if (isMarker (type, cubicMarker)) { cubicTo (d[i], d[i + 1], d[i + 2], d[i + 3], d[i + 4], d[i + 5]); i += 6; } - else if (type == closeSubPathMarker) + else if (isMarker (type, closeSubPathMarker)) { closeSubPath(); } @@ -864,44 +865,44 @@ void Path::addPath (const Path& other, const AffineTransform& transformToApply) { size_t i = 0; - const float* const d = other.data.elements; + const float* d = other.data.elements; while (i < other.numElements) { - const float type = d [i++]; + auto type = d[i++]; - if (type == closeSubPathMarker) + if (isMarker (type, closeSubPathMarker)) { closeSubPath(); } else { - float x = d[i++]; - float y = d[i++]; + auto x = d[i++]; + auto y = d[i++]; transformToApply.transformPoint (x, y); - if (type == moveMarker) + if (isMarker (type, moveMarker)) { startNewSubPath (x, y); } - else if (type == lineMarker) + else if (isMarker (type, lineMarker)) { lineTo (x, y); } - else if (type == quadMarker) + else if (isMarker (type, quadMarker)) { - float x2 = d [i++]; - float y2 = d [i++]; + auto x2 = d[i++]; + auto y2 = d[i++]; transformToApply.transformPoint (x2, y2); quadraticTo (x, y, x2, y2); } - else if (type == cubicMarker) + else if (isMarker (type, cubicMarker)) { - float x2 = d [i++]; - float y2 = d [i++]; - float x3 = d [i++]; - float y3 = d [i++]; + auto x2 = d[i++]; + auto y2 = d[i++]; + auto x3 = d[i++]; + auto y3 = d[i++]; transformToApply.transformPoints (x2, y2, x3, y3); cubicTo (x, y, x2, y2, x3, y3); @@ -921,13 +922,13 @@ void Path::applyTransform (const AffineTransform& transform) noexcept bounds.reset(); bool firstPoint = true; float* d = data.elements; - float* const end = d + numElements; + auto* end = d + numElements; while (d < end) { - const float type = *d++; + auto type = *d++; - if (type == moveMarker) + if (isMarker (type, moveMarker)) { transform.transformPoint (d[0], d[1]); @@ -943,19 +944,19 @@ void Path::applyTransform (const AffineTransform& transform) noexcept d += 2; } - else if (type == lineMarker) + else if (isMarker (type, lineMarker)) { transform.transformPoint (d[0], d[1]); bounds.extend (d[0], d[1]); d += 2; } - else if (type == quadMarker) + else if (isMarker (type, quadMarker)) { transform.transformPoints (d[0], d[1], d[2], d[3]); bounds.extend (d[0], d[1], d[2], d[3]); d += 4; } - else if (type == cubicMarker) + else if (isMarker (type, cubicMarker)) { transform.transformPoints (d[0], d[1], d[2], d[3], d[4], d[5]); bounds.extend (d[0], d[1], d[2], d[3]); @@ -979,7 +980,7 @@ AffineTransform Path::getTransformToScaleToFit (const float x, const float y, const bool preserveProportions, Justification justification) const { - Rectangle boundsRect (getBounds()); + auto boundsRect = getBounds(); if (preserveProportions) { @@ -987,7 +988,7 @@ AffineTransform Path::getTransformToScaleToFit (const float x, const float y, return AffineTransform(); float newW, newH; - const float srcRatio = boundsRect.getHeight() / boundsRect.getWidth(); + auto srcRatio = boundsRect.getHeight() / boundsRect.getWidth(); if (srcRatio > h / w) { @@ -1000,8 +1001,8 @@ AffineTransform Path::getTransformToScaleToFit (const float x, const float y, newH = w * srcRatio; } - float newXCentre = x; - float newYCentre = y; + auto newXCentre = x; + auto newYCentre = y; if (justification.testFlags (Justification::left)) newXCentre += newW * 0.5f; else if (justification.testFlags (Justification::right)) newXCentre += w - newW * 0.5f; @@ -1042,7 +1043,7 @@ bool Path::contains (const float x, const float y, const float tolerance) const { if ((i.y1 <= y && i.y2 > y) || (i.y2 <= y && i.y1 > y)) { - const float intersectX = i.x1 + (i.x2 - i.x1) * (y - i.y1) / (i.y2 - i.y1); + auto intersectX = i.x1 + (i.x2 - i.x1) * (y - i.y1) / (i.y2 - i.y1); if (intersectX <= x) { @@ -1093,7 +1094,7 @@ Line Path::getClippedLine (Line line, const bool keepSectionOutsid while (i.next()) { - if (line.intersects (Line (i.x1, i.y1, i.x2, i.y2), intersection)) + if (line.intersects ({ i.x1, i.y1, i.x2, i.y2 }, intersection)) { if ((startInside && keepSectionOutsidePath) || (endInside && ! keepSectionOutsidePath)) result.setStart (intersection); @@ -1126,7 +1127,7 @@ Point Path::getPointAlongPath (float distanceFromStart, while (i.next()) { const Line line (i.x1, i.y1, i.x2, i.y2); - const float lineLength = line.getLength(); + auto lineLength = line.getLength(); if (distanceFromStart <= lineLength) return line.getPointAlongLine (distanceFromStart); @@ -1134,7 +1135,7 @@ Point Path::getPointAlongPath (float distanceFromStart, distanceFromStart -= lineLength; } - return Point (i.x2, i.y2); + return { i.x2, i.y2 }; } float Path::getNearestPoint (const Point targetPoint, Point& pointOnPath, @@ -1149,7 +1150,7 @@ float Path::getNearestPoint (const Point targetPoint, Point& point while (i.next()) { const Line line (i.x1, i.y1, i.x2, i.y2); - const float distance = line.getDistanceFromPoint (targetPoint, pointOnLine); + auto distance = line.getDistanceFromPoint (targetPoint, pointOnLine); if (distance < bestDistance) { @@ -1170,73 +1171,73 @@ Path Path::createPathWithRoundedCorners (const float cornerRadius) const if (cornerRadius <= 0.01f) return *this; + Path p; size_t indexOfPathStart = 0, indexOfPathStartThis = 0; size_t n = 0; bool lastWasLine = false, firstWasLine = false; - Path p; while (n < numElements) { - const float type = data.elements [n++]; + auto type = data.elements[n++]; - if (type == moveMarker) + if (isMarker (type, moveMarker)) { indexOfPathStart = p.numElements; indexOfPathStartThis = n - 1; - const float x = data.elements [n++]; - const float y = data.elements [n++]; + auto x = data.elements[n++]; + auto y = data.elements[n++]; p.startNewSubPath (x, y); lastWasLine = false; - firstWasLine = (data.elements [n] == lineMarker); + firstWasLine = (isMarker (data.elements[n], lineMarker)); } - else if (type == lineMarker || type == closeSubPathMarker) + else if (isMarker (type, lineMarker) || isMarker (type, closeSubPathMarker)) { float startX = 0, startY = 0, joinX = 0, joinY = 0, endX, endY; - if (type == lineMarker) + if (isMarker (type, lineMarker)) { - endX = data.elements [n++]; - endY = data.elements [n++]; + endX = data.elements[n++]; + endY = data.elements[n++]; if (n > 8) { - startX = data.elements [n - 8]; - startY = data.elements [n - 7]; - joinX = data.elements [n - 5]; - joinY = data.elements [n - 4]; + startX = data.elements[n - 8]; + startY = data.elements[n - 7]; + joinX = data.elements[n - 5]; + joinY = data.elements[n - 4]; } } else { - endX = data.elements [indexOfPathStartThis + 1]; - endY = data.elements [indexOfPathStartThis + 2]; + endX = data.elements[indexOfPathStartThis + 1]; + endY = data.elements[indexOfPathStartThis + 2]; if (n > 6) { - startX = data.elements [n - 6]; - startY = data.elements [n - 5]; - joinX = data.elements [n - 3]; - joinY = data.elements [n - 2]; + startX = data.elements[n - 6]; + startY = data.elements[n - 5]; + joinX = data.elements[n - 3]; + joinY = data.elements[n - 2]; } } if (lastWasLine) { - const double len1 = PathHelpers::lengthOf (startX, startY, joinX, joinY); + auto len1 = PathHelpers::lengthOf (startX, startY, joinX, joinY); if (len1 > 0) { - const double propNeeded = jmin (0.5, cornerRadius / len1); + auto propNeeded = jmin (0.5, cornerRadius / len1); - p.data.elements [p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded); - p.data.elements [p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded); + p.data.elements[p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded); + p.data.elements[p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded); } - const double len2 = PathHelpers::lengthOf (endX, endY, joinX, joinY); + auto len2 = PathHelpers::lengthOf (endX, endY, joinX, joinY); if (len2 > 0) { - const double propNeeded = jmin (0.5, cornerRadius / len2); + auto propNeeded = jmin (0.5, cornerRadius / len2); p.quadraticTo (joinX, joinY, (float) (joinX + (endX - joinX) * propNeeded), @@ -1245,70 +1246,70 @@ Path Path::createPathWithRoundedCorners (const float cornerRadius) const p.lineTo (endX, endY); } - else if (type == lineMarker) + else if (isMarker (type, lineMarker)) { p.lineTo (endX, endY); lastWasLine = true; } - if (type == closeSubPathMarker) + if (isMarker (type, closeSubPathMarker)) { if (firstWasLine) { - startX = data.elements [n - 3]; - startY = data.elements [n - 2]; + startX = data.elements[n - 3]; + startY = data.elements[n - 2]; joinX = endX; joinY = endY; - endX = data.elements [indexOfPathStartThis + 4]; - endY = data.elements [indexOfPathStartThis + 5]; + endX = data.elements[indexOfPathStartThis + 4]; + endY = data.elements[indexOfPathStartThis + 5]; - const double len1 = PathHelpers::lengthOf (startX, startY, joinX, joinY); + auto len1 = PathHelpers::lengthOf (startX, startY, joinX, joinY); if (len1 > 0) { - const double propNeeded = jmin (0.5, cornerRadius / len1); + auto propNeeded = jmin (0.5, cornerRadius / len1); - p.data.elements [p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded); - p.data.elements [p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded); + p.data.elements[p.numElements - 2] = (float) (joinX - (joinX - startX) * propNeeded); + p.data.elements[p.numElements - 1] = (float) (joinY - (joinY - startY) * propNeeded); } - const double len2 = PathHelpers::lengthOf (endX, endY, joinX, joinY); + auto len2 = PathHelpers::lengthOf (endX, endY, joinX, joinY); if (len2 > 0) { - const double propNeeded = jmin (0.5, cornerRadius / len2); + auto propNeeded = jmin (0.5, cornerRadius / len2); endX = (float) (joinX + (endX - joinX) * propNeeded); endY = (float) (joinY + (endY - joinY) * propNeeded); p.quadraticTo (joinX, joinY, endX, endY); - p.data.elements [indexOfPathStart + 1] = endX; - p.data.elements [indexOfPathStart + 2] = endY; + p.data.elements[indexOfPathStart + 1] = endX; + p.data.elements[indexOfPathStart + 2] = endY; } } p.closeSubPath(); } } - else if (type == quadMarker) + else if (isMarker (type, quadMarker)) { lastWasLine = false; - const float x1 = data.elements [n++]; - const float y1 = data.elements [n++]; - const float x2 = data.elements [n++]; - const float y2 = data.elements [n++]; + auto x1 = data.elements[n++]; + auto y1 = data.elements[n++]; + auto x2 = data.elements[n++]; + auto y2 = data.elements[n++]; p.quadraticTo (x1, y1, x2, y2); } - else if (type == cubicMarker) + else if (isMarker (type, cubicMarker)) { lastWasLine = false; - const float x1 = data.elements [n++]; - const float y1 = data.elements [n++]; - const float x2 = data.elements [n++]; - const float y2 = data.elements [n++]; - const float x3 = data.elements [n++]; - const float y3 = data.elements [n++]; + auto x1 = data.elements[n++]; + auto y1 = data.elements[n++]; + auto x2 = data.elements[n++]; + auto y2 = data.elements[n++]; + auto x3 = data.elements[n++]; + auto y3 = data.elements[n++]; p.cubicTo (x1, y1, x2, y2, x3, y3); } } @@ -1325,38 +1326,38 @@ void Path::loadPathFromStream (InputStream& source) { case 'm': { - const float x = source.readFloat(); - const float y = source.readFloat(); + auto x = source.readFloat(); + auto y = source.readFloat(); startNewSubPath (x, y); break; } case 'l': { - const float x = source.readFloat(); - const float y = source.readFloat(); + auto x = source.readFloat(); + auto y = source.readFloat(); lineTo (x, y); break; } case 'q': { - const float x1 = source.readFloat(); - const float y1 = source.readFloat(); - const float x2 = source.readFloat(); - const float y2 = source.readFloat(); + auto x1 = source.readFloat(); + auto y1 = source.readFloat(); + auto x2 = source.readFloat(); + auto y2 = source.readFloat(); quadraticTo (x1, y1, x2, y2); break; } case 'b': { - const float x1 = source.readFloat(); - const float y1 = source.readFloat(); - const float x2 = source.readFloat(); - const float y2 = source.readFloat(); - const float x3 = source.readFloat(); - const float y3 = source.readFloat(); + auto x1 = source.readFloat(); + auto y1 = source.readFloat(); + auto x2 = source.readFloat(); + auto y2 = source.readFloat(); + auto x3 = source.readFloat(); + auto y3 = source.readFloat(); cubicTo (x1, y1, x2, y2, x3, y3); break; } @@ -1393,42 +1394,41 @@ void Path::writePathToStream (OutputStream& dest) const { dest.writeByte (useNonZeroWinding ? 'n' : 'z'); - size_t i = 0; - while (i < numElements) + for (size_t i = 0; i < numElements;) { - const float type = data.elements [i++]; + auto type = data.elements[i++]; - if (type == moveMarker) + if (isMarker (type, moveMarker)) { dest.writeByte ('m'); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); } - else if (type == lineMarker) + else if (isMarker (type, lineMarker)) { dest.writeByte ('l'); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); } - else if (type == quadMarker) + else if (isMarker (type, quadMarker)) { dest.writeByte ('q'); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); } - else if (type == cubicMarker) + else if (isMarker (type, cubicMarker)) { dest.writeByte ('b'); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); - dest.writeFloat (data.elements [i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); + dest.writeFloat (data.elements[i++]); } - else if (type == closeSubPathMarker) + else if (isMarker (type, closeSubPathMarker)) { dest.writeByte ('c'); } @@ -1448,48 +1448,48 @@ String Path::toString() const while (i < numElements) { - const float marker = data.elements [i++]; + auto type = data.elements[i++]; char markerChar = 0; int numCoords = 0; - if (marker == moveMarker) + if (isMarker (type, moveMarker)) { markerChar = 'm'; numCoords = 2; } - else if (marker == lineMarker) + else if (isMarker (type, lineMarker)) { markerChar = 'l'; numCoords = 2; } - else if (marker == quadMarker) + else if (isMarker (type, quadMarker)) { markerChar = 'q'; numCoords = 4; } - else if (marker == cubicMarker) + else if (isMarker (type, cubicMarker)) { markerChar = 'c'; numCoords = 6; } else { - jassert (marker == closeSubPathMarker); + jassert (isMarker (type, closeSubPathMarker)); markerChar = 'z'; } - if (marker != lastMarker) + if (! isMarker (type, lastMarker)) { if (s.getDataSize() != 0) s << ' '; s << markerChar; - lastMarker = marker; + lastMarker = type; } while (--numCoords >= 0 && i < numElements) { - String coord (data.elements [i++], 3); + String coord (data.elements[i++], 3); while (coord.endsWithChar ('0') && coord != "0") coord = coord.dropLastCharacters (1); @@ -1512,15 +1512,15 @@ void Path::restoreFromString (StringRef stringVersion) clear(); setUsingNonZeroWinding (true); - String::CharPointerType t (stringVersion.text); + auto t = stringVersion.text; juce_wchar marker = 'm'; int numValues = 2; - float values [6]; + float values[6]; for (;;) { - const String token (PathHelpers::nextToken (t)); - const juce_wchar firstChar = token[0]; + auto token = PathHelpers::nextToken (t); + auto firstChar = token[0]; int startNum = 0; if (firstChar == 0) @@ -1574,9 +1574,7 @@ void Path::restoreFromString (StringRef stringVersion) //============================================================================== Path::Iterator::Iterator (const Path& p) noexcept - : elementType (startNewSubPath), - x1 (0), y1 (0), x2 (0), y2 (0), x3 (0), y3 (0), - path (p), index (0) + : elementType (startNewSubPath), path (p) { } @@ -1586,43 +1584,43 @@ Path::Iterator::~Iterator() noexcept bool Path::Iterator::next() noexcept { - const float* const elements = path.data.elements; + const float* elements = path.data.elements; if (index < path.numElements) { - const float type = elements [index++]; + auto type = elements[index++]; - if (type == moveMarker) + if (isMarker (type, moveMarker)) { elementType = startNewSubPath; - x1 = elements [index++]; - y1 = elements [index++]; + x1 = elements[index++]; + y1 = elements[index++]; } - else if (type == lineMarker) + else if (isMarker (type, lineMarker)) { elementType = lineTo; - x1 = elements [index++]; - y1 = elements [index++]; + x1 = elements[index++]; + y1 = elements[index++]; } - else if (type == quadMarker) + else if (isMarker (type, quadMarker)) { elementType = quadraticTo; - x1 = elements [index++]; - y1 = elements [index++]; - x2 = elements [index++]; - y2 = elements [index++]; + x1 = elements[index++]; + y1 = elements[index++]; + x2 = elements[index++]; + y2 = elements[index++]; } - else if (type == cubicMarker) + else if (isMarker (type, cubicMarker)) { elementType = cubicTo; - x1 = elements [index++]; - y1 = elements [index++]; - x2 = elements [index++]; - y2 = elements [index++]; - x3 = elements [index++]; - y3 = elements [index++]; + x1 = elements[index++]; + y1 = elements[index++]; + x2 = elements[index++]; + y2 = elements[index++]; + x3 = elements[index++]; + y3 = elements[index++]; } - else if (type == closeSubPathMarker) + else if (isMarker (type, closeSubPathMarker)) { elementType = closePath; } diff --git a/source/modules/juce_graphics/geometry/juce_Path.h b/source/modules/juce_graphics/geometry/juce_Path.h index 6ddca5dd1..ac1880ca6 100644 --- a/source/modules/juce_graphics/geometry/juce_Path.h +++ b/source/modules/juce_graphics/geometry/juce_Path.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PATH_H_INCLUDED -#define JUCE_PATH_H_INCLUDED +#pragma once //============================================================================== @@ -75,10 +76,11 @@ public: /** Copies this path from another one. */ Path& operator= (const Path&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ Path (Path&&) noexcept; + + /** Move assignment operator */ Path& operator= (Path&&) noexcept; - #endif bool operator== (const Path&) const noexcept; bool operator!= (const Path&) const noexcept; @@ -746,12 +748,12 @@ public: PathElementType elementType; - float x1, y1, x2, y2, x3, y3; + float x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0; //============================================================================== private: const Path& path; - size_t index; + size_t index = 0; JUCE_DECLARE_NON_COPYABLE (Iterator) }; @@ -802,7 +804,7 @@ private: friend class PathFlatteningIterator; friend class Path::Iterator; ArrayAllocationBase data; - size_t numElements; + size_t numElements = 0; struct PathBounds { @@ -813,11 +815,11 @@ private: void extend (float, float) noexcept; void extend (float, float, float, float) noexcept; - float pathXMin, pathXMax, pathYMin, pathYMax; + float pathXMin = 0, pathXMax = 0, pathYMin = 0, pathYMax = 0; }; PathBounds bounds; - bool useNonZeroWinding; + bool useNonZeroWinding = true; static const float lineMarker; static const float moveMarker; @@ -827,5 +829,3 @@ private: JUCE_LEAK_DETECTOR (Path) }; - -#endif // JUCE_PATH_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_PathIterator.cpp b/source/modules/juce_graphics/geometry/juce_PathIterator.cpp index 76663ace0..f3fbe128a 100644 --- a/source/modules/juce_graphics/geometry/juce_PathIterator.cpp +++ b/source/modules/juce_graphics/geometry/juce_PathIterator.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -38,12 +40,7 @@ PathFlatteningIterator::PathFlatteningIterator (const Path& path_, transform (transform_), points (path_.data.elements), toleranceSquared (tolerance * tolerance), - subPathCloseX (0), - subPathCloseY (0), - isIdentityTransform (transform_.isIdentity()), - stackBase (32), - index (0), - stackSize (32) + isIdentityTransform (transform_.isIdentity()) { stackPos = stackBase; } @@ -55,7 +52,7 @@ PathFlatteningIterator::~PathFlatteningIterator() bool PathFlatteningIterator::isLastInSubpath() const noexcept { return stackPos == stackBase.getData() - && (index >= path.numElements || points [index] == Path::moveMarker); + && (index >= path.numElements || isMarker (points[index], Path::moveMarker)); } bool PathFlatteningIterator::next() @@ -79,12 +76,12 @@ bool PathFlatteningIterator::next() type = points [index++]; - if (type != Path::closeSubPathMarker) + if (! isMarker (type, Path::closeSubPathMarker)) { x2 = points [index++]; y2 = points [index++]; - if (type == Path::quadMarker) + if (isMarker (type, Path::quadMarker)) { x3 = points [index++]; y3 = points [index++]; @@ -92,7 +89,7 @@ bool PathFlatteningIterator::next() if (! isIdentityTransform) transform.transformPoints (x2, y2, x3, y3); } - else if (type == Path::cubicMarker) + else if (isMarker (type, Path::cubicMarker)) { x3 = points [index++]; y3 = points [index++]; @@ -113,17 +110,17 @@ bool PathFlatteningIterator::next() { type = *--stackPos; - if (type != Path::closeSubPathMarker) + if (! isMarker (type, Path::closeSubPathMarker)) { x2 = *--stackPos; y2 = *--stackPos; - if (type == Path::quadMarker) + if (isMarker (type, Path::quadMarker)) { x3 = *--stackPos; y3 = *--stackPos; } - else if (type == Path::cubicMarker) + else if (isMarker (type, Path::cubicMarker)) { x3 = *--stackPos; y3 = *--stackPos; @@ -133,7 +130,7 @@ bool PathFlatteningIterator::next() } } - if (type == Path::lineMarker) + if (isMarker (type, Path::lineMarker)) { ++subPathIndex; @@ -146,7 +143,7 @@ bool PathFlatteningIterator::next() return true; } - if (type == Path::quadMarker) + if (isMarker (type, Path::quadMarker)) { const size_t offset = (size_t) (stackPos - stackBase); @@ -157,15 +154,15 @@ bool PathFlatteningIterator::next() stackPos = stackBase + offset; } - const float m1x = (x1 + x2) * 0.5f; - const float m1y = (y1 + y2) * 0.5f; - const float m2x = (x2 + x3) * 0.5f; - const float m2y = (y2 + y3) * 0.5f; - const float m3x = (m1x + m2x) * 0.5f; - const float m3y = (m1y + m2y) * 0.5f; + auto m1x = (x1 + x2) * 0.5f; + auto m1y = (y1 + y2) * 0.5f; + auto m2x = (x2 + x3) * 0.5f; + auto m2y = (y2 + y3) * 0.5f; + auto m3x = (m1x + m2x) * 0.5f; + auto m3y = (m1y + m2y) * 0.5f; - const float errorX = m3x - x2; - const float errorY = m3y - y2; + auto errorX = m3x - x2; + auto errorY = m3y - y2; if (errorX * errorX + errorY * errorY > toleranceSquared) { @@ -194,7 +191,7 @@ bool PathFlatteningIterator::next() jassert (stackPos < stackBase + stackSize); } - else if (type == Path::cubicMarker) + else if (isMarker (type, Path::cubicMarker)) { const size_t offset = (size_t) (stackPos - stackBase); @@ -205,21 +202,21 @@ bool PathFlatteningIterator::next() stackPos = stackBase + offset; } - const float m1x = (x1 + x2) * 0.5f; - const float m1y = (y1 + y2) * 0.5f; - const float m2x = (x3 + x2) * 0.5f; - const float m2y = (y3 + y2) * 0.5f; - const float m3x = (x3 + x4) * 0.5f; - const float m3y = (y3 + y4) * 0.5f; - const float m4x = (m1x + m2x) * 0.5f; - const float m4y = (m1y + m2y) * 0.5f; - const float m5x = (m3x + m2x) * 0.5f; - const float m5y = (m3y + m2y) * 0.5f; - - const float error1X = m4x - x2; - const float error1Y = m4y - y2; - const float error2X = m5x - x3; - const float error2Y = m5y - y3; + auto m1x = (x1 + x2) * 0.5f; + auto m1y = (y1 + y2) * 0.5f; + auto m2x = (x3 + x2) * 0.5f; + auto m2y = (y3 + y2) * 0.5f; + auto m3x = (x3 + x4) * 0.5f; + auto m3y = (y3 + y4) * 0.5f; + auto m4x = (m1x + m2x) * 0.5f; + auto m4y = (m1y + m2y) * 0.5f; + auto m5x = (m3x + m2x) * 0.5f; + auto m5y = (m3y + m2y) * 0.5f; + + auto error1X = m4x - x2; + auto error1Y = m4y - y2; + auto error2X = m5x - x3; + auto error2Y = m5y - y3; if (error1X * error1X + error1Y * error1Y > toleranceSquared || error2X * error2X + error2Y * error2Y > toleranceSquared) @@ -255,7 +252,7 @@ bool PathFlatteningIterator::next() *stackPos++ = Path::lineMarker; } } - else if (type == Path::closeSubPathMarker) + else if (isMarker (type, Path::closeSubPathMarker)) { if (x2 != subPathCloseX || y2 != subPathCloseY) { @@ -270,7 +267,7 @@ bool PathFlatteningIterator::next() } else { - jassert (type == Path::moveMarker); + jassert (isMarker (type, Path::moveMarker)); subPathIndex = -1; subPathCloseX = x1 = x2; diff --git a/source/modules/juce_graphics/geometry/juce_PathIterator.h b/source/modules/juce_graphics/geometry/juce_PathIterator.h index 0e0c5de79..96c70a852 100644 --- a/source/modules/juce_graphics/geometry/juce_PathIterator.h +++ b/source/modules/juce_graphics/geometry/juce_PathIterator.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PATHITERATOR_H_INCLUDED -#define JUCE_PATHITERATOR_H_INCLUDED +#pragma once //============================================================================== @@ -96,15 +97,12 @@ private: const AffineTransform transform; float* points; const float toleranceSquared; - float subPathCloseX, subPathCloseY; + float subPathCloseX = 0, subPathCloseY = 0; const bool isIdentityTransform; - HeapBlock stackBase; + HeapBlock stackBase { 32 }; float* stackPos; - size_t index, stackSize; + size_t index = 0, stackSize = 32; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PathFlatteningIterator) }; - - -#endif // JUCE_PATHITERATOR_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_PathStrokeType.cpp b/source/modules/juce_graphics/geometry/juce_PathStrokeType.cpp index f9a7fbc89..dbab9c7bb 100644 --- a/source/modules/juce_graphics/geometry/juce_PathStrokeType.cpp +++ b/source/modules/juce_graphics/geometry/juce_PathStrokeType.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -76,19 +78,19 @@ namespace PathStrokeHelpers { if (x2 != x3 || y2 != y3) { - const float dx1 = x2 - x1; - const float dy1 = y2 - y1; - const float dx2 = x4 - x3; - const float dy2 = y4 - y3; - const float divisor = dx1 * dy2 - dx2 * dy1; + auto dx1 = x2 - x1; + auto dy1 = y2 - y1; + auto dx2 = x4 - x3; + auto dy2 = y4 - y3; + auto divisor = dx1 * dy2 - dx2 * dy1; - if (divisor == 0) + if (divisor == 0.0f) { - if (! ((dx1 == 0 && dy1 == 0) || (dx2 == 0 && dy2 == 0))) + if (! ((dx1 == 0.0f && dy1 == 0.0f) || (dx2 == 0.0f && dy2 == 0.0f))) { - if (dy1 == 0 && dy2 != 0) + if (dy1 == 0.0f && dy2 != 0.0f) { - const float along = (y1 - y3) / dy2; + auto along = (y1 - y3) / dy2; intersectionX = x3 + along * dx2; intersectionY = y1; @@ -100,9 +102,9 @@ namespace PathStrokeHelpers return along >= 0 && along <= 1.0f; } - if (dy2 == 0 && dy1 != 0) + if (dy2 == 0.0f && dy1 != 0.0f) { - const float along = (y3 - y1) / dy1; + auto along = (y3 - y1) / dy1; intersectionX = x1 + along * dx1; intersectionY = y3; @@ -114,9 +116,9 @@ namespace PathStrokeHelpers return along >= 0 && along <= 1.0f; } - if (dx1 == 0 && dx2 != 0) + if (dx1 == 0.0f && dx2 != 0.0f) { - const float along = (x1 - x3) / dx2; + auto along = (x1 - x3) / dx2; intersectionX = x1; intersectionY = y3 + along * dy2; @@ -129,9 +131,9 @@ namespace PathStrokeHelpers return along >= 0 && along <= 1.0f; } - if (dx2 == 0 && dx1 != 0) + if (dx2 == 0.0f && dx1 != 0.0f) { - const float along = (x3 - x1) / dx1; + auto along = (x3 - x1) / dx1; intersectionX = x3; intersectionY = y1 + along * dy1; @@ -151,14 +153,14 @@ namespace PathStrokeHelpers return false; } - const float along1 = ((y1 - y3) * dx2 - (x1 - x3) * dy2) / divisor; + auto along1 = ((y1 - y3) * dx2 - (x1 - x3) * dy2) / divisor; intersectionX = x1 + along1 * dx1; intersectionY = y1 + along1 * dy1; if (along1 >= 0 && along1 <= 1.0f) { - const float along2 = ((y1 - y3) * dx1 - (x1 - x3) * dy1) / divisor; + auto along2 = ((y1 - y3) * dx1 - (x1 - x3) * dy1) / divisor; if (along2 >= 0 && along2 <= 1.0f) { @@ -293,18 +295,18 @@ namespace PathStrokeHelpers { float offx1, offy1, offx2, offy2; - float dx = x2 - x1; - float dy = y2 - y1; - const float len = juce_hypot (dx, dy); + auto dx = x2 - x1; + auto dy = y2 - y1; + auto len = juce_hypot (dx, dy); - if (len == 0) + if (len == 0.0f) { offx1 = offx2 = x1; offy1 = offy2 = y1; } else { - const float offset = width / len; + auto offset = width / len; dx *= offset; dy *= offset; @@ -324,8 +326,8 @@ namespace PathStrokeHelpers else { // rounded ends - const float midx = (offx1 + offx2) * 0.5f; - const float midy = (offy1 + offy2) * 0.5f; + auto midx = (offx1 + offx2) * 0.5f; + auto midy = (offy1 + offy2) * 0.5f; destPath.cubicTo (x1 + (offx1 - x1) * 0.55f, y1 + (offy1 - y1) * 0.55f, offx1 + (midx - offx1) * 0.45f, offy1 + (midy - offy1) * 0.45f, @@ -369,10 +371,10 @@ namespace PathStrokeHelpers { while (amountAtEnd > 0 && subPath.size() > 0) { - LineSection& l = subPath.getReference (subPath.size() - 1); - float dx = l.rx2 - l.rx1; - float dy = l.ry2 - l.ry1; - const float len = juce_hypot (dx, dy); + auto& l = subPath.getReference (subPath.size() - 1); + auto dx = l.rx2 - l.rx1; + auto dy = l.ry2 - l.ry1; + auto len = juce_hypot (dx, dy); if (len <= amountAtEnd && subPath.size() > 1) { @@ -384,7 +386,7 @@ namespace PathStrokeHelpers } else { - const float prop = jmin (0.9999f, amountAtEnd / len); + auto prop = jmin (0.9999f, amountAtEnd / len); dx *= prop; dy *= prop; l.rx1 += dx; @@ -397,10 +399,10 @@ namespace PathStrokeHelpers while (amountAtStart > 0 && subPath.size() > 0) { - LineSection& l = subPath.getReference (0); - float dx = l.rx2 - l.rx1; - float dy = l.ry2 - l.ry1; - const float len = juce_hypot (dx, dy); + auto& l = subPath.getReference (0); + auto dx = l.rx2 - l.rx1; + auto dy = l.ry2 - l.ry1; + auto len = juce_hypot (dx, dy); if (len <= amountAtStart && subPath.size() > 1) { @@ -412,7 +414,7 @@ namespace PathStrokeHelpers } else { - const float prop = jmin (0.9999f, amountAtStart / len); + auto prop = jmin (0.9999f, amountAtStart / len); dx *= prop; dy *= prop; l.rx2 -= dx; @@ -434,12 +436,12 @@ namespace PathStrokeHelpers if (arrowhead != nullptr) shortenSubPath (subPath, arrowhead->startLength, arrowhead->endLength); - const LineSection& firstLine = subPath.getReference (0); + auto& firstLine = subPath.getReference (0); - float lastX1 = firstLine.lx1; - float lastY1 = firstLine.ly1; - float lastX2 = firstLine.lx2; - float lastY2 = firstLine.ly2; + auto lastX1 = firstLine.lx1; + auto lastY1 = firstLine.ly1; + auto lastX2 = firstLine.lx2; + auto lastY2 = firstLine.ly2; if (isClosed) { @@ -472,11 +474,11 @@ namespace PathStrokeHelpers lastY2 = l.ly2; } - const LineSection& lastLine = subPath.getReference (subPath.size() - 1); + auto& lastLine = subPath.getReference (subPath.size() - 1); if (isClosed) { - const LineSection& l = subPath.getReference (0); + auto& l = subPath.getReference (0); addEdgeAndJoint (destPath, jointStyle, maxMiterExtensionSquared, width, @@ -505,7 +507,7 @@ namespace PathStrokeHelpers for (int i = subPath.size() - 1; --i >= 0;) { - const LineSection& l = subPath.getReference (i); + auto& l = subPath.getReference (i); addEdgeAndJoint (destPath, jointStyle, maxMiterExtensionSquared, width, @@ -572,7 +574,7 @@ namespace PathStrokeHelpers // left/right-hand lines along either side of it... PathFlatteningIterator it (*sourcePath, transform, Path::defaultToleranceForMeasurement / extraAccuracy); - Array subPath; + Array subPath; subPath.ensureStorageAllocated (512); LineSection l; l.x1 = 0; @@ -600,20 +602,20 @@ namespace PathStrokeHelpers float dx = l.x2 - l.x1; float dy = l.y2 - l.y1; - const float hypotSquared = dx*dx + dy*dy; + auto hypotSquared = dx * dx + dy * dy; if (it.closesSubPath || hypotSquared > minSegmentLength || it.isLastInSubpath()) { - const float len = std::sqrt (hypotSquared); + auto len = std::sqrt (hypotSquared); - if (len == 0) + if (len == 0.0f) { l.rx1 = l.rx2 = l.lx1 = l.lx2 = l.x1; l.ry1 = l.ry2 = l.ly1 = l.ly2 = l.y1; } else { - const float offset = width / len; + auto offset = width / len; dx *= offset; dy *= offset; diff --git a/source/modules/juce_graphics/geometry/juce_PathStrokeType.h b/source/modules/juce_graphics/geometry/juce_PathStrokeType.h index 2f17bc5bf..de804b143 100644 --- a/source/modules/juce_graphics/geometry/juce_PathStrokeType.h +++ b/source/modules/juce_graphics/geometry/juce_PathStrokeType.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PATHSTROKETYPE_H_INCLUDED -#define JUCE_PATHSTROKETYPE_H_INCLUDED +#pragma once //============================================================================== @@ -200,5 +201,3 @@ private: JUCE_LEAK_DETECTOR (PathStrokeType) }; - -#endif // JUCE_PATHSTROKETYPE_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_Point.h b/source/modules/juce_graphics/geometry/juce_Point.h index 6f8f86385..54efe9f05 100644 --- a/source/modules/juce_graphics/geometry/juce_Point.h +++ b/source/modules/juce_graphics/geometry/juce_Point.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_POINT_H_INCLUDED -#define JUCE_POINT_H_INCLUDED +#pragma once //============================================================================== @@ -238,6 +239,3 @@ public: /** Multiplies the point's coordinates by a scalar value. */ template Point operator* (ValueType value, Point p) noexcept { return p * value; } - - -#endif // JUCE_POINT_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_Rectangle.h b/source/modules/juce_graphics/geometry/juce_Rectangle.h index bd13c30d2..dca99f300 100644 --- a/source/modules/juce_graphics/geometry/juce_Rectangle.h +++ b/source/modules/juce_graphics/geometry/juce_Rectangle.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RECTANGLE_H_INCLUDED -#define JUCE_RECTANGLE_H_INCLUDED +#pragma once //============================================================================== @@ -83,7 +84,7 @@ public: static Rectangle leftTopRightBottom (ValueType left, ValueType top, ValueType right, ValueType bottom) noexcept { - return Rectangle (left, top, right - left, bottom - top); + return { left, top, right - left, bottom - top }; } Rectangle& operator= (const Rectangle& other) noexcept @@ -101,7 +102,7 @@ public: bool isEmpty() const noexcept { return w <= ValueType() || h <= ValueType(); } /** Returns true if the rectangle's values are all finite numbers, i.e. not NaN or infinity. */ - inline bool isFinite() const noexcept { return pos.isFinite() && juce_isfinite(w) && juce_isfinite(h); } + inline bool isFinite() const noexcept { return pos.isFinite() && juce_isfinite (w) && juce_isfinite (h); } /** Returns the x coordinate of the rectangle's left-hand-side. */ inline ValueType getX() const noexcept { return pos.x; } @@ -128,8 +129,8 @@ public: ValueType getCentreY() const noexcept { return pos.y + h / (ValueType) 2; } /** Returns the centre point of the rectangle. */ - Point getCentre() const noexcept { return Point (pos.x + w / (ValueType) 2, - pos.y + h / (ValueType) 2); } + Point getCentre() const noexcept { return { pos.x + w / (ValueType) 2, + pos.y + h / (ValueType) 2 }; } /** Returns the aspect ratio of the rectangle's width / height. If widthOverHeight is true, it returns width / height; if widthOverHeight is false, @@ -150,13 +151,13 @@ public: Point getTopLeft() const noexcept { return pos; } /** Returns the rectangle's top-right position as a Point. */ - Point getTopRight() const noexcept { return Point (pos.x + w, pos.y); } + Point getTopRight() const noexcept { return { pos.x + w, pos.y }; } /** Returns the rectangle's bottom-left position as a Point. */ - Point getBottomLeft() const noexcept { return Point (pos.x, pos.y + h); } + Point getBottomLeft() const noexcept { return { pos.x, pos.y + h }; } /** Returns the rectangle's bottom-right position as a Point. */ - Point getBottomRight() const noexcept { return Point (pos.x + w, pos.y + h); } + Point getBottomRight() const noexcept { return { pos.x + w, pos.y + h }; } /** Returns the rectangle's left and right positions as a Range. */ Range getHorizontalRange() const noexcept { return Range::withStartAndLength (pos.x, w); } @@ -197,42 +198,42 @@ public: void setVerticalRange (Range range) noexcept { pos.y = range.getStart(); h = range.getLength(); } /** Returns a rectangle which has the same size and y-position as this one, but with a different x-position. */ - Rectangle withX (ValueType newX) const noexcept { return Rectangle (newX, pos.y, w, h); } + Rectangle withX (ValueType newX) const noexcept { return { newX, pos.y, w, h }; } /** Returns a rectangle which has the same size and x-position as this one, but with a different y-position. */ - Rectangle withY (ValueType newY) const noexcept { return Rectangle (pos.x, newY, w, h); } + Rectangle withY (ValueType newY) const noexcept { return { pos.x, newY, w, h }; } /** Returns a rectangle which has the same size and y-position as this one, but whose right-hand edge has the given position. */ - Rectangle withRightX (ValueType newRightX) const noexcept { return Rectangle (newRightX - w, pos.y, w, h); } + Rectangle withRightX (ValueType newRightX) const noexcept { return { newRightX - w, pos.y, w, h }; } /** Returns a rectangle which has the same size and x-position as this one, but whose bottom edge has the given position. */ - Rectangle withBottomY (ValueType newBottomY) const noexcept { return Rectangle (pos.x, newBottomY - h, w, h); } + Rectangle withBottomY (ValueType newBottomY) const noexcept { return { pos.x, newBottomY - h, w, h }; } /** Returns a rectangle with the same size as this one, but a new position. */ - Rectangle withPosition (ValueType newX, ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); } + Rectangle withPosition (ValueType newX, ValueType newY) const noexcept { return { newX, newY, w, h }; } /** Returns a rectangle with the same size as this one, but a new position. */ - Rectangle withPosition (Point newPos) const noexcept { return Rectangle (newPos.x, newPos.y, w, h); } + Rectangle withPosition (Point newPos) const noexcept { return { newPos.x, newPos.y, w, h }; } /** Returns a rectangle whose size is the same as this one, but whose top-left position is (0, 0). */ - Rectangle withZeroOrigin() const noexcept { return Rectangle (w, h); } + Rectangle withZeroOrigin() const noexcept { return { w, h }; } /** Returns a rectangle with the same size as this one, but a new centre position. */ - Rectangle withCentre (Point newCentre) const noexcept { return Rectangle (newCentre.x - w / (ValueType) 2, - newCentre.y - h / (ValueType) 2, w, h); } + Rectangle withCentre (Point newCentre) const noexcept { return { newCentre.x - w / (ValueType) 2, + newCentre.y - h / (ValueType) 2, w, h }; } /** Returns a rectangle which has the same position and height as this one, but with a different width. */ - Rectangle withWidth (ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); } + Rectangle withWidth (ValueType newWidth) const noexcept { return { pos.x, pos.y, newWidth, h }; } /** Returns a rectangle which has the same position and width as this one, but with a different height. */ - Rectangle withHeight (ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); } + Rectangle withHeight (ValueType newHeight) const noexcept { return { pos.x, pos.y, w, newHeight }; } /** Returns a rectangle with the same top-left position as this one, but a new size. */ - Rectangle withSize (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); } + Rectangle withSize (ValueType newWidth, ValueType newHeight) const noexcept { return { pos.x, pos.y, newWidth, newHeight }; } /** Returns a rectangle with the same centre position as this one, but a new size. */ - Rectangle withSizeKeepingCentre (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x + (w - newWidth) / (ValueType) 2, - pos.y + (h - newHeight) / (ValueType) 2, newWidth, newHeight); } + Rectangle withSizeKeepingCentre (ValueType newWidth, ValueType newHeight) const noexcept { return { pos.x + (w - newWidth) / (ValueType) 2, + pos.y + (h - newHeight) / (ValueType) 2, newWidth, newHeight }; } /** Moves the x position, adjusting the width so that the right-hand edge remains in the same place. If the x is moved to be on the right of the current right-hand edge, the width will be set to zero. @@ -244,7 +245,7 @@ public: If the new x is beyond the right of the current right-hand edge, the width will be set to zero. @see setLeft */ - Rectangle withLeft (ValueType newLeft) const noexcept { return Rectangle (newLeft, pos.y, jmax (ValueType(), pos.x + w - newLeft), h); } + Rectangle withLeft (ValueType newLeft) const noexcept { return { newLeft, pos.y, jmax (ValueType(), pos.x + w - newLeft), h }; } /** Moves the y position, adjusting the height so that the bottom edge remains in the same place. If the y is moved to be below the current bottom edge, the height will be set to zero. @@ -256,7 +257,7 @@ public: If the new y is beyond the bottom of the current rectangle, the height will be set to zero. @see setTop */ - Rectangle withTop (ValueType newTop) const noexcept { return Rectangle (pos.x, newTop, w, jmax (ValueType(), pos.y + h - newTop)); } + Rectangle withTop (ValueType newTop) const noexcept { return { pos.x, newTop, w, jmax (ValueType(), pos.y + h - newTop) }; } /** Adjusts the width so that the right-hand edge of the rectangle has this new value. If the new right is below the current X value, the X will be pushed down to match it. @@ -268,7 +269,7 @@ public: If the new right edge is below the current left-hand edge, the width will be set to zero. @see setRight */ - Rectangle withRight (ValueType newRight) const noexcept { return Rectangle (jmin (pos.x, newRight), pos.y, jmax (ValueType(), newRight - pos.x), h); } + Rectangle withRight (ValueType newRight) const noexcept { return { jmin (pos.x, newRight), pos.y, jmax (ValueType(), newRight - pos.x), h }; } /** Adjusts the height so that the bottom edge of the rectangle has this new value. If the new bottom is lower than the current Y value, the Y will be pushed down to match it. @@ -280,7 +281,7 @@ public: If the new y is beyond the bottom of the current rectangle, the height will be set to zero. @see setBottom */ - Rectangle withBottom (ValueType newBottom) const noexcept { return Rectangle (pos.x, jmin (pos.y, newBottom), w, jmax (ValueType(), newBottom - pos.y)); } + Rectangle withBottom (ValueType newBottom) const noexcept { return { pos.x, jmin (pos.y, newBottom), w, jmax (ValueType(), newBottom - pos.y) }; } /** Returns a version of this rectangle with the given amount removed from its left-hand edge. */ Rectangle withTrimmedLeft (ValueType amountToRemove) const noexcept { return withLeft (pos.x + amountToRemove); } @@ -307,13 +308,13 @@ public: Rectangle translated (ValueType deltaX, ValueType deltaY) const noexcept { - return Rectangle (pos.x + deltaX, pos.y + deltaY, w, h); + return { pos.x + deltaX, pos.y + deltaY, w, h }; } /** Returns a rectangle which is the same as this one moved by a given amount. */ Rectangle operator+ (Point deltaPosition) const noexcept { - return Rectangle (pos.x + deltaPosition.x, pos.y + deltaPosition.y, w, h); + return { pos.x + deltaPosition.x, pos.y + deltaPosition.y, w, h }; } /** Moves this rectangle by a given amount. */ @@ -326,7 +327,7 @@ public: /** Returns a rectangle which is the same as this one moved by a given amount. */ Rectangle operator- (Point deltaPosition) const noexcept { - return Rectangle (pos.x - deltaPosition.x, pos.y - deltaPosition.y, w, h); + return { pos.x - deltaPosition.x, pos.y - deltaPosition.y, w, h }; } /** Moves this rectangle by a given amount. */ @@ -418,8 +419,8 @@ public: void expand (ValueType deltaX, ValueType deltaY) noexcept { - const ValueType nw = jmax (ValueType(), w + deltaX * 2); - const ValueType nh = jmax (ValueType(), h + deltaY * 2); + auto nw = jmax (ValueType(), w + deltaX * 2); + auto nh = jmax (ValueType(), h + deltaY * 2); setBounds (pos.x - deltaX, pos.y - deltaY, nw, nh); } @@ -431,9 +432,9 @@ public: Rectangle expanded (ValueType deltaX, ValueType deltaY) const noexcept { - const ValueType nw = jmax (ValueType(), w + deltaX * 2); - const ValueType nh = jmax (ValueType(), h + deltaY * 2); - return Rectangle (pos.x - deltaX, pos.y - deltaY, nw, nh); + auto nw = jmax (ValueType(), w + deltaX * 2); + auto nh = jmax (ValueType(), h + deltaY * 2); + return { pos.x - deltaX, pos.y - deltaY, nw, nh }; } /** Returns a rectangle that is larger than this one by a given amount. @@ -548,8 +549,8 @@ public: /** Returns the nearest point to the specified point that lies within this rectangle. */ Point getConstrainedPoint (Point point) const noexcept { - return Point (jlimit (pos.x, pos.x + w, point.x), - jlimit (pos.y, pos.y + h, point.y)); + return { jlimit (pos.x, pos.x + w, point.x), + jlimit (pos.y, pos.y + h, point.y) }; } /** Returns a point within this rectangle, specified as proportional coordinates. @@ -560,8 +561,8 @@ public: template Point getRelativePoint (FloatType relativeX, FloatType relativeY) const noexcept { - return Point (pos.x + static_cast (w * relativeX), - pos.y + static_cast (h * relativeY)); + return { pos.x + static_cast (w * relativeX), + pos.y + static_cast (h * relativeY) }; } /** Returns a proportion of the width of this rectangle. */ @@ -585,10 +586,10 @@ public: template Rectangle getProportion (Rectangle proportionalRect) const noexcept { - return Rectangle (pos.x + static_cast (w * proportionalRect.pos.x), - pos.y + static_cast (h * proportionalRect.pos.y), - proportionOfWidth (proportionalRect.w), - proportionOfHeight (proportionalRect.h)); + return { pos.x + static_cast (w * proportionalRect.pos.x), + pos.y + static_cast (h * proportionalRect.pos.y), + proportionOfWidth (proportionalRect.w), + proportionOfHeight (proportionalRect.h) }; } //============================================================================== @@ -611,14 +612,14 @@ public: } /** Returns true if this other rectangle is completely inside this one. */ - bool contains (const Rectangle& other) const noexcept + bool contains (Rectangle other) const noexcept { return pos.x <= other.pos.x && pos.y <= other.pos.y && pos.x + w >= other.pos.x + other.w && pos.y + h >= other.pos.y + other.h; } /** Returns true if any part of another rectangle overlaps this one. */ - bool intersects (const Rectangle& other) const noexcept + bool intersects (Rectangle other) const noexcept { return pos.x + w > other.pos.x && pos.y + h > other.pos.y @@ -641,17 +642,21 @@ public: /** Returns the region that is the overlap between this and another rectangle. If the two rectangles don't overlap, the rectangle returned will be empty. */ - Rectangle getIntersection (const Rectangle& other) const noexcept + Rectangle getIntersection (Rectangle other) const noexcept { - const ValueType nx = jmax (pos.x, other.pos.x); - const ValueType ny = jmax (pos.y, other.pos.y); - const ValueType nw = jmin (pos.x + w, other.pos.x + other.w) - nx; - const ValueType nh = jmin (pos.y + h, other.pos.y + other.h) - ny; + auto nx = jmax (pos.x, other.pos.x); + auto ny = jmax (pos.y, other.pos.y); + auto nw = jmin (pos.x + w, other.pos.x + other.w) - nx; - if (nw >= ValueType() && nh >= ValueType()) - return Rectangle (nx, ny, nw, nh); + if (nw >= ValueType()) + { + auto nh = jmin (pos.y + h, other.pos.y + other.h) - ny; + + if (nh >= ValueType()) + return { nx, ny, nw, nh }; + } - return Rectangle(); + return {}; } /** Clips a set of rectangle coordinates so that they lie only within this one. @@ -660,12 +665,12 @@ public: */ bool intersectRectangle (ValueType& otherX, ValueType& otherY, ValueType& otherW, ValueType& otherH) const noexcept { - const ValueType maxX (jmax (otherX, pos.x)); + auto maxX = jmax (otherX, pos.x); otherW = jmin (otherX + otherW, pos.x + w) - maxX; if (otherW > ValueType()) { - const ValueType maxY (jmax (otherY, pos.y)); + auto maxY = jmax (otherY, pos.y); otherH = jmin (otherY + otherH, pos.y + h) - maxY; if (otherH > ValueType()) @@ -684,7 +689,7 @@ public: bool intersectRectangle (Rectangle& rectangleToClip) const noexcept { return intersectRectangle (rectangleToClip.pos.x, rectangleToClip.pos.y, - rectangleToClip.w, rectangleToClip.h); + rectangleToClip.w, rectangleToClip.h); } /** Returns the smallest rectangle that contains both this one and the one passed-in. @@ -692,17 +697,17 @@ public: If either this or the other rectangle are empty, they will not be counted as part of the resulting region. */ - Rectangle getUnion (const Rectangle& other) const noexcept + Rectangle getUnion (Rectangle other) const noexcept { if (other.isEmpty()) return *this; if (isEmpty()) return other; - const ValueType newX = jmin (pos.x, other.pos.x); - const ValueType newY = jmin (pos.y, other.pos.y); + auto newX = jmin (pos.x, other.pos.x); + auto newY = jmin (pos.y, other.pos.y); - return Rectangle (newX, newY, - jmax (pos.x + w, other.pos.x + other.w) - newX, - jmax (pos.y + h, other.pos.y + other.h) - newY); + return { newX, newY, + jmax (pos.x + w, other.pos.x + other.w) - newX, + jmax (pos.y + h, other.pos.y + other.h) - newY }; } /** If this rectangle merged with another one results in a simple rectangle, this @@ -711,12 +716,12 @@ public: Returns false and does nothing to this rectangle if the two rectangles don't overlap, or if they form a complex region. */ - bool enlargeIfAdjacent (const Rectangle& other) noexcept + bool enlargeIfAdjacent (Rectangle other) noexcept { if (pos.x == other.pos.x && getRight() == other.getRight() && (other.getBottom() >= pos.y && other.pos.y <= getBottom())) { - const ValueType newY = jmin (pos.y, other.pos.y); + auto newY = jmin (pos.y, other.pos.y); h = jmax (getBottom(), other.getBottom()) - newY; pos.y = newY; return true; @@ -725,7 +730,7 @@ public: if (pos.y == other.pos.y && getBottom() == other.getBottom() && (other.getRight() >= pos.x && other.pos.x <= getRight())) { - const ValueType newX = jmin (pos.x, other.pos.x); + auto newX = jmin (pos.x, other.pos.x); w = jmax (getRight(), other.getRight()) - newX; pos.x = newX; return true; @@ -740,16 +745,16 @@ public: Returns false and does nothing to this rectangle if the two rectangles don't overlap, or if removing the other one would form a complex region. */ - bool reduceIfPartlyContainedIn (const Rectangle& other) noexcept + bool reduceIfPartlyContainedIn (Rectangle other) noexcept { int inside = 0; - const ValueType otherR (other.getRight()); + auto otherR = other.getRight(); if (pos.x >= other.pos.x && pos.x < otherR) inside = 1; - const ValueType otherB (other.getBottom()); + auto otherB = other.getBottom(); if (pos.y >= other.pos.y && pos.y < otherB) inside |= 2; - const ValueType r (pos.x + w); + auto r = pos.x + w; if (r >= other.pos.x && r < otherR) inside |= 4; - const ValueType b (pos.y + h); + auto b = pos.y + h; if (b >= other.pos.y && b < otherB) inside |= 8; switch (inside) @@ -770,14 +775,14 @@ public: is larger than the target rectangle in either dimension, then that dimension will be reduced to fit within the target. */ - Rectangle constrainedWithin (const Rectangle& areaToFitWithin) const noexcept + Rectangle constrainedWithin (Rectangle areaToFitWithin) const noexcept { - const ValueType newW (jmin (w, areaToFitWithin.getWidth())); - const ValueType newH (jmin (h, areaToFitWithin.getHeight())); + auto newW = jmin (w, areaToFitWithin.getWidth()); + auto newH = jmin (h, areaToFitWithin.getHeight()); - return Rectangle (jlimit (areaToFitWithin.getX(), areaToFitWithin.getRight() - newW, pos.x), - jlimit (areaToFitWithin.getY(), areaToFitWithin.getBottom() - newH, pos.y), - newW, newH); + return { jlimit (areaToFitWithin.getX(), areaToFitWithin.getRight() - newW, pos.x), + jlimit (areaToFitWithin.getY(), areaToFitWithin.getBottom() - newH, pos.y), + newW, newH }; } /** Returns the smallest rectangle that can contain the shape created by applying @@ -789,18 +794,18 @@ public: { typedef typename TypeHelpers::SmallestFloatType::type FloatType; - FloatType x1 = static_cast (pos.x), y1 = static_cast (pos.y); - FloatType x2 = static_cast (pos.x + w), y2 = static_cast (pos.y); - FloatType x3 = static_cast (pos.x), y3 = static_cast (pos.y + h); - FloatType x4 = static_cast (x2), y4 = static_cast (y3); + auto x1 = static_cast (pos.x), y1 = static_cast (pos.y); + auto x2 = static_cast (pos.x + w), y2 = static_cast (pos.y); + auto x3 = static_cast (pos.x), y3 = static_cast (pos.y + h); + auto x4 = static_cast (x2), y4 = static_cast (y3); transform.transformPoints (x1, y1, x2, y2); transform.transformPoints (x3, y3, x4, y4); - const FloatType rx1 = jmin (x1, x2, x3, x4); - const FloatType rx2 = jmax (x1, x2, x3, x4); - const FloatType ry1 = jmin (y1, y2, y3, y4); - const FloatType ry2 = jmax (y1, y2, y3, y4); + auto rx1 = jmin (x1, x2, x3, x4); + auto rx2 = jmax (x1, x2, x3, x4); + auto ry1 = jmin (y1, y2, y3, y4); + auto ry2 = jmax (y1, y2, y3, y4); Rectangle r; Rectangle (rx1, ry1, rx2 - rx1, ry2 - ry1).copyWithRounding (r); @@ -813,12 +818,10 @@ public: */ Rectangle getSmallestIntegerContainer() const noexcept { - const int x1 = floorAsInt (pos.x); - const int y1 = floorAsInt (pos.y); - const int x2 = ceilAsInt (pos.x + w); - const int y2 = ceilAsInt (pos.y + h); - - return Rectangle (x1, y1, x2 - x1, y2 - y1); + return Rectangle::leftTopRightBottom (floorAsInt (pos.x), + floorAsInt (pos.y), + ceilAsInt (pos.x + w), + ceilAsInt (pos.y + h)); } /** Casts this rectangle to a Rectangle. @@ -828,8 +831,8 @@ public: */ Rectangle toNearestInt() const noexcept { - return Rectangle (roundToInt (pos.x), roundToInt (pos.y), - roundToInt (w), roundToInt (h)); + return { roundToInt (pos.x), roundToInt (pos.y), + roundToInt (w), roundToInt (h) }; } /** Casts this rectangle to a Rectangle. @@ -837,8 +840,8 @@ public: */ Rectangle toFloat() const noexcept { - return Rectangle (static_cast (pos.x), static_cast (pos.y), - static_cast (w), static_cast (h)); + return { static_cast (pos.x), static_cast (pos.y), + static_cast (w), static_cast (h) }; } /** Casts this rectangle to a Rectangle. @@ -846,8 +849,8 @@ public: */ Rectangle toDouble() const noexcept { - return Rectangle (static_cast (pos.x), static_cast (pos.y), - static_cast (w), static_cast (h)); + return { static_cast (pos.x), static_cast (pos.y), + static_cast (w), static_cast (h) }; } /** Casts this rectangle to a Rectangle with the given type. @@ -863,15 +866,15 @@ public: } /** Returns the smallest Rectangle that can contain a set of points. */ - static Rectangle findAreaContainingPoints (const Point* const points, const int numPoints) noexcept + static Rectangle findAreaContainingPoints (const Point* points, int numPoints) noexcept { - if (numPoints == 0) - return Rectangle(); + if (numPoints <= 0) + return {}; - ValueType minX (points[0].x); - ValueType maxX (minX); - ValueType minY (points[0].y); - ValueType maxY (minY); + auto minX = points[0].x; + auto maxX = minX; + auto minY = points[0].y; + auto maxY = minY; for (int i = 1; i < numPoints; ++i) { @@ -881,7 +884,7 @@ public: maxY = jmax (maxY, points[i].y); } - return Rectangle (minX, minY, maxX - minX, maxY - minY); + return { minX, minY, maxX - minX, maxY - minY }; } //============================================================================== @@ -890,14 +893,14 @@ public: @see intersectRectangle */ static bool intersectRectangles (ValueType& x1, ValueType& y1, ValueType& w1, ValueType& h1, - const ValueType x2, const ValueType y2, const ValueType w2, const ValueType h2) noexcept + ValueType x2, ValueType y2, ValueType w2, ValueType h2) noexcept { - const ValueType x (jmax (x1, x2)); + auto x = jmax (x1, x2); w1 = jmin (x1 + w1, x2 + w2) - x; if (w1 > ValueType()) { - const ValueType y (jmax (y1, y2)); + auto y = jmax (y1, y2); h1 = jmin (y1 + h1, y2 + h2) - y; if (h1 > ValueType()) @@ -943,10 +946,10 @@ public: StringArray toks; toks.addTokens (stringVersion.text.findEndOfWhitespace(), ",; \t\r\n", ""); - return Rectangle (parseIntAfterSpace (toks[0]), - parseIntAfterSpace (toks[1]), - parseIntAfterSpace (toks[2]), - parseIntAfterSpace (toks[3])); + return { parseIntAfterSpace (toks[0]), + parseIntAfterSpace (toks[1]), + parseIntAfterSpace (toks[2]), + parseIntAfterSpace (toks[3]) }; } #ifndef DOXYGEN @@ -968,12 +971,9 @@ private: void copyWithRounding (Rectangle& result) const noexcept { result = toDouble(); } static int floorAsInt (int n) noexcept { return n; } - static int floorAsInt (float n) noexcept { return (int) std::floor (n); } - static int floorAsInt (double n) noexcept { return (int) std::floor (n); } + static int floorAsInt (float n) noexcept { return n > (float) std::numeric_limits::min() ? (int) std::floor (n) : std::numeric_limits::min(); } + static int floorAsInt (double n) noexcept { return n > (double) std::numeric_limits::min() ? (int) std::floor (n) : std::numeric_limits::min(); } static int ceilAsInt (int n) noexcept { return n; } - static int ceilAsInt (float n) noexcept { return (int) std::ceil (n); } - static int ceilAsInt (double n) noexcept { return (int) std::ceil (n); } + static int ceilAsInt (float n) noexcept { return n < (float) std::numeric_limits::max() ? (int) std::ceil (n) : std::numeric_limits::max(); } + static int ceilAsInt (double n) noexcept { return n < (double) std::numeric_limits::max() ? (int) std::ceil (n) : std::numeric_limits::max(); } }; - - -#endif // JUCE_RECTANGLE_H_INCLUDED diff --git a/source/modules/juce_graphics/geometry/juce_RectangleList.h b/source/modules/juce_graphics/geometry/juce_RectangleList.h index ac3bc7d82..e611fcb8f 100644 --- a/source/modules/juce_graphics/geometry/juce_RectangleList.h +++ b/source/modules/juce_graphics/geometry/juce_RectangleList.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RECTANGLELIST_H_INCLUDED -#define JUCE_RECTANGLELIST_H_INCLUDED +#pragma once //============================================================================== @@ -64,22 +65,22 @@ public: return *this; } - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ RectangleList (RectangleList&& other) noexcept : rects (static_cast&&> (other.rects)) { } + /** Move assignment operator */ RectangleList& operator= (RectangleList&& other) noexcept { rects = static_cast&&> (other.rects); return *this; } - #endif //============================================================================== /** Returns true if the region is empty. */ - bool isEmpty() const noexcept { return rects.size() == 0; } + bool isEmpty() const noexcept { return rects.isEmpty(); } /** Returns the number of rectangles in the list. */ int getNumRectangles() const noexcept { return rects.size(); } @@ -111,7 +112,7 @@ public: if (! rect.isEmpty()) { - if (rects.size() == 0) + if (isEmpty()) { rects.add (rect); } @@ -121,7 +122,7 @@ public: for (int j = rects.size(); --j >= 0;) { - RectangleType& ourRect = rects.getReference (j); + auto& ourRect = rects.getReference (j); if (rect.intersects (ourRect)) { @@ -132,19 +133,17 @@ public: } } - if (anyOverlaps && rects.size() > 0) + if (anyOverlaps && ! isEmpty()) { RectangleList r (rect); - for (int i = rects.size(); --i >= 0;) + for (auto& ourRect : rects) { - const RectangleType& ourRect = rects.getReference (i); - if (rect.intersects (ourRect)) { r.subtract (ourRect); - if (r.rects.size() == 0) + if (r.isEmpty()) return; } } @@ -192,7 +191,7 @@ public: */ void add (const RectangleList& other) { - for (const RectangleType* r = other.begin(), * const e = other.end(); r != e; ++r) + for (auto& r : other) add (*r); } @@ -203,23 +202,21 @@ public: */ void subtract (const RectangleType& rect) { - const int originalNumRects = rects.size(); - - if (originalNumRects > 0) + if (auto numRects = rects.size()) { - const ValueType x1 = rect.getX(); - const ValueType y1 = rect.getY(); - const ValueType x2 = x1 + rect.getWidth(); - const ValueType y2 = y1 + rect.getHeight(); + auto x1 = rect.getX(); + auto y1 = rect.getY(); + auto x2 = x1 + rect.getWidth(); + auto y2 = y1 + rect.getHeight(); - for (int i = getNumRectangles(); --i >= 0;) + for (int i = numRects; --i >= 0;) { - RectangleType& r = rects.getReference (i); + auto& r = rects.getReference (i); - const ValueType rx1 = r.getX(); - const ValueType ry1 = r.getY(); - const ValueType rx2 = rx1 + r.getWidth(); - const ValueType ry2 = ry1 + r.getHeight(); + auto rx1 = r.getX(); + auto ry1 = r.getY(); + auto rx2 = rx1 + r.getWidth(); + auto ry2 = ry1 + r.getHeight(); if (! (x2 <= rx1 || x1 >= rx2 || y2 <= ry1 || y1 >= ry2)) { @@ -293,10 +290,15 @@ public: */ bool subtract (const RectangleList& otherList) { - for (int i = otherList.rects.size(); --i >= 0 && rects.size() > 0;) - subtract (otherList.rects.getReference (i)); + for (auto& r : otherList) + { + if (isEmpty()) + return false; + + subtract (r); + } - return rects.size() > 0; + return ! isEmpty(); } /** Removes any areas of the region that lie outside a given rectangle. @@ -322,7 +324,7 @@ public: { for (int i = rects.size(); --i >= 0;) { - RectangleType& r = rects.getReference (i); + auto& r = rects.getReference (i); if (! rect.intersectRectangle (r)) rects.remove (i); @@ -346,18 +348,16 @@ public: template bool clipTo (const RectangleList& other) { - if (rects.size() == 0) + if (isEmpty()) return false; RectangleList result; - for (int j = 0; j < rects.size(); ++j) + for (auto& rect : rects) { - const RectangleType& rect = rects.getReference (j); - - for (const Rectangle* r = other.begin(), * const e = other.end(); r != e; ++r) + for (auto& r : other) { - RectangleType clipped (r->template toType()); + auto clipped = r.template toType(); if (rect.intersectRectangle (clipped)) result.rects.add (clipped); @@ -384,17 +384,11 @@ public: destRegion.clear(); if (! rect.isEmpty()) - { - for (int i = rects.size(); --i >= 0;) - { - RectangleType r (rects.getReference (i)); - + for (auto& r : rects) if (rect.intersectRectangle (r)) destRegion.rects.add (r); - } - } - return destRegion.rects.size() > 0; + return ! destRegion.isEmpty(); } /** Swaps the contents of this and another list. @@ -413,8 +407,8 @@ public: */ bool containsPoint (Point point) const noexcept { - for (const RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - if (r->contains (point)) + for (auto& r : rects) + if (r.contains (point)) return true; return false; @@ -440,15 +434,15 @@ public: { RectangleList r (rectangleToCheck); - for (int i = rects.size(); --i >= 0;) + for (auto& rect : rects) { - r.subtract (rects.getReference (i)); + r.subtract (rect); - if (r.rects.size() == 0) + if (r.isEmpty()) return true; } } - else if (rects.size() > 0) + else if (! isEmpty()) { return rects.getReference (0).contains (rectangleToCheck); } @@ -464,8 +458,8 @@ public: */ bool intersectsRectangle (const RectangleType& rectangleToCheck) const noexcept { - for (const RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - if (r->intersects (rectangleToCheck)) + for (auto& r : rects) + if (r.intersects (rectangleToCheck)) return true; return false; @@ -477,8 +471,8 @@ public: */ bool intersects (const RectangleList& other) const noexcept { - for (const RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - if (other.intersectsRectangle (*r)) + for (auto& r : rects) + if (other.intersectsRectangle (r)) return true; return false; @@ -488,24 +482,22 @@ public: /** Returns the smallest rectangle that can enclose the whole of this region. */ RectangleType getBounds() const noexcept { - if (rects.size() <= 1) - { - if (rects.size() == 0) - return RectangleType(); + if (isEmpty()) + return {}; - return rects.getReference (0); - } + auto& r = rects.getReference (0); - const RectangleType& r = rects.getReference (0); + if (rects.size() == 1) + return r; - ValueType minX = r.getX(); - ValueType minY = r.getY(); - ValueType maxX = minX + r.getWidth(); - ValueType maxY = minY + r.getHeight(); + auto minX = r.getX(); + auto minY = r.getY(); + auto maxX = minX + r.getWidth(); + auto maxY = minY + r.getHeight(); for (int i = rects.size(); --i > 0;) { - const RectangleType& r2 = rects.getReference (i); + auto& r2 = rects.getReference (i); minX = jmin (minX, r2.getX()); minY = jmin (minY, r2.getY()); @@ -513,7 +505,7 @@ public: maxY = jmax (maxY, r2.getBottom()); } - return RectangleType (minX, minY, maxX - minX, maxY - minY); + return { minX, minY, maxX - minX, maxY - minY }; } /** Optimises the list into a minimum number of constituent rectangles. @@ -526,19 +518,19 @@ public: { for (int i = 0; i < rects.size() - 1; ++i) { - RectangleType& r = rects.getReference (i); - const ValueType rx1 = r.getX(); - const ValueType ry1 = r.getY(); - const ValueType rx2 = rx1 + r.getWidth(); - const ValueType ry2 = ry1 + r.getHeight(); + auto& r = rects.getReference (i); + auto rx1 = r.getX(); + auto ry1 = r.getY(); + auto rx2 = rx1 + r.getWidth(); + auto ry2 = ry1 + r.getHeight(); for (int j = rects.size(); --j > i;) { - RectangleType& r2 = rects.getReference (j); - const ValueType jrx1 = r2.getX(); - const ValueType jry1 = r2.getY(); - const ValueType jrx2 = jrx1 + r2.getWidth(); - const ValueType jry2 = jry1 + r2.getHeight(); + auto& r2 = rects.getReference (j); + auto jrx1 = r2.getX(); + auto jry1 = r2.getY(); + auto jrx2 = jrx1 + r2.getWidth(); + auto jry2 = jry1 + r2.getHeight(); // if the vertical edges of any blocks are touching and their horizontals don't // line up, split them horizontally.. @@ -579,7 +571,7 @@ public: for (int i = 0; i < rects.size() - 1; ++i) { - RectangleType& r = rects.getReference (i); + auto& r = rects.getReference (i); for (int j = rects.size(); --j > i;) { @@ -596,8 +588,8 @@ public: /** Adds an x and y value to all the coordinates. */ void offsetAll (Point offset) noexcept { - for (RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - *r += offset; + for (auto& r : rects) + r += offset; } /** Adds an x and y value to all the coordinates. */ @@ -610,8 +602,8 @@ public: template void scaleAll (ScaleType scaleFactor) noexcept { - for (RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - *r *= scaleFactor; + for (auto& r : rects) + r *= scaleFactor; } /** Applies a transform to all the rectangles. @@ -620,8 +612,8 @@ public: */ void transformAll (const AffineTransform& transform) noexcept { - for (RectangleType* r = rects.begin(), * const e = rects.end(); r != e; ++r) - *r = r->transformedBy (transform); + for (auto& r : rects) + r = r.transformedBy (transform); } //============================================================================== @@ -630,8 +622,8 @@ public: { Path p; - for (int i = 0; i < rects.size(); ++i) - p.addRectangle (rects.getReference (i)); + for (auto& r : rects) + p.addRectangle (r); return p; } @@ -657,6 +649,3 @@ private: //============================================================================== Array rects; }; - - -#endif // JUCE_RECTANGLELIST_H_INCLUDED diff --git a/source/modules/juce_graphics/image_formats/jpglib/jccolor.c b/source/modules/juce_graphics/image_formats/jpglib/jccolor.c index fa239c137..8ad78efc6 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jccolor.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jccolor.c @@ -132,11 +132,11 @@ rgb_ycc_convert (j_compress_ptr cinfo, JDIMENSION output_row, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_ycc_tab; - register JSAMPROW inptr; - register JSAMPROW outptr0, outptr1, outptr2; - register JDIMENSION col; + int r, g, b; + INT32 * ctab = cconvert->rgb_ycc_tab; + JSAMPROW inptr; + JSAMPROW outptr0, outptr1, outptr2; + JDIMENSION col; JDIMENSION num_cols = cinfo->image_width; while (--num_rows >= 0) { @@ -188,11 +188,11 @@ rgb_gray_convert (j_compress_ptr cinfo, JDIMENSION output_row, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_ycc_tab; - register JSAMPROW inptr; - register JSAMPROW outptr; - register JDIMENSION col; + int r, g, b; + INT32 * ctab = cconvert->rgb_ycc_tab; + JSAMPROW inptr; + JSAMPROW outptr; + JDIMENSION col; JDIMENSION num_cols = cinfo->image_width; while (--num_rows >= 0) { @@ -227,11 +227,11 @@ cmyk_ycck_convert (j_compress_ptr cinfo, JDIMENSION output_row, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_ycc_tab; - register JSAMPROW inptr; - register JSAMPROW outptr0, outptr1, outptr2, outptr3; - register JDIMENSION col; + int r, g, b; + INT32 * ctab = cconvert->rgb_ycc_tab; + JSAMPROW inptr; + JSAMPROW outptr0, outptr1, outptr2, outptr3; + JDIMENSION col; JDIMENSION num_cols = cinfo->image_width; while (--num_rows >= 0) { @@ -281,9 +281,9 @@ grayscale_convert (j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) { - register JSAMPROW inptr; - register JSAMPROW outptr; - register JDIMENSION col; + JSAMPROW inptr; + JSAMPROW outptr; + JDIMENSION col; JDIMENSION num_cols = cinfo->image_width; int instride = cinfo->input_components; @@ -310,10 +310,10 @@ null_convert (j_compress_ptr cinfo, JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) { - register JSAMPROW inptr; - register JSAMPROW outptr; - register JDIMENSION col; - register int ci; + JSAMPROW inptr; + JSAMPROW outptr; + JDIMENSION col; + int ci; int nc = cinfo->num_components; JDIMENSION num_cols = cinfo->image_width; diff --git a/source/modules/juce_graphics/image_formats/jpglib/jcdctmgr.c b/source/modules/juce_graphics/image_formats/jpglib/jcdctmgr.c index e3f90dc39..0589ccdf6 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jcdctmgr.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jcdctmgr.c @@ -194,9 +194,9 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { /* Load data into workspace, applying unsigned->signed conversion */ - { register DCTELEM *workspaceptr; - register JSAMPROW elemptr; - register int elemr; + { DCTELEM *workspaceptr; + JSAMPROW elemptr; + int elemr; workspaceptr = workspace; for (elemr = 0; elemr < DCTSIZE; elemr++) { @@ -211,7 +211,7 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; #else - { register int elemc; + { int elemc; for (elemc = DCTSIZE; elemc > 0; elemc--) { *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; } @@ -224,9 +224,9 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, (*do_dct) (workspace); /* Quantize/descale the coefficients, and store into coef_blocks[] */ - { register DCTELEM temp, qval; - register int i; - register JCOEFPTR output_ptr = coef_blocks[bi]; + { DCTELEM temp, qval; + int i; + JCOEFPTR output_ptr = coef_blocks[bi]; for (i = 0; i < DCTSIZE2; i++) { qval = divisors[i]; @@ -284,9 +284,9 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) { /* Load data into workspace, applying unsigned->signed conversion */ - { register FAST_FLOAT *workspaceptr; - register JSAMPROW elemptr; - register int elemr; + { FAST_FLOAT *workspaceptr; + JSAMPROW elemptr; + int elemr; workspaceptr = workspace; for (elemr = 0; elemr < DCTSIZE; elemr++) { @@ -301,7 +301,7 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); #else - { register int elemc; + { int elemc; for (elemc = DCTSIZE; elemc > 0; elemc--) { *workspaceptr++ = (FAST_FLOAT) (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); @@ -315,9 +315,9 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, (*do_dct) (workspace); /* Quantize/descale the coefficients, and store into coef_blocks[] */ - { register FAST_FLOAT temp; - register int i; - register JCOEFPTR output_ptr = coef_blocks[bi]; + { FAST_FLOAT temp; + int i; + JCOEFPTR output_ptr = coef_blocks[bi]; for (i = 0; i < DCTSIZE2; i++) { /* Apply the quantization and scaling factor */ diff --git a/source/modules/juce_graphics/image_formats/jpglib/jchuff.c b/source/modules/juce_graphics/image_formats/jpglib/jchuff.c index 581ed59c6..e718cf50a 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jchuff.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jchuff.c @@ -303,8 +303,8 @@ emit_bits (working_state * state, unsigned int code, int size) /* Emit some bits; return TRUE if successful, FALSE if must suspend */ { /* This routine is heavily used, so it's worth coding tightly. */ - register INT32 put_buffer = (INT32) code; - register int put_bits = state->cur.put_bits; + INT32 put_buffer = (INT32) code; + int put_bits = state->cur.put_bits; /* if size is 0, caller used an invalid Huffman table entry */ if (size == 0) @@ -353,9 +353,9 @@ LOCAL(boolean) encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, c_derived_tbl *dctbl, c_derived_tbl *actbl) { - register int temp, temp2; - register int nbits; - register int k, r, i; + int temp, temp2; + int nbits; + int k, r, i; /* Encode the DC coefficient difference per section F.1.2.1 */ @@ -572,9 +572,9 @@ LOCAL(void) htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, long dc_counts[], long ac_counts[]) { - register int temp; - register int nbits; - register int k, r; + int temp; + int nbits; + int k, r; /* Encode the DC coefficient difference per section F.1.2.1 */ diff --git a/source/modules/juce_graphics/image_formats/jpglib/jcphuff.c b/source/modules/juce_graphics/image_formats/jpglib/jcphuff.c index 692b52b9f..f35e75a26 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jcphuff.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jcphuff.c @@ -229,8 +229,8 @@ emit_bits_p (phuff_entropy_ptr entropy, unsigned int code, int size) /* Emit some bits, unless we are in gather mode */ { /* This routine is heavily used, so it's worth coding tightly. */ - register INT32 put_buffer = (INT32) code; - register int put_bits = entropy->put_bits; + INT32 put_buffer = (INT32) code; + int put_bits = entropy->put_bits; /* if size is 0, caller used an invalid Huffman table entry */ if (size == 0) @@ -315,7 +315,7 @@ emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, LOCAL(void) emit_eobrun (phuff_entropy_ptr entropy) { - register int temp, nbits; + int temp, nbits; if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */ temp = entropy->EOBRUN; @@ -377,8 +377,8 @@ METHODDEF(boolean) encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - register int temp, temp2; - register int nbits; + int temp, temp2; + int nbits; int blkn, ci; int Al = cinfo->Al; JBLOCKROW block; @@ -464,9 +464,9 @@ METHODDEF(boolean) encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - register int temp, temp2; - register int nbits; - register int r, k; + int temp, temp2; + int nbits; + int r, k; int Se = cinfo->Se; int Al = cinfo->Al; JBLOCKROW block; @@ -571,7 +571,7 @@ METHODDEF(boolean) encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - register int temp; + int temp; int blkn; int Al = cinfo->Al; JBLOCKROW block; @@ -618,8 +618,8 @@ METHODDEF(boolean) encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - register int temp; - register int r, k; + int temp; + int r, k; int EOB; char *BR_buffer; unsigned int BR; diff --git a/source/modules/juce_graphics/image_formats/jpglib/jcprepct.c b/source/modules/juce_graphics/image_formats/jpglib/jcprepct.c index fdc4bc2d5..463d6137a 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jcprepct.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jcprepct.c @@ -106,7 +106,7 @@ LOCAL(void) expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, int input_rows, int output_rows) { - register int row; + int row; for (row = input_rows; row < output_rows; row++) { jcopy_sample_rows(image_data, input_rows-1, image_data, row, diff --git a/source/modules/juce_graphics/image_formats/jpglib/jcsample.c b/source/modules/juce_graphics/image_formats/jpglib/jcsample.c index 37c658f54..13f3cbcb5 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jcsample.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jcsample.c @@ -87,9 +87,9 @@ LOCAL(void) expand_right_edge (JSAMPARRAY image_data, int num_rows, JDIMENSION input_cols, JDIMENSION output_cols) { - register JSAMPROW ptr; - register JSAMPLE pixval; - register int count; + JSAMPROW ptr; + JSAMPLE pixval; + int count; int row; int numcols = (int) (output_cols - input_cols); @@ -215,8 +215,8 @@ h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, int outrow; JDIMENSION outcol; JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; - register JSAMPROW inptr, outptr; - register int bias; + JSAMPROW inptr, outptr; + int bias; /* Expand input data enough to let all the output samples be generated * by the standard loop. Special-casing padded output would be more @@ -252,8 +252,8 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, int inrow, outrow; JDIMENSION outcol; JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; - register JSAMPROW inptr0, inptr1, outptr; - register int bias; + JSAMPROW inptr0, inptr1, outptr; + int bias; /* Expand input data enough to let all the output samples be generated * by the standard loop. Special-casing padded output would be more @@ -295,7 +295,7 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, int inrow, outrow; JDIMENSION colctr; JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; - register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr; + JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr; INT32 membersum, neighsum, memberscale, neighscale; /* Expand input data enough to let all the output samples be generated @@ -395,7 +395,7 @@ fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, int outrow; JDIMENSION colctr; JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; - register JSAMPROW inptr, above_ptr, below_ptr, outptr; + JSAMPROW inptr, above_ptr, below_ptr, outptr; INT32 membersum, neighsum, memberscale, neighscale; int colsum, lastcolsum, nextcolsum; diff --git a/source/modules/juce_graphics/image_formats/jpglib/jdcolor.c b/source/modules/juce_graphics/image_formats/jpglib/jdcolor.c index a4ca25688..30763e921 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jdcolor.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jdcolor.c @@ -122,17 +122,17 @@ ycc_rgb_convert (j_decompress_ptr cinfo, JSAMPARRAY output_buf, int num_rows) { my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert; - register int y, cb, cr; - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2; - register JDIMENSION col; + int y, cb, cr; + JSAMPROW outptr; + JSAMPROW inptr0, inptr1, inptr2; + JDIMENSION col; JDIMENSION num_cols = cinfo->output_width; /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - register int * Crrtab = cconvert->Cr_r_tab; - register int * Cbbtab = cconvert->Cb_b_tab; - register INT32 * Crgtab = cconvert->Cr_g_tab; - register INT32 * Cbgtab = cconvert->Cb_g_tab; + JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = cconvert->Cr_r_tab; + int * Cbbtab = cconvert->Cb_b_tab; + INT32 * Crgtab = cconvert->Cr_g_tab; + INT32 * Cbgtab = cconvert->Cb_g_tab; SHIFT_TEMPS while (--num_rows >= 0) { @@ -170,9 +170,9 @@ null_convert2 (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { - register JSAMPROW inptr, outptr; - register JDIMENSION count; - register int num_components = cinfo->num_components; + JSAMPROW inptr, outptr; + JDIMENSION count; + int num_components = cinfo->num_components; JDIMENSION num_cols = cinfo->output_width; int ci; @@ -218,8 +218,8 @@ gray_rgb_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPARRAY output_buf, int num_rows) { - register JSAMPROW inptr, outptr; - register JDIMENSION col; + JSAMPROW inptr, outptr; + JDIMENSION col; JDIMENSION num_cols = cinfo->output_width; while (--num_rows >= 0) { @@ -247,17 +247,17 @@ ycck_cmyk_convert (j_decompress_ptr cinfo, JSAMPARRAY output_buf, int num_rows) { my_cconvert_ptr2 cconvert = (my_cconvert_ptr2) cinfo->cconvert; - register int y, cb, cr; - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2, inptr3; - register JDIMENSION col; + int y, cb, cr; + JSAMPROW outptr; + JSAMPROW inptr0, inptr1, inptr2, inptr3; + JDIMENSION col; JDIMENSION num_cols = cinfo->output_width; /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - register int * Crrtab = cconvert->Cr_r_tab; - register int * Cbbtab = cconvert->Cb_b_tab; - register INT32 * Crgtab = cconvert->Cr_g_tab; - register INT32 * Cbgtab = cconvert->Cb_g_tab; + JSAMPLE * range_limit = cinfo->sample_range_limit; + int * Crrtab = cconvert->Cr_r_tab; + int * Cbbtab = cconvert->Cb_b_tab; + INT32 * Crgtab = cconvert->Cr_g_tab; + INT32 * Cbgtab = cconvert->Cb_g_tab; SHIFT_TEMPS while (--num_rows >= 0) { diff --git a/source/modules/juce_graphics/image_formats/jpglib/jdhuff.c b/source/modules/juce_graphics/image_formats/jpglib/jdhuff.c index 1468a834c..e7e0ab73a 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jdhuff.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jdhuff.c @@ -290,13 +290,13 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno, GLOBAL(boolean) jpeg_fill_bit_buffer (bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, + bit_buf_type get_buffer, int bits_left, int nbits) /* Load up the bit buffer to a depth of at least nbits */ { /* Copy heavily used state fields into locals (hopefully registers) */ - register const JOCTET * next_input_byte = state->next_input_byte; - register size_t bytes_in_buffer = state->bytes_in_buffer; + const JOCTET * next_input_byte = state->next_input_byte; + size_t bytes_in_buffer = state->bytes_in_buffer; j_decompress_ptr cinfo = state->cinfo; /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */ @@ -305,7 +305,7 @@ jpeg_fill_bit_buffer (bitread_working_state * state, if (cinfo->unread_marker == 0) { /* cannot advance past a marker */ while (bits_left < MIN_GET_BITS) { - register int c; + int c; /* Attempt to read a byte */ if (bytes_in_buffer == 0) { @@ -396,11 +396,11 @@ jpeg_fill_bit_buffer (bitread_working_state * state, GLOBAL(int) jpeg_huff_decode (bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, + bit_buf_type get_buffer, int bits_left, d_derived_tbl * htbl, int min_bits) { - register int l = min_bits; - register INT32 code; + int l = min_bits; + INT32 code; /* HUFF_DECODE has determined that the code is at least min_bits */ /* bits long, so fetch that many bits in one swoop. */ @@ -517,7 +517,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) JBLOCKROW block = MCU_data[blkn]; d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn]; d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn]; - register int s, k, r; + int s, k, r; /* Decode a single block's worth of coefficients */ diff --git a/source/modules/juce_graphics/image_formats/jpglib/jdhuff.h b/source/modules/juce_graphics/image_formats/jpglib/jdhuff.h index 1b139871a..492a91257 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jdhuff.h +++ b/source/modules/juce_graphics/image_formats/jpglib/jdhuff.h @@ -103,8 +103,8 @@ typedef struct { /* Bitreading working state within an MCU */ /* Macros to declare and load/save bitread local variables. */ #define BITREAD_STATE_VARS \ - register bit_buf_type get_buffer; \ - register int bits_left; \ + bit_buf_type get_buffer; \ + int bits_left; \ bitread_working_state br_state #define BITREAD_LOAD_STATE(cinfop,permstate) \ @@ -155,8 +155,8 @@ typedef struct { /* Bitreading working state within an MCU */ /* Load up the bit buffer to a depth of at least nbits */ EXTERN(boolean) jpeg_fill_bit_buffer - JPP((bitread_working_state * state, register bit_buf_type get_buffer, - register int bits_left, int nbits)); + JPP((bitread_working_state * state, bit_buf_type get_buffer, + int bits_left, int nbits)); /* @@ -177,7 +177,7 @@ EXTERN(boolean) jpeg_fill_bit_buffer */ #define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \ -{ register int nb, look; \ +{ int nb, look; \ if (bits_left < HUFF_LOOKAHEAD) { \ if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \ get_buffer = state.get_buffer; bits_left = state.bits_left; \ @@ -200,7 +200,7 @@ slowlabel: \ /* Out-of-line case for Huffman code fetching */ EXTERN(int) jpeg_huff_decode - JPP((bitread_working_state * state, register bit_buf_type get_buffer, - register int bits_left, d_derived_tbl * htbl, int min_bits)); + JPP((bitread_working_state * state, bit_buf_type get_buffer, + int bits_left, d_derived_tbl * htbl, int min_bits)); #endif diff --git a/source/modules/juce_graphics/image_formats/jpglib/jdmerge.c b/source/modules/juce_graphics/image_formats/jpglib/jdmerge.c index faee6ce5c..1f483f622 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jdmerge.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jdmerge.c @@ -228,13 +228,13 @@ h2v1_merged_upsample (j_decompress_ptr cinfo, JSAMPARRAY output_buf) { my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - register int y, cred, cgreen, cblue; + int y, cred, cgreen, cblue; int cb, cr; - register JSAMPROW outptr; + JSAMPROW outptr; JSAMPROW inptr0, inptr1, inptr2; JDIMENSION col; /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; + JSAMPLE * range_limit = cinfo->sample_range_limit; int * Crrtab = upsample->Cr_r_tab; int * Cbbtab = upsample->Cb_b_tab; INT32 * Crgtab = upsample->Cr_g_tab; @@ -290,13 +290,13 @@ h2v2_merged_upsample (j_decompress_ptr cinfo, JSAMPARRAY output_buf) { my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - register int y, cred, cgreen, cblue; + int y, cred, cgreen, cblue; int cb, cr; - register JSAMPROW outptr0, outptr1; + JSAMPROW outptr0, outptr1; JSAMPROW inptr00, inptr01, inptr1, inptr2; JDIMENSION col; /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; + JSAMPLE * range_limit = cinfo->sample_range_limit; int * Crrtab = upsample->Cr_r_tab; int * Cbbtab = upsample->Cb_b_tab; INT32 * Crgtab = upsample->Cr_g_tab; diff --git a/source/modules/juce_graphics/image_formats/jpglib/jdphuff.c b/source/modules/juce_graphics/image_formats/jpglib/jdphuff.c index c70096835..10e0a4636 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jdphuff.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jdphuff.c @@ -261,7 +261,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { phuff_entropy_ptr2 entropy = (phuff_entropy_ptr2) cinfo->entropy; int Al = cinfo->Al; - register int s, r; + int s, r; int blkn, ci; JBLOCKROW block; BITREAD_STATE_VARS; @@ -333,7 +333,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) phuff_entropy_ptr2 entropy = (phuff_entropy_ptr2) cinfo->entropy; int Se = cinfo->Se; int Al = cinfo->Al; - register int s, k, r; + int s, k, r; unsigned int EOBRUN; JBLOCKROW block; BITREAD_STATE_VARS; @@ -468,7 +468,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) int Se = cinfo->Se; int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ - register int s, k, r; + int s, k, r; unsigned int EOBRUN; JBLOCKROW block; JCOEFPTR thiscoef; diff --git a/source/modules/juce_graphics/image_formats/jpglib/jdsample.c b/source/modules/juce_graphics/image_formats/jpglib/jdsample.c index c0a142a74..ab2c01286 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jdsample.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jdsample.c @@ -191,9 +191,9 @@ int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, { my_upsample_ptr2 upsample = (my_upsample_ptr2) cinfo->upsample; JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register JSAMPLE invalue; - register int h; + JSAMPROW inptr, outptr; + JSAMPLE invalue; + int h; JSAMPROW outend; int h_expand, v_expand; int inrow, outrow; @@ -234,8 +234,8 @@ h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info *, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register JSAMPLE invalue; + JSAMPROW inptr, outptr; + JSAMPLE invalue; JSAMPROW outend; int inrow; @@ -262,8 +262,8 @@ h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info *, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register JSAMPLE invalue; + JSAMPROW inptr, outptr; + JSAMPLE invalue; JSAMPROW outend; int inrow, outrow; @@ -305,9 +305,9 @@ h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register int invalue; - register JDIMENSION colctr; + JSAMPROW inptr, outptr; + int invalue; + JDIMENSION colctr; int inrow; for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { @@ -346,13 +346,13 @@ h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr0, inptr1, outptr; + JSAMPROW inptr0, inptr1, outptr; #if BITS_IN_JSAMPLE == 8 - register int thiscolsum, lastcolsum, nextcolsum; + int thiscolsum, lastcolsum, nextcolsum; #else - register INT32 thiscolsum, lastcolsum, nextcolsum; + INT32 thiscolsum, lastcolsum, nextcolsum; #endif - register JDIMENSION colctr; + JDIMENSION colctr; int inrow, outrow, v; inrow = outrow = 0; diff --git a/source/modules/juce_graphics/image_formats/jpglib/jquant1.c b/source/modules/juce_graphics/image_formats/jpglib/jquant1.c index 7153f467b..65f488237 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jquant1.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jquant1.c @@ -462,12 +462,12 @@ color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; JSAMPARRAY colorindex = cquantize->colorindex; - register int pixcode, ci; - register JSAMPROW ptrin, ptrout; + int pixcode, ci; + JSAMPROW ptrin, ptrout; int row; JDIMENSION col; JDIMENSION width = cinfo->output_width; - register int nc = cinfo->out_color_components; + int nc = cinfo->out_color_components; for (row = 0; row < num_rows; row++) { ptrin = input_buf[row]; @@ -489,8 +489,8 @@ color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, /* Fast path for out_color_components==3, no dithering */ { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register int pixcode; - register JSAMPROW ptrin, ptrout; + int pixcode; + JSAMPROW ptrin, ptrout; JSAMPROW colorindex0 = cquantize->colorindex[0]; JSAMPROW colorindex1 = cquantize->colorindex[1]; JSAMPROW colorindex2 = cquantize->colorindex[2]; @@ -517,8 +517,8 @@ quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, /* General case, with ordered dithering */ { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register JSAMPROW input_ptr; - register JSAMPROW output_ptr; + JSAMPROW input_ptr; + JSAMPROW output_ptr; JSAMPROW colorindex_ci; int * dither; /* points to active row of dither matrix */ int row_index, col_index; /* current indexes into dither matrix */ @@ -567,9 +567,9 @@ quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, /* Fast path for out_color_components==3, with ordered dithering */ { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register int pixcode; - register JSAMPROW input_ptr; - register JSAMPROW output_ptr; + int pixcode; + JSAMPROW input_ptr; + JSAMPROW output_ptr; JSAMPROW colorindex0 = cquantize->colorindex[0]; JSAMPROW colorindex1 = cquantize->colorindex[1]; JSAMPROW colorindex2 = cquantize->colorindex[2]; @@ -612,14 +612,14 @@ quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, /* General case, with Floyd-Steinberg dithering */ { my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register LOCFSERROR cur; /* current error or pixel value */ + LOCFSERROR cur; /* current error or pixel value */ LOCFSERROR belowerr; /* error for pixel below cur */ LOCFSERROR bpreverr; /* error for below/prev col */ LOCFSERROR bnexterr; /* error for below/next col */ LOCFSERROR delta; - register FSERRPTR errorptr; /* => fserrors[] at column before current */ - register JSAMPROW input_ptr; - register JSAMPROW output_ptr; + FSERRPTR errorptr; /* => fserrors[] at column before current */ + JSAMPROW input_ptr; + JSAMPROW output_ptr; JSAMPROW colorindex_ci; JSAMPROW colormap_ci; int pixcode; diff --git a/source/modules/juce_graphics/image_formats/jpglib/jquant2.c b/source/modules/juce_graphics/image_formats/jpglib/jquant2.c index 6c2524e1d..8f50d536a 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jquant2.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jquant2.c @@ -225,9 +225,9 @@ prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY, int num_rows) { my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize; - register JSAMPROW ptr; - register histptr histp; - register hist3d histogram = cquantize->histogram; + JSAMPROW ptr; + histptr histp; + hist3d histogram = cquantize->histogram; int row; JDIMENSION col; JDIMENSION width = cinfo->output_width; @@ -274,9 +274,9 @@ find_biggest_color_pop (boxptr boxlist, int numboxes) /* Find the splittable box with the largest color population */ /* Returns NULL if no splittable boxes remain */ { - register boxptr boxp; - register int i; - register long maxc = 0; + boxptr boxp; + int i; + long maxc = 0; boxptr which = NULL; for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { @@ -294,9 +294,9 @@ find_biggest_volume (boxptr boxlist, int numboxes) /* Find the splittable box with the largest (scaled) volume */ /* Returns NULL if no splittable boxes remain */ { - register boxptr boxp; - register int i; - register INT32 maxv = 0; + boxptr boxp; + int i; + INT32 maxv = 0; boxptr which = NULL; for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { @@ -427,7 +427,7 @@ median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, { int n,lb; int c0,c1,c2,cmax; - register boxptr b1,b2; + boxptr b1,b2; while (numboxes < desired_colors) { /* Select box to split. @@ -783,12 +783,12 @@ find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, { int ic0, ic1, ic2; int i, icolor; - register INT32 * bptr; /* pointer into bestdist[] array */ + INT32 * bptr; /* pointer into bestdist[] array */ JSAMPLE * cptr; /* pointer into bestcolor[] array */ INT32 dist0, dist1; /* initial distance values */ - register INT32 dist2; /* current distance in inner loop */ + INT32 dist2; /* current distance in inner loop */ INT32 xx0, xx1; /* distance increments */ - register INT32 xx2; + INT32 xx2; INT32 inc0, inc1, inc2; /* initial values for increments */ /* This array holds the distance to the nearest-so-far color for each cell */ INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; @@ -861,8 +861,8 @@ fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) hist3d histogram = cquantize->histogram; int minc0, minc1, minc2; /* lower left corner of update box */ int ic0, ic1, ic2; - register JSAMPLE * cptr; /* pointer into bestcolor[] array */ - register histptr cachep; /* pointer into main cache array */ + JSAMPLE * cptr; /* pointer into bestcolor[] array */ + histptr cachep; /* pointer into main cache array */ /* This array lists the candidate colormap indexes. */ JSAMPLE colorlist[MAXNUMCOLORS]; int numcolors; /* number of candidate colors */ @@ -918,9 +918,9 @@ pass2_no_dither (j_decompress_ptr cinfo, { my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize; hist3d histogram = cquantize->histogram; - register JSAMPROW inptr, outptr; - register histptr cachep; - register int c0, c1, c2; + JSAMPROW inptr, outptr; + histptr cachep; + int c0, c1, c2; int row; JDIMENSION col; JDIMENSION width = cinfo->output_width; @@ -952,10 +952,10 @@ pass2_fs_dither (j_decompress_ptr cinfo, { my_cquantize_ptr2 cquantize = (my_cquantize_ptr2) cinfo->cquantize; hist3d histogram = cquantize->histogram; - register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ + LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ - register FSERRPTR errorptr; /* => fserrors[] at column before current */ + FSERRPTR errorptr; /* => fserrors[] at column before current */ JSAMPROW inptr; /* => current input pixel */ JSAMPROW outptr; /* => current output pixel */ histptr cachep; @@ -1030,7 +1030,7 @@ pass2_fs_dither (j_decompress_ptr cinfo, if (*cachep == 0) fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT); /* Now emit the colormap index for this cell */ - { register int pixcode = *cachep - 1; + { int pixcode = *cachep - 1; *outptr = (JSAMPLE) pixcode; /* Compute representation error for this pixel */ cur0 -= GETJSAMPLE(colormap0[pixcode]); @@ -1041,7 +1041,7 @@ pass2_fs_dither (j_decompress_ptr cinfo, * Add these into the running sums, and simultaneously shift the * next-line error sums left by 1 column. */ - { register LOCFSERROR bnexterr, delta; + { LOCFSERROR bnexterr, delta; bnexterr = cur0; /* Process component 0 */ delta = cur0 * 2; diff --git a/source/modules/juce_graphics/image_formats/jpglib/jutils.c b/source/modules/juce_graphics/image_formats/jpglib/jutils.c index 286cda207..68a808339 100644 --- a/source/modules/juce_graphics/image_formats/jpglib/jutils.c +++ b/source/modules/juce_graphics/image_formats/jpglib/jutils.c @@ -117,13 +117,13 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row, * The source and destination arrays must be at least as wide as num_cols. */ { - register JSAMPROW inptr, outptr; + JSAMPROW inptr, outptr; #ifdef FMEMCOPY - register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE)); + size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE)); #else - register JDIMENSION count; + JDIMENSION count; #endif - register int row; + int row; input_array += source_row; output_array += dest_row; @@ -149,8 +149,8 @@ jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, #ifdef FMEMCOPY FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); #else - register JCOEFPTR inptr, outptr; - register long count; + JCOEFPTR inptr, outptr; + long count; inptr = (JCOEFPTR) input_row; outptr = (JCOEFPTR) output_row; @@ -169,8 +169,8 @@ jzero_far (void FAR * target, size_t bytestozero) #ifdef FMEMZERO FMEMZERO(target, bytestozero); #else - register char FAR * ptr = (char FAR *) target; - register size_t count; + char FAR * ptr = (char FAR *) target; + size_t count; for (count = bytestozero; count > 0; count--) { *ptr++ = 0; diff --git a/source/modules/juce_graphics/image_formats/juce_GIFLoader.cpp b/source/modules/juce_graphics/image_formats/juce_GIFLoader.cpp index e0c5b70ab..5d8c205e1 100644 --- a/source/modules/juce_graphics/image_formats/juce_GIFLoader.cpp +++ b/source/modules/juce_graphics/image_formats/juce_GIFLoader.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp b/source/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp index cf32f3a54..ff5c1629d 100644 --- a/source/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp +++ b/source/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -38,6 +40,9 @@ namespace jpeglibNamespace #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wdeprecated-register" + #if __has_warning("-Wcomma") + #pragma clang diagnostic ignored "-Wcomma" + #endif #endif #define JPEG_INTERNALS @@ -223,13 +228,23 @@ bool JPEGImageFormat::usesFileExtension (const File& f) { return f.hasFileExte bool JPEGImageFormat::canUnderstand (InputStream& in) { - const int bytesNeeded = 10; + const int bytesNeeded = 24; uint8 header [bytesNeeded]; - return in.read (header, bytesNeeded) == bytesNeeded + if (in.read (header, bytesNeeded) == bytesNeeded && header[0] == 0xff && header[1] == 0xd8 - && header[2] == 0xff; + && header[2] == 0xff) + return true; + + #if JUCE_USING_COREIMAGE_LOADER + return header[20] == 'j' + && header[21] == 'p' + && header[22] == '2' + && header[23] == ' '; + #endif + + return false; } #if JUCE_USING_COREIMAGE_LOADER diff --git a/source/modules/juce_graphics/image_formats/juce_PNGLoader.cpp b/source/modules/juce_graphics/image_formats/juce_PNGLoader.cpp index 4885a49d2..dbf35059e 100644 --- a/source/modules/juce_graphics/image_formats/juce_PNGLoader.cpp +++ b/source/modules/juce_graphics/image_formats/juce_PNGLoader.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -61,6 +63,9 @@ namespace pnglibNamespace #if JUCE_CLANG #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wsign-conversion" + #if __has_warning("-Wcomma") + #pragma clang diagnostic ignored "-Wcomma" + #endif #endif #undef check diff --git a/source/modules/juce_graphics/image_formats/pnglib/png.c b/source/modules/juce_graphics/image_formats/pnglib/png.c index 67e7e2ef6..75e610521 100644 --- a/source/modules/juce_graphics/image_formats/pnglib/png.c +++ b/source/modules/juce_graphics/image_formats/pnglib/png.c @@ -2863,7 +2863,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, fp = 0; /* Guarantees termination below. */ } - if (d == 0) + if (d == 0.0) { ++czero; if (cdigits == 0) ++clead; diff --git a/source/modules/juce_graphics/images/juce_Image.cpp b/source/modules/juce_graphics/images/juce_Image.cpp index 4e6f4c634..278968838 100644 --- a/source/modules/juce_graphics/images/juce_Image.cpp +++ b/source/modules/juce_graphics/images/juce_Image.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -242,7 +244,6 @@ Image& Image::operator= (const Image& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Image::Image (Image&& other) noexcept : image (static_cast (other.image)) { @@ -253,7 +254,6 @@ Image& Image::operator= (Image&& other) noexcept image = static_cast (other.image); return *this; } -#endif Image::~Image() { @@ -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/source/modules/juce_graphics/images/juce_Image.h b/source/modules/juce_graphics/images/juce_Image.h index e817cc7f4..a2c436d25 100644 --- a/source/modules/juce_graphics/images/juce_Image.h +++ b/source/modules/juce_graphics/images/juce_Image.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IMAGE_H_INCLUDED -#define JUCE_IMAGE_H_INCLUDED +#pragma once class ImageType; class ImagePixelData; @@ -74,7 +75,9 @@ public: The image's internal type will be of the NativeImageType class - to specify a different type, use the other constructor, which takes an ImageType to use. - @param format the number of colour channels in the image + @param format the preferred pixel format. Note that this is only a *hint* which + is passed to the ImageType class - different ImageTypes may not support + all formats, so may substitute e.g. ARGB for RGB. @param imageWidth the desired width of the image, in pixels - this value must be greater than zero (otherwise a width of 1 will be used) @param imageHeight the desired width of the image, in pixels - this value must be @@ -87,7 +90,9 @@ public: /** Creates an image with a specified size and format. - @param format the number of colour channels in the image + @param format the preferred pixel format. Note that this is only a *hint* which + is passed to the ImageType class - different ImageTypes may not support + all formats, so may substitute e.g. ARGB for RGB. @param imageWidth the desired width of the image, in pixels - this value must be greater than zero (otherwise a width of 1 will be used) @param imageHeight the desired width of the image, in pixels - this value must be @@ -116,10 +121,11 @@ public: */ Image& operator= (const Image&); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ Image (Image&&) noexcept; + + /** Move assignment operator */ Image& operator= (Image&&) noexcept; - #endif /** Destructor. */ ~Image(); @@ -494,7 +500,7 @@ public: virtual ~ImageType(); /** Creates a new image of this type, and the specified parameters. */ - virtual ImagePixelData::Ptr create (Image::PixelFormat format, int width, int height, bool shouldClearImage) const = 0; + virtual ImagePixelData::Ptr create (Image::PixelFormat, int width, int height, bool shouldClearImage) const = 0; /** Must return a unique number to identify this type. */ virtual int getTypeID() const = 0; @@ -536,6 +542,3 @@ public: ImagePixelData::Ptr create (Image::PixelFormat, int width, int height, bool clearImage) const override; int getTypeID() const override; }; - - -#endif // JUCE_IMAGE_H_INCLUDED diff --git a/source/modules/juce_graphics/images/juce_ImageCache.cpp b/source/modules/juce_graphics/images/juce_ImageCache.cpp index 9d6573936..50c3203f4 100644 --- a/source/modules/juce_graphics/images/juce_ImageCache.cpp +++ b/source/modules/juce_graphics/images/juce_ImageCache.cpp @@ -2,53 +2,51 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -class ImageCache::Pimpl : private Timer, - private DeletedAtShutdown +struct ImageCache::Pimpl : private Timer, + private DeletedAtShutdown { -public: - Pimpl() : cacheTimeout (5000) - { - } + Pimpl() {} + ~Pimpl() { clearSingletonInstance(); } - ~Pimpl() - { - clearSingletonInstance(); - } + juce_DeclareSingleton_SingleThreaded_Minimal (ImageCache::Pimpl) - Image getFromHashCode (const int64 hashCode) + Image getFromHashCode (const int64 hashCode) noexcept { const ScopedLock sl (lock); - for (int i = images.size(); --i >= 0;) + for (auto& item : images) { - const Item* const item = images.getUnchecked(i); - - if (item->hashCode == hashCode) - return item->image; + if (item.hashCode == hashCode) + { + item.lastUseTime = Time::getApproximateMillisecondCounter(); + return item.image; + } } - return Image(); - } + return {}; + } void addImageToCache (const Image& image, const int64 hashCode) { @@ -57,38 +55,33 @@ public: if (! isTimerRunning()) startTimer (2000); - Item* const item = new Item(); - item->hashCode = hashCode; - item->image = image; - item->lastUseTime = Time::getApproximateMillisecondCounter(); - const ScopedLock sl (lock); - images.add (item); + images.add ({ image, hashCode, Time::getApproximateMillisecondCounter() }); } } void timerCallback() override { - const uint32 now = Time::getApproximateMillisecondCounter(); + auto now = Time::getApproximateMillisecondCounter(); const ScopedLock sl (lock); for (int i = images.size(); --i >= 0;) { - Item* const item = images.getUnchecked(i); + auto& item = images.getReference(i); - if (item->image.getReferenceCount() <= 1) + if (item.image.getReferenceCount() <= 1) { - if (now > item->lastUseTime + cacheTimeout || now < item->lastUseTime - 1000) + if (now > item.lastUseTime + cacheTimeout || now < item.lastUseTime - 1000) images.remove (i); } else { - item->lastUseTime = now; // multiply-referenced, so this image is still in use. + item.lastUseTime = now; // multiply-referenced, so this image is still in use. } } - if (images.size() == 0) + if (images.isEmpty()) stopTimer(); } @@ -97,7 +90,7 @@ public: const ScopedLock sl (lock); for (int i = images.size(); --i >= 0;) - if (images.getUnchecked(i)->image.getReferenceCount() <= 1) + if (images.getReference(i).image.getReferenceCount() <= 1) images.remove (i); } @@ -108,13 +101,9 @@ public: uint32 lastUseTime; }; - unsigned int cacheTimeout; - - juce_DeclareSingleton_SingleThreaded_Minimal (ImageCache::Pimpl) - -private: - OwnedArray images; + Array images; CriticalSection lock; + unsigned int cacheTimeout = 5000; JUCE_DECLARE_NON_COPYABLE (Pimpl) }; @@ -128,7 +117,7 @@ Image ImageCache::getFromHashCode (const int64 hashCode) if (Pimpl::getInstanceWithoutCreating() != nullptr) return Pimpl::getInstanceWithoutCreating()->getFromHashCode (hashCode); - return Image(); + return {}; } void ImageCache::addImageToCache (const Image& image, const int64 hashCode) @@ -138,8 +127,8 @@ void ImageCache::addImageToCache (const Image& image, const int64 hashCode) Image ImageCache::getFromFile (const File& file) { - const int64 hashCode = file.hashCode64(); - Image image (getFromHashCode (hashCode)); + auto hashCode = file.hashCode64(); + auto image = getFromHashCode (hashCode); if (image.isNull()) { @@ -152,8 +141,8 @@ Image ImageCache::getFromFile (const File& file) Image ImageCache::getFromMemory (const void* imageData, const int dataSize) { - const int64 hashCode = (int64) (pointer_sized_int) imageData; - Image image (getFromHashCode (hashCode)); + auto hashCode = (int64) (pointer_sized_int) imageData; + auto image = getFromHashCode (hashCode); if (image.isNull()) { diff --git a/source/modules/juce_graphics/images/juce_ImageCache.h b/source/modules/juce_graphics/images/juce_ImageCache.h index 77bdc6081..fa5b5710c 100644 --- a/source/modules/juce_graphics/images/juce_ImageCache.h +++ b/source/modules/juce_graphics/images/juce_ImageCache.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IMAGECACHE_H_INCLUDED -#define JUCE_IMAGECACHE_H_INCLUDED +#pragma once //============================================================================== @@ -113,13 +114,11 @@ public: private: //============================================================================== - class Pimpl; - friend class Pimpl; + struct Pimpl; + friend struct Pimpl; ImageCache(); ~ImageCache(); JUCE_DECLARE_NON_COPYABLE (ImageCache) }; - -#endif // JUCE_IMAGECACHE_H_INCLUDED diff --git a/source/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp b/source/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp index 95a184cc4..a56cab1eb 100644 --- a/source/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp +++ b/source/modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/images/juce_ImageConvolutionKernel.h b/source/modules/juce_graphics/images/juce_ImageConvolutionKernel.h index 43afc9e00..cc399d965 100644 --- a/source/modules/juce_graphics/images/juce_ImageConvolutionKernel.h +++ b/source/modules/juce_graphics/images/juce_ImageConvolutionKernel.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IMAGECONVOLUTIONKERNEL_H_INCLUDED -#define JUCE_IMAGECONVOLUTIONKERNEL_H_INCLUDED +#pragma once //============================================================================== @@ -106,6 +107,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageConvolutionKernel) }; - - -#endif // JUCE_IMAGECONVOLUTIONKERNEL_H_INCLUDED diff --git a/source/modules/juce_graphics/images/juce_ImageFileFormat.cpp b/source/modules/juce_graphics/images/juce_ImageFileFormat.cpp index 30b47d0c7..669a39be4 100644 --- a/source/modules/juce_graphics/images/juce_ImageFileFormat.cpp +++ b/source/modules/juce_graphics/images/juce_ImageFileFormat.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/images/juce_ImageFileFormat.h b/source/modules/juce_graphics/images/juce_ImageFileFormat.h index e54ede699..e558906af 100644 --- a/source/modules/juce_graphics/images/juce_ImageFileFormat.h +++ b/source/modules/juce_graphics/images/juce_ImageFileFormat.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IMAGEFILEFORMAT_H_INCLUDED -#define JUCE_IMAGEFILEFORMAT_H_INCLUDED +#pragma once //============================================================================== @@ -211,6 +212,3 @@ public: Image decodeImage (InputStream&) override; bool writeImageToStream (const Image&, OutputStream&) override; }; - - -#endif // JUCE_IMAGEFILEFORMAT_H_INCLUDED diff --git a/source/modules/juce_graphics/juce_graphics.cpp b/source/modules/juce_graphics/juce_graphics.cpp index b2c64da10..688498188 100644 --- a/source/modules/juce_graphics/juce_graphics.cpp +++ b/source/modules/juce_graphics/juce_graphics.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,8 +33,6 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #define JUCE_CORE_INCLUDE_OBJC_HELPERS 1 #define JUCE_CORE_INCLUDE_COM_SMART_PTR 1 #define JUCE_CORE_INCLUDE_JNI_HELPERS 1 @@ -57,7 +57,7 @@ #undef JUCE_USE_DIRECTWRITE #endif - #if JUCE_USE_DIRECTWRITE + #if JUCE_USE_DIRECTWRITE || JUCE_DIRECT2D /* If you hit a compile error trying to include these files, you may need to update your version of the Windows SDK to the latest one. The DirectWrite and Direct2D headers are in the version 7 SDKs. @@ -146,21 +146,25 @@ namespace juce #if JUCE_MAC || JUCE_IOS #include "native/juce_mac_Fonts.mm" #include "native/juce_mac_CoreGraphicsContext.mm" + #include "native/juce_mac_IconHelpers.cpp" #elif JUCE_WINDOWS #include "native/juce_win32_DirectWriteTypeface.cpp" #include "native/juce_win32_DirectWriteTypeLayout.cpp" #include "native/juce_win32_Fonts.cpp" + #include "native/juce_win32_IconHelpers.cpp" #if JUCE_DIRECT2D #include "native/juce_win32_Direct2DGraphicsContext.cpp" #endif #elif JUCE_LINUX #include "native/juce_linux_Fonts.cpp" + #include "native/juce_linux_IconHelpers.cpp" #elif JUCE_ANDROID #include "native/juce_android_GraphicsContext.cpp" #include "native/juce_android_Fonts.cpp" + #include "native/juce_android_IconHelpers.cpp" #endif } diff --git a/source/modules/juce_graphics/juce_graphics.h b/source/modules/juce_graphics/juce_graphics.h index 69fd59e04..c823b10f1 100644 --- a/source/modules/juce_graphics/juce_graphics.h +++ b/source/modules/juce_graphics/juce_graphics.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -33,7 +35,7 @@ ID: juce_graphics vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE graphics classes description: Classes for 2D vector graphics, image loading/saving, font handling, etc. website: http://www.juce.com/juce @@ -41,7 +43,7 @@ dependencies: juce_events OSXFrameworks: Cocoa QuartzCore - iOSFrameworks: CoreGraphics CoreText QuartzCore + iOSFrameworks: CoreGraphics CoreImage CoreText QuartzCore linuxPackages: x11 xinerama xext freetype2 END_JUCE_MODULE_DECLARATION @@ -49,7 +51,7 @@ *******************************************************************************/ -#ifndef JUCE_GRAPHICS_H_INCLUDED // %% +#pragma once #define JUCE_GRAPHICS_H_INCLUDED #include @@ -140,6 +142,8 @@ class LowLevelGraphicsContext; #include "native/juce_mac_CoreGraphicsContext.h" #endif -} +#if JUCE_DIRECT2D && JUCE_WINDOWS +#include "native/juce_win32_Direct2DGraphicsContext.h" +#endif -#endif // JUCE_GRAPHICS_H_INCLUDED +} diff --git a/source/modules/juce_graphics/native/juce_RenderingHelpers.h b/source/modules/juce_graphics/native/juce_RenderingHelpers.h index 60df647e7..1c4cd31ef 100644 --- a/source/modules/juce_graphics/native/juce_RenderingHelpers.h +++ b/source/modules/juce_graphics/native/juce_RenderingHelpers.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RENDERINGHELPERS_H_INCLUDED -#define JUCE_RENDERINGHELPERS_H_INCLUDED +#pragma once #if JUCE_MSVC #pragma warning (push) @@ -87,7 +88,7 @@ public: complexTransform = getTransformWith (t); isOnlyTranslated = false; - isRotated = (complexTransform.mat01 != 0 || complexTransform.mat10 != 0 + isRotated = (complexTransform.mat01 != 0.0f || complexTransform.mat10 != 0.0f || complexTransform.mat00 < 0 || complexTransform.mat11 < 0); } @@ -1606,8 +1607,8 @@ struct ClipRegions RectangleList inverse (edgeTable.getMaximumBounds()); if (inverse.subtract (r)) - for (const Rectangle* i = inverse.begin(), * const e = inverse.end(); i != e; ++i) - edgeTable.excludeRectangle (*i); + for (auto& i : inverse) + edgeTable.excludeRectangle (i); return edgeTable.isEmpty() ? nullptr : this; } @@ -1846,14 +1847,14 @@ struct ClipRegions template void iterate (Renderer& r) const noexcept { - for (const Rectangle* i = clip.begin(), * const e = clip.end(); i != e; ++i) + for (auto& i : clip) { - const int x = i->getX(); - const int w = i->getWidth(); + const int x = i.getX(); + const int w = i.getWidth(); jassert (w > 0); - const int bottom = i->getBottom(); + const int bottom = i.getBottom(); - for (int y = i->getY(); y < bottom; ++y) + for (int y = i.getY(); y < bottom; ++y) { r.setEdgeTableYPos (y); r.handleEdgeTableLineFull (x, w); @@ -1873,9 +1874,9 @@ struct ClipRegions template void iterate (Renderer& r) const noexcept { - for (const Rectangle* i = clip.begin(), * const e = clip.end(); i != e; ++i) + for (auto& i : clip) { - const Rectangle rect (i->getIntersection (area)); + auto rect = i.getIntersection (area); if (! rect.isEmpty()) { @@ -1913,12 +1914,12 @@ struct ClipRegions { const RenderingHelpers::FloatRectangleRasterisingInfo f (area); - for (const Rectangle* i = clip.begin(), * const e = clip.end(); i != e; ++i) + for (auto& i : clip) { - const int clipLeft = i->getX(); - const int clipRight = i->getRight(); - const int clipTop = i->getY(); - const int clipBottom = i->getBottom(); + const int clipLeft = i.getX(); + const int clipRight = i.getRight(); + const int clipTop = i.getY(); + const int clipBottom = i.getBottom(); if (f.totalBottom > clipTop && f.totalTop < clipBottom && f.totalRight > clipLeft && f.totalLeft < clipRight) @@ -2067,8 +2068,8 @@ public: cloneClipIfMultiplyReferenced(); RectangleList scaledList; - for (const Rectangle* i = r.begin(), * const e = r.end(); i != e; ++i) - scaledList.add (transform.transformed (*i)); + for (auto& i : r) + scaledList.add (transform.transformed (i)); clip = clip->clipToRectangleList (scaledList); } @@ -2685,5 +2686,3 @@ protected: #if JUCE_MSVC #pragma warning (pop) #endif - -#endif // JUCE_RENDERINGHELPERS_H_INCLUDED diff --git a/source/modules/juce_graphics/native/juce_android_Fonts.cpp b/source/modules/juce_graphics/native/juce_android_Fonts.cpp index 6ce3e23c9..5bfe92da6 100644 --- a/source/modules/juce_graphics/native/juce_android_Fonts.cpp +++ b/source/modules/juce_graphics/native/juce_android_Fonts.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -169,8 +171,8 @@ public: { JNIEnv* const env = getEnv(); - LocalRef bytes (env->NewByteArray (size)); - env->SetByteArrayRegion (bytes, 0, size, (const jbyte*) data); + LocalRef bytes (env->NewByteArray ((jsize) size)); + env->SetByteArrayRegion (bytes, 0, (jsize) size, (const jbyte*) data); typeface = GlobalRef (android.activity.callObjectMethod (JuceAppActivity.getTypeFaceFromByteArray, bytes.get())); @@ -207,7 +209,7 @@ public: const int numDone = paint.callIntMethod (Paint.getTextWidths, javaString (text).get(), widths); - HeapBlock localWidths (numDone); + HeapBlock localWidths (static_cast (numDone)); env->GetFloatArrayRegion (widths, 0, numDone, localWidths); env->DeleteLocalRef (widths); @@ -226,7 +228,7 @@ public: const int numDone = paint.callIntMethod (Paint.getTextWidths, javaString (text).get(), widths); - HeapBlock localWidths (numDone); + HeapBlock localWidths (static_cast (numDone)); env->GetFloatArrayRegion (widths, 0, numDone, localWidths); env->DeleteLocalRef (widths); @@ -237,8 +239,40 @@ public: float x = 0; for (int i = 0; i < numDone; ++i) { - glyphs.add ((int) s.getAndAdvance()); - x += localWidths[i]; + const float local = localWidths[i]; + + // Android uses jchar (UTF-16) characters + jchar ch = (jchar) s.getAndAdvance(); + + // Android has no proper glyph support, so we have to do + // a hacky workaround for ligature detection + + #if JUCE_STRING_UTF_TYPE <= 16 + static_assert (sizeof (int) >= (sizeof (jchar) * 2), "Unable store two java chars in one glyph"); + + // if the width of this glyph is zero inside the string but has + // a width on it's own, then it's probably due to ligature + if (local == 0.0f && glyphs.size() > 0 && getStringWidth (String (ch)) > 0.0f) + { + // modify the previous glyph + int& glyphNumber = glyphs.getReference (glyphs.size() - 1); + + // make sure this is not a three character ligature + if (glyphNumber < std::numeric_limits::max()) + { + const unsigned int previousGlyph + = static_cast (glyphNumber) & ((1U << (sizeof (jchar) * 8U)) - 1U); + const unsigned int thisGlyph + = static_cast (ch) & ((1U << (sizeof (jchar) * 8U)) - 1U); + + glyphNumber = static_cast ((thisGlyph << (sizeof (jchar) * 8U)) | previousGlyph); + ch = 0; + } + } + #endif + + glyphs.add ((int) ch); + x += local; xOffsets.add (x * referenceFontToUnits); } } @@ -250,10 +284,22 @@ public: EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform& t, float /*fontHeight*/) override { + #if JUCE_STRING_UTF_TYPE <= 16 + static_assert (sizeof (int) >= (sizeof (jchar) * 2), "Unable store two jni chars in one int"); + + // glyphNumber of zero is used to indicate that the last character was a ligature + if (glyphNumber == 0) return nullptr; + + jchar ch1 = (static_cast (glyphNumber) >> 0) & ((1U << (sizeof (jchar) * 8U)) - 1U); + jchar ch2 = (static_cast (glyphNumber) >> (sizeof (jchar) * 8U)) & ((1U << (sizeof (jchar) * 8U)) - 1U); + #else + jchar ch1 = glyphNumber, ch2 = 0; + #endif + JNIEnv* env = getEnv(); jobject matrix = GraphicsHelpers::createMatrix (env, AffineTransform::scale (referenceFontToUnits).followedBy (t)); - jintArray maskData = (jintArray) android.activity.callObjectMethod (JuceAppActivity.renderGlyph, (jchar) glyphNumber, paint.get(), matrix, rect.get()); + jintArray maskData = (jintArray) android.activity.callObjectMethod (JuceAppActivity.renderGlyph, ch1, ch2, paint.get(), matrix, rect.get()); env->DeleteLocalRef (matrix); diff --git a/source/modules/juce_graphics/native/juce_android_GraphicsContext.cpp b/source/modules/juce_graphics/native/juce_android_GraphicsContext.cpp index 4c4881291..2f36d872e 100644 --- a/source/modules/juce_graphics/native/juce_android_GraphicsContext.cpp +++ b/source/modules/juce_graphics/native/juce_android_GraphicsContext.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/native/juce_android_IconHelpers.cpp b/source/modules/juce_graphics/native/juce_android_IconHelpers.cpp new file mode 100644 index 000000000..287005422 --- /dev/null +++ b/source/modules/juce_graphics/native/juce_android_IconHelpers.cpp @@ -0,0 +1,30 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +Image JUCE_API getIconFromApplication (const String&, const int) +{ + return Image(); +} diff --git a/source/modules/juce_graphics/native/juce_freetype_Fonts.cpp b/source/modules/juce_graphics/native/juce_freetype_Fonts.cpp index 04a05ddab..1f01b77c9 100644 --- a/source/modules/juce_graphics/native/juce_freetype_Fonts.cpp +++ b/source/modules/juce_graphics/native/juce_freetype_Fonts.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/native/juce_linux_Fonts.cpp b/source/modules/juce_graphics/native/juce_linux_Fonts.cpp index 39dd38444..24b98669e 100644 --- a/source/modules/juce_graphics/native/juce_linux_Fonts.cpp +++ b/source/modules/juce_graphics/native/juce_linux_Fonts.cpp @@ -2,26 +2,40 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ +static XmlElement* findFontsConfFile() +{ + static const char* pathsToSearch[] = { "/etc/fonts/fonts.conf", + "/usr/share/fonts/fonts.conf" }; + + for (auto* path : pathsToSearch) + if (auto* xml = XmlDocument::parse (File (path))) + return xml; + + return nullptr; +} + StringArray FTTypefaceList::getDefaultFontDirectories() { StringArray fontDirs; @@ -29,21 +43,19 @@ StringArray FTTypefaceList::getDefaultFontDirectories() fontDirs.addTokens (String (CharPointer_UTF8 (getenv ("JUCE_FONT_PATH"))), ";,", ""); fontDirs.removeEmptyStrings (true); - if (fontDirs.size() == 0) + if (fontDirs.isEmpty()) { - const ScopedPointer fontsInfo (XmlDocument::parse (File ("/etc/fonts/fonts.conf"))); - - if (fontsInfo != nullptr) + if (ScopedPointer fontsInfo = findFontsConfFile()) { forEachXmlChildElementWithTagName (*fontsInfo, e, "dir") { - String fontPath (e->getAllSubText().trim()); + auto fontPath = e->getAllSubText().trim(); if (fontPath.isNotEmpty()) { if (e->getStringAttribute ("prefix") == "xdg") { - String xdgDataHome (SystemStats::getEnvironmentVariable ("XDG_DATA_HOME", String())); + auto xdgDataHome = SystemStats::getEnvironmentVariable ("XDG_DATA_HOME", {}); if (xdgDataHome.trimStart().isEmpty()) xdgDataHome = "~/.local/share"; @@ -57,7 +69,7 @@ StringArray FTTypefaceList::getDefaultFontDirectories() } } - if (fontDirs.size() == 0) + if (fontDirs.isEmpty()) fontDirs.add ("/usr/X11R6/lib/X11/fonts"); fontDirs.removeDuplicates (false); @@ -120,19 +132,19 @@ private: { const StringArray choices (choicesArray); - for (int j = 0; j < choices.size(); ++j) - if (names.contains (choices[j], true)) - return choices[j]; + for (auto& choice : choices) + if (names.contains (choice, true)) + return choice; - for (int j = 0; j < choices.size(); ++j) - for (int i = 0; i < names.size(); ++i) - if (names[i].startsWithIgnoreCase (choices[j])) - return names[i]; + for (auto& choice : choices) + for (auto& name : names) + if (name.startsWithIgnoreCase (choice)) + return name; - for (int j = 0; j < choices.size(); ++j) - for (int i = 0; i < names.size(); ++i) - if (names[i].containsIgnoreCase (choices[j])) - return names[i]; + for (auto& choice : choices) + for (auto& name : names) + if (name.containsIgnoreCase (choice)) + return name; return names[0]; } diff --git a/source/modules/juce_graphics/native/juce_linux_IconHelpers.cpp b/source/modules/juce_graphics/native/juce_linux_IconHelpers.cpp new file mode 100644 index 000000000..287005422 --- /dev/null +++ b/source/modules/juce_graphics/native/juce_linux_IconHelpers.cpp @@ -0,0 +1,30 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +Image JUCE_API getIconFromApplication (const String&, const int) +{ + return Image(); +} diff --git a/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h b/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h index 4210c2acb..4b81cf100 100644 --- a/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h +++ b/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MAC_COREGRAPHICSCONTEXT_H_INCLUDED -#define JUCE_MAC_COREGRAPHICSCONTEXT_H_INCLUDED +#pragma once //============================================================================== class CoreGraphicsContext : public LowLevelGraphicsContext @@ -109,5 +110,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreGraphicsContext) }; - -#endif // JUCE_MAC_COREGRAPHICSCONTEXT_H_INCLUDED diff --git a/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm b/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm index 957d9cfa2..fa97d97a5 100644 --- a/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm +++ b/source/modules/juce_graphics/native/juce_mac_CoreGraphicsContext.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -249,8 +251,8 @@ bool CoreGraphicsContext::clipToRectangleListWithoutTest (const RectangleList rects (numRects); int i = 0; - for (const Rectangle* r = clipRegion.begin(), * const e = clipRegion.end(); r != e; ++r) - rects[i++] = CGRectMake (r->getX(), flipHeight - r->getBottom(), r->getWidth(), r->getHeight()); + for (auto& r : clipRegion) + rects[i++] = CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()); CGContextClipToRects (context, rects, numRects); lastClipRectIsValid = false; @@ -559,8 +561,9 @@ void CoreGraphicsContext::fillRectList (const RectangleList& list) HeapBlock rects ((size_t) list.getNumRectangles()); size_t num = 0; - for (const Rectangle* r = list.begin(), * const e = list.end(); r != e; ++r) - rects[num++] = CGRectMake (r->getX(), flipHeight - r->getBottom(), r->getWidth(), r->getHeight()); + + for (auto& r : list) + rects[num++] = CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()); if (state->fillType.isColour()) { @@ -876,7 +879,6 @@ Image juce_loadWithCoreImage (InputStream& input) } #endif -#if JUCE_MAC Image juce_createImageFromCIImage (CIImage*, int, int); Image juce_createImageFromCIImage (CIImage* im, int w, int h) { @@ -904,4 +906,16 @@ CGContextRef juce_getImageContext (const Image& image) return 0; } +#if JUCE_IOS +Image juce_createImageFromUIImage (UIImage* img) +{ + CGImageRef image = [img CGImage]; + + Image retval (Image::ARGB, (int) CGImageGetWidth (image), (int) CGImageGetHeight (image), true); + CGContextRef ctx = juce_getImageContext (retval); + + CGContextDrawImage (ctx, CGRectMake (0.0f, 0.0f, CGImageGetWidth (image), CGImageGetHeight (image)), image); + + return retval; +} #endif diff --git a/source/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h b/source/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h index 1982ea3db..f60b158a1 100644 --- a/source/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h +++ b/source/modules/juce_graphics/native/juce_mac_CoreGraphicsHelpers.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MAC_COREGRAPHICSHELPERS_H_INCLUDED -#define JUCE_MAC_COREGRAPHICSHELPERS_H_INCLUDED +#pragma once //============================================================================== @@ -57,4 +58,6 @@ namespace extern CGImageRef juce_createCoreGraphicsImage (const Image&, CGColorSpaceRef, bool mustOutliveSource); extern CGContextRef juce_getImageContext (const Image&); -#endif // JUCE_MAC_COREGRAPHICSHELPERS_H_INCLUDED +#if JUCE_IOS +extern Image juce_createImageFromUIImage (UIImage*); +#endif diff --git a/source/modules/juce_graphics/native/juce_mac_Fonts.mm b/source/modules/juce_graphics/native/juce_mac_Fonts.mm index 47ed02ee1..61c9cf8c2 100644 --- a/source/modules/juce_graphics/native/juce_mac_Fonts.mm +++ b/source/modules/juce_graphics/native/juce_mac_Fonts.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -564,6 +566,13 @@ public: CGDataProviderRef provider = CGDataProviderCreateWithCFData (cfData); CFRelease (cfData); + #if JUCE_IOS + // Workaround for a an obscure iOS bug which can cause the app to dead-lock + // when loading custom type faces. See: http://www.openradar.me/18778790 and + // http://stackoverflow.com/questions/40242370/app-hangs-in-simulator + [UIFont systemFontOfSize: 12]; + #endif + fontRef = CGFontCreateWithDataProvider (provider); CGDataProviderRelease (provider); diff --git a/source/modules/juce_graphics/native/juce_mac_IconHelpers.cpp b/source/modules/juce_graphics/native/juce_mac_IconHelpers.cpp new file mode 100644 index 000000000..0f3b740b0 --- /dev/null +++ b/source/modules/juce_graphics/native/juce_mac_IconHelpers.cpp @@ -0,0 +1,137 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +Image getIconFromIcnsFile (const File& icnsFile, const int size) +{ + FileInputStream stream (icnsFile); + if (! stream.openedOk()) + return {}; + + const int numHeaderSectionBytes = 4; + char headerSection [numHeaderSectionBytes]; + + if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes + || headerSection[0] != 'i' + || headerSection[1] != 'c' + || headerSection[2] != 'n' + || headerSection[3] != 's') + return {}; + + if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes) + return {}; + + const auto dataSize = juce::ByteOrder::bigEndianInt (headerSection); + if (dataSize <= 0) + return {}; + + OwnedArray internalFormats; + internalFormats.add (new PNGImageFormat()); + internalFormats.add (new JPEGImageFormat()); + + Array images; + auto maxWidth = 0; + auto maxWidthIndex = -1; + + while (stream.getPosition() < dataSize) + { + const auto sectionStart = stream.getPosition(); + + if (! stream.setPosition (sectionStart + 4)) + break; + + if (stream.read (headerSection, numHeaderSectionBytes) != numHeaderSectionBytes) + break; + + const auto sectionSize = ByteOrder::bigEndianInt (headerSection); + if (sectionSize <= 0) + break; + + const auto sectionDataStart = stream.getPosition(); + + for (auto* fmt : internalFormats) + { + if (fmt->canUnderstand (stream)) + { + stream.setPosition (sectionDataStart); + + images.add (fmt->decodeImage (stream)); + + const auto lastImageIndex = images.size() - 1; + const auto lastWidth = images.getReference (lastImageIndex).getWidth(); + if (lastWidth > maxWidth) + { + maxWidthIndex = lastImageIndex; + maxWidth = lastWidth; + } + } + + stream.setPosition (sectionDataStart); + } + + stream.setPosition (sectionStart + sectionSize); + } + + return maxWidthIndex == -1 ? juce::Image() + : images.getReference (maxWidthIndex).rescaled (size, size, Graphics::ResamplingQuality::highResamplingQuality); +} + +Image JUCE_API getIconFromApplication (const String& applicationPath, const int size) +{ + Image hostIcon; + + if (CFStringRef pathCFString = CFStringCreateWithCString (kCFAllocatorDefault, applicationPath.toRawUTF8(), kCFStringEncodingUTF8)) + { + if (CFURLRef url = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, pathCFString, kCFURLPOSIXPathStyle, 1)) + { + if (CFBundleRef appBundle = CFBundleCreate (kCFAllocatorDefault, url)) + { + if (CFTypeRef infoValue = CFBundleGetValueForInfoDictionaryKey (appBundle, CFSTR("CFBundleIconFile"))) + { + if (CFGetTypeID (infoValue) == CFStringGetTypeID()) + { + CFStringRef iconFilename = reinterpret_cast (infoValue); + CFStringRef resourceURLSuffix = CFStringHasSuffix (iconFilename, CFSTR(".icns")) ? nullptr : CFSTR("icns"); + if (CFURLRef iconURL = CFBundleCopyResourceURL (appBundle, iconFilename, resourceURLSuffix, nullptr)) + { + if (CFStringRef iconPath = CFURLCopyFileSystemPath (iconURL, kCFURLPOSIXPathStyle)) + { + File icnsFile (CFStringGetCStringPtr (iconPath, CFStringGetSystemEncoding())); + hostIcon = getIconFromIcnsFile (icnsFile, size); + CFRelease (iconPath); + } + CFRelease (iconURL); + } + } + } + CFRelease (appBundle); + } + CFRelease (url); + } + CFRelease (pathCFString); + } + + return hostIcon; +} diff --git a/source/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp b/source/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp index b36409236..40f848e58 100644 --- a/source/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp +++ b/source/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp @@ -2,837 +2,824 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -class Direct2DLowLevelGraphicsContext : public LowLevelGraphicsContext +template +D2D1_RECT_F rectangleToRectF (const Rectangle& r) { -public: - Direct2DLowLevelGraphicsContext (HWND hwnd_) - : hwnd (hwnd_), - currentState (nullptr) + return D2D1::RectF ((float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom()); +} + +static D2D1_COLOR_F colourToD2D (Colour c) +{ + return D2D1::ColorF::ColorF (c.getFloatRed(), c.getFloatGreen(), c.getFloatBlue(), c.getFloatAlpha()); +} + +static void pathToGeometrySink (const Path& path, ID2D1GeometrySink* sink, const AffineTransform& transform) +{ + Path::Iterator it (path); + + while (it.next()) { - RECT windowRect; - GetClientRect (hwnd, &windowRect); - D2D1_SIZE_U size = { windowRect.right - windowRect.left, windowRect.bottom - windowRect.top }; - bounds.setSize (size.width, size.height); + switch (it.elementType) + { + case Path::Iterator::cubicTo: + { + D2D1_BEZIER_SEGMENT seg; + + transform.transformPoint (it.x1, it.y1); + seg.point1 = D2D1::Point2F (it.x1, it.y1); + + transform.transformPoint (it.x2, it.y2); + seg.point2 = D2D1::Point2F (it.x2, it.y2); - D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(); - D2D1_HWND_RENDER_TARGET_PROPERTIES propsHwnd = D2D1::HwndRenderTargetProperties (hwnd, size); + transform.transformPoint (it.x3, it.y3); + seg.point3 = D2D1::Point2F (it.x3, it.y3); - if (factories->d2dFactory != nullptr) + sink->AddBezier (seg); + break; + } + + case Path::Iterator::lineTo: { - HRESULT hr = factories->d2dFactory->CreateHwndRenderTarget (props, propsHwnd, renderingTarget.resetAndGetPointerAddress()); - jassert (SUCCEEDED (hr)); ignoreUnused (hr); - hr = renderingTarget->CreateSolidColorBrush (D2D1::ColorF::ColorF (0.0f, 0.0f, 0.0f, 1.0f), colourBrush.resetAndGetPointerAddress()); + transform.transformPoint (it.x1, it.y1); + sink->AddLine (D2D1::Point2F (it.x1, it.y1)); + break; } - } - ~Direct2DLowLevelGraphicsContext() - { - states.clear(); - } + case Path::Iterator::quadraticTo: + { + D2D1_QUADRATIC_BEZIER_SEGMENT seg; - void resized() - { - RECT windowRect; - GetClientRect (hwnd, &windowRect); - D2D1_SIZE_U size = { windowRect.right - windowRect.left, windowRect.bottom - windowRect.top }; + transform.transformPoint (it.x1, it.y1); + seg.point1 = D2D1::Point2F (it.x1, it.y1); - renderingTarget->Resize (size); - bounds.setSize (size.width, size.height); - } + transform.transformPoint (it.x2, it.y2); + seg.point2 = D2D1::Point2F (it.x2, it.y2); - void clear() - { - renderingTarget->Clear (D2D1::ColorF (D2D1::ColorF::White, 0.0f)); // xxx why white and not black? - } + sink->AddQuadraticBezier (seg); + break; + } - void start() - { - renderingTarget->BeginDraw(); - saveState(); - } + case Path::Iterator::closePath: + { + sink->EndFigure (D2D1_FIGURE_END_CLOSED); + break; + } - void end() - { - states.clear(); - currentState = 0; - renderingTarget->EndDraw(); - renderingTarget->CheckWindowState(); + case Path::Iterator::startNewSubPath: + { + transform.transformPoint (it.x1, it.y1); + sink->BeginFigure (D2D1::Point2F (it.x1, it.y1), D2D1_FIGURE_BEGIN_FILLED); + break; + } + } } +} - bool isVectorDevice() const { return false; } +static D2D1::Matrix3x2F transformToMatrix (const AffineTransform& transform) +{ + D2D1::Matrix3x2F matrix; + matrix._11 = transform.mat00; + matrix._12 = transform.mat10; + matrix._21 = transform.mat01; + matrix._22 = transform.mat11; + matrix._31 = transform.mat02; + matrix._32 = transform.mat12; + return matrix; +} + +static D2D1_POINT_2F pointTransformed (int x, int y, const AffineTransform& transform) +{ + transform.transformPoint (x, y); + return D2D1::Point2F ((FLOAT) x, (FLOAT) y); +} - void setOrigin (Point o) +static void rectToGeometrySink (const Rectangle& rect, ID2D1GeometrySink* sink, const AffineTransform& transform) +{ + sink->BeginFigure (pointTransformed (rect.getX(), rect.getY(), transform), D2D1_FIGURE_BEGIN_FILLED); + sink->AddLine (pointTransformed (rect.getRight(), rect.getY(), transform)); + sink->AddLine (pointTransformed (rect.getRight(), rect.getBottom(), transform)); + sink->AddLine (pointTransformed (rect.getX(), rect.getBottom(), transform)); + sink->EndFigure (D2D1_FIGURE_END_CLOSED); +} + +//============================================================================== +struct Direct2DLowLevelGraphicsContext::Pimpl +{ + ID2D1PathGeometry* rectListToPathGeometry (const RectangleList& clipRegion) { - addTransform (AffineTransform::translation ((float) o.x, (float) o.y)); - } + ID2D1PathGeometry* p = nullptr; + factories->d2dFactory->CreatePathGeometry (&p); - void addTransform (const AffineTransform& transform) - { - currentState->transform = transform.followedBy (currentState->transform); - } + ComSmartPtr sink; + HRESULT hr = p->Open (sink.resetAndGetPointerAddress()); // xxx handle error + sink->SetFillMode (D2D1_FILL_MODE_WINDING); - float getPhysicalPixelScaleFactor() - { - return currentState->transform.getScaleFactor(); - } + for (int i = clipRegion.getNumRectangles(); --i >= 0;) + rectToGeometrySink (clipRegion.getRectangle(i), sink, AffineTransform()); - bool clipToRectangle (const Rectangle& r) - { - currentState->clipToRectangle (r); - return ! isClipEmpty(); + hr = sink->Close(); + return p; } - bool clipToRectangleList (const RectangleList& clipRegion) + ID2D1PathGeometry* pathToPathGeometry (const Path& path, const AffineTransform& transform) { - currentState->clipToRectList (rectListToPathGeometry (clipRegion)); - return ! isClipEmpty(); - } + ID2D1PathGeometry* p = nullptr; + factories->d2dFactory->CreatePathGeometry (&p); - void excludeClipRectangle (const Rectangle&) - { - //xxx - } + ComSmartPtr sink; + HRESULT hr = p->Open (sink.resetAndGetPointerAddress()); + sink->SetFillMode (D2D1_FILL_MODE_WINDING); // xxx need to check Path::isUsingNonZeroWinding() - void clipToPath (const Path& path, const AffineTransform& transform) - { - currentState->clipToPath (pathToPathGeometry (path, transform)); - } + pathToGeometrySink (path, sink, transform); - void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) - { - currentState->clipToImage (sourceImage, transform); + hr = sink->Close(); + return p; } - bool clipRegionIntersects (const Rectangle& r) - { - return currentState->clipRect.intersects (r.toFloat().transformed (currentState->transform).getSmallestIntegerContainer()); - } + SharedResourcePointer factories; - Rectangle getClipBounds() const - { - // xxx could this take into account complex clip regions? - return currentState->clipRect.toFloat().transformed (currentState->transform.inverted()).getSmallestIntegerContainer(); - } + ComSmartPtr renderingTarget; + ComSmartPtr colourBrush; +}; - bool isClipEmpty() const +//============================================================================== +struct Direct2DLowLevelGraphicsContext::SavedState +{ +public: + SavedState (Direct2DLowLevelGraphicsContext& owner_) + : owner (owner_) { - return currentState->clipRect.isEmpty(); + if (owner.currentState != nullptr) + { + // xxx seems like a very slow way to create one of these, and this is a performance + // bottleneck.. Can the same internal objects be shared by multiple state objects, maybe using copy-on-write? + setFill (owner.currentState->fillType); + currentBrush = owner.currentState->currentBrush; + clipRect = owner.currentState->clipRect; + transform = owner.currentState->transform; + + font = owner.currentState->font; + currentFontFace = owner.currentState->currentFontFace; + } + else + { + const D2D1_SIZE_U size (owner.pimpl->renderingTarget->GetPixelSize()); + clipRect.setSize (size.width, size.height); + setFill (FillType (Colours::black)); + } } - void saveState() + ~SavedState() { - states.add (new SavedState (*this)); - currentState = states.getLast(); + clearClip(); + clearFont(); + clearFill(); + clearPathClip(); + clearImageClip(); + complexClipLayer = nullptr; + bitmapMaskLayer = nullptr; } - void restoreState() + void clearClip() { - jassert (states.size() > 1) //you should never pop the last state! - states.removeLast (1); - currentState = states.getLast(); + popClips(); + shouldClipRect = false; } - void beginTransparencyLayer (float /*opacity*/) + void clipToRectangle (const Rectangle& r) { - jassertfalse; //xxx todo + clearClip(); + clipRect = r.toFloat().transformed (transform).getSmallestIntegerContainer(); + shouldClipRect = true; + pushClips(); } - void endTransparencyLayer() + void clearPathClip() { - jassertfalse; //xxx todo - } + popClips(); - void setFill (const FillType& fillType) - { - currentState->setFill (fillType); + if (shouldClipComplex) + { + complexClipGeometry = nullptr; + shouldClipComplex = false; + } } - void setOpacity (float newOpacity) + void Direct2DLowLevelGraphicsContext::SavedState::clipToPath (ID2D1Geometry* geometry) { - currentState->setOpacity (newOpacity); - } + clearPathClip(); - void setInterpolationQuality (Graphics::ResamplingQuality /*quality*/) - { - } + if (complexClipLayer == nullptr) + owner.pimpl->renderingTarget->CreateLayer (complexClipLayer.resetAndGetPointerAddress()); - void fillRect (const Rectangle& r, bool /*replaceExistingContents*/) - { - fillRect (r.toFloat()); + complexClipGeometry = geometry; + shouldClipComplex = true; + pushClips(); } - void fillRect (const Rectangle& r) + void clearRectListClip() { - renderingTarget->SetTransform (transformToMatrix (currentState->transform)); - currentState->createBrush(); - renderingTarget->FillRectangle (rectangleToRectF (r), currentState->currentBrush); - renderingTarget->SetTransform (D2D1::IdentityMatrix()); - } + popClips(); - void fillRectList (const RectangleList& list) - { - for (const Rectangle* r = list.begin(), * const e = list.end(); r != e; ++r) - fillRect (*r); + if (shouldClipRectList) + { + rectListGeometry = nullptr; + shouldClipRectList = false; + } } - void fillPath (const Path& p, const AffineTransform& transform) + void clipToRectList (ID2D1Geometry* geometry) { - currentState->createBrush(); - ComSmartPtr geometry (pathToPathGeometry (p, transform.followedBy (currentState->transform))); + clearRectListClip(); - if (renderingTarget != nullptr) - renderingTarget->FillGeometry (geometry, currentState->currentBrush); + if (rectListLayer == nullptr) + owner.pimpl->renderingTarget->CreateLayer (rectListLayer.resetAndGetPointerAddress()); + + rectListGeometry = geometry; + shouldClipRectList = true; + pushClips(); } - void drawImage (const Image& image, const AffineTransform& transform) + void clearImageClip() { - renderingTarget->SetTransform (transformToMatrix (transform.followedBy (currentState->transform))); - - D2D1_SIZE_U size; - size.width = image.getWidth(); - size.height = image.getHeight(); - - D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); - - Image img (image.convertedToFormat (Image::ARGB)); - Image::BitmapData bd (img, Image::BitmapData::readOnly); - bp.pixelFormat = renderingTarget->GetPixelFormat(); - bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + popClips(); + if (shouldClipBitmap) { - ComSmartPtr tempBitmap; - renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, tempBitmap.resetAndGetPointerAddress()); - if (tempBitmap != nullptr) - renderingTarget->DrawBitmap (tempBitmap); + maskBitmap = nullptr; + bitmapMaskBrush = nullptr; + shouldClipBitmap = false; } - - renderingTarget->SetTransform (D2D1::IdentityMatrix()); } - void drawLine (const Line & line) + void clipToImage (const Image& clipImage, const AffineTransform& clipTransform) { - // xxx doesn't seem to be correctly aligned, may need nudging by 0.5 to match the software renderer's behaviour - renderingTarget->SetTransform (transformToMatrix (currentState->transform)); - currentState->createBrush(); - - renderingTarget->DrawLine (D2D1::Point2F (line.getStartX(), line.getStartY()), - D2D1::Point2F (line.getEndX(), line.getEndY()), - currentState->currentBrush); - renderingTarget->SetTransform (D2D1::IdentityMatrix()); - } + clearImageClip(); - void setFont (const Font& newFont) - { - currentState->setFont (newFont); - } + if (bitmapMaskLayer == nullptr) + owner.pimpl->renderingTarget->CreateLayer (bitmapMaskLayer.resetAndGetPointerAddress()); - const Font& getFont() - { - return currentState->font; - } + D2D1_BRUSH_PROPERTIES brushProps; + brushProps.opacity = 1; + brushProps.transform = transformToMatrix (clipTransform); - void drawGlyph (int glyphNumber, const AffineTransform& transform) - { - currentState->createBrush(); - currentState->createFont(); - - float hScale = currentState->font.getHorizontalScale(); - - renderingTarget->SetTransform (transformToMatrix (AffineTransform::scale (hScale, 1.0f) - .followedBy (transform) - .followedBy (currentState->transform))); - - const UINT16 glyphIndices = (UINT16) glyphNumber; - const FLOAT glyphAdvances = 0; - DWRITE_GLYPH_OFFSET offset; - offset.advanceOffset = 0; - offset.ascenderOffset = 0; - - DWRITE_GLYPH_RUN glyphRun; - glyphRun.fontFace = currentState->currentFontFace; - glyphRun.fontEmSize = (FLOAT) (currentState->font.getHeight() * currentState->fontHeightToEmSizeFactor); - glyphRun.glyphCount = 1; - glyphRun.glyphIndices = &glyphIndices; - glyphRun.glyphAdvances = &glyphAdvances; - glyphRun.glyphOffsets = &offset; - glyphRun.isSideways = FALSE; - glyphRun.bidiLevel = 0; - - renderingTarget->DrawGlyphRun (D2D1::Point2F (0, 0), &glyphRun, currentState->currentBrush); - renderingTarget->SetTransform (D2D1::IdentityMatrix()); - } + D2D1_BITMAP_BRUSH_PROPERTIES bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP); - bool drawTextLayout (const AttributedString& text, const Rectangle& area) - { - renderingTarget->SetTransform (transformToMatrix (currentState->transform)); + D2D1_SIZE_U size; + size.width = clipImage.getWidth(); + size.height = clipImage.getHeight(); - DirectWriteTypeLayout::drawToD2DContext (text, area, *renderingTarget, factories->directWriteFactory, - factories->d2dFactory, factories->systemFonts); + D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); + + maskImage = clipImage.convertedToFormat (Image::ARGB); + Image::BitmapData bd (maskImage, Image::BitmapData::readOnly); // xxx should be maskImage? + bp.pixelFormat = owner.pimpl->renderingTarget->GetPixelFormat(); + bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - renderingTarget->SetTransform (D2D1::IdentityMatrix()); - return true; + HRESULT hr = owner.pimpl->renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, maskBitmap.resetAndGetPointerAddress()); + hr = owner.pimpl->renderingTarget->CreateBitmapBrush (maskBitmap, bmProps, brushProps, bitmapMaskBrush.resetAndGetPointerAddress()); + + imageMaskLayerParams = D2D1::LayerParameters(); + imageMaskLayerParams.opacityBrush = bitmapMaskBrush; + + shouldClipBitmap = true; + pushClips(); } - //============================================================================== - class SavedState + void popClips() { - public: - SavedState (Direct2DLowLevelGraphicsContext& owner_) - : owner (owner_), currentBrush (0), - fontHeightToEmSizeFactor (1.0f), currentFontFace (0), - clipsRect (false), shouldClipRect (false), - clipsRectList (false), shouldClipRectList (false), - clipsComplex (false), shouldClipComplex (false), - clipsBitmap (false), shouldClipBitmap (false) + if (clipsBitmap) { - if (owner.currentState != nullptr) - { - // xxx seems like a very slow way to create one of these, and this is a performance - // bottleneck.. Can the same internal objects be shared by multiple state objects, maybe using copy-on-write? - setFill (owner.currentState->fillType); - currentBrush = owner.currentState->currentBrush; - clipRect = owner.currentState->clipRect; - transform = owner.currentState->transform; - - font = owner.currentState->font; - currentFontFace = owner.currentState->currentFontFace; - } - else - { - const D2D1_SIZE_U size (owner.renderingTarget->GetPixelSize()); - clipRect.setSize (size.width, size.height); - setFill (FillType (Colours::black)); - } + owner.pimpl->renderingTarget->PopLayer(); + clipsBitmap = false; } - ~SavedState() + if (clipsComplex) { - clearClip(); - clearFont(); - clearFill(); - clearPathClip(); - clearImageClip(); - complexClipLayer = 0; - bitmapMaskLayer = 0; + owner.pimpl->renderingTarget->PopLayer(); + clipsComplex = false; } - void clearClip() + if (clipsRectList) { - popClips(); - shouldClipRect = false; + owner.pimpl->renderingTarget->PopLayer(); + clipsRectList = false; } - void clipToRectangle (const Rectangle& r) + if (clipsRect) { - clearClip(); - clipRect = r.toFloat().transformed (transform).getSmallestIntegerContainer(); - shouldClipRect = true; - pushClips(); + owner.pimpl->renderingTarget->PopAxisAlignedClip(); + clipsRect = false; } + } - void clearPathClip() + void pushClips() + { + if (shouldClipRect && !clipsRect) { - popClips(); - - if (shouldClipComplex) - { - complexClipGeometry = 0; - shouldClipComplex = false; - } + owner.pimpl->renderingTarget->PushAxisAlignedClip (rectangleToRectF (clipRect), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); + clipsRect = true; } - void clipToPath (ID2D1Geometry* geometry) + if (shouldClipRectList && !clipsRectList) { - clearPathClip(); - - if (complexClipLayer == 0) - owner.renderingTarget->CreateLayer (complexClipLayer.resetAndGetPointerAddress()); - - complexClipGeometry = geometry; - shouldClipComplex = true; - pushClips(); + D2D1_LAYER_PARAMETERS layerParams = D2D1::LayerParameters(); + rectListGeometry->GetBounds (D2D1::IdentityMatrix(), &layerParams.contentBounds); + layerParams.geometricMask = rectListGeometry; + owner.pimpl->renderingTarget->PushLayer (layerParams, rectListLayer); + clipsRectList = true; } - void clearRectListClip() + if (shouldClipComplex && !clipsComplex) { - popClips(); - - if (shouldClipRectList) - { - rectListGeometry = 0; - shouldClipRectList = false; - } + D2D1_LAYER_PARAMETERS layerParams = D2D1::LayerParameters(); + complexClipGeometry->GetBounds (D2D1::IdentityMatrix(), &layerParams.contentBounds); + layerParams.geometricMask = complexClipGeometry; + owner.pimpl->renderingTarget->PushLayer (layerParams, complexClipLayer); + clipsComplex = true; } - void clipToRectList (ID2D1Geometry* geometry) + if (shouldClipBitmap && !clipsBitmap) { - clearRectListClip(); - - if (rectListLayer == 0) - owner.renderingTarget->CreateLayer (rectListLayer.resetAndGetPointerAddress()); - - rectListGeometry = geometry; - shouldClipRectList = true; - pushClips(); + owner.pimpl->renderingTarget->PushLayer (imageMaskLayerParams, bitmapMaskLayer); + clipsBitmap = true; } + } - void clearImageClip() + void setFill (const FillType& newFillType) + { + if (fillType != newFillType) { - popClips(); - - if (shouldClipBitmap) - { - maskBitmap = 0; - bitmapMaskBrush = 0; - shouldClipBitmap = false; - } + fillType = newFillType; + clearFill(); } + } - void clipToImage (const Image& image, const AffineTransform& transform) - { - clearImageClip(); - - if (bitmapMaskLayer == 0) - owner.renderingTarget->CreateLayer (bitmapMaskLayer.resetAndGetPointerAddress()); - - D2D1_BRUSH_PROPERTIES brushProps; - brushProps.opacity = 1; - brushProps.transform = transformToMatrix (transform); - - D2D1_BITMAP_BRUSH_PROPERTIES bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP); - - D2D1_SIZE_U size; - size.width = image.getWidth(); - size.height = image.getHeight(); - - D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); - - maskImage = image.convertedToFormat (Image::ARGB); - Image::BitmapData bd (this->image, Image::BitmapData::readOnly); // xxx should be maskImage? - bp.pixelFormat = owner.renderingTarget->GetPixelFormat(); - bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - - HRESULT hr = owner.renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, maskBitmap.resetAndGetPointerAddress()); - hr = owner.renderingTarget->CreateBitmapBrush (maskBitmap, bmProps, brushProps, bitmapMaskBrush.resetAndGetPointerAddress()); - - imageMaskLayerParams = D2D1::LayerParameters(); - imageMaskLayerParams.opacityBrush = bitmapMaskBrush; + void clearFont() + { + currentFontFace = localFontFace = nullptr; + } - shouldClipBitmap = true; - pushClips(); + void setFont (const Font& newFont) + { + if (font != newFont) + { + font = newFont; + clearFont(); } + } - void popClips() + void createFont() + { + if (currentFontFace == nullptr) { - if (clipsBitmap) - { - owner.renderingTarget->PopLayer(); - clipsBitmap = false; - } + WindowsDirectWriteTypeface* typeface = dynamic_cast (font.getTypeface()); + currentFontFace = typeface->getIDWriteFontFace(); + fontHeightToEmSizeFactor = typeface->getUnitsToHeightScaleFactor(); + } + } - if (clipsComplex) - { - owner.renderingTarget->PopLayer(); - clipsComplex = false; - } + void setOpacity (float newOpacity) + { + fillType.setOpacity (newOpacity); - if (clipsRectList) - { - owner.renderingTarget->PopLayer(); - clipsRectList = false; - } + if (currentBrush != nullptr) + currentBrush->SetOpacity (newOpacity); + } - if (clipsRect) - { - owner.renderingTarget->PopAxisAlignedClip(); - clipsRect = false; - } - } + void clearFill() + { + gradientStops = nullptr; + linearGradient = nullptr; + radialGradient = nullptr; + bitmap = nullptr; + bitmapBrush = nullptr; + currentBrush = nullptr; + } - void pushClips() + void createBrush() + { + if (currentBrush == nullptr) { - if (shouldClipRect && ! clipsRect) + if (fillType.isColour()) { - owner.renderingTarget->PushAxisAlignedClip (rectangleToRectF (clipRect), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); - clipsRect = true; + D2D1_COLOR_F colour = colourToD2D (fillType.colour); + owner.pimpl->colourBrush->SetColor (colour); + currentBrush = owner.pimpl->colourBrush; } - - if (shouldClipRectList && ! clipsRectList) + else if (fillType.isTiledImage()) { - D2D1_LAYER_PARAMETERS layerParams = D2D1::LayerParameters(); - rectListGeometry->GetBounds (D2D1::IdentityMatrix(), &layerParams.contentBounds); - layerParams.geometricMask = rectListGeometry; - owner.renderingTarget->PushLayer (layerParams, rectListLayer); - clipsRectList = true; - } + D2D1_BRUSH_PROPERTIES brushProps; + brushProps.opacity = fillType.getOpacity(); + brushProps.transform = transformToMatrix (fillType.transform); - if (shouldClipComplex && ! clipsComplex) - { - D2D1_LAYER_PARAMETERS layerParams = D2D1::LayerParameters(); - complexClipGeometry->GetBounds (D2D1::IdentityMatrix(), &layerParams.contentBounds); - layerParams.geometricMask = complexClipGeometry; - owner.renderingTarget->PushLayer (layerParams, complexClipLayer); - clipsComplex = true; - } + D2D1_BITMAP_BRUSH_PROPERTIES bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP); - if (shouldClipBitmap && ! clipsBitmap) - { - owner.renderingTarget->PushLayer (imageMaskLayerParams, bitmapMaskLayer); - clipsBitmap = true; - } - } + image = fillType.image; - void setFill (const FillType& newFillType) - { - if (fillType != newFillType) - { - fillType = newFillType; - clearFill(); - } - } + D2D1_SIZE_U size; + size.width = image.getWidth(); + size.height = image.getHeight(); - void clearFont() - { - currentFontFace = localFontFace = 0; - } + D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); - void setFont (const Font& newFont) - { - if (font != newFont) - { - font = newFont; - clearFont(); - } - } + this->image = image.convertedToFormat (Image::ARGB); + Image::BitmapData bd (this->image, Image::BitmapData::readOnly); + bp.pixelFormat = owner.pimpl->renderingTarget->GetPixelFormat(); + bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - void createFont() - { - if (currentFontFace == nullptr) - { - WindowsDirectWriteTypeface* typeface = dynamic_cast (font.getTypeface()); - currentFontFace = typeface->getIDWriteFontFace(); - fontHeightToEmSizeFactor = typeface->unitsToHeightScaleFactor(); + HRESULT hr = owner.pimpl->renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, bitmap.resetAndGetPointerAddress()); + hr = owner.pimpl->renderingTarget->CreateBitmapBrush (bitmap, bmProps, brushProps, bitmapBrush.resetAndGetPointerAddress()); + + currentBrush = bitmapBrush; } - } + else if (fillType.isGradient()) + { + gradientStops = nullptr; - void setOpacity (float newOpacity) - { - fillType.setOpacity (newOpacity); + D2D1_BRUSH_PROPERTIES brushProps; + brushProps.opacity = fillType.getOpacity(); + brushProps.transform = transformToMatrix (fillType.transform.followedBy (transform)); - if (currentBrush != nullptr) - currentBrush->SetOpacity (newOpacity); - } + const int numColors = fillType.gradient->getNumColours(); - void clearFill() - { - gradientStops = 0; - linearGradient = 0; - radialGradient = 0; - bitmap = 0; - bitmapBrush = 0; - currentBrush = 0; - } + HeapBlock stops (numColors); - void createBrush() - { - if (currentBrush == 0) - { - if (fillType.isColour()) + for (int i = fillType.gradient->getNumColours(); --i >= 0;) { - D2D1_COLOR_F colour = colourToD2D (fillType.colour); - owner.colourBrush->SetColor (colour); - currentBrush = owner.colourBrush; + stops[i].color = colourToD2D (fillType.gradient->getColour (i)); + stops[i].position = (FLOAT) fillType.gradient->getColourPosition (i); } - else if (fillType.isTiledImage()) + + owner.pimpl->renderingTarget->CreateGradientStopCollection (stops.getData(), numColors, gradientStops.resetAndGetPointerAddress()); + + if (fillType.gradient->isRadial) { - D2D1_BRUSH_PROPERTIES brushProps; - brushProps.opacity = fillType.getOpacity(); - brushProps.transform = transformToMatrix (fillType.transform); + radialGradient = nullptr; - D2D1_BITMAP_BRUSH_PROPERTIES bmProps = D2D1::BitmapBrushProperties (D2D1_EXTEND_MODE_WRAP,D2D1_EXTEND_MODE_WRAP); + const Point p1 = fillType.gradient->point1; + const Point p2 = fillType.gradient->point2; + float r = p1.getDistanceFrom(p2); - image = fillType.image; + D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES props = + D2D1::RadialGradientBrushProperties(D2D1::Point2F(p1.x, p1.y), + D2D1::Point2F(0, 0), + r, r); - D2D1_SIZE_U size; - size.width = image.getWidth(); - size.height = image.getHeight(); + owner.pimpl->renderingTarget->CreateRadialGradientBrush(props, brushProps, gradientStops, radialGradient.resetAndGetPointerAddress()); + currentBrush = radialGradient; + } + else + { + linearGradient = 0; - D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); + const Point p1 = fillType.gradient->point1; + const Point p2 = fillType.gradient->point2; - this->image = image.convertedToFormat (Image::ARGB); - Image::BitmapData bd (this->image, Image::BitmapData::readOnly); - bp.pixelFormat = owner.renderingTarget->GetPixelFormat(); - bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES props = + D2D1::LinearGradientBrushProperties(D2D1::Point2F(p1.x, p1.y), + D2D1::Point2F(p2.x, p2.y)); - HRESULT hr = owner.renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, bitmap.resetAndGetPointerAddress()); - hr = owner.renderingTarget->CreateBitmapBrush (bitmap, bmProps, brushProps, bitmapBrush.resetAndGetPointerAddress()); + owner.pimpl->renderingTarget->CreateLinearGradientBrush (props, brushProps, gradientStops, linearGradient.resetAndGetPointerAddress()); - currentBrush = bitmapBrush; + currentBrush = linearGradient; } - else if (fillType.isGradient()) - { - gradientStops = 0; + } + } + } - D2D1_BRUSH_PROPERTIES brushProps; - brushProps.opacity = fillType.getOpacity(); - brushProps.transform = transformToMatrix (fillType.transform.followedBy (transform)); + Direct2DLowLevelGraphicsContext& owner; - const int numColors = fillType.gradient->getNumColours(); + AffineTransform transform; - HeapBlock stops (numColors); + Font font; + float fontHeightToEmSizeFactor = 1.0; - for (int i = fillType.gradient->getNumColours(); --i >= 0;) - { - stops[i].color = colourToD2D (fillType.gradient->getColour(i)); - stops[i].position = (FLOAT) fillType.gradient->getColourPosition(i); - } + IDWriteFontFace* currentFontFace = nullptr; + ComSmartPtr localFontFace; - owner.renderingTarget->CreateGradientStopCollection (stops.getData(), numColors, gradientStops.resetAndGetPointerAddress()); + Rectangle clipRect; + bool clipsRect = false, shouldClipRect = false; - if (fillType.gradient->isRadial) - { - radialGradient = 0; + Image image; + ComSmartPtr bitmap; // xxx needs a better name - what is this for?? + bool clipsBitmap = false, shouldClipBitmap = false; - const Point p1 = fillType.gradient->point1; - const Point p2 = fillType.gradient->point2; - float r = p1.getDistanceFrom (p2); + ComSmartPtr complexClipGeometry; + D2D1_LAYER_PARAMETERS complexClipLayerParams; + ComSmartPtr complexClipLayer; + bool clipsComplex = false, shouldClipComplex = false; - D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES props = - D2D1::RadialGradientBrushProperties (D2D1::Point2F (p1.x, p1.y), - D2D1::Point2F (0, 0), - r, r); + ComSmartPtr rectListGeometry; + D2D1_LAYER_PARAMETERS rectListLayerParams; + ComSmartPtr rectListLayer; + bool clipsRectList = false, shouldClipRectList = false; - owner.renderingTarget->CreateRadialGradientBrush (props, brushProps, gradientStops, radialGradient.resetAndGetPointerAddress()); - currentBrush = radialGradient; - } - else - { - linearGradient = 0; + Image maskImage; + D2D1_LAYER_PARAMETERS imageMaskLayerParams; + ComSmartPtr bitmapMaskLayer; + ComSmartPtr maskBitmap; + ComSmartPtr bitmapMaskBrush; - const Point p1 = fillType.gradient->point1; - const Point p2 = fillType.gradient->point2; + ID2D1Brush* currentBrush = nullptr; + ComSmartPtr bitmapBrush; + ComSmartPtr linearGradient; + ComSmartPtr radialGradient; + ComSmartPtr gradientStops; - D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES props = - D2D1::LinearGradientBrushProperties (D2D1::Point2F (p1.x, p1.y), - D2D1::Point2F (p2.x, p2.y)); + FillType fillType; - owner.renderingTarget->CreateLinearGradientBrush (props, brushProps, gradientStops, linearGradient.resetAndGetPointerAddress()); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SavedState) +}; - currentBrush = linearGradient; - } - } - } - } +//============================================================================== +Direct2DLowLevelGraphicsContext::Direct2DLowLevelGraphicsContext (HWND hwnd_) + : hwnd (hwnd_), + currentState (nullptr), + pimpl (new Pimpl()) +{ + RECT windowRect; + GetClientRect (hwnd, &windowRect); + D2D1_SIZE_U size = { (UINT32) (windowRect.right - windowRect.left), (UINT32) (windowRect.bottom - windowRect.top) }; + bounds.setSize (size.width, size.height); - //============================================================================== - //xxx most of these members should probably be private... + D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(); + D2D1_HWND_RENDER_TARGET_PROPERTIES propsHwnd = D2D1::HwndRenderTargetProperties (hwnd, size); - Direct2DLowLevelGraphicsContext& owner; + if (pimpl->factories->d2dFactory != nullptr) + { + HRESULT hr = pimpl->factories->d2dFactory->CreateHwndRenderTarget (props, propsHwnd, pimpl->renderingTarget.resetAndGetPointerAddress()); + jassert (SUCCEEDED (hr)); ignoreUnused (hr); + hr = pimpl->renderingTarget->CreateSolidColorBrush (D2D1::ColorF::ColorF (0.0f, 0.0f, 0.0f, 1.0f), pimpl->colourBrush.resetAndGetPointerAddress()); + } +} - AffineTransform transform; +Direct2DLowLevelGraphicsContext::~Direct2DLowLevelGraphicsContext() +{ + states.clear(); +} - Font font; - float fontHeightToEmSizeFactor; - IDWriteFontFace* currentFontFace; - ComSmartPtr localFontFace; +void Direct2DLowLevelGraphicsContext::resized() +{ + RECT windowRect; + GetClientRect (hwnd, &windowRect); + D2D1_SIZE_U size = { (UINT32) (windowRect.right - windowRect.left), (UINT32) (windowRect.bottom - windowRect.top) }; - FillType fillType; + pimpl->renderingTarget->Resize (size); + bounds.setSize (size.width, size.height); +} - Image image; - ComSmartPtr bitmap; // xxx needs a better name - what is this for?? +void Direct2DLowLevelGraphicsContext::clear() +{ + pimpl->renderingTarget->Clear (D2D1::ColorF (D2D1::ColorF::White, 0.0f)); // xxx why white and not black? +} - Rectangle clipRect; - bool clipsRect, shouldClipRect; +void Direct2DLowLevelGraphicsContext::start() +{ + pimpl->renderingTarget->BeginDraw(); + saveState(); +} - ComSmartPtr complexClipGeometry; - D2D1_LAYER_PARAMETERS complexClipLayerParams; - ComSmartPtr complexClipLayer; - bool clipsComplex, shouldClipComplex; +void Direct2DLowLevelGraphicsContext::end() +{ + states.clear(); + currentState = 0; + pimpl->renderingTarget->EndDraw(); + pimpl->renderingTarget->CheckWindowState(); +} - ComSmartPtr rectListGeometry; - D2D1_LAYER_PARAMETERS rectListLayerParams; - ComSmartPtr rectListLayer; - bool clipsRectList, shouldClipRectList; +void Direct2DLowLevelGraphicsContext::setOrigin (Point o) +{ + addTransform (AffineTransform::translation ((float) o.x, (float) o.y)); +} - Image maskImage; - D2D1_LAYER_PARAMETERS imageMaskLayerParams; - ComSmartPtr bitmapMaskLayer; - ComSmartPtr maskBitmap; - ComSmartPtr bitmapMaskBrush; - bool clipsBitmap, shouldClipBitmap; +void Direct2DLowLevelGraphicsContext::addTransform (const AffineTransform& transform) +{ + currentState->transform = transform.followedBy (currentState->transform); +} - ID2D1Brush* currentBrush; - ComSmartPtr bitmapBrush; - ComSmartPtr linearGradient; - ComSmartPtr radialGradient; - ComSmartPtr gradientStops; +float Direct2DLowLevelGraphicsContext::getPhysicalPixelScaleFactor() +{ + return currentState->transform.getScaleFactor(); +} - private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SavedState) - }; +bool Direct2DLowLevelGraphicsContext::clipToRectangle (const Rectangle& r) +{ + currentState->clipToRectangle (r); + return ! isClipEmpty(); +} - //============================================================================== -private: - SharedResourcePointer factories; - HWND hwnd; - ComSmartPtr renderingTarget; - ComSmartPtr colourBrush; - Rectangle bounds; +bool Direct2DLowLevelGraphicsContext::clipToRectangleList (const RectangleList& clipRegion) +{ + currentState->clipToRectList (pimpl->rectListToPathGeometry (clipRegion)); + return ! isClipEmpty(); +} - SavedState* currentState; - OwnedArray states; +void Direct2DLowLevelGraphicsContext::excludeClipRectangle (const Rectangle&) +{ + //xxx +} - //============================================================================== - template - static D2D1_RECT_F rectangleToRectF (const Rectangle& r) - { - return D2D1::RectF ((float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom()); - } +void Direct2DLowLevelGraphicsContext::clipToPath (const Path& path, const AffineTransform& transform) +{ + currentState->clipToPath (pimpl->pathToPathGeometry (path, transform)); +} - static D2D1_COLOR_F colourToD2D (Colour c) - { - return D2D1::ColorF::ColorF (c.getFloatRed(), c.getFloatGreen(), c.getFloatBlue(), c.getFloatAlpha()); - } +void Direct2DLowLevelGraphicsContext::clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) +{ + currentState->clipToImage (sourceImage, transform); +} - static D2D1_POINT_2F pointTransformed (int x, int y, const AffineTransform& transform) - { - transform.transformPoint (x, y); - return D2D1::Point2F ((FLOAT) x, (FLOAT) y); - } +bool Direct2DLowLevelGraphicsContext::clipRegionIntersects (const Rectangle& r) +{ + return currentState->clipRect.intersects (r.toFloat().transformed (currentState->transform).getSmallestIntegerContainer()); +} - static void rectToGeometrySink (const Rectangle& rect, ID2D1GeometrySink* sink) - { - sink->BeginFigure (pointTransformed (rect.getX(), rect.getY()), D2D1_FIGURE_BEGIN_FILLED); - sink->AddLine (pointTransformed (rect.getRight(), rect.getY())); - sink->AddLine (pointTransformed (rect.getRight(), rect.getBottom())); - sink->AddLine (pointTransformed (rect.getX(), rect.getBottom())); - sink->EndFigure (D2D1_FIGURE_END_CLOSED); - } +Rectangle Direct2DLowLevelGraphicsContext::getClipBounds() const +{ + // xxx could this take into account complex clip regions? + return currentState->clipRect.toFloat().transformed (currentState->transform.inverted()).getSmallestIntegerContainer(); +} - static ID2D1PathGeometry* rectListToPathGeometry (const RectangleList& clipRegion) - { - ID2D1PathGeometry* p = nullptr; - factories->d2dFactory->CreatePathGeometry (&p); +bool Direct2DLowLevelGraphicsContext::isClipEmpty() const +{ + return currentState->clipRect.isEmpty(); +} - ComSmartPtr sink; - HRESULT hr = p->Open (sink.resetAndGetPointerAddress()); // xxx handle error - sink->SetFillMode (D2D1_FILL_MODE_WINDING); +void Direct2DLowLevelGraphicsContext::saveState() +{ + states.add (new SavedState (*this)); + currentState = states.getLast(); +} - for (int i = clipRegion.getNumRectangles(); --i >= 0;) - rectToGeometrySink (clipRegion.getRectangle(i), sink); +void Direct2DLowLevelGraphicsContext::restoreState() +{ + jassert (states.size() > 1); //you should never pop the last state! + states.removeLast (1); + currentState = states.getLast(); +} - hr = sink->Close(); - return p; - } +void Direct2DLowLevelGraphicsContext::beginTransparencyLayer (float /*opacity*/) +{ + jassertfalse; //xxx todo +} - static void pathToGeometrySink (const Path& path, ID2D1GeometrySink* sink, const AffineTransform& transform) - { - Path::Iterator it (path); +void Direct2DLowLevelGraphicsContext::endTransparencyLayer() +{ + jassertfalse; //xxx todo +} - while (it.next()) - { - switch (it.elementType) - { - case Path::Iterator::cubicTo: - { - D2D1_BEZIER_SEGMENT seg; +void Direct2DLowLevelGraphicsContext::setFill (const FillType& fillType) +{ + currentState->setFill (fillType); +} + +void Direct2DLowLevelGraphicsContext::setOpacity (float newOpacity) +{ + currentState->setOpacity (newOpacity); +} - transform.transformPoint (it.x1, it.y1); - seg.point1 = D2D1::Point2F (it.x1, it.y1); +void Direct2DLowLevelGraphicsContext::setInterpolationQuality (Graphics::ResamplingQuality /*quality*/) +{ +} - transform.transformPoint (it.x2, it.y2); - seg.point2 = D2D1::Point2F (it.x2, it.y2); +void Direct2DLowLevelGraphicsContext::fillRect (const Rectangle& r, bool /*replaceExistingContents*/) +{ + fillRect (r.toFloat()); +} - transform.transformPoint(it.x3, it.y3); - seg.point3 = D2D1::Point2F (it.x3, it.y3); +void Direct2DLowLevelGraphicsContext::fillRect (const Rectangle& r) +{ + pimpl->renderingTarget->SetTransform (transformToMatrix (currentState->transform)); + currentState->createBrush(); + pimpl->renderingTarget->FillRectangle (rectangleToRectF (r), currentState->currentBrush); + pimpl->renderingTarget->SetTransform (D2D1::IdentityMatrix()); +} - sink->AddBezier (seg); - break; - } +void Direct2DLowLevelGraphicsContext::fillRectList (const RectangleList& list) +{ + for (auto& r : list) + fillRect (r); +} - case Path::Iterator::lineTo: - { - transform.transformPoint (it.x1, it.y1); - sink->AddLine (D2D1::Point2F (it.x1, it.y1)); - break; - } +void Direct2DLowLevelGraphicsContext::fillPath (const Path& p, const AffineTransform& transform) +{ + currentState->createBrush(); + ComSmartPtr geometry (pimpl->pathToPathGeometry (p, transform.followedBy (currentState->transform))); - case Path::Iterator::quadraticTo: - { - D2D1_QUADRATIC_BEZIER_SEGMENT seg; + if (pimpl->renderingTarget != nullptr) + pimpl->renderingTarget->FillGeometry (geometry, currentState->currentBrush); +} - transform.transformPoint (it.x1, it.y1); - seg.point1 = D2D1::Point2F (it.x1, it.y1); +void Direct2DLowLevelGraphicsContext::drawImage (const Image& image, const AffineTransform& transform) +{ + pimpl->renderingTarget->SetTransform (transformToMatrix (transform.followedBy (currentState->transform))); - transform.transformPoint (it.x2, it.y2); - seg.point2 = D2D1::Point2F (it.x2, it.y2); + D2D1_SIZE_U size; + size.width = image.getWidth(); + size.height = image.getHeight(); - sink->AddQuadraticBezier (seg); - break; - } + D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties(); - case Path::Iterator::closePath: - { - sink->EndFigure (D2D1_FIGURE_END_CLOSED); - break; - } + Image img (image.convertedToFormat (Image::ARGB)); + Image::BitmapData bd (img, Image::BitmapData::readOnly); + bp.pixelFormat = pimpl->renderingTarget->GetPixelFormat(); + bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; - case Path::Iterator::startNewSubPath: - { - transform.transformPoint (it.x1, it.y1); - sink->BeginFigure (D2D1::Point2F (it.x1, it.y1), D2D1_FIGURE_BEGIN_FILLED); - break; - } - } - } + { + ComSmartPtr tempBitmap; + pimpl->renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, tempBitmap.resetAndGetPointerAddress()); + if (tempBitmap != nullptr) + pimpl->renderingTarget->DrawBitmap (tempBitmap); } - static ID2D1PathGeometry* pathToPathGeometry (const Path& path, const AffineTransform& transform) - { - ID2D1PathGeometry* p = nullptr; - factories->d2dFactory->CreatePathGeometry (&p); + pimpl->renderingTarget->SetTransform (D2D1::IdentityMatrix()); +} - ComSmartPtr sink; - HRESULT hr = p->Open (sink.resetAndGetPointerAddress()); - sink->SetFillMode (D2D1_FILL_MODE_WINDING); // xxx need to check Path::isUsingNonZeroWinding() +void Direct2DLowLevelGraphicsContext::drawLine (const Line & line) +{ + // xxx doesn't seem to be correctly aligned, may need nudging by 0.5 to match the software renderer's behaviour + pimpl->renderingTarget->SetTransform (transformToMatrix (currentState->transform)); + currentState->createBrush(); - pathToGeometrySink (path, sink, transform); + pimpl->renderingTarget->DrawLine (D2D1::Point2F (line.getStartX(), line.getStartY()), + D2D1::Point2F (line.getEndX(), line.getEndY()), + currentState->currentBrush); + pimpl->renderingTarget->SetTransform (D2D1::IdentityMatrix()); +} - hr = sink->Close(); - return p; - } +void Direct2DLowLevelGraphicsContext::setFont (const Font& newFont) +{ + currentState->setFont (newFont); +} - static D2D1::Matrix3x2F transformToMatrix (const AffineTransform& transform) - { - D2D1::Matrix3x2F matrix; - matrix._11 = transform.mat00; - matrix._12 = transform.mat10; - matrix._21 = transform.mat01; - matrix._22 = transform.mat11; - matrix._31 = transform.mat02; - matrix._32 = transform.mat12; - return matrix; - } +const Font& Direct2DLowLevelGraphicsContext::getFont() +{ + return currentState->font; +} - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DLowLevelGraphicsContext) -}; +void Direct2DLowLevelGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& transform) +{ + currentState->createBrush(); + currentState->createFont(); + + float hScale = currentState->font.getHorizontalScale(); + + pimpl->renderingTarget->SetTransform (transformToMatrix (AffineTransform::scale (hScale, 1.0f) + .followedBy (transform) + .followedBy (currentState->transform))); + + const UINT16 glyphIndices = (UINT16) glyphNumber; + const FLOAT glyphAdvances = 0; + DWRITE_GLYPH_OFFSET offset; + offset.advanceOffset = 0; + offset.ascenderOffset = 0; + + DWRITE_GLYPH_RUN glyphRun; + glyphRun.fontFace = currentState->currentFontFace; + glyphRun.fontEmSize = (FLOAT) (currentState->font.getHeight() * currentState->fontHeightToEmSizeFactor); + glyphRun.glyphCount = 1; + glyphRun.glyphIndices = &glyphIndices; + glyphRun.glyphAdvances = &glyphAdvances; + glyphRun.glyphOffsets = &offset; + glyphRun.isSideways = FALSE; + glyphRun.bidiLevel = 0; + + pimpl->renderingTarget->DrawGlyphRun (D2D1::Point2F (0, 0), &glyphRun, currentState->currentBrush); + pimpl->renderingTarget->SetTransform (D2D1::IdentityMatrix()); +} + +bool Direct2DLowLevelGraphicsContext::drawTextLayout (const AttributedString& text, const Rectangle& area) +{ + pimpl->renderingTarget->SetTransform (transformToMatrix (currentState->transform)); + + DirectWriteTypeLayout::drawToD2DContext (text, area, + *(pimpl->renderingTarget), + *(pimpl->factories->directWriteFactory), + *(pimpl->factories->systemFonts)); + + pimpl->renderingTarget->SetTransform (D2D1::IdentityMatrix()); + return true; +} diff --git a/source/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.h b/source/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.h new file mode 100644 index 000000000..2c923a76e --- /dev/null +++ b/source/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.h @@ -0,0 +1,103 @@ +/* + ============================================================================== + + 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 + +#ifndef _WINDEF_ +class HWND__; // Forward or never +typedef HWND__* HWND; +#endif + +class Direct2DLowLevelGraphicsContext : public LowLevelGraphicsContext +{ +public: + Direct2DLowLevelGraphicsContext (HWND); + ~Direct2DLowLevelGraphicsContext(); + + //============================================================================== + bool isVectorDevice() const override { return false; } + + void setOrigin (Point) override; + void addTransform (const AffineTransform&) override; + float getPhysicalPixelScaleFactor() override; + bool clipToRectangle (const Rectangle&) override; + bool clipToRectangleList (const RectangleList&) override; + void excludeClipRectangle (const Rectangle&) override; + void clipToPath (const Path&, const AffineTransform&) override; + void clipToImageAlpha (const Image&, const AffineTransform&) override; + bool clipRegionIntersects (const Rectangle&) override; + Rectangle getClipBounds() const override; + bool isClipEmpty() const override; + + //============================================================================== + void saveState() override; + void restoreState() override; + void beginTransparencyLayer (float opacity) override; + void endTransparencyLayer() override; + + //============================================================================== + void setFill (const FillType&) override; + void setOpacity (float) override; + void setInterpolationQuality (Graphics::ResamplingQuality) override; + + //============================================================================== + void fillRect (const Rectangle&, bool replaceExistingContents) override; + void fillRect (const Rectangle&) override; + void fillRectList (const RectangleList&) override; + void fillPath (const Path&, const AffineTransform&) override; + void drawImage (const Image& sourceImage, const AffineTransform&) override; + + //============================================================================== + void drawLine (const Line&) override; + void setFont (const Font&) override; + const Font& getFont() override; + void drawGlyph (int glyphNumber, const AffineTransform&) override; + bool drawTextLayout (const AttributedString&, const Rectangle&) override; + + void resized(); + void clear(); + + void start(); + void end(); + + //============================================================================== +private: + struct SavedState; + + HWND hwnd; + + SavedState* currentState; + OwnedArray states; + + Rectangle bounds; + + struct Pimpl; + friend struct Pimpl; + friend struct ContainerDeletePolicy; + ScopedPointer pimpl; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DLowLevelGraphicsContext) +}; diff --git a/source/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp b/source/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp index f2a70895d..739fc539a 100644 --- a/source/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp +++ b/source/modules/juce_graphics/native/juce_win32_DirectWriteTypeLayout.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp b/source/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp index d6f785e6d..fb30ddb42 100644 --- a/source/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp +++ b/source/modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -263,6 +265,8 @@ public: IDWriteFontFace* getIDWriteFontFace() const noexcept { return dwFontFace; } + float getUnitsToHeightScaleFactor() const noexcept { return unitsToHeightScaleFactor; } + private: SharedResourcePointer factories; ComSmartPtr dwFontFace; diff --git a/source/modules/juce_graphics/native/juce_win32_Fonts.cpp b/source/modules/juce_graphics/native/juce_win32_Fonts.cpp index 9d84483df..d8198341c 100644 --- a/source/modules/juce_graphics/native/juce_win32_Fonts.cpp +++ b/source/modules/juce_graphics/native/juce_win32_Fonts.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -73,7 +75,7 @@ namespace TTFNameExtractor for (int i = 0; i < numChars; ++i) buffer[i] = ByteOrder::swapIfLittleEndian (buffer[i]); - static_jassert (sizeof (CharPointer_UTF16::CharType) == sizeof (uint16)); + static_assert (sizeof (CharPointer_UTF16::CharType) == sizeof (uint16), "Sanity check UTF-16 type"); result = CharPointer_UTF16 ((CharPointer_UTF16::CharType*) buffer.getData()); } else @@ -110,7 +112,7 @@ namespace TTFNameExtractor } } - return String(); + return {}; } static String getTypefaceNameFromFile (MemoryInputStream& input) @@ -128,7 +130,7 @@ namespace TTFNameExtractor return parseNameTable (input, ByteOrder::swapIfLittleEndian (tableDirectory.offset)); } - return String(); + return {}; } } diff --git a/source/modules/juce_graphics/native/juce_win32_IconHelpers.cpp b/source/modules/juce_graphics/native/juce_win32_IconHelpers.cpp new file mode 100644 index 000000000..287005422 --- /dev/null +++ b/source/modules/juce_graphics/native/juce_win32_IconHelpers.cpp @@ -0,0 +1,30 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +Image JUCE_API getIconFromApplication (const String&, const int) +{ + return Image(); +} diff --git a/source/modules/juce_graphics/placement/juce_Justification.h b/source/modules/juce_graphics/placement/juce_Justification.h index c48ab7172..a70ea2518 100644 --- a/source/modules/juce_graphics/placement/juce_Justification.h +++ b/source/modules/juce_graphics/placement/juce_Justification.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_JUSTIFICATION_H_INCLUDED -#define JUCE_JUSTIFICATION_H_INCLUDED +#pragma once //============================================================================== @@ -185,5 +186,3 @@ private: //============================================================================== int flags; }; - -#endif // JUCE_JUSTIFICATION_H_INCLUDED diff --git a/source/modules/juce_graphics/placement/juce_RectanglePlacement.cpp b/source/modules/juce_graphics/placement/juce_RectanglePlacement.cpp index 1cfed08f6..1d1143636 100644 --- a/source/modules/juce_graphics/placement/juce_RectanglePlacement.cpp +++ b/source/modules/juce_graphics/placement/juce_RectanglePlacement.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -46,7 +48,7 @@ bool RectanglePlacement::operator!= (const RectanglePlacement& other) const noex void RectanglePlacement::applyTo (double& x, double& y, double& w, double& h, const double dx, const double dy, const double dw, const double dh) const noexcept { - if (w == 0 || h == 0) + if (w == 0.0 || h == 0.0) return; if ((flags & stretchToFit) != 0) diff --git a/source/modules/juce_graphics/placement/juce_RectanglePlacement.h b/source/modules/juce_graphics/placement/juce_RectanglePlacement.h index dcbf38014..1d6aefd74 100644 --- a/source/modules/juce_graphics/placement/juce_RectanglePlacement.h +++ b/source/modules/juce_graphics/placement/juce_RectanglePlacement.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RECTANGLEPLACEMENT_H_INCLUDED -#define JUCE_RECTANGLEPLACEMENT_H_INCLUDED +#pragma once //============================================================================== @@ -168,5 +169,3 @@ private: //============================================================================== int flags; }; - -#endif // JUCE_RECTANGLEPLACEMENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/application/juce_Application.cpp b/source/modules/juce_gui_basics/application/juce_Application.cpp index 449f6c020..a365031d2 100644 --- a/source/modules/juce_gui_basics/application/juce_Application.cpp +++ b/source/modules/juce_gui_basics/application/juce_Application.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/application/juce_Application.h b/source/modules/juce_gui_basics/application/juce_Application.h index b5c3f28ef..9ade8bbe9 100644 --- a/source/modules/juce_gui_basics/application/juce_Application.h +++ b/source/modules/juce_gui_basics/application/juce_Application.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_APPLICATION_H_INCLUDED -#define JUCE_APPLICATION_H_INCLUDED +#pragma once //============================================================================== @@ -187,6 +188,3 @@ private: JUCE_DECLARE_NON_COPYABLE (JUCEApplication) }; - - -#endif // JUCE_APPLICATION_H_INCLUDED diff --git a/source/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp b/source/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp index 5ff5411cc..4076462db 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp +++ b/source/modules/juce_gui_basics/buttons/juce_ArrowButton.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/buttons/juce_ArrowButton.h b/source/modules/juce_gui_basics/buttons/juce_ArrowButton.h index 17efd6fd5..c05a0c5f6 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ArrowButton.h +++ b/source/modules/juce_gui_basics/buttons/juce_ArrowButton.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ARROWBUTTON_H_INCLUDED -#define JUCE_ARROWBUTTON_H_INCLUDED +#pragma once //============================================================================== @@ -59,6 +60,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ArrowButton) }; - - -#endif // JUCE_ARROWBUTTON_H_INCLUDED diff --git a/source/modules/juce_gui_basics/buttons/juce_Button.cpp b/source/modules/juce_gui_basics/buttons/juce_Button.cpp index 81a49d39d..2dc869601 100644 --- a/source/modules/juce_gui_basics/buttons/juce_Button.cpp +++ b/source/modules/juce_gui_basics/buttons/juce_Button.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -240,19 +242,17 @@ void Button::setRadioGroupId (const int newGroupId, NotificationType notificatio void Button::turnOffOtherButtonsInGroup (const NotificationType notification) { - if (Component* const p = getParentComponent()) + if (auto* p = getParentComponent()) { if (radioGroupId != 0) { WeakReference deletionWatcher (this); - for (int i = p->getNumChildComponents(); --i >= 0;) + for (auto* c : p->getChildren()) { - Component* const c = p->getChildComponent (i); - if (c != this) { - if (Button* const b = dynamic_cast (c)) + if (auto b = dynamic_cast (c)) { if (b->getRadioGroupId() == radioGroupId) { @@ -329,6 +329,11 @@ void Button::setTriggeredOnMouseDown (const bool isTriggeredOnMouseDown) noexcep triggerOnMouseDown = isTriggeredOnMouseDown; } +bool Button::getTriggeredOnMouseDown() const noexcept +{ + return triggerOnMouseDown; +} + //============================================================================== void Button::clicked() { diff --git a/source/modules/juce_gui_basics/buttons/juce_Button.h b/source/modules/juce_gui_basics/buttons/juce_Button.h index 47c6fab54..e15ef92f0 100644 --- a/source/modules/juce_gui_basics/buttons/juce_Button.h +++ b/source/modules/juce_gui_basics/buttons/juce_Button.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BUTTON_H_INCLUDED -#define JUCE_BUTTON_H_INCLUDED +#pragma once //============================================================================== @@ -266,6 +267,11 @@ public: */ void setTriggeredOnMouseDown (bool isTriggeredOnMouseDown) noexcept; + /** Returns whether the button click happens when the mouse is pressed or released. + @see setTriggeredOnMouseDown + */ + bool getTriggeredOnMouseDown() const noexcept; + /** Returns the number of milliseconds since the last time the button went into the 'down' state. */ @@ -512,5 +518,3 @@ private: /** This typedef is just for compatibility with old code and VC6 - newer code should use Button::Listener instead. */ typedef Button::Listener ButtonListener; #endif - -#endif // JUCE_BUTTON_H_INCLUDED diff --git a/source/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp b/source/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp index 6bbfc2026..988b22a58 100644 --- a/source/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp +++ b/source/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/buttons/juce_DrawableButton.h b/source/modules/juce_gui_basics/buttons/juce_DrawableButton.h index 7c142bcd7..91e332eb5 100644 --- a/source/modules/juce_gui_basics/buttons/juce_DrawableButton.h +++ b/source/modules/juce_gui_basics/buttons/juce_DrawableButton.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAWABLEBUTTON_H_INCLUDED -#define JUCE_DRAWABLEBUTTON_H_INCLUDED +#pragma once //============================================================================== @@ -149,7 +150,7 @@ public: enum ColourIds { textColourId = 0x1004010, /**< The colour to use for the button's text label. */ - textColourOnId = 0x1004013, /**< The colour to use for the button's text.when the button's toggle state is "on". */ + textColourOnId = 0x1004013, /**< The colour to use for the button's text when the button's toggle state is "on". */ backgroundColourId = 0x1004011, /**< The colour used to fill the button's background (when the button is toggled 'off'). Note that if you use the @@ -183,6 +184,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DrawableButton) }; - - -#endif // JUCE_DRAWABLEBUTTON_H_INCLUDED diff --git a/source/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp b/source/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp index dd52f6f21..5d76c4310 100644 --- a/source/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp +++ b/source/modules/juce_gui_basics/buttons/juce_HyperlinkButton.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h b/source/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h index e40dae532..746dd4e28 100644 --- a/source/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h +++ b/source/modules/juce_gui_basics/buttons/juce_HyperlinkButton.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_HYPERLINKBUTTON_H_INCLUDED -#define JUCE_HYPERLINKBUTTON_H_INCLUDED +#pragma once //============================================================================== @@ -110,5 +111,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HyperlinkButton) }; - -#endif // JUCE_HYPERLINKBUTTON_H_INCLUDED diff --git a/source/modules/juce_gui_basics/buttons/juce_ImageButton.cpp b/source/modules/juce_gui_basics/buttons/juce_ImageButton.cpp index dacad5426..7bd3fb5f1 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ImageButton.cpp +++ b/source/modules/juce_gui_basics/buttons/juce_ImageButton.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/buttons/juce_ImageButton.h b/source/modules/juce_gui_basics/buttons/juce_ImageButton.h index e2669800d..d24de290c 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ImageButton.h +++ b/source/modules/juce_gui_basics/buttons/juce_ImageButton.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IMAGEBUTTON_H_INCLUDED -#define JUCE_IMAGEBUTTON_H_INCLUDED +#pragma once //============================================================================== @@ -155,6 +156,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageButton) }; - - -#endif // JUCE_IMAGEBUTTON_H_INCLUDED diff --git a/source/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp b/source/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp index 7d6e90319..733b1a41e 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp +++ b/source/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp @@ -2,29 +2,33 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ ShapeButton::ShapeButton (const String& t, Colour n, Colour o, Colour d) : Button (t), - normalColour (n), overColour (o), downColour (d), + normalColour (n), overColour (o), downColour (d), + normalColourOn (n), overColourOn (o), downColourOn (d), + useOnColours(false), maintainShapeProportions (false), outlineWidth (0.0f) { @@ -35,8 +39,20 @@ ShapeButton::~ShapeButton() {} void ShapeButton::setColours (Colour newNormalColour, Colour newOverColour, Colour newDownColour) { normalColour = newNormalColour; - overColour = newOverColour; - downColour = newDownColour; + overColour = newOverColour; + downColour = newDownColour; +} + +void ShapeButton::setOnColours (Colour newNormalColourOn, Colour newOverColourOn, Colour newDownColourOn) +{ + normalColourOn = newNormalColourOn; + overColourOn = newOverColourOn; + downColourOn = newDownColourOn; +} + +void ShapeButton::shouldUseOnColours (bool shouldUse) +{ + useOnColours = shouldUse; } void ShapeButton::setOutline (Colour newOutlineColour, const float newOutlineWidth) @@ -101,9 +117,10 @@ void ShapeButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButto const AffineTransform trans (shape.getTransformToScaleToFit (r, maintainShapeProportions)); - g.setColour (isButtonDown || getToggleState() ? downColour - : isMouseOverButton ? overColour - : normalColour); + if (isButtonDown) g.setColour (getToggleState() && useOnColours ? downColourOn : downColour); + else if (isMouseOverButton) g.setColour (getToggleState() && useOnColours ? overColourOn : overColour); + else g.setColour (getToggleState() && useOnColours ? normalColourOn : normalColour); + g.fillPath (shape, trans); if (outlineWidth > 0.0f) diff --git a/source/modules/juce_gui_basics/buttons/juce_ShapeButton.h b/source/modules/juce_gui_basics/buttons/juce_ShapeButton.h index 624a23143..60372a3bf 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ShapeButton.h +++ b/source/modules/juce_gui_basics/buttons/juce_ShapeButton.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SHAPEBUTTON_H_INCLUDED -#define JUCE_SHAPEBUTTON_H_INCLUDED +#pragma once //============================================================================== @@ -75,6 +76,23 @@ public: Colour overColour, Colour downColour); + /** Sets the colours to use for drawing the shape when the button's toggle state is 'on'. To enable this behaviour, use the + shouldUseOnColours() method. + + @param normalColourOn the colour to fill the shape with when the mouse isn't over and the button's toggle state is 'on' + @param overColourOn the colour to use when the mouse is over the shape and the button's toggle state is 'on' + @param downColourOn the colour to use when the button is in the pressed-down state and the button's toggle state is 'on' + */ + void setOnColours (Colour normalColourOn, + Colour overColourOn, + Colour downColourOn); + + /** Set whether the button should use the 'on' set of colours when its toggle state is 'on'. + By default these will be the same as the normal colours but the setOnColours method can be + used to provide a different set of colours. + */ + void shouldUseOnColours (bool shouldUse); + /** Sets up an outline to draw around the shape. @param outlineColour the colour to use @@ -92,7 +110,9 @@ public: private: //============================================================================== - Colour normalColour, overColour, downColour, outlineColour; + Colour normalColour, overColour, downColour, + normalColourOn, overColourOn, downColourOn, outlineColour; + bool useOnColours; DropShadowEffect shadow; Path shape; BorderSize border; @@ -101,6 +121,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ShapeButton) }; - - -#endif // JUCE_SHAPEBUTTON_H_INCLUDED diff --git a/source/modules/juce_gui_basics/buttons/juce_TextButton.cpp b/source/modules/juce_gui_basics/buttons/juce_TextButton.cpp index 534a9f4d6..59e80696d 100644 --- a/source/modules/juce_gui_basics/buttons/juce_TextButton.cpp +++ b/source/modules/juce_gui_basics/buttons/juce_TextButton.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/buttons/juce_TextButton.h b/source/modules/juce_gui_basics/buttons/juce_TextButton.h index 161b38979..b5f6d346b 100644 --- a/source/modules/juce_gui_basics/buttons/juce_TextButton.h +++ b/source/modules/juce_gui_basics/buttons/juce_TextButton.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TEXTBUTTON_H_INCLUDED -#define JUCE_TEXTBUTTON_H_INCLUDED +#pragma once //============================================================================== @@ -108,6 +109,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextButton) }; - - -#endif // JUCE_TEXTBUTTON_H_INCLUDED diff --git a/source/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp b/source/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp index fd838075b..a9a3c84f9 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp +++ b/source/modules/juce_gui_basics/buttons/juce_ToggleButton.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/buttons/juce_ToggleButton.h b/source/modules/juce_gui_basics/buttons/juce_ToggleButton.h index 291a32027..500946ec6 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ToggleButton.h +++ b/source/modules/juce_gui_basics/buttons/juce_ToggleButton.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TOGGLEBUTTON_H_INCLUDED -#define JUCE_TOGGLEBUTTON_H_INCLUDED +#pragma once //============================================================================== @@ -84,6 +85,3 @@ protected: private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToggleButton) }; - - -#endif // JUCE_TOGGLEBUTTON_H_INCLUDED diff --git a/source/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp b/source/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp index f398f335b..e09bd913a 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp +++ b/source/modules/juce_gui_basics/buttons/juce_ToolbarButton.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/buttons/juce_ToolbarButton.h b/source/modules/juce_gui_basics/buttons/juce_ToolbarButton.h index 9721aa810..20a4322bc 100644 --- a/source/modules/juce_gui_basics/buttons/juce_ToolbarButton.h +++ b/source/modules/juce_gui_basics/buttons/juce_ToolbarButton.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TOOLBARBUTTON_H_INCLUDED -#define JUCE_TOOLBARBUTTON_H_INCLUDED +#pragma once //============================================================================== @@ -92,6 +93,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToolbarButton) }; - - -#endif // JUCE_TOOLBARBUTTON_H_INCLUDED diff --git a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h index d24d49ed5..65c3e4b70 100644 --- a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h +++ b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandID.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_APPLICATIONCOMMANDID_H_INCLUDED -#define JUCE_APPLICATIONCOMMANDID_H_INCLUDED +#pragma once //============================================================================== @@ -86,6 +87,3 @@ namespace StandardApplicationCommandIDs redo = 0x1009 }; } - - -#endif // JUCE_APPLICATIONCOMMANDID_H_INCLUDED diff --git a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp index e86ff44cd..388113d6c 100644 --- a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp +++ b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h index 23c571b17..c6cb9927e 100644 --- a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h +++ b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_APPLICATIONCOMMANDINFO_H_INCLUDED -#define JUCE_APPLICATIONCOMMANDINFO_H_INCLUDED +#pragma once //============================================================================== @@ -184,6 +185,3 @@ struct JUCE_API ApplicationCommandInfo */ int flags; }; - - -#endif // JUCE_APPLICATIONCOMMANDINFO_H_INCLUDED diff --git a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp index 0d3a1d083..7379a9b48 100644 --- a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp +++ b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -51,7 +53,7 @@ void ApplicationCommandManager::registerCommand (const ApplicationCommandInfo& n // the name isn't optional! jassert (newCommand.shortName.isNotEmpty()); - if (ApplicationCommandInfo* command = getMutableCommandForID (newCommand.commandID)) + if (auto* command = getMutableCommandForID (newCommand.commandID)) { // Trying to re-register the same command ID with different parameters can often indicate a typo. // This assertion is here because I've found it useful catching some mistakes, but it may also cause @@ -132,19 +134,19 @@ const ApplicationCommandInfo* ApplicationCommandManager::getCommandForID (const String ApplicationCommandManager::getNameOfCommand (const CommandID commandID) const noexcept { - if (const ApplicationCommandInfo* const ci = getCommandForID (commandID)) + if (auto* ci = getCommandForID (commandID)) return ci->shortName; - return String(); + return {}; } String ApplicationCommandManager::getDescriptionOfCommand (const CommandID commandID) const noexcept { - if (const ApplicationCommandInfo* const ci = getCommandForID (commandID)) + if (auto* ci = getCommandForID (commandID)) return ci->description.isNotEmpty() ? ci->description : ci->shortName; - return String(); + return {}; } StringArray ApplicationCommandManager::getCommandCategories() const @@ -186,7 +188,7 @@ bool ApplicationCommandManager::invoke (const ApplicationCommandTarget::Invocati bool ok = false; ApplicationCommandInfo commandInfo (0); - if (ApplicationCommandTarget* const target = getTargetForCommand (inf.commandID, commandInfo)) + if (auto* target = getTargetForCommand (inf.commandID, commandInfo)) { ApplicationCommandTarget::InvocationInfo info (inf); info.commandFlags = commandInfo.flags; @@ -248,7 +250,7 @@ ApplicationCommandTarget* ApplicationCommandManager::findDefaultComponentTarget( if (c == nullptr) { - if (TopLevelWindow* const activeWindow = TopLevelWindow::getActiveTopLevelWindow()) + if (auto* activeWindow = TopLevelWindow::getActiveTopLevelWindow()) { c = activeWindow->getPeer()->getLastFocusedSubcomponent(); @@ -259,12 +261,12 @@ ApplicationCommandTarget* ApplicationCommandManager::findDefaultComponentTarget( if (c == nullptr && Process::isForegroundProcess()) { - Desktop& desktop = Desktop::getInstance(); + auto& desktop = Desktop::getInstance(); // getting a bit desperate now: try all desktop comps.. for (int i = desktop.getNumComponents(); --i >= 0;) - if (ComponentPeer* const peer = desktop.getComponent(i)->getPeer()) - if (ApplicationCommandTarget* const target = findTargetForComponent (peer->getLastFocusedSubcomponent())) + if (auto* peer = desktop.getComponent(i)->getPeer()) + if (auto* target = findTargetForComponent (peer->getLastFocusedSubcomponent())) return target; } @@ -274,11 +276,11 @@ ApplicationCommandTarget* ApplicationCommandManager::findDefaultComponentTarget( // component that really should get the event. And if not, the event will // still be passed up to the top level window anyway, so let's send it to the // content comp. - if (ResizableWindow* const resizableWindow = dynamic_cast (c)) - if (Component* const content = resizableWindow->getContentComponent()) + if (auto* resizableWindow = dynamic_cast (c)) + if (auto* content = resizableWindow->getContentComponent()) c = content; - if (ApplicationCommandTarget* const target = findTargetForComponent (c)) + if (auto* target = findTargetForComponent (c)) return target; } diff --git a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h index 4ace28425..9baf3da99 100644 --- a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h +++ b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandManager.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_APPLICATIONCOMMANDMANAGER_H_INCLUDED -#define JUCE_APPLICATIONCOMMANDMANAGER_H_INCLUDED +#pragma once //============================================================================== @@ -347,7 +348,3 @@ public: */ virtual void applicationCommandListChanged() = 0; }; - - - -#endif // JUCE_APPLICATIONCOMMANDMANAGER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp index 092f6d2d8..fa25e1244 100644 --- a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp +++ b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h index 6870042fa..f37414180 100644 --- a/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h +++ b/source/modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_APPLICATIONCOMMANDTARGET_H_INCLUDED -#define JUCE_APPLICATIONCOMMANDTARGET_H_INCLUDED +#pragma once //============================================================================== @@ -240,6 +241,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandTarget) }; - - -#endif // JUCE_APPLICATIONCOMMANDTARGET_H_INCLUDED diff --git a/source/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp b/source/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp index aa52f0c25..2293d5835 100644 --- a/source/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp +++ b/source/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h b/source/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h index 315de8f64..75e3ca5f3 100644 --- a/source/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h +++ b/source/modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_KEYPRESSMAPPINGSET_H_INCLUDED -#define JUCE_KEYPRESSMAPPINGSET_H_INCLUDED +#pragma once //============================================================================== @@ -240,6 +241,3 @@ private: KeyPressMappingSet& operator= (const KeyPressMappingSet&); JUCE_LEAK_DETECTOR (KeyPressMappingSet) }; - - -#endif // JUCE_KEYPRESSMAPPINGSET_H_INCLUDED diff --git a/source/modules/juce_gui_basics/components/juce_CachedComponentImage.h b/source/modules/juce_gui_basics/components/juce_CachedComponentImage.h index e9be2c632..fda4f550e 100644 --- a/source/modules/juce_gui_basics/components/juce_CachedComponentImage.h +++ b/source/modules/juce_gui_basics/components/juce_CachedComponentImage.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CACHEDCOMPONENTIMAGE_H_INCLUDED -#define JUCE_CACHEDCOMPONENTIMAGE_H_INCLUDED +#pragma once //============================================================================== @@ -66,5 +67,3 @@ public: */ virtual void releaseResources() = 0; }; - -#endif // JUCE_CACHEDCOMPONENTIMAGE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/components/juce_Component.cpp b/source/modules/juce_gui_basics/components/juce_Component.cpp index f207733f7..7efb8a919 100644 --- a/source/modules/juce_gui_basics/components/juce_Component.cpp +++ b/source/modules/juce_gui_basics/components/juce_Component.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -69,7 +71,7 @@ public: if (checker.shouldBailOut()) return; - if (MouseListenerList* const list = comp.mouseListeners) + if (auto* list = comp.mouseListeners.get()) { for (int i = list->listeners.size(); --i >= 0;) { @@ -84,7 +86,7 @@ public: for (Component* p = comp.parentComponent; p != nullptr; p = p->parentComponent) { - MouseListenerList* const list = p->mouseListeners; + auto* list = p->mouseListeners.get(); if (list != nullptr && list->numDeepMouseListeners > 0) { @@ -106,7 +108,7 @@ public: static void sendWheelEvent (Component& comp, Component::BailOutChecker& checker, const MouseEvent& e, const MouseWheelDetails& wheel) { - if (MouseListenerList* const list = comp.mouseListeners) + if (auto* list = comp.mouseListeners.get()) { for (int i = list->listeners.size(); --i >= 0;) { @@ -144,9 +146,8 @@ private: Array listeners; int numDeepMouseListeners; - class BailOutChecker2 + struct BailOutChecker2 { - public: BailOutChecker2 (Component::BailOutChecker& boc, Component* const comp) : checker (boc), safePointer (comp) { @@ -175,7 +176,10 @@ struct FocusRestorer ~FocusRestorer() { if (lastFocus != nullptr && ! lastFocus->isCurrentlyBlockedByAnotherModalComponent()) - lastFocus->grabKeyboardFocus(); + { + if (lastFocus != nullptr && lastFocus->isShowing()) + lastFocus->grabKeyboardFocus(); + } } WeakReference lastFocus; @@ -361,7 +365,7 @@ struct Component::ComponentHelpers template static PointOrRect convertFromDistantParentSpace (const Component* parent, const Component& target, const PointOrRect& coordInParent) { - const Component* const directParent = target.getParentComponent(); + auto* directParent = target.getParentComponent(); jassert (directParent != nullptr); if (directParent == parent) @@ -389,7 +393,7 @@ struct Component::ComponentHelpers if (target == nullptr) return p; - const Component* const topLevelComp = target->getTopLevelComponent(); + auto* topLevelComp = target->getTopLevelComponent(); p = convertFromParentSpace (*topLevelComp, p); @@ -405,11 +409,11 @@ struct Component::ComponentHelpers for (int i = comp.childComponentList.size(); --i >= 0;) { - const Component& child = *comp.childComponentList.getUnchecked(i); + auto& child = *comp.childComponentList.getUnchecked(i); if (child.isVisible() && ! child.isTransformed()) { - const Rectangle newClip (clipRect.getIntersection (child.boundsRelativeToParent)); + auto newClip = clipRect.getIntersection (child.boundsRelativeToParent); if (! newClip.isEmpty()) { @@ -420,7 +424,8 @@ struct Component::ComponentHelpers } else { - const Point childPos (child.getPosition()); + auto childPos = child.getPosition(); + if (clipObscuredRegions (child, g, newClip - childPos, childPos + delta)) wasClipped = true; } @@ -433,7 +438,7 @@ struct Component::ComponentHelpers static Rectangle getParentOrMainMonitorBounds (const Component& comp) { - if (Component* p = comp.getParentComponent()) + if (auto* p = comp.getParentComponent()) return p->getLocalBounds(); return Desktop::getInstance().getDisplays().getMainDisplay().userArea; @@ -441,37 +446,28 @@ struct Component::ComponentHelpers static void releaseAllCachedImageResources (Component& c) { - if (CachedComponentImage* cached = c.getCachedComponentImage()) + if (auto* cached = c.getCachedComponentImage()) cached->releaseResources(); - for (int i = c.getNumChildComponents(); --i >= 0;) - releaseAllCachedImageResources (*c.getChildComponent (i)); + for (auto* child : c.childComponentList) + releaseAllCachedImageResources (*child); } }; //============================================================================== Component::Component() noexcept - : parentComponent (nullptr), - lookAndFeel (nullptr), - effect (nullptr), - componentFlags (0), - componentTransparency (0) + : componentFlags (0) { } Component::Component (const String& name) noexcept - : componentName (name), - parentComponent (nullptr), - lookAndFeel (nullptr), - effect (nullptr), - componentFlags (0), - componentTransparency (0) + : componentName (name), componentFlags (0) { } Component::~Component() { - static_jassert (sizeof (flags) <= sizeof (componentFlags)); + static_assert (sizeof (flags) <= sizeof (componentFlags), "componentFlags has too many bits!"); componentListeners.call (&ComponentListener::componentBeingDeleted, *this); @@ -504,7 +500,7 @@ void Component::setName (const String& name) componentName = name; if (flags.hasHeavyweightPeerFlag) - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) peer->setTitle (name); BailOutChecker checker (this); @@ -554,7 +550,7 @@ void Component::setVisible (bool shouldBeVisible) if (safePointer != nullptr && flags.hasHeavyweightPeerFlag) { - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) { peer->setVisible (shouldBeVisible); internalHierarchyChanged(); @@ -583,7 +579,7 @@ bool Component::isShowing() const if (parentComponent != nullptr) return parentComponent->isShowing(); - if (const ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) return ! peer->isMinimised(); return false; @@ -592,7 +588,7 @@ bool Component::isShowing() const //============================================================================== void* Component::getWindowHandle() const { - if (const ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) return peer->getNativeHandle(); return nullptr; @@ -778,8 +774,8 @@ public: void paint (Graphics& g) override { scale = g.getInternalContext().getPhysicalPixelScaleFactor(); - const Rectangle compBounds (owner.getLocalBounds()); - const Rectangle imageBounds (compBounds * scale); + auto compBounds = owner.getLocalBounds(); + auto imageBounds = compBounds * scale; if (image.isNull() || image.getBounds() != imageBounds) { @@ -795,12 +791,12 @@ public: if (! validArea.containsRectangle (compBounds)) { Graphics imG (image); - LowLevelGraphicsContext& lg = imG.getInternalContext(); + auto& lg = imG.getInternalContext(); lg.addTransform (AffineTransform::scale (scale)); - for (const Rectangle* i = validArea.begin(), * const e = validArea.end(); i != e; ++i) - lg.excludeClipRectangle (*i); + for (auto& i : validArea) + lg.excludeClipRectangle (i); if (! owner.isOpaque()) { @@ -865,7 +861,7 @@ void Component::reorderChildInternal (const int sourceIndex, const int destIndex { if (sourceIndex != destIndex) { - Component* const c = childComponentList.getUnchecked (sourceIndex); + auto* c = childComponentList.getUnchecked (sourceIndex); jassert (c != nullptr); c->repaintParent(); @@ -884,7 +880,7 @@ void Component::toFront (const bool setAsForeground) if (flags.hasHeavyweightPeerFlag) { - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) { peer->toFront (setAsForeground); @@ -894,11 +890,11 @@ void Component::toFront (const bool setAsForeground) } else if (parentComponent != nullptr) { - const Array& childList = parentComponent->childComponentList; + auto& childList = parentComponent->childComponentList; if (childList.getLast() != this) { - const int index = childList.indexOf (this); + auto index = childList.indexOf (this); if (index >= 0) { @@ -919,7 +915,9 @@ void Component::toFront (const bool setAsForeground) if (setAsForeground) { internalBroughtToFront(); - grabKeyboardFocus(); + + if (isShowing()) + grabKeyboardFocus(); } } } @@ -933,8 +931,8 @@ void Component::toBehind (Component* const other) if (parentComponent != nullptr) { - const Array& childList = parentComponent->childComponentList; - const int index = childList.indexOf (this); + auto& childList = parentComponent->childComponentList; + auto index = childList.indexOf (this); if (index >= 0 && childList [index + 1] != other) { @@ -955,8 +953,8 @@ void Component::toBehind (Component* const other) if (other->isOnDesktop()) { - ComponentPeer* const us = getPeer(); - ComponentPeer* const them = other->getPeer(); + auto* us = getPeer(); + auto* them = other->getPeer(); jassert (us != nullptr && them != nullptr); if (us != nullptr && them != nullptr) @@ -974,11 +972,11 @@ void Component::toBack() } else if (parentComponent != nullptr) { - const Array& childList = parentComponent->childComponentList; + auto& childList = parentComponent->childComponentList; if (childList.getFirst() != this) { - const int index = childList.indexOf (this); + auto index = childList.indexOf (this); if (index > 0) { @@ -1004,7 +1002,7 @@ void Component::setAlwaysOnTop (const bool shouldStayOnTop) if (isOnDesktop()) { - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) { if (! peer->setAlwaysOnTop (shouldStayOnTop)) { @@ -1067,7 +1065,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); } @@ -1082,7 +1080,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); } @@ -1153,7 +1151,7 @@ void Component::setBounds (const int x, const int y, int w, int h) flags.isResizeCallbackPending = wasResized; if (flags.hasHeavyweightPeerFlag) - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) peer->updateBounds(); sendMovedResizedMessagesIfPending(); @@ -1212,12 +1210,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()); } @@ -1232,7 +1230,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()); } @@ -1244,7 +1242,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, @@ -1259,13 +1257,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)); @@ -1273,14 +1268,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))); } @@ -1380,7 +1375,7 @@ bool Component::hitTest (int x, int y) { for (int i = childComponentList.size(); --i >= 0;) { - Component& child = *childComponentList.getUnchecked (i); + auto& child = *childComponentList.getUnchecked (i); if (child.isVisible() && ComponentHelpers::hitTest (child, ComponentHelpers::convertFromParentSpace (child, Point (x, y)))) @@ -1413,7 +1408,7 @@ bool Component::contains (Point point) return parentComponent->contains (ComponentHelpers::convertToParentSpace (*this, point)); if (flags.hasHeavyweightPeerFlag) - if (const ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) return peer->contains (ComponentHelpers::localPositionToRawPeerPos (*this, point), true); } @@ -1425,8 +1420,8 @@ bool Component::reallyContains (Point point, const bool returnTrueIfWithinA if (! contains (point)) return false; - Component* const top = getTopLevelComponent(); - const Component* const compAtPosition = top->getComponentAt (top->getLocalPoint (this, point)); + auto* top = getTopLevelComponent(); + auto* compAtPosition = top->getComponentAt (top->getLocalPoint (this, point)); return (compAtPosition == this) || (returnTrueIfWithinAChild && isParentOf (compAtPosition)); } @@ -1437,7 +1432,8 @@ Component* Component::getComponentAt (Point position) { for (int i = childComponentList.size(); --i >= 0;) { - Component* child = childComponentList.getUnchecked(i); + auto* child = childComponentList.getUnchecked(i); + child = child->getComponentAt (ComponentHelpers::convertFromParentSpace (*child, position)); if (child != nullptr) @@ -1538,7 +1534,7 @@ Component* Component::removeChildComponent (const int index, bool sendParentEven // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN - Component* const child = childComponentList [index]; + auto* child = childComponentList [index]; if (child != nullptr) { @@ -1607,7 +1603,7 @@ int Component::getNumChildComponents() const noexcept Component* Component::getChildComponent (const int index) const noexcept { - return childComponentList [index]; + return childComponentList[index]; } int Component::getIndexOfChildComponent (const Component* const child) const noexcept @@ -1617,12 +1613,9 @@ int Component::getIndexOfChildComponent (const Component* const child) const noe Component* Component::findChildWithID (StringRef targetID) const noexcept { - for (int i = childComponentList.size(); --i >= 0;) - { - Component* const c = childComponentList.getUnchecked(i); + for (auto* c : childComponentList) if (c->componentID == targetID) return c; - } return nullptr; } @@ -1730,7 +1723,7 @@ void Component::enterModalState (const bool shouldTakeKeyboardFocus, if (! isCurrentlyModal (false)) { - ModalComponentManager& mcm = *ModalComponentManager::getInstance(); + auto& mcm = *ModalComponentManager::getInstance(); mcm.startModal (this, deleteWhenDismissed); mcm.attachCallback (this, callback); @@ -1752,36 +1745,24 @@ void Component::exitModalState (const int returnValue) { if (MessageManager::getInstance()->isThisTheMessageThread()) { - ModalComponentManager& mcm = *ModalComponentManager::getInstance(); + auto& mcm = *ModalComponentManager::getInstance(); mcm.endModal (this, returnValue); mcm.bringModalComponentsToFront(); // If any of the mouse sources are over another Component when we exit the modal state then send a mouse enter event - const Array& mouseSources = Desktop::getInstance().getMouseSources(); - - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) - { - if (Component* c = mi->getComponentUnderMouse()) - c->internalMouseEnter (*mi, mi->getScreenPosition(), Time::getCurrentTime()); - } + for (auto& ms : Desktop::getInstance().getMouseSources()) + if (auto* c = ms.getComponentUnderMouse()) + c->internalMouseEnter (ms, ms.getScreenPosition(), Time::getCurrentTime()); } else { - struct ExitModalStateMessage : public CallbackMessage - { - ExitModalStateMessage (Component* c, int res) : target (c), result (res) {} + WeakReference target (this); - void messageCallback() override - { - if (Component* c = target) - c->exitModalState (result); - } - - WeakReference target; - int result; - }; - - (new ExitModalStateMessage (this, returnValue))->post(); + MessageManager::callAsync ([=]() + { + if (auto* c = target.get()) + c->exitModalState (returnValue); + }); } } } @@ -1791,7 +1772,7 @@ bool Component::isCurrentlyModal (bool onlyConsiderForemostModalComponent) const const int n = onlyConsiderForemostModalComponent ? 1 : getNumCurrentlyModalComponents(); for (int i = 0; i < n; ++i) - if (getCurrentlyModalComponent (i) == this) + if (getCurrentlyModalComponent(i) == this) return true; return false; @@ -1799,7 +1780,7 @@ bool Component::isCurrentlyModal (bool onlyConsiderForemostModalComponent) const bool Component::isCurrentlyBlockedByAnotherModalComponent() const { - Component* const mc = getCurrentlyModalComponent(); + auto* mc = getCurrentlyModalComponent(); return ! (mc == nullptr || mc == this || mc->isParentOf (this) || mc->canModalEventBeSentToComponent (this)); @@ -1875,7 +1856,7 @@ void Component::alphaChanged() { if (flags.hasHeavyweightPeerFlag) { - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) peer->setAlpha (getAlpha()); } else @@ -1895,7 +1876,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); } @@ -1929,12 +1910,12 @@ void Component::internalRepaintUnchecked (Rectangle area, const bool isEnti // thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe. ASSERT_MESSAGE_MANAGER_IS_LOCKED - if (ComponentPeer* const peer = getPeer()) + 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); } @@ -1973,7 +1954,7 @@ void Component::paintWithinParentContext (Graphics& g) void Component::paintComponentAndChildren (Graphics& g) { - const Rectangle clipBounds (g.getClipBounds()); + auto clipBounds = g.getClipBounds(); if (flags.dontClipGraphicsFlag) { @@ -1991,7 +1972,7 @@ void Component::paintComponentAndChildren (Graphics& g) for (int i = 0; i < childComponentList.size(); ++i) { - Component& child = *childComponentList.getUnchecked (i); + auto& child = *childComponentList.getUnchecked (i); if (child.isVisible()) { @@ -2019,7 +2000,7 @@ void Component::paintComponentAndChildren (Graphics& g) for (int j = i + 1; j < childComponentList.size(); ++j) { - const Component& sibling = *childComponentList.getUnchecked (j); + auto& sibling = *childComponentList.getUnchecked (j); if (sibling.flags.opaqueFlag && sibling.isVisible() && sibling.affineTransform == nullptr) { @@ -2058,9 +2039,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); @@ -2101,10 +2082,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()); @@ -2141,7 +2122,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); @@ -2327,30 +2308,20 @@ bool Component::canModalEventBeSentToComponent (const Component*) void Component::internalModalInputAttempt() { - if (Component* const current = getCurrentlyModalComponent()) + if (auto* current = getCurrentlyModalComponent()) current->inputAttemptWhenModal(); } //============================================================================== -void Component::postCommandMessage (const int commandId) +void Component::postCommandMessage (const int commandID) { - struct CustomCommandMessage : public CallbackMessage - { - CustomCommandMessage (Component* const c, const int command) - : target (c), commandId (command) {} - - void messageCallback() override - { - if (Component* c = target.get()) - c->handleCommandMessage (commandId); - } + WeakReference target (this); - private: - WeakReference target; - int commandId; - }; - - (new CustomCommandMessage (this, commandId))->post(); + MessageManager::callAsync ([=]() + { + if (auto* c = target.get()) + c->handleCommandMessage (commandID); + }); } void Component::handleCommandMessage (int) @@ -2402,6 +2373,8 @@ void Component::internalMouseEnter (MouseInputSource source, Point relati BailOutChecker checker (this); const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, + MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, this, this, time, relativePos, time, 0, false); mouseEnter (me); @@ -2428,6 +2401,8 @@ void Component::internalMouseExit (MouseInputSource source, Point relativ BailOutChecker checker (this); const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, + MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, this, this, time, relativePos, time, 0, false); mouseExit (me); @@ -2440,7 +2415,8 @@ void Component::internalMouseExit (MouseInputSource source, Point relativ MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseExit, me); } -void Component::internalMouseDown (MouseInputSource source, Point relativePos, Time time, float pressure) +void Component::internalMouseDown (MouseInputSource source, Point relativePos, Time time, + float pressure, float orientation, float rotation, float tiltX, float tiltY) { Desktop& desktop = Desktop::getInstance(); BailOutChecker checker (this); @@ -2458,9 +2434,9 @@ void Component::internalMouseDown (MouseInputSource source, Point relativ if (isCurrentlyBlockedByAnotherModalComponent()) { // allow blocked mouse-events to go to global listeners.. - const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - pressure, this, this, time, relativePos, time, - source.getNumberOfMultipleClicks(), false); + const MouseEvent me (source, relativePos, source.getCurrentModifiers(), pressure, + orientation, rotation, tiltX, tiltY, this, this, time, relativePos, + time, source.getNumberOfMultipleClicks(), false); desktop.getMouseListeners().callChecked (checker, &MouseListener::mouseDown, me); return; @@ -2491,9 +2467,9 @@ void Component::internalMouseDown (MouseInputSource source, Point relativ if (flags.repaintOnMouseActivityFlag) repaint(); - const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - pressure, this, this, time, relativePos, time, - source.getNumberOfMultipleClicks(), false); + const MouseEvent me (source, relativePos, source.getCurrentModifiers(), pressure, + orientation, rotation, tiltX, tiltY, this, this, time, relativePos, + time, source.getNumberOfMultipleClicks(), false); mouseDown (me); if (checker.shouldBailOut()) @@ -2504,8 +2480,8 @@ void Component::internalMouseDown (MouseInputSource source, Point relativ MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDown, me); } -void Component::internalMouseUp (MouseInputSource source, Point relativePos, - Time time, const ModifierKeys oldModifiers, float pressure) +void Component::internalMouseUp (MouseInputSource source, Point relativePos, Time time, + const ModifierKeys oldModifiers, float pressure, float orientation, float rotation, float tiltX, float tiltY) { if (flags.mouseDownWasBlocked && isCurrentlyBlockedByAnotherModalComponent()) return; @@ -2515,8 +2491,8 @@ void Component::internalMouseUp (MouseInputSource source, Point relativeP if (flags.repaintOnMouseActivityFlag) repaint(); - const MouseEvent me (source, relativePos, - oldModifiers, pressure, this, this, time, + const MouseEvent me (source, relativePos, oldModifiers, pressure, orientation, + rotation, tiltX, tiltY, this, this, time, getLocalPoint (nullptr, source.getLastMouseDownPosition()), source.getLastMouseDownTime(), source.getNumberOfMultipleClicks(), @@ -2547,14 +2523,15 @@ void Component::internalMouseUp (MouseInputSource source, Point relativeP } } -void Component::internalMouseDrag (MouseInputSource source, Point relativePos, Time time, float pressure) +void Component::internalMouseDrag (MouseInputSource source, Point relativePos, Time time, + float pressure, float orientation, float rotation, float tiltX, float tiltY) { if (! isCurrentlyBlockedByAnotherModalComponent()) { BailOutChecker checker (this); const MouseEvent me (source, relativePos, source.getCurrentModifiers(), - pressure, this, this, time, + pressure, orientation, rotation, tiltX, tiltY, this, this, time, getLocalPoint (nullptr, source.getLastMouseDownPosition()), source.getLastMouseDownTime(), source.getNumberOfMultipleClicks(), @@ -2584,6 +2561,8 @@ void Component::internalMouseMove (MouseInputSource source, Point relativ BailOutChecker checker (this); const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, + MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, this, this, time, relativePos, time, 0, false); mouseMove (me); @@ -2603,6 +2582,8 @@ void Component::internalMouseWheel (MouseInputSource source, Point relati BailOutChecker checker (this); const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, + MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, this, this, time, relativePos, time, 0, false); if (isCurrentlyBlockedByAnotherModalComponent()) @@ -2630,6 +2611,8 @@ void Component::internalMagnifyGesture (MouseInputSource source, Point re if (! isCurrentlyBlockedByAnotherModalComponent()) { const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, + MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, this, this, time, relativePos, time, 0, false); mouseMagnify (me, amount); @@ -2672,7 +2655,7 @@ void Component::internalBroughtToFront() // When brought to the front and there's a modal component blocking this one, // we need to bring the modal one to the front instead.. - if (Component* const cm = getCurrentlyModalComponent()) + if (auto* cm = getCurrentlyModalComponent()) if (cm->getTopLevelComponent() != getTopLevelComponent()) ModalComponentManager::getInstance()->bringModalComponentsToFront (false); // very important that this is false, otherwise in Windows, // non-front components can't get focus when another modal comp is @@ -2781,7 +2764,7 @@ void Component::takeKeyboardFocus (const FocusChangeType cause) if (currentlyFocusedComponent != this) { // get the focus onto our desktop window - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) { const WeakReference safePointer (this); peer->grabFocus(); @@ -2827,7 +2810,7 @@ void Component::grabFocusInternal (const FocusChangeType cause, const bool canTr if (traverser != nullptr) { - Component* const defaultComp = traverser->getDefaultComponent (this); + auto* defaultComp = traverser->getDefaultComponent (this); traverser = nullptr; if (defaultComp != nullptr) @@ -2855,6 +2838,12 @@ void Component::grabKeyboardFocus() ASSERT_MESSAGE_MANAGER_IS_LOCKED grabFocusInternal (focusChangedDirectly, true); + + // A component can only be focused when it's actually on the screen! + // If this fails then you're probably trying to grab the focus before you've + // added the component to a parent or made it visible. Or maybe one of its parent + // components isn't yet visible. + jassert (isShowing() || isOnDesktop()); } void Component::moveKeyboardFocusToSibling (const bool moveToNext) @@ -2869,8 +2858,8 @@ void Component::moveKeyboardFocusToSibling (const bool moveToNext) if (traverser != nullptr) { - Component* const nextComp = moveToNext ? traverser->getNextComponent (this) - : traverser->getPreviousComponent (this); + auto* nextComp = moveToNext ? traverser->getNextComponent (this) + : traverser->getPreviousComponent (this); traverser = nullptr; if (nextComp != nullptr) @@ -2906,13 +2895,13 @@ Component* JUCE_CALLTYPE Component::getCurrentlyFocusedComponent() noexcept void JUCE_CALLTYPE Component::unfocusAllComponents() { - if (Component* c = getCurrentlyFocusedComponent()) + if (auto* c = getCurrentlyFocusedComponent()) c->giveAwayFocus (true); } void Component::giveAwayFocus (const bool sendFocusLossEvent) { - Component* const componentLosingFocus = currentlyFocusedComponent; + auto* componentLosingFocus = currentlyFocusedComponent; currentlyFocusedComponent = nullptr; if (sendFocusLossEvent && componentLosingFocus != nullptr) @@ -2954,7 +2943,7 @@ void Component::sendEnablementChangeMessage() for (int i = getNumChildComponents(); --i >= 0;) { - if (Component* const c = getChildComponent (i)) + if (auto* c = getChildComponent (i)) { c->sendEnablementChangeMessage(); @@ -2967,15 +2956,13 @@ void Component::sendEnablementChangeMessage() //============================================================================== bool Component::isMouseOver (const bool includeChildren) const { - const Array& mouseSources = Desktop::getInstance().getMouseSources(); - - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) + for (auto& ms : Desktop::getInstance().getMouseSources()) { - Component* const c = mi->getComponentUnderMouse(); + auto* c = ms.getComponentUnderMouse(); if ((c == this || (includeChildren && isParentOf (c))) - && c->reallyContains (c->getLocalPoint (nullptr, mi->getScreenPosition()).roundToInt(), false) - && (mi->isMouse() || mi->isDragging())) + && c->reallyContains (c->getLocalPoint (nullptr, ms.getScreenPosition()).roundToInt(), false) + && ((! ms.isTouch()) || ms.isDragging())) return true; } @@ -2984,10 +2971,8 @@ bool Component::isMouseOver (const bool includeChildren) const bool Component::isMouseButtonDown() const { - const Array& mouseSources = Desktop::getInstance().getMouseSources(); - - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) - if (mi->isDragging() && mi->getComponentUnderMouse() == this) + for (auto& ms : Desktop::getInstance().getMouseSources()) + if (ms.isDragging() && ms.getComponentUnderMouse() == this) return true; return false; @@ -2995,14 +2980,12 @@ bool Component::isMouseButtonDown() const bool Component::isMouseOverOrDragging (const bool includeChildren) const { - const Array& mouseSources = Desktop::getInstance().getMouseSources(); - - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) + for (auto& ms : Desktop::getInstance().getMouseSources()) { - Component* const c = mi->getComponentUnderMouse(); + auto* c = ms.getComponentUnderMouse(); if ((c == this || (includeChildren && isParentOf (c))) - && (mi->isMouse() || mi->isDragging())) + && ((! ms.isTouch()) || ms.isDragging())) return true; } diff --git a/source/modules/juce_gui_basics/components/juce_Component.h b/source/modules/juce_gui_basics/components/juce_Component.h index e60dff79d..d482a0e69 100644 --- a/source/modules/juce_gui_basics/components/juce_Component.h +++ b/source/modules/juce_gui_basics/components/juce_Component.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMPONENT_H_INCLUDED -#define JUCE_COMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -298,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 @@ -365,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 @@ -384,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. @@ -470,29 +471,7 @@ public: @see setBounds */ - void setBounds (const 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); + void setBounds (Rectangle newBounds); /** Changes the component's position and size in terms of fractions of its parent's size. @@ -513,7 +492,7 @@ public: @see setBounds */ - void setBoundsInset (const BorderSize& borders); + void setBoundsInset (BorderSize borders); /** Positions the component within a given rectangle, keeping its proportions unchanged. @@ -542,6 +521,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. @@ -625,7 +613,7 @@ public: //============================================================================== /** Returns the number of child components that this component contains. - @see getChildComponent, getIndexOfChildComponent + @see getChildren, getChildComponent, getIndexOfChildComponent */ int getNumChildComponents() const noexcept; @@ -636,7 +624,7 @@ public: If the index is out-of-range, this will return a null pointer. - @see getNumChildComponents, getIndexOfChildComponent + @see getChildren, getNumChildComponents, getIndexOfChildComponent */ Component* getChildComponent (int index) const noexcept; @@ -647,10 +635,15 @@ public: Returns -1 if the component passed-in is not a child of this component. - @see getNumChildComponents, getChildComponent, addChildComponent, toFront, toBack, toBehind + @see getChildren, getNumChildComponents, getChildComponent, addChildComponent, toFront, toBack, toBehind */ int getIndexOfChildComponent (const Component* child) const noexcept; + /** Provides access to the underlying array of child components. + The most likely reason you may want to use this is for iteration in a range-based for loop. + */ + const Array& getChildren() const noexcept { return childComponentList; } + /** Looks for a child component with the specified ID. @see setComponentID, getComponentID */ @@ -974,7 +967,7 @@ public: @see repaint() */ - void repaint (const Rectangle& area); + void repaint (Rectangle area); //============================================================================== /** Makes the component use an internal buffer to optimise its redrawing. @@ -1006,7 +999,7 @@ public: @see paintEntireComponent */ - Image createComponentSnapshot (const Rectangle& areaToGrab, + Image createComponentSnapshot (Rectangle areaToGrab, bool clipImageToComponentBounds = true, float scaleFactor = 1.0f); @@ -1209,6 +1202,11 @@ public: parent instead, unless it's a top-level component without a parent, in which case it just takes the focus itself. + Important note! It's obviously not possible for a component to be focused + unless it's actually visible, on-screen, and inside a window that is also + visible. So there's no point trying to call this in the component's own + constructor or before all of its parent hierarchy has been fully instantiated. + @see setWantsKeyboardFocus, getWantsKeyboardFocus, hasKeyboardFocus, getCurrentlyFocusedComponent, focusGained, focusLost, keyPressed, keyStateChanged @@ -2224,7 +2222,18 @@ public: /** Returns the object that was set by setCachedComponentImage(). @see setCachedComponentImage */ - CachedComponentImage* getCachedComponentImage() const noexcept { return cachedImage; } + CachedComponentImage* getCachedComponentImage() const noexcept { return cachedImage; } + + /** Sets a flag to indicate whether mouse drag events on this Component should be ignored when it is inside a + Viewport with drag-to-scroll functionality enabled. This is useful for Components such as sliders that + should not move their parent Viewport when dragged. + */ + void setViewportIgnoreDragFlag (bool ignoreDrag) noexcept { flags.viewportIgnoreDragFlag = ignoreDrag; } + + /** Retrieves the current state of the Viewport drag-to-scroll functionality flag. + @see setViewportIgnoreDragFlag + */ + bool getViewportIgnoreDragFlag() const noexcept { return flags.viewportIgnoreDragFlag; } //============================================================================== // These methods are deprecated - use localPointToGlobal, getLocalPoint, getLocalPoint, etc instead. @@ -2232,6 +2241,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; @@ -2243,14 +2256,14 @@ private: //============================================================================== String componentName, componentID; - Component* parentComponent; + Component* parentComponent = nullptr; Rectangle boundsRelativeToParent; ScopedPointer positioner; ScopedPointer affineTransform; Array childComponentList; - LookAndFeel* lookAndFeel; + LookAndFeel* lookAndFeel = nullptr; MouseCursor cursor; - ImageEffectFilter* effect; + ImageEffectFilter* effect = nullptr; ScopedPointer cachedImage; class MouseListenerList; @@ -2284,6 +2297,7 @@ private: bool mouseDownWasBlocked : 1; bool isMoveCallbackPending : 1; bool isResizeCallbackPending : 1; + bool viewportIgnoreDragFlag : 1; #if JUCE_DEBUG bool isInsidePaintCall : 1; #endif @@ -2295,14 +2309,14 @@ private: ComponentFlags flags; }; - uint8 componentTransparency; + uint8 componentTransparency = 0; //============================================================================== void internalMouseEnter (MouseInputSource, Point, Time); void internalMouseExit (MouseInputSource, Point, Time); - void internalMouseDown (MouseInputSource, Point, Time, float); - void internalMouseUp (MouseInputSource, Point, Time, const ModifierKeys oldModifiers, float); - void internalMouseDrag (MouseInputSource, Point, Time, float); + void internalMouseDown (MouseInputSource, Point, Time, float, float, float, float, float); + void internalMouseUp (MouseInputSource, Point, Time, const ModifierKeys oldModifiers, float, float, float, float, float); + void internalMouseDrag (MouseInputSource, Point, Time, float, float, float, float, float); void internalMouseMove (MouseInputSource, Point, Time); void internalMouseWheel (MouseInputSource, Point, Time, const MouseWheelDetails&); void internalMagnifyGesture (MouseInputSource, Point, Time, float); @@ -2358,6 +2372,3 @@ protected: virtual ComponentPeer* createNewPeer (int styleFlags, void* nativeWindowToAttachTo); #endif }; - - -#endif // JUCE_COMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/components/juce_ComponentListener.cpp b/source/modules/juce_gui_basics/components/juce_ComponentListener.cpp index b5968d9a1..0c45b3f30 100644 --- a/source/modules/juce_gui_basics/components/juce_ComponentListener.cpp +++ b/source/modules/juce_gui_basics/components/juce_ComponentListener.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/components/juce_ComponentListener.h b/source/modules/juce_gui_basics/components/juce_ComponentListener.h index 39e5b37ff..9c24fb1b5 100644 --- a/source/modules/juce_gui_basics/components/juce_ComponentListener.h +++ b/source/modules/juce_gui_basics/components/juce_ComponentListener.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMPONENTLISTENER_H_INCLUDED -#define JUCE_COMPONENTLISTENER_H_INCLUDED +#pragma once //============================================================================== @@ -106,6 +107,3 @@ public: */ virtual void componentBeingDeleted (Component& component); }; - - -#endif // JUCE_COMPONENTLISTENER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/components/juce_Desktop.cpp b/source/modules/juce_gui_basics/components/juce_Desktop.cpp index 1a591b482..9317213fe 100644 --- a/source/modules/juce_gui_basics/components/juce_Desktop.cpp +++ b/source/modules/juce_gui_basics/components/juce_Desktop.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -93,7 +95,7 @@ LookAndFeel& Desktop::getDefaultLookAndFeel() noexcept if (currentLookAndFeel == nullptr) { if (defaultLookAndFeel == nullptr) - defaultLookAndFeel = new LookAndFeel_V3(); + defaultLookAndFeel = new LookAndFeel_V4(); currentLookAndFeel = defaultLookAndFeel; } @@ -240,14 +242,16 @@ void Desktop::sendMouseMove() lastFakeMouseMove = getMousePositionFloat(); - if (Component* const target = findComponentAt (lastFakeMouseMove.roundToInt())) + if (auto* target = findComponentAt (lastFakeMouseMove.roundToInt())) { Component::BailOutChecker checker (target); const Point pos (target->getLocalPoint (nullptr, lastFakeMouseMove)); const Time now (Time::getCurrentTime()); - const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), - MouseInputSource::invalidPressure, target, target, now, pos, now, 0, false); + const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, + MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, + target, target, now, pos, now, 0, false); if (me.mods.isAnyMouseButtonDown()) mouseListeners.callChecked (checker, &MouseListener::mouseDrag, me); @@ -397,6 +401,11 @@ void Desktop::setOrientationsEnabled (const int newOrientations) } } +int Desktop::getOrientationsEnabled() const noexcept +{ + return allowedOrientations; +} + bool Desktop::isOrientationEnabled (const DisplayOrientation orientation) const noexcept { // Make sure you only pass one valid flag in here... diff --git a/source/modules/juce_gui_basics/components/juce_Desktop.h b/source/modules/juce_gui_basics/components/juce_Desktop.h index 427a24785..367726329 100644 --- a/source/modules/juce_gui_basics/components/juce_Desktop.h +++ b/source/modules/juce_gui_basics/components/juce_Desktop.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DESKTOP_H_INCLUDED -#define JUCE_DESKTOP_H_INCLUDED +#pragma once //============================================================================== @@ -71,6 +72,8 @@ public: /** Makes the mouse pointer jump to a given location. The coordinates are relative to the top-left of the main monitor. + Note that this is a pretty old method, kept around mainly for backwards-compatibility, + and you should use the MouseInputSource class directly in new code. */ static void setMousePosition (Point newPosition); @@ -309,6 +312,11 @@ public: */ void setOrientationsEnabled (int allowedOrientations); + /** Returns the set of orientations the display is allowed to rotate to. + @see setOrientationsEnabled + */ + int getOrientationsEnabled() const noexcept; + /** Returns whether the display is allowed to auto-rotate to the given orientation. Each orientation can be enabled using setOrientationEnabled(). By default, all orientations are allowed. */ @@ -462,6 +470,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Desktop) }; - - -#endif // JUCE_DESKTOP_H_INCLUDED diff --git a/source/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp b/source/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp index 908c4d1f9..d0cbb13f5 100644 --- a/source/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp +++ b/source/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -295,7 +297,6 @@ int ModalComponentManager::runEventLoopForCurrentComponent() #endif //============================================================================== -#if JUCE_COMPILER_SUPPORTS_LAMBDAS struct LambdaCallback : public ModalComponentManager::Callback { LambdaCallback (std::function fn) noexcept : function (fn) {} @@ -310,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 @@ -196,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 @@ -371,6 +370,3 @@ private: ~ModalCallbackFunction(); JUCE_DECLARE_NON_COPYABLE (ModalCallbackFunction) }; - - -#endif // JUCE_MODALCOMPONENTMANAGER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/drawables/juce_Drawable.cpp b/source/modules/juce_gui_basics/drawables/juce_Drawable.cpp index 91d322e00..3bd5833e4 100644 --- a/source/modules/juce_gui_basics/drawables/juce_Drawable.cpp +++ b/source/modules/juce_gui_basics/drawables/juce_Drawable.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,6 +33,9 @@ Drawable::Drawable() Drawable::Drawable (const Drawable& other) : Component (other.getName()) { + setInterceptsMouseClicks (false, false); + setPaintingIsUnclipped (true); + setComponentID (other.getComponentID()); setTransform (other.getTransform()); } @@ -39,6 +44,17 @@ Drawable::~Drawable() { } +void Drawable::applyDrawableClipPath (Graphics& g) +{ + if (drawableClipPath != nullptr) + { + auto clipPath = drawableClipPath->getOutlineAsPath(); + + if (! clipPath.isEmpty()) + g.getInternalContext().clipToPath (clipPath, {}); + } +} + //============================================================================== void Drawable::draw (Graphics& g, float opacity, const AffineTransform& transform) const { @@ -54,6 +70,8 @@ void Drawable::nonConstDraw (Graphics& g, float opacity, const AffineTransform& .followedBy (getTransform()) .followedBy (transform)); + applyDrawableClipPath (g); + if (! g.isClipEmpty()) { if (opacity < 1.0f) @@ -74,7 +92,7 @@ void Drawable::drawAt (Graphics& g, float x, float y, float opacity) const draw (g, opacity, AffineTransform::translation (x, y)); } -void Drawable::drawWithin (Graphics& g, const Rectangle& destArea, +void Drawable::drawWithin (Graphics& g, Rectangle destArea, RectanglePlacement placement, float opacity) const { draw (g, opacity, placement.getTransformToFit (getDrawableBounds(), destArea)); @@ -86,6 +104,15 @@ DrawableComposite* Drawable::getParent() const return dynamic_cast (getParentComponent()); } +void Drawable::setClipPath (Drawable* clipPath) +{ + if (drawableClipPath != clipPath) + { + drawableClipPath = clipPath; + repaint(); + } +} + void Drawable::transformContextToCorrectOrigin (Graphics& g) { g.setOrigin (originRelativeToComponent); @@ -96,14 +123,14 @@ void Drawable::parentHierarchyChanged() setBoundsToEnclose (getDrawableBounds()); } -void Drawable::setBoundsToEnclose (const Rectangle& area) +void Drawable::setBoundsToEnclose (Rectangle area) { - Drawable* const parent = getParent(); Point parentOrigin; - if (parent != nullptr) + + if (auto* parent = getParent()) parentOrigin = parent->originRelativeToComponent; - const Rectangle newBounds (area.getSmallestIntegerContainer() + parentOrigin); + auto newBounds = area.getSmallestIntegerContainer() + parentOrigin; originRelativeToComponent = parentOrigin - newBounds.getPosition(); setBounds (newBounds); } @@ -113,8 +140,8 @@ bool Drawable::replaceColour (Colour original, Colour replacement) { bool changed = false; - for (int i = getNumChildComponents(); --i >= 0;) - if (Drawable* d = dynamic_cast (getChildComponent(i))) + for (auto* c : getChildren()) + if (auto* d = dynamic_cast (c)) changed = d->replaceColour (original, replacement) || changed; return changed; @@ -137,17 +164,17 @@ Drawable* Drawable::createFromImageData (const void* data, const size_t numBytes { Drawable* result = nullptr; - Image image (ImageFileFormat::loadFrom (data, numBytes)); + auto image = ImageFileFormat::loadFrom (data, numBytes); if (image.isValid()) { - DrawableImage* const di = new DrawableImage(); + auto* di = new DrawableImage(); di->setImage (image); result = di; } else { - const String asString (String::createStringFromData (data, (int) numBytes)); + auto asString = String::createStringFromData (data, (int) numBytes); XmlDocument doc (asString); ScopedPointer outer (doc.getDocumentElement (true)); @@ -181,17 +208,15 @@ Drawable* Drawable::createFromImageFile (const File& file) //============================================================================== template -class DrawableTypeHandler : public ComponentBuilder::TypeHandler +struct DrawableTypeHandler : public ComponentBuilder::TypeHandler { -public: - DrawableTypeHandler() - : ComponentBuilder::TypeHandler (DrawableClass::valueTreeType) + DrawableTypeHandler() : ComponentBuilder::TypeHandler (DrawableClass::valueTreeType) { } Component* addNewComponentFromState (const ValueTree& state, Component* parent) { - DrawableClass* const d = new DrawableClass(); + auto* d = new DrawableClass(); if (parent != nullptr) parent->addAndMakeVisible (d); @@ -202,19 +227,20 @@ public: void updateComponentFromState (Component* component, const ValueTree& state) { - DrawableClass* const d = dynamic_cast (component); - jassert (d != nullptr); - d->refreshFromValueTree (state, *this->getBuilder()); + if (auto* d = dynamic_cast (component)) + d->refreshFromValueTree (state, *this->getBuilder()); + else + jassertfalse; } }; void Drawable::registerDrawableTypeHandlers (ComponentBuilder& builder) { - builder.registerTypeHandler (new DrawableTypeHandler ()); - builder.registerTypeHandler (new DrawableTypeHandler ()); - builder.registerTypeHandler (new DrawableTypeHandler ()); - builder.registerTypeHandler (new DrawableTypeHandler ()); - builder.registerTypeHandler (new DrawableTypeHandler ()); + builder.registerTypeHandler (new DrawableTypeHandler()); + builder.registerTypeHandler (new DrawableTypeHandler()); + builder.registerTypeHandler (new DrawableTypeHandler()); + builder.registerTypeHandler (new DrawableTypeHandler()); + builder.registerTypeHandler (new DrawableTypeHandler()); } Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider) @@ -224,7 +250,7 @@ Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder registerDrawableTypeHandlers (builder); ScopedPointer comp (builder.createComponent()); - Drawable* const d = dynamic_cast (static_cast (comp)); + auto* d = dynamic_cast (static_cast (comp)); if (d != nullptr) comp.release(); @@ -233,8 +259,7 @@ Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder } //============================================================================== -Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_) - : state (state_) +Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& s) : state (s) { } diff --git a/source/modules/juce_gui_basics/drawables/juce_Drawable.h b/source/modules/juce_gui_basics/drawables/juce_Drawable.h index 88e6936fe..810970b2c 100644 --- a/source/modules/juce_gui_basics/drawables/juce_Drawable.h +++ b/source/modules/juce_gui_basics/drawables/juce_Drawable.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAWABLE_H_INCLUDED -#define JUCE_DRAWABLE_H_INCLUDED +#pragma once //============================================================================== @@ -53,6 +54,9 @@ public: */ virtual Drawable* createCopy() const = 0; + /** Creates a path that describes the outline of this drawable. */ + virtual Path getOutlineAsPath() const = 0; + //============================================================================== /** Renders this Drawable object. @@ -97,7 +101,7 @@ public: @param opacity the opacity to use, in the range 0 to 1.0 */ void drawWithin (Graphics& g, - const Rectangle& destArea, + Rectangle destArea, RectanglePlacement placement, float opacity) const; @@ -116,6 +120,11 @@ public: /** Returns the DrawableComposite that contains this object, if there is one. */ DrawableComposite* getParent() const; + /** Sets a the clipping region of this drawable using another drawable. + The drawbale passed in ill be deleted when no longer needed. + */ + void setClipPath (Drawable* drawableClipPath); + //============================================================================== /** Tries to turn some kind of image file into a drawable. @@ -149,6 +158,20 @@ public: */ static Drawable* createFromSVG (const XmlElement& svgDocument); + /** Attempts to parse an SVG (Scalable Vector Graphics) document from a file, + and to turn this into a Drawable tree. + + The object returned must be deleted by the caller. If something goes wrong + while parsing, it may return nullptr. + + SVG is a pretty large and complex spec, and this doesn't aim to be a full + implementation, but it can return the basic vector objects. + + Any references to references to external image files will be relative to + the parent directory of the file passed. + */ + static Drawable* createFromSVGFile (const File& svgFile); + /** Parses an SVG path string and returns it. */ static Path parseSVGPath (const String& svgPath); @@ -212,9 +235,12 @@ protected: /** @internal */ void parentHierarchyChanged() override; /** @internal */ - void setBoundsToEnclose (const Rectangle&); + void setBoundsToEnclose (Rectangle); + /** @internal */ + void applyDrawableClipPath (Graphics&); Point originRelativeToComponent; + ScopedPointer drawableClipPath; #ifndef DOXYGEN /** Internal utility class used by Drawables. */ @@ -255,6 +281,3 @@ private: Drawable& operator= (const Drawable&); JUCE_LEAK_DETECTOR (Drawable) }; - - -#endif // JUCE_DRAWABLE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp b/source/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp index 0c0f6737d..b406400af 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp @@ -2,45 +2,42 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ DrawableComposite::DrawableComposite() - : bounds (Point(), Point (100.0f, 0.0f), Point (0.0f, 100.0f)), - updateBoundsReentrant (false) + : bounds (Point(), Point (100.0f, 0.0f), Point (0.0f, 100.0f)) { - 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) : Drawable (other), bounds (other.bounds), markersX (other.markersX), - markersY (other.markersY), - updateBoundsReentrant (false) + markersY (other.markersY) { - for (int i = 0; i < other.getNumChildComponents(); ++i) - if (const Drawable* const d = dynamic_cast (other.getChildComponent(i))) + for (auto* c : other.getChildren()) + if (auto* d = dynamic_cast (c)) addAndMakeVisible (d->createCopy()); } @@ -59,8 +56,8 @@ Rectangle DrawableComposite::getDrawableBounds() const { Rectangle r; - for (int i = getNumChildComponents(); --i >= 0;) - if (const Drawable* const d = dynamic_cast (getChildComponent(i))) + for (auto* c : getChildren()) + if (auto* d = dynamic_cast (c)) r = r.getUnion (d->isTransformed() ? d->getDrawableBounds().transformedBy (d->getTransform()) : d->getDrawableBounds()); @@ -97,7 +94,7 @@ void DrawableComposite::setBoundingBox (const RelativeParallelogram& newBounds) if (bounds.isDynamic()) { - Drawable::Positioner* const p = new Drawable::Positioner (*this); + auto p = new Drawable::Positioner (*this); setPositioner (p); p->apply(); } @@ -120,12 +117,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(); } @@ -141,11 +133,11 @@ void DrawableComposite::recalculateCoordinates (Expression::Scope* scope) Point resolved[3]; bounds.resolveThreePoints (resolved, scope); - const Rectangle content (getContentArea().resolve (scope)); + auto content = getContentArea().resolve (scope); - AffineTransform t (AffineTransform::fromTargetPoints (content.getX(), content.getY(), resolved[0].x, resolved[0].y, - content.getRight(), content.getY(), resolved[1].x, resolved[1].y, - content.getX(), content.getBottom(), resolved[2].x, resolved[2].y)); + auto t = AffineTransform::fromTargetPoints (content.getX(), content.getY(), resolved[0].x, resolved[0].y, + content.getRight(), content.getY(), resolved[1].x, resolved[1].y, + content.getX(), content.getBottom(), resolved[2].x, resolved[2].y); if (t.isSingularity()) t = AffineTransform(); @@ -155,8 +147,7 @@ void DrawableComposite::recalculateCoordinates (Expression::Scope* scope) void DrawableComposite::parentHierarchyChanged() { - DrawableComposite* parent = getParent(); - if (parent != nullptr) + if (auto* parent = getParent()) originRelativeToComponent = parent->originRelativeToComponent - getPosition(); } @@ -178,10 +169,10 @@ void DrawableComposite::updateBoundsToFitChildren() Rectangle childArea; - for (int i = getNumChildComponents(); --i >= 0;) - childArea = childArea.getUnion (getChildComponent(i)->getBoundsInParent()); + for (auto* c : getChildren()) + childArea = childArea.getUnion (c->getBoundsInParent()); - const Point delta (childArea.getPosition()); + auto delta = childArea.getPosition(); childArea += getPosition(); if (childArea != getBounds()) @@ -190,9 +181,8 @@ void DrawableComposite::updateBoundsToFitChildren() { originRelativeToComponent -= delta; - for (int i = getNumChildComponents(); --i >= 0;) - if (Component* const c = getChildComponent(i)) - c->setBounds (c->getBounds() - delta); + for (auto* c : getChildren()) + c->setBounds (c->getBounds() - delta); } setBounds (childArea); @@ -312,9 +302,9 @@ ValueTree DrawableComposite::createValueTree (ComponentBuilder::ImageProvider* i ValueTree childList (v.getChildListCreating (nullptr)); - for (int i = 0; i < getNumChildComponents(); ++i) + for (auto* c : getChildren()) { - const Drawable* const d = dynamic_cast (getChildComponent(i)); + auto* d = dynamic_cast (c); jassert (d != nullptr); // You can't save a mix of Drawables and normal components! childList.addChild (d->createValueTree (imageProvider), -1, nullptr); @@ -325,3 +315,15 @@ ValueTree DrawableComposite::createValueTree (ComponentBuilder::ImageProvider* i return tree; } + +Path DrawableComposite::getOutlineAsPath() const +{ + Path p; + + for (auto* c : getChildren()) + if (auto* d = dynamic_cast (c)) + p.addPath (d->getOutlineAsPath()); + + p.applyTransform (getTransform()); + return p; +} diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableComposite.h b/source/modules/juce_gui_basics/drawables/juce_DrawableComposite.h index 8c484c987..00217e4f9 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableComposite.h +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableComposite.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAWABLECOMPOSITE_H_INCLUDED -#define JUCE_DRAWABLECOMPOSITE_H_INCLUDED +#pragma once //============================================================================== @@ -114,6 +115,8 @@ public: void parentHierarchyChanged() override; /** @internal */ MarkerList* getMarkers (bool xAxis) override; + /** @internal */ + Path getOutlineAsPath() const override; //============================================================================== /** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ @@ -145,7 +148,7 @@ private: //============================================================================== RelativeParallelogram bounds; MarkerList markersX, markersY; - bool updateBoundsReentrant; + bool updateBoundsReentrant = false; friend class Drawable::Positioner; bool registerCoordinates (RelativeCoordinatePositionerBase&); @@ -156,6 +159,3 @@ private: DrawableComposite& operator= (const DrawableComposite&); JUCE_LEAK_DETECTOR (DrawableComposite) }; - - -#endif // JUCE_DRAWABLECOMPOSITE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp b/source/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp index 768364352..c8f177095 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -288,3 +290,8 @@ ValueTree DrawableImage::createValueTree (ComponentBuilder::ImageProvider* image return tree; } + +Path DrawableImage::getOutlineAsPath() const +{ + return {}; // not applicable for images +} diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableImage.h b/source/modules/juce_gui_basics/drawables/juce_DrawableImage.h index 56814a8f7..818012e44 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableImage.h +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableImage.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAWABLEIMAGE_H_INCLUDED -#define JUCE_DRAWABLEIMAGE_H_INCLUDED +#pragma once //============================================================================== @@ -93,6 +94,8 @@ public: ValueTree createValueTree (ComponentBuilder::ImageProvider*) const override; /** @internal */ static const Identifier valueTreeType; + /** @internal */ + Path getOutlineAsPath() const override; //============================================================================== /** Internally-used class for wrapping a DrawableImage's state into a ValueTree. */ @@ -133,6 +136,3 @@ private: DrawableImage& operator= (const DrawableImage&); JUCE_LEAK_DETECTOR (DrawableImage) }; - - -#endif // JUCE_DRAWABLEIMAGE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp b/source/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp index 19a2d4dfe..975a05385 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp +++ b/source/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawablePath.h b/source/modules/juce_gui_basics/drawables/juce_DrawablePath.h index a06ea4349..1dd33f7ae 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawablePath.h +++ b/source/modules/juce_gui_basics/drawables/juce_DrawablePath.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAWABLEPATH_H_INCLUDED -#define JUCE_DRAWABLEPATH_H_INCLUDED +#pragma once //============================================================================== @@ -140,6 +141,3 @@ private: DrawablePath& operator= (const DrawablePath&); JUCE_LEAK_DETECTOR (DrawablePath) }; - - -#endif // JUCE_DRAWABLEPATH_H_INCLUDED diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp b/source/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp index c9cb67b40..4bd0c70ec 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h b/source/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h index b136b8d8c..f34e77b79 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAWABLERECTANGLE_H_INCLUDED -#define JUCE_DRAWABLERECTANGLE_H_INCLUDED +#pragma once //============================================================================== @@ -98,6 +99,3 @@ private: DrawableRectangle& operator= (const DrawableRectangle&); JUCE_LEAK_DETECTOR (DrawableRectangle) }; - - -#endif // JUCE_DRAWABLERECTANGLE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp b/source/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp index 0f6952298..9c23c44a7 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -169,6 +171,7 @@ void DrawableShape::writeTo (FillAndStrokeState& state, ComponentBuilder::ImageP void DrawableShape::paint (Graphics& g) { transformContextToCorrectOrigin (g); + applyDrawableClipPath (g); g.setFillType (mainFill.fill); g.fillPath (path); @@ -486,3 +489,10 @@ bool DrawableShape::replaceColour (Colour original, Colour replacement) bool changed2 = replaceColourInFill (strokeFill, original, replacement); return changed1 || changed2; } + +Path DrawableShape::getOutlineAsPath() const +{ + Path outline (isStrokeVisible() ? strokePath : path); + outline.applyTransform (getTransform()); + return outline; +} diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableShape.h b/source/modules/juce_gui_basics/drawables/juce_DrawableShape.h index 20cbc3cf7..2cb7e3712 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableShape.h +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableShape.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAWABLESHAPE_H_INCLUDED -#define JUCE_DRAWABLESHAPE_H_INCLUDED +#pragma once //============================================================================== @@ -126,7 +127,7 @@ public: void setDashLengths (const Array& newDashLengths); /** Returns the set of dash lengths that the path is using. */ - const Array& getDashLengths() const noexcept { return dashLengths; }; + const Array& getDashLengths() const noexcept { return dashLengths; } //============================================================================== /** @internal */ @@ -155,6 +156,8 @@ public: bool hitTest (int x, int y) override; /** @internal */ bool replaceColour (Colour originalColour, Colour replacementColour) override; + /** @internal */ + Path getOutlineAsPath() const override; protected: //============================================================================== @@ -184,6 +187,3 @@ private: DrawableShape& operator= (const DrawableShape&); }; - - -#endif // JUCE_DRAWABLESHAPE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableText.cpp b/source/modules/juce_gui_basics/drawables/juce_DrawableText.cpp index d14288151..3bfddce9d 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableText.cpp +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableText.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -160,6 +162,18 @@ void DrawableText::recalculateCoordinates (Expression::Scope* scope) } //============================================================================== +Rectangle DrawableText::getTextArea (float w, float h) const +{ + return Rectangle (w, h).getSmallestIntegerContainer(); +} + +AffineTransform DrawableText::getTextTransform (float w, float h) const +{ + return AffineTransform::fromTargetPoints (0, 0, resolvedPoints[0].x, resolvedPoints[0].y, + w, 0, resolvedPoints[1].x, resolvedPoints[1].y, + 0, h, resolvedPoints[2].x, resolvedPoints[2].y); +} + void DrawableText::paint (Graphics& g) { transformContextToCorrectOrigin (g); @@ -167,13 +181,11 @@ void DrawableText::paint (Graphics& g) const float w = Line (resolvedPoints[0], resolvedPoints[1]).getLength(); const float h = Line (resolvedPoints[0], resolvedPoints[2]).getLength(); - g.addTransform (AffineTransform::fromTargetPoints (0, 0, resolvedPoints[0].x, resolvedPoints[0].y, - w, 0, resolvedPoints[1].x, resolvedPoints[1].y, - 0, h, resolvedPoints[2].x, resolvedPoints[2].y)); + g.addTransform (getTextTransform (w, h)); g.setFont (scaledFont); g.setColour (colour); - g.drawFittedText (text, Rectangle (w, h).getSmallestIntegerContainer(), justification, 0x100000); + g.drawFittedText (text, getTextArea (w, h), justification, 0x100000); } Rectangle DrawableText::getDrawableBounds() const @@ -332,3 +344,31 @@ ValueTree DrawableText::createValueTree (ComponentBuilder::ImageProvider*) const return tree; } + +Path DrawableText::getOutlineAsPath() const +{ + auto w = Line (resolvedPoints[0], resolvedPoints[1]).getLength(); + auto h = Line (resolvedPoints[0], resolvedPoints[2]).getLength(); + const auto area = getTextArea (w, h).toFloat(); + + GlyphArrangement arr; + arr.addFittedText (scaledFont, text, + area.getX(), area.getY(), + area.getWidth(), area.getHeight(), + justification, + 0x100000); + + Path pathOfAllGlyphs; + + for (int i = 0; i < arr.getNumGlyphs(); ++i) + { + Path gylphPath; + arr.getGlyph (i).createPath (gylphPath); + pathOfAllGlyphs.addPath (gylphPath); + } + + pathOfAllGlyphs.applyTransform (getTextTransform (w, h) + .followedBy (getTransform())); + + return pathOfAllGlyphs; +} diff --git a/source/modules/juce_gui_basics/drawables/juce_DrawableText.h b/source/modules/juce_gui_basics/drawables/juce_DrawableText.h index 16b801bb0..1033b0b66 100644 --- a/source/modules/juce_gui_basics/drawables/juce_DrawableText.h +++ b/source/modules/juce_gui_basics/drawables/juce_DrawableText.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAWABLETEXT_H_INCLUDED -#define JUCE_DRAWABLETEXT_H_INCLUDED +#pragma once //============================================================================== @@ -98,6 +99,8 @@ public: static const Identifier valueTreeType; /** @internal */ Rectangle getDrawableBounds() const override; + /** @internal */ + Path getOutlineAsPath() const override; //============================================================================== /** Internally-used class for wrapping a DrawableText's state into a ValueTree. */ @@ -146,10 +149,9 @@ private: bool registerCoordinates (RelativeCoordinatePositionerBase&); void recalculateCoordinates (Expression::Scope*); void refreshBounds(); + Rectangle getTextArea (float width, float height) const; + AffineTransform getTextTransform (float width, float height) const; DrawableText& operator= (const DrawableText&); JUCE_LEAK_DETECTOR (DrawableText) }; - - -#endif // JUCE_DRAWABLETEXT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/drawables/juce_SVGParser.cpp b/source/modules/juce_gui_basics/drawables/juce_SVGParser.cpp index 8b17df846..60de4aa0a 100644 --- a/source/modules/juce_gui_basics/drawables/juce_SVGParser.cpp +++ b/source/modules/juce_gui_basics/drawables/juce_SVGParser.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -26,10 +28,8 @@ class SVGState { public: //============================================================================== - explicit SVGState (const XmlElement* const topLevel) - : topLevelXml (topLevel, nullptr), - width (512), height (512), - viewBoxW (0), viewBoxH (0) + explicit SVGState (const XmlElement* topLevel, const File& svgFile = {}) + : originalFile (svgFile), topLevelXml (topLevel, nullptr) { } @@ -48,11 +48,9 @@ public: { XmlPath child (e, this); - if (e->compareAttribute ("id", id)) - { - op (child); - return true; - } + if (e->compareAttribute ("id", id) + && ! child->hasTagName ("defs")) + return op (child); if (child.applyOperationToChildWithID (id, op)) return true; @@ -68,23 +66,63 @@ public: //============================================================================== struct UsePathOp { - const SVGState* state; - Path* targetPath; + const SVGState* state; + Path* targetPath; - void operator() (const XmlPath& xmlPath) - { - state->parsePathElement (xmlPath, *targetPath); - } + bool operator() (const XmlPath& xmlPath) const + { + return state->parsePathElement (xmlPath, *targetPath); + } }; - struct GetClipPathOp + struct UseShapeOp + { + const SVGState* state; + Path* sourcePath; + AffineTransform* transform; + Drawable* target; + + bool operator() (const XmlPath& xmlPath) + { + target = state->parseShape (xmlPath, *sourcePath, true, transform); + return target != nullptr; + } + }; + + struct UseTextOp + { + const SVGState* state; + AffineTransform* transform; + Drawable* target; + + bool operator() (const XmlPath& xmlPath) + { + target = state->parseText (xmlPath, true, transform); + return target != nullptr; + } + }; + + struct UseImageOp { const SVGState* state; + AffineTransform* transform; Drawable* target; - void operator() (const XmlPath& xmlPath) + bool operator() (const XmlPath& xmlPath) { - state->applyClipPath (*target, xmlPath); + target = state->parseImage (xmlPath, true, transform); + return target != nullptr; + } + }; + + struct GetClipPathOp + { + SVGState* state; + Drawable* target; + + bool operator() (const XmlPath& xmlPath) + { + return state->applyClipPath (*target, xmlPath); } }; @@ -93,9 +131,9 @@ public: const SVGState* state; ColourGradient* gradient; - void operator() (const XmlPath& xml) + bool operator() (const XmlPath& xml) const { - state->addGradientStopsIn (*gradient, xml); + return state->addGradientStopsIn (*gradient, xml); } }; @@ -106,18 +144,23 @@ public: float opacity; FillType fillType; - void operator() (const XmlPath& xml) + bool operator() (const XmlPath& xml) { if (xml->hasTagNameIgnoringNamespace ("linearGradient") || xml->hasTagNameIgnoringNamespace ("radialGradient")) + { fillType = state->getGradientFillType (xml, *path, opacity); + return true; + } + + return false; } }; //============================================================================== Drawable* parseSVGElement (const XmlPath& xml) { - DrawableComposite* const drawable = new DrawableComposite(); + auto drawable = new DrawableComposite(); setCommonAttributes (*drawable, xml); SVGState newState (*this); @@ -135,8 +178,8 @@ public: if (xml->hasAttribute ("viewBox")) { - const String viewBoxAtt (xml->getStringAttribute ("viewBox")); - String::CharPointerType viewParams (viewBoxAtt.getCharPointer()); + auto viewBoxAtt = xml->getStringAttribute ("viewBox"); + auto viewParams = viewBoxAtt.getCharPointer(); Point vwh; if (parseCoords (viewParams, viewboxXY, true) @@ -147,7 +190,7 @@ public: newState.viewBoxW = vwh.x; newState.viewBoxH = vwh.y; - const int placementFlags = parsePlacementFlags (xml->getStringAttribute ("preserveAspectRatio").trim()); + auto placementFlags = parsePlacementFlags (xml->getStringAttribute ("preserveAspectRatio").trim()); if (placementFlags != 0) newState.transform = RectanglePlacement (placementFlags) @@ -158,8 +201,8 @@ public: } else { - if (viewBoxW == 0) newState.viewBoxW = newState.width; - if (viewBoxH == 0) newState.viewBoxH = newState.height; + if (viewBoxW == 0.0f) newState.viewBoxW = newState.width; + if (viewBoxH == 0.0f) newState.viewBoxH = newState.height; } newState.parseSubElements (xml, *drawable); @@ -176,7 +219,7 @@ public: //============================================================================== void parsePathString (Path& path, const String& pathString) const { - String::CharPointerType d (pathString.getCharPointer().findEndOfWhitespace()); + auto d = pathString.getCharPointer().findEndOfWhitespace(); Point subpathStart, last, last2, p1, p2, p3; juce_wchar currentCommand = 0, previousCommand = 0; @@ -403,26 +446,45 @@ public: private: //============================================================================== + const File originalFile; const XmlPath topLevelXml; - float width, height, viewBoxW, viewBoxH; + float width = 512, height = 512, viewBoxW = 0, viewBoxH = 0; AffineTransform transform; String cssStyleText; + static bool isNone (const String& s) noexcept + { + return s.equalsIgnoreCase ("none"); + } + static void setCommonAttributes (Drawable& d, const XmlPath& xml) { - String compID (xml->getStringAttribute ("id")); + auto compID = xml->getStringAttribute ("id"); d.setName (compID); d.setComponentID (compID); - if (xml->getStringAttribute ("display") == "none") + if (isNone (xml->getStringAttribute ("display"))) d.setVisible (false); } //============================================================================== - void parseSubElements (const XmlPath& xml, DrawableComposite& parentDrawable) + void parseSubElements (const XmlPath& xml, DrawableComposite& parentDrawable, const bool shouldParseClip = true) { forEachXmlChildElement (*xml, e) - parentDrawable.addAndMakeVisible (parseSubElement (xml.getChild (e))); + { + const XmlPath child (xml.getChild (e)); + + if (auto* drawable = parseSubElement (child)) + { + parentDrawable.addChildComponent (drawable); + + if (! isNone (getStyleAttribute (child, "display"))) + drawable->setVisible (true); + + if (shouldParseClip) + parseClipPath (child, *drawable); + } + } } Drawable* parseSubElement (const XmlPath& xml) @@ -433,21 +495,24 @@ private: return parseShape (xml, path); } - const String tag (xml->getTagNameWithoutNamespace()); + auto tag = xml->getTagNameWithoutNamespace(); - if (tag == "g") return parseGroupElement (xml); + if (tag == "g") return parseGroupElement (xml, true); if (tag == "svg") return parseSVGElement (xml); if (tag == "text") return parseText (xml, true); + if (tag == "image") return parseImage (xml, true); if (tag == "switch") return parseSwitch (xml); if (tag == "a") return parseLinkElement (xml); + if (tag == "use") return parseUseOther (xml); if (tag == "style") parseCSSStyle (xml); + if (tag == "defs") parseDefs (xml); return nullptr; } bool parsePathElement (const XmlPath& xml, Path& path) const { - const String tag (xml->getTagNameWithoutNamespace()); + auto tag = xml->getTagNameWithoutNamespace(); if (tag == "path") { parsePath (xml, path); return true; } if (tag == "rect") { parseRect (xml, path); return true; } @@ -456,43 +521,40 @@ private: if (tag == "line") { parseLine (xml, path); return true; } if (tag == "polyline") { parsePolygon (xml, true, path); return true; } if (tag == "polygon") { parsePolygon (xml, false, path); return true; } - if (tag == "use") { parseUse (xml, path); return true; } + if (tag == "use") { return parseUsePath (xml, path); } return false; } DrawableComposite* parseSwitch (const XmlPath& xml) { - if (const XmlElement* const group = xml->getChildByName ("g")) - return parseGroupElement (xml.getChild (group)); + if (auto* group = xml->getChildByName ("g")) + return parseGroupElement (xml.getChild (group), true); return nullptr; } - DrawableComposite* parseGroupElement (const XmlPath& xml) + DrawableComposite* parseGroupElement (const XmlPath& xml, bool shouldParseTransform) { - DrawableComposite* const drawable = new DrawableComposite(); - - setCommonAttributes (*drawable, xml); - - if (xml->hasAttribute ("transform")) + if (shouldParseTransform && xml->hasAttribute ("transform")) { SVGState newState (*this); newState.addTransform (xml); - newState.parseSubElements (xml, *drawable); - } - else - { - parseSubElements (xml, *drawable); + + return newState.parseGroupElement (xml, false); } + auto* drawable = new DrawableComposite(); + setCommonAttributes (*drawable, xml); + parseSubElements (xml, *drawable); + drawable->resetContentAreaAndBoundingBoxToFitChildren(); return drawable; } DrawableComposite* parseLinkElement (const XmlPath& xml) { - return parseGroupElement (xml); // TODO: support for making this clickable + return parseGroupElement (xml, true); // TODO: support for making this clickable } //============================================================================== @@ -536,29 +598,29 @@ private: void parseCircle (const XmlPath& xml, Path& circle) const { - const float cx = getCoordLength (xml, "cx", viewBoxW); - const float cy = getCoordLength (xml, "cy", viewBoxH); - const float radius = getCoordLength (xml, "r", viewBoxW); + auto cx = getCoordLength (xml, "cx", viewBoxW); + auto cy = getCoordLength (xml, "cy", viewBoxH); + auto radius = getCoordLength (xml, "r", viewBoxW); circle.addEllipse (cx - radius, cy - radius, radius * 2.0f, radius * 2.0f); } void parseEllipse (const XmlPath& xml, Path& ellipse) const { - const float cx = getCoordLength (xml, "cx", viewBoxW); - const float cy = getCoordLength (xml, "cy", viewBoxH); - const float radiusX = getCoordLength (xml, "rx", viewBoxW); - const float radiusY = getCoordLength (xml, "ry", viewBoxH); + auto cx = getCoordLength (xml, "cx", viewBoxW); + auto cy = getCoordLength (xml, "cy", viewBoxH); + auto radiusX = getCoordLength (xml, "rx", viewBoxW); + auto radiusY = getCoordLength (xml, "ry", viewBoxH); ellipse.addEllipse (cx - radiusX, cy - radiusY, radiusX * 2.0f, radiusY * 2.0f); } void parseLine (const XmlPath& xml, Path& line) const { - const float x1 = getCoordLength (xml, "x1", viewBoxW); - const float y1 = getCoordLength (xml, "y1", viewBoxH); - const float x2 = getCoordLength (xml, "x2", viewBoxW); - const float y2 = getCoordLength (xml, "y2", viewBoxH); + auto x1 = getCoordLength (xml, "x1", viewBoxW); + auto y1 = getCoordLength (xml, "y1", viewBoxH); + auto x2 = getCoordLength (xml, "x2", viewBoxW); + auto y2 = getCoordLength (xml, "y2", viewBoxH); line.startNewSubPath (x1, y1); line.lineTo (x2, y2); @@ -566,8 +628,8 @@ private: void parsePolygon (const XmlPath& xml, const bool isPolyline, Path& path) const { - const String pointsAtt (xml->getStringAttribute ("points")); - String::CharPointerType points (pointsAtt.getCharPointer()); + auto pointsAtt = xml->getStringAttribute ("points"); + auto points = pointsAtt.getCharPointer(); Point p; if (parseCoords (points, p, true)) @@ -587,17 +649,35 @@ private: } } - void parseUse (const XmlPath& xml, Path& path) const + static String getLinkedID (const XmlPath& xml) { - const String link (xml->getStringAttribute ("xlink:href")); + auto link = xml->getStringAttribute ("xlink:href"); if (link.startsWithChar ('#')) - { - const String linkedID = link.substring (1); + return link.substring (1); + return {}; + } + + bool parseUsePath (const XmlPath& xml, Path& path) const + { + auto linkedID = getLinkedID (xml); + + if (linkedID.isNotEmpty()) + { UsePathOp op = { this, &path }; - topLevelXml.applyOperationToChildWithID (linkedID, op); + return topLevelXml.applyOperationToChildWithID (linkedID, op); } + + return false; + } + + Drawable* parseUseOther (const XmlPath& xml) const + { + if (auto* drawableText = parseText (xml, false)) return drawableText; + if (auto* drawableImage = parseImage (xml, false)) return drawableImage; + + return nullptr; } static String parseURL (const String& str) @@ -606,26 +686,50 @@ private: return str.fromFirstOccurrenceOf ("#", false, false) .upToLastOccurrenceOf (")", false, false).trim(); - return String(); + return {}; } //============================================================================== + + Drawable* useShape (const XmlPath& xml, Path& path) const + { + auto translation = AffineTransform::translation ((float) xml->getDoubleAttribute ("x", 0.0), + (float) xml->getDoubleAttribute ("y", 0.0)); + + UseShapeOp op = { this, &path, &translation, nullptr }; + + auto linkedID = getLinkedID (xml); + + if (linkedID.isNotEmpty()) + topLevelXml.applyOperationToChildWithID (linkedID, op); + + return op.target; + } + Drawable* parseShape (const XmlPath& xml, Path& path, - const bool shouldParseTransform = true) const + const bool shouldParseTransform = true, + AffineTransform* additonalTransform = nullptr) const { if (shouldParseTransform && xml->hasAttribute ("transform")) { SVGState newState (*this); newState.addTransform (xml); - return newState.parseShape (xml, path, false); + return newState.parseShape (xml, path, false, additonalTransform); } - DrawablePath* dp = new DrawablePath(); + if (xml->hasTagName ("use")) + return useShape (xml, path); + + auto dp = new DrawablePath(); setCommonAttributes (*dp, xml); dp->setFill (Colours::transparentBlack); path.applyTransform (transform); + + if (additonalTransform != nullptr) + path.applyTransform (*additonalTransform); + dp->setPath (path); dp->setFill (getPathFillType (path, xml, "fill", @@ -634,9 +738,9 @@ private: pathContainsClosedSubPath (path) ? Colours::black : Colours::transparentBlack)); - const String strokeType (getStyleAttribute (xml, "stroke")); + auto strokeType = getStyleAttribute (xml, "stroke"); - if (strokeType.isNotEmpty() && ! strokeType.equalsIgnoreCase ("none")) + if (strokeType.isNotEmpty() && ! isNone (strokeType)) { dp->setStrokeFill (getPathFillType (path, xml, "stroke", getStyleAttribute (xml, "stroke-opacity"), @@ -646,13 +750,11 @@ private: dp->setStrokeType (getStrokeFor (xml)); } - const String strokeDashArray (getStyleAttribute (xml, "stroke-dasharray")); + auto strokeDashArray = getStyleAttribute (xml, "stroke-dasharray"); if (strokeDashArray.isNotEmpty()) parseDashArray (strokeDashArray, *dp); - parseClipPath (xml, *dp); - return dp; } @@ -667,12 +769,12 @@ private: void parseDashArray (const String& dashList, DrawablePath& dp) const { - if (dashList.equalsIgnoreCase ("null") || dashList.equalsIgnoreCase ("none")) + if (dashList.equalsIgnoreCase ("null") || isNone (dashList)) return; Array dashLengths; - for (String::CharPointerType t = dashList.getCharPointer();;) + for (auto t = dashList.getCharPointer();;) { float value; if (! parseCoord (t, value, true, true)) @@ -688,7 +790,7 @@ private: if (dashLengths.size() > 0) { - float* const dashes = dashLengths.getRawDataPointer(); + auto* dashes = dashLengths.getRawDataPointer(); for (int i = 0; i < dashLengths.size(); ++i) { @@ -712,40 +814,54 @@ private: } } - void parseClipPath (const XmlPath& xml, Drawable& d) const + bool parseClipPath (const XmlPath& xml, Drawable& d) { const String clipPath (getStyleAttribute (xml, "clip-path")); if (clipPath.isNotEmpty()) { - String urlID = parseURL (clipPath); + auto urlID = parseURL (clipPath); if (urlID.isNotEmpty()) { GetClipPathOp op = { this, &d }; - topLevelXml.applyOperationToChildWithID (urlID, op); + return topLevelXml.applyOperationToChildWithID (urlID, op); } } + + return false; } - void applyClipPath (Drawable& target, const XmlPath& xmlPath) const + bool applyClipPath (Drawable& target, const XmlPath& xmlPath) { if (xmlPath->hasTagNameIgnoringNamespace ("clipPath")) { - // TODO: implement clipping.. - ignoreUnused (target); + ScopedPointer drawableClipPath (new DrawableComposite()); + + parseSubElements (xmlPath, *drawableClipPath, false); + + if (drawableClipPath->getNumChildComponents() > 0) + { + setCommonAttributes (*drawableClipPath, xmlPath); + target.setClipPath (drawableClipPath.release()); + return true; + } } + + return false; } - void addGradientStopsIn (ColourGradient& cg, const XmlPath& fillXml) const + bool addGradientStopsIn (ColourGradient& cg, const XmlPath& fillXml) const { + bool result = false; + if (fillXml.xml != nullptr) { forEachXmlChildElementWithTagName (*fillXml, e, "stop") { - Colour col (parseColour (fillXml.getChild (e), "stop-color", Colours::black)); + auto col = parseColour (fillXml.getChild (e), "stop-color", Colours::black); - const String opacity (getStyleAttribute (fillXml.getChild (e), "stop-opacity", "1")); + auto opacity = getStyleAttribute (fillXml.getChild (e), "stop-opacity", "1"); col = col.withMultipliedAlpha (jlimit (0.0f, 1.0f, opacity.getFloatValue())); double offset = e->getDoubleAttribute ("offset"); @@ -754,8 +870,11 @@ private: offset *= 0.01; cg.addColour (jlimit (0.0, 1.0, offset), col); + result = true; } } + + return result; } FillType getGradientFillType (const XmlPath& fillXml, @@ -765,12 +884,12 @@ private: ColourGradient gradient; { - const String id (fillXml->getStringAttribute ("xlink:href")); + auto linkedID = getLinkedID (fillXml); - if (id.startsWithChar ('#')) + if (linkedID.isNotEmpty()) { SetGradientStopsOp op = { this, &gradient, }; - topLevelXml.applyOperationToChildWithID (id.substring (1), op); + topLevelXml.applyOperationToChildWithID (linkedID, op); } } @@ -806,7 +925,7 @@ private: if (! userSpace) { - const Rectangle bounds (path.getBounds()); + auto bounds = path.getBounds(); dx = bounds.getX(); dy = bounds.getY(); gradientWidth = bounds.getWidth(); @@ -822,7 +941,7 @@ private: gradient.point1.setXY (dx + gradientWidth * getCoordLength (fillXml->getStringAttribute ("cx", "50%"), 1.0f), dy + gradientHeight * getCoordLength (fillXml->getStringAttribute ("cy", "50%"), 1.0f)); - const float radius = getCoordLength (fillXml->getStringAttribute ("r", "50%"), gradientWidth); + auto radius = getCoordLength (fillXml->getStringAttribute ("r", "50%"), gradientWidth); gradient.point2 = gradient.point1 + Point (radius, 0.0f); //xxx (the fx, fy focal point isn't handled properly here..) @@ -852,8 +971,8 @@ private: FillType type (gradient); - const AffineTransform gradientTransform (parseTransform (fillXml->getStringAttribute ("gradientTransform")) - .followedBy (transform)); + auto gradientTransform = parseTransform (fillXml->getStringAttribute ("gradientTransform")) + .followedBy (transform); if (gradient.isRadial) { @@ -863,12 +982,12 @@ private: { // Transform the perpendicular vector into the new coordinate space for the gradient. // This vector is now the slope of the linear gradient as it should appear in the new coord space - const Point perpendicular (Point (gradient.point2.y - gradient.point1.y, - gradient.point1.x - gradient.point2.x) - .transformedBy (gradientTransform.withAbsoluteTranslation (0, 0))); + auto perpendicular = Point (gradient.point2.y - gradient.point1.y, + gradient.point1.x - gradient.point2.x) + .transformedBy (gradientTransform.withAbsoluteTranslation (0, 0)); - const Point newGradPoint1 (gradient.point1.transformedBy (gradientTransform)); - const Point newGradPoint2 (gradient.point2.transformedBy (gradientTransform)); + auto newGradPoint1 = gradient.point1.transformedBy (gradientTransform); + auto newGradPoint2 = gradient.point2.transformedBy (gradientTransform); // Project the transformed gradient vector onto the transformed slope of the linear // gradient as it should appear in the new coordinate space @@ -908,7 +1027,7 @@ private: return op.fillType; } - if (fill.equalsIgnoreCase ("none")) + if (isNone (fill)) return Colours::transparentBlack; return parseColour (xml, fillAttribute, defaultColour).withMultipliedAlpha (opacity); @@ -943,16 +1062,39 @@ private: } //============================================================================== - Drawable* parseText (const XmlPath& xml, bool shouldParseTransform) + + Drawable* useText (const XmlPath& xml) const + { + auto translation = AffineTransform::translation ((float) xml->getDoubleAttribute ("x", 0.0), + (float) xml->getDoubleAttribute ("y", 0.0)); + + UseTextOp op = { this, &translation, nullptr }; + + auto linkedID = getLinkedID (xml); + + if (linkedID.isNotEmpty()) + topLevelXml.applyOperationToChildWithID (linkedID, op); + + return op.target; + } + + Drawable* parseText (const XmlPath& xml, bool shouldParseTransform, + AffineTransform* additonalTransform = nullptr) const { if (shouldParseTransform && xml->hasAttribute ("transform")) { SVGState newState (*this); newState.addTransform (xml); - return newState.parseText (xml, false); + return newState.parseText (xml, false, additonalTransform); } + if (xml->hasTagName ("use")) + return useText (xml); + + if (! xml->hasTagName ("text")) + return nullptr; + Array xCoords, yCoords, dxCoords, dyCoords; getCoordList (xCoords, getInheritedAttribute (xml, "x"), true, true); @@ -960,24 +1102,28 @@ private: getCoordList (dxCoords, getInheritedAttribute (xml, "dx"), true, true); getCoordList (dyCoords, getInheritedAttribute (xml, "dy"), true, false); - const Font font (getFont (xml)); - const String anchorStr = getStyleAttribute(xml, "text-anchor"); + auto font = getFont (xml); + auto anchorStr = getStyleAttribute (xml, "text-anchor"); - DrawableComposite* dc = new DrawableComposite(); + auto dc = new DrawableComposite(); setCommonAttributes (*dc, xml); forEachXmlChildElement (*xml, e) { if (e->isTextElement()) { - const String text (e->getText().trim()); + auto text = e->getText().trim(); - DrawableText* dt = new DrawableText(); + auto dt = new DrawableText(); dc->addAndMakeVisible (dt); dt->setText (text); dt->setFont (font, true); - dt->setTransform (transform); + + if (additonalTransform != nullptr) + dt->setTransform (transform.followedBy (*additonalTransform)); + else + dt->setTransform (transform); dt->setColour (parseColour (xml, "fill", Colours::black) .withMultipliedAlpha (getStyleAttribute (xml, "fill-opacity", "1").getFloatValue())); @@ -1001,17 +1147,108 @@ private: Font getFont (const XmlPath& xml) const { - const float fontSize = getCoordLength (getStyleAttribute (xml, "font-size"), 1.0f); + Font f; + auto family = getStyleAttribute (xml, "font-family").unquoted(); - int style = getStyleAttribute (xml, "font-style").containsIgnoreCase ("italic") ? Font::italic : Font::plain; + if (family.isNotEmpty()) + f.setTypefaceName (family); + + if (getStyleAttribute (xml, "font-style").containsIgnoreCase ("italic")) + f.setItalic (true); if (getStyleAttribute (xml, "font-weight").containsIgnoreCase ("bold")) - style |= Font::bold; + f.setBold (true); + + return f.withPointHeight (getCoordLength (getStyleAttribute (xml, "font-size"), 1.0f)); + } + + //============================================================================== + Drawable* useImage (const XmlPath& xml) const + { + auto translation = AffineTransform::translation ((float) xml->getDoubleAttribute ("x", 0.0), + (float) xml->getDoubleAttribute ("y", 0.0)); + + UseImageOp op = { this, &translation, nullptr }; + + auto linkedID = getLinkedID (xml); + + if (linkedID.isNotEmpty()) + topLevelXml.applyOperationToChildWithID (linkedID, op); + + return op.target; + } + + Drawable* parseImage (const XmlPath& xml, bool shouldParseTransform, + AffineTransform* additionalTransform = nullptr) const + { + if (shouldParseTransform && xml->hasAttribute ("transform")) + { + SVGState newState (*this); + newState.addTransform (xml); + + return newState.parseImage (xml, false, additionalTransform); + } + + if (xml->hasTagName ("use")) + return useImage (xml); + + if (! xml->hasTagName ("image")) + return nullptr; + + auto link = xml->getStringAttribute ("xlink:href"); + + ScopedPointer inputStream; + MemoryOutputStream imageStream; + + if (link.startsWith ("data:")) + { + const auto indexOfComma = link.indexOf (","); + auto format = link.substring (5, indexOfComma).trim(); + + const auto indexOfSemi = format.indexOf (";"); - const String family (getStyleAttribute (xml, "font-family")); + if (format.substring (indexOfSemi + 1).trim().equalsIgnoreCase ("base64")) + { + auto mime = format.substring (0, indexOfSemi).trim(); + + if (mime.equalsIgnoreCase ("image/png") || mime.equalsIgnoreCase ("image/jpeg")) + { + const String base64text = link.substring (indexOfComma + 1).removeCharacters ("\t\n\r "); + + if (Base64::convertFromBase64 (imageStream, base64text)) + inputStream = new MemoryInputStream (imageStream.getData(), imageStream.getDataSize(), false); + } + } + } + else + { + auto linkedFile = originalFile.getParentDirectory().getChildFile (link); - return family.isEmpty() ? Font (fontSize, style) - : Font (family, fontSize, style); + if (linkedFile.existsAsFile()) + inputStream = linkedFile.createInputStream(); + } + + if (inputStream != nullptr) + { + auto image = ImageFileFormat::loadFrom (*inputStream); + + if (image.isValid()) + { + auto* di = new DrawableImage(); + + setCommonAttributes (*di, xml); + di->setImage (image); + + if (additionalTransform != nullptr) + di->setTransform (transform.followedBy (*additionalTransform)); + else + di->setTransform (transform); + + return di; + } + } + + return nullptr; } //============================================================================== @@ -1080,7 +1317,7 @@ private: void getCoordList (Array& coords, const String& list, bool allowUnits, const bool isX) const { - String::CharPointerType text (list.getCharPointer()); + auto text = list.getCharPointer(); float value; while (parseCoord (text, value, allowUnits, isX)) @@ -1093,56 +1330,68 @@ private: cssStyleText = xml->getAllSubText() + "\n" + cssStyleText; } + void parseDefs (const XmlPath& xml) + { + if (auto* style = xml->getChildByName ("style")) + parseCSSStyle (xml.getChild (style)); + } + static String::CharPointerType findStyleItem (String::CharPointerType source, String::CharPointerType name) { - const int nameLength = (int) name.length(); + auto nameLength = (int) name.length(); while (! source.isEmpty()) { if (source.getAndAdvance() == '.' && CharacterFunctions::compareIgnoreCaseUpTo (source, name, nameLength) == 0) { - String::CharPointerType endOfName ((source + nameLength).findEndOfWhitespace()); + auto endOfName = (source + nameLength).findEndOfWhitespace(); if (*endOfName == '{') return endOfName; + + if (*endOfName == ',') + return CharacterFunctions::find (endOfName, (juce_wchar) '{'); } } return source; } - String getStyleAttribute (const XmlPath& xml, StringRef attributeName, - const String& defaultValue = String()) const + String getStyleAttribute (const XmlPath& xml, StringRef attributeName, const String& defaultValue = String()) const { if (xml->hasAttribute (attributeName)) return xml->getStringAttribute (attributeName, defaultValue); - const String styleAtt (xml->getStringAttribute ("style")); + auto styleAtt = xml->getStringAttribute ("style"); if (styleAtt.isNotEmpty()) { - const String value (getAttributeFromStyleList (styleAtt, attributeName, String())); + auto value = getAttributeFromStyleList (styleAtt, attributeName, {}); if (value.isNotEmpty()) return value; } else if (xml->hasAttribute ("class")) { - String::CharPointerType openBrace = findStyleItem (cssStyleText.getCharPointer(), - xml->getStringAttribute ("class").getCharPointer()); - - if (! openBrace.isEmpty()) + for (auto i = cssStyleText.getCharPointer();;) { - String::CharPointerType closeBrace = CharacterFunctions::find (openBrace, (juce_wchar) '}'); + auto openBrace = findStyleItem (i, xml->getStringAttribute ("class").getCharPointer()); - if (closeBrace != openBrace) - { - const String value (getAttributeFromStyleList (String (openBrace + 1, closeBrace), - attributeName, defaultValue)); - if (value.isNotEmpty()) - return value; - } + if (openBrace.isEmpty()) + break; + + auto closeBrace = CharacterFunctions::find (openBrace, (juce_wchar) '}'); + + if (closeBrace.isEmpty()) + break; + + auto value = getAttributeFromStyleList (String (openBrace + 1, closeBrace), + attributeName, defaultValue); + if (value.isNotEmpty()) + return value; + + i = closeBrace + 1; } } @@ -1160,7 +1409,7 @@ private: if (xml.parent != nullptr) return getInheritedAttribute (*xml.parent, attributeName); - return String(); + return {}; } static int parsePlacementFlags (const String& align) noexcept @@ -1168,7 +1417,7 @@ private: if (align.isEmpty()) return 0; - if (align.containsIgnoreCase ("none")) + if (isNone (align)) return RectanglePlacement::stretchToFit; return (align.containsIgnoreCase ("slice") ? RectanglePlacement::fillDestination : 0) @@ -1232,7 +1481,7 @@ private: while (s.isWhitespace() || *s == ',') ++s; - String::CharPointerType start (s); + auto start = s; if (isStartOfNumber (*s)) ++s; @@ -1278,17 +1527,17 @@ private: //============================================================================== Colour parseColour (const XmlPath& xml, StringRef attributeName, const Colour defaultColour) const { - const String text (getStyleAttribute (xml, attributeName)); + auto text = getStyleAttribute (xml, attributeName); if (text.startsWithChar ('#')) { uint32 hex[6] = { 0 }; int numChars = 0; - String::CharPointerType s = text.getCharPointer(); + auto s = text.getCharPointer(); while (numChars < 6) { - const int hexValue = CharacterFunctions::getHexDigitValue (*++s); + auto hexValue = CharacterFunctions::getHexDigitValue (*++s); if (hexValue >= 0) hex [numChars++] = (uint32) hexValue; @@ -1308,8 +1557,8 @@ private: if (text.startsWith ("rgb")) { - const int openBracket = text.indexOfChar ('('); - const int closeBracket = text.indexOfChar (openBracket, ')'); + auto openBracket = text.indexOfChar ('('); + auto closeBracket = text.indexOfChar (openBracket, ')'); if (openBracket >= 3 && closeBracket > openBracket) { @@ -1486,6 +1735,25 @@ Drawable* Drawable::createFromSVG (const XmlElement& svgDocument) return state.parseSVGElement (SVGState::XmlPath (&svgDocument, nullptr)); } +Drawable* Drawable::createFromSVGFile (const File& svgFile) +{ + XmlDocument doc (svgFile); + ScopedPointer outer (doc.getDocumentElement (true)); + + if (outer != nullptr && outer->hasTagName ("svg")) + { + ScopedPointer svgDocument (doc.getDocumentElement()); + + if (svgDocument != nullptr) + { + SVGState state (svgDocument, svgFile); + return state.parseSVGElement (SVGState::XmlPath (svgDocument, nullptr)); + } + } + + return nullptr; +} + Path Drawable::parseSVGPath (const String& svgPath) { SVGState state (nullptr); diff --git a/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp b/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp index 552a676bf..5e9268fe9 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp @@ -2,28 +2,30 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -DirectoryContentsDisplayComponent::DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow) - : fileList (listToShow) +DirectoryContentsDisplayComponent::DirectoryContentsDisplayComponent (DirectoryContentsList& l) + : directoryContentsList (l) { } @@ -36,15 +38,8 @@ FileBrowserListener::~FileBrowserListener() { } -void DirectoryContentsDisplayComponent::addListener (FileBrowserListener* const listener) -{ - listeners.add (listener); -} - -void DirectoryContentsDisplayComponent::removeListener (FileBrowserListener* const listener) -{ - listeners.remove (listener); -} +void DirectoryContentsDisplayComponent::addListener (FileBrowserListener* l) { listeners.add (l); } +void DirectoryContentsDisplayComponent::removeListener (FileBrowserListener* l) { listeners.remove (l); } void DirectoryContentsDisplayComponent::sendSelectionChangeMessage() { @@ -54,7 +49,7 @@ void DirectoryContentsDisplayComponent::sendSelectionChangeMessage() void DirectoryContentsDisplayComponent::sendMouseClickMessage (const File& file, const MouseEvent& e) { - if (fileList.getDirectory().exists()) + if (directoryContentsList.getDirectory().exists()) { Component::BailOutChecker checker (dynamic_cast (this)); listeners.callChecked (checker, &FileBrowserListener::fileClicked, file, e); @@ -63,7 +58,7 @@ void DirectoryContentsDisplayComponent::sendMouseClickMessage (const File& file, void DirectoryContentsDisplayComponent::sendDoubleClickMessage (const File& file) { - if (fileList.getDirectory().exists()) + if (directoryContentsList.getDirectory().exists()) { Component::BailOutChecker checker (dynamic_cast (this)); listeners.callChecked (checker, &FileBrowserListener::fileDoubleClicked, file); diff --git a/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h b/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h index 0aa8235da..77279ed5a 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_H_INCLUDED -#define JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -42,6 +43,10 @@ public: /** Destructor. */ virtual ~DirectoryContentsDisplayComponent(); + //============================================================================== + /** The list that this component is displaying */ + DirectoryContentsList& directoryContentsList; + //============================================================================== /** Returns the number of files the user has got selected. @see getSelectedFile @@ -94,18 +99,14 @@ public: /** @internal */ void sendSelectionChangeMessage(); /** @internal */ - void sendDoubleClickMessage (const File& file); + void sendDoubleClickMessage (const File&); /** @internal */ - void sendMouseClickMessage (const File& file, const MouseEvent& e); + void sendMouseClickMessage (const File&, const MouseEvent&); protected: //============================================================================== - DirectoryContentsList& fileList; - ListenerList listeners; + ListenerList listeners; private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectoryContentsDisplayComponent) }; - - -#endif // JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp b/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp index 79d810fdb..27a32cfa3 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -119,7 +121,7 @@ bool DirectoryContentsList::getFileInfo (const int index, FileInfo& result) cons { const ScopedLock sl (fileListLock); - if (const FileInfo* const info = files [index]) + if (auto* info = files [index]) { result = *info; return true; @@ -132,10 +134,10 @@ File DirectoryContentsList::getFile (const int index) const { const ScopedLock sl (fileListLock); - if (const FileInfo* const info = files [index]) + if (auto* info = files [index]) return root.getChildFile (info->filename); - return File(); + return {}; } bool DirectoryContentsList::contains (const File& targetFile) const diff --git a/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h b/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h index 3e2258feb..33e062ff7 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DIRECTORYCONTENTSLIST_H_INCLUDED -#define JUCE_DIRECTORYCONTENTSLIST_H_INCLUDED +#pragma once //============================================================================== @@ -218,6 +219,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectoryContentsList) }; - - -#endif // JUCE_DIRECTORYCONTENTSLIST_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp b/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp index 6c6e57f6f..c7030fb88 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h b/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h index 058a36de4..6d1f15914 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILEBROWSERCOMPONENT_H_INCLUDED -#define JUCE_FILEBROWSERCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -194,6 +195,7 @@ public: const String& instructions) = 0; virtual void drawFileBrowserRow (Graphics&, int width, int height, + const File& file, const String& filename, Image* optionalIcon, const String& fileSizeDescription, @@ -283,7 +285,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileBrowserComponent) }; - - - -#endif // JUCE_FILEBROWSERCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h b/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h index 8ff56ad8c..fe7776bca 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileBrowserListener.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILEBROWSERLISTENER_H_INCLUDED -#define JUCE_FILEBROWSERLISTENER_H_INCLUDED +#pragma once //============================================================================== @@ -52,6 +53,3 @@ public: /** Callback when the browser's root folder changes. */ virtual void browserRootChanged (const File& newRoot) = 0; }; - - -#endif // JUCE_FILEBROWSERLISTENER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp b/source/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp index 7a6eb3605..0e3995c75 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileChooser.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileChooser.h b/source/modules/juce_gui_basics/filebrowser/juce_FileChooser.h index e6a35d50a..82a31abb5 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileChooser.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileChooser.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILECHOOSER_H_INCLUDED -#define JUCE_FILECHOOSER_H_INCLUDED +#pragma once //============================================================================== @@ -200,6 +201,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileChooser) }; - - -#endif // JUCE_FILECHOOSER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp b/source/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp index ef851cbf9..642860daf 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h b/source/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h index f0e82bb44..aea327976 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileChooserDialogBox.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILECHOOSERDIALOGBOX_H_INCLUDED -#define JUCE_FILECHOOSERDIALOGBOX_H_INCLUDED +#pragma once //============================================================================== @@ -152,6 +153,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileChooserDialogBox) }; - - -#endif // JUCE_FILECHOOSERDIALOGBOX_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp b/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp index 2333dcc82..4e201007c 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -27,16 +29,16 @@ Image juce_createIconForFile (const File& file); //============================================================================== FileListComponent::FileListComponent (DirectoryContentsList& listToShow) - : ListBox (String(), nullptr), + : ListBox ({}, nullptr), DirectoryContentsDisplayComponent (listToShow) { setModel (this); - fileList.addChangeListener (this); + directoryContentsList.addChangeListener (this); } FileListComponent::~FileListComponent() { - fileList.removeChangeListener (this); + directoryContentsList.removeChangeListener (this); } int FileListComponent::getNumSelectedFiles() const @@ -46,7 +48,7 @@ int FileListComponent::getNumSelectedFiles() const File FileListComponent::getSelectedFile (int index) const { - return fileList.getFile (getSelectedRow (index)); + return directoryContentsList.getFile (getSelectedRow (index)); } void FileListComponent::deselectAllFiles() @@ -61,9 +63,9 @@ void FileListComponent::scrollToTop() void FileListComponent::setSelectedFile (const File& f) { - for (int i = fileList.getNumFiles(); --i >= 0;) + for (int i = directoryContentsList.getNumFiles(); --i >= 0;) { - if (fileList.getFile(i) == f) + if (directoryContentsList.getFile(i) == f) { selectRow (i); return; @@ -78,9 +80,9 @@ void FileListComponent::changeListenerCallback (ChangeBroadcaster*) { updateContent(); - if (lastDirectory != fileList.getDirectory()) + if (lastDirectory != directoryContentsList.getDirectory()) { - lastDirectory = fileList.getDirectory(); + lastDirectory = directoryContentsList.getDirectory(); deselectAllRows(); } } @@ -92,7 +94,7 @@ class FileListComponent::ItemComponent : public Component, { public: ItemComponent (FileListComponent& fc, TimeSliceThread& t) - : owner (fc), thread (t), index (0), highlighted (false) + : owner (fc), thread (t) { } @@ -105,7 +107,7 @@ public: void paint (Graphics& g) override { getLookAndFeel().drawFileBrowserRow (g, getWidth(), getHeight(), - file.getFileName(), + file, file.getFileName(), &icon, fileSize, modTime, isDirectory, highlighted, index, owner); @@ -122,17 +124,15 @@ public: owner.sendDoubleClickMessage (file); } - void update (const File& root, - const DirectoryContentsList::FileInfo* const fileInfo, - const int index_, - const bool highlighted_) + void update (const File& root, const DirectoryContentsList::FileInfo* fileInfo, + int newIndex, bool nowHighlighted) { thread.removeTimeSliceClient (this); - if (highlighted_ != highlighted || index_ != index) + if (nowHighlighted != highlighted || newIndex != index) { - index = index_; - highlighted = highlighted_; + index = newIndex; + highlighted = nowHighlighted; repaint(); } @@ -186,15 +186,15 @@ private: File file; String fileSize, modTime; Image icon; - int index; - bool highlighted, isDirectory; + int index = 0; + bool highlighted = false, isDirectory = false; void updateIcon (const bool onlyUpdateIfCached) { if (icon.isNull()) { - const int hashCode = (file.getFullPathName() + "_iconCacheSalt").hashCode(); - Image im (ImageCache::getFromHashCode (hashCode)); + auto hashCode = (file.getFullPathName() + "_iconCacheSalt").hashCode(); + auto im = ImageCache::getFromHashCode (hashCode); if (im.isNull() && ! onlyUpdateIfCached) { @@ -218,7 +218,7 @@ private: //============================================================================== int FileListComponent::getNumRows() { - return fileList.getNumFiles(); + return directoryContentsList.getNumFiles(); } void FileListComponent::paintListBoxItem (int, Graphics&, int, int, bool) @@ -229,14 +229,14 @@ Component* FileListComponent::refreshComponentForRow (int row, bool isSelected, { jassert (existingComponentToUpdate == nullptr || dynamic_cast (existingComponentToUpdate) != nullptr); - ItemComponent* comp = static_cast (existingComponentToUpdate); + auto comp = static_cast (existingComponentToUpdate); if (comp == nullptr) - comp = new ItemComponent (*this, fileList.getTimeSliceThread()); + comp = new ItemComponent (*this, directoryContentsList.getTimeSliceThread()); DirectoryContentsList::FileInfo fileInfo; - comp->update (fileList.getDirectory(), - fileList.getFileInfo (row, fileInfo) ? &fileInfo : nullptr, + comp->update (directoryContentsList.getDirectory(), + directoryContentsList.getFileInfo (row, fileInfo) ? &fileInfo : nullptr, row, isSelected); return comp; @@ -253,5 +253,5 @@ void FileListComponent::deleteKeyPressed (int /*currentSelectedRow*/) void FileListComponent::returnKeyPressed (int currentSelectedRow) { - sendDoubleClickMessage (fileList.getFile (currentSelectedRow)); + sendDoubleClickMessage (directoryContentsList.getFile (currentSelectedRow)); } diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h b/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h index 30fb4fe33..3dbf93efc 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILELISTCOMPONENT_H_INCLUDED -#define JUCE_FILELISTCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -45,8 +46,7 @@ class JUCE_API FileListComponent : public ListBox, { public: //============================================================================== - /** Creates a listbox to show the contents of a specified directory. - */ + /** Creates a listbox to show the contents of a specified directory. */ FileListComponent (DirectoryContentsList& listToShow); /** Destructor. */ @@ -77,11 +77,9 @@ public: private: //============================================================================== File lastDirectory; - class ItemComponent; void changeListenerCallback (ChangeBroadcaster*) override; - int getNumRows() override; void paintListBoxItem (int, Graphics&, int, int, bool) override; Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component*) override; @@ -91,6 +89,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileListComponent) }; - - -#endif // JUCE_FILELISTCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h b/source/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h index a1c342b9a..74e99c6e2 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_FilePreviewComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILEPREVIEWCOMPONENT_H_INCLUDED -#define JUCE_FILEPREVIEWCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -60,6 +61,3 @@ private: //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePreviewComponent) }; - - -#endif // JUCE_FILEPREVIEWCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp b/source/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp index 6c9364ef5..0bee475fc 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h b/source/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h index 17d4b9cca..07e39ddf1 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILESEARCHPATHLISTCOMPONENT_H_INCLUDED -#define JUCE_FILESEARCHPATHLISTCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -111,6 +112,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileSearchPathListComponent) }; - - -#endif // JUCE_FILESEARCHPATHLISTCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp b/source/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp index 6565ba461..15bc43a44 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -32,8 +34,8 @@ class FileListTreeItem : public TreeViewItem, { public: FileListTreeItem (FileTreeComponent& treeComp, - DirectoryContentsList* const parentContents, - const int indexInContents, + DirectoryContentsList* parentContents, + int indexInContents, const File& f, TimeSliceThread& t) : file (f), @@ -133,7 +135,7 @@ public: for (int maxRetries = 500; --maxRetries > 0;) { for (int i = 0; i < getNumSubItems(); ++i) - if (FileListTreeItem* f = dynamic_cast (getSubItem (i))) + if (auto* f = dynamic_cast (getSubItem (i))) if (f->selectFile (target)) return true; @@ -181,7 +183,7 @@ public: } owner.getLookAndFeel().drawFileBrowserRow (g, width, height, - file.getFileName(), + file, file.getFileName(), &icon, fileSize, modTime, isDirectory, isSelected(), indexInContentsList, owner); @@ -231,8 +233,8 @@ private: { if (icon.isNull()) { - const int hashCode = (file.getFullPathName() + "_iconCacheSalt").hashCode(); - Image im (ImageCache::getFromHashCode (hashCode)); + auto hashCode = (file.getFullPathName() + "_iconCacheSalt").hashCode(); + auto im = ImageCache::getFromHashCode (hashCode); if (im.isNull() && ! onlyUpdateIfCached) { @@ -271,21 +273,20 @@ void FileTreeComponent::refresh() { deleteRootItem(); - FileListTreeItem* const root - = new FileListTreeItem (*this, nullptr, 0, fileList.getDirectory(), - fileList.getTimeSliceThread()); + auto root = new FileListTreeItem (*this, nullptr, 0, directoryContentsList.getDirectory(), + directoryContentsList.getTimeSliceThread()); - root->setSubContentsList (&fileList, false); + root->setSubContentsList (&directoryContentsList, false); setRootItem (root); } //============================================================================== File FileTreeComponent::getSelectedFile (const int index) const { - if (const FileListTreeItem* const item = dynamic_cast (getSelectedItem (index))) + if (auto* item = dynamic_cast (getSelectedItem (index))) return item->file; - return File(); + return {}; } void FileTreeComponent::deselectAllFiles() @@ -305,7 +306,7 @@ void FileTreeComponent::setDragAndDropDescription (const String& description) void FileTreeComponent::setSelectedFile (const File& target) { - if (FileListTreeItem* t = dynamic_cast (getRootItem())) + if (auto* t = dynamic_cast (getRootItem())) if (! t->selectFile (target)) clearSelectedItems(); } @@ -316,7 +317,7 @@ void FileTreeComponent::setItemHeight (int newHeight) { itemHeight = newHeight; - if (TreeViewItem* root = getRootItem()) + if (auto* root = getRootItem()) root->treeHasChanged(); } } diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h b/source/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h index 7f45f67d7..46d2b2109 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILETREECOMPONENT_H_INCLUDED -#define JUCE_FILETREECOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -99,6 +100,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileTreeComponent) }; - - -#endif // JUCE_FILETREECOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp b/source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp index 6cfc09b70..fee3d6c96 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -124,6 +126,7 @@ void FilenameComponent::buttonClicked (Button*) setCurrentFile (fc.getResult(), true); } #else + ignoreUnused (isSaving); jassertfalse; // needs rewriting to deal with non-modal environments #endif } diff --git a/source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h b/source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h index 0385e9e1e..42c7c9e80 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILENAMECOMPONENT_H_INCLUDED -#define JUCE_FILENAMECOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -228,7 +229,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilenameComponent) }; - - - -#endif // JUCE_FILENAMECOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp b/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp index 1b6265a59..c1d3e699d 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp +++ b/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -63,7 +65,7 @@ void ImagePreviewComponent::timerCallback() ScopedPointer in (fileToLoad.createInputStream()); - if (in != nullptr) + if (in != nullptr && in->getFile().existsAsFile()) { if (ImageFileFormat* const format = ImageFileFormat::findImageFormatForStream (*in)) { diff --git a/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h b/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h index 50347d048..0af35fefd 100644 --- a/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h +++ b/source/modules/juce_gui_basics/filebrowser/juce_ImagePreviewComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IMAGEPREVIEWCOMPONENT_H_INCLUDED -#define JUCE_IMAGEPREVIEWCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -61,6 +62,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImagePreviewComponent) }; - - -#endif // JUCE_IMAGEPREVIEWCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/juce_gui_basics.cpp b/source/modules/juce_gui_basics/juce_gui_basics.cpp index 25d0b80fb..b710d391a 100644 --- a/source/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/source/modules/juce_gui_basics/juce_gui_basics.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,8 +33,6 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #define NS_FORMAT_FUNCTION(F,A) // To avoid spurious warnings from GCC #define JUCE_CORE_INCLUDE_OBJC_HELPERS 1 @@ -76,10 +76,6 @@ #endif #endif - #if JUCE_QUICKTIME && JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES - #pragma comment (lib, "QTMLClient.lib") - #endif - #if JUCE_DIRECT2D && JUCE_MSVC && ! JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES #pragma comment (lib, "Dwrite.lib") #pragma comment (lib, "D2d1.lib") @@ -208,6 +204,7 @@ extern bool juce_areThereAnyAlwaysOnTopWindows(); #include "lookandfeel/juce_LookAndFeel_V2.cpp" #include "lookandfeel/juce_LookAndFeel_V1.cpp" #include "lookandfeel/juce_LookAndFeel_V3.cpp" +#include "lookandfeel/juce_LookAndFeel_V4.cpp" #include "menus/juce_MenuBarComponent.cpp" #include "menus/juce_MenuBarModel.cpp" #include "menus/juce_PopupMenu.cpp" @@ -254,9 +251,10 @@ extern bool juce_areThereAnyAlwaysOnTopWindows(); #include "application/juce_Application.cpp" #include "misc/juce_BubbleComponent.cpp" #include "misc/juce_DropShadower.cpp" +#include "misc/juce_JUCESplashScreen.cpp" // these classes are C++11-only -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS && JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS && JUCE_COMPILER_SUPPORTS_LAMBDAS +#if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS #include "layout/juce_FlexBox.cpp" #endif @@ -266,6 +264,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" @@ -275,6 +278,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" @@ -284,8 +291,9 @@ extern bool juce_areThereAnyAlwaysOnTopWindows(); #include "native/juce_win32_FileChooser.cpp" #elif JUCE_LINUX - #include "native/juce_linux_Clipboard.cpp" - #include "native/juce_linux_Windowing.cpp" + #include "native/juce_linux_X11.cpp" + #include "native/juce_linux_X11_Clipboard.cpp" + #include "native/juce_linux_X11_Windowing.cpp" #include "native/juce_linux_FileChooser.cpp" #elif JUCE_ANDROID diff --git a/source/modules/juce_gui_basics/juce_gui_basics.h b/source/modules/juce_gui_basics/juce_gui_basics.h index f299d9b78..7891b5c32 100644 --- a/source/modules/juce_gui_basics/juce_gui_basics.h +++ b/source/modules/juce_gui_basics/juce_gui_basics.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -33,7 +35,7 @@ ID: juce_gui_basics vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE GUI core classes description: Basic user-interface components and related classes. website: http://www.juce.com/juce @@ -49,7 +51,7 @@ *******************************************************************************/ -#ifndef JUCE_GUI_BASICS_H_INCLUDED +#pragma once #define JUCE_GUI_BASICS_H_INCLUDED #include @@ -120,6 +122,7 @@ class MarkerList; class RelativeRectangle; class MouseEvent; struct MouseWheelDetails; +struct PenDetails; class ToggleButton; class TextButton; class AlertWindow; @@ -175,7 +178,6 @@ class FlexBox; #include "mouse/juce_DragAndDropContainer.h" #include "mouse/juce_FileDragAndDropTarget.h" #include "mouse/juce_SelectedItemSet.h" -#include "mouse/juce_LassoComponent.h" #include "mouse/juce_MouseInactivityDetector.h" #include "mouse/juce_TextDragAndDropTarget.h" #include "mouse/juce_TooltipClient.h" @@ -244,6 +246,7 @@ class FlexBox; #include "widgets/juce_ToolbarItemPalette.h" #include "buttons/juce_ToolbarButton.h" #include "misc/juce_DropShadower.h" +#include "misc/juce_JUCESplashScreen.h" #include "widgets/juce_TreeView.h" #include "windows/juce_TopLevelWindow.h" #include "windows/juce_AlertWindow.h" @@ -281,13 +284,17 @@ class FlexBox; #include "lookandfeel/juce_LookAndFeel_V2.h" #include "lookandfeel/juce_LookAndFeel_V1.h" #include "lookandfeel/juce_LookAndFeel_V3.h" +#include "lookandfeel/juce_LookAndFeel_V4.h" +#include "mouse/juce_LassoComponent.h" + +#if JUCE_LINUX + #include "native/juce_linux_X11.h" +#endif // these classes are C++11-only -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS && JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS && JUCE_COMPILER_SUPPORTS_LAMBDAS +#if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS #include "layout/juce_FlexItem.h" #include "layout/juce_FlexBox.h" #endif } - -#endif // JUCE_GUI_BASICS_H_INCLUDED diff --git a/source/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp b/source/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp index 5cc596650..fce9c35bc 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp +++ b/source/modules/juce_gui_basics/keyboard/juce_CaretComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/keyboard/juce_CaretComponent.h b/source/modules/juce_gui_basics/keyboard/juce_CaretComponent.h index 4c4077f48..acee48a28 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_CaretComponent.h +++ b/source/modules/juce_gui_basics/keyboard/juce_CaretComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CARETCOMPONENT_H_INCLUDED -#define JUCE_CARETCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -75,6 +76,3 @@ private: JUCE_DECLARE_NON_COPYABLE (CaretComponent) }; - - -#endif // JUCE_CARETCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp b/source/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp index 5ad902501..38e9de545 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp +++ b/source/modules/juce_gui_basics/keyboard/juce_KeyListener.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/keyboard/juce_KeyListener.h b/source/modules/juce_gui_basics/keyboard/juce_KeyListener.h index 15a966d05..1dc7b10cb 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_KeyListener.h +++ b/source/modules/juce_gui_basics/keyboard/juce_KeyListener.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_KEYLISTENER_H_INCLUDED -#define JUCE_KEYLISTENER_H_INCLUDED +#pragma once //============================================================================== @@ -71,6 +72,3 @@ public: */ virtual bool keyStateChanged (bool isKeyDown, Component* originatingComponent); }; - - -#endif // JUCE_KEYLISTENER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp b/source/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp index 22fc2c249..8f407972b 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp +++ b/source/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -150,7 +152,7 @@ namespace KeyPressHelpers { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - return (int) (KeyPress::numberPad0 + lastChar - '0'); + return (int) (KeyPress::numberPad0 + (int) lastChar - '0'); case '+': return KeyPress::numberPadAdd; case '-': return KeyPress::numberPadSubtract; diff --git a/source/modules/juce_gui_basics/keyboard/juce_KeyPress.h b/source/modules/juce_gui_basics/keyboard/juce_KeyPress.h index 938230e47..420a869fb 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_KeyPress.h +++ b/source/modules/juce_gui_basics/keyboard/juce_KeyPress.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_KEYPRESS_H_INCLUDED -#define JUCE_KEYPRESS_H_INCLUDED +#pragma once //============================================================================== @@ -249,6 +250,3 @@ private: JUCE_LEAK_DETECTOR (KeyPress) }; - - -#endif // JUCE_KEYPRESS_H_INCLUDED diff --git a/source/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp b/source/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp index 56306671f..13afbd402 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp +++ b/source/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -28,46 +30,40 @@ namespace KeyboardFocusHelpers // left-to-right and then top-to-bottom. struct ScreenPositionComparator { - static int compareElements (const Component* const first, const Component* const second) + static int compareElements (const Component* first, const Component* second) { - const int explicitOrder1 = getOrder (first); - const int explicitOrder2 = getOrder (second); + auto explicitOrder1 = getOrder (first); + auto explicitOrder2 = getOrder (second); if (explicitOrder1 != explicitOrder2) return explicitOrder1 - explicitOrder2; - const int yDiff = first->getY() - second->getY(); + auto yDiff = first->getY() - second->getY(); return yDiff == 0 ? first->getX() - second->getX() : yDiff; } - static int getOrder (const Component* const c) + static int getOrder (const Component* c) { - const int order = c->getExplicitFocusOrder(); + auto order = c->getExplicitFocusOrder(); return order > 0 ? order : (std::numeric_limits::max() / 2); } }; - static void findAllFocusableComponents (Component* const parent, Array & comps) + static void findAllFocusableComponents (Component* parent, Array& comps) { - if (parent->getNumChildComponents() > 0) + if (parent->getNumChildComponents() != 0) { - Array localComps; + Array localComps; ScreenPositionComparator comparator; - for (int i = parent->getNumChildComponents(); --i >= 0;) - { - Component* const c = parent->getChildComponent (i); - + for (auto* c : parent->getChildren()) if (c->isVisible() && c->isEnabled()) localComps.addSorted (comparator, c); - } - for (int i = 0; i < localComps.size(); ++i) + for (auto* c : localComps) { - Component* const c = localComps.getUnchecked (i); - if (c->getWantsKeyboardFocus()) comps.add (c); @@ -88,18 +84,16 @@ namespace KeyboardFocusHelpers return c; } - static Component* getIncrementedComponent (Component* const current, const int delta) + static Component* getIncrementedComponent (Component* current, int delta) { - Component* focusContainer = findFocusContainer (current); - - if (focusContainer != nullptr) + if (auto* focusContainer = findFocusContainer (current)) { - Array comps; + Array comps; KeyboardFocusHelpers::findAllFocusableComponents (focusContainer, comps); - if (comps.size() > 0) + if (! comps.isEmpty()) { - const int index = comps.indexOf (current); + auto index = comps.indexOf (current); return comps [(index + comps.size() + delta) % comps.size()]; } } @@ -126,7 +120,7 @@ Component* KeyboardFocusTraverser::getPreviousComponent (Component* current) Component* KeyboardFocusTraverser::getDefaultComponent (Component* parentComponent) { - Array comps; + Array comps; if (parentComponent != nullptr) KeyboardFocusHelpers::findAllFocusableComponents (parentComponent, comps); diff --git a/source/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h b/source/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h index c1ece1e60..856677cc7 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h +++ b/source/modules/juce_gui_basics/keyboard/juce_KeyboardFocusTraverser.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_KEYBOARDFOCUSTRAVERSER_H_INCLUDED -#define JUCE_KEYBOARDFOCUSTRAVERSER_H_INCLUDED +#pragma once //============================================================================== @@ -84,6 +85,3 @@ public: */ virtual Component* getDefaultComponent (Component* parentComponent); }; - - -#endif // JUCE_KEYBOARDFOCUSTRAVERSER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp b/source/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp index 37a33b812..7fbb58742 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp +++ b/source/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h b/source/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h index c44d77b3c..3337b9adb 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h +++ b/source/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MODIFIERKEYS_H_INCLUDED -#define JUCE_MODIFIERKEYS_H_INCLUDED +#pragma once //============================================================================== @@ -218,6 +219,3 @@ private: static ModifierKeys currentModifiers; static void updateCurrentModifiers() noexcept; }; - - -#endif // JUCE_MODIFIERKEYS_H_INCLUDED diff --git a/source/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h b/source/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h index d21b78ef5..dbe6bdabd 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h +++ b/source/modules/juce_gui_basics/keyboard/juce_SystemClipboard.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SYSTEMCLIPBOARD_H_INCLUDED -#define JUCE_SYSTEMCLIPBOARD_H_INCLUDED +#pragma once //============================================================================== @@ -43,5 +44,3 @@ public: */ static String getTextFromClipboard(); }; - -#endif // JUCE_SYSTEMCLIPBOARD_H_INCLUDED diff --git a/source/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h b/source/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h index 5f1da8261..e8fd74f96 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h +++ b/source/modules/juce_gui_basics/keyboard/juce_TextEditorKeyMapper.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TEXTEDITORKEYMAPPER_H_INCLUDED -#define JUCE_TEXTEDITORKEYMAPPER_H_INCLUDED +#pragma once //============================================================================== @@ -117,6 +118,3 @@ struct TextEditorKeyMapper return false; } }; - - -#endif // JUCE_TEXTEDITORKEYMAPPER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h b/source/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h index 9021fb625..e63a84a61 100644 --- a/source/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h +++ b/source/modules/juce_gui_basics/keyboard/juce_TextInputTarget.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TEXTINPUTTARGET_H_INCLUDED -#define JUCE_TEXTINPUTTARGET_H_INCLUDED +#pragma once //============================================================================== @@ -90,6 +91,3 @@ public: */ virtual VirtualKeyboardType getKeyboardType() { return textKeyboard; } }; - - -#endif // JUCE_TEXTINPUTTARGET_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_AnimatedPosition.h b/source/modules/juce_gui_basics/layout/juce_AnimatedPosition.h index 60c25019b..7f75916fd 100644 --- a/source/modules/juce_gui_basics/layout/juce_AnimatedPosition.h +++ b/source/modules/juce_gui_basics/layout/juce_AnimatedPosition.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ANIMATEDPOSITION_H_INCLUDED -#define JUCE_ANIMATEDPOSITION_H_INCLUDED +#pragma once //============================================================================== @@ -59,7 +60,7 @@ public: } /** Sets a range within which the value will be constrained. */ - void setLimits (Range newRange) + void setLimits (Range newRange) noexcept { range = newRange; } @@ -204,6 +205,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnimatedPosition) }; - - -#endif // JUCE_ANIMATEDPOSITION_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h b/source/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h index fafdeaa94..e29bc73cc 100644 --- a/source/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h +++ b/source/modules/juce_gui_basics/layout/juce_AnimatedPositionBehaviours.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ANIMATEDPOSITIONBEHAVIOURS_H_INCLUDED -#define JUCE_ANIMATEDPOSITIONBEHAVIOURS_H_INCLUDED +#pragma once //============================================================================== @@ -44,7 +45,6 @@ namespace AnimatedPositionBehaviours struct ContinuousWithMomentum { ContinuousWithMomentum() noexcept - : velocity (0), damping (0.92) { } @@ -83,11 +83,11 @@ namespace AnimatedPositionBehaviours */ bool isStopped (double /*position*/) const noexcept { - return velocity == 0; + return velocity == 0.0; } private: - double velocity, damping; + double velocity = 0, damping = 0.92; }; //============================================================================== @@ -146,6 +146,3 @@ namespace AnimatedPositionBehaviours double targetSnapPosition; }; } - - -#endif // JUCE_ANIMATEDPOSITIONBEHAVIOURS_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp b/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp index d2929f805..d322f4ae9 100644 --- a/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp +++ b/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -27,6 +29,11 @@ class ComponentAnimator::AnimationTask public: AnimationTask (Component* c) noexcept : component (c) {} + ~AnimationTask() + { + masterReference.clear(); + } + void reset (const Rectangle& finalBounds, float finalAlpha, int millisecondsToSpendMoving, @@ -63,14 +70,15 @@ public: bool useTimeslice (const int elapsed) { - if (Component* const c = proxy != nullptr ? static_cast (proxy) - : static_cast (component)) + if (auto* c = proxy != nullptr ? static_cast (proxy) + : static_cast (component)) { msElapsed += elapsed; double newProgress = msElapsed / (double) msTotal; if (newProgress >= 0 && newProgress < 1.0) { + const WeakReference weakRef (this); newProgress = timeToDistance (newProgress); const double delta = (newProgress - lastProgress) / (1.0 - lastProgress); jassert (newProgress >= lastProgress); @@ -99,6 +107,11 @@ public: } } + // Check whether the animation was cancelled/deleted during + // a callback during the setBounds method + if (weakRef.wasObjectDeleted()) + return false; + if (isChangingAlpha) { alpha += (destAlpha - alpha) * delta; @@ -120,18 +133,19 @@ public: { if (component != nullptr) { + const WeakReference weakRef (this); component->setAlpha ((float) destAlpha); component->setBounds (destination); - if (proxy != nullptr) - component->setVisible (destAlpha > 0); + if (! weakRef.wasObjectDeleted()) + if (proxy != nullptr) + component->setVisible (destAlpha > 0); } } //============================================================================== - class ProxyComponent : public Component + struct ProxyComponent : public Component { - public: ProxyComponent (Component& c) { setWantsKeyboardFocus (false); @@ -140,15 +154,15 @@ public: setAlpha (c.getAlpha()); setInterceptsMouseClicks (false, false); - if (Component* const parent = c.getParentComponent()) + if (auto* parent = c.getParentComponent()) parent->addAndMakeVisible (this); else if (c.isOnDesktop() && c.getPeer() != nullptr) addToDesktop (c.getPeer()->getStyleFlags() | ComponentPeer::windowIgnoresKeyPresses); else jassertfalse; // seem to be trying to animate a component that's not visible.. - const float scale = (float) Desktop::getInstance().getDisplays() - .getDisplayContaining (getScreenBounds().getCentre()).scale; + auto scale = (float) Desktop::getInstance().getDisplays() + .getDisplayContaining (getScreenBounds().getCentre()).scale; image = c.createComponentSnapshot (c.getLocalBounds(), false, scale); @@ -169,6 +183,9 @@ public: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProxyComponent) }; + WeakReference::Master masterReference; + friend class WeakReference; + WeakReference component; ScopedPointer proxy; @@ -187,6 +204,8 @@ private: : 0.5 * (startSpeed + 0.5 * (midSpeed - startSpeed)) + (time - 0.5) * (midSpeed + (time - 0.5) * (endSpeed - midSpeed)); } + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnimationTask) }; //============================================================================== @@ -216,7 +235,7 @@ void ComponentAnimator::animateComponent (Component* const component, if (component != nullptr) { - AnimationTask* at = findTaskFor (component); + auto* at = findTaskFor (component); if (at == nullptr) { @@ -273,7 +292,7 @@ void ComponentAnimator::cancelAllAnimations (const bool moveComponentsToTheirFin void ComponentAnimator::cancelAnimation (Component* const component, const bool moveComponentToItsFinalPosition) { - if (AnimationTask* const at = findTaskFor (component)) + if (auto* at = findTaskFor (component)) { if (moveComponentToItsFinalPosition) at->moveToFinalDestination(); @@ -287,7 +306,7 @@ Rectangle ComponentAnimator::getComponentDestination (Component* const comp { jassert (component != nullptr); - if (AnimationTask* const at = findTaskFor (component)) + if (auto* at = findTaskFor (component)) return at->destination; return component->getBounds(); @@ -305,18 +324,18 @@ bool ComponentAnimator::isAnimating() const noexcept void ComponentAnimator::timerCallback() { - const uint32 timeNow = Time::getMillisecondCounter(); + auto timeNow = Time::getMillisecondCounter(); - if (lastTime == 0 || lastTime == timeNow) + if (lastTime == 0) lastTime = timeNow; - const int elapsed = (int) (timeNow - lastTime); + auto elapsed = (int) (timeNow - lastTime); - for (int i = tasks.size(); --i >= 0;) + for (auto* task : Array (tasks.begin(), tasks.size())) { - if (! tasks.getUnchecked(i)->useTimeslice (elapsed)) + if (tasks.contains (task) && ! task->useTimeslice (elapsed)) { - tasks.remove (i); + tasks.removeObject (task); sendChangeMessage(); } } diff --git a/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.h b/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.h index 0b573e1e5..5a9441b7c 100644 --- a/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.h +++ b/source/modules/juce_gui_basics/layout/juce_ComponentAnimator.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMPONENTANIMATOR_H_INCLUDED -#define JUCE_COMPONENTANIMATOR_H_INCLUDED +#pragma once //============================================================================== @@ -156,6 +157,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentAnimator) }; - - -#endif // JUCE_COMPONENTANIMATOR_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp b/source/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp index e012e8510..b34240c57 100644 --- a/source/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp +++ b/source/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.cpp @@ -2,48 +2,38 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -ComponentBoundsConstrainer::ComponentBoundsConstrainer() noexcept - : minW (0), maxW (0x3fffffff), - minH (0), maxH (0x3fffffff), - minOffTop (0), - minOffLeft (0), - minOffBottom (0), - minOffRight (0), - aspectRatio (0.0) -{ -} - -ComponentBoundsConstrainer::~ComponentBoundsConstrainer() -{ -} +ComponentBoundsConstrainer::ComponentBoundsConstrainer() noexcept {} +ComponentBoundsConstrainer::~ComponentBoundsConstrainer() {} //============================================================================== -void ComponentBoundsConstrainer::setMinimumWidth (const int minimumWidth) noexcept { minW = minimumWidth; } -void ComponentBoundsConstrainer::setMaximumWidth (const int maximumWidth) noexcept { maxW = maximumWidth; } -void ComponentBoundsConstrainer::setMinimumHeight (const int minimumHeight) noexcept { minH = minimumHeight; } -void ComponentBoundsConstrainer::setMaximumHeight (const int maximumHeight) noexcept { maxH = maximumHeight; } +void ComponentBoundsConstrainer::setMinimumWidth (int minimumWidth) noexcept { minW = minimumWidth; } +void ComponentBoundsConstrainer::setMaximumWidth (int maximumWidth) noexcept { maxW = maximumWidth; } +void ComponentBoundsConstrainer::setMinimumHeight (int minimumHeight) noexcept { minH = minimumHeight; } +void ComponentBoundsConstrainer::setMaximumHeight (int maximumHeight) noexcept { maxH = maximumHeight; } -void ComponentBoundsConstrainer::setMinimumSize (const int minimumWidth, const int minimumHeight) noexcept +void ComponentBoundsConstrainer::setMinimumSize (int minimumWidth, int minimumHeight) noexcept { jassert (maxW >= minimumWidth); jassert (maxH >= minimumHeight); @@ -56,7 +46,7 @@ void ComponentBoundsConstrainer::setMinimumSize (const int minimumWidth, const i if (minH > maxH) maxH = minH; } -void ComponentBoundsConstrainer::setMaximumSize (const int maximumWidth, const int maximumHeight) noexcept +void ComponentBoundsConstrainer::setMaximumSize (int maximumWidth, int maximumHeight) noexcept { jassert (maximumWidth >= minW); jassert (maximumHeight >= minH); @@ -66,10 +56,10 @@ void ComponentBoundsConstrainer::setMaximumSize (const int maximumWidth, const i maxH = jmax (minH, maximumHeight); } -void ComponentBoundsConstrainer::setSizeLimits (const int minimumWidth, - const int minimumHeight, - const int maximumWidth, - const int maximumHeight) noexcept +void ComponentBoundsConstrainer::setSizeLimits (int minimumWidth, + int minimumHeight, + int maximumWidth, + int maximumHeight) noexcept { jassert (maximumWidth >= minimumWidth); jassert (maximumHeight >= minimumHeight); @@ -82,10 +72,10 @@ void ComponentBoundsConstrainer::setSizeLimits (const int minimumWidth, maxH = jmax (minH, maximumHeight); } -void ComponentBoundsConstrainer::setMinimumOnscreenAmounts (const int minimumWhenOffTheTop, - const int minimumWhenOffTheLeft, - const int minimumWhenOffTheBottom, - const int minimumWhenOffTheRight) noexcept +void ComponentBoundsConstrainer::setMinimumOnscreenAmounts (int minimumWhenOffTheTop, + int minimumWhenOffTheLeft, + int minimumWhenOffTheBottom, + int minimumWhenOffTheRight) noexcept { minOffTop = minimumWhenOffTheTop; minOffLeft = minimumWhenOffTheLeft; @@ -93,7 +83,7 @@ void ComponentBoundsConstrainer::setMinimumOnscreenAmounts (const int minimumWhe minOffRight = minimumWhenOffTheRight; } -void ComponentBoundsConstrainer::setFixedAspectRatio (const double widthOverHeight) noexcept +void ComponentBoundsConstrainer::setFixedAspectRatio (double widthOverHeight) noexcept { aspectRatio = jmax (0.0, widthOverHeight); } @@ -103,28 +93,30 @@ double ComponentBoundsConstrainer::getFixedAspectRatio() const noexcept return aspectRatio; } -void ComponentBoundsConstrainer::setBoundsForComponent (Component* const component, - const Rectangle& targetBounds, - const bool isStretchingTop, - const bool isStretchingLeft, - const bool isStretchingBottom, - const bool isStretchingRight) +void ComponentBoundsConstrainer::setBoundsForComponent (Component* component, + Rectangle targetBounds, + bool isStretchingTop, + bool isStretchingLeft, + bool isStretchingBottom, + bool isStretchingRight) { jassert (component != nullptr); Rectangle limits, bounds (targetBounds); BorderSize border; - if (Component* const parent = component->getParentComponent()) + if (auto* parent = component->getParentComponent()) { limits.setSize (parent->getWidth(), parent->getHeight()); } else { - if (ComponentPeer* const peer = component->getPeer()) + if (auto* peer = component->getPeer()) border = peer->getFrameSize(); - limits = Desktop::getInstance().getDisplays().getDisplayContaining (bounds.getCentre()).userArea; + auto screenBounds = Desktop::getInstance().getDisplays().getDisplayContaining (targetBounds.getCentre()).userArea; + + limits = component->getLocalArea (nullptr, screenBounds) + component->getPosition(); } border.addTo (bounds); @@ -136,7 +128,7 @@ void ComponentBoundsConstrainer::setBoundsForComponent (Component* const compone border.subtractFrom (bounds); - applyBoundsToComponent (component, bounds); + applyBoundsToComponent (*component, bounds); } void ComponentBoundsConstrainer::checkComponentBounds (Component* component) @@ -145,13 +137,12 @@ void ComponentBoundsConstrainer::checkComponentBounds (Component* component) false, false, false, false); } -void ComponentBoundsConstrainer::applyBoundsToComponent (Component* component, - const Rectangle& bounds) +void ComponentBoundsConstrainer::applyBoundsToComponent (Component& component, Rectangle bounds) { - if (Component::Positioner* const positioner = component->getPositioner()) + if (auto* positioner = component.getPositioner()) positioner->applyNewBounds (bounds); else - component->setBounds (bounds); + component.setBounds (bounds); } //============================================================================== @@ -167,10 +158,10 @@ void ComponentBoundsConstrainer::resizeEnd() void ComponentBoundsConstrainer::checkBounds (Rectangle& bounds, const Rectangle& old, const Rectangle& limits, - const bool isStretchingTop, - const bool isStretchingLeft, - const bool isStretchingBottom, - const bool isStretchingRight) + bool isStretchingTop, + bool isStretchingLeft, + bool isStretchingBottom, + bool isStretchingRight) { if (isStretchingLeft) bounds.setLeft (jlimit (old.getRight() - maxW, old.getRight() - minW, bounds.getX())); diff --git a/source/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h b/source/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h index 0031e41ed..e9d0a9493 100644 --- a/source/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h +++ b/source/modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMPONENTBOUNDSCONSTRAINER_H_INCLUDED -#define JUCE_COMPONENTBOUNDSCONSTRAINER_H_INCLUDED +#pragma once //============================================================================== @@ -164,7 +165,7 @@ public: /** Checks the given bounds, and then sets the component to the corrected size. */ void setBoundsForComponent (Component* component, - const Rectangle& bounds, + Rectangle bounds, bool isStretchingTop, bool isStretchingLeft, bool isStretchingBottom, @@ -181,17 +182,13 @@ public: By default this just calls setBounds(), but is virtual in case it's needed for extremely cunning purposes. */ - virtual void applyBoundsToComponent (Component* component, - const Rectangle& bounds); + virtual void applyBoundsToComponent (Component&, Rectangle bounds); private: //============================================================================== - int minW, maxW, minH, maxH; - int minOffTop, minOffLeft, minOffBottom, minOffRight; - double aspectRatio; + int minW = 0, maxW = 0x3fffffff, minH = 0, maxH = 0x3fffffff; + int minOffTop = 0, minOffLeft = 0, minOffBottom = 0, minOffRight = 0; + double aspectRatio = 0; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentBoundsConstrainer) }; - - -#endif // JUCE_COMPONENTBOUNDSCONSTRAINER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp b/source/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp index 157d9e5e9..bd5b6c52d 100644 --- a/source/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp +++ b/source/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -50,9 +52,9 @@ namespace ComponentBuilderHelpers if (c.getComponentID() == compId) return &c; - for (int i = c.getNumChildComponents(); --i >= 0;) - if (Component* const child = findComponentWithID (*c.getChildComponent (i), compId)) - return child; + for (auto* child : c.getChildren()) + if (auto* found = findComponentWithID (*child, compId)) + return found; return nullptr; } @@ -236,7 +238,7 @@ void ComponentBuilder::updateChildComponents (Component& parent, const ValueTree { using namespace ComponentBuilderHelpers; - const int numExistingChildComps = parent.getNumChildComponents(); + auto numExistingChildComps = parent.getNumChildComponents(); Array componentsInOrder; componentsInOrder.ensureStorageAllocated (numExistingChildComps); @@ -248,15 +250,16 @@ void ComponentBuilder::updateChildComponents (Component& parent, const ValueTree for (int i = 0; i < numExistingChildComps; ++i) existingComponents.add (parent.getChildComponent (i)); - const int newNumChildren = children.getNumChildren(); + auto newNumChildren = children.getNumChildren(); + for (int i = 0; i < newNumChildren; ++i) { - const ValueTree childState (children.getChild (i)); - Component* c = removeComponentWithID (existingComponents, getStateId (childState)); + auto childState = children.getChild (i); + auto* c = removeComponentWithID (existingComponents, getStateId (childState)); if (c == nullptr) { - if (TypeHandler* const type = getHandlerForState (childState)) + if (auto* type = getHandlerForState (childState)) c = ComponentBuilderHelpers::createNewComponent (*type, childState, &parent); else jassertfalse; diff --git a/source/modules/juce_gui_basics/layout/juce_ComponentBuilder.h b/source/modules/juce_gui_basics/layout/juce_ComponentBuilder.h index 0b5868409..fc389b68a 100644 --- a/source/modules/juce_gui_basics/layout/juce_ComponentBuilder.h +++ b/source/modules/juce_gui_basics/layout/juce_ComponentBuilder.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMPONENTBUILDER_H_INCLUDED -#define JUCE_COMPONENTBUILDER_H_INCLUDED +#pragma once //============================================================================== @@ -241,5 +242,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentBuilder) }; - -#endif // JUCE_COMPONENTBUILDER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp b/source/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp index 32e8a0c21..c42f004b3 100644 --- a/source/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp +++ b/source/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h b/source/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h index 8c91598c2..0a1c55bd9 100644 --- a/source/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h +++ b/source/modules/juce_gui_basics/layout/juce_ComponentMovementWatcher.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMPONENTMOVEMENTWATCHER_H_INCLUDED -#define JUCE_COMPONENTMOVEMENTWATCHER_H_INCLUDED +#pragma once //============================================================================== @@ -37,7 +38,7 @@ It also includes a callback that lets you know when the top-level peer is changed. - This class is used by specialised components like WebBrowserComponent or QuickTimeComponent + This class is used by specialised components like WebBrowserComponent because they need to keep their custom windows in the right place and respond to changes in the peer. */ @@ -90,6 +91,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentMovementWatcher) }; - - -#endif // JUCE_COMPONENTMOVEMENTWATCHER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp b/source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp index a6358cf3f..175699812 100644 --- a/source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp +++ b/source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -219,16 +221,25 @@ public: void paint (Graphics& g) override { - const Rectangle area (getWidth(), getHeaderSize()); - g.reduceClipRegion (area); + if (customHeaderComponent == nullptr) + { + const Rectangle area (getWidth(), getHeaderSize()); + g.reduceClipRegion (area); - getLookAndFeel().drawConcertinaPanelHeader (g, area, isMouseOver(), isMouseButtonDown(), - getPanel(), *component); + getLookAndFeel().drawConcertinaPanelHeader (g, area, isMouseOver(), isMouseButtonDown(), + getPanel(), *component); + } } void resized() override { - component->setBounds (getLocalBounds().withTop (getHeaderSize())); + auto bounds = getLocalBounds(); + auto headerBounds = bounds.removeFromTop (getHeaderSize()); + + if (customHeaderComponent != nullptr) + customHeaderComponent->setBounds (headerBounds); + + component->setBounds (bounds); } void mouseDown (const MouseEvent&) override @@ -250,11 +261,23 @@ public: getPanel().panelHeaderDoubleClicked (component); } + void setCustomHeaderComponent (Component* headerComponent, bool shouldTakeOwnership) + { + customHeaderComponent.set (headerComponent, shouldTakeOwnership); + + if (headerComponent != nullptr) + { + addAndMakeVisible (customHeaderComponent); + customHeaderComponent->addMouseListener (this, false); + } + } + OptionalScopedPointer component; private: PanelSizes dragStartSizes; int mouseDownY; + OptionalScopedPointer customHeaderComponent; int getHeaderSize() const noexcept { @@ -349,16 +372,30 @@ void ConcertinaPanel::setMaximumPanelSize (Component* component, int maximumSize void ConcertinaPanel::setPanelHeaderSize (Component* component, int headerSize) { - const int index = indexOfComp (component); + const auto index = indexOfComp (component); jassert (index >= 0); // The specified component doesn't seem to have been added! if (index >= 0) { - currentSizes->get(index).minSize = headerSize; + auto oldMin = currentSizes->get (index).minSize; + + currentSizes->get (index).minSize = headerSize; + currentSizes->get (index).size += headerSize - oldMin; resized(); } } +void ConcertinaPanel::setCustomPanelHeader (Component* component, Component* customComponent, bool takeOwnership) +{ + OptionalScopedPointer optional (customComponent, takeOwnership); + + const auto index = indexOfComp (component); + jassert (index >= 0); // The specified component doesn't seem to have been added! + + if (index >= 0) + holders.getUnchecked (index)->setCustomHeaderComponent (optional.release(), takeOwnership); +} + void ConcertinaPanel::resized() { applyLayout (getFittedSizes(), false); diff --git a/source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h b/source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h index 33f60d455..4670fd2ed 100644 --- a/source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h +++ b/source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CONCERTINAPANEL_H_INCLUDED -#define JUCE_CONCERTINAPANEL_H_INCLUDED +#pragma once //============================================================================== @@ -93,6 +94,19 @@ public: /** Sets the height of the header section for one of the panels. */ void setPanelHeaderSize (Component* panelComponent, int headerSize); + /** Sets a custom header Component for one of the panels. + + @param panelComponent the panel component to add the custom header to. + @param customHeaderComponent the custom component to use for the panel header. + This can be nullptr to clear the custom header component + and just use the standard LookAndFeel panel. + @param takeOwnership if true, then the PanelHolder will take ownership + of the custom header component, and will delete it later when + it's no longer needed. If false, it won't delete it, and + you must make sure it doesn't get deleted while in use. + */ + void setCustomPanelHeader (Component* panelComponent, Component* customHeaderComponent, bool takeOwnership); + //============================================================================== /** This abstract base class is implemented by LookAndFeel classes. */ struct JUCE_API LookAndFeelMethods @@ -127,6 +141,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ConcertinaPanel) }; - - -#endif // JUCE_CONCERTINAPANEL_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_FlexBox.cpp b/source/modules/juce_gui_basics/layout/juce_FlexBox.cpp index 5c8919023..bdaaea806 100644 --- a/source/modules/juce_gui_basics/layout/juce_FlexBox.cpp +++ b/source/modules/juce_gui_basics/layout/juce_FlexBox.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -588,12 +590,12 @@ private: if (positiveFlexibility) { - if (totalFlexGrow != 0) + if (totalFlexGrow != 0.0) changeUnit = difference / totalFlexGrow; } else { - if (totalFlexShrink != 0) + if (totalFlexShrink != 0.0) changeUnit = difference / totalFlexShrink; } @@ -785,7 +787,13 @@ void FlexBox::performLayout (Rectangle targetArea) item.currentBounds += targetArea.getPosition(); if (auto comp = item.associatedComponent) - comp->setBounds (item.currentBounds.getSmallestIntegerContainer()); + { + auto position = item.currentBounds.getPosition().roundToInt(); + comp->setBounds (position.getX(), + position.getY(), + roundToInt (item.currentBounds.getRight()) - position.getX(), + roundToInt (item.currentBounds.getBottom()) - position.getY()); + } if (auto box = item.associatedFlexBox) box->performLayout (item.currentBounds); diff --git a/source/modules/juce_gui_basics/layout/juce_FlexBox.h b/source/modules/juce_gui_basics/layout/juce_FlexBox.h index 7057192d3..35b26e9fd 100644 --- a/source/modules/juce_gui_basics/layout/juce_FlexBox.h +++ b/source/modules/juce_gui_basics/layout/juce_FlexBox.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_FlexItem.h b/source/modules/juce_gui_basics/layout/juce_FlexItem.h index 0877c2474..3565c9899 100644 --- a/source/modules/juce_gui_basics/layout/juce_FlexItem.h +++ b/source/modules/juce_gui_basics/layout/juce_FlexItem.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_GroupComponent.cpp b/source/modules/juce_gui_basics/layout/juce_GroupComponent.cpp index 7f9e5e9d2..172d3d7ef 100644 --- a/source/modules/juce_gui_basics/layout/juce_GroupComponent.cpp +++ b/source/modules/juce_gui_basics/layout/juce_GroupComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_GroupComponent.h b/source/modules/juce_gui_basics/layout/juce_GroupComponent.h index 8ad22e939..f8f3a2f05 100644 --- a/source/modules/juce_gui_basics/layout/juce_GroupComponent.h +++ b/source/modules/juce_gui_basics/layout/juce_GroupComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_GROUPCOMPONENT_H_INCLUDED -#define JUCE_GROUPCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -106,6 +107,3 @@ private: JUCE_DECLARE_NON_COPYABLE (GroupComponent) }; - - -#endif // JUCE_GROUPCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp b/source/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp index b81a3f1a7..65c745420 100644 --- a/source/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp +++ b/source/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -141,7 +143,7 @@ void MultiDocumentPanel::addWindow (Component* component) int x = 4; - if (Component* const topComp = getChildComponent (getNumChildComponents() - 1)) + if (auto* topComp = getChildren().getLast()) if (topComp->getX() == x && topComp->getY() == x) x += 16; @@ -198,7 +200,7 @@ bool MultiDocumentPanel::addDocument (Component* const component, { addAndMakeVisible (tabComponent = new TabbedComponentInternal()); - Array temp (components); + Array temp (components); for (int i = 0; i < temp.size(); ++i) tabComponent->addTab (temp[i]->getName(), docColour, temp[i], false); @@ -237,9 +239,9 @@ bool MultiDocumentPanel::closeDocument (Component* component, if (mode == FloatingWindows) { - for (int i = getNumChildComponents(); --i >= 0;) + for (auto* child : getChildren()) { - if (MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i))) + if (auto* dw = dynamic_cast (child)) { if (dw->getContentComponent() == component) { @@ -324,8 +326,8 @@ Component* MultiDocumentPanel::getActiveDocument() const noexcept { if (mode == FloatingWindows) { - for (int i = getNumChildComponents(); --i >= 0;) - if (MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i))) + for (auto* child : getChildren()) + if (auto* dw = dynamic_cast (child)) if (dw->isActiveWindow()) return dw->getContentComponent(); } @@ -409,7 +411,7 @@ void MultiDocumentPanel::setLayoutMode (const LayoutMode newLayoutMode) resized(); - const Array tempComps (components); + const Array tempComps (components); components.clear(); for (int i = 0; i < tempComps.size(); ++i) @@ -443,8 +445,8 @@ void MultiDocumentPanel::resized() { if (mode == MaximisedWindowsWithTabs || components.size() == numDocsBeforeTabsUsed) { - for (int i = getNumChildComponents(); --i >= 0;) - getChildComponent (i)->setBounds (getLocalBounds()); + for (auto* child : getChildren()) + child->setBounds (getLocalBounds()); } setWantsKeyboardFocus (components.size() == 0); @@ -454,8 +456,8 @@ Component* MultiDocumentPanel::getContainerComp (Component* c) const { if (mode == FloatingWindows) { - for (int i = 0; i < getNumChildComponents(); ++i) - if (MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i))) + for (auto* child : getChildren()) + if (auto* dw = dynamic_cast (child)) if (dw->getContentComponent() == c) return dw; } @@ -467,8 +469,8 @@ void MultiDocumentPanel::componentNameChanged (Component&) { if (mode == FloatingWindows) { - for (int i = 0; i < getNumChildComponents(); ++i) - if (MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i))) + for (auto* child : getChildren()) + if (auto* dw = dynamic_cast (child)) dw->setName (dw->getContentComponent()->getName()); } else if (tabComponent != nullptr) @@ -480,21 +482,21 @@ void MultiDocumentPanel::componentNameChanged (Component&) void MultiDocumentPanel::updateOrder() { - const Array oldList (components); + auto oldList = components; if (mode == FloatingWindows) { components.clear(); - for (int i = 0; i < getNumChildComponents(); ++i) - if (MultiDocumentPanelWindow* const dw = dynamic_cast (getChildComponent (i))) + for (auto* child : getChildren()) + if (auto* dw = dynamic_cast (child)) components.add (dw->getContentComponent()); } else { if (tabComponent != nullptr) { - if (Component* const current = tabComponent->getCurrentContentComponent()) + if (auto* current = tabComponent->getCurrentContentComponent()) { components.removeFirstMatchingValue (current); components.add (current); diff --git a/source/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h b/source/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h index e6e6311a4..b55f3de30 100644 --- a/source/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h +++ b/source/modules/juce_gui_basics/layout/juce_MultiDocumentPanel.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MULTIDOCUMENTPANEL_H_INCLUDED -#define JUCE_MULTIDOCUMENTPANEL_H_INCLUDED +#pragma once class MultiDocumentPanel; @@ -299,6 +300,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiDocumentPanel) }; - - -#endif // JUCE_MULTIDOCUMENTPANEL_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp b/source/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp index 7653f8b81..ee4b1ee6b 100644 --- a/source/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp +++ b/source/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h b/source/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h index ffafc987a..612fd26eb 100644 --- a/source/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h +++ b/source/modules/juce_gui_basics/layout/juce_ResizableBorderComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RESIZABLEBORDERCOMPONENT_H_INCLUDED -#define JUCE_RESIZABLEBORDERCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -190,6 +191,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResizableBorderComponent) }; - - -#endif // JUCE_RESIZABLEBORDERCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp b/source/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp index 1b2be734a..5e7ef095d 100644 --- a/source/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp +++ b/source/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h b/source/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h index 8ca9adc91..14b36f22b 100644 --- a/source/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h +++ b/source/modules/juce_gui_basics/layout/juce_ResizableCornerComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RESIZABLECORNERCOMPONENT_H_INCLUDED -#define JUCE_RESIZABLECORNERCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -86,6 +87,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResizableCornerComponent) }; - - -#endif // JUCE_RESIZABLECORNERCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp b/source/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp index d23088beb..9c3a78d02 100644 --- a/source/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp +++ b/source/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h b/source/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h index 9ebab6688..4d8b45e26 100644 --- a/source/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h +++ b/source/modules/juce_gui_basics/layout/juce_ResizableEdgeComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RESIZABLEEDGECOMPONENT_H_INCLUDED -#define JUCE_RESIZABLEEDGECOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -94,6 +95,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResizableEdgeComponent) }; - - -#endif // JUCE_RESIZABLEEDGECOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_ScrollBar.cpp b/source/modules/juce_gui_basics/layout/juce_ScrollBar.cpp index f7777de47..e3aa126fd 100644 --- a/source/modules/juce_gui_basics/layout/juce_ScrollBar.cpp +++ b/source/modules/juce_gui_basics/layout/juce_ScrollBar.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_ScrollBar.h b/source/modules/juce_gui_basics/layout/juce_ScrollBar.h index c663bfdba..f94e905c2 100644 --- a/source/modules/juce_gui_basics/layout/juce_ScrollBar.h +++ b/source/modules/juce_gui_basics/layout/juce_ScrollBar.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SCROLLBAR_H_INCLUDED -#define JUCE_SCROLLBAR_H_INCLUDED +#pragma once //============================================================================== @@ -401,6 +402,3 @@ private: /** This typedef is just for compatibility with old code - newer code should use the ScrollBar::Listener class directly. */ typedef ScrollBar::Listener ScrollBarListener; - - -#endif // JUCE_SCROLLBAR_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp b/source/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp index 14141bd6d..64d217471 100644 --- a/source/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp +++ b/source/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h b/source/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h index 1de508e6f..2e86faaa9 100644 --- a/source/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h +++ b/source/modules/juce_gui_basics/layout/juce_StretchableLayoutManager.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STRETCHABLELAYOUTMANAGER_H_INCLUDED -#define JUCE_STRETCHABLELAYOUTMANAGER_H_INCLUDED +#pragma once //============================================================================== @@ -255,6 +256,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StretchableLayoutManager) }; - - -#endif // JUCE_STRETCHABLELAYOUTMANAGER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp b/source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp index 87373776d..c23baabe9 100644 --- a/source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp +++ b/source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h b/source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h index 28de39f12..87b18cfd2 100644 --- a/source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h +++ b/source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STRETCHABLELAYOUTRESIZERBAR_H_INCLUDED -#define JUCE_STRETCHABLELAYOUTRESIZERBAR_H_INCLUDED +#pragma once //============================================================================== @@ -99,6 +100,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StretchableLayoutResizerBar) }; - - -#endif // JUCE_STRETCHABLELAYOUTRESIZERBAR_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp b/source/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp index 9deeb903e..7fada6a5b 100644 --- a/source/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp +++ b/source/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h b/source/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h index 9bf11f007..c7e368fd0 100644 --- a/source/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h +++ b/source/modules/juce_gui_basics/layout/juce_StretchableObjectResizer.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_STRETCHABLEOBJECTRESIZER_H_INCLUDED -#define JUCE_STRETCHABLEOBJECTRESIZER_H_INCLUDED +#pragma once //============================================================================== @@ -96,6 +97,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StretchableObjectResizer) }; - - -#endif // JUCE_STRETCHABLEOBJECTRESIZER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp b/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp index ee9d20290..3f9b05752 100644 --- a/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp +++ b/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -219,8 +221,8 @@ void TabbedButtonBar::setOrientation (const Orientation newOrientation) { orientation = newOrientation; - for (int i = getNumChildComponents(); --i >= 0;) - getChildComponent (i)->resized(); + for (auto* child : getChildren()) + child->resized(); resized(); } diff --git a/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h b/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h index 9622a23ad..8936f4612 100644 --- a/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h +++ b/source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TABBEDBUTTONBAR_H_INCLUDED -#define JUCE_TABBEDBUTTONBAR_H_INCLUDED +#pragma once class TabbedButtonBar; @@ -364,6 +365,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TabbedButtonBar) }; - - -#endif // JUCE_TABBEDBUTTONBAR_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp b/source/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp index 25d716589..1e731df3d 100644 --- a/source/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp +++ b/source/modules/juce_gui_basics/layout/juce_TabbedComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -297,6 +299,7 @@ void TabbedComponent::changeCallback (const int newCurrentTabIndex, const String // do these ops as two stages instead of addAndMakeVisible() so that the // component has always got a parent when it gets the visibilityChanged() callback addChildComponent (panelComponent); + panelComponent->sendLookAndFeelChange(); panelComponent->setVisible (true); panelComponent->toFront (true); } diff --git a/source/modules/juce_gui_basics/layout/juce_TabbedComponent.h b/source/modules/juce_gui_basics/layout/juce_TabbedComponent.h index 98f627a36..0dac8a02c 100644 --- a/source/modules/juce_gui_basics/layout/juce_TabbedComponent.h +++ b/source/modules/juce_gui_basics/layout/juce_TabbedComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TABBEDCOMPONENT_H_INCLUDED -#define JUCE_TABBEDCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -220,6 +221,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TabbedComponent) }; - - -#endif // JUCE_TABBEDCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/layout/juce_Viewport.cpp b/source/modules/juce_gui_basics/layout/juce_Viewport.cpp index edb0ba250..eae3b6bb5 100644 --- a/source/modules/juce_gui_basics/layout/juce_Viewport.cpp +++ b/source/modules/juce_gui_basics/layout/juce_Viewport.cpp @@ -2,39 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -Viewport::Viewport (const String& name) - : Component (name), - scrollBarThickness (0), - singleStepX (16), - singleStepY (16), - showHScrollbar (true), - showVScrollbar (true), - deleteContent (true), - customScrollBarThickness (false), - allowScrollingWithoutScrollbarV (false), - allowScrollingWithoutScrollbarH (false), - verticalScrollBar (true), - horizontalScrollBar (false) +Viewport::Viewport (const String& name) : Component (name) { // content holder is used to clip the contents so they don't overlap the scrollbars addAndMakeVisible (contentHolder); @@ -104,14 +94,18 @@ void Viewport::setViewedComponent (Component* const newViewedComponent, const bo } } -int Viewport::getMaximumVisibleWidth() const { return contentHolder.getWidth(); } -int Viewport::getMaximumVisibleHeight() const { return contentHolder.getHeight(); } +int Viewport::getMaximumVisibleWidth() const { return contentHolder.getWidth(); } +int Viewport::getMaximumVisibleHeight() const { return contentHolder.getHeight(); } + +bool Viewport::canScrollVertically() const noexcept { return contentComp->getY() < 0 || contentComp->getBottom() > getHeight(); } +bool Viewport::canScrollHorizontally() const noexcept { return contentComp->getX() < 0 || contentComp->getRight() > getWidth(); } Point Viewport::viewportPosToCompPos (Point pos) const { jassert (contentComp != nullptr); - Rectangle contentBounds = contentHolder.getLocalArea (contentComp, contentComp->getLocalBounds()); + auto contentBounds = contentHolder.getLocalArea (contentComp, contentComp->getLocalBounds()); + Point p (jmax (jmin (0, contentHolder.getWidth() - contentBounds.getWidth()), jmin (0, -(pos.x))), jmax (jmin (0, contentHolder.getHeight() - contentBounds.getHeight()), jmin (0, -(pos.y)))); @@ -121,7 +115,7 @@ Point Viewport::viewportPosToCompPos (Point pos) const void Viewport::setViewPosition (const int xPixelsOffset, const int yPixelsOffset) { - setViewPosition (Point (xPixelsOffset, yPixelsOffset)); + setViewPosition ({ xPixelsOffset, yPixelsOffset }); } void Viewport::setViewPosition (Point newPosition) @@ -143,7 +137,7 @@ bool Viewport::autoScroll (const int mouseX, const int mouseY, const int activeB { int dx = 0, dy = 0; - if (horizontalScrollBar.isVisible() || contentComp->getX() < 0 || contentComp->getRight() > getWidth()) + if (horizontalScrollBar.isVisible() || canScrollHorizontally()) { if (mouseX < activeBorderThickness) dx = activeBorderThickness - mouseX; @@ -156,7 +150,7 @@ bool Viewport::autoScroll (const int mouseX, const int mouseY, const int activeB dx = jmin (dx, maximumSpeed, -contentComp->getX()); } - if (verticalScrollBar.isVisible() || contentComp->getY() < 0 || contentComp->getBottom() > getHeight()) + if (verticalScrollBar.isVisible() || canScrollVertically()) { if (mouseY < activeBorderThickness) dy = activeBorderThickness - mouseY; @@ -192,8 +186,7 @@ typedef AnimatedPosition Vie struct Viewport::DragToScrollListener : private MouseListener, private ViewportDragPosition::Listener { - DragToScrollListener (Viewport& v) - : viewport (v), numTouches (0), isDragging (false) + DragToScrollListener (Viewport& v) : viewport (v) { viewport.contentHolder.addMouseListener (this, true); offsetX.addListener (this); @@ -211,14 +204,17 @@ struct Viewport::DragToScrollListener : private MouseListener, (int) offsetY.getPosition())); } - void mouseDown (const MouseEvent&) override + void mouseDown (const MouseEvent& e) override { + if (doesMouseEventComponentBlockViewportDrag (e.eventComponent)) + isViewportDragBlocked = true; + ++numTouches; } void mouseDrag (const MouseEvent& e) override { - if (numTouches == 1) + if (numTouches == 1 && ! isViewportDragBlocked) { Point totalOffset = e.getOffsetFromDragStart().toFloat(); @@ -241,23 +237,35 @@ struct Viewport::DragToScrollListener : private MouseListener, } } - void mouseUp (const MouseEvent&) override + void mouseUp (const MouseEvent& e) override { - if (--numTouches == 0) + if (doesMouseEventComponentBlockViewportDrag (e.eventComponent)) + isViewportDragBlocked = false; + + if (--numTouches <= 0) { offsetX.endDrag(); offsetY.endDrag(); isDragging = false; + numTouches = 0; } + } + + bool doesMouseEventComponentBlockViewportDrag (const Component* eventComp) + { + for (auto c = eventComp; c != nullptr && c != &viewport; c = c->getParentComponent()) + if (c->getViewportIgnoreDragFlag()) + return true; - jassert (numTouches >= 0); + return false; } Viewport& viewport; ViewportDragPosition offsetX, offsetY; Point originalViewPos; - int numTouches; - bool isDragging; + int numTouches = 0; + bool isDragging = false; + bool isViewportDragBlocked = false; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DragToScrollListener) }; @@ -301,7 +309,7 @@ void Viewport::resized() //============================================================================== void Viewport::updateVisibleArea() { - const int scrollbarWidth = getScrollBarThickness(); + auto scrollbarWidth = getScrollBarThickness(); const bool canShowAnyBars = getWidth() > scrollbarWidth && getHeight() > scrollbarWidth; const bool canShowHBar = showHScrollbar && canShowAnyBars; const bool canShowVBar = showVScrollbar && canShowAnyBars; @@ -342,7 +350,7 @@ void Viewport::updateVisibleArea() break; } - const Rectangle oldContentBounds (contentComp->getBounds()); + auto oldContentBounds = contentComp->getBounds(); contentHolder.setBounds (contentArea); // If the content has changed its size, that might affect our scrollbars, so go round again and re-caclulate.. @@ -354,7 +362,7 @@ void Viewport::updateVisibleArea() if (contentComp != nullptr) contentBounds = contentHolder.getLocalArea (contentComp, contentComp->getLocalBounds()); - Point visibleOrigin (-contentBounds.getPosition()); + auto visibleOrigin = -contentBounds.getPosition(); horizontalScrollBar.setBounds (0, contentArea.getHeight(), contentArea.getWidth(), scrollbarWidth); horizontalScrollBar.setRangeLimits (0.0, contentBounds.getWidth()); @@ -380,7 +388,7 @@ void Viewport::updateVisibleArea() if (contentComp != nullptr) { - const Point newContentCompPos (viewportPosToCompPos (visibleOrigin)); + auto newContentCompPos = viewportPosToCompPos (visibleOrigin); if (contentComp->getBounds().getPosition() != newContentCompPos) { @@ -483,7 +491,7 @@ void Viewport::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& whe static int rescaleMouseWheelDistance (float distance, int singleStepSize) noexcept { - if (distance == 0) + if (distance == 0.0f) return 0; distance *= 14.0f * singleStepSize; @@ -501,10 +509,10 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelD if (canScrollHorz || canScrollVert) { - const int deltaX = rescaleMouseWheelDistance (wheel.deltaX, singleStepX); - const int deltaY = rescaleMouseWheelDistance (wheel.deltaY, singleStepY); + auto deltaX = rescaleMouseWheelDistance (wheel.deltaX, singleStepX); + auto deltaY = rescaleMouseWheelDistance (wheel.deltaY, singleStepY); - Point pos (getViewPosition()); + auto pos = getViewPosition(); if (deltaX != 0 && deltaY != 0 && canScrollHorz && canScrollVert) { diff --git a/source/modules/juce_gui_basics/layout/juce_Viewport.h b/source/modules/juce_gui_basics/layout/juce_Viewport.h index ee73e2770..7da6dfd27 100644 --- a/source/modules/juce_gui_basics/layout/juce_Viewport.h +++ b/source/modules/juce_gui_basics/layout/juce_Viewport.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_VIEWPORT_H_INCLUDED -#define JUCE_VIEWPORT_H_INCLUDED +#pragma once //============================================================================== @@ -212,15 +213,12 @@ public: bool isHorizontalScrollBarShown() const noexcept { return showHScrollbar; } /** Changes the width of the scrollbars. - If this isn't specified, the default width from the LookAndFeel class will be used. - @see LookAndFeel::getDefaultScrollbarWidth */ void setScrollBarThickness (int thickness); /** Returns the thickness of the scrollbars. - @see setScrollBarThickness */ int getScrollBarThickness() const; @@ -240,6 +238,15 @@ public: */ ScrollBar* getHorizontalScrollBar() noexcept { return &horizontalScrollBar; } + /** True if there's any off-screen content that could be scrolled vertically, + or false if everything is currently visible. + */ + bool canScrollVertically() const noexcept; + + /** True if there's any off-screen content that could be scrolled horizontally, + or false if everything is currently visible. + */ + bool canScrollHorizontally() const noexcept; /** Enables or disables drag-to-scroll functionality in the viewport. */ void setScrollOnDragEnabled (bool shouldScrollOnDrag); @@ -272,15 +279,15 @@ public: private: //============================================================================== + ScrollBar verticalScrollBar { true }, horizontalScrollBar { false }; + Component contentHolder; WeakReference contentComp; Rectangle lastVisibleArea; - int scrollBarThickness; - int singleStepX, singleStepY; - bool showHScrollbar, showVScrollbar, deleteContent; - bool customScrollBarThickness; - bool allowScrollingWithoutScrollbarV, allowScrollingWithoutScrollbarH; - Component contentHolder; - ScrollBar verticalScrollBar, horizontalScrollBar; + int scrollBarThickness = 0; + int singleStepX = 16, singleStepY = 16; + bool showHScrollbar = true, showVScrollbar = true, deleteContent = true; + bool customScrollBarThickness = false; + bool allowScrollingWithoutScrollbarV = false, allowScrollingWithoutScrollbarH = false; struct DragToScrollListener; friend struct DragToScrollListener; @@ -299,6 +306,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Viewport) }; - - -#endif // JUCE_VIEWPORT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp index 005c05b3f..4fd176651 100644 --- a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h index 8332a9aba..81267298a 100644 --- a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LOOKANDFEEL_H_INCLUDED -#define JUCE_LOOKANDFEEL_H_INCLUDED +#pragma once //============================================================================== /** This class is used to hold a few look and feel base classes which are associated @@ -228,6 +229,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel) }; - - -#endif // JUCE_LOOKANDFEEL_H_INCLUDED diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp index 927873c59..d88596565 100644 --- a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h index c8753267d..f9f708940 100644 --- a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LOOKANDFEEL_V1_H_INCLUDED -#define JUCE_LOOKANDFEEL_V1_H_INCLUDED +#pragma once //============================================================================== /** @@ -96,6 +97,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V1) }; - - -#endif // JUCE_LOOKANDFEEL_V1_H_INCLUDED diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp index 426b672b0..9edee80c9 100644 --- a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -607,6 +609,11 @@ void LookAndFeel_V2::drawSpinningWaitAnimation (Graphics& g, const Colour& colou } } +bool LookAndFeel_V2::isProgressBarOpaque (ProgressBar& progressBar) +{ + return progressBar.findColour (ProgressBar::backgroundColourId).isOpaque(); +} + bool LookAndFeel_V2::areScrollbarButtonsVisible() { return true; @@ -1097,6 +1104,8 @@ Component* LookAndFeel_V2::getParentComponentForMenuOptions (const PopupMenu::Op void LookAndFeel_V2::preparePopupMenuWindow (Component&) {} +bool LookAndFeel_V2::shouldPopupMenuScaleWithTargetComponent (const PopupMenu::Options&) { return true; } + //============================================================================== void LookAndFeel_V2::fillTextEditorBackground (Graphics& g, int /*width*/, int /*height*/, TextEditor& textEditor) { @@ -1475,14 +1484,14 @@ Button* LookAndFeel_V2::createSliderButton (Slider&, const bool isIncrement) class LookAndFeel_V2::SliderLabelComp : public Label { public: - SliderLabelComp() : Label (String(), String()) {} + SliderLabelComp() : Label ({}, {}) {} void mouseWheelMove (const MouseEvent&, const MouseWheelDetails&) {} }; Label* LookAndFeel_V2::createSliderTextBox (Slider& slider) { - Label* const l = new SliderLabelComp(); + auto l = new SliderLabelComp(); l->setJustificationType (Justification::centred); l->setKeyboardType (TextInputTarget::decimalKeyboard); @@ -1629,7 +1638,7 @@ void LookAndFeel_V2::layoutFilenameComponent (FilenameComponent& filenameComp, { browseButton->setSize (80, filenameComp.getHeight()); - if (TextButton* const tb = dynamic_cast (browseButton)) + if (auto* tb = dynamic_cast (browseButton)) tb->changeWidthToFitText(); browseButton->setTopRightPosition (filenameComp.getWidth(), 0); @@ -2041,7 +2050,7 @@ int LookAndFeel_V2::getTabButtonBestWidth (TabBarButton& button, int tabDepth) int width = Font (tabDepth * 0.6f).getStringWidth (button.getButtonText().trim()) + getTabButtonOverlap (tabDepth) * 2; - if (Component* const extraComponent = button.getExtraComponent()) + if (auto* extraComponent = button.getExtraComponent()) width += button.getTabbedButtonBar().isVertical() ? extraComponent->getHeight() : extraComponent->getWidth(); @@ -2052,7 +2061,7 @@ Rectangle LookAndFeel_V2::getTabButtonExtraComponentBounds (const TabBarBut { Rectangle extraComp; - const TabbedButtonBar::Orientation orientation = button.getTabbedButtonBar().getOrientation(); + auto orientation = button.getTabbedButtonBar().getOrientation(); if (button.getExtraComponentPlacement() == TabBarButton::beforeText) { @@ -2082,7 +2091,7 @@ Rectangle LookAndFeel_V2::getTabButtonExtraComponentBounds (const TabBarBut void LookAndFeel_V2::createTabButtonShape (TabBarButton& button, Path& p, bool /*isMouseOver*/, bool /*isMouseDown*/) { - const Rectangle activeArea (button.getActiveArea()); + auto activeArea = button.getActiveArea(); const float w = (float) activeArea.getWidth(); const float h = (float) activeArea.getHeight(); @@ -2142,7 +2151,7 @@ void LookAndFeel_V2::createTabButtonShape (TabBarButton& button, Path& p, bool / void LookAndFeel_V2::fillTabButtonShape (TabBarButton& button, Graphics& g, const Path& path, bool /*isMouseOver*/, bool /*isMouseDown*/) { - const Colour tabBackground (button.getTabBackgroundColour()); + auto tabBackground = button.getTabBackgroundColour(); const bool isFrontTab = button.isFrontTab(); g.setColour (isFrontTab ? tabBackground @@ -2484,7 +2493,7 @@ AttributedString LookAndFeel_V2::createFileChooserHeaderText (const String& titl AttributedString s; s.setJustification (Justification::centred); - const Colour colour (findColour (FileChooserDialogBox::titleTextColourId)); + auto colour = findColour (FileChooserDialogBox::titleTextColourId); s.append (title + "\n\n", Font (17.0f, Font::bold), colour); s.append (instructions, Font (14.0f), colour); @@ -2492,13 +2501,13 @@ AttributedString LookAndFeel_V2::createFileChooserHeaderText (const String& titl } void LookAndFeel_V2::drawFileBrowserRow (Graphics& g, int width, int height, - const String& filename, Image* icon, + const File&, const String& filename, Image* icon, const String& fileSizeDescription, const String& fileTimeDescription, - const bool isDirectory, const bool isItemSelected, - const int /*itemIndex*/, DirectoryContentsDisplayComponent& dcc) + bool isDirectory, bool isItemSelected, + int /*itemIndex*/, DirectoryContentsDisplayComponent& dcc) { - Component* const fileListComp = dynamic_cast (&dcc); + auto fileListComp = dynamic_cast (&dcc); if (isItemSelected) g.fillAll (fileListComp != nullptr ? fileListComp->findColour (DirectoryContentsDisplayComponent::highlightColourId) @@ -2515,8 +2524,8 @@ void LookAndFeel_V2::drawFileBrowserRow (Graphics& g, int width, int height, } else { - if (const Drawable* d = isDirectory ? getDefaultFolderImage() - : getDefaultDocumentFileImage()) + if (auto* d = isDirectory ? getDefaultFolderImage() + : getDefaultDocumentFileImage()) d->drawWithin (g, Rectangle (2.0f, 2.0f, x - 4.0f, height - 4.0f), RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, 1.0f); } @@ -2559,10 +2568,10 @@ void LookAndFeel_V2::drawFileBrowserRow (Graphics& g, int width, int height, Button* LookAndFeel_V2::createFileBrowserGoUpButton() { - DrawableButton* goUpButton = new DrawableButton ("up", DrawableButton::ImageOnButtonBackground); + auto goUpButton = new DrawableButton ("up", DrawableButton::ImageOnButtonBackground); Path arrowPath; - arrowPath.addArrow (Line (50.0f, 100.0f, 50.0f, 0.0f), 40.0f, 100.0f, 50.0f); + arrowPath.addArrow ({ 50.0f, 100.0f, 50.0f, 0.0f }, 40.0f, 100.0f, 50.0f); DrawablePath arrowImage; arrowImage.setFill (Colours::black.withAlpha (0.4f)); @@ -2581,11 +2590,11 @@ void LookAndFeel_V2::layoutFileBrowserComponent (FileBrowserComponent& browserCo Button* goUpButton) { const int x = 8; - int w = browserComp.getWidth() - x - x; + auto w = browserComp.getWidth() - x - x; if (previewComp != nullptr) { - const int previewWidth = w / 3; + auto previewWidth = w / 3; previewComp->setBounds (x + w - previewWidth, 0, previewWidth, browserComp.getHeight()); w -= previewWidth + 4; @@ -2602,7 +2611,7 @@ void LookAndFeel_V2::layoutFileBrowserComponent (FileBrowserComponent& browserCo y += controlsHeight + 4; - if (Component* const listAsComp = dynamic_cast (fileListComponent)) + if (auto listAsComp = dynamic_cast (fileListComponent)) { listAsComp->setBounds (x, y, w, browserComp.getHeight() - y - bottomSectionHeight); y = listAsComp->getBottom() + 4; diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h index f1f7e2693..302edef3e 100644 --- a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LOOKANDFEEL_V2_H_INCLUDED -#define JUCE_LOOKANDFEEL_V2_H_INCLUDED +#pragma once //============================================================================== @@ -90,6 +91,7 @@ public: //============================================================================== void drawProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String& textToShow) override; void drawSpinningWaitAnimation (Graphics&, const Colour& colour, int x, int y, int w, int h) override; + bool isProgressBarOpaque (ProgressBar&) override; //============================================================================== bool areScrollbarButtonsVisible() override; @@ -127,7 +129,7 @@ public: AttributedString createFileChooserHeaderText (const String& title, const String& instructions) override; void drawFileBrowserRow (Graphics&, int width, int height, - const String& filename, Image* icon, + const File& file, const String& filename, Image* icon, const String& fileSizeDescription, const String& fileTimeDescription, bool isDirectory, bool isItemSelected, int itemIndex, DirectoryContentsDisplayComponent&) override; @@ -178,6 +180,8 @@ public: Component* getParentComponentForMenuOptions (const PopupMenu::Options& options) override; + bool shouldPopupMenuScaleWithTargetComponent (const PopupMenu::Options& options) override; + //============================================================================== void drawComboBox (Graphics&, int width, int height, bool isButtonDown, int buttonX, int buttonY, int buttonW, int buttonH, @@ -366,6 +370,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V2) }; - - -#endif // JUCE_LOOKANDFEEL_V2_H_INCLUDED diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp index 774830c0a..5108791ff 100644 --- a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -28,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)); diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h index 2a474259b..dc0be9ca5 100644 --- a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LOOKANDFEEL_V3_H_INCLUDED -#define JUCE_LOOKANDFEEL_V3_H_INCLUDED +#pragma once //============================================================================== /** @@ -91,6 +92,3 @@ private: Image backgroundTexture; Colour backgroundTextureBaseColour; }; - - -#endif // JUCE_LOOKANDFEEL_V3_H_INCLUDED diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp new file mode 100644 index 000000000..9bfbd8d10 --- /dev/null +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp @@ -0,0 +1,1433 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + + +Colour LookAndFeel_V4::ColourScheme::getUIColour (UIColour index) const noexcept +{ + if (isPositiveAndBelow (index, numColours)) + return palette[index]; + + jassertfalse; + return {}; +} + +void LookAndFeel_V4::ColourScheme::setUIColour (UIColour index, Colour newColour) noexcept +{ + if (isPositiveAndBelow (index, numColours)) + palette[index] = newColour; + else + jassertfalse; +} + +bool LookAndFeel_V4::ColourScheme::operator== (const ColourScheme& other) const noexcept +{ + for (int i = 0; i < numColours; ++i) + if (palette[i] != other.palette[i]) + return false; + + return true; +} + +bool LookAndFeel_V4::ColourScheme::operator!= (const ColourScheme& other) const noexcept +{ + return ! operator== (other); +} + +//============================================================================== +LookAndFeel_V4::LookAndFeel_V4() : currentColourScheme (getDarkColourScheme()) +{ + initialiseColours(); +} + +LookAndFeel_V4::LookAndFeel_V4 (ColourScheme scheme) : currentColourScheme (scheme) +{ + initialiseColours(); +} + +LookAndFeel_V4::~LookAndFeel_V4() {} + +//============================================================================== +void LookAndFeel_V4::setColourScheme (ColourScheme newColourScheme) +{ + currentColourScheme = newColourScheme; + initialiseColours(); +} + +LookAndFeel_V4::ColourScheme LookAndFeel_V4::getDarkColourScheme() +{ + return { 0xff323e44, 0xff263238, 0xff323e44, + 0xff8e989b, 0xffffffff, 0xff42a2c8, + 0xffffffff, 0xff181f22, 0xffffffff }; +} + +LookAndFeel_V4::ColourScheme LookAndFeel_V4::getMidnightColourScheme() +{ + return { 0xff2f2f3a, 0xff191926, 0xffd0d0d0, + 0xff66667c, 0xc8ffffff, 0xffd8d8d8, + 0xffffffff, 0xff606073, 0xff000000 }; +} + +LookAndFeel_V4::ColourScheme LookAndFeel_V4::getGreyColourScheme() +{ + return { 0xff505050, 0xff424242, 0xff606060, + 0xffa6a6a6, 0xffffffff, 0xff21ba90, + 0xff000000, 0xffffffff, 0xffffffff }; +} + +LookAndFeel_V4::ColourScheme LookAndFeel_V4::getLightColourScheme() +{ + return { 0xffefefef, 0xffffffff, 0xffffffff, + 0xffdddddd, 0xff000000, 0xffa9a9a9, + 0xffffffff, 0xff42a2c8, 0xff000000 }; +} + +//============================================================================== +class LookAndFeel_V4_DocumentWindowButton : public Button +{ +public: + LookAndFeel_V4_DocumentWindowButton (const String& name, Colour c, const Path& normal, const Path& toggled) + : Button (name), colour (c), normalShape (normal), toggledShape (toggled) + { + } + + void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override + { + auto background = Colours::grey; + + if (auto* rw = findParentComponentOfClass()) + if (auto lf = dynamic_cast (&rw->getLookAndFeel())) + background = lf->getCurrentColourScheme().getUIColour (LookAndFeel_V4::ColourScheme::widgetBackground); + + g.fillAll (background); + + g.setColour ((! isEnabled() || isButtonDown) ? colour.withAlpha (0.6f) + : colour); + + if (isMouseOverButton) + { + g.fillAll(); + g.setColour (background); + } + + auto& p = getToggleState() ? toggledShape : normalShape; + + auto reducedRect = Justification (Justification::centred) + .appliedToRectangle (Rectangle (getHeight(), getHeight()), getLocalBounds()) + .toFloat() + .reduced (getHeight() * 0.3f); + + g.fillPath (p, p.getTransformToScaleToFit (reducedRect, true)); + } + +private: + Colour colour; + Path normalShape, toggledShape; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V4_DocumentWindowButton) +}; + +Button* LookAndFeel_V4::createDocumentWindowButton (int buttonType) +{ + Path shape; + const float crossThickness = 0.15f; + + if (buttonType == DocumentWindow::closeButton) + { + shape.addLineSegment ({ 0.0f, 0.0f, 1.0f, 1.0f }, crossThickness); + shape.addLineSegment ({ 1.0f, 0.0f, 0.0f, 1.0f }, crossThickness); + + return new LookAndFeel_V4_DocumentWindowButton ("close", Colour (0xff9A131D), shape, shape); + } + + if (buttonType == DocumentWindow::minimiseButton) + { + shape.addLineSegment ({ 0.0f, 0.5f, 1.0f, 0.5f }, crossThickness); + + return new LookAndFeel_V4_DocumentWindowButton ("minimise", Colour (0xffaa8811), shape, shape); + } + + if (buttonType == DocumentWindow::maximiseButton) + { + shape.addLineSegment ({ 0.5f, 0.0f, 0.5f, 1.0f }, crossThickness); + shape.addLineSegment ({ 0.0f, 0.5f, 1.0f, 0.5f }, crossThickness); + + Path fullscreenShape; + fullscreenShape.startNewSubPath (45.0f, 100.0f); + fullscreenShape.lineTo (0.0f, 100.0f); + fullscreenShape.lineTo (0.0f, 0.0f); + fullscreenShape.lineTo (100.0f, 0.0f); + fullscreenShape.lineTo (100.0f, 45.0f); + fullscreenShape.addRectangle (45.0f, 45.0f, 100.0f, 100.0f); + PathStrokeType (30.0f).createStrokedPath (fullscreenShape, fullscreenShape); + + return new LookAndFeel_V4_DocumentWindowButton ("maximise", Colour (0xff0A830A), shape, fullscreenShape); + } + + jassertfalse; + return nullptr; +} + +void LookAndFeel_V4::positionDocumentWindowButtons (DocumentWindow&, + int titleBarX, int titleBarY, + int titleBarW, int titleBarH, + Button* minimiseButton, + Button* maximiseButton, + Button* closeButton, + bool positionTitleBarButtonsOnLeft) +{ + const int buttonW = (int) (titleBarH * 1.2); + + int x = positionTitleBarButtonsOnLeft ? titleBarX + : titleBarX + titleBarW - buttonW; + + if (closeButton != nullptr) + { + closeButton->setBounds (x, titleBarY, buttonW, titleBarH); + x += positionTitleBarButtonsOnLeft ? buttonW : -buttonW; + } + + if (positionTitleBarButtonsOnLeft) + std::swap (minimiseButton, maximiseButton); + + if (maximiseButton != nullptr) + { + maximiseButton->setBounds (x, titleBarY, buttonW, titleBarH); + x += positionTitleBarButtonsOnLeft ? buttonW : -buttonW; + } + + if (minimiseButton != nullptr) + minimiseButton->setBounds (x, titleBarY, buttonW, titleBarH); +} + +void LookAndFeel_V4::drawDocumentWindowTitleBar (DocumentWindow& window, Graphics& g, + int w, int h, int titleSpaceX, int titleSpaceW, + const Image* icon, bool drawTitleTextOnLeft) +{ + if (w * h == 0) + return; + + const bool isActive = window.isActiveWindow(); + + g.setColour (getCurrentColourScheme().getUIColour (ColourScheme::widgetBackground)); + g.fillAll(); + + Font font (h * 0.65f, Font::plain); + g.setFont (font); + + int textW = font.getStringWidth (window.getName()); + int iconW = 0; + int iconH = 0; + + if (icon != nullptr) + { + iconH = (int) font.getHeight(); + iconW = icon->getWidth() * iconH / icon->getHeight() + 4; + } + + textW = jmin (titleSpaceW, textW + iconW); + int textX = drawTitleTextOnLeft ? titleSpaceX + : jmax (titleSpaceX, (w - textW) / 2); + + if (textX + textW > titleSpaceX + titleSpaceW) + textX = titleSpaceX + titleSpaceW - textW; + + if (icon != nullptr) + { + g.setOpacity (isActive ? 1.0f : 0.6f); + g.drawImageWithin (*icon, textX, (h - iconH) / 2, iconW, iconH, + RectanglePlacement::centred, false); + textX += iconW; + textW -= iconW; + } + + if (window.isColourSpecified (DocumentWindow::textColourId) || isColourSpecified (DocumentWindow::textColourId)) + g.setColour (window.findColour (DocumentWindow::textColourId)); + else + g.setColour (getCurrentColourScheme().getUIColour (ColourScheme::defaultText)); + + g.drawText (window.getName(), textX, 0, textW, h, Justification::centredLeft, true); +} + +//============================================================================== +void LookAndFeel_V4::drawButtonBackground (Graphics& g, + Button& button, + const Colour& backgroundColour, + bool isMouseOverButton, + bool isButtonDown) +{ + const auto cornerSize = 6.0f; + const auto bounds = button.getLocalBounds().toFloat().reduced (0.5f, 0.5f); + + auto baseColour = backgroundColour.withMultipliedSaturation (button.hasKeyboardFocus (true) ? 1.3f : 0.9f) + .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f); + + if (isButtonDown || isMouseOverButton) + baseColour = baseColour.contrasting (isButtonDown ? 0.2f : 0.05f); + + g.setColour (baseColour); + + if (button.isConnectedOnLeft() || button.isConnectedOnRight()) + { + Path path; + path.addRoundedRectangle (bounds.getX(), bounds.getY(), + bounds.getWidth(), bounds.getHeight(), + cornerSize, cornerSize, + ! button.isConnectedOnLeft(), + ! button.isConnectedOnRight(), + ! button.isConnectedOnLeft(), + ! button.isConnectedOnRight()); + + g.fillPath (path); + + g.setColour (button.findColour (ComboBox::outlineColourId)); + g.strokePath (path, PathStrokeType (1.0f)); + } + else + { + g.fillRoundedRectangle (bounds, cornerSize); + + g.setColour (button.findColour (ComboBox::outlineColourId)); + g.drawRoundedRectangle (bounds, cornerSize, 1.0f); + } +} + +void LookAndFeel_V4::drawToggleButton (Graphics& g, ToggleButton& button, + bool isMouseOverButton, bool isButtonDown) +{ + const auto fontSize = jmin (15.0f, button.getHeight() * 0.75f); + const auto tickWidth = fontSize * 1.1f; + + drawTickBox (g, button, 4.0f, (button.getHeight() - tickWidth) * 0.5f, + tickWidth, tickWidth, + button.getToggleState(), + button.isEnabled(), + isMouseOverButton, + isButtonDown); + + g.setColour (button.findColour (ToggleButton::textColourId)); + g.setFont (fontSize); + + if (! button.isEnabled()) + g.setOpacity (0.5f); + + const auto textX = roundToInt (tickWidth) + 10; + + g.drawFittedText (button.getButtonText(), + textX, 0, + button.getWidth() - textX - 2, button.getHeight(), + Justification::centredLeft, 10); +} + +void LookAndFeel_V4::drawTickBox (Graphics& g, Component& component, + float x, float y, float w, float h, + const bool ticked, + const bool isEnabled, + const bool isMouseOverButton, + const bool isButtonDown) +{ + ignoreUnused (isEnabled, isMouseOverButton, isButtonDown); + + Rectangle tickBounds (x, y, w, h); + + g.setColour (component.findColour (ToggleButton::tickDisabledColourId)); + g.drawRoundedRectangle (tickBounds, 4.0f, 1.0f); + + if (ticked) + { + g.setColour (component.findColour (ToggleButton::tickColourId)); + const auto tick = getTickShape (0.75f); + g.fillPath (tick, tick.getTransformToScaleToFit (tickBounds.reduced (4, 5).toFloat(), false)); + } +} + +//============================================================================== +AlertWindow* LookAndFeel_V4::createAlertWindow (const String& title, const String& message, + const String& button1, const String& button2, const String& button3, + AlertWindow::AlertIconType iconType, + int numButtons, Component* associatedComponent) +{ + const auto boundsOffset = 50; + + auto* aw = LookAndFeel_V2::createAlertWindow (title, message, button1, button2, button3, + iconType, numButtons, associatedComponent); + + auto bounds = aw->getBounds(); + bounds = bounds.withSizeKeepingCentre (bounds.getWidth() + boundsOffset, bounds.getHeight() + boundsOffset); + aw->setBounds (bounds); + + for (auto* child : aw->getChildren()) + if (auto button = dynamic_cast (child)) + button->setBounds (button->getBounds() + Point (25, 40)); + + return aw; +} + +void LookAndFeel_V4::drawAlertBox (Graphics& g, AlertWindow& alert, + const Rectangle& textArea, TextLayout& textLayout) +{ + const auto cornerSize = 4.0f; + + g.setColour (alert.findColour (AlertWindow::outlineColourId)); + g.drawRoundedRectangle (alert.getLocalBounds().toFloat(), cornerSize, 2.0f); + + const auto bounds = alert.getLocalBounds().reduced (1); + g.reduceClipRegion (bounds); + + g.setColour (alert.findColour (AlertWindow::backgroundColourId)); + g.fillRoundedRectangle (bounds.toFloat(), cornerSize); + + auto iconSpaceUsed = 0; + + const auto iconWidth = 80; + auto iconSize = jmin (iconWidth + 50, bounds.getHeight() + 20); + + if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2) + iconSize = jmin (iconSize, textArea.getHeight() + 50); + + const Rectangle iconRect (iconSize / -10, iconSize / -10, + iconSize, iconSize); + + if (alert.getAlertType() != AlertWindow::NoIcon) + { + Path icon; + char character; + uint32 colour; + + if (alert.getAlertType() == AlertWindow::WarningIcon) + { + character = '!'; + + icon.addTriangle (iconRect.getX() + iconRect.getWidth() * 0.5f, (float) iconRect.getY(), + (float) iconRect.getRight(), (float) iconRect.getBottom(), + (float) iconRect.getX(), (float) iconRect.getBottom()); + + icon = icon.createPathWithRoundedCorners (5.0f); + colour = 0x66ff2a00; + } + else + { + colour = Colour (0xff00b0b9).withAlpha (0.4f).getARGB(); + character = alert.getAlertType() == AlertWindow::InfoIcon ? 'i' : '?'; + + icon.addEllipse (iconRect.toFloat()); + } + + GlyphArrangement ga; + ga.addFittedText (Font (iconRect.getHeight() * 0.9f, Font::bold), + String::charToString ((juce_wchar) (uint8) character), + (float) iconRect.getX(), (float) iconRect.getY(), + (float) iconRect.getWidth(), (float) iconRect.getHeight(), + Justification::centred, false); + ga.createPath (icon); + + icon.setUsingNonZeroWinding (false); + g.setColour (Colour (colour)); + g.fillPath (icon); + + iconSpaceUsed = iconSize; + } + + g.setColour (alert.findColour (AlertWindow::textColourId)); + + const Rectangle alertBounds (bounds.getX() + iconSpaceUsed, + 30, + bounds.getWidth(), + bounds.getHeight() - getAlertWindowButtonHeight() - 20); + + textLayout.draw (g, alertBounds.toFloat()); +} + +int LookAndFeel_V4::getAlertWindowButtonHeight() { return 40; } +Font LookAndFeel_V4::getAlertWindowTitleFont() { return Font (18.0f, Font::FontStyleFlags::bold); } +Font LookAndFeel_V4::getAlertWindowMessageFont() { return Font (16.0f); } +Font LookAndFeel_V4::getAlertWindowFont() { return Font (14.0f); } + +//============================================================================== +void LookAndFeel_V4::drawProgressBar (Graphics& g, ProgressBar& progressBar, + int width, int height, double progress, const String& textToShow) +{ + if (width == height) + drawCircularProgressBar (g, progressBar, textToShow); + else + drawLinearProgressBar (g, progressBar, width, height, progress); +} + +void LookAndFeel_V4::drawLinearProgressBar (Graphics& g, ProgressBar& progressBar, int width, int height, double progress) +{ + const auto background = progressBar.findColour (ProgressBar::backgroundColourId); + const auto foreground = progressBar.findColour (ProgressBar::foregroundColourId); + + auto barBounds = progressBar.getLocalBounds().toFloat(); + + g.setColour (background); + g.fillRoundedRectangle (barBounds, progressBar.getHeight() * 0.5f); + + if (progress >= 0.0f && progress <= 1.0f) + { + Path p; + p.addRoundedRectangle (barBounds, progressBar.getHeight() * 0.5f); + g.reduceClipRegion (p); + + barBounds.setWidth (barBounds.getWidth() * (float) progress); + g.setColour (foreground); + g.fillRoundedRectangle (barBounds, progressBar.getHeight() * 0.5f); + } + else + { + // spinning bar.. + g.setColour (background); + + const auto stripeWidth = height * 2; + const auto position = (int) (Time::getMillisecondCounter() / 15) % stripeWidth; + + Path p; + + for (auto x = (float) (-position); x < width + stripeWidth; x += stripeWidth) + p.addQuadrilateral (x, 0.0f, + x + stripeWidth * 0.5f, 0.0f, + x, (float) height, + x - stripeWidth * 0.5f, (float) height); + + Image im (Image::ARGB, width, height, true); + + { + Graphics g2 (im); + g2.setColour (foreground); + g2.fillRoundedRectangle (barBounds, progressBar.getHeight() * 0.5f); + } + + g.setTiledImageFill (im, 0, 0, 0.85f); + g.fillPath (p); + } +} + +void LookAndFeel_V4::drawCircularProgressBar (Graphics& g, ProgressBar& progressBar, const String& progressText) +{ + const auto background = progressBar.findColour (ProgressBar::backgroundColourId); + const auto foreground = progressBar.findColour (ProgressBar::foregroundColourId); + + auto barBounds = progressBar.getLocalBounds().reduced (2, 2).toFloat(); + + auto rotationInDegrees = static_cast ((Time::getMillisecondCounter() / 10) % 360); + auto normalisedRotation = rotationInDegrees / 360.0f; + + const auto rotationOffset = 22.5f; + const auto maxRotation = 315.0f; + + auto startInDegrees = rotationInDegrees; + auto endInDegrees = startInDegrees + rotationOffset; + + if (normalisedRotation >= 0.25f && normalisedRotation < 0.5f) + { + const auto rescaledRotation = (normalisedRotation * 4.0f) - 1.0f; + endInDegrees = startInDegrees + rotationOffset + (maxRotation * rescaledRotation); + } + else if (normalisedRotation >= 0.5f && normalisedRotation <= 1.0f) + { + endInDegrees = startInDegrees + rotationOffset + maxRotation; + const auto rescaledRotation = 1.0f - ((normalisedRotation * 2.0f) - 1.0f); + startInDegrees = endInDegrees - rotationOffset - (maxRotation * rescaledRotation); + } + + g.setColour (background); + Path arcPath2; + arcPath2.addCentredArc (barBounds.getCentreX(), + barBounds.getCentreY(), + barBounds.getWidth() * 0.5f, + barBounds.getHeight() * 0.5f, 0.0f, + 0.0f, + 2.0f * float_Pi, + true); + g.strokePath (arcPath2, PathStrokeType (4.0f)); + + g.setColour (foreground); + Path arcPath; + arcPath.addCentredArc (barBounds.getCentreX(), + barBounds.getCentreY(), + barBounds.getWidth() * 0.5f, + barBounds.getHeight() * 0.5f, + 0.0f, + degreesToRadians (startInDegrees), + degreesToRadians (endInDegrees), + true); + + arcPath.applyTransform (AffineTransform::rotation (normalisedRotation * float_Pi * 2.25f, barBounds.getCentreX(), barBounds.getCentreY())); + g.strokePath (arcPath, PathStrokeType (4.0f)); + + if (progressText.isNotEmpty()) + { + g.setColour (progressBar.findColour (TextButton::textColourOffId)); + g.setFont (Font (12.0f, 2)); + g.drawText (progressText, barBounds, Justification::centred, false); + } +} + +//============================================================================== +int LookAndFeel_V4::getDefaultScrollbarWidth() +{ + return 8; +} + +void LookAndFeel_V4::drawScrollbar (Graphics& g, ScrollBar& scrollbar, int x, int y, int width, int height, + bool isScrollbarVertical, int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown) +{ + ignoreUnused (isMouseDown); + + Rectangle thumbBounds; + + if (isScrollbarVertical) + thumbBounds = { x, thumbStartPosition, width, thumbSize }; + else + thumbBounds = { thumbStartPosition, y, thumbSize, height }; + + const auto c = scrollbar.findColour (ScrollBar::ColourIds::thumbColourId); + g.setColour (isMouseOver ? c.brighter (0.25f) : c); + g.fillRoundedRectangle (thumbBounds.reduced (1).toFloat(), 4.0f); +} + +//============================================================================== +Path LookAndFeel_V4::getTickShape (float height) +{ + static const unsigned char pathData[] = { 110,109,32,210,202,64,126,183,148,64,108,39,244,247,64,245,76,124,64,108,178,131,27,65,246,76,252,64,108,175,242,4,65,246,76,252, + 64,108,236,5,68,65,0,0,160,180,108,240,150,90,65,21,136,52,63,108,48,59,16,65,0,0,32,65,108,32,210,202,64,126,183,148,64, 99,101,0,0 }; + + Path path; + path.loadPathFromData (pathData, sizeof (pathData)); + path.scaleToFit (0, 0, height * 2.0f, height, true); + + return path; +} + +Path LookAndFeel_V4::getCrossShape (float height) +{ + static const unsigned char pathData[] = { 110,109,51,51,255,66,0,0,0,0,108,205,204,13,67,51,51,99,65,108,0,0,170,66,205,204,141,66,108,51,179,13,67,52,51,255,66,108,0,0,255, + 66,205,204,13,67,108,205,204,141,66,0,0,170,66,108,52,51,99,65,51,179,13,67,108,0,0,0,0,51,51,255,66,108,205,204,98,66, 204,204,141,66,108,0,0,0,0,51,51,99,65,108,51,51, + 99,65,0,0,0,0,108,205,204,141,66,205,204,98,66,108,51,51,255,66,0,0,0,0,99,101,0,0 }; + + Path path; + path.loadPathFromData (pathData, sizeof (pathData)); + path.scaleToFit (0, 0, height * 2.0f, height, true); + + return path; +} + +//============================================================================== +void LookAndFeel_V4::fillTextEditorBackground (Graphics& g, int width, int height, TextEditor& textEditor) +{ + if (dynamic_cast (textEditor.getParentComponent()) != nullptr) + { + g.setColour (textEditor.findColour (TextEditor::backgroundColourId)); + g.fillRect (0, 0, width, height); + + g.setColour (textEditor.findColour (TextEditor::outlineColourId)); + g.drawHorizontalLine (height - 1, 0.0f, static_cast (width)); + } + else + { + LookAndFeel_V2::fillTextEditorBackground (g, width, height, textEditor); + } +} + +void LookAndFeel_V4::drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor) +{ + if (dynamic_cast (textEditor.getParentComponent()) == nullptr) + { + if (textEditor.isEnabled()) + { + if (textEditor.hasKeyboardFocus (true) && ! textEditor.isReadOnly()) + { + g.setColour (textEditor.findColour (TextEditor::focusedOutlineColourId)); + g.drawRect (0, 0, width, height, 2); + } + else + { + g.setColour (textEditor.findColour (TextEditor::outlineColourId)); + g.drawRect (0, 0, width, height); + } + } + } +} + +//============================================================================== +Button* LookAndFeel_V4::createFileBrowserGoUpButton() +{ + auto* goUpButton = new DrawableButton ("up", DrawableButton::ImageOnButtonBackground); + + Path arrowPath; + arrowPath.addArrow ({ 50.0f, 100.0f, 50.0f, 0.0f }, 40.0f, 100.0f, 50.0f); + + DrawablePath arrowImage; + arrowImage.setFill (goUpButton->findColour (TextButton::textColourOffId)); + arrowImage.setPath (arrowPath); + + goUpButton->setImages (&arrowImage); + + return goUpButton; +} + +void LookAndFeel_V4::layoutFileBrowserComponent (FileBrowserComponent& browserComp, + DirectoryContentsDisplayComponent* fileListComponent, + FilePreviewComponent* previewComp, + ComboBox* currentPathBox, + TextEditor* filenameBox, + Button* goUpButton) +{ + const auto sectionHeight = 22; + const auto buttonWidth = 50; + + auto b = browserComp.getLocalBounds().reduced (20, 5); + + auto topSlice = b.removeFromTop (sectionHeight); + auto bottomSlice = b.removeFromBottom (sectionHeight); + + currentPathBox->setBounds (topSlice.removeFromLeft (topSlice.getWidth() - buttonWidth)); + currentPathBox->setColour (ComboBox::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuBackground)); + currentPathBox->setColour (ComboBox::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText)); + currentPathBox->setColour (ComboBox::arrowColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText)); + + topSlice.removeFromLeft (6); + goUpButton->setBounds (topSlice); + + bottomSlice.removeFromLeft (20); + filenameBox->setBounds (bottomSlice); + filenameBox->setColour (TextEditor::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuBackground)); + filenameBox->setColour (TextEditor::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText)); + + if (previewComp != nullptr) + previewComp->setBounds (b.removeFromRight (b.getWidth() / 3)); + + if (auto listAsComp = dynamic_cast (fileListComponent)) + listAsComp->setBounds (b.reduced (0, 10)); +} + +void LookAndFeel_V4::drawFileBrowserRow (Graphics& g, int width, int height, + const File& file, const String& filename, Image* icon, + const String& fileSizeDescription, + const String& fileTimeDescription, + bool isDirectory, bool isItemSelected, + int itemIndex, DirectoryContentsDisplayComponent& dcc) +{ + if (auto fileListComp = dynamic_cast (&dcc)) + fileListComp->setColour (DirectoryContentsDisplayComponent::textColourId, + currentColourScheme.getUIColour (isItemSelected ? ColourScheme::UIColour::highlightedText + : ColourScheme::UIColour::menuText)); + + LookAndFeel_V2::drawFileBrowserRow (g, width, height, file, filename, icon, + fileSizeDescription, fileTimeDescription, + isDirectory, isItemSelected, itemIndex, dcc); +} + +//============================================================================== +void LookAndFeel_V4::drawPopupMenuItem (Graphics& g, const Rectangle& area, + const bool isSeparator, const bool isActive, + const bool isHighlighted, const bool isTicked, + const bool hasSubMenu, const String& text, + const String& shortcutKeyText, + const Drawable* icon, const Colour* const textColourToUse) +{ + if (isSeparator) + { + auto r = area.reduced (5, 0); + r.removeFromTop (roundToInt ((r.getHeight() * 0.5f) - 0.5f)); + + g.setColour (findColour (PopupMenu::textColourId).withAlpha (0.3f)); + g.fillRect (r.removeFromTop (1)); + } + else + { + auto textColour = (textColourToUse == nullptr ? findColour (PopupMenu::textColourId) + : *textColourToUse); + + auto r = area.reduced (1); + + if (isHighlighted && isActive) + { + g.setColour (findColour (PopupMenu::highlightedBackgroundColourId)); + g.fillRect (r); + + g.setColour (findColour (PopupMenu::highlightedTextColourId)); + } + else + { + g.setColour (textColour.withMultipliedAlpha (isActive ? 1.0f : 0.5f)); + } + + r.reduce (jmin (5, area.getWidth() / 20), 0); + + auto font = getPopupMenuFont(); + + const auto maxFontHeight = r.getHeight() / 1.3f; + + if (font.getHeight() > maxFontHeight) + font.setHeight (maxFontHeight); + + g.setFont (font); + + auto iconArea = r.removeFromLeft (roundToInt (maxFontHeight)).toFloat(); + + if (icon != nullptr) + { + icon->drawWithin (g, iconArea, RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, 1.0f); + } + else if (isTicked) + { + const auto tick = getTickShape (1.0f); + g.fillPath (tick, tick.getTransformToScaleToFit (iconArea.reduced (iconArea.getWidth() / 5, 0).toFloat(), true)); + } + + if (hasSubMenu) + { + const auto arrowH = 0.6f * getPopupMenuFont().getAscent(); + + const auto x = (float) r.removeFromRight ((int) arrowH).getX(); + const auto halfH = (float) r.getCentreY(); + + Path path; + path.startNewSubPath (x, halfH - arrowH * 0.5f); + path.lineTo (x + arrowH * 0.6f, halfH); + path.lineTo (x, halfH + arrowH * 0.5f); + + g.strokePath (path, PathStrokeType (2.0f)); + } + + r.removeFromRight (3); + g.drawFittedText (text, r, Justification::centredLeft, 1); + + if (shortcutKeyText.isNotEmpty()) + { + auto f2 = font; + f2.setHeight (f2.getHeight() * 0.75f); + f2.setHorizontalScale (0.95f); + g.setFont (f2); + + g.drawText (shortcutKeyText, r, Justification::centredRight, true); + } + } +} + +void LookAndFeel_V4::getIdealPopupMenuItemSize (const String& text, const bool isSeparator, + int standardMenuItemHeight, int& idealWidth, int& idealHeight) +{ + if (isSeparator) + { + idealWidth = 50; + idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight / 10 : 10; + } + else + { + auto font = getPopupMenuFont(); + + if (standardMenuItemHeight > 0 && font.getHeight() > standardMenuItemHeight / 1.3f) + font.setHeight (standardMenuItemHeight / 1.3f); + + idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight : roundToInt (font.getHeight() * 1.3f); + idealWidth = font.getStringWidth (text) + idealHeight * 2; + } +} + +void LookAndFeel_V4::drawMenuBarBackground (Graphics& g, int width, int height, + bool, MenuBarComponent& menuBar) +{ + const auto colour = menuBar.findColour (TextButton::buttonColourId).withAlpha (0.4f); + + Rectangle r (width, height); + + g.setColour (colour.contrasting (0.15f)); + g.fillRect (r.removeFromTop (1)); + g.fillRect (r.removeFromBottom (1)); + + g.setGradientFill (ColourGradient (colour, 0, 0, colour.darker (0.2f), 0, (float) height, false)); + g.fillRect (r); +} + +void LookAndFeel_V4::drawMenuBarItem (Graphics& g, int width, int height, + int itemIndex, const String& itemText, + bool isMouseOverItem, bool isMenuOpen, + bool /*isMouseOverBar*/, MenuBarComponent& menuBar) +{ + if (! menuBar.isEnabled()) + { + g.setColour (menuBar.findColour (TextButton::textColourOffId) + .withMultipliedAlpha (0.5f)); + } + else if (isMenuOpen || isMouseOverItem) + { + g.fillAll (menuBar.findColour (TextButton::buttonOnColourId)); + g.setColour (menuBar.findColour (TextButton::textColourOnId)); + } + else + { + g.setColour (menuBar.findColour (TextButton::textColourOffId)); + } + + g.setFont (getMenuBarFont (menuBar, itemIndex, itemText)); + g.drawFittedText (itemText, 0, 0, width, height, Justification::centred, 1); +} + +//============================================================================== +void LookAndFeel_V4::drawComboBox (Graphics& g, int width, int height, bool, + int, int, int, int, ComboBox& box) +{ + const auto cornerSize = box.findParentComponentOfClass() != nullptr ? 0.0f : 3.0f; + const Rectangle boxBounds (0, 0, width, height); + + g.setColour (box.findColour (ComboBox::backgroundColourId)); + g.fillRoundedRectangle (boxBounds.toFloat(), cornerSize); + + g.setColour (box.findColour (ComboBox::outlineColourId)); + g.drawRoundedRectangle (boxBounds.toFloat().reduced (0.5f, 0.5f), cornerSize, 1.0f); + + Rectangle arrowZone (width - 30, 0, 20, height); + Path path; + path.startNewSubPath (arrowZone.getX() + 3.0f, arrowZone.getCentreY() - 2.0f); + path.lineTo (static_cast (arrowZone.getCentreX()), arrowZone.getCentreY() + 3.0f); + path.lineTo (arrowZone.getRight() - 3.0f, arrowZone.getCentreY() - 2.0f); + + g.setColour (box.findColour (ComboBox::arrowColourId).withAlpha ((box.isEnabled() ? 0.9f : 0.2f))); + g.strokePath (path, PathStrokeType (2.0f)); +} + +Font LookAndFeel_V4::getComboBoxFont (ComboBox& box) +{ + return Font (jmin (16.0f, box.getHeight() * 0.85f)); +} + +void LookAndFeel_V4::positionComboBoxText (ComboBox& box, Label& label) +{ + label.setBounds (1, 1, + box.getWidth() - 30, + box.getHeight() - 2); + + label.setFont (getComboBoxFont (box)); +} + +//============================================================================== +void LookAndFeel_V4::drawLinearSlider (Graphics& g, int x, int y, int width, int height, + float sliderPos, + float minSliderPos, + float maxSliderPos, + const Slider::SliderStyle style, Slider& slider) +{ + if (slider.isBar()) + { + g.setColour (slider.findColour (Slider::trackColourId)); + g.fillRect (slider.isHorizontal() ? Rectangle (static_cast (x), y + 0.5f, sliderPos - x, height - 1.0f) + : Rectangle (x + 0.5f, sliderPos, width - 1.0f, y + (height - sliderPos))); + } + else + { + const auto isTwoVal = (style == Slider::SliderStyle::TwoValueVertical || style == Slider::SliderStyle::TwoValueHorizontal); + const auto isThreeVal = (style == Slider::SliderStyle::ThreeValueVertical || style == Slider::SliderStyle::ThreeValueHorizontal); + + const auto trackWidth = jmin (6.0f, slider.isHorizontal() ? height * 0.25f : width * 0.25f); + + const Point startPoint (slider.isHorizontal() ? x : width * 0.5f, + slider.isHorizontal() ? height * 0.5f : height + y); + + const Point endPoint (slider.isHorizontal() ? width + x : startPoint.x, + slider.isHorizontal() ? startPoint.y : y); + + Path backgroundTrack; + backgroundTrack.startNewSubPath (startPoint); + backgroundTrack.lineTo (endPoint); + g.setColour (slider.findColour (Slider::backgroundColourId)); + g.strokePath (backgroundTrack, PathStrokeType (trackWidth, PathStrokeType::curved, PathStrokeType::rounded)); + + Path valueTrack; + Point minPoint, maxPoint, thumbPoint; + + if (isTwoVal || isThreeVal) + { + minPoint = { slider.isHorizontal() ? minSliderPos : width * 0.5f, + slider.isHorizontal() ? height * 0.5f : minSliderPos }; + + if (isThreeVal) + thumbPoint = { slider.isHorizontal() ? sliderPos : width * 0.5f, + slider.isHorizontal() ? height * 0.5f : sliderPos }; + + maxPoint = { slider.isHorizontal() ? maxSliderPos : width * 0.5f, + slider.isHorizontal() ? height * 0.5f : maxSliderPos }; + } + else + { + const auto kx = slider.isHorizontal() ? sliderPos : (x + width * 0.5f); + const auto ky = slider.isHorizontal() ? (y + height * 0.5f) : sliderPos; + + minPoint = startPoint; + maxPoint = { kx, ky }; + } + + const auto thumbWidth = trackWidth * 2.0f; + + valueTrack.startNewSubPath (minPoint); + valueTrack.lineTo (isThreeVal ? thumbPoint : maxPoint); + g.setColour (slider.findColour (Slider::trackColourId)); + g.strokePath (valueTrack, PathStrokeType (trackWidth, PathStrokeType::curved, PathStrokeType::rounded)); + + if (! isTwoVal) + { + g.setColour (slider.findColour (Slider::thumbColourId)); + g.fillEllipse (Rectangle (thumbWidth, thumbWidth).withCentre (isThreeVal ? thumbPoint : maxPoint)); + } + + if (isTwoVal || isThreeVal) + { + const auto sr = jmin (trackWidth, (slider.isHorizontal() ? height : width) * 0.4f); + const auto pointerColour = slider.findColour (Slider::thumbColourId); + + if (slider.isHorizontal()) + { + drawPointer (g, minSliderPos - sr, + jmax (0.0f, y + height * 0.5f - trackWidth * 2.0f), + trackWidth * 2.0f, pointerColour, 2); + + drawPointer (g, maxSliderPos - trackWidth, + jmin (y + height - trackWidth * 2.0f, y + height * 0.5f), + trackWidth * 2.0f, pointerColour, 4); + } + else + { + drawPointer (g, jmax (0.0f, x + width * 0.5f - trackWidth * 2.0f), + minSliderPos - trackWidth, + trackWidth * 2.0f, pointerColour, 1); + + drawPointer (g, jmin (x + width - trackWidth * 2.0f, x + width * 0.5f), maxSliderPos - sr, + trackWidth * 2.0f, pointerColour, 3); + } + } + } +} + +void LookAndFeel_V4::drawRotarySlider (Graphics& g, int x, int y, int width, int height, float sliderPos, + const float rotaryStartAngle, const float rotaryEndAngle, Slider& slider) +{ + const auto outline = slider.findColour (Slider::rotarySliderOutlineColourId); + const auto fill = slider.findColour (Slider::rotarySliderFillColourId); + + const auto bounds = Rectangle (x, y, width, height).toFloat().reduced (10); + + auto radius = jmin (bounds.getWidth(), bounds.getHeight()) / 2.0f; + const auto toAngle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle); + auto lineW = jmin (8.0f, radius * 0.5f); + auto arcRadius = radius - lineW * 0.5f; + + Path backgroundArc; + backgroundArc.addCentredArc (bounds.getCentreX(), + bounds.getCentreY(), + arcRadius, + arcRadius, + 0.0f, + rotaryStartAngle, + rotaryEndAngle, + true); + + g.setColour (outline); + g.strokePath (backgroundArc, PathStrokeType (lineW, PathStrokeType::curved, PathStrokeType::rounded)); + + if (slider.isEnabled()) + { + Path valueArc; + valueArc.addCentredArc (bounds.getCentreX(), + bounds.getCentreY(), + arcRadius, + arcRadius, + 0.0f, + rotaryStartAngle, + toAngle, + true); + + g.setColour (fill); + g.strokePath (valueArc, PathStrokeType (lineW, PathStrokeType::curved, PathStrokeType::rounded)); + } + + const auto thumbWidth = lineW * 2.0f; + const Point thumbPoint (bounds.getCentreX() + arcRadius * std::cos (toAngle - float_Pi * 0.5f), + bounds.getCentreY() + arcRadius * std::sin (toAngle - float_Pi * 0.5f)); + + g.setColour (slider.findColour (Slider::thumbColourId)); + g.fillEllipse (Rectangle (thumbWidth, thumbWidth).withCentre (thumbPoint)); +} + +void LookAndFeel_V4::drawPointer (Graphics& g, const float x, const float y, const float diameter, + const Colour& colour, const int direction) noexcept +{ + Path p; + p.startNewSubPath (x + diameter * 0.5f, y); + p.lineTo (x + diameter, y + diameter * 0.6f); + p.lineTo (x + diameter, y + diameter); + p.lineTo (x, y + diameter); + p.lineTo (x, y + diameter * 0.6f); + p.closeSubPath(); + + p.applyTransform (AffineTransform::rotation (direction * (float_Pi * 0.5f), x + diameter * 0.5f, y + diameter * 0.5f)); + + g.setColour (colour); + g.fillPath (p); +} + +//============================================================================== +void LookAndFeel_V4::drawTooltip (Graphics& g, const String& text, int width, int height) +{ + Rectangle bounds (width, height); + const auto cornerSize = 5.0f; + + g.setColour (findColour (TooltipWindow::backgroundColourId)); + g.fillRoundedRectangle (bounds.toFloat(), cornerSize); + + g.setColour (findColour (TooltipWindow::outlineColourId)); + g.drawRoundedRectangle (bounds.toFloat().reduced (0.5f, 0.5f), cornerSize, 1.0f); + + LookAndFeelHelpers::layoutTooltipText (text, findColour (TooltipWindow::textColourId)) + .draw (g, Rectangle ((float) width, (float) height)); +} + +//============================================================================== +void LookAndFeel_V4::drawConcertinaPanelHeader (Graphics& g, const Rectangle& area, + bool isMouseOver, bool /*isMouseDown*/, + ConcertinaPanel& concertina, Component& panel) +{ + auto bounds = area.toFloat().reduced (0.5f); + const auto cornerSize = 4.0f; + auto isTopPanel = (concertina.getPanel (0) == &panel); + + Path p; + p.addRoundedRectangle (bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(), + cornerSize, cornerSize, isTopPanel, isTopPanel, false, false); + + const auto bkg = Colours::grey; + + g.setGradientFill (ColourGradient (Colours::white.withAlpha (isMouseOver ? 0.4f : 0.2f), 0, (float) area.getY(), + Colours::darkgrey.withAlpha (0.1f), 0, (float) area.getBottom(), false)); + g.fillPath (p); +} + +//============================================================================== +void LookAndFeel_V4::drawLevelMeter (Graphics& g, int width, int height, float level) +{ + const auto outerCornerSize = 3.0f; + const auto outerBorderWidth = 2.0f; + const auto totalBlocks = 7; + const auto spacingFraction = 0.03f; + + g.setColour (findColour (ResizableWindow::backgroundColourId)); + g.fillRoundedRectangle (0.0f, 0.0f, (float) width, (float) height, outerCornerSize); + + const auto doubleOuterBorderWidth = 2.0f * outerBorderWidth; + const auto numBlocks = roundToInt (totalBlocks * level); + + const auto blockWidth = (width - doubleOuterBorderWidth) / (float) totalBlocks; + const auto blockHeight = height - doubleOuterBorderWidth; + + const auto blockRectWidth = (1.0f - 2.0f * spacingFraction) * blockWidth; + const auto blockRectSpacing = spacingFraction * blockWidth; + + const auto blockCornerSize = 0.1f * blockWidth; + + const auto c = findColour (Slider::thumbColourId); + + for (int i = 0; i < totalBlocks; ++i) + { + if (i >= numBlocks) + g.setColour (c.withAlpha (0.5f)); + else + g.setColour (i < totalBlocks - 1 ? c : Colours::red); + + g.fillRoundedRectangle (outerBorderWidth + (i * blockWidth) + blockRectSpacing, + outerBorderWidth, + blockRectWidth, + blockHeight, + blockCornerSize); + } +} + +//============================================================================== +void LookAndFeel_V4::paintToolbarBackground (Graphics& g, int w, int h, Toolbar& toolbar) +{ + const auto background = toolbar.findColour (Toolbar::backgroundColourId); + + g.setGradientFill (ColourGradient (background, 0.0f, 0.0f, + background.darker (0.2f), + toolbar.isVertical() ? w - 1.0f : 0.0f, + toolbar.isVertical() ? 0.0f : h - 1.0f, + false)); + g.fillAll(); +} + +void LookAndFeel_V4::paintToolbarButtonLabel (Graphics& g, int x, int y, int width, int height, + const String& text, ToolbarItemComponent& component) +{ + auto baseTextColour = component.findParentComponentOfClass() != nullptr + ? component.findColour (PopupMenu::textColourId) + : component.findColour (Toolbar::labelTextColourId); + + g.setColour (baseTextColour.withAlpha (component.isEnabled() ? 1.0f : 0.25f)); + + const auto fontHeight = jmin (14.0f, height * 0.85f); + g.setFont (fontHeight); + + g.drawFittedText (text, + x, y, width, height, + Justification::centred, + jmax (1, height / (int) fontHeight)); +} + +//============================================================================== +void LookAndFeel_V4::drawPropertyPanelSectionHeader (Graphics& g, const String& name, + bool isOpen, int width, int height) +{ + const auto buttonSize = height * 0.75f; + const auto buttonIndent = (height - buttonSize) * 0.5f; + + drawTreeviewPlusMinusBox (g, Rectangle (buttonIndent, buttonIndent, buttonSize, buttonSize), + findColour (ResizableWindow::backgroundColourId), isOpen, false); + + const auto textX = (int) (buttonIndent * 2.0f + buttonSize + 2.0f); + + g.setColour (findColour (PropertyComponent::labelTextColourId)); + + g.setFont (Font (height * 0.7f, Font::bold)); + g.drawText (name, textX, 0, width - textX - 4, height, Justification::centredLeft, true); +} + +void LookAndFeel_V4::drawPropertyComponentBackground (Graphics& g, int width, int height, PropertyComponent& component) +{ + g.setColour (component.findColour (PropertyComponent::backgroundColourId)); + g.fillRect (0, 0, width, height - 1); +} + +void LookAndFeel_V4::drawPropertyComponentLabel (Graphics& g, int width, int height, PropertyComponent& component) +{ + ignoreUnused (width); + + const auto indent = getPropertyComponentIndent (component); + + g.setColour (component.findColour (PropertyComponent::labelTextColourId) + .withMultipliedAlpha (component.isEnabled() ? 1.0f : 0.6f)); + + g.setFont (jmin (height, 24) * 0.65f); + + auto r = getPropertyComponentContentPosition (component); + + g.drawFittedText (component.getName(), + indent, r.getY(), r.getX() - 5, r.getHeight(), + Justification::centredLeft, 2); +} + +int LookAndFeel_V4::getPropertyComponentIndent (PropertyComponent& component) +{ + return jmin (10, component.getWidth() / 10); +} + +Rectangle LookAndFeel_V4::getPropertyComponentContentPosition (PropertyComponent& component) +{ + const auto textW = jmin (200, component.getWidth() / 2); + return { textW, 0, component.getWidth() - textW, component.getHeight() - 1 }; +} + +//============================================================================== +void LookAndFeel_V4::drawCallOutBoxBackground (CallOutBox& box, Graphics& g, + const Path& path, Image& cachedImage) +{ + if (cachedImage.isNull()) + { + cachedImage = Image (Image::ARGB, box.getWidth(), box.getHeight(), true); + Graphics g2 (cachedImage); + + DropShadow (Colours::black.withAlpha (0.7f), 8, Point (0, 2)).drawForPath (g2, path); + } + + g.setColour (Colours::black); + g.drawImageAt (cachedImage, 0, 0); + + g.setColour (currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).withAlpha (0.8f)); + g.fillPath (path); + + g.setColour (currentColourScheme.getUIColour (ColourScheme::UIColour::outline).withAlpha (0.8f)); + g.strokePath (path, PathStrokeType (2.0f)); +} + +//============================================================================== +void LookAndFeel_V4::drawStretchableLayoutResizerBar (Graphics& g, int /*w*/, int /*h*/, bool /*isVerticalBar*/, + bool isMouseOver, bool isMouseDragging) +{ + if (isMouseOver || isMouseDragging) + g.fillAll (currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).withAlpha (0.5f)); +} + +//============================================================================== +void LookAndFeel_V4::initialiseColours() +{ + const uint32 transparent = 0x00000000; + + const uint32 coloursToUse[] = + { + TextButton::buttonColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + TextButton::buttonOnColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + TextButton::textColourOnId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(), + TextButton::textColourOffId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + + ToggleButton::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + ToggleButton::tickColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + ToggleButton::tickDisabledColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).withAlpha (0.5f).getARGB(), + + TextEditor::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + TextEditor::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + TextEditor::highlightColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + TextEditor::highlightedTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(), + TextEditor::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + TextEditor::focusedOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + TextEditor::shadowColourId, transparent, + + CaretComponent::caretColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(), + + Label::backgroundColourId, transparent, + Label::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + Label::outlineColourId, transparent, + Label::textWhenEditingColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + + ScrollBar::backgroundColourId, transparent, + ScrollBar::thumbColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(), + ScrollBar::trackColourId, transparent, + + TreeView::linesColourId, transparent, + TreeView::backgroundColourId, transparent, + TreeView::dragAndDropIndicatorColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + TreeView::selectedItemBackgroundColourId, transparent, + TreeView::oddItemsColourId, transparent, + TreeView::evenItemsColourId, transparent, + + PopupMenu::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuBackground).getARGB(), + PopupMenu::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText).getARGB(), + PopupMenu::headerTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText).getARGB(), + PopupMenu::highlightedTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(), + PopupMenu::highlightedBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + + ComboBox::buttonColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + ComboBox::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + ComboBox::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + ComboBox::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + ComboBox::arrowColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + + PropertyComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + PropertyComponent::labelTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + + TextPropertyComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + TextPropertyComponent::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + TextPropertyComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + + BooleanPropertyComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + BooleanPropertyComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + + ListBox::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + ListBox::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + ListBox::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + + Slider::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + Slider::thumbColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(), + Slider::trackColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + Slider::rotarySliderFillColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + Slider::rotarySliderOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + Slider::textBoxTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + Slider::textBoxBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).withAlpha (0.0f).getARGB(), + Slider::textBoxHighlightColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + Slider::textBoxOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + + ResizableWindow::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::windowBackground).getARGB(), + + DocumentWindow::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + + AlertWindow::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + AlertWindow::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + AlertWindow::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + + ProgressBar::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + ProgressBar::foregroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + + TooltipWindow::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + TooltipWindow::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(), + TooltipWindow::outlineColourId, transparent, + + TabbedComponent::backgroundColourId, transparent, + TabbedComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + TabbedButtonBar::tabOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).withAlpha (0.5f).getARGB(), + TabbedButtonBar::frontOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + + Toolbar::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).withAlpha (0.4f).getARGB(), + Toolbar::separatorColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + Toolbar::buttonMouseOverBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).contrasting (0.2f).getARGB(), + Toolbar::buttonMouseDownBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).contrasting (0.5f).getARGB(), + Toolbar::labelTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + Toolbar::editingModeOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + + DrawableButton::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + DrawableButton::textColourOnId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(), + DrawableButton::backgroundColourId, transparent, + DrawableButton::backgroundOnColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + + HyperlinkButton::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).interpolatedWith (Colours::blue, 0.4f).getARGB(), + + GroupComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + GroupComponent::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + + BubbleComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + BubbleComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + + DirectoryContentsDisplayComponent::highlightColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + DirectoryContentsDisplayComponent::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText).getARGB(), + + 0x1000440, /*LassoComponent::lassoFillColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(), + 0x1000441, /*LassoComponent::lassoOutlineColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(), + + 0x1005000, /*MidiKeyboardComponent::whiteNoteColourId*/ 0xffffffff, + 0x1005001, /*MidiKeyboardComponent::blackNoteColourId*/ 0xff000000, + 0x1005002, /*MidiKeyboardComponent::keySeparatorLineColourId*/ 0x66000000, + 0x1005003, /*MidiKeyboardComponent::mouseOverKeyOverlayColourId*/ 0x80ffff00, + 0x1005004, /*MidiKeyboardComponent::keyDownOverlayColourId*/ 0xffb6b600, + 0x1005005, /*MidiKeyboardComponent::textLabelColourId*/ 0xff000000, + 0x1005006, /*MidiKeyboardComponent::upDownButtonBackgroundColourId*/ 0xffd3d3d3, + 0x1005007, /*MidiKeyboardComponent::upDownButtonArrowColourId*/ 0xff000000, + 0x1005008, /*MidiKeyboardComponent::shadowColourId*/ 0x4c000000, + + 0x1004500, /*CodeEditorComponent::backgroundColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + 0x1004502, /*CodeEditorComponent::highlightColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(), + 0x1004503, /*CodeEditorComponent::defaultTextColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + 0x1004504, /*CodeEditorComponent::lineNumberBackgroundId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).withAlpha (0.5f).getARGB(), + 0x1004505, /*CodeEditorComponent::lineNumberTextId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(), + + 0x1007000, /*ColourSelector::backgroundColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + 0x1007001, /*ColourSelector::labelTextColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + + 0x100ad00, /*KeyMappingEditorComponent::backgroundColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(), + 0x100ad01, /*KeyMappingEditorComponent::textColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + + FileSearchPathListComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuBackground).getARGB(), + + FileChooserDialogBox::titleTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(), + }; + + for (int i = 0; i < numElementsInArray (coloursToUse); i += 2) + setColour ((int) coloursToUse [i], Colour ((uint32) coloursToUse [i + 1])); +} diff --git a/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.h b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.h new file mode 100644 index 000000000..76b1371f9 --- /dev/null +++ b/source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.h @@ -0,0 +1,240 @@ +/* + ============================================================================== + + 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 JUCE_API LookAndFeel_V4 : public LookAndFeel_V3 +{ +public: + /** + A struct containing the set of colours to apply to the GUI + */ + class ColourScheme + { + public: + /** The standard set of colours to use. */ + enum UIColour + { + windowBackground = 0, + widgetBackground, + menuBackground, + outline, + defaultText, + defaultFill, + highlightedText, + highlightedFill, + menuText, + + numColours + }; + + template + ColourScheme (ItemColours... coloursToUse) + { + static_assert (sizeof... (coloursToUse) == numColours, "Must supply one colour for each UIColour item"); + const Colour c[] = { Colour (coloursToUse)... }; + + for (int i = 0; i < numColours; ++i) + palette[i] = c[i]; + } + + ColourScheme (const ColourScheme&) = default; + ColourScheme& operator= (const ColourScheme&) = default; + + /** Returns a colour from the scheme */ + Colour getUIColour (UIColour colourToGet) const noexcept; + + /** Sets a scheme colour. */ + void setUIColour (UIColour colourToSet, Colour newColour) noexcept; + + /** Returns true if two ColourPalette objects contain the same colours. */ + bool operator== (const ColourScheme&) const noexcept; + /** Returns false if two ColourPalette objects contain the same colours. */ + bool operator!= (const ColourScheme&) const noexcept; + + private: + Colour palette[numColours]; + }; + + //============================================================================== + /** Creates a LookAndFeel_V4 object with a default colour scheme. */ + LookAndFeel_V4(); + + /** Creates a LookAndFeel_V4 object with a given colour scheme. */ + LookAndFeel_V4 (ColourScheme); + + /** Destructor. */ + ~LookAndFeel_V4(); + + //============================================================================== + void setColourScheme (ColourScheme); + ColourScheme& getCurrentColourScheme() noexcept { return currentColourScheme; } + + static ColourScheme getDarkColourScheme(); + static ColourScheme getMidnightColourScheme(); + static ColourScheme getGreyColourScheme(); + static ColourScheme getLightColourScheme(); + + //============================================================================== + Button* createDocumentWindowButton (int) override; + void positionDocumentWindowButtons (DocumentWindow&, int, int, int, int, Button*, Button*, Button*, bool) override; + void drawDocumentWindowTitleBar (DocumentWindow&, Graphics&, int, int, int, int, const Image*, bool) override; + + //============================================================================== + void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour, + bool isMouseOverButton, bool isButtonDown) override; + + void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) override; + void drawTickBox (Graphics&, Component&, + float x, float y, float w, float h, + bool ticked, bool isEnabled, bool isMouseOverButton, bool isButtonDown) override; + + //============================================================================== + AlertWindow* createAlertWindow (const String& title, const String& message, + const String& button1, + const String& button2, + const String& button3, + AlertWindow::AlertIconType iconType, + int numButtons, Component* associatedComponent) override; + void drawAlertBox (Graphics&, AlertWindow&, const Rectangle& textArea, TextLayout&) override; + + int getAlertWindowButtonHeight() override; + Font getAlertWindowTitleFont() override; + Font getAlertWindowMessageFont() override; + Font getAlertWindowFont() override; + + //============================================================================== + void drawProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String& textToShow) override; + bool isProgressBarOpaque (ProgressBar&) override { return false; } + + //============================================================================== + int getDefaultScrollbarWidth() override; + void drawScrollbar (Graphics&, ScrollBar&, int x, int y, int width, int height, bool isScrollbarVertical, + int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown) override; + + //============================================================================== + Path getTickShape (float height) override; + Path getCrossShape (float height) override; + + //============================================================================== + void fillTextEditorBackground (Graphics&, int width, int height, TextEditor&) override; + void drawTextEditorOutline (Graphics&, int width, int height, TextEditor&) override; + + //============================================================================== + Button* createFileBrowserGoUpButton() override; + + void layoutFileBrowserComponent (FileBrowserComponent&, + DirectoryContentsDisplayComponent*, + FilePreviewComponent*, + ComboBox* currentPathBox, + TextEditor* filenameBox, + Button* goUpButton) override; + + void drawFileBrowserRow (Graphics&, int width, int height, + const File& file, const String& filename, Image* icon, + const String& fileSizeDescription, const String& fileTimeDescription, + bool isDirectory, bool isItemSelected, int itemIndex, + DirectoryContentsDisplayComponent&) override; + + //============================================================================== + void drawPopupMenuItem (Graphics&, const Rectangle& area, + bool isSeparator, bool isActive, bool isHighlighted, bool isTicked, bool hasSubMenu, + const String& text, const String& shortcutKeyText, + const Drawable* icon, const Colour* textColour) override; + + void getIdealPopupMenuItemSize (const String& text, bool isSeparator, int standardMenuItemHeight, + int& idealWidth, int& idealHeight) override; + + void drawMenuBarBackground (Graphics&, int width, int height, bool isMouseOverBar, MenuBarComponent&) override; + + void drawMenuBarItem (Graphics&, int width, int height, + int itemIndex, const String& itemText, + bool isMouseOverItem, bool isMenuOpen, bool isMouseOverBar, + MenuBarComponent&) override; + + //============================================================================== + void drawComboBox (Graphics&, int width, int height, bool isButtonDown, + int buttonX, int buttonY, int buttonW, int buttonH, + ComboBox&) override; + Font getComboBoxFont (ComboBox&) override; + void positionComboBoxText (ComboBox&, Label&) override; + + //============================================================================== + void drawLinearSlider (Graphics&, int x, int y, int width, int height, + float sliderPos, float minSliderPos, float maxSliderPos, + const Slider::SliderStyle, Slider&) override; + + void drawRotarySlider (Graphics&, int x, int y, int width, int height, + float sliderPosProportional, float rotaryStartAngle, + float rotaryEndAngle, Slider&) override; + + void drawPointer (Graphics&, float x, float y, float diameter, + const Colour&, int direction) noexcept; + + //============================================================================== + void drawTooltip (Graphics&, const String& text, int width, int height) override; + + //============================================================================== + void drawConcertinaPanelHeader (Graphics&, const Rectangle& area, + bool isMouseOver, bool isMouseDown, + ConcertinaPanel&, Component& panel) override; + + //============================================================================== + void drawLevelMeter (Graphics&, int, int, float) override; + + //============================================================================== + void paintToolbarBackground (Graphics&, int width, int height, Toolbar&) override; + + void paintToolbarButtonLabel (Graphics&, int x, int y, int width, int height, + const String& text, ToolbarItemComponent&) override; + + //============================================================================== + void drawPropertyPanelSectionHeader (Graphics&, const String& name, bool isOpen, int width, int height) override; + void drawPropertyComponentBackground (Graphics&, int width, int height, PropertyComponent&) override; + void drawPropertyComponentLabel (Graphics&, int width, int height, PropertyComponent&) override; + Rectangle getPropertyComponentContentPosition (PropertyComponent&) override; + + //============================================================================== + void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path&, Image&) override; + + //============================================================================== + void drawStretchableLayoutResizerBar (Graphics&, int, int, bool, bool, bool) override; + +private: + //============================================================================== + void drawLinearProgressBar (Graphics&, ProgressBar&, int width, int height, double progress); + void drawCircularProgressBar (Graphics&, ProgressBar&, const String&); + + int getPropertyComponentIndent (PropertyComponent&); + + //============================================================================== + void initialiseColours(); + ColourScheme currentColourScheme; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V4) +}; diff --git a/source/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp b/source/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp index b979ba481..bc9515b5b 100644 --- a/source/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp +++ b/source/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/menus/juce_MenuBarComponent.h b/source/modules/juce_gui_basics/menus/juce_MenuBarComponent.h index 22be75ba5..96a00c8f5 100644 --- a/source/modules/juce_gui_basics/menus/juce_MenuBarComponent.h +++ b/source/modules/juce_gui_basics/menus/juce_MenuBarComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MENUBARCOMPONENT_H_INCLUDED -#define JUCE_MENUBARCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -114,5 +115,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MenuBarComponent) }; - -#endif // JUCE_MENUBARCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp b/source/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp index ccfcbc49b..e5be870ab 100644 --- a/source/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp +++ b/source/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/menus/juce_MenuBarModel.h b/source/modules/juce_gui_basics/menus/juce_MenuBarModel.h index 4267661f6..01e6023d6 100644 --- a/source/modules/juce_gui_basics/menus/juce_MenuBarModel.h +++ b/source/modules/juce_gui_basics/menus/juce_MenuBarModel.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MENUBARMODEL_H_INCLUDED -#define JUCE_MENUBARMODEL_H_INCLUDED +#pragma once //============================================================================== @@ -130,7 +131,7 @@ public: virtual void menuItemSelected (int menuItemID, int topLevelMenuIndex) = 0; - /** This is called when the user starts/stops navigating the maenu bar. + /** This is called when the user starts/stops navigating the menu bar. @param isActive true when the user starts navigating the menu bar */ @@ -188,6 +189,3 @@ private: /** This typedef is just for compatibility with old code - newer code should use the MenuBarModel::Listener class directly. */ typedef MenuBarModel::Listener MenuBarModelListener; - - -#endif // JUCE_MENUBARMODEL_H_INCLUDED diff --git a/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp b/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp index c1dbcebab..27aa3e5d0 100644 --- a/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp +++ b/source/modules/juce_gui_basics/menus/juce_PopupMenu.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -157,12 +159,11 @@ private: && item.shortcutKeyDescription.isEmpty()) { String shortcutKey; - const Array keyPresses (item.commandManager->getKeyMappings() - ->getKeyPressesAssignedToCommand (item.itemID)); - for (int i = 0; i < keyPresses.size(); ++i) + for (auto& keypress : item.commandManager->getKeyMappings() + ->getKeyPressesAssignedToCommand (item.itemID)) { - const String key (keyPresses.getReference (i).getTextDescriptionWithIcons()); + auto key = keypress.getTextDescriptionWithIcons(); if (shortcutKey.isNotEmpty()) shortcutKey << ", "; @@ -190,29 +191,19 @@ private: class MenuWindow : public Component { public: - MenuWindow (const PopupMenu& menu, MenuWindow* const parentWindow, - const Options& opts, - const bool alignToRectangle, - const bool shouldDismissOnMouseUp, - ApplicationCommandManager** const manager) + MenuWindow (const PopupMenu& menu, MenuWindow* parentWindow, + const Options& opts, bool alignToRectangle, bool shouldDismissOnMouseUp, + ApplicationCommandManager** manager, float parentScaleFactor = 1.0f) : Component ("menu"), parent (parentWindow), options (opts), managerOfChosenCommand (manager), componentAttachedTo (options.targetComponent), - parentComponent (nullptr), - hasBeenOver (false), - needsToScroll (false), dismissOnMouseUp (shouldDismissOnMouseUp), - hideOnExit (false), - disableMouseMoves (false), - hasAnyJuceCompHadFocus (false), - numColumns (0), - contentHeight (0), - childYOffset (0), windowCreationTime (Time::getMillisecondCounter()), lastFocusedTime (windowCreationTime), - timeEnteredCurrentChildComp (windowCreationTime) + timeEnteredCurrentChildComp (windowCreationTime), + scaleFactor (parentWindow != nullptr ? parentScaleFactor : 1.0f) { setWantsKeyboardFocus (false); setMouseClickGrabsKeyboardFocus (false); @@ -221,32 +212,37 @@ public: setLookAndFeel (parent != nullptr ? &(parent->getLookAndFeel()) : menu.lookAndFeel.get()); - LookAndFeel& lf = getLookAndFeel(); + auto& lf = getLookAndFeel(); parentComponent = lf.getParentComponentForMenuOptions (options); + if (parentComponent == nullptr && parentWindow == nullptr && lf.shouldPopupMenuScaleWithTargetComponent (options)) + if (auto* targetComponent = options.getTargetComponent()) + scaleFactor = getApproximateScaleFactorForTargetComponent (targetComponent); + setOpaque (lf.findColour (PopupMenu::backgroundColourId).isOpaque() || ! Desktop::canUseSemiTransparentWindows()); for (int i = 0; i < menu.items.size(); ++i) { - PopupMenu::Item* const item = menu.items.getUnchecked (i); + auto item = menu.items.getUnchecked (i); if (i < menu.items.size() - 1 || ! item->isSeparator) items.add (new ItemComponent (*item, options.standardHeight, *this)); } - calculateWindowPos (options.targetArea, alignToRectangle); + Rectangle targetArea = options.targetArea / scaleFactor; + + calculateWindowPos (targetArea, alignToRectangle); setTopLeftPosition (windowPos.getPosition()); updateYPositions(); if (options.visibleItemID != 0) { - const Point targetPosition = - (parentComponent != nullptr ? parentComponent->getLocalPoint (nullptr, options.targetArea.getTopLeft()) - : options.targetArea.getTopLeft()); + auto targetPosition = parentComponent != nullptr ? parentComponent->getLocalPoint (nullptr, targetArea.getTopLeft()) + : targetArea.getTopLeft(); - const int y = targetPosition.getY() - windowPos.getY(); + auto y = targetPosition.getY() - windowPos.getY(); ensureItemIsVisible (options.visibleItemID, isPositiveAndBelow (y, windowPos.getHeight()) ? y : -1); } @@ -268,6 +264,8 @@ public: } lf.preparePopupMenuWindow (*this); + + getMouseState (Desktop::getInstance().getMainMouseSource()); // forces creation of a mouse source watcher for the main mouse } ~MenuWindow() @@ -289,7 +287,7 @@ public: void paintOverChildren (Graphics& g) override { - LookAndFeel& lf = getLookAndFeel(); + auto& lf = getLookAndFeel(); if (parentComponent != nullptr) lf.drawResizableFrame (g, getWidth(), getHeight(), BorderSize (PopupMenuSettings::borderSize)); @@ -309,7 +307,7 @@ public: //============================================================================== // hide this and all sub-comps - void hide (const PopupMenu::Item* const item, const bool makeInvisible) + void hide (const PopupMenu::Item* item, bool makeInvisible) { if (isVisible()) { @@ -337,7 +335,7 @@ public: if (item == nullptr) return 0; - if (CustomCallback* cc = item->customCallback) + if (auto* cc = item->customCallback.get()) if (! cc->menuItemTriggered()) return 0; @@ -355,7 +353,7 @@ public: if (item != nullptr) { // need a copy of this on the stack as the one passed in will get deleted during this call - const PopupMenu::Item mi (*item); + auto mi (*item); hide (&mi, false); } else @@ -365,6 +363,8 @@ public: } } + float getDesktopScaleFactor() const override { return scaleFactor * Desktop::getInstance().getGlobalScaleFactor(); } + //============================================================================== bool keyPressed (const KeyPress& key) override { @@ -429,9 +429,9 @@ public: { WeakReference deletionChecker (this); - for (int i = mouseSourceStates.size(); --i >= 0;) + for (auto* ms : mouseSourceStates) { - mouseSourceStates.getUnchecked (i)->timerCallback(); + ms->timerCallback(); if (deletionChecker == nullptr) return; @@ -447,7 +447,7 @@ public: // as they'll expect the menu to go away, and in fact it'll just // come back. So only dismiss synchronously if they're not on the original // comp that we're attached to. - const Point mousePos (componentAttachedTo->getMouseXYRelative()); + auto mousePos = componentAttachedTo->getMouseXYRelative(); if (componentAttachedTo->reallyContains (mousePos, true)) { @@ -495,7 +495,7 @@ public: return false; } - if (MenuWindow* currentlyModalWindow = dynamic_cast (Component::getCurrentlyModalComponent())) + if (auto* currentlyModalWindow = dynamic_cast (Component::getCurrentlyModalComponent())) if (! treeContains (currentlyModalWindow)) return false; @@ -510,14 +510,11 @@ public: MouseSourceState& getMouseState (MouseInputSource source) { - for (int i = mouseSourceStates.size(); --i >= 0;) - { - MouseSourceState& ms = *mouseSourceStates.getUnchecked (i); - if (ms.source == source) - return ms; - } + for (auto* ms : mouseSourceStates) + if (ms->source == source) + return *ms; - MouseSourceState* ms = new MouseSourceState (*this, source); + auto ms = new MouseSourceState (*this, source); mouseSourceStates.add (ms); return *ms; } @@ -537,8 +534,8 @@ public: bool isAnyMouseOver() const { - for (int i = 0; i < mouseSourceStates.size(); ++i) - if (mouseSourceStates.getUnchecked (i)->isOver()) + for (auto* ms : mouseSourceStates) + if (ms->isOver()) return true; return false; @@ -589,13 +586,12 @@ public: //============================================================================== Rectangle getParentArea (Point targetPoint) { - Rectangle parentArea (Desktop::getInstance().getDisplays() - .getDisplayContaining (targetPoint) - #if JUCE_MAC - .userArea); - #else - .totalArea); // on windows, don't stop the menu overlapping the taskbar - #endif + auto parentArea = Desktop::getInstance().getDisplays().getDisplayContaining (targetPoint) + #if JUCE_MAC + .userArea; + #else + .totalArea; // on windows, don't stop the menu overlapping the taskbar + #endif if (parentComponent == nullptr) return parentArea; @@ -608,7 +604,7 @@ public: void calculateWindowPos (Rectangle target, const bool alignToRectangle) { - const Rectangle parentArea = getParentArea (target.getCentre()); + auto parentArea = getParentArea (target.getCentre()); if (parentComponent != nullptr) target = parentComponent->getLocalArea (nullptr, target).getIntersection (parentArea); @@ -704,10 +700,9 @@ public: workOutBestSize (maxMenuW); // to update col widths break; } - else if (totalW > maxMenuW / 2 || contentHeight < maxMenuH) - { + + if (totalW > maxMenuW / 2 || contentHeight < maxMenuH) break; - } } while (numColumns < maximumNumColumns); @@ -767,12 +762,12 @@ public: for (int i = items.size(); --i >= 0;) { - if (ItemComponent* const m = items.getUnchecked (i)) + if (auto* m = items.getUnchecked (i)) { if (m->item.itemID == itemID && windowPos.getHeight() > PopupMenuSettings::scrollZone * 4) { - const int currentY = m->getY(); + auto currentY = m->getY(); if (wantedY > 0 || currentY < 0 || m->getBottom() > windowPos.getHeight()) { @@ -782,16 +777,16 @@ public: windowPos.getHeight() - (PopupMenuSettings::scrollZone + m->getHeight())), currentY); - const Rectangle parantArea = getParentArea (windowPos.getPosition()); + auto parentArea = getParentArea (windowPos.getPosition()); int deltaY = wantedY - currentY; - windowPos.setSize (jmin (windowPos.getWidth(), parantArea.getWidth()), - jmin (windowPos.getHeight(), parantArea.getHeight())); + windowPos.setSize (jmin (windowPos.getWidth(), parentArea.getWidth()), + jmin (windowPos.getHeight(), parentArea.getHeight())); - const int newY = jlimit (parantArea.getY(), - parantArea.getBottom() - windowPos.getHeight(), - windowPos.getY() + deltaY); + auto newY = jlimit (parentArea.getY(), + parentArea.getBottom() - windowPos.getHeight(), + windowPos.getY() + deltaY); deltaY -= newY - windowPos.getY(); @@ -809,7 +804,7 @@ public: void resizeToBestWindowPos() { - Rectangle r (windowPos); + auto r = windowPos; if (childYOffset < 0) { @@ -866,7 +861,7 @@ public: for (int i = 0; i < numChildren; ++i) { - Component* const c = items.getUnchecked (childNum + i); + auto* c = items.getUnchecked (childNum + i); c->setBounds (x, y, colW, c->getHeight()); y += c->getHeight(); } @@ -905,7 +900,7 @@ public: options.withTargetScreenArea (childComp->getScreenBounds()) .withMinimumWidth (0) .withTargetComponent (nullptr), - false, dismissOnMouseUp, managerOfChosenCommand); + false, dismissOnMouseUp, managerOfChosenCommand, scaleFactor); activeSubMenu->setVisible (true); // (must be called before enterModalState on Windows to avoid DropShadower confusion) activeSubMenu->enterModalState (false); @@ -937,7 +932,7 @@ public: { start += delta; - if (ItemComponent* mic = items.getUnchecked ((start + items.size()) % items.size())) + if (auto* mic = items.getUnchecked ((start + items.size()) % items.size())) { if (canBeTriggered (mic->item) || hasActiveSubMenu (mic->item)) { @@ -960,22 +955,39 @@ public: bool isTopScrollZoneActive() const noexcept { return canScroll() && childYOffset > 0; } bool isBottomScrollZoneActive() const noexcept { return canScroll() && childYOffset < contentHeight - windowPos.getHeight(); } + //============================================================================== + static float getApproximateScaleFactorForTargetComponent (Component* targetComponent) + { + AffineTransform transform; + + for (auto* target = targetComponent; target != nullptr; target = target->getParentComponent()) + { + transform = transform.followedBy (target->getTransform()); + + if (target->isOnDesktop()) + transform = transform.scaled (target->getDesktopScaleFactor()); + } + + return (transform.getScaleFactor() / Desktop::getInstance().getGlobalScaleFactor()); + } + //============================================================================== MenuWindow* parent; const Options options; OwnedArray items; ApplicationCommandManager** managerOfChosenCommand; WeakReference componentAttachedTo; - Component* parentComponent; + Component* parentComponent = nullptr; Rectangle windowPos; - bool hasBeenOver, needsToScroll; - bool dismissOnMouseUp, hideOnExit, disableMouseMoves, hasAnyJuceCompHadFocus; - int numColumns, contentHeight, childYOffset; + bool hasBeenOver = false, needsToScroll = false; + bool dismissOnMouseUp, hideOnExit = false, disableMouseMoves = false, hasAnyJuceCompHadFocus = false; + int numColumns = 0, contentHeight = 0, childYOffset = 0; Component::SafePointer currentChild; ScopedPointer activeSubMenu; Array columnWidths; uint32 windowCreationTime, lastFocusedTime, timeEnteredCurrentChildComp; OwnedArray mouseSourceStates; + float scaleFactor; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MenuWindow) }; @@ -985,10 +997,9 @@ class MouseSourceState : private Timer { public: MouseSourceState (MenuWindow& w, MouseInputSource s) - : window (w), source (s), scrollAcceleration (1.0), - lastScrollTime (Time::getMillisecondCounter()), - lastMouseMoveTime (0), isDown (false) + : window (w), source (s), lastScrollTime (Time::getMillisecondCounter()) { + startTimerHz (20); } void handleMouseEvent (const MouseEvent& e) @@ -1016,15 +1027,14 @@ public: private: Point lastMousePos; - double scrollAcceleration; - uint32 lastScrollTime, lastMouseMoveTime; - bool isDown; + double scrollAcceleration = 0; + uint32 lastScrollTime, lastMouseMoveTime = 0; + bool isDown = false; void handleMousePosition (Point globalMousePos) { - const Point localMousePos (window.getLocalPoint (nullptr, globalMousePos)); - - const uint32 timeNow = Time::getMillisecondCounter(); + auto localMousePos = window.getLocalPoint (nullptr, globalMousePos); + auto timeNow = Time::getMillisecondCounter(); if (timeNow > window.timeEnteredCurrentChildComp + 100 && window.reallyContains (localMousePos, true) @@ -1104,11 +1114,11 @@ private: if (! isMovingTowardsMenu) { - Component* c = window.getComponentAt (localMousePos); + auto* c = window.getComponentAt (localMousePos); if (c == &window) c = nullptr; - ItemComponent* itemUnderMouse = dynamic_cast (c); + auto* itemUnderMouse = dynamic_cast (c); if (itemUnderMouse == nullptr && c != nullptr) itemUnderMouse = c->findParentComponentOfClass(); @@ -1137,10 +1147,10 @@ private: // submenu. To do this, look at whether the mouse stays inside a triangular region that // extends from the last mouse pos to the submenu's rectangle.. - const Rectangle itemScreenBounds (window.activeSubMenu->getScreenBounds()); - float subX = (float) itemScreenBounds.getX(); + auto itemScreenBounds = window.activeSubMenu->getScreenBounds(); + auto subX = (float) itemScreenBounds.getX(); - Point oldGlobalPos (lastMousePos); + auto oldGlobalPos = lastMousePos; if (itemScreenBounds.getX() > window.getX()) { @@ -1200,8 +1210,7 @@ private: //============================================================================== struct NormalComponentWrapper : public PopupMenu::CustomComponent { - NormalComponentWrapper (Component* const comp, const int w, const int h, - const bool triggerMenuItemAutomaticallyWhenClicked) + NormalComponentWrapper (Component* comp, int w, int h, bool triggerMenuItemAutomaticallyWhenClicked) : PopupMenu::CustomComponent (triggerMenuItemAutomaticallyWhenClicked), width (w), height (h) { @@ -1216,7 +1225,7 @@ struct NormalComponentWrapper : public PopupMenu::CustomComponent void resized() override { - if (Component* const child = getChildComponent (0)) + if (auto* child = getChildComponent (0)) child->setBounds (getLocalBounds()); } @@ -1251,7 +1260,6 @@ PopupMenu& PopupMenu::operator= (const PopupMenu& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS PopupMenu::PopupMenu (PopupMenu&& other) noexcept : lookAndFeel (other.lookAndFeel) { @@ -1266,7 +1274,6 @@ PopupMenu& PopupMenu::operator= (PopupMenu&& other) noexcept lookAndFeel = other.lookAndFeel; return *this; } -#endif PopupMenu::~PopupMenu() { @@ -1349,7 +1356,7 @@ static Drawable* createDrawableFromImage (const Image& im) { if (im.isValid()) { - DrawableImage* d = new DrawableImage(); + auto d = new DrawableImage(); d->setImage (im); return d; } @@ -1380,10 +1387,10 @@ void PopupMenu::addCommandItem (ApplicationCommandManager* commandManager, { jassert (commandManager != nullptr && commandID != 0); - if (const ApplicationCommandInfo* const registeredInfo = commandManager->getCommandForID (commandID)) + if (auto* registeredInfo = commandManager->getCommandForID (commandID)) { ApplicationCommandInfo info (*registeredInfo); - ApplicationCommandTarget* const target = commandManager->getTargetForCommand (commandID, info); + auto* target = commandManager->getTargetForCommand (commandID, info); Item i; i.text = displayName.isNotEmpty() ? displayName : info.shortName; @@ -1564,8 +1571,7 @@ Component* PopupMenu::createWindow (const Options& options, struct PopupMenuCompletionCallback : public ModalComponentManager::Callback { PopupMenuCompletionCallback() - : managerOfChosenCommand (nullptr), - prevFocused (Component::getCurrentlyFocusedComponent()), + : prevFocused (Component::getCurrentlyFocusedComponent()), prevTopLevel (prevFocused != nullptr ? prevFocused->getTopLevelComponent() : nullptr) { PopupMenuSettings::menuWasHiddenBecauseOfAppChange = false; @@ -1594,7 +1600,7 @@ struct PopupMenuCompletionCallback : public ModalComponentManager::Callback } } - ApplicationCommandManager* managerOfChosenCommand; + ApplicationCommandManager* managerOfChosenCommand = nullptr; ScopedPointer component; WeakReference prevFocused, prevTopLevel; @@ -1607,7 +1613,7 @@ int PopupMenu::showWithOptionalCallback (const Options& options, ModalComponentM ScopedPointer userCallbackDeleter (userCallback); ScopedPointer callback (new PopupMenuCompletionCallback()); - if (Component* window = createWindow (options, &(callback->managerOfChosenCommand))) + if (auto* window = createWindow (options, &(callback->managerOfChosenCommand))) { callback->component = window; @@ -1695,11 +1701,11 @@ int PopupMenu::showAt (Component* componentToAttachTo, bool JUCE_CALLTYPE PopupMenu::dismissAllActiveMenus() { - const Array& windows = HelperClasses::MenuWindow::getActiveWindows(); - const int numWindows = windows.size(); + auto& windows = HelperClasses::MenuWindow::getActiveWindows(); + auto numWindows = windows.size(); for (int i = numWindows; --i >= 0;) - if (HelperClasses::MenuWindow* const pmw = windows[i]) + if (auto* pmw = windows[i]) pmw->dismissMenu (nullptr); return numWindows > 0; @@ -1710,8 +1716,8 @@ int PopupMenu::getNumItems() const noexcept { int num = 0; - for (int i = items.size(); --i >= 0;) - if (! items.getUnchecked (i)->isSeparator) + for (auto* mi : items) + if (! mi->isSeparator) ++num; return num; @@ -1719,30 +1725,24 @@ int PopupMenu::getNumItems() const noexcept bool PopupMenu::containsCommandItem (const int commandID) const { - for (int i = items.size(); --i >= 0;) - { - const Item& mi = *items.getUnchecked (i); - - if ((mi.itemID == commandID && mi.commandManager != nullptr) - || (mi.subMenu != nullptr && mi.subMenu->containsCommandItem (commandID))) + for (auto* mi : items) + if ((mi->itemID == commandID && mi->commandManager != nullptr) + || (mi->subMenu != nullptr && mi->subMenu->containsCommandItem (commandID))) return true; - } return false; } bool PopupMenu::containsAnyActiveItems() const noexcept { - for (int i = items.size(); --i >= 0;) + for (auto* mi : items) { - const Item& mi = *items.getUnchecked (i); - - if (mi.subMenu != nullptr) + if (mi->subMenu != nullptr) { - if (mi.subMenu->containsAnyActiveItems()) + if (mi->subMenu->containsAnyActiveItems()) return true; } - else if (mi.isEnabled) + else if (mi->isEnabled) { return true; } @@ -1775,9 +1775,9 @@ void PopupMenu::CustomComponent::setHighlighted (bool shouldBeHighlighted) void PopupMenu::CustomComponent::triggerMenuItem() { - if (HelperClasses::ItemComponent* const mic = findParentComponentOfClass()) + if (auto* mic = findParentComponentOfClass()) { - if (HelperClasses::MenuWindow* const pmw = mic->findParentComponentOfClass()) + if (auto* pmw = mic->findParentComponentOfClass()) { pmw->dismissMenu (&mic->item); } diff --git a/source/modules/juce_gui_basics/menus/juce_PopupMenu.h b/source/modules/juce_gui_basics/menus/juce_PopupMenu.h index edfcb088f..14d36b8fc 100644 --- a/source/modules/juce_gui_basics/menus/juce_PopupMenu.h +++ b/source/modules/juce_gui_basics/menus/juce_PopupMenu.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_POPUPMENU_H_INCLUDED -#define JUCE_POPUPMENU_H_INCLUDED +#pragma once //============================================================================== @@ -96,10 +97,11 @@ public: /** Copies this menu from another one. */ PopupMenu& operator= (const PopupMenu& other); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ PopupMenu (PopupMenu&& other) noexcept; + + /** Move assignment operator */ PopupMenu& operator= (PopupMenu&& other) noexcept; - #endif //============================================================================== /** Resets the menu, removing all its items. */ @@ -717,6 +719,10 @@ public: virtual Component* getParentComponentForMenuOptions (const PopupMenu::Options& options) = 0; virtual void preparePopupMenuWindow (Component& newWindow) = 0; + + /** Return true if you want your popup menus to scale with the target component's AffineTransform + or scale factor */ + virtual bool shouldPopupMenuScaleWithTargetComponent (const PopupMenu::Options& options) = 0; }; private: @@ -738,5 +744,3 @@ private: JUCE_LEAK_DETECTOR (PopupMenu) }; - -#endif // JUCE_POPUPMENU_H_INCLUDED diff --git a/source/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp b/source/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp index 7a547854b..b2595731a 100644 --- a/source/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp +++ b/source/modules/juce_gui_basics/misc/juce_BubbleComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/misc/juce_BubbleComponent.h b/source/modules/juce_gui_basics/misc/juce_BubbleComponent.h index 8536f9bd7..4b03495c2 100644 --- a/source/modules/juce_gui_basics/misc/juce_BubbleComponent.h +++ b/source/modules/juce_gui_basics/misc/juce_BubbleComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BUBBLECOMPONENT_H_INCLUDED -#define JUCE_BUBBLECOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -180,6 +181,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BubbleComponent) }; - - -#endif // JUCE_BUBBLECOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/misc/juce_DropShadower.cpp b/source/modules/juce_gui_basics/misc/juce_DropShadower.cpp index 0c3f4ad62..42cac3e67 100644 --- a/source/modules/juce_gui_basics/misc/juce_DropShadower.cpp +++ b/source/modules/juce_gui_basics/misc/juce_DropShadower.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/misc/juce_DropShadower.h b/source/modules/juce_gui_basics/misc/juce_DropShadower.h index 584f548a0..d201430b7 100644 --- a/source/modules/juce_gui_basics/misc/juce_DropShadower.h +++ b/source/modules/juce_gui_basics/misc/juce_DropShadower.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DROPSHADOWER_H_INCLUDED -#define JUCE_DROPSHADOWER_H_INCLUDED +#pragma once //============================================================================== @@ -75,6 +76,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DropShadower) }; - - -#endif // JUCE_DROPSHADOWER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp b/source/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp new file mode 100644 index 000000000..103266104 --- /dev/null +++ b/source/modules/juce_gui_basics/misc/juce_JUCESplashScreen.cpp @@ -0,0 +1,356 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +/* + ============================================================================== + + In accordance with the terms of the JUCE 5 End-Use License Agreement, the + JUCE Code in SECTION A cannot be removed, changed or otherwise rendered + ineffective unless you have a JUCE Indie or Pro license, or are using JUCE + under the GPL v3 license. + + End User License Agreement: www.juce.com/juce-5-licence + ============================================================================== +*/ + +// BEGIN SECTION A + +#if ! defined (JUCE_REPORT_APP_USAGE) + #define JUCE_REPORT_APP_USAGE 1 +#endif + +#if ! defined (JUCE_DISPLAY_SPLASH_SCREEN) + #define JUCE_DISPLAY_SPLASH_SCREEN 1 +#endif + +#if ! defined (JUCE_USE_DARK_SPLASH_SCREEN) + #define JUCE_USE_DARK_SPLASH_SCREEN 1 +#endif + +static const int millisecondsToDisplaySplash = 2000, splashScreenFadeOutTime = 2000; +static const int splashScreenLogoWidth = 123, splashScreenLogoHeight = 63; +static uint32 splashDisplayTime = 0; +static bool appUsageReported = false; + + +Rectangle getLogoArea (Rectangle parentRect) +{ + return parentRect.reduced (6.0f) + .removeFromRight ((float) splashScreenLogoWidth) + .removeFromBottom ((float) splashScreenLogoHeight); +} + +//============================================================================== +struct ReportingThread; + +struct ReportingThreadContainer : public ChangeListener, + public DeletedAtShutdown +{ + void sendReport (String, String&, StringPairArray&); + void changeListenerCallback (ChangeBroadcaster*) override; + + ScopedPointer reportingThread; + + juce_DeclareSingleton_SingleThreaded_Minimal (ReportingThreadContainer) +}; + +juce_ImplementSingleton_SingleThreaded (ReportingThreadContainer); + +//============================================================================== +struct ReportingThread : public Thread, + private ChangeBroadcaster +{ + ReportingThread (ReportingThreadContainer& container, + String& address, + String& userAgent, + StringPairArray& parameters) + : Thread ("JUCE app usage reporting"), + threadContainer (container), + headers ("User-Agent: " + userAgent) + { + StringArray postData; + + for (auto& key : parameters.getAllKeys()) + if (parameters[key].isNotEmpty()) + postData.add (key + "=" + URL::addEscapeChars (parameters[key], true)); + + url = URL (address).withPOSTData (postData.joinIntoString ("&")); + + addChangeListener (&threadContainer); + } + + ~ReportingThread() + { + removeChangeListener (&threadContainer); + + if (webStream != nullptr) + webStream->cancel(); + + stopThread (2000); + } + + void run() override + { + webStream = new WebInputStream (url, true); + webStream->withExtraHeaders (headers); + webStream->connect (nullptr); + + sendChangeMessage(); + } + +private: + ReportingThreadContainer& threadContainer; + URL url; + String headers; + ScopedPointer webStream; +}; + +//============================================================================== +void ReportingThreadContainer::sendReport (String address, String& userAgent, StringPairArray& parameters) +{ + reportingThread = new ReportingThread (*this, address, userAgent, parameters); + + reportingThread->startThread(); +} + +void ReportingThreadContainer::changeListenerCallback (ChangeBroadcaster*) +{ + reportingThread = nullptr; +} + +//============================================================================== +JUCESplashScreen::JUCESplashScreen (Component& parent) +{ + ignoreUnused (hasStartedFading); + ignoreUnused (parent); + + #if JUCE_REPORT_APP_USAGE + if (! appUsageReported) + { + const ScopedTryLock appUsageReportingLock (appUsageReporting); + + if (appUsageReportingLock.isLocked() && ! appUsageReported) + { + const auto deviceDescription = SystemStats::getDeviceDescription(); + const auto deviceString = SystemStats::getDeviceIdentifiers().joinIntoString (":"); + const auto deviceIdentifier = String::toHexString (deviceString.hashCode64()); + const auto osName = SystemStats::getOperatingSystemName(); + + StringPairArray data; + + data.set ("v", "1"); + data.set ("tid", "UA-19759318-3"); + data.set ("cid", deviceIdentifier); + data.set ("t", "event"); + data.set ("ec", "info"); + data.set ("ea", "appStarted"); + + data.set ("cd1", SystemStats::getJUCEVersion()); + data.set ("cd2", osName); + data.set ("cd3", deviceDescription); + data.set ("cd4", deviceIdentifier); + + String appType, appName, appVersion, appManufacturer; + + #if defined(JucePlugin_Name) + appType = "Plugin"; + appName = JucePlugin_Name; + appVersion = JucePlugin_VersionString; + appManufacturer = JucePlugin_Manufacturer; + #else + if (JUCEApplicationBase::isStandaloneApp()) + { + appType = "Application"; + + if (auto* app = JUCEApplicationBase::getInstance()) + { + appName = app->getApplicationName(); + appVersion = app->getApplicationVersion(); + } + } + else + { + appType = "Library"; + } + #endif + + data.set ("cd5", appType); + data.set ("cd6", appName); + data.set ("cd7", appVersion); + data.set ("cd8", appManufacturer); + + data.set ("an", appName); + data.set ("av", appVersion); + + auto agentCPUVendor = SystemStats::getCpuVendor(); + + if (agentCPUVendor.isEmpty()) + agentCPUVendor = "CPU"; + + auto agentOSName = osName.replaceCharacter ('.', '_') + .replace ("iOS", "iPhone OS"); + #if JUCE_IOS + agentOSName << " like Mac OS X"; + #endif + + String userAgent; + userAgent << "Mozilla/5.0 (" + << deviceDescription << ";" + << agentCPUVendor << " " << agentOSName << ";" + << SystemStats::getDisplayLanguage() << ")"; + + ReportingThreadContainer::getInstance()->sendReport ("https://www.google-analytics.com/collect", userAgent, data); + + appUsageReported = true; + } + } + #else + ignoreUnused (appUsageReported); + #endif + + #if JUCE_DISPLAY_SPLASH_SCREEN + if (splashDisplayTime == 0 + || Time::getMillisecondCounter() < splashDisplayTime + (uint32) millisecondsToDisplaySplash) + { + content = getSplashScreenLogo(); + + setAlwaysOnTop (true); + parent.addAndMakeVisible (this); + } + else + #endif + { + startTimer (1); + } +} + +JUCESplashScreen::~JUCESplashScreen() +{ +} + +Drawable* JUCESplashScreen::getSplashScreenLogo() +{ + const char* svgData = R"JUCESPLASHSCREEN( + + + + + + + + + + " + R"JUCESPLASHSCREEN( + + + + + + + + + + + + + + + + )JUCESPLASHSCREEN"; + + ScopedPointer svgXml (XmlDocument::parse (svgData)); + return Drawable::createFromSVG (*svgXml); +} + +void JUCESplashScreen::paint (Graphics& g) +{ + auto r = getLocalBounds().toFloat(); + 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), + Colour (0xff000000), bottomRight, false); + cg.addColour (0.25f, Colour (0x10000000)); + cg.addColour (0.50f, Colour (0x30000000)); + cg.addColour (0.75f, Colour (0x70000000)); + g.setFillType (cg); + g.fillAll(); + + content->drawWithin (g, getLogoArea (r), RectanglePlacement::centred, 1.0f); + + if (splashDisplayTime == 0) + splashDisplayTime = Time::getMillisecondCounter(); + + if (! isTimerRunning()) + startTimer (millisecondsToDisplaySplash); +} + +void JUCESplashScreen::timerCallback() +{ + #if JUCE_DISPLAY_SPLASH_SCREEN + if (isVisible() && ! hasStartedFading) + { + hasStartedFading = true; + fader.animateComponent (this, getBounds(), 0.0f, splashScreenFadeOutTime, false, 0, 0); + } + + if (hasStartedFading && ! fader.isAnimating()) + #endif + delete this; +} + +void JUCESplashScreen::parentSizeChanged() +{ + if (auto* p = getParentComponent()) + setBounds (p->getLocalBounds().removeFromBottom (splashScreenLogoHeight * 3) + .removeFromRight (splashScreenLogoWidth * 3)); +} + +void JUCESplashScreen::parentHierarchyChanged() +{ + toFront (false); +} + +bool JUCESplashScreen::hitTest (int x, int y) +{ + return getLogoArea (getLocalBounds().toFloat()).contains ((float) x, (float) y); +} + +void JUCESplashScreen::mouseUp (const MouseEvent&) +{ + URL juceWebsite ("https://juce.com"); + juceWebsite.launchInDefaultBrowser(); +} + +// END SECTION A diff --git a/source/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h b/source/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h new file mode 100644 index 000000000..fc733568b --- /dev/null +++ b/source/modules/juce_gui_basics/misc/juce_JUCESplashScreen.h @@ -0,0 +1,72 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +/* + ============================================================================== + + In accordance with the terms of the JUCE 5 End-Use License Agreement, the + JUCE Code in SECTION A cannot be removed, changed or otherwise rendered + ineffective unless you have a JUCE Indie or Pro license, or are using JUCE + under the GPL v3 license. + + End User License Agreement: www.juce.com/juce-5-licence + ============================================================================== +*/ + +// BEGIN SECTION A + +#pragma once + +/** + The standard JUCE splash screen component. +*/ +class JUCE_API JUCESplashScreen : public Component, + private Timer, + private DeletedAtShutdown +{ +public: + JUCESplashScreen (Component& parentToAddTo); + ~JUCESplashScreen(); + + static Drawable* getSplashScreenLogo(); + +private: + void paint (Graphics&) override; + void timerCallback() override; + void parentSizeChanged() override; + void parentHierarchyChanged() override; + bool hitTest (int, int) override; + void mouseUp (const MouseEvent&) override; + + ScopedPointer content; + CriticalSection appUsageReporting; + ComponentAnimator fader; + bool hasStartedFading = false; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JUCESplashScreen) +}; + +// END SECTION A diff --git a/source/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp b/source/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp index 139ae269e..d5c9f3709 100644 --- a/source/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp +++ b/source/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/mouse/juce_ComponentDragger.h b/source/modules/juce_gui_basics/mouse/juce_ComponentDragger.h index 7475710f8..ab6141cdc 100644 --- a/source/modules/juce_gui_basics/mouse/juce_ComponentDragger.h +++ b/source/modules/juce_gui_basics/mouse/juce_ComponentDragger.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMPONENTDRAGGER_H_INCLUDED -#define JUCE_COMPONENTDRAGGER_H_INCLUDED +#pragma once //============================================================================== @@ -95,5 +96,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentDragger) }; - -#endif // JUCE_COMPONENTDRAGGER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp b/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp index 527c8ea8a..14bf227fe 100644 --- a/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp +++ b/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -40,8 +42,7 @@ public: : sourceDetails (desc, sourceComponent, Point()), image (im), owner (ddc), mouseDragSource (mouseSource), - imageOffset (offset), - hasCheckedForExternalDrag (false) + imageOffset (offset) { updateSize(); @@ -211,7 +212,7 @@ private: DragAndDropContainer& owner; WeakReference mouseDragSource, currentlyOverComp; const Point imageOffset; - bool hasCheckedForExternalDrag; + bool hasCheckedForExternalDrag = false; Time lastTimeOverTarget; void updateSize() @@ -294,27 +295,6 @@ private: target->itemDragMove (details); } - struct ExternalDragAndDropMessage : public CallbackMessage - { - ExternalDragAndDropMessage (const StringArray& f, bool canMove) - : files (f), canMoveFiles (canMove) - {} - - ExternalDragAndDropMessage (const String& t) : text (t), canMoveFiles() {} - - void messageCallback() override - { - if (text.isEmpty()) - DragAndDropContainer::performExternalDragDropOfFiles (files, canMoveFiles); - else - DragAndDropContainer::performExternalDragDropOfText (text); - } - - String text; - StringArray files; - bool canMoveFiles; - }; - void checkForExternalDrag (DragAndDropTarget::SourceDetails& details, Point screenPos) { if (! hasCheckedForExternalDrag) @@ -322,21 +302,26 @@ private: if (Desktop::getInstance().findComponentAt (screenPos) == nullptr) { hasCheckedForExternalDrag = true; - StringArray files; - String text; - bool canMoveFiles = false; if (ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown()) { + StringArray files; + bool canMoveFiles = false; + if (owner.shouldDropFilesWhenDraggedExternally (details, files, canMoveFiles) && ! files.isEmpty()) { - (new ExternalDragAndDropMessage (files, canMoveFiles))->post(); + MessageManager::callAsync ([=]() { DragAndDropContainer::performExternalDragDropOfFiles (files, canMoveFiles); }); deleteSelf(); + return; } - else if (owner.shouldDropTextWhenDraggedExternally (details, text) && text.isNotEmpty()) + + String text; + + if (owner.shouldDropTextWhenDraggedExternally (details, text) && text.isNotEmpty()) { - (new ExternalDragAndDropMessage (text))->post(); + MessageManager::callAsync ([=]() { DragAndDropContainer::performExternalDragDropOfText (text); }); deleteSelf(); + return; } } } diff --git a/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h b/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h index a80705781..05793358e 100644 --- a/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h +++ b/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAGANDDROPCONTAINER_H_INCLUDED -#define JUCE_DRAGANDDROPCONTAINER_H_INCLUDED +#pragma once //============================================================================== @@ -130,11 +131,14 @@ public: @param files a list of filenames to drag @param canMoveFiles if true, the app that receives the files is allowed to move the files to a new location (if this is appropriate). If false, the receiver is expected to make a copy of them. - @returns true if the files were successfully dropped somewhere, or false if it - was interrupted + @param sourceComponent Normally, JUCE will assume that the component under the mouse is the source component + of the drag, but you can use this parameter to override this. + @returns true if the files were successfully dropped somewhere, or false if it + was interrupted @see performExternalDragDropOfText */ - static bool performExternalDragDropOfFiles (const StringArray& files, bool canMoveFiles); + static bool performExternalDragDropOfFiles (const StringArray& files, bool canMoveFiles, + Component* sourceComponent = nullptr); /** This performs a synchronous drag-and-drop of a block of text to some external application. @@ -144,12 +148,14 @@ public: uses a native operating system drag-and-drop operation to move or copy some text to another application. - @param text the text to copy - @returns true if the text was successfully dropped somewhere, or false if it - was interrupted + @param text the text to copy + @param sourceComponent Normally, JUCE will assume that the component under the mouse is the source component + of the drag, but you can use this parameter to override this. + @returns true if the text was successfully dropped somewhere, or false if it + was interrupted @see performExternalDragDropOfFiles */ - static bool performExternalDragDropOfText (const String& text); + static bool performExternalDragDropOfText (const String& text, Component* sourceComponent = nullptr); protected: /** Override this if you want to be able to perform an external drag of a set of files @@ -206,6 +212,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DragAndDropContainer) }; - - -#endif // JUCE_DRAGANDDROPCONTAINER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h b/source/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h index 7d8184129..886948e9f 100644 --- a/source/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h +++ b/source/modules/juce_gui_basics/mouse/juce_DragAndDropTarget.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DRAGANDDROPTARGET_H_INCLUDED -#define JUCE_DRAGANDDROPTARGET_H_INCLUDED +#pragma once //============================================================================== @@ -148,5 +149,3 @@ private: virtual int itemDropped (const String&, Component*, int, int) { return 0; } #endif }; - -#endif // JUCE_DRAGANDDROPTARGET_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h b/source/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h index e949ea3f4..465e234c9 100644 --- a/source/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h +++ b/source/modules/juce_gui_basics/mouse/juce_FileDragAndDropTarget.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILEDRAGANDDROPTARGET_H_INCLUDED -#define JUCE_FILEDRAGANDDROPTARGET_H_INCLUDED +#pragma once /** Components derived from this class can have files dropped onto them by an external application. @@ -99,6 +100,3 @@ public: */ virtual void filesDropped (const StringArray& files, int x, int y) = 0; }; - - -#endif // JUCE_FILEDRAGANDDROPTARGET_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_LassoComponent.h b/source/modules/juce_gui_basics/mouse/juce_LassoComponent.h index 65e2f16e6..77663e5e0 100644 --- a/source/modules/juce_gui_basics/mouse/juce_LassoComponent.h +++ b/source/modules/juce_gui_basics/mouse/juce_LassoComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LASSOCOMPONENT_H_INCLUDED -#define JUCE_LASSOCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -218,6 +219,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LassoComponent) }; - - -#endif // JUCE_LASSOCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp b/source/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp index f1b834cc5..7716e519a 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp +++ b/source/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -171,7 +173,6 @@ MouseCursor& MouseCursor::operator= (const MouseCursor& other) return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS MouseCursor::MouseCursor (MouseCursor&& other) noexcept : cursorHandle (other.cursorHandle) { @@ -183,7 +184,6 @@ MouseCursor& MouseCursor::operator= (MouseCursor&& other) noexcept std::swap (cursorHandle, other.cursorHandle); return *this; } -#endif bool MouseCursor::operator== (const MouseCursor& other) const noexcept { diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseCursor.h b/source/modules/juce_gui_basics/mouse/juce_MouseCursor.h index ce6983b38..0856fd656 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseCursor.h +++ b/source/modules/juce_gui_basics/mouse/juce_MouseCursor.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MOUSECURSOR_H_INCLUDED -#define JUCE_MOUSECURSOR_H_INCLUDED +#pragma once //============================================================================== @@ -111,10 +112,11 @@ public: /** Destructor. */ ~MouseCursor(); - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Move constructor */ MouseCursor (MouseCursor&&) noexcept; + + /** Move assignment operator */ MouseCursor& operator= (MouseCursor&&) noexcept; - #endif /** Checks whether two mouse cursors are the same. @@ -176,5 +178,3 @@ private: JUCE_LEAK_DETECTOR (MouseCursor) }; - -#endif // JUCE_MOUSECURSOR_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp b/source/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp index 8d558cac8..799099564 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp +++ b/source/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -26,6 +28,8 @@ MouseEvent::MouseEvent (MouseInputSource inputSource, Point pos, ModifierKeys modKeys, float force, + float o, float r, + float tX, float tY, Component* const eventComp, Component* const originator, Time time, @@ -38,6 +42,8 @@ MouseEvent::MouseEvent (MouseInputSource inputSource, y (roundToInt (pos.y)), mods (modKeys), pressure (force), + orientation (o), rotation (r), + tiltX (tX), tiltY (tY), eventComponent (eventComp), originalComponent (originator), eventTime (time), @@ -59,23 +65,24 @@ MouseEvent MouseEvent::getEventRelativeTo (Component* const otherComponent) cons jassert (otherComponent != nullptr); return MouseEvent (source, otherComponent->getLocalPoint (eventComponent, position), - mods, pressure, otherComponent, originalComponent, eventTime, + mods, pressure, orientation, rotation, tiltX, tiltY, + otherComponent, originalComponent, eventTime, otherComponent->getLocalPoint (eventComponent, mouseDownPos), mouseDownTime, numberOfClicks, wasMovedSinceMouseDown != 0); } MouseEvent MouseEvent::withNewPosition (Point newPosition) const noexcept { - return MouseEvent (source, newPosition, mods, pressure, eventComponent, - originalComponent, eventTime, mouseDownPos, mouseDownTime, + return MouseEvent (source, newPosition, mods, pressure, orientation, rotation, tiltX, tiltY, + eventComponent, originalComponent, eventTime, mouseDownPos, mouseDownTime, numberOfClicks, wasMovedSinceMouseDown != 0); } MouseEvent MouseEvent::withNewPosition (Point newPosition) const noexcept { - return MouseEvent (source, newPosition.toFloat(), mods, pressure, eventComponent, - originalComponent, eventTime, mouseDownPos, mouseDownTime, - numberOfClicks, wasMovedSinceMouseDown != 0); + return MouseEvent (source, newPosition.toFloat(), mods, pressure, orientation, rotation, + tiltX, tiltY, eventComponent, originalComponent, eventTime, mouseDownPos, + mouseDownTime, numberOfClicks, wasMovedSinceMouseDown != 0); } //============================================================================== @@ -120,6 +127,9 @@ int MouseEvent::getMouseDownScreenX() const { return getMous int MouseEvent::getMouseDownScreenY() const { return getMouseDownScreenPosition().y; } bool MouseEvent::isPressureValid() const noexcept { return pressure > 0.0f && pressure < 1.0f; } +bool MouseEvent::isOrientationValid() const noexcept { return orientation >= 0.0f && orientation <= 2.0f * float_Pi; } +bool MouseEvent::isRotationValid() const noexcept { return rotation >= 0 && rotation <= 2.0f * float_Pi; } +bool MouseEvent::isTiltValid (bool isX) const noexcept { return isX ? (tiltX >= -1.0f && tiltX <= 1.0f) : (tiltY >= -1.0f && tiltY <= 1.0f); } //============================================================================== static int doubleClickTimeOutMs = 400; diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseEvent.h b/source/modules/juce_gui_basics/mouse/juce_MouseEvent.h index a0a6f6414..44a7a49f1 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseEvent.h +++ b/source/modules/juce_gui_basics/mouse/juce_MouseEvent.h @@ -2,29 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MOUSEEVENT_H_INCLUDED -#define JUCE_MOUSEEVENT_H_INCLUDED - +#pragma once //============================================================================== /** @@ -47,6 +47,10 @@ public: @param pressure the pressure of the touch or stylus, in the range 0 to 1. Devices that do not support force information may return 0.0, 1.0, or a negative value, depending on the platform + @param orientation the orientation of the touch input for this event in radians. The default is 0 + @param rotation the rotation of the pen device for this event in radians. The default is 0 + @param tiltX the tilt of the pen device along the x-axis between -1.0 and 1.0. The default is 0 + @param tiltY the tilt of the pen device along the y-axis between -1.0 and 1.0. The default is 0 @param eventComponent the component that the mouse event applies to @param originator the component that originally received the event @param eventTime the time the event happened @@ -63,6 +67,8 @@ public: Point position, ModifierKeys modifiers, float pressure, + float orientation, float rotation, + float tiltX, float tiltY, Component* eventComponent, Component* originator, Time eventTime, @@ -118,7 +124,27 @@ public: If the input device doesn't provide any pressure data, it may return a negative value here, or 0.0 or 1.0, depending on the platform. */ - float pressure; + const float pressure; + + /** The orientation of the touch input for this event in radians where 0 indicates a touch aligned with the x-axis + and pointing from left to right; increasing values indicate rotation in the clockwise direction. The default is 0. + */ + const float orientation; + + /** The rotation of the pen device for this event in radians. Indicates the clockwise + rotation, or twist, of the pen. The default is 0. + */ + const float rotation; + + /** The tilt of the pen device along the x-axis between -1.0 and 1.0. A positive value indicates + a tilt to the right. The default is 0. + */ + const float tiltX; + + /** The tilt of the pen device along the y-axis between -1.0 and 1.0. A positive value indicates + a tilt toward the user. The default is 0. + */ + const float tiltY; /** The component that this event applies to. @@ -240,6 +266,15 @@ public: /** Returns true if the pressure value for this event is meaningful. */ bool isPressureValid() const noexcept; + /** Returns true if the orientation value for this event is meaningful. */ + bool isOrientationValid() const noexcept; + + /** Returns true if the rotation value for this event is meaningful. */ + bool isRotationValid() const noexcept; + + /** Returns true if the current tilt value (either x- or y-axis) is meaningful. */ + bool isTiltValid (bool tiltX) const noexcept; + //============================================================================== /** The position of the mouse when the event occurred. @@ -376,5 +411,29 @@ struct MouseWheelDetails bool isInertial; }; +//============================================================================== +/** + Contains status information about a pen event. -#endif // JUCE_MOUSEEVENT_H_INCLUDED + @see MouseListener, MouseEvent +*/ +struct PenDetails +{ + /** + The rotation of the pen device in radians. Indicates the clockwise rotation, or twist, + of the pen. The default is 0. + */ + float rotation; + + /** + Indicates the angle of tilt of the pointer in a range of -1.0 to 1.0 along the x-axis where + a positive value indicates a tilt to the right. The default is 0. + */ + float tiltX; + + /** + Indicates the angle of tilt of the pointer in a range of -1.0 to 1.0 along the y-axis where + a positive value indicates a tilt toward the user. The default is 0. + */ + float tiltY; +}; diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp b/source/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp index 03aa87c19..6ac495c0e 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp +++ b/source/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h b/source/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h index 949f05908..790c44b3a 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h +++ b/source/modules/juce_gui_basics/mouse/juce_MouseInactivityDetector.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MOUSEINACTIVITYDETECTOR_H_INCLUDED -#define JUCE_MOUSEINACTIVITYDETECTOR_H_INCLUDED +#pragma once //============================================================================== @@ -106,6 +107,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MouseInactivityDetector) }; - - -#endif // JUCE_MOUSEINACTIVITYDETECTOR_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp b/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp index bcc4e8488..7ca6f099a 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp +++ b/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -25,12 +27,7 @@ class MouseInputSourceInternal : private AsyncUpdater { public: - //============================================================================== - MouseInputSourceInternal (const int i, const bool isMouse) - : index (i), isMouseDevice (isMouse), pressure (0.0f), - isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), - lastPeer (nullptr), currentCursorHandle (nullptr), - mouseEventCounter (0), mouseMovedSignificantlySincePressed (false) + MouseInputSourceInternal (int i, MouseInputSource::InputSourceType type) : index (i), inputType (type) { } @@ -60,10 +57,10 @@ public: static Point screenPosToLocalPos (Component& comp, Point pos) { - if (ComponentPeer* const peer = comp.getPeer()) + if (auto* peer = comp.getPeer()) { pos = peer->globalToLocal (pos); - Component& peerComp = peer->getComponent(); + auto& peerComp = peer->getComponent(); return comp.getLocalPoint (&peerComp, ScalingHelpers::unscaledScreenPosToScaled (peerComp, pos)); } @@ -72,13 +69,12 @@ public: Component* findComponentAt (Point screenPos) { - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) { - Point relativePos (ScalingHelpers::unscaledScreenPosToScaled (peer->getComponent(), - peer->globalToLocal (screenPos))); - Component& comp = peer->getComponent(); - - const Point pos (relativePos.roundToInt()); + auto relativePos = ScalingHelpers::unscaledScreenPosToScaled (peer->getComponent(), + peer->globalToLocal (screenPos)); + auto& comp = peer->getComponent(); + auto pos = relativePos.roundToInt(); // (the contains() call is needed to test for overlapping desktop windows) if (comp.contains (pos)) @@ -93,8 +89,8 @@ public: // This needs to return the live position if possible, but it mustn't update the lastScreenPos // value, because that can cause continuity problems. return ScalingHelpers::unscaledScreenPosToScaled - (unboundedMouseOffset + (isMouseDevice ? MouseInputSource::getCurrentRawMousePosition() - : lastScreenPos)); + (unboundedMouseOffset + (inputType != MouseInputSource::InputSourceType::touch ? MouseInputSource::getCurrentRawMousePosition() + : lastScreenPos)); } void setScreenPosition (Point p) @@ -102,7 +98,10 @@ public: MouseInputSource::setRawMousePosition (ScalingHelpers::scaledScreenPosToUnscaled (p)); } - bool isPressureValid() const noexcept { return pressure > 0.0f && pressure < 1.0f; } + bool isPressureValid() const noexcept { return pressure >= 0.0f && pressure <= 1.0f; } + bool isOrientationValid() const noexcept { return orientation >= 0.0f && orientation <= 2.0f * float_Pi; } + bool isRotationValid() const noexcept { return rotation >= 0.0f && rotation <= 2.0f * float_Pi; } + bool isTiltValid (bool isX) const noexcept { return isX ? (tiltX >= -1.0f && tiltX <= 1.0f) : (tiltY >= -1.0f && tiltY <= 1.0f); } //============================================================================== #if JUCE_DUMP_MOUSE_EVENTS @@ -134,19 +133,19 @@ public: void sendMouseDown (Component& comp, Point screenPos, Time time) { JUCE_MOUSE_EVENT_DBG ("down") - comp.internalMouseDown (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure); + comp.internalMouseDown (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure, orientation, rotation, tiltX, tiltY); } void sendMouseDrag (Component& comp, Point screenPos, Time time) { JUCE_MOUSE_EVENT_DBG ("drag") - comp.internalMouseDrag (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure); + comp.internalMouseDrag (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure, orientation, rotation, tiltX, tiltY); } void sendMouseUp (Component& comp, Point screenPos, Time time, const ModifierKeys oldMods) { JUCE_MOUSE_EVENT_DBG ("up") - comp.internalMouseUp (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, oldMods, pressure); + comp.internalMouseUp (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, oldMods, pressure, orientation, rotation, tiltX, tiltY); } void sendMouseWheel (Component& comp, Point screenPos, Time time, const MouseWheelDetails& wheel) @@ -179,13 +178,13 @@ public: return false; } - const int lastCounter = mouseEventCounter; + auto lastCounter = mouseEventCounter; if (buttonState.isAnyMouseButtonDown()) { - if (Component* const current = getComponentUnderMouse()) + if (auto* current = getComponentUnderMouse()) { - const ModifierKeys oldMods (getCurrentModifiers()); + auto oldMods = getCurrentModifiers(); buttonState = newButtonState; // must change this before calling sendMouseUp, in case it runs a modal loop sendMouseUp (*current, screenPos + unboundedMouseOffset, time, oldMods); @@ -203,7 +202,7 @@ public: { Desktop::getInstance().incrementMouseClickCounter(); - if (Component* const current = getComponentUnderMouse()) + if (auto* current = getComponentUnderMouse()) { registerMouseDown (screenPos, time, *current, buttonState); sendMouseDown (*current, screenPos, time); @@ -215,12 +214,12 @@ public: void setComponentUnderMouse (Component* const newComponent, Point screenPos, Time time) { - Component* current = getComponentUnderMouse(); + auto* current = getComponentUnderMouse(); if (newComponent != current) { WeakReference safeNewComp (newComponent); - const ModifierKeys originalButtonState (buttonState); + auto originalButtonState = buttonState; if (current != nullptr) { @@ -268,7 +267,7 @@ public: cancelPendingUpdate(); lastScreenPos = newScreenPos; - if (Component* const current = getComponentUnderMouse()) + if (auto* current = getComponentUnderMouse()) { if (isDragging()) { @@ -290,23 +289,38 @@ public: //============================================================================== void handleEvent (ComponentPeer& newPeer, Point positionWithinPeer, Time time, - const ModifierKeys newMods, float newPressure) + const ModifierKeys newMods, float newPressure, float newOrientation, PenDetails pen) { lastTime = time; + const bool pressureChanged = (pressure != newPressure); pressure = newPressure; + + const bool orientationChanged = (orientation != newOrientation); + orientation = newOrientation; + + const bool rotationChanged = (rotation != pen.rotation); + rotation = pen.rotation; + + const bool tiltChanged = (tiltX != pen.tiltX || tiltY != pen.tiltY); + tiltX = pen.tiltX; + tiltY = pen.tiltY; + + const bool shouldUpdate = (pressureChanged || orientationChanged || rotationChanged || tiltChanged); + ++mouseEventCounter; - const Point screenPos (newPeer.localToGlobal (positionWithinPeer)); + + auto screenPos = newPeer.localToGlobal (positionWithinPeer); if (isDragging() && newMods.isAnyMouseButtonDown()) { - setScreenPos (screenPos, time, pressureChanged); + setScreenPos (screenPos, time, shouldUpdate); } else { setPeer (newPeer, screenPos, time); - if (ComponentPeer* peer = getPeer()) + if (auto* peer = getPeer()) { if (setButtons (screenPos, time, newMods)) return; // some modal events have been dispatched, so the current event is now out-of-date @@ -314,7 +328,7 @@ public: peer = getPeer(); if (peer != nullptr) - setScreenPos (screenPos, time, pressureChanged); + setScreenPos (screenPos, time, shouldUpdate); } } } @@ -345,6 +359,8 @@ public: // scrollable components. if (lastNonInertialWheelTarget == nullptr || ! wheel.isInertial) lastNonInertialWheelTarget = getTargetForGesture (peer, positionWithinPeer, time, screenPos); + else + screenPos = peer.localToGlobal (positionWithinPeer); if (Component* target = lastNonInertialWheelTarget) sendMouseWheel (*target, screenPos, time, wheel); @@ -354,7 +370,8 @@ public: Time time, const float scaleFactor) { Point screenPos; - if (Component* current = getTargetForGesture (peer, positionWithinPeer, time, screenPos)) + + if (auto* current = getTargetForGesture (peer, positionWithinPeer, time, screenPos)) sendMagnifyGesture (*current, screenPos, time, scaleFactor); } @@ -408,13 +425,13 @@ public: if ((! enable) && ((! isCursorVisibleUntilOffscreen) || ! unboundedMouseOffset.isOrigin())) { // when released, return the mouse to within the component's bounds - if (Component* current = getComponentUnderMouse()) + if (auto* current = getComponentUnderMouse()) setScreenPosition (current->getScreenBounds().toFloat() .getConstrainedPoint (ScalingHelpers::unscaledScreenPosToScaled (lastScreenPos))); } isUnboundedMouseModeOn = enable; - unboundedMouseOffset = Point(); + unboundedMouseOffset = {}; revealCursor (true); } @@ -422,12 +439,11 @@ public: void handleUnboundedDrag (Component& current) { - const Rectangle componentScreenBounds - = ScalingHelpers::scaledScreenPosToUnscaled (current.getParentMonitorArea().reduced (2, 2).toFloat()); + auto componentScreenBounds = ScalingHelpers::scaledScreenPosToUnscaled (current.getParentMonitorArea().reduced (2, 2).toFloat()); if (! componentScreenBounds.contains (lastScreenPos)) { - const Point componentCentre (current.getScreenBounds().toFloat().getCentre()); + auto componentCentre = current.getScreenBounds().toFloat().getCentre(); unboundedMouseOffset += (lastScreenPos - ScalingHelpers::scaledScreenPosToUnscaled (componentCentre)); setScreenPosition (componentCentre); } @@ -436,7 +452,7 @@ public: && componentScreenBounds.contains (lastScreenPos + unboundedMouseOffset)) { MouseInputSource::setRawMousePosition (lastScreenPos + unboundedMouseOffset); - unboundedMouseOffset = Point(); + unboundedMouseOffset = {}; } } @@ -465,7 +481,7 @@ public: { MouseCursor mc (MouseCursor::NormalCursor); - if (Component* current = getComponentUnderMouse()) + if (auto* current = getComponentUnderMouse()) mc = current->getLookAndFeel().getMouseCursorFor (*current); showMouseCursor (mc, forcedUpdate); @@ -473,30 +489,34 @@ public: //============================================================================== const int index; - const bool isMouseDevice; + const MouseInputSource::InputSourceType inputType; Point lastScreenPos, unboundedMouseOffset; // NB: these are unscaled coords ModifierKeys buttonState; - float pressure; + float pressure = 0; + float orientation = 0; + float rotation = 0; + float tiltX = 0; + float tiltY = 0; - bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; + bool isUnboundedMouseModeOn = false, isCursorVisibleUntilOffscreen = false; private: WeakReference componentUnderMouse, lastNonInertialWheelTarget; - ComponentPeer* lastPeer; + ComponentPeer* lastPeer = nullptr; - void* currentCursorHandle; - int mouseEventCounter; + void* currentCursorHandle = nullptr; + int mouseEventCounter = 0; struct RecentMouseDown { - RecentMouseDown() noexcept : peerID (0) {} + RecentMouseDown() = default; Point position; Time time; ModifierKeys buttons; - uint32 peerID; + uint32 peerID = 0; - bool canBePartOfMultipleClickWith (const RecentMouseDown& other, const int maxTimeBetweenMs) const + bool canBePartOfMultipleClickWith (const RecentMouseDown& other, int maxTimeBetweenMs) const noexcept { return time - other.time < RelativeTime::milliseconds (maxTimeBetweenMs) && std::abs (position.x - other.position.x) < 8 @@ -508,7 +528,7 @@ private: RecentMouseDown mouseDowns[4]; Time lastTime; - bool mouseMovedSignificantlySincePressed; + bool mouseMovedSignificantlySincePressed = false; void registerMouseDown (Point screenPos, Time time, Component& component, const ModifierKeys modifiers) noexcept @@ -520,7 +540,7 @@ private: mouseDowns[0].time = time; mouseDowns[0].buttons = modifiers.withOnlyMouseButtons(); - if (ComponentPeer* const peer = component.getPeer()) + if (auto* peer = component.getPeer()) mouseDowns[0].peerID = peer->getUniqueID(); else mouseDowns[0].peerID = 0; @@ -549,36 +569,45 @@ MouseInputSource& MouseInputSource::operator= (const MouseInputSource& other) no return *this; } -bool MouseInputSource::isMouse() const noexcept { return pimpl->isMouseDevice; } -bool MouseInputSource::isTouch() const noexcept { return ! isMouse(); } -bool MouseInputSource::canHover() const noexcept { return isMouse(); } -bool MouseInputSource::hasMouseWheel() const noexcept { return isMouse(); } -int MouseInputSource::getIndex() const noexcept { return pimpl->index; } -bool MouseInputSource::isDragging() const noexcept { return pimpl->isDragging(); } -Point MouseInputSource::getScreenPosition() const noexcept { return pimpl->getScreenPosition(); } -ModifierKeys MouseInputSource::getCurrentModifiers() const noexcept { return pimpl->getCurrentModifiers(); } -float MouseInputSource::getCurrentPressure() const noexcept { return pimpl->pressure; } -bool MouseInputSource::isPressureValid() const noexcept { return pimpl->isPressureValid(); } -Component* MouseInputSource::getComponentUnderMouse() const { return pimpl->getComponentUnderMouse(); } -void MouseInputSource::triggerFakeMove() const { pimpl->triggerFakeMove(); } -int MouseInputSource::getNumberOfMultipleClicks() const noexcept { return pimpl->getNumberOfMultipleClicks(); } -Time MouseInputSource::getLastMouseDownTime() const noexcept { return pimpl->getLastMouseDownTime(); } -Point MouseInputSource::getLastMouseDownPosition() const noexcept { return pimpl->getLastMouseDownPosition(); } +MouseInputSource::InputSourceType MouseInputSource::getType() const noexcept { return pimpl->inputType; } +bool MouseInputSource::isMouse() const noexcept { return (getType() == MouseInputSource::InputSourceType::mouse); } +bool MouseInputSource::isTouch() const noexcept { return (getType() == MouseInputSource::InputSourceType::touch); } +bool MouseInputSource::isPen() const noexcept { return (getType() == MouseInputSource::InputSourceType::pen); } +bool MouseInputSource::canHover() const noexcept { return ! isTouch(); } +bool MouseInputSource::hasMouseWheel() const noexcept { return ! isTouch(); } +int MouseInputSource::getIndex() const noexcept { return pimpl->index; } +bool MouseInputSource::isDragging() const noexcept { return pimpl->isDragging(); } +Point MouseInputSource::getScreenPosition() const noexcept { return pimpl->getScreenPosition(); } +ModifierKeys MouseInputSource::getCurrentModifiers() const noexcept { return pimpl->getCurrentModifiers(); } +float MouseInputSource::getCurrentPressure() const noexcept { return pimpl->pressure; } +bool MouseInputSource::isPressureValid() const noexcept { return pimpl->isPressureValid(); } +float MouseInputSource::getCurrentOrientation() const noexcept { return pimpl->orientation; } +bool MouseInputSource::isOrientationValid() const noexcept { return pimpl->isOrientationValid(); } +float MouseInputSource::getCurrentRotation() const noexcept { return pimpl->rotation; } +bool MouseInputSource::isRotationValid() const noexcept { return pimpl->isRotationValid(); } +float MouseInputSource::getCurrentTilt (bool tiltX) const noexcept { return tiltX ? pimpl->tiltX : pimpl->tiltY; } +bool MouseInputSource::isTiltValid (bool isX) const noexcept { return pimpl->isTiltValid (isX); } +Component* MouseInputSource::getComponentUnderMouse() const { return pimpl->getComponentUnderMouse(); } +void MouseInputSource::triggerFakeMove() const { pimpl->triggerFakeMove(); } +int MouseInputSource::getNumberOfMultipleClicks() const noexcept { return pimpl->getNumberOfMultipleClicks(); } +Time MouseInputSource::getLastMouseDownTime() const noexcept { return pimpl->getLastMouseDownTime(); } +Point MouseInputSource::getLastMouseDownPosition() const noexcept { return pimpl->getLastMouseDownPosition(); } bool MouseInputSource::hasMouseMovedSignificantlySincePressed() const noexcept { return pimpl->hasMouseMovedSignificantlySincePressed(); } -bool MouseInputSource::canDoUnboundedMovement() const noexcept { return isMouse(); } +bool MouseInputSource::canDoUnboundedMovement() const noexcept { return ! isTouch(); } void MouseInputSource::enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen) const { pimpl->enableUnboundedMouseMovement (isEnabled, keepCursorVisibleUntilOffscreen); } bool MouseInputSource::isUnboundedMouseMovementEnabled() const { return pimpl->isUnboundedMouseModeOn; } -bool MouseInputSource::hasMouseCursor() const noexcept { return isMouse(); } +bool MouseInputSource::hasMouseCursor() const noexcept { return ! isTouch(); } void MouseInputSource::showMouseCursor (const MouseCursor& cursor) { pimpl->showMouseCursor (cursor, false); } void MouseInputSource::hideCursor() { pimpl->hideCursor(); } void MouseInputSource::revealCursor() { pimpl->revealCursor (false); } void MouseInputSource::forceMouseCursorUpdate() { pimpl->revealCursor (true); } void MouseInputSource::setScreenPosition (Point p) { pimpl->setScreenPosition (p); } -void MouseInputSource::handleEvent (ComponentPeer& peer, Point pos, int64 time, ModifierKeys mods, float pressure) +void MouseInputSource::handleEvent (ComponentPeer& peer, Point pos, int64 time, ModifierKeys mods, + float pressure, float orientation, const PenDetails& penDetails) { - pimpl->handleEvent (peer, pos, Time (time), mods.withOnlyMouseButtons(), pressure); + pimpl->handleEvent (peer, pos, Time (time), mods.withOnlyMouseButtons(), pressure, orientation, penDetails); } void MouseInputSource::handleWheel (ComponentPeer& peer, Point pos, int64 time, const MouseWheelDetails& wheel) @@ -592,22 +621,30 @@ void MouseInputSource::handleMagnifyGesture (ComponentPeer& peer, Point p } const float MouseInputSource::invalidPressure = 0.0f; +const float MouseInputSource::invalidOrientation = 0.0f; +const float MouseInputSource::invalidRotation = 0.0f; + +const float MouseInputSource::invalidTiltX = 0.0f; +const float MouseInputSource::invalidTiltY = 0.0f; //============================================================================== struct MouseInputSource::SourceList : public Timer { SourceList() { - addSource(); + addSource (0, MouseInputSource::InputSourceType::mouse); } bool addSource(); + bool canUseTouch(); - void addSource (int index, bool isMouse) + MouseInputSource* addSource (int index, MouseInputSource::InputSourceType type) { - MouseInputSourceInternal* s = new MouseInputSourceInternal (index, isMouse); + auto* s = new MouseInputSourceInternal (index, type); sources.add (s); sourceArray.add (MouseInputSource (s)); + + return &sourceArray.getReference (sourceArray.size() - 1); } MouseInputSource* getMouseSource (int index) const noexcept @@ -616,29 +653,37 @@ struct MouseInputSource::SourceList : public Timer : nullptr; } - MouseInputSource* getOrCreateMouseInputSource (int touchIndex) + MouseInputSource* getOrCreateMouseInputSource (MouseInputSource::InputSourceType type, int touchIndex = 0) { - jassert (touchIndex >= 0 && touchIndex < 100); // sanity-check on number of fingers + if (type == MouseInputSource::InputSourceType::mouse || type == MouseInputSource::InputSourceType::pen) + { + for (auto& m : sourceArray) + if (type == m.getType()) + return &m; - for (;;) + addSource (0, type); + } + else if (type == MouseInputSource::InputSourceType::touch) { - if (MouseInputSource* mouse = getMouseSource (touchIndex)) - return mouse; + jassert (touchIndex >= 0 && touchIndex < 100); // sanity-check on number of fingers - if (! addSource()) - { - jassertfalse; // not enough mouse sources! - return nullptr; - } + for (auto& m : sourceArray) + if (type == m.getType() && touchIndex == m.getIndex()) + return &m; + + if (canUseTouch()) + return addSource (touchIndex, type); } + + return nullptr; } int getNumDraggingMouseSources() const noexcept { int num = 0; - for (int i = 0; i < sources.size(); ++i) - if (sources.getUnchecked(i)->isDragging()) + for (auto* s : sources) + if (s->isDragging()) ++num; return num; @@ -648,14 +693,12 @@ struct MouseInputSource::SourceList : public Timer { int num = 0; - for (int i = 0; i < sources.size(); ++i) + for (auto& s : sourceArray) { - MouseInputSource* const mi = &(sourceArray.getReference(i)); - - if (mi->isDragging()) + if (s.isDragging()) { if (index == num) - return mi; + return &s; ++num; } @@ -679,20 +722,21 @@ struct MouseInputSource::SourceList : public Timer void timerCallback() override { - int numMiceDown = 0; + bool anyDragging = false; - for (int i = 0; i < sources.size(); ++i) + for (auto* s : sources) { - MouseInputSourceInternal* const mi = sources.getUnchecked(i); - - if (mi->isDragging()) + // NB: when doing auto-repeat, we need to force an update of the current position and button state, + // because on some OSes the queue can get overloaded with messages so that mouse-events don't get through.. + if (s->isDragging() && ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown()) { - mi->triggerFakeMove(); - ++numMiceDown; + s->lastScreenPos = s->getScreenPosition(); + s->triggerFakeMove(); + anyDragging = true; } } - if (numMiceDown == 0) + if (! anyDragging) stopTimer(); } diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.h b/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.h index bbceb508d..e99c4565c 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.h +++ b/source/modules/juce_gui_basics/mouse/juce_MouseInputSource.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MOUSEINPUTSOURCE_H_INCLUDED -#define JUCE_MOUSEINPUTSOURCE_H_INCLUDED +#pragma once //============================================================================== @@ -49,6 +50,14 @@ class JUCE_API MouseInputSource { public: + /** Possible mouse input sources. */ + enum InputSourceType + { + mouse, + touch, + pen + }; + //============================================================================== MouseInputSource (const MouseInputSource&) noexcept; MouseInputSource& operator= (const MouseInputSource&) noexcept; @@ -59,12 +68,18 @@ public: bool operator!= (const MouseInputSource& other) const noexcept { return pimpl != other.pimpl; } //============================================================================== + /** Returns the type of input source that this object represents. */ + MouseInputSource::InputSourceType getType() const noexcept; + /** Returns true if this object represents a normal desk-based mouse device. */ bool isMouse() const noexcept; - /** Returns true if this object represents a source of touch events - i.e. a finger or stylus. */ + /** Returns true if this object represents a source of touch events. */ bool isTouch() const noexcept; + /** Returns true if this object represents a pen device. */ + bool isPen() const noexcept; + /** Returns true if this source has an on-screen pointer that can hover over items without clicking them. */ @@ -102,9 +117,35 @@ public: */ float getCurrentPressure() const noexcept; + /** Returns the device's current orientation in radians. 0 indicates a touch pointer + aligned with the x-axis and pointing from left to right; increasing values indicate + rotation in the clockwise direction. Only reported by a touch pointer. + */ + float getCurrentOrientation() const noexcept; + + /** Returns the device's current rotation. Indicates the clockwise rotation, or twist, of the pointer + in radians. The default is 0. Only reported by a pen pointer. + */ + float getCurrentRotation() const noexcept; + + /** Returns the angle of tilt of the pointer in a range of -1.0 to 1.0 either in the x- or y-axis. The default is 0. + If x-axis, a positive value indicates a tilt to the right and if y-axis, a positive value indicates a tilt toward the user. + Only reported by a pen pointer. + */ + float getCurrentTilt (bool tiltX) const noexcept; + /** Returns true if the current pressure value is meaningful. */ bool isPressureValid() const noexcept; + /** Returns true if the current orientation value is meaningful. */ + bool isOrientationValid() const noexcept; + + /** Returns true if the current rotation value is meaningful. */ + bool isRotationValid() const noexcept; + + /** Returns true if the current tilt value (either x- or y-axis) is meaningful. */ + bool isTiltValid (bool tiltX) const noexcept; + /** Returns the component that was last known to be under this pointer. */ Component* getComponentUnderMouse() const; @@ -179,6 +220,16 @@ public: */ static const float invalidPressure; + /** A default value for orientation, which is used when a device doesn't support it */ + static const float invalidOrientation; + + /** A default value for rotation, which is used when a device doesn't support it */ + static const float invalidRotation; + + /** Default values for tilt, which are used when a device doesn't support it */ + static const float invalidTiltX; + static const float invalidTiltY; + private: //============================================================================== friend class ComponentPeer; @@ -189,7 +240,7 @@ private: struct SourceList; explicit MouseInputSource (MouseInputSourceInternal*) noexcept; - void handleEvent (ComponentPeer&, Point, int64 time, ModifierKeys, float); + void handleEvent (ComponentPeer&, Point, int64 time, ModifierKeys, float, float, const PenDetails&); void handleWheel (ComponentPeer&, Point, int64 time, const MouseWheelDetails&); void handleMagnifyGesture (ComponentPeer&, Point, int64 time, float scaleFactor); @@ -198,6 +249,3 @@ private: JUCE_LEAK_DETECTOR (MouseInputSource) }; - - -#endif // JUCE_MOUSEINPUTSOURCE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseListener.cpp b/source/modules/juce_gui_basics/mouse/juce_MouseListener.cpp index 3021bcbfd..abe9ff512 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseListener.cpp +++ b/source/modules/juce_gui_basics/mouse/juce_MouseListener.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/mouse/juce_MouseListener.h b/source/modules/juce_gui_basics/mouse/juce_MouseListener.h index 5aab50b2e..fd467ba82 100644 --- a/source/modules/juce_gui_basics/mouse/juce_MouseListener.h +++ b/source/modules/juce_gui_basics/mouse/juce_MouseListener.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MOUSELISTENER_H_INCLUDED -#define JUCE_MOUSELISTENER_H_INCLUDED +#pragma once //============================================================================== @@ -160,6 +161,3 @@ private: virtual int mouseWheelMove (const MouseEvent&, float, float) { return 0; } #endif }; - - -#endif // JUCE_MOUSELISTENER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h b/source/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h index 6535e8295..c78c97072 100644 --- a/source/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h +++ b/source/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SELECTEDITEMSET_H_INCLUDED -#define JUCE_SELECTEDITEMSET_H_INCLUDED +#pragma once //============================================================================== @@ -46,7 +47,7 @@ public: //============================================================================== typedef SelectableItemType ItemType; typedef Array ItemArray; - typedef PARAMETER_TYPE (SelectableItemType) ParameterType; + typedef typename TypeHelpers::ParameterType::type ParameterType; //============================================================================== /** Creates an empty set. */ @@ -318,6 +319,3 @@ private: JUCE_LEAK_DETECTOR (SelectedItemSet) }; - - -#endif // JUCE_SELECTEDITEMSET_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h b/source/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h index 90e171327..9cba6b261 100644 --- a/source/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h +++ b/source/modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TEXTDRAGANDDROPTARGET_H_INCLUDED -#define JUCE_TEXTDRAGANDDROPTARGET_H_INCLUDED +#pragma once //============================================================================== @@ -100,6 +101,3 @@ public: */ virtual void textDropped (const String& text, int x, int y) = 0; }; - - -#endif // JUCE_TEXTDRAGANDDROPTARGET_H_INCLUDED diff --git a/source/modules/juce_gui_basics/mouse/juce_TooltipClient.h b/source/modules/juce_gui_basics/mouse/juce_TooltipClient.h index c449f9a15..1219822a6 100644 --- a/source/modules/juce_gui_basics/mouse/juce_TooltipClient.h +++ b/source/modules/juce_gui_basics/mouse/juce_TooltipClient.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TOOLTIPCLIENT_H_INCLUDED -#define JUCE_TOOLTIPCLIENT_H_INCLUDED +#pragma once //============================================================================== @@ -80,6 +81,3 @@ protected: private: String tooltipString; }; - - -#endif // JUCE_TOOLTIPCLIENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/native/juce_MultiTouchMapper.h b/source/modules/juce_gui_basics/native/juce_MultiTouchMapper.h index dd866b5e2..5cca8b541 100644 --- a/source/modules/juce_gui_basics/native/juce_MultiTouchMapper.h +++ b/source/modules/juce_gui_basics/native/juce_MultiTouchMapper.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MULTITOUCHMAPPER_H_INCLUDED -#define JUCE_MULTITOUCHMAPPER_H_INCLUDED +#pragma once template class MultiTouchMapper @@ -73,5 +74,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiTouchMapper) }; - -#endif // JUCE_MULTITOUCHMAPPER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/native/juce_android_FileChooser.cpp b/source/modules/juce_gui_basics/native/juce_android_FileChooser.cpp index 1313f6e2b..aa8ed4f72 100644 --- a/source/modules/juce_gui_basics/native/juce_android_FileChooser.cpp +++ b/source/modules/juce_gui_basics/native/juce_android_FileChooser.cpp @@ -2,37 +2,39 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -void FileChooser::showPlatformDialog (Array& results, - const String& title, - const File& currentFileOrDirectory, - const String& filter, - bool selectsDirectory, - bool selectsFiles, - bool isSaveDialogue, - bool warnAboutOverwritingExistingFiles, - bool selectMultipleFiles, +void FileChooser::showPlatformDialog (Array& /*results*/, + const String& /*title*/, + const File& /*currentFileOrDirectory*/, + const String& /*filter*/, + bool /*selectsDirectory*/, + bool /*selectsFiles*/, + bool /*isSaveDialogue*/, + bool /*warnAboutOverwritingExistingFiles*/, + bool /*selectMultipleFiles*/, bool /*treatFilePackagesAsDirs*/, - FilePreviewComponent* extraInfoComponent) + FilePreviewComponent* /*extraInfoComponent*/) { // TODO diff --git a/source/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/source/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 09bc0674d..9ae74bb91 100644 --- a/source/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/source/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -56,7 +58,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, launchApp, void, (JNIEnv* en jassert (MessageManager::getInstance()->isThisTheMessageThread()); } -JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, suspendApp, void, (JNIEnv* env, jobject activity)) +JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, suspendApp, void, (JNIEnv* env, jobject)) { setEnv (env); @@ -64,7 +66,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, suspendApp, void, (JNIEnv* e app->suspended(); } -JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, resumeApp, void, (JNIEnv* env, jobject activity)) +JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, resumeApp, void, (JNIEnv* env, jobject)) { setEnv (env); @@ -72,7 +74,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, resumeApp, void, (JNIEnv* en app->resumed(); } -JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, quitApp, void, (JNIEnv* env, jobject activity)) +JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, quitApp, void, (JNIEnv* env, jobject)) { setEnv (env); @@ -106,7 +108,7 @@ DECLARE_JNI_CLASS (CanvasMinimal, "android/graphics/Canvas"); METHOD (invalidate, "invalidate", "(IIII)V") \ METHOD (containsPoint, "containsPoint", "(II)Z") \ METHOD (showKeyboard, "showKeyboard", "(Ljava/lang/String;)V") \ - METHOD (setSystemUiVisibility, "setSystemUiVisibility", "(I)V") \ + METHOD (setSystemUiVisibility, "setSystemUiVisibilityCompat", "(I)V") \ DECLARE_JNI_CLASS (ComponentPeerView, JUCE_ANDROID_ACTIVITY_CLASSPATH "$ComponentPeerView"); #undef JNI_CLASS_MEMBERS @@ -119,7 +121,6 @@ class AndroidComponentPeer : public ComponentPeer, public: AndroidComponentPeer (Component& comp, const int windowStyleFlags) : ComponentPeer (comp, windowStyleFlags), - usingAndroidGraphics (false), fullScreen (false), sizeAllocated (0), scale ((float) Desktop::getInstance().getDisplays().getMainDisplay().scale) @@ -138,6 +139,7 @@ public: { if (MessageManager::getInstance()->isThisTheMessageThread()) { + frontWindow = nullptr; android.activity.callVoidMethod (JuceAppActivity.deleteView, view.get()); } else @@ -213,7 +215,7 @@ public: class ViewMover : public CallbackMessage { public: - ViewMover (const GlobalRef& v, const Rectangle& r) : view (v), bounds (r) {} + ViewMover (const GlobalRef& v, const Rectangle& boundsToUse) : view (v), bounds (boundsToUse) {} void messageCallback() override { @@ -262,7 +264,7 @@ public: return screenPosition - getScreenPosition().toFloat(); } - void setMinimised (bool shouldBeMinimised) override + void setMinimised (bool /*shouldBeMinimised*/) override { // n/a } @@ -337,7 +339,7 @@ public: stopTimer(); } - void setIcon (const Image& newIcon) override + void setIcon (const Image& /*newIcon*/) override { // n/a } @@ -357,7 +359,7 @@ public: return BorderSize(); } - bool setAlwaysOnTop (bool alwaysOnTop) override + bool setAlwaysOnTop (bool /*alwaysOnTop*/) override { // TODO return false; @@ -365,7 +367,13 @@ public: void toFront (bool makeActive) override { - view.callVoidMethod (ComponentPeerView.bringToFront); + // Avoid calling bringToFront excessively: it's very slow + if (frontWindow != this) + { + view.callVoidMethod (ComponentPeerView.bringToFront); + + frontWindow = this; + } if (makeActive) grabFocus(); @@ -385,7 +393,8 @@ public: lastMousePos = pos; // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. - handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, time); + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, currentModifiers.withoutMouseButtons(), + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index); if (isValidPeer (this)) handleMouseDragCallback (index, sysPos, time); @@ -399,8 +408,8 @@ public: jassert (index < 64); touchesDown = (touchesDown | (1 << (index & 63))); currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); - handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier), - MouseInputSource::invalidPressure, time); + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier), + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index); } void handleMouseUpCallback (int index, Point pos, int64 time) @@ -414,27 +423,38 @@ public: if (touchesDown == 0) currentModifiers = currentModifiers.withoutMouseButtons(); - handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, time); + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, time, {}, index); } void handleKeyDownCallback (int k, int kc) { - handleKeyPress (k, kc); + handleKeyPress (k, static_cast (kc)); + } + + void handleKeyUpCallback (int /*k*/, int /*kc*/) + { } - void handleKeyUpCallback (int k, int kc) + void handleBackButtonCallback() { + if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + app->backButtonPressed(); } //============================================================================== bool isFocused() const override { - return view.callBooleanMethod (ComponentPeerView.hasFocus); + if (view != nullptr) + return view.callBooleanMethod (ComponentPeerView.hasFocus); + + return false; } void grabFocus() override { - view.callBooleanMethod (ComponentPeerView.requestFocus); + if (view != nullptr) + view.callBooleanMethod (ComponentPeerView.requestFocus); } void handleFocusChangeCallback (bool hasFocus) @@ -549,7 +569,7 @@ public: // TODO } - void setAlpha (float newAlpha) override + void setAlpha (float /*newAlpha*/) override { // TODO } @@ -568,9 +588,10 @@ private: //============================================================================== GlobalRef view; GlobalRef buffer; - bool usingAndroidGraphics, fullScreen; + bool fullScreen; int sizeAllocated; float scale; + static AndroidComponentPeer* frontWindow; struct PreallocatedImage : public ImagePixelData { @@ -578,7 +599,7 @@ private: : ImagePixelData (Image::ARGB, width_, height_), data (data_), hasAlpha (hasAlpha_) { if (hasAlpha_) - zeromem (data_, width * height * sizeof (jint)); + zeromem (data_, static_cast (width * height) * sizeof (jint)); } ~PreallocatedImage() @@ -598,20 +619,20 @@ private: ImageType* createType() const override { return new SoftwareImageType(); } LowLevelGraphicsContext* createLowLevelContext() override { return new LowLevelGraphicsSoftwareRenderer (Image (this)); } - void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode mode) + void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/) override { - bm.lineStride = width * sizeof (jint); - bm.pixelStride = sizeof (jint); + bm.lineStride = width * static_cast (sizeof (jint)); + bm.pixelStride = static_cast (sizeof (jint)); bm.pixelFormat = Image::ARGB; bm.data = (uint8*) (data + x + y * width); } - ImagePixelData::Ptr clone() + ImagePixelData::Ptr clone() override { PreallocatedImage* s = new PreallocatedImage (width, height, 0, hasAlpha); - s->allocatedData.malloc (sizeof (jint) * width * height); + s->allocatedData.malloc (sizeof (jint) * static_cast (width * height)); s->data = s->allocatedData; - memcpy (s->data, data, sizeof (jint) * width * height); + memcpy (s->data, data, sizeof (jint) * static_cast (width * height)); return s; } @@ -629,6 +650,7 @@ private: ModifierKeys AndroidComponentPeer::currentModifiers = 0; Point AndroidComponentPeer::lastMousePos; int64 AndroidComponentPeer::touchesDown = 0; +AndroidComponentPeer* AndroidComponentPeer::frontWindow = nullptr; //============================================================================== #define JUCE_VIEW_CALLBACK(returnType, javaMethodName, params, juceMethodInvocation) \ @@ -639,14 +661,15 @@ int64 AndroidComponentPeer::touchesDown = 0; peer->juceMethodInvocation; \ } -JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject view, jlong host, jobject canvas, jobject paint), handlePaintCallback (env, canvas, paint)) -JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, Point ((float) x, (float) y), (int64) time)) -JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, Point ((float) x, (float) y), (int64) time)) -JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, Point ((float) x, (float) y), (int64) time)) -JUCE_VIEW_CALLBACK (void, viewSizeChanged, (JNIEnv* env, jobject view, jlong host), handleMovedOrResized()) -JUCE_VIEW_CALLBACK (void, focusChanged, (JNIEnv* env, jobject view, jlong host, jboolean hasFocus), handleFocusChangeCallback (hasFocus)) -JUCE_VIEW_CALLBACK (void, handleKeyDown, (JNIEnv* env, jobject view, jlong host, jint k, jint kc), handleKeyDownCallback ((int) k, (int) kc)) -JUCE_VIEW_CALLBACK (void, handleKeyUp, (JNIEnv* env, jobject view, jlong host, jint k, jint kc), handleKeyUpCallback ((int) k, (int) kc)) +JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject /*view*/, jlong host, jobject canvas, jobject paint), handlePaintCallback (env, canvas, paint)) +JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, Point ((float) x, (float) y), (int64) time)) +JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, Point ((float) x, (float) y), (int64) time)) +JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, Point ((float) x, (float) y), (int64) time)) +JUCE_VIEW_CALLBACK (void, viewSizeChanged, (JNIEnv* env, jobject /*view*/, jlong host), handleMovedOrResized()) +JUCE_VIEW_CALLBACK (void, focusChanged, (JNIEnv* env, jobject /*view*/, jlong host, jboolean hasFocus), handleFocusChangeCallback (hasFocus)) +JUCE_VIEW_CALLBACK (void, handleKeyDown, (JNIEnv* env, jobject /*view*/, jlong host, jint k, jint kc), handleKeyDownCallback ((int) k, (int) kc)) +JUCE_VIEW_CALLBACK (void, handleKeyUp, (JNIEnv* env, jobject /*view*/, jlong host, jint k, jint kc), handleKeyUpCallback ((int) k, (int) kc)) +JUCE_VIEW_CALLBACK (void, handleBackButton, (JNIEnv* env, jobject /*view*/, jlong host), handleBackButtonCallback()) //============================================================================== ComponentPeer* Component::createNewPeer (int styleFlags, void*) @@ -673,7 +696,12 @@ Desktop::DisplayOrientation Desktop::getCurrentOrientation() const bool MouseInputSource::SourceList::addSource() { - addSource (sources.size(), false); + addSource (sources.size(), MouseInputSource::InputSourceType::touch); + return true; +} + +bool MouseInputSource::SourceList::canUseTouch() +{ return true; } @@ -688,7 +716,7 @@ void MouseInputSource::setRawMousePosition (Point) } //============================================================================== -bool KeyPress::isKeyCurrentlyDown (const int keyCode) +bool KeyPress::isKeyCurrentlyDown (const int /*keyCode*/) { // TODO return false; @@ -711,30 +739,31 @@ JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() {} JUCE_API void JUCE_CALLTYPE Process::hide() {} //============================================================================== -void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType, +void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, - Component* associatedComponent, + Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { android.activity.callVoidMethod (JuceAppActivity.showMessageBox, javaString (title).get(), javaString (message).get(), (jlong) (pointer_sized_int) callback); } -bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType, +bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, - Component* associatedComponent, + Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { jassert (callback != nullptr); // on android, all alerts must be non-modal!! android.activity.callVoidMethod (JuceAppActivity.showOkCancelBox, javaString (title).get(), - javaString (message).get(), (jlong) (pointer_sized_int) callback); + javaString (message).get(), (jlong) (pointer_sized_int) callback, + javaString (TRANS ("OK")).get(), javaString (TRANS ("Cancel")).get()); return false; } -int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType, +int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType /*iconType*/, const String& title, const String& message, - Component* associatedComponent, + Component* /*associatedComponent*/, ModalComponentManager::Callback* callback) { jassert (callback != nullptr); // on android, all alerts must be non-modal!! @@ -744,7 +773,20 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy return 0; } -JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, alertDismissed, void, (JNIEnv* env, jobject activity, +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType /*iconType*/, + const String& title, const String& message, + Component* /*associatedComponent*/, + ModalComponentManager::Callback* callback) +{ + jassert (callback != nullptr); // on android, all alerts must be non-modal!! + + android.activity.callVoidMethod (JuceAppActivity.showOkCancelBox, javaString (title).get(), + javaString (message).get(), (jlong) (pointer_sized_int) callback, + javaString (TRANS ("Yes")).get(), javaString (TRANS ("No")).get()); + return 0; +} + +JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, alertDismissed, void, (JNIEnv* env, jobject /*activity*/, jlong callbackAsLong, jint result)) { setEnv (env); @@ -830,7 +872,7 @@ void Desktop::Displays::findDisplays (float masterScale) displays.add (d); } -JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, setScreenSize, void, (JNIEnv* env, jobject activity, +JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, setScreenSize, void, (JNIEnv* env, jobject /*activity*/, jint screenWidth, jint screenHeight, jint dpi)) { @@ -844,7 +886,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, setScreenSize, void, (JNIEnv } //============================================================================== -Image juce_createIconForFile (const File& file) +Image juce_createIconForFile (const File& /*file*/) { return Image(); } @@ -859,12 +901,13 @@ void MouseCursor::showInWindow (ComponentPeer*) const {} void MouseCursor::showInAllWindows() const {} //============================================================================== -bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMove) +bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& /*files*/, const bool /*canMove*/, + Component* /*srcComp*/) { return false; } -bool DragAndDropContainer::performExternalDragDropOfText (const String& text) +bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/, Component* /*srcComp*/) { return false; } diff --git a/source/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm b/source/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm index afdc29562..e9cb4a22d 100644 --- a/source/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm +++ b/source/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -214,7 +216,7 @@ public: UIWindow* window; JuceUIView* view; JuceUIViewController* controller; - bool isSharedWindow, fullScreen, insideDrawRect; + bool isSharedWindow, fullScreen, insideDrawRect, isAppex; static ModifierKeys currentModifiers; static int64 getMouseTime (UIEvent* e) noexcept @@ -283,7 +285,7 @@ public: return r; } - MultiTouchMapper currentTouches; + static MultiTouchMapper currentTouches; private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UIViewComponentPeer) @@ -322,6 +324,8 @@ static bool isKioskModeView (JuceUIViewController* c) return Desktop::getInstance().getKioskModeComponent() == &(juceView->owner->getComponent()); } +MultiTouchMapper UIViewComponentPeer::currentTouches; + } // (juce namespace) @@ -551,7 +555,8 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, const int windowStyle controller (nil), isSharedWindow (viewToAttachTo != nil), fullScreen (false), - insideDrawRect (false) + insideDrawRect (false), + isAppex (SystemStats::isRunningInAppExtensionSandbox()) { CGRect r = convertToCGRect (component.getBounds()); @@ -727,7 +732,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]; @@ -846,8 +851,8 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons modsToSend = currentModifiers; // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. - handleMouseEvent (touchIndex, pos, modsToSend.withoutMouseButtons(), - MouseInputSource::invalidPressure, time); + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend.withoutMouseButtons(), + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, touchIndex); if (! isValidPeer (this)) // (in case this component was deleted by the event) return; @@ -874,15 +879,16 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons float pressure = maximumForce > 0 ? jlimit (0.0001f, 0.9999f, getTouchForce (touch) / maximumForce) : MouseInputSource::invalidPressure; - handleMouseEvent (touchIndex, pos, modsToSend, pressure, time); + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend, pressure, + MouseInputSource::invalidOrientation, time, { }, touchIndex); if (! isValidPeer (this)) // (in case this component was deleted by the event) return; if (isUp || isCancel) { - handleMouseEvent (touchIndex, Point (-1.0f, -1.0f), - modsToSend, MouseInputSource::invalidPressure, time); + handleMouseEvent (MouseInputSource::InputSourceType::touch, Point (-1.0f, -1.0f), modsToSend, + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, touchIndex); if (! isValidPeer (this)) return; @@ -917,6 +923,9 @@ void UIViewComponentPeer::viewFocusLoss() bool UIViewComponentPeer::isFocused() const { + if (isAppex) + return true; + return isSharedWindow ? this == currentlyFocusedPeer : (window != nil && [window isKeyWindow]); } diff --git a/source/modules/juce_gui_basics/native/juce_ios_Windowing.mm b/source/modules/juce_gui_basics/native/juce_ios_Windowing.mm index 0e605f79c..a82990358 100644 --- a/source/modules/juce_gui_basics/native/juce_ios_Windowing.mm +++ b/source/modules/juce_gui_basics/native/juce_ios_Windowing.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -37,9 +39,11 @@ Array appBecomingInactiveCallbacks; @interface JuceAppStartupDelegate : NSObject { + UIBackgroundTaskIdentifier appSuspendTask; } @property (strong, nonatomic) UIWindow *window; +- (id)init; - (void) applicationDidFinishLaunching: (UIApplication*) application; - (void) applicationWillTerminate: (UIApplication*) application; - (void) applicationDidEnterBackground: (UIApplication*) application; @@ -52,6 +56,14 @@ Array appBecomingInactiveCallbacks; @implementation JuceAppStartupDelegate +- (id)init +{ + self = [super init]; + appSuspendTask = UIBackgroundTaskInvalid; + + return self; +} + - (void) applicationDidFinishLaunching: (UIApplication*) application { ignoreUnused (application); @@ -76,10 +88,23 @@ Array appBecomingInactiveCallbacks; - (void) applicationDidEnterBackground: (UIApplication*) application { - ignoreUnused (application); - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + { + #if JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK + appSuspendTask = [application beginBackgroundTaskWithName:@"JUCE Suspend Task" expirationHandler:^{ + if (appSuspendTask != UIBackgroundTaskInvalid) + { + [application endBackgroundTask:appSuspendTask]; + appSuspendTask = UIBackgroundTaskInvalid; + } + }]; + + MessageManager::callAsync ([self,application,app] () { app->suspended(); }); + #else + ignoreUnused (application); app->suspended(); + #endif + } } - (void) applicationWillEnterForeground: (UIApplication*) application @@ -329,14 +354,28 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy return 0; } +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType /*iconType*/, + const String& title, const String& message, + Component* /*associatedComponent*/, + ModalComponentManager::Callback* callback) +{ + ScopedPointer mb (new iOSMessageBox (title, message, @"No", @"Yes", nil, callback, callback != nullptr)); + + if (callback == nullptr) + return mb->getResult(); + + mb.release(); + return 0; +} + //============================================================================== -bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray&, bool) +bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray&, bool, Component*) { jassertfalse; // no such thing on iOS! return false; } -bool DragAndDropContainer::performExternalDragDropOfText (const String&) +bool DragAndDropContainer::performExternalDragDropOfText (const String&, Component*) { jassertfalse; // no such thing on iOS! return false; @@ -384,7 +423,12 @@ String SystemClipboard::getTextFromClipboard() //============================================================================== bool MouseInputSource::SourceList::addSource() { - addSource (sources.size(), false); + addSource (sources.size(), MouseInputSource::InputSourceType::touch); + return true; +} + +bool MouseInputSource::SourceList::canUseTouch() +{ return true; } diff --git a/source/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp b/source/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp index 05b23f6fc..8a485abc2 100644 --- a/source/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp +++ b/source/modules/juce_gui_basics/native/juce_linux_FileChooser.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -175,6 +177,15 @@ void FileChooser::showPlatformDialog (Array& results, if (child.start (args, ChildProcess::wantStdOut)) { + if (MessageManager::getInstance()->isThisTheMessageThread()) + { + while (child.isRunning()) + { + if (! MessageManager::getInstance()->runDispatchLoopUntil(20)) + break; + } + } + const String result (child.readAllProcessOutput().trim()); if (result.isNotEmpty()) diff --git a/source/modules/juce_gui_basics/native/juce_linux_X11.cpp b/source/modules/juce_gui_basics/native/juce_linux_X11.cpp new file mode 100644 index 000000000..af009643d --- /dev/null +++ b/source/modules/juce_gui_basics/native/juce_linux_X11.cpp @@ -0,0 +1,335 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +typedef void (*WindowMessageReceiveCallback) (XEvent&); +WindowMessageReceiveCallback dispatchWindowMessage = nullptr; + +typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&); +SelectionRequestCallback handleSelectionRequest = nullptr; + +::Window juce_messageWindowHandle; + +XContext windowHandleXContext; + +//============================================================================== +namespace X11ErrorHandling +{ + static XErrorHandler oldErrorHandler = (XErrorHandler) 0; + static XIOErrorHandler oldIOErrorHandler = (XIOErrorHandler) 0; + + //============================================================================== + // Usually happens when client-server connection is broken + int ioErrorHandler (::Display*) + { + DBG ("ERROR: connection to X server broken.. terminating."); + + if (JUCEApplicationBase::isStandaloneApp()) + MessageManager::getInstance()->stopDispatchLoop(); + + // set this somewhere + // errorOccurred = true; + return 0; + } + + + int errorHandler (::Display* display, XErrorEvent* event) + { + ignoreUnused (display, event); + + #if JUCE_DEBUG_XERRORS + char errorStr[64] = { 0 }; + char requestStr[64] = { 0 }; + + XGetErrorText (display, event->error_code, errorStr, 64); + XGetErrorDatabaseText (display, "XRequest", String (event->request_code).toUTF8(), "Unknown", requestStr, 64); + DBG ("ERROR: X returned " << errorStr << " for operation " << requestStr); + #endif + + return 0; + } + + void installXErrorHandlers() + { + oldIOErrorHandler = XSetIOErrorHandler (ioErrorHandler); + oldErrorHandler = XSetErrorHandler (errorHandler); + } + + void removeXErrorHandlers() + { + XSetIOErrorHandler (oldIOErrorHandler); + oldIOErrorHandler = 0; + + XSetErrorHandler (oldErrorHandler); + oldErrorHandler = 0; + } +} + +//============================================================================== +XWindowSystem::XWindowSystem() noexcept + : display (nullptr) +{ + if (JUCEApplicationBase::isStandaloneApp()) + { + // Initialise xlib for multiple thread support + static bool initThreadCalled = false; + + if (! initThreadCalled) + { + if (! XInitThreads()) + { + // This is fatal! Print error and closedown + Logger::outputDebugString ("Failed to initialise xlib thread support."); + Process::terminate(); + return; + } + + initThreadCalled = true; + } + + X11ErrorHandling::installXErrorHandlers(); + } +} + +XWindowSystem::~XWindowSystem() noexcept +{ + if (JUCEApplicationBase::isStandaloneApp()) + X11ErrorHandling::removeXErrorHandlers(); + + clearSingletonInstance(); +} + + +::Display* XWindowSystem::displayRef() noexcept +{ + if (++displayCount - 1 == 0) + { + String displayName (getenv ("DISPLAY")); + if (displayName.isEmpty()) + displayName = ":0.0"; + + display = XOpenDisplay (displayName.toUTF8()); + + initialiseXDisplay(); + } + + return this->display; +} + +::Display* XWindowSystem::displayUnref() noexcept +{ + jassert (display != nullptr); + jassert (displayCount.get() > 0); + + if (--displayCount == 0) + { + destroyXDisplay(); + XCloseDisplay (display); + display = nullptr; + } + + return display; +} + +void XWindowSystem::initialiseXDisplay() noexcept +{ + // This is fatal! Print error and closedown + if (display == nullptr) + { + Logger::outputDebugString ("Failed to connect to the X Server."); + Process::terminate(); + } + + // Create a context to store user data associated with Windows we create + windowHandleXContext = XUniqueContext(); + + // We're only interested in client messages for this window, which are always sent + XSetWindowAttributes swa; + swa.event_mask = NoEventMask; + + // Create our message window (this will never be mapped) + const int screen = DefaultScreen (display); + juce_messageWindowHandle = XCreateWindow (display, RootWindow (display, screen), + 0, 0, 1, 1, 0, 0, InputOnly, + DefaultVisual (display, screen), + CWEventMask, &swa); + + XSync (display, False); + + // Setup input event handler + int fd = XConnectionNumber (display); + LinuxEventLoop::setWindowSystemFd + (fd, + [this](int /*fd*/) { + do + { + XEvent evt; + + { + ScopedXLock xlock (display); + + if (! XPending (display)) + return false; + + XNextEvent (display, &evt); + } + + if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle + && handleSelectionRequest != nullptr) + handleSelectionRequest (evt.xselectionrequest); + else if (evt.xany.window != juce_messageWindowHandle + && dispatchWindowMessage != nullptr) + dispatchWindowMessage (evt); + + } while (display != nullptr); + + return false; + }); +} + +void XWindowSystem::destroyXDisplay() noexcept +{ + ScopedXLock xlock (display); + + XDestroyWindow (display, juce_messageWindowHandle); + + juce_messageWindowHandle = 0; + + XSync (display, True); + + LinuxEventLoop::removeWindowSystemFd(); +} + +juce_ImplementSingleton (XWindowSystem) + +//============================================================================== +ScopedXDisplay::ScopedXDisplay() : display (XWindowSystem::getInstance()->displayRef()) +{ +} + +ScopedXDisplay::~ScopedXDisplay() +{ + XWindowSystem::getInstance()->displayUnref(); +} + +//============================================================================== +ScopedXLock::ScopedXLock(::Display* d) : display (d) +{ + if (display != nullptr) XLockDisplay (display); +} + +ScopedXLock::~ScopedXLock() +{ + if (display != nullptr) XUnlockDisplay (display); +} + +//============================================================================== +Atoms::Atoms(::Display* display) +{ + protocols = getIfExists (display, "WM_PROTOCOLS"); + protocolList [TAKE_FOCUS] = getIfExists (display, "WM_TAKE_FOCUS"); + protocolList [DELETE_WINDOW] = getIfExists (display, "WM_DELETE_WINDOW"); + protocolList [PING] = getIfExists (display, "_NET_WM_PING"); + changeState = getIfExists (display, "WM_CHANGE_STATE"); + state = getIfExists (display, "WM_STATE"); + userTime = getCreating (display, "_NET_WM_USER_TIME"); + activeWin = getCreating (display, "_NET_ACTIVE_WINDOW"); + pid = getCreating (display, "_NET_WM_PID"); + windowType = getIfExists (display, "_NET_WM_WINDOW_TYPE"); + windowState = getIfExists (display, "_NET_WM_STATE"); + + XdndAware = getCreating (display, "XdndAware"); + XdndEnter = getCreating (display, "XdndEnter"); + XdndLeave = getCreating (display, "XdndLeave"); + XdndPosition = getCreating (display, "XdndPosition"); + XdndStatus = getCreating (display, "XdndStatus"); + XdndDrop = getCreating (display, "XdndDrop"); + XdndFinished = getCreating (display, "XdndFinished"); + XdndSelection = getCreating (display, "XdndSelection"); + + XdndTypeList = getCreating (display, "XdndTypeList"); + XdndActionList = getCreating (display, "XdndActionList"); + XdndActionCopy = getCreating (display, "XdndActionCopy"); + XdndActionPrivate = getCreating (display, "XdndActionPrivate"); + XdndActionDescription = getCreating (display, "XdndActionDescription"); + + XembedMsgType = getCreating (display, "_XEMBED"); + XembedInfo = getCreating (display, "_XEMBED_INFO"); + + allowedMimeTypes[0] = getCreating (display, "UTF8_STRING"); + allowedMimeTypes[1] = getCreating (display, "text/plain;charset=utf-8"); + allowedMimeTypes[2] = getCreating (display, "text/plain"); + allowedMimeTypes[3] = getCreating (display, "text/uri-list"); + + allowedActions[0] = getCreating (display, "XdndActionMove"); + allowedActions[1] = XdndActionCopy; + allowedActions[2] = getCreating (display, "XdndActionLink"); + allowedActions[3] = getCreating (display, "XdndActionAsk"); + allowedActions[4] = XdndActionPrivate; +} + +Atom Atoms::getIfExists (::Display* display, const char* name) +{ + return XInternAtom (display, name, True); +} + +Atom Atoms::getCreating (::Display* display, const char* name) +{ + return XInternAtom (display, name, False); +} + +String Atoms::getName (::Display* display, const Atom atom) +{ + if (atom == None) + return "None"; + + return String (XGetAtomName (display, atom)); +} + +bool Atoms::isMimeTypeFile (::Display* display, const Atom atom) +{ + return getName (display, atom).equalsIgnoreCase ("text/uri-list"); +} + + +const unsigned long Atoms::DndVersion = 3; + +//============================================================================== +GetXProperty::GetXProperty (::Display* display, Window window, Atom atom, + long offset, long length, bool shouldDelete, + Atom requestedType) + : data (nullptr) +{ + success = (XGetWindowProperty (display, window, atom, offset, length, + (Bool) shouldDelete, requestedType, &actualType, + &actualFormat, &numItems, &bytesLeft, &data) == Success) + && data != nullptr; +} + +GetXProperty::~GetXProperty() +{ + if (data != nullptr) + XFree (data); +} diff --git a/source/modules/juce_gui_basics/native/juce_linux_X11.h b/source/modules/juce_gui_basics/native/juce_linux_X11.h new file mode 100644 index 000000000..00c55bf12 --- /dev/null +++ b/source/modules/juce_gui_basics/native/juce_linux_X11.h @@ -0,0 +1,144 @@ +/* + ============================================================================== + + 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 + +// Hack to forward declare _XDisplay outside the +// juce namespace + +} + +struct _XDisplay; + +namespace juce +{ + +typedef ::_XDisplay* XDisplay; + +typedef unsigned long ATOM_TYPE; +typedef unsigned long WINDOW_TYPE; + + +//============================================================================== +class XWindowSystem +{ +public: + XDisplay displayRef() noexcept; + XDisplay displayUnref() noexcept; + + juce_DeclareSingleton (XWindowSystem, false) + +private: + XDisplay display; + Atomic displayCount; + + XWindowSystem() noexcept; + ~XWindowSystem() noexcept; + + void initialiseXDisplay() noexcept; + void destroyXDisplay() noexcept; +}; + +//============================================================================== +class ScopedXDisplay +{ +public: + ScopedXDisplay(); + ~ScopedXDisplay(); + + const XDisplay display; +}; + +//============================================================================== +/** A handy class that uses XLockDisplay and XUnlockDisplay to lock the X server + using RAII (Only available in Linux!). +*/ +class ScopedXLock +{ +public: + /** Creating a ScopedXLock object locks the X display. + This uses XLockDisplay() to grab the display that Juce is using. + */ + ScopedXLock (XDisplay); + + /** Deleting a ScopedXLock object unlocks the X display. + This calls XUnlockDisplay() to release the lock. + */ + ~ScopedXLock(); + +private: + // defined in juce_linux_X11.h + XDisplay display; +}; + +//============================================================================== +struct Atoms +{ + Atoms (XDisplay); + + enum ProtocolItems + { + TAKE_FOCUS = 0, + DELETE_WINDOW = 1, + PING = 2 + }; + + ATOM_TYPE protocols, protocolList[3], changeState, state, userTime, + activeWin, pid, windowType, windowState, + XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus, + XdndDrop, XdndFinished, XdndSelection, XdndTypeList, XdndActionList, + XdndActionDescription, XdndActionCopy, XdndActionPrivate, + XembedMsgType, XembedInfo, + allowedActions[5], + allowedMimeTypes[4]; + + static const unsigned long DndVersion; + + static ATOM_TYPE getIfExists (XDisplay, const char* name); + static ATOM_TYPE getCreating (XDisplay, const char* name); + + static String getName (XDisplay, ATOM_TYPE atom); + + static bool isMimeTypeFile (XDisplay, ATOM_TYPE atom); +}; + +//============================================================================== +struct GetXProperty +{ + GetXProperty (XDisplay, WINDOW_TYPE window, ATOM_TYPE atom, + long offset, long length, bool shouldDelete, + ATOM_TYPE requestedType); + + ~GetXProperty(); + + bool success; + unsigned char* data; + unsigned long numItems, bytesLeft; + ATOM_TYPE actualType; + int actualFormat; +}; + +#undef ATOM_TYPE diff --git a/source/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp b/source/modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp similarity index 58% rename from source/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp rename to source/modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp index 0427e9458..9c8e92b5b 100644 --- a/source/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp +++ b/source/modules/juce_gui_basics/native/juce_linux_X11_Clipboard.cpp @@ -2,27 +2,28 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -extern ::Display* display; extern ::Window juce_messageWindowHandle; namespace ClipboardHelpers @@ -33,7 +34,7 @@ namespace ClipboardHelpers static Atom atom_TARGETS; //============================================================================== - static void initSelectionAtoms() + static void initSelectionAtoms (::Display* display) { static bool isInitialised = false; @@ -41,16 +42,16 @@ namespace ClipboardHelpers { isInitialised = true; - atom_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False); - atom_CLIPBOARD = XInternAtom (display, "CLIPBOARD", False); - atom_TARGETS = XInternAtom (display, "TARGETS", False); + atom_UTF8_STRING = Atoms::getCreating (display, "UTF8_STRING"); + atom_CLIPBOARD = Atoms::getCreating (display, "CLIPBOARD"); + atom_TARGETS = Atoms::getCreating (display, "TARGETS"); } } //============================================================================== // Read the content of a window property as either a locale-dependent string or an utf8 string // works only for strings shorter than 1000000 bytes - static String readWindowProperty (Window window, Atom prop) + static String readWindowProperty (::Display* display, Window window, Atom prop) { String returnData; @@ -86,7 +87,8 @@ namespace ClipboardHelpers //============================================================================== // Send a SelectionRequest to the window owning the selection and waits for its answer (with a timeout) */ - static bool requestSelectionContent (String& selectionContent, Atom selection, Atom requestedFormat) + static bool requestSelectionContent (::Display* display, String& selectionContent, + Atom selection, Atom requestedFormat) { Atom property_name = XInternAtom (display, "JUCE_SEL", false); @@ -107,7 +109,7 @@ namespace ClipboardHelpers { jassert (event.xselection.requestor == juce_messageWindowHandle); - selectionContent = readWindowProperty (event.xselection.requestor, + selectionContent = readWindowProperty (display, event.xselection.requestor, event.xselection.property); return true; } @@ -128,69 +130,66 @@ namespace ClipboardHelpers // Called from the event loop in juce_linux_Messaging in response to SelectionRequest events static void handleSelection (XSelectionRequestEvent& evt) { - if (display != nullptr) + ClipboardHelpers::initSelectionAtoms (evt.display); + + // the selection content is sent to the target window as a window property + XSelectionEvent reply; + reply.type = SelectionNotify; + reply.display = evt.display; + reply.requestor = evt.requestor; + reply.selection = evt.selection; + reply.target = evt.target; + reply.property = None; // == "fail" + reply.time = evt.time; + + HeapBlock data; + int propertyFormat = 0; + size_t numDataItems = 0; + + if (evt.selection == XA_PRIMARY || evt.selection == ClipboardHelpers::atom_CLIPBOARD) { - ClipboardHelpers::initSelectionAtoms(); - - // the selection content is sent to the target window as a window property - XSelectionEvent reply; - reply.type = SelectionNotify; - reply.display = evt.display; - reply.requestor = evt.requestor; - reply.selection = evt.selection; - reply.target = evt.target; - reply.property = None; // == "fail" - reply.time = evt.time; - - HeapBlock data; - int propertyFormat = 0; - size_t numDataItems = 0; - - if (evt.selection == XA_PRIMARY || evt.selection == ClipboardHelpers::atom_CLIPBOARD) + if (evt.target == XA_STRING || evt.target == ClipboardHelpers::atom_UTF8_STRING) { - if (evt.target == XA_STRING || evt.target == ClipboardHelpers::atom_UTF8_STRING) - { - // translate to utf8 - numDataItems = ClipboardHelpers::localClipboardContent.getNumBytesAsUTF8() + 1; - data.calloc (numDataItems + 1); - ClipboardHelpers::localClipboardContent.copyToUTF8 (data, numDataItems); - propertyFormat = 8; // bits/item - } - else if (evt.target == ClipboardHelpers::atom_TARGETS) - { - // another application wants to know what we are able to send - numDataItems = 2; - propertyFormat = 32; // atoms are 32-bit - data.calloc (numDataItems * 4); - Atom* atoms = reinterpret_cast (data.getData()); - atoms[0] = ClipboardHelpers::atom_UTF8_STRING; - atoms[1] = XA_STRING; - - evt.target = XA_ATOM; - } + // translate to utf8 + numDataItems = ClipboardHelpers::localClipboardContent.getNumBytesAsUTF8() + 1; + data.calloc (numDataItems + 1); + ClipboardHelpers::localClipboardContent.copyToUTF8 (data, numDataItems); + propertyFormat = 8; // bits/item } - else + else if (evt.target == ClipboardHelpers::atom_TARGETS) { - DBG ("requested unsupported clipboard"); + // another application wants to know what we are able to send + numDataItems = 2; + propertyFormat = 32; // atoms are 32-bit + data.calloc (numDataItems * 4); + Atom* atoms = reinterpret_cast (data.getData()); + atoms[0] = ClipboardHelpers::atom_UTF8_STRING; + atoms[1] = XA_STRING; + + evt.target = XA_ATOM; } + } + else + { + DBG ("requested unsupported clipboard"); + } - if (data != nullptr) - { - const size_t maxReasonableSelectionSize = 1000000; + if (data != nullptr) + { + const size_t maxReasonableSelectionSize = 1000000; - // for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss - if (evt.property != None && numDataItems < maxReasonableSelectionSize) - { - XChangeProperty (evt.display, evt.requestor, - evt.property, evt.target, - propertyFormat /* 8 or 32 */, PropModeReplace, - reinterpret_cast (data.getData()), (int) numDataItems); - reply.property = evt.property; // " == success" - } + // for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss + if (evt.property != None && numDataItems < maxReasonableSelectionSize) + { + XChangeProperty (evt.display, evt.requestor, + evt.property, evt.target, + propertyFormat /* 8 or 32 */, PropModeReplace, + reinterpret_cast (data.getData()), (int) numDataItems); + reply.property = evt.property; // " == success" } - - XSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply); } + + XSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply); } } @@ -211,9 +210,11 @@ static ClipboardCallbackInitialiser clipboardInitialiser; //============================================================================== void SystemClipboard::copyTextToClipboard (const String& clipText) { - if (display != nullptr) + ScopedXDisplay xDisplay; + + if (auto display = xDisplay.display) { - ClipboardHelpers::initSelectionAtoms(); + ClipboardHelpers::initSelectionAtoms (display); ClipboardHelpers::localClipboardContent = clipText; XSetSelectionOwner (display, XA_PRIMARY, juce_messageWindowHandle, CurrentTime); @@ -224,10 +225,11 @@ void SystemClipboard::copyTextToClipboard (const String& clipText) String SystemClipboard::getTextFromClipboard() { String content; + ScopedXDisplay xDisplay; - if (display != nullptr) + if (auto display = xDisplay.display) { - ClipboardHelpers::initSelectionAtoms(); + ClipboardHelpers::initSelectionAtoms (display); /* 1) try to read from the "CLIPBOARD" selection first (the "high level" clipboard that is supposed to be filled by ctrl-C @@ -256,12 +258,14 @@ String SystemClipboard::getTextFromClipboard() else { // first try: we want an utf8 string - bool ok = ClipboardHelpers::requestSelectionContent (content, selection, ClipboardHelpers::atom_UTF8_STRING); + bool ok = ClipboardHelpers::requestSelectionContent (display, content, + selection, ClipboardHelpers::atom_UTF8_STRING); if (! ok) { // second chance, ask for a good old locale-dependent string .. - ok = ClipboardHelpers::requestSelectionContent (content, selection, XA_STRING); + ok = ClipboardHelpers::requestSelectionContent (display, content, + selection, XA_STRING); } } } diff --git a/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/source/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp similarity index 76% rename from source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp rename to source/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp index 412394825..30367b17c 100644 --- a/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp +++ b/source/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp @@ -2,135 +2,49 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -extern ::Display* display; -extern XContext windowHandleXContext; -typedef void (*WindowMessageReceiveCallback) (XEvent&); -extern WindowMessageReceiveCallback dispatchWindowMessage; - - -//============================================================================== -struct Atoms -{ - Atoms() - { - protocols = getIfExists ("WM_PROTOCOLS"); - protocolList [TAKE_FOCUS] = getIfExists ("WM_TAKE_FOCUS"); - protocolList [DELETE_WINDOW] = getIfExists ("WM_DELETE_WINDOW"); - protocolList [PING] = getIfExists ("_NET_WM_PING"); - changeState = getIfExists ("WM_CHANGE_STATE"); - state = getIfExists ("WM_STATE"); - userTime = getCreating ("_NET_WM_USER_TIME"); - activeWin = getCreating ("_NET_ACTIVE_WINDOW"); - pid = getCreating ("_NET_WM_PID"); - windowType = getIfExists ("_NET_WM_WINDOW_TYPE"); - windowState = getIfExists ("_NET_WM_STATE"); - - XdndAware = getCreating ("XdndAware"); - XdndEnter = getCreating ("XdndEnter"); - XdndLeave = getCreating ("XdndLeave"); - XdndPosition = getCreating ("XdndPosition"); - XdndStatus = getCreating ("XdndStatus"); - XdndDrop = getCreating ("XdndDrop"); - XdndFinished = getCreating ("XdndFinished"); - XdndSelection = getCreating ("XdndSelection"); - - XdndTypeList = getCreating ("XdndTypeList"); - XdndActionList = getCreating ("XdndActionList"); - XdndActionCopy = getCreating ("XdndActionCopy"); - XdndActionPrivate = getCreating ("XdndActionPrivate"); - XdndActionDescription = getCreating ("XdndActionDescription"); - - allowedMimeTypes[0] = getCreating ("UTF8_STRING"); - allowedMimeTypes[1] = getCreating ("text/plain;charset=utf-8"); - allowedMimeTypes[2] = getCreating ("text/plain"); - allowedMimeTypes[3] = getCreating ("text/uri-list"); - - allowedActions[0] = getCreating ("XdndActionMove"); - allowedActions[1] = XdndActionCopy; - allowedActions[2] = getCreating ("XdndActionLink"); - allowedActions[3] = getCreating ("XdndActionAsk"); - allowedActions[4] = XdndActionPrivate; - } - - enum ProtocolItems - { - TAKE_FOCUS = 0, - DELETE_WINDOW = 1, - PING = 2 - }; - - Atom protocols, protocolList[3], changeState, state, userTime, - activeWin, pid, windowType, windowState, - XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus, - XdndDrop, XdndFinished, XdndSelection, XdndTypeList, XdndActionList, - XdndActionDescription, XdndActionCopy, XdndActionPrivate, - allowedActions[5], - allowedMimeTypes[4]; - - static const unsigned long DndVersion; - - static Atom getIfExists (const char* name) { return XInternAtom (display, name, True); } - static Atom getCreating (const char* name) { return XInternAtom (display, name, False); } - - static String getName (const Atom atom) - { - if (atom == None) - return "None"; - - return String (XGetAtomName (display, atom)); - } +#if JUCE_DEBUG && ! defined (JUCE_DEBUG_XERRORS) + #define JUCE_DEBUG_XERRORS 1 +#endif - static bool isMimeTypeFile (const Atom atom) { return getName (atom).equalsIgnoreCase ("text/uri-list"); } -}; +#if JUCE_MODULE_AVAILABLE_juce_gui_extra + #define JUCE_X11_SUPPORTS_XEMBED 1 +#else + #define JUCE_X11_SUPPORTS_XEMBED 0 +#endif -const unsigned long Atoms::DndVersion = 3; +#if JUCE_X11_SUPPORTS_XEMBED +bool juce_handleXEmbedEvent (ComponentPeer*, void*); +unsigned long juce_getCurrentFocusWindow (ComponentPeer*); +#endif -//============================================================================== -struct GetXProperty -{ - GetXProperty (Window window, Atom atom, long offset, long length, bool shouldDelete, Atom requestedType) - : data (nullptr) - { - success = (XGetWindowProperty (display, window, atom, offset, length, - (Bool) shouldDelete, requestedType, &actualType, - &actualFormat, &numItems, &bytesLeft, &data) == Success) - && data != nullptr; - } +extern WindowMessageReceiveCallback dispatchWindowMessage; - ~GetXProperty() - { - if (data != nullptr) - XFree (data); - } +extern XContext windowHandleXContext; - bool success; - unsigned char* data; - unsigned long numItems, bytesLeft; - Atom actualType; - int actualFormat; -}; +//=============================== X11 - Keys =================================== -//============================================================================== namespace Keys { enum MouseButtons @@ -153,49 +67,111 @@ namespace Keys bool KeyPress::isKeyCurrentlyDown (const int keyCode) { - if (display == nullptr) - return false; + ScopedXDisplay xDisplay; - int keysym; - - if (keyCode & Keys::extendedKeyModifier) + if (auto display = xDisplay.display) { - keysym = 0xff00 | (keyCode & 0xff); - } - else - { - keysym = keyCode; + int keysym; - if (keysym == (XK_Tab & 0xff) - || keysym == (XK_Return & 0xff) - || keysym == (XK_Escape & 0xff) - || keysym == (XK_BackSpace & 0xff)) + if (keyCode & Keys::extendedKeyModifier) { - keysym |= 0xff00; + keysym = 0xff00 | (keyCode & 0xff); } - } + else + { + keysym = keyCode; - ScopedXLock xlock; + if (keysym == (XK_Tab & 0xff) + || keysym == (XK_Return & 0xff) + || keysym == (XK_Escape & 0xff) + || keysym == (XK_BackSpace & 0xff)) + { + keysym |= 0xff00; + } + } - const int keycode = XKeysymToKeycode (display, (KeySym) keysym); + ScopedXLock xlock (display); - const int keybyte = keycode >> 3; - const int keybit = (1 << (keycode & 7)); - return (Keys::keyStates [keybyte] & keybit) != 0; + const int keycode = XKeysymToKeycode (display, (KeySym) keysym); + + const int keybyte = keycode >> 3; + const int keybit = (1 << (keycode & 7)); + return (Keys::keyStates [keybyte] & keybit) != 0; + } + + return false; } //============================================================================== + +const int KeyPress::spaceKey = XK_space & 0xff; +const int KeyPress::returnKey = XK_Return & 0xff; +const int KeyPress::escapeKey = XK_Escape & 0xff; +const int KeyPress::backspaceKey = XK_BackSpace & 0xff; +const int KeyPress::leftKey = (XK_Left & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::rightKey = (XK_Right & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::upKey = (XK_Up & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::downKey = (XK_Down & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::pageUpKey = (XK_Page_Up & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::pageDownKey = (XK_Page_Down & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::endKey = (XK_End & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::homeKey = (XK_Home & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::insertKey = (XK_Insert & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::deleteKey = (XK_Delete & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::tabKey = XK_Tab & 0xff; +const int KeyPress::F1Key = (XK_F1 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F2Key = (XK_F2 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F3Key = (XK_F3 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F4Key = (XK_F4 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F5Key = (XK_F5 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F6Key = (XK_F6 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F7Key = (XK_F7 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F8Key = (XK_F8 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F9Key = (XK_F9 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F10Key = (XK_F10 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F11Key = (XK_F11 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F12Key = (XK_F12 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F13Key = (XK_F13 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F14Key = (XK_F14 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F15Key = (XK_F15 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::F16Key = (XK_F16 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad0 = (XK_KP_0 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad1 = (XK_KP_1 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad2 = (XK_KP_2 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad3 = (XK_KP_3 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad4 = (XK_KP_4 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad5 = (XK_KP_5 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad6 = (XK_KP_6 & 0xff) | Keys::extendedKeyModifier; +const int KeyPress::numberPad7 = (XK_KP_7 & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPad8 = (XK_KP_8 & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPad9 = (XK_KP_9 & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPadAdd = (XK_KP_Add & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPadSubtract = (XK_KP_Subtract & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPadMultiply = (XK_KP_Multiply & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPadDivide = (XK_KP_Divide & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPadSeparator = (XK_KP_Separator & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPadDecimalPoint = (XK_KP_Decimal & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPadEquals = (XK_KP_Equal & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::numberPadDelete = (XK_KP_Delete & 0xff)| Keys::extendedKeyModifier; +const int KeyPress::playKey = ((int) 0xffeeff00) | Keys::extendedKeyModifier; +const int KeyPress::stopKey = ((int) 0xffeeff01) | Keys::extendedKeyModifier; +const int KeyPress::fastForwardKey = ((int) 0xffeeff02) | Keys::extendedKeyModifier; +const int KeyPress::rewindKey = ((int) 0xffeeff03) | Keys::extendedKeyModifier; + +//================================== X11 - Shm ================================= + #if JUCE_USE_XSHM namespace XSHMHelpers { static int trappedErrorCode = 0; + extern "C" int errorTrapHandler (Display*, XErrorEvent* err) { trappedErrorCode = err->error_code; return 0; } - static bool isShmAvailable() noexcept + static bool isShmAvailable (::Display* display) noexcept { static bool isChecked = false; static bool isAvailable = false; @@ -209,7 +185,7 @@ namespace XSHMHelpers int major, minor; Bool pixmaps; - ScopedXLock xlock; + ScopedXLock xlock (display); if (XShmQueryVersion (display, &major, &minor, &pixmaps)) { @@ -219,8 +195,8 @@ namespace XSHMHelpers XShmSegmentInfo segmentInfo; zerostruct (segmentInfo); - if (XImage* xImage = XShmCreateImage (display, DefaultVisual (display, DefaultScreen (display)), - 24, ZPixmap, 0, &segmentInfo, 50, 50)) + if (auto* xImage = XShmCreateImage (display, DefaultVisual (display, DefaultScreen (display)), + 24, ZPixmap, 0, &segmentInfo, 50, 50)) { if ((segmentInfo.shmid = shmget (IPC_PRIVATE, (size_t) (xImage->bytes_per_line * xImage->height), @@ -264,7 +240,8 @@ namespace XSHMHelpers } #endif -//============================================================================== +//=============================== X11 - Render ================================= + #if JUCE_USE_XRENDER namespace XRender { @@ -278,7 +255,7 @@ namespace XRender static tXRenderFindFormat xRenderFindFormat = nullptr; static tXRenderFindVisualFormat xRenderFindVisualFormat = nullptr; - static bool isAvailable() + static bool isAvailable (::Display* display) { static bool hasLoaded = false; @@ -288,9 +265,9 @@ namespace XRender { hasLoaded = true; - ScopedXLock xlock; + ScopedXLock xlock (display); - if (void* h = dlopen ("libXrender.so", RTLD_GLOBAL | RTLD_NOW)) + if (void* h = dlopen ("libXrender.so.1", RTLD_GLOBAL | RTLD_NOW)) { xRenderQueryVersion = (tXRenderQueryVersion) dlsym (h, "XRenderQueryVersion"); xRenderFindStandardFormat = (tXRenderFindStandardFormat) dlsym (h, "XRenderFindStandardFormat"); @@ -315,15 +292,15 @@ namespace XRender return xRenderQueryVersion != nullptr; } - static bool hasCompositingWindowManager() noexcept + static bool hasCompositingWindowManager (::Display* display) noexcept { return display != nullptr && XGetSelectionOwner (display, Atoms::getCreating ("_NET_WM_CM_S0")) != 0; } - static XRenderPictFormat* findPictureFormat() + static XRenderPictFormat* findPictureFormat (::Display* display) { - ScopedXLock xlock; + ScopedXLock xlock (display); XRenderPictFormat* pictFormat = nullptr; if (isAvailable()) @@ -362,12 +339,13 @@ namespace XRender } #endif -//============================================================================== +//================================ X11 - Visuals =============================== + namespace Visuals { - static Visual* findVisualWithDepth (const int desiredDepth) noexcept + static Visual* findVisualWithDepth (::Display* display, const int desiredDepth) noexcept { - ScopedXLock xlock; + ScopedXLock xlock (display); Visual* visual = nullptr; int numVisuals = 0; @@ -414,19 +392,19 @@ namespace Visuals return visual; } - static Visual* findVisualFormat (const int desiredDepth, int& matchedDepth) noexcept + static Visual* findVisualFormat (::Display* display, const int desiredDepth, int& matchedDepth) noexcept { Visual* visual = nullptr; if (desiredDepth == 32) { #if JUCE_USE_XSHM - if (XSHMHelpers::isShmAvailable()) + if (XSHMHelpers::isShmAvailable (display)) { #if JUCE_USE_XRENDER - if (XRender::isAvailable()) + if (XRender::isAvailable (display)) { - if (XRenderPictFormat* pictFormat = XRender::findPictureFormat()) + if (XRenderPictFormat* pictFormat = XRender::findPictureFormat (display)) { int numVisuals = 0; XVisualInfo desiredVisual; @@ -459,7 +437,7 @@ namespace Visuals #endif if (visual == nullptr) { - visual = findVisualWithDepth (32); + visual = findVisualWithDepth (display, 32); if (visual != nullptr) matchedDepth = 32; } @@ -469,14 +447,14 @@ namespace Visuals if (visual == nullptr && desiredDepth >= 24) { - visual = findVisualWithDepth (24); + visual = findVisualWithDepth (display, 24); if (visual != nullptr) matchedDepth = 24; } if (visual == nullptr && desiredDepth >= 16) { - visual = findVisualWithDepth (16); + visual = findVisualWithDepth (display, 16); if (visual != nullptr) matchedDepth = 16; } @@ -485,27 +463,28 @@ namespace Visuals } } -//============================================================================== +//================================= X11 - Bitmap =============================== + class XBitmapImage : public ImagePixelData { public: - XBitmapImage (const Image::PixelFormat format, const int w, const int h, - const bool clearImage, const unsigned int imageDepth_, Visual* visual) + XBitmapImage (::Display* d, Image::PixelFormat format, int w, int h, + bool clearImage, unsigned int imageDepth_, Visual* visual) : ImagePixelData (format, w, h), imageDepth (imageDepth_), - gc (None) + display (d) { jassert (format == Image::RGB || format == Image::ARGB); pixelStride = (format == Image::RGB) ? 3 : 4; lineStride = ((w * pixelStride + 3) & ~3); - ScopedXLock xlock; + ScopedXLock xlock (display); #if JUCE_USE_XSHM usingXShm = false; - if ((imageDepth > 16) && XSHMHelpers::isShmAvailable()) + if ((imageDepth > 16) && XSHMHelpers::isShmAvailable (display)) { zerostruct (segmentInfo); @@ -594,7 +573,7 @@ public: ~XBitmapImage() { - ScopedXLock xlock; + ScopedXLock xlock (display); if (gc != None) XFreeGC (display, gc); @@ -645,7 +624,7 @@ public: void blitToWindow (Window window, int dx, int dy, unsigned int dw, unsigned int dh, int sx, int sy) { - ScopedXLock xlock; + ScopedXLock xlock (display); if (gc == None) { @@ -682,7 +661,7 @@ public: for (int x = sx; x < sx + (int)dw; ++x) { - const PixelRGB* const pixel = (const PixelRGB*) p; + auto* pixel = (const PixelRGB*) p; p += srcData.pixelStride; XPutPixel (xImage, x, y, @@ -708,13 +687,14 @@ public: private: //============================================================================== - XImage* xImage; + XImage* xImage = {}; const unsigned int imageDepth; HeapBlock imageDataAllocated; HeapBlock imageData16Bit; int pixelStride, lineStride; - uint8* imageData; - GC gc; + uint8* imageData = {}; + GC gc = None; + ::Display* display = {}; #if JUCE_USE_XSHM XShmSegmentInfo segmentInfo; @@ -735,6 +715,7 @@ private: }; //============================================================================== + #if JUCE_USE_XRANDR template <> struct ContainerDeletePolicy @@ -755,17 +736,18 @@ struct ContainerDeletePolicy }; #endif -//============================================================================== +//================================ X11 - DisplayGeometry ======================= + class DisplayGeometry { private: //============================================================================== - DisplayGeometry (::Display* dpy, double masterScale) + DisplayGeometry (::Display* display, double masterScale) { jassert (instance == nullptr); instance = this; - queryDisplayInfos (dpy, masterScale); + queryDisplayInfos (display, masterScale); updatePositions(); } @@ -791,16 +773,16 @@ public: Array infos; //============================================================================== - ExtendedInfo& findDisplayForRect (const Rectangle& bounds, bool isScaledBounds) + ExtendedInfo& findDisplayForRect (Rectangle bounds, bool isScaledBounds) { int maxArea = -1; ExtendedInfo* retval = nullptr; for (int i = 0; i < infos.size(); ++i) { - ExtendedInfo& dpy = infos.getReference (i); + auto& dpy = infos.getReference (i); - Rectangle displayBounds = dpy.totalBounds; + auto displayBounds = dpy.totalBounds; if (isScaledBounds) displayBounds = (displayBounds.withZeroOrigin() / dpy.scale) + dpy.topLeftScaled; @@ -825,9 +807,9 @@ public: for (int i = 0; i < infos.size(); ++i) { - ExtendedInfo& dpy = infos.getReference (i); + auto& dpy = infos.getReference (i); - Rectangle displayBounds = dpy.totalBounds; + auto displayBounds = dpy.totalBounds; if (isScaledPoint) displayBounds = (displayBounds.withZeroOrigin() / dpy.scale) + dpy.topLeftScaled; @@ -847,39 +829,38 @@ public: } //============================================================================== - static Rectangle physicalToScaled (const Rectangle& physicalBounds) + static Rectangle physicalToScaled (Rectangle physicalBounds) { // first find with which display physicalBounds has the most overlap - ExtendedInfo& dpy = getInstance().findDisplayForRect (physicalBounds, false); + auto& dpy = getInstance().findDisplayForRect (physicalBounds, false); // convert to local screen bounds - Rectangle retval = physicalBounds - dpy.totalBounds.getTopLeft(); + physicalBounds -= dpy.totalBounds.getTopLeft(); // now we can safely scale the coordinates and convert to global again - return (retval / dpy.scale) + dpy.topLeftScaled; + return (physicalBounds / dpy.scale) + dpy.topLeftScaled; } - static Rectangle scaledToPhysical (const Rectangle& scaledBounds) + static Rectangle scaledToPhysical (Rectangle scaledBounds) { // first find with which display physicalBounds has the most overlap - ExtendedInfo& dpy = getInstance().findDisplayForRect (scaledBounds, true); + auto& dpy = getInstance().findDisplayForRect (scaledBounds, true); // convert to local screen bounds - Rectangle retval = scaledBounds - dpy.topLeftScaled; + scaledBounds -= dpy.topLeftScaled; // now we can safely scale the coordinates and convert to global again - return (retval * dpy.scale) + dpy.totalBounds.getTopLeft(); + return (scaledBounds * dpy.scale) + dpy.totalBounds.getTopLeft(); } //============================================================================== template - static Point physicalToScaled (const Point& physicalPoint) + static Point physicalToScaled (Point physicalPoint) { - ExtendedInfo& dpy = getInstance().findDisplayForPoint (physicalPoint.roundToInt(), false); - Point scaledTopLeft = - Point (dpy.topLeftScaled.getX(), dpy.topLeftScaled.getY()); - Point physicalTopLeft = - Point (dpy.totalBounds.getX(), dpy.totalBounds.getY()); + auto& dpy = getInstance().findDisplayForPoint (physicalPoint.roundToInt(), false); + + Point scaledTopLeft (dpy.topLeftScaled.getX(), dpy.topLeftScaled.getY()); + Point physicalTopLeft (dpy.totalBounds.getX(), dpy.totalBounds.getY()); return ((physicalPoint - physicalTopLeft) / dpy.scale) + scaledTopLeft; } @@ -887,11 +868,10 @@ public: template static Point scaledToPhysical (const Point& scaledPoint) { - ExtendedInfo& dpy = getInstance().findDisplayForPoint (scaledPoint.roundToInt(), true); - Point scaledTopLeft = - Point (dpy.topLeftScaled.getX(), dpy.topLeftScaled.getY()); - Point physicalTopLeft = - Point (dpy.totalBounds.getX(), dpy.totalBounds.getY()); + auto& dpy = getInstance().findDisplayForPoint (scaledPoint.roundToInt(), true); + + Point scaledTopLeft (dpy.topLeftScaled.getX(), dpy.topLeftScaled.getY()); + Point physicalTopLeft (dpy.totalBounds.getX(), dpy.totalBounds.getY()); return ((scaledPoint - scaledTopLeft) * dpy.scale) + physicalTopLeft; } @@ -903,10 +883,10 @@ public: return *instance; } - static DisplayGeometry& getOrCreateInstance (::Display* dpy, double masterScale) + static DisplayGeometry& getOrCreateInstance (::Display* display, double masterScale) { if (instance == nullptr) - new DisplayGeometry (dpy, masterScale); + new DisplayGeometry (display, masterScale); return getInstance(); } @@ -917,14 +897,14 @@ private: //============================================================================== #if JUCE_USE_XINERAMA - static Array XineramaQueryDisplays (::Display* dpy) + static Array XineramaQueryDisplays (::Display* display) { typedef Bool (*tXineramaIsActive) (::Display*); typedef XineramaScreenInfo* (*tXineramaQueryScreens) (::Display*, int*); int major_opcode, first_event, first_error; - if (XQueryExtension (dpy, "XINERAMA", &major_opcode, &first_event, &first_error)) + if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error)) { static void* libXinerama = nullptr; static tXineramaIsActive isActiveFuncPtr = nullptr; @@ -944,10 +924,11 @@ private: } } - if (isActiveFuncPtr != nullptr && xineramaQueryScreens != nullptr && isActiveFuncPtr (dpy) != 0) + if (isActiveFuncPtr != nullptr && xineramaQueryScreens != nullptr && isActiveFuncPtr (display) != 0) { int numScreens; - if (XineramaScreenInfo* xinfo = xineramaQueryScreens (dpy, &numScreens)) + + if (auto* xinfo = xineramaQueryScreens (display, &numScreens)) { Array infos (xinfo, numScreens); XFree (xinfo); @@ -957,7 +938,7 @@ private: } } - return Array(); + return {}; } #endif @@ -971,21 +952,13 @@ private: { private: XRandrWrapper() - : libXrandr (nullptr), - getScreenResourcesPtr (nullptr), - freeScreenResourcesPtr (nullptr), - getOutputInfoPtr (nullptr), - freeOutputInfoPtr (nullptr), - getCrtcInfoPtr (nullptr), - freeCrtcInfoPtr (nullptr), - getOutputPrimaryPtr (nullptr) { if (libXrandr == nullptr) { libXrandr = dlopen ("libXrandr.so", RTLD_GLOBAL | RTLD_NOW); if (libXrandr == nullptr) - libXrandr = dlopen ("libXinerama.so.2", RTLD_GLOBAL | RTLD_NOW); + libXrandr = dlopen ("libXrandr.so.2", RTLD_GLOBAL | RTLD_NOW); if (libXrandr != nullptr) { @@ -1013,34 +986,34 @@ private: } //============================================================================== - XRRScreenResources* getScreenResources (::Display* dpy, ::Window window) + XRRScreenResources* getScreenResources (::Display* display, ::Window window) { if (getScreenResourcesPtr != nullptr) - return getScreenResourcesPtr (dpy, window); + return getScreenResourcesPtr (display, window); return nullptr; } - XRROutputInfo* getOutputInfo (::Display* dpy, XRRScreenResources* resources, RROutput output) + XRROutputInfo* getOutputInfo (::Display* display, XRRScreenResources* resources, RROutput output) { if (getOutputInfoPtr != nullptr) - return getOutputInfoPtr (dpy, resources, output); + return getOutputInfoPtr (display, resources, output); return nullptr; } - XRRCrtcInfo* getCrtcInfo (::Display* dpy, XRRScreenResources* resources, RRCrtc crtc) + XRRCrtcInfo* getCrtcInfo (::Display* display, XRRScreenResources* resources, RRCrtc crtc) { if (getCrtcInfoPtr != nullptr) - return getCrtcInfoPtr (dpy, resources, crtc); + return getCrtcInfoPtr (display, resources, crtc); return nullptr; } - RROutput getOutputPrimary (::Display* dpy, ::Window window) + RROutput getOutputPrimary (::Display* display, ::Window window) { if (getOutputPrimaryPtr != nullptr) - return getOutputPrimaryPtr (dpy, window); + return getOutputPrimaryPtr (display, window); return 0; } @@ -1079,19 +1052,19 @@ private: typedef void (*tXRRFreeCrtcInfo) (XRRCrtcInfo*); typedef RROutput (*tXRRGetOutputPrimary) (::Display*, ::Window); - void* libXrandr; - tXRRGetScreenResources getScreenResourcesPtr; - tXRRFreeScreenResources freeScreenResourcesPtr; - tXRRGetOutputInfo getOutputInfoPtr; - tXRRFreeOutputInfo freeOutputInfoPtr; - tXRRGetCrtcInfo getCrtcInfoPtr; - tXRRFreeCrtcInfo freeCrtcInfoPtr; - tXRRGetOutputPrimary getOutputPrimaryPtr; + void* libXrandr = nullptr; + tXRRGetScreenResources getScreenResourcesPtr = nullptr; + tXRRFreeScreenResources freeScreenResourcesPtr = nullptr; + tXRRGetOutputInfo getOutputInfoPtr = nullptr; + tXRRFreeOutputInfo freeOutputInfoPtr = nullptr; + tXRRGetCrtcInfo getCrtcInfoPtr = nullptr; + tXRRFreeCrtcInfo freeCrtcInfoPtr = nullptr; + tXRRGetOutputPrimary getOutputPrimaryPtr = nullptr; }; #endif - static double getDisplayDPI (int index) + static double getDisplayDPI (::Display* display, int index) { double dpiX = (DisplayWidth (display, index) * 25.4) / DisplayWidthMM (display, index); double dpiY = (DisplayHeight (display, index) * 25.4) / DisplayHeightMM (display, index); @@ -1135,15 +1108,17 @@ private: { // Other gnome based distros now use gsettings for a global scale factor ChildProcess gsettings; - if (File ("/usr/bin/gsettings").existsAsFile() && - gsettings.start ("/usr/bin/gsettings get org.gnome.desktop.interface scaling-factor", ChildProcess::wantStdOut)) + + if (File ("/usr/bin/gsettings").existsAsFile() + && gsettings.start ("/usr/bin/gsettings get org.gnome.desktop.interface scaling-factor", ChildProcess::wantStdOut)) { if (gsettings.waitForProcessToFinish (200)) { - StringArray gsettingsOutput = StringArray::fromTokens (gsettings.readAllProcessOutput(), true); + auto gsettingsOutput = StringArray::fromTokens (gsettings.readAllProcessOutput(), true); + if (gsettingsOutput.size() >= 2 && gsettingsOutput[1].length() > 0) { - double scaleFactor = gsettingsOutput[1].getDoubleValue(); + auto scaleFactor = gsettingsOutput[1].getDoubleValue(); if (scaleFactor > 0.0) return scaleFactor; @@ -1159,26 +1134,26 @@ private: } //============================================================================== - void queryDisplayInfos (::Display* dpy, double masterScale) noexcept + void queryDisplayInfos (::Display* display, double masterScale) noexcept { - ScopedXLock xlock; + ScopedXLock xlock (display); #if JUCE_USE_XRANDR { int major_opcode, first_event, first_error; - if (XQueryExtension (dpy, "RANDR", &major_opcode, &first_event, &first_error)) + if (XQueryExtension (display, "RANDR", &major_opcode, &first_event, &first_error)) { XRandrWrapper& xrandr = XRandrWrapper::getInstance(); ScopedPointer screens; - const int numMonitors = ScreenCount (dpy); - RROutput mainDisplay = xrandr.getOutputPrimary (dpy, RootWindow (dpy, 0)); + const int numMonitors = ScreenCount (display); + RROutput mainDisplay = xrandr.getOutputPrimary (display, RootWindow (display, 0)); for (int i = 0; i < numMonitors; ++i) { - if ((screens = xrandr.getScreenResources (dpy, RootWindow (dpy, i))).get()) + if ((screens = xrandr.getScreenResources (display, RootWindow (display, i))).get()) { for (int j = 0; j < screens->noutput; ++j) { @@ -1192,14 +1167,14 @@ private: ScopedPointer output; - if ((output = xrandr.getOutputInfo (dpy, screens.get(), screens->outputs[j])).get()) + if ((output = xrandr.getOutputInfo (display, screens.get(), screens->outputs[j])).get()) { if (! output->crtc) continue; ScopedPointer crtc; - if ((crtc = xrandr.getCrtcInfo (dpy, screens.get(), output->crtc)).get()) + if ((crtc = xrandr.getCrtcInfo (display, screens.get(), output->crtc)).get()) { ExtendedInfo e; e.totalBounds = Rectangle (crtc->x, crtc->y, @@ -1207,7 +1182,7 @@ private: e.usableBounds = e.totalBounds.withZeroOrigin(); // Support for usable area is not implemented in JUCE yet e.topLeftScaled = e.totalBounds.getTopLeft(); e.isMain = (mainDisplay == screens->outputs[j]) && (i == 0); - e.dpi = getDisplayDPI (0); + e.dpi = getDisplayDPI (display, 0); // The raspberry pi returns a zero sized display, so we need to guard for divide-by-zero if (output->mm_width > 0 && output->mm_height > 0) @@ -1231,7 +1206,7 @@ private: #endif #if JUCE_USE_XINERAMA { - Array screens = XineramaQueryDisplays (dpy); + Array screens = XineramaQueryDisplays (display); int numMonitors = screens.size(); for (int index = 0; index < numMonitors; ++index) @@ -1249,7 +1224,7 @@ private: e.topLeftScaled = e.totalBounds.getTopLeft(); // this will be overwritten by updatePositions later e.isMain = (index == 0); e.scale = masterScale; - e.dpi = getDisplayDPI (0); // (all screens share the same DPI) + e.dpi = getDisplayDPI (display, 0); // (all screens share the same DPI) infos.add (e); } @@ -1260,15 +1235,15 @@ private: if (infos.size() == 0) #endif { - Atom hints = Atoms::getIfExists ("_NET_WORKAREA"); + Atom hints = Atoms::getIfExists (display, "_NET_WORKAREA"); if (hints != None) { - const int numMonitors = ScreenCount (dpy); + const int numMonitors = ScreenCount (display); for (int i = 0; i < numMonitors; ++i) { - GetXProperty prop (RootWindow (dpy, i), hints, 0, 4, false, XA_CARDINAL); + GetXProperty prop (display, RootWindow (display, i), hints, 0, 4, false, XA_CARDINAL); if (prop.success && prop.actualType == XA_CARDINAL && prop.actualFormat == 32 && prop.numItems == 4) { @@ -1281,7 +1256,7 @@ private: e.topLeftScaled = e.totalBounds.getTopLeft(); // this will be overwritten by updatePositions later e.isMain = (infos.size() == 0); e.scale = masterScale; - e.dpi = getDisplayDPI (i); + e.dpi = getDisplayDPI (display, i); infos.add (e); } @@ -1291,13 +1266,13 @@ private: if (infos.size() == 0) { ExtendedInfo e; - e.totalBounds = Rectangle (DisplayWidth (dpy, DefaultScreen (dpy)), - DisplayHeight (dpy, DefaultScreen (dpy))); + e.totalBounds = Rectangle (DisplayWidth (display, DefaultScreen (display)), + DisplayHeight (display, DefaultScreen (display))); e.usableBounds = e.totalBounds; // Support for usable area is not implemented in JUCE yet e.topLeftScaled = e.totalBounds.getTopLeft(); // this will be overwritten by updatePositions later e.isMain = true; e.scale = masterScale; - e.dpi = getDisplayDPI (0); + e.dpi = getDisplayDPI (display, 0); infos.add (e); } @@ -1309,8 +1284,7 @@ private: { bool sortByYCoordinate; - SortByCoordinate (bool byYCoordinate) - : sortByYCoordinate (byYCoordinate) + SortByCoordinate (bool byYCoordinate) : sortByYCoordinate (byYCoordinate) { } @@ -1334,7 +1308,7 @@ private: }; //============================================================================== - void updateScaledDisplayCoordinate(bool updateYCoordinates) + void updateScaledDisplayCoordinate (bool updateYCoordinates) { if (infos.size() < 2) return; @@ -1348,12 +1322,12 @@ private: for (int i = 1; i < copy.size(); ++i) { - ExtendedInfo& current = *copy[i]; + auto& current = *copy[i]; // Is this screen's position aligned to any other previous display? for (int j = i - 1; j >= 0; --j) { - ExtendedInfo& other = *copy[j]; + auto& other = *copy[j]; int prevCoordinate = updateYCoordinates ? other.totalBounds.getBottom() : other.totalBounds.getRight(); int curCoordinate = updateYCoordinates ? current.totalBounds.getY() : current.totalBounds.getX(); if (prevCoordinate == curCoordinate) @@ -1405,12 +1379,13 @@ void ContainerDeletePolicy::destroy (XRRCrtcInfo* ptr) } #endif -//============================================================================== +//=============================== X11 - Pixmap ================================= + namespace PixmapHelpers { - Pixmap createColourPixmapFromImage (Display* display, const Image& image) + Pixmap createColourPixmapFromImage (::Display* display, const Image& image) { - ScopedXLock xlock; + ScopedXLock xlock (display); const unsigned int width = (unsigned int) image.getWidth(); const unsigned int height = (unsigned int) image.getHeight(); @@ -1435,9 +1410,9 @@ namespace PixmapHelpers return pixmap; } - Pixmap createMaskPixmapFromImage (Display* display, const Image& image) + Pixmap createMaskPixmapFromImage (::Display* display, const Image& image) { - ScopedXLock xlock; + ScopedXLock xlock (display); const unsigned int width = (unsigned int) image.getWidth(); const unsigned int height = (unsigned int) image.getHeight(); @@ -1487,17 +1462,16 @@ class LinuxComponentPeer : public ComponentPeer public: LinuxComponentPeer (Component& comp, const int windowStyleFlags, Window parentToAddTo) : ComponentPeer (comp, windowStyleFlags), - windowH (0), parentWindow (0), - fullScreen (false), mapped (false), - visual (nullptr), depth (0), - isAlwaysOnTop (comp.isAlwaysOnTop()), - currentScaleFactor (1.0) + isAlwaysOnTop (comp.isAlwaysOnTop()) { // it's dangerous to create a window on a thread other than the message thread.. jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); - dispatchWindowMessage = windowMessageReceive; - repainter = new LinuxRepaintManager (*this); + display = XWindowSystem::getInstance()->displayRef(); + + atoms = new Atoms (display); + dragState = new DragState (display); + repainter = new LinuxRepaintManager (*this, display); if (isAlwaysOnTop) ++numAlwaysOnTopPeers; @@ -1512,27 +1486,21 @@ public: // it's dangerous to delete a window on a thread other than the message thread.. jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + #if JUCE_X11_SUPPORTS_XEMBED + juce_handleXEmbedEvent (this, nullptr); + #endif + deleteIconPixmaps(); destroyWindow(); windowH = 0; if (isAlwaysOnTop) --numAlwaysOnTopPeers; - } - // (this callback is hooked up in the messaging code) - static void windowMessageReceive (XEvent& event) - { - if (event.xany.window != None) - { - if (LinuxComponentPeer* const peer = getPeerFor (event.xany.window)) - peer->handleWindowMessage (event); - } - else if (event.xany.type == KeymapNotify) - { - const XKeymapEvent& keymapEvent = (const XKeymapEvent&) event.xkeymap; - memcpy (Keys::keyStates, keymapEvent.key_vector, 32); - } + // delete before display + repainter = nullptr; + + display = XWindowSystem::getInstance()->displayUnref(); } //============================================================================== @@ -1547,7 +1515,7 @@ public: if (display != nullptr) { - ScopedXLock xlock; + ScopedXLock xlock (display); if (! XFindContext (display, (XID) windowHandle, windowHandleXContext, &peer)) if (peer != nullptr && ! ComponentPeer::isValidPeer (reinterpret_cast (peer))) @@ -1559,7 +1527,7 @@ public: void setVisible (bool shouldBeVisible) override { - ScopedXLock xlock; + ScopedXLock xlock (display); if (shouldBeVisible) XMapWindow (display, windowH); @@ -1571,7 +1539,7 @@ public: { XTextProperty nameProperty; char* strings[] = { const_cast (title.toRawUTF8()) }; - ScopedXLock xlock; + ScopedXLock xlock (display); if (XStringListToTextProperty (strings, 1, &nameProperty)) { @@ -1588,7 +1556,7 @@ public: { // When transitioning back from fullscreen, we might need to remove // the FULLSCREEN window property - Atom fs = Atoms::getIfExists ("_NET_WM_STATE_FULLSCREEN"); + Atom fs = Atoms::getIfExists (display, "_NET_WM_STATE_FULLSCREEN"); if (fs != None) { @@ -1599,13 +1567,13 @@ public: clientMsg.window = windowH; clientMsg.type = ClientMessage; clientMsg.format = 32; - clientMsg.message_type = atoms.windowState; + clientMsg.message_type = atoms->windowState; clientMsg.data.l[0] = 0; // Remove clientMsg.data.l[1] = (long) fs; clientMsg.data.l[2] = 0; clientMsg.data.l[3] = 1; // Normal Source - ScopedXLock xlock; + ScopedXLock xlock (display); XSendEvent (display, root, false, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*) &clientMsg); @@ -1621,11 +1589,10 @@ public: currentScaleFactor = DisplayGeometry::getInstance().findDisplayForRect (bounds, true).scale; - Rectangle physicalBounds = - DisplayGeometry::scaledToPhysical (bounds); + auto physicalBounds = DisplayGeometry::scaledToPhysical (bounds); WeakReference deletionChecker (&component); - ScopedXLock xlock; + ScopedXLock xlock (display); XSizeHints* const hints = XAllocSizeHints(); hints->flags = USSize | USPosition; @@ -1691,10 +1658,10 @@ public: clientMsg.window = windowH; clientMsg.type = ClientMessage; clientMsg.format = 32; - clientMsg.message_type = atoms.changeState; + clientMsg.message_type = atoms->changeState; clientMsg.data.l[0] = IconicState; - ScopedXLock xlock; + ScopedXLock xlock (display); XSendEvent (display, root, false, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*) &clientMsg); } else @@ -1705,11 +1672,11 @@ public: bool isMinimised() const override { - ScopedXLock xlock; - GetXProperty prop (windowH, atoms.state, 0, 64, false, atoms.state); + ScopedXLock xlock (display); + GetXProperty prop (display, windowH, atoms->state, 0, 64, false, atoms->state); return prop.success - && prop.actualType == atoms.state + && prop.actualType == atoms->state && prop.actualFormat == 32 && prop.numItems > 0 && ((unsigned long*) prop.data)[0] == IconicState; @@ -1717,7 +1684,7 @@ public: void setFullScreen (const bool shouldBeFullScreen) override { - Rectangle r (lastNonFullscreenBounds); // (get a copy of this before de-minimising) + auto r = lastNonFullscreenBounds; // (get a copy of this before de-minimising) setMinimised (false); @@ -1744,7 +1711,7 @@ public: uint32 windowListSize = 0; Window parent, root; - ScopedXLock xlock; + ScopedXLock xlock (display); if (XQueryTree (display, windowH, &root, &parent, &windowList, &windowListSize) != 0) { if (windowList != nullptr) @@ -1756,13 +1723,40 @@ public: return false; } + bool isParentWindowOf (Window possibleChild) const + { + if (windowH != 0 && possibleChild != 0) + { + if (possibleChild == windowH) + return true; + + Window* windowList = nullptr; + uint32 windowListSize = 0; + Window parent, root; + + ScopedXLock xlock (display); + if (XQueryTree (display, possibleChild, &root, &parent, &windowList, &windowListSize) != 0) + { + if (windowList != nullptr) + XFree (windowList); + + if (parent == root) + return false; + + return isParentWindowOf (parent); + } + } + + return false; + } + bool isFrontWindow() const { Window* windowList = nullptr; uint32 windowListSize = 0; bool result = false; - ScopedXLock xlock; + ScopedXLock xlock (display); Window parent, root = RootWindow (display, DefaultScreen (display)); if (XQueryTree (display, root, &root, &parent, &windowList, &windowListSize) != 0) @@ -1790,12 +1784,15 @@ public: for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) { - Component* const c = Desktop::getInstance().getComponent (i); + auto* c = Desktop::getInstance().getComponent (i); if (c == &component) break; - if (ComponentPeer* peer = c->getPeer()) + if (! c->isVisible()) + continue; + + if (auto* peer = c->getPeer()) if (peer->contains (localPos + bounds.getPosition() - peer->getBounds().getPosition(), true)) return false; } @@ -1807,7 +1804,7 @@ public: int wx, wy; unsigned int ww, wh, bw, bitDepth; - ScopedXLock xlock; + ScopedXLock xlock (display); localPos *= currentScaleFactor; @@ -1818,7 +1815,7 @@ public: BorderSize getFrameSize() const override { - return BorderSize(); + return {}; } bool setAlwaysOnTop (bool /* alwaysOnTop */) override @@ -1835,12 +1832,12 @@ public: } { - ScopedXLock xlock; + ScopedXLock xlock (display); XEvent ev; ev.xclient.type = ClientMessage; ev.xclient.serial = 0; ev.xclient.send_event = True; - ev.xclient.message_type = atoms.activeWin; + ev.xclient.message_type = atoms->activeWin; ev.xclient.window = windowH; ev.xclient.format = 32; ev.xclient.data.l[0] = 2; @@ -1860,7 +1857,7 @@ public: void toBehind (ComponentPeer* other) override { - if (LinuxComponentPeer* const otherPeer = dynamic_cast (other)) + if (auto* otherPeer = dynamic_cast (other)) { if (otherPeer->styleFlags & windowIsTemporary) return; @@ -1869,7 +1866,7 @@ public: Window newStack[] = { otherPeer->windowH, windowH }; - ScopedXLock xlock; + ScopedXLock xlock (display); XRestackWindows (display, newStack, 2); } else @@ -1880,23 +1877,33 @@ public: { int revert = 0; Window focusedWindow = 0; - ScopedXLock xlock; + ScopedXLock xlock (display); XGetInputFocus (display, &focusedWindow, &revert); - return focusedWindow == windowH; + return isParentWindowOf (focusedWindow); + } + + Window getFocusWindow() + { + #if JUCE_X11_SUPPORTS_XEMBED + if (Window w = (Window) juce_getCurrentFocusWindow (this)) + return w; + #endif + + return windowH; } void grabFocus() override { XWindowAttributes atts; - ScopedXLock xlock; + ScopedXLock xlock (display); if (windowH != 0 && XGetWindowAttributes (display, windowH, &atts) && atts.map_state == IsViewable && ! isFocused()) { - XSetInputFocus (display, windowH, RevertToParent, (::Time) getUserTime()); + XSetInputFocus (display, getFocusWindow(), RevertToParent, (::Time) getUserTime()); isActiveApplication = true; } } @@ -1926,8 +1933,8 @@ public: for (int x = 0; x < newIcon.getWidth(); ++x) data[index++] = (unsigned long) newIcon.getPixelAt (x, y).getARGB(); - ScopedXLock xlock; - xchangeProperty (windowH, Atoms::getCreating ("_NET_WM_ICON"), XA_CARDINAL, 32, data.getData(), dataSize); + ScopedXLock xlock (display); + xchangeProperty (windowH, Atoms::getCreating (display, "_NET_WM_ICON"), XA_CARDINAL, 32, data.getData(), dataSize); deleteIconPixmaps(); @@ -1948,10 +1955,9 @@ public: void deleteIconPixmaps() { - ScopedXLock xlock; - XWMHints* wmHints = XGetWMHints (display, windowH); + ScopedXLock xlock (display); - if (wmHints != nullptr) + if (auto* wmHints = XGetWMHints (display, windowH)) { if ((wmHints->flags & IconPixmapHint) != 0) { @@ -2011,9 +2017,9 @@ public: default: #if JUCE_USE_XSHM - if (XSHMHelpers::isShmAvailable()) + if (XSHMHelpers::isShmAvailable (display)) { - ScopedXLock xlock; + ScopedXLock xlock (display); if (event.xany.type == XShmGetEventBase (display)) repainter->notifyPaintCompleted(); } @@ -2024,7 +2030,7 @@ public: void handleKeyPressEvent (XKeyEvent& keyEvent) { - const ModifierKeys oldMods (currentModifiers); + auto oldMods = currentModifiers; char utf8 [64] = { 0 }; juce_wchar unicodeChar = 0; @@ -2033,7 +2039,7 @@ public: KeySym sym; { - ScopedXLock xlock; + ScopedXLock xlock (display); updateKeyStates ((int) keyEvent.keycode, true); String oldLocale (::setlocale (LC_ALL, 0)); @@ -2165,11 +2171,11 @@ public: KeySym sym; { - ScopedXLock xlock; + ScopedXLock xlock (display); sym = XkbKeycodeToKeysym (display, (::KeyCode) keyEvent.keycode, 0, 0); } - const ModifierKeys oldMods (currentModifiers); + auto oldMods = currentModifiers; const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false); if (oldMods != currentModifiers) @@ -2195,29 +2201,35 @@ public: wheel.isSmooth = false; wheel.isInertial = false; - handleMouseWheel (0, getMousePos (buttonPressEvent), getEventTime (buttonPressEvent), wheel); + handleMouseWheel (MouseInputSource::InputSourceType::mouse, getMousePos (buttonPressEvent), + getEventTime (buttonPressEvent), wheel); } void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent, int buttonModifierFlag) { currentModifiers = currentModifiers.withFlags (buttonModifierFlag); toFront (true); - handleMouseEvent (0, getMousePos (buttonPressEvent), currentModifiers, - MouseInputSource::invalidPressure, getEventTime (buttonPressEvent)); + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonPressEvent), currentModifiers, + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonPressEvent), {}); } void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent) { updateKeyModifiers ((int) buttonPressEvent.state); - switch (pointerMap [buttonPressEvent.button - Button1]) + auto mapIndex = (uint32) (buttonPressEvent.button - Button1); + + if (mapIndex < (uint32) numElementsInArray (pointerMap)) { - case Keys::WheelUp: handleWheelEvent (buttonPressEvent, 50.0f / 256.0f); break; - case Keys::WheelDown: handleWheelEvent (buttonPressEvent, -50.0f / 256.0f); break; - case Keys::LeftButton: handleButtonPressEvent (buttonPressEvent, ModifierKeys::leftButtonModifier); break; - case Keys::RightButton: handleButtonPressEvent (buttonPressEvent, ModifierKeys::rightButtonModifier); break; - case Keys::MiddleButton: handleButtonPressEvent (buttonPressEvent, ModifierKeys::middleButtonModifier); break; - default: break; + switch (pointerMap[mapIndex]) + { + case Keys::WheelUp: handleWheelEvent (buttonPressEvent, 50.0f / 256.0f); break; + case Keys::WheelDown: handleWheelEvent (buttonPressEvent, -50.0f / 256.0f); break; + case Keys::LeftButton: handleButtonPressEvent (buttonPressEvent, ModifierKeys::leftButtonModifier); break; + case Keys::RightButton: handleButtonPressEvent (buttonPressEvent, ModifierKeys::rightButtonModifier); break; + case Keys::MiddleButton: handleButtonPressEvent (buttonPressEvent, ModifierKeys::middleButtonModifier); break; + default: break; + } } clearLastMousePos(); @@ -2230,19 +2242,24 @@ public: if (parentWindow != 0) updateWindowBounds(); - switch (pointerMap [buttonRelEvent.button - Button1]) + auto mapIndex = (uint32) (buttonRelEvent.button - Button1); + + if (mapIndex < (uint32) numElementsInArray (pointerMap)) { - case Keys::LeftButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::leftButtonModifier); break; - case Keys::RightButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::rightButtonModifier); break; - case Keys::MiddleButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::middleButtonModifier); break; - default: break; + switch (pointerMap[mapIndex]) + { + case Keys::LeftButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::leftButtonModifier); break; + case Keys::RightButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::rightButtonModifier); break; + case Keys::MiddleButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::middleButtonModifier); break; + default: break; + } } - if (dragState.dragging) + if (dragState->dragging) handleExternalDragButtonReleaseEvent(); - handleMouseEvent (0, getMousePos (buttonRelEvent), currentModifiers, - MouseInputSource::invalidPressure, getEventTime (buttonRelEvent)); + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonRelEvent), currentModifiers, + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonRelEvent)); clearLastMousePos(); } @@ -2253,11 +2270,11 @@ public: lastMousePos = Point (movedEvent.x_root, movedEvent.y_root); - if (dragState.dragging) + if (dragState->dragging) handleExternalDragMotionNotify(); - handleMouseEvent (0, getMousePos (movedEvent), currentModifiers, - MouseInputSource::invalidPressure, getEventTime (movedEvent)); + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (movedEvent), currentModifiers, + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (movedEvent)); } void handleEnterNotifyEvent (const XEnterWindowEvent& enterEvent) @@ -2270,8 +2287,8 @@ public: if (! currentModifiers.isAnyMouseButtonDown()) { updateKeyModifiers ((int) enterEvent.state); - handleMouseEvent (0, getMousePos (enterEvent), currentModifiers, - MouseInputSource::invalidPressure, getEventTime (enterEvent)); + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (enterEvent), currentModifiers, + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (enterEvent)); } } @@ -2284,30 +2301,38 @@ public: || leaveEvent.mode == NotifyUngrab) { updateKeyModifiers ((int) leaveEvent.state); - handleMouseEvent (0, getMousePos (leaveEvent), currentModifiers, - MouseInputSource::invalidPressure, getEventTime (leaveEvent)); + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (leaveEvent), currentModifiers, + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (leaveEvent)); } } void handleFocusInEvent() { isActiveApplication = true; - if (isFocused()) + + if (isFocused() && ! focused) + { + focused = true; handleFocusGain(); + } } void handleFocusOutEvent() { - isActiveApplication = false; - if (! isFocused()) + if (! isFocused() && focused) + { + focused = false; + isActiveApplication = false; + handleFocusLoss(); + } } void handleExposeEvent (XExposeEvent& exposeEvent) { // Batch together all pending expose events XEvent nextEvent; - ScopedXLock xlock; + ScopedXLock xlock (display); // if we have opengl contexts then just repaint them all // regardless if this is really necessary @@ -2349,16 +2374,12 @@ public: if ((styleFlags & windowHasTitleBar) != 0 && component.isCurrentlyBlockedByAnotherModalComponent()) { - if (Component* const currentModalComp = Component::getCurrentlyModalComponent()) + if (auto* currentModalComp = Component::getCurrentlyModalComponent()) currentModalComp->inputAttemptWhenModal(); } - if (confEvent.window == windowH - && confEvent.above != 0 - && isFrontWindow()) - { + if (confEvent.window == windowH && confEvent.above != 0 && isFrontWindow()) handleBroughtToFront(); - } } void handleReparentNotifyEvent() @@ -2369,7 +2390,7 @@ public: unsigned int numChildren; { - ScopedXLock xlock; + ScopedXLock xlock (display); XQueryTree (display, windowH, &wRoot, &parentWindow, &wChild, &numChildren); } @@ -2391,7 +2412,7 @@ public: if (mappingEvent.request != MappingPointer) { // Deal with modifier/keyboard mapping - ScopedXLock xlock; + ScopedXLock xlock (display); XRefreshKeyboardMapping (&mappingEvent); updateModifierMappings(); } @@ -2399,11 +2420,11 @@ public: void handleClientMessageEvent (XClientMessageEvent& clientMsg, XEvent& event) { - if (clientMsg.message_type == atoms.protocols && clientMsg.format == 32) + if (clientMsg.message_type == atoms->protocols && clientMsg.format == 32) { const Atom atom = (Atom) clientMsg.data.l[0]; - if (atom == atoms.protocolList [Atoms::PING]) + if (atom == atoms->protocolList [Atoms::PING]) { Window root = RootWindow (display, DefaultScreen (display)); @@ -2412,48 +2433,52 @@ public: XSendEvent (display, root, False, NoEventMask, &event); XFlush (display); } - else if (atom == atoms.protocolList [Atoms::TAKE_FOCUS]) + else if (atom == atoms->protocolList [Atoms::TAKE_FOCUS]) { if ((getStyleFlags() & juce::ComponentPeer::windowIgnoresKeyPresses) == 0) { XWindowAttributes atts; - ScopedXLock xlock; + ScopedXLock xlock (display); if (clientMsg.window != 0 && XGetWindowAttributes (display, clientMsg.window, &atts)) { if (atts.map_state == IsViewable) - XSetInputFocus (display, clientMsg.window, RevertToParent, (::Time) clientMsg.data.l[1]); + XSetInputFocus (display, + (clientMsg.window == windowH ? getFocusWindow () + : clientMsg.window), + RevertToParent, + (::Time) clientMsg.data.l[1]); } } } - else if (atom == atoms.protocolList [Atoms::DELETE_WINDOW]) + else if (atom == atoms->protocolList [Atoms::DELETE_WINDOW]) { handleUserClosingWindow(); } } - else if (clientMsg.message_type == atoms.XdndEnter) + else if (clientMsg.message_type == atoms->XdndEnter) { handleDragAndDropEnter (clientMsg); } - else if (clientMsg.message_type == atoms.XdndLeave) + else if (clientMsg.message_type == atoms->XdndLeave) { handleDragExit (dragInfo); resetDragAndDrop(); } - else if (clientMsg.message_type == atoms.XdndPosition) + else if (clientMsg.message_type == atoms->XdndPosition) { handleDragAndDropPosition (clientMsg); } - else if (clientMsg.message_type == atoms.XdndDrop) + else if (clientMsg.message_type == atoms->XdndDrop) { handleDragAndDropDrop (clientMsg); } - else if (clientMsg.message_type == atoms.XdndStatus) + else if (clientMsg.message_type == atoms->XdndStatus) { handleExternalDragAndDropStatus (clientMsg); } - else if (clientMsg.message_type == atoms.XdndFinished) + else if (clientMsg.message_type == atoms->XdndFinished) { externalResetDragAndDrop(); } @@ -2461,7 +2486,7 @@ public: bool externalDragTextInit (const String& text) { - if (dragState.dragging) + if (dragState->dragging) return false; return externalDragInit (true, text); @@ -2469,15 +2494,13 @@ public: bool externalDragFileInit (const StringArray& files, bool /*canMoveFiles*/) { - if (dragState.dragging) + if (dragState->dragging) return false; StringArray uriList; - for (int i = 0; i < files.size(); ++i) + for (auto& f : files) { - const String& f = files[i]; - if (f.matchesWildcard ("?*://*", false)) uriList.add (f); else @@ -2490,7 +2513,7 @@ public: //============================================================================== void showMouseCursor (Cursor cursor) noexcept { - ScopedXLock xlock; + ScopedXLock xlock (display); XDefineCursor (display, windowH, cursor); } @@ -2516,9 +2539,52 @@ public: void repaintOpenGLContexts() { for (int i = 0; i < glRepaintListeners.size(); ++i) - { - if (Component* c = glRepaintListeners [i]) + if (auto* c = glRepaintListeners [i]) c->handleCommandMessage (0); + } + + //============================================================================== + unsigned long createKeyProxy() + { + jassert (keyProxy == 0 && windowH != 0); + + if (keyProxy == 0 && windowH != 0) + { + XSetWindowAttributes swa; + swa.event_mask = KeyPressMask | KeyReleaseMask | FocusChangeMask; + + keyProxy = XCreateWindow (display, windowH, + -1, -1, 1, 1, 0, 0, + InputOnly, CopyFromParent, + CWEventMask, + &swa); + + XMapWindow (display, keyProxy); + XSaveContext (display, (XID) keyProxy, windowHandleXContext, (XPointer) this); + } + + return keyProxy; + } + + void deleteKeyProxy() + { + jassert (keyProxy != 0); + + if (keyProxy != 0) + { + XPointer handlePointer; + + if (! XFindContext (display, (XID) keyProxy, windowHandleXContext, &handlePointer)) + XDeleteContext (display, (XID) keyProxy, windowHandleXContext); + + XDestroyWindow (display, keyProxy); + XSync (display, false); + + XEvent event; + while (XCheckWindowEvent (display, keyProxy, getAllEventsMask(), &event) == True) + {} + + keyProxy = 0; } } @@ -2533,17 +2599,15 @@ private: class LinuxRepaintManager : public Timer { public: - LinuxRepaintManager (LinuxComponentPeer& p) - : peer (p), lastTimeImageUsed (0) + LinuxRepaintManager (LinuxComponentPeer& p, ::Display* d) + : peer (p), display (d) { #if JUCE_USE_XSHM - shmPaintsPending = 0; - - useARGBImagesForRendering = XSHMHelpers::isShmAvailable(); + useARGBImagesForRendering = XSHMHelpers::isShmAvailable (display); if (useARGBImagesForRendering) { - ScopedXLock xlock; + ScopedXLock xlock (display); XShmSegmentInfo segmentinfo; XImage* const testImage @@ -2575,7 +2639,7 @@ private: } } - void repaint (const Rectangle& area) + void repaint (Rectangle area) { if (! isTimerRunning()) startTimer (repaintTimerPeriod); @@ -2603,10 +2667,10 @@ private: || image.getHeight() < totalArea.getHeight()) { #if JUCE_USE_XSHM - image = Image (new XBitmapImage (useARGBImagesForRendering ? Image::ARGB - : Image::RGB, + image = Image (new XBitmapImage (display, useARGBImagesForRendering ? Image::ARGB + : Image::RGB, #else - image = Image (new XBitmapImage (Image::RGB, + image = Image (new XBitmapImage (display, Image::RGB, #endif (totalArea.getWidth() + 31) & ~31, (totalArea.getHeight() + 31) & ~31, @@ -2619,8 +2683,8 @@ private: adjustedList.offsetAll (-totalArea.getX(), -totalArea.getY()); if (peer.depth == 32) - for (const Rectangle* i = originalRepaintRegion.begin(), * const e = originalRepaintRegion.end(); i != e; ++i) - image.clear (*i - totalArea.getPosition()); + for (auto& i : originalRepaintRegion) + image.clear (i - totalArea.getPosition()); { ScopedPointer context (peer.getComponent().getLookAndFeel() @@ -2629,9 +2693,10 @@ private: peer.handlePaint (*context); } - for (const Rectangle* i = originalRepaintRegion.begin(), * const e = originalRepaintRegion.end(); i != e; ++i) + for (auto& i : originalRepaintRegion) { - XBitmapImage* xbitmap = static_cast (image.getPixelData()); + auto* xbitmap = static_cast (image.getPixelData()); + #if JUCE_USE_XSHM if (xbitmap->isUsingXShm()) ++shmPaintsPending; @@ -2639,10 +2704,10 @@ private: xbitmap->blitToWindow (peer.windowH, - i->getX(), i->getY(), - (unsigned int) i->getWidth(), - (unsigned int) i->getHeight(), - i->getX() - totalArea.getX(), i->getY() - totalArea.getY()); + i.getX(), i.getY(), + (unsigned int) i.getWidth(), + (unsigned int) i.getHeight(), + i.getX() - totalArea.getX(), i.getY() - totalArea.getY()); } } @@ -2659,31 +2724,33 @@ private: LinuxComponentPeer& peer; Image image; - uint32 lastTimeImageUsed; + uint32 lastTimeImageUsed = 0; RectangleList regionsNeedingRepaint; + ::Display* display; #if JUCE_USE_XSHM bool useARGBImagesForRendering; - int shmPaintsPending; + int shmPaintsPending = 0; #endif JUCE_DECLARE_NON_COPYABLE (LinuxRepaintManager) }; - const Atoms atoms; + ScopedPointer atoms; ScopedPointer repainter; friend class LinuxRepaintManager; - Window windowH, parentWindow; + Window windowH = {}, parentWindow = {}, keyProxy = {}; Rectangle bounds; Image taskbarImage; - bool fullScreen, mapped; - Visual* visual; - int depth; + bool fullScreen = false, mapped = false, focused = false; + Visual* visual = {}; + int depth = 0; BorderSize windowBorder; bool isAlwaysOnTop; - double currentScaleFactor; + double currentScaleFactor = 1.0; Array glRepaintListeners; enum { KeyPressEventType = 2 }; + static ::Display* display; struct MotifWmHints { @@ -2765,7 +2832,7 @@ private: // modifier constants: check what they're mapped to static void updateModifierMappings() noexcept { - ScopedXLock xlock; + ScopedXLock xlock (display); const int altLeftCode = XKeysymToKeycode (display, XK_Alt_L); const int numLockCode = XKeysymToKeycode (display, XK_Num_Lock); @@ -2774,18 +2841,12 @@ private: if (XModifierKeymap* const mapping = XGetModifierMapping (display)) { - const int numMods = 8; - const int maxKeysPerMod = mapping->max_keypermod; - - for (int i = 0; i < numMods; i++) + for (int i = 0; i < 8; i++) { - for (int j = 0; j < maxKeysPerMod; ++j) - { - const int index = (i * maxKeysPerMod) + j; - - if (mapping->modifiermap[index] == altLeftCode) Keys::AltMask = 1 << i; - else if (mapping->modifiermap[index] == numLockCode) Keys::NumLockMask = 1 << i; - } + if (mapping->modifiermap [i << 1] == altLeftCode) + Keys::AltMask = 1 << i; + else if (mapping->modifiermap [i << 1] == numLockCode) + Keys::NumLockMask = 1 << i; } XFreeModifiermap (mapping); @@ -2800,7 +2861,7 @@ private: void removeWindowDecorations (Window wndH) { - Atom hints = Atoms::getIfExists ("_MOTIF_WM_HINTS"); + Atom hints = Atoms::getIfExists (display, "_MOTIF_WM_HINTS"); if (hints != None) { @@ -2810,43 +2871,43 @@ private: motifHints.flags = 2; /* MWM_HINTS_DECORATIONS */ motifHints.decorations = 0; - ScopedXLock xlock; + ScopedXLock xlock (display); xchangeProperty (wndH, hints, hints, 32, &motifHints, 4); } - hints = Atoms::getIfExists ("_WIN_HINTS"); + hints = Atoms::getIfExists (display, "_WIN_HINTS"); if (hints != None) { long gnomeHints = 0; - ScopedXLock xlock; + ScopedXLock xlock (display); xchangeProperty (wndH, hints, hints, 32, &gnomeHints, 1); } - hints = Atoms::getIfExists ("KWM_WIN_DECORATION"); + hints = Atoms::getIfExists (display, "KWM_WIN_DECORATION"); if (hints != None) { long kwmHints = 2; /*KDE_tinyDecoration*/ - ScopedXLock xlock; + ScopedXLock xlock (display); xchangeProperty (wndH, hints, hints, 32, &kwmHints, 1); } - hints = Atoms::getIfExists ("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE"); + hints = Atoms::getIfExists (display, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE"); if (hints != None) { - ScopedXLock xlock; - xchangeProperty (wndH, atoms.windowType, XA_ATOM, 32, &hints, 1); + ScopedXLock xlock (display); + xchangeProperty (wndH, atoms->windowType, XA_ATOM, 32, &hints, 1); } } void addWindowButtons (Window wndH) { - ScopedXLock xlock; - Atom hints = Atoms::getIfExists ("_MOTIF_WM_HINTS"); + ScopedXLock xlock (display); + Atom hints = Atoms::getIfExists (display, "_MOTIF_WM_HINTS"); if (hints != None) { @@ -2882,7 +2943,7 @@ private: xchangeProperty (wndH, hints, hints, 32, &motifHints, 5); } - hints = Atoms::getIfExists ("_NET_WM_ALLOWED_ACTIONS"); + hints = Atoms::getIfExists (display, "_NET_WM_ALLOWED_ACTIONS"); if (hints != None) { @@ -2890,16 +2951,16 @@ private: int num = 0; if ((styleFlags & windowIsResizable) != 0) - netHints [num++] = Atoms::getIfExists ("_NET_WM_ACTION_RESIZE"); + netHints [num++] = Atoms::getIfExists (display, "_NET_WM_ACTION_RESIZE"); if ((styleFlags & windowHasMaximiseButton) != 0) - netHints [num++] = Atoms::getIfExists ("_NET_WM_ACTION_FULLSCREEN"); + netHints [num++] = Atoms::getIfExists (display, "_NET_WM_ACTION_FULLSCREEN"); if ((styleFlags & windowHasMinimiseButton) != 0) - netHints [num++] = Atoms::getIfExists ("_NET_WM_ACTION_MINIMIZE"); + netHints [num++] = Atoms::getIfExists (display, "_NET_WM_ACTION_MINIMIZE"); if ((styleFlags & windowHasCloseButton) != 0) - netHints [num++] = Atoms::getIfExists ("_NET_WM_ACTION_CLOSE"); + netHints [num++] = Atoms::getIfExists (display, "_NET_WM_ACTION_CLOSE"); xchangeProperty (wndH, hints, XA_ATOM, 32, &netHints, num); } @@ -2910,29 +2971,29 @@ private: Atom netHints [2]; if (styleFlags & windowIsTemporary) - netHints [0] = Atoms::getIfExists ("_NET_WM_WINDOW_TYPE_TOOLTIP"); + netHints [0] = Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"); else if ((styleFlags & windowHasDropShadow) == 0 && Desktop::canUseSemiTransparentWindows()) - netHints [0] = Atoms::getIfExists ("_NET_WM_WINDOW_TYPE_COMBO"); + netHints [0] = Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_COMBO"); else - netHints [0] = Atoms::getIfExists ("_NET_WM_WINDOW_TYPE_NORMAL"); + netHints [0] = Atoms::getIfExists (display, "_NET_WM_WINDOW_TYPE_NORMAL"); - xchangeProperty (windowH, atoms.windowType, XA_ATOM, 32, &netHints, 1); + xchangeProperty (windowH, atoms->windowType, XA_ATOM, 32, &netHints, 1); int numHints = 0; if ((styleFlags & windowAppearsOnTaskbar) == 0) - netHints [numHints++] = Atoms::getIfExists ("_NET_WM_STATE_SKIP_TASKBAR"); + netHints [numHints++] = Atoms::getIfExists (display, "_NET_WM_STATE_SKIP_TASKBAR"); if (component.isAlwaysOnTop()) - netHints [numHints++] = Atoms::getIfExists ("_NET_WM_STATE_ABOVE"); + netHints [numHints++] = Atoms::getIfExists (display, "_NET_WM_STATE_ABOVE"); if (numHints > 0) - xchangeProperty (windowH, atoms.windowState, XA_ATOM, 32, &netHints, numHints); + xchangeProperty (windowH, atoms->windowState, XA_ATOM, 32, &netHints, numHints); } void createWindow (Window parentToAddTo) { - ScopedXLock xlock; + ScopedXLock xlock (display); resetDragAndDrop(); // Get defaults for various properties @@ -2942,7 +3003,7 @@ private: parentWindow = parentToAddTo; // Try to obtain a 32-bit visual or fallback to 24 or 16 - visual = Visuals::findVisualFormat ((styleFlags & windowIsSemiTransparent) ? 32 : 24, depth); + visual = Visuals::findVisualFormat (display, (styleFlags & windowIsSemiTransparent) ? 32 : 24, depth); if (visual == nullptr) { @@ -2968,11 +3029,6 @@ private: CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask | CWOverrideRedirect, &swa); - unsigned int buttonMask = EnterWindowMask | LeaveWindowMask | PointerMotionMask; - - if ((styleFlags & windowIgnoresMouseClicks) == 0) - buttonMask |= ButtonPressMask | ButtonReleaseMask; - // Set the window context to identify the window handle object if (XSaveContext (display, (XID) windowH, windowHandleXContext, (XPointer) this)) { @@ -3005,16 +3061,16 @@ private: // Associate the PID, allowing to be shut down when something goes wrong unsigned long pid = (unsigned long) getpid(); - xchangeProperty (windowH, atoms.pid, XA_CARDINAL, 32, &pid, 1); + xchangeProperty (windowH, atoms->pid, XA_CARDINAL, 32, &pid, 1); // Set window manager protocols - xchangeProperty (windowH, atoms.protocols, XA_ATOM, 32, atoms.protocolList, 2); + xchangeProperty (windowH, atoms->protocols, XA_ATOM, 32, atoms->protocolList, 2); // Set drag and drop flags - xchangeProperty (windowH, atoms.XdndTypeList, XA_ATOM, 32, atoms.allowedMimeTypes, numElementsInArray (atoms.allowedMimeTypes)); - xchangeProperty (windowH, atoms.XdndActionList, XA_ATOM, 32, atoms.allowedActions, numElementsInArray (atoms.allowedActions)); - xchangeProperty (windowH, atoms.XdndActionDescription, XA_STRING, 8, "", 0); - xchangeProperty (windowH, atoms.XdndAware, XA_ATOM, 32, &Atoms::DndVersion, 1); + xchangeProperty (windowH, atoms->XdndTypeList, XA_ATOM, 32, atoms->allowedMimeTypes, numElementsInArray (atoms->allowedMimeTypes)); + xchangeProperty (windowH, atoms->XdndActionList, XA_ATOM, 32, atoms->allowedActions, numElementsInArray (atoms->allowedActions)); + xchangeProperty (windowH, atoms->XdndActionDescription, XA_STRING, 8, "", 0); + xchangeProperty (windowH, atoms->XdndAware, XA_ATOM, 32, &atoms->DndVersion, 1); initialisePointerMap(); updateModifierMappings(); @@ -3022,9 +3078,13 @@ private: void destroyWindow() { - ScopedXLock xlock; + ScopedXLock xlock (display); XPointer handlePointer; + + if (keyProxy != 0) + deleteKeyProxy(); + if (! XFindContext (display, (XID) windowH, windowHandleXContext, &handlePointer)) XDeleteContext (display, (XID) windowH, windowHandleXContext); @@ -3044,7 +3104,7 @@ private: return NoEventMask | KeyPressMask | KeyReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask | ExposureMask | StructureNotifyMask | FocusChangeMask - | ((styleFlags & windowIgnoresMouseClicks) != 0 ? 0 : (ButtonPressMask | ButtonReleaseMask)); + | ((styleFlags & windowIgnoresMouseClicks) != 0 ? 0 : (ButtonPressMask | ButtonReleaseMask)); } template @@ -3066,7 +3126,7 @@ private: long getUserTime() const { - GetXProperty prop (windowH, atoms.userTime, 0, 65536, false, XA_CARDINAL); + GetXProperty prop (display, windowH, atoms->userTime, 0, 65536, false, XA_CARDINAL); return prop.success ? *(long*) prop.data : 0; } @@ -3078,12 +3138,12 @@ private: } else if (windowBorder.getTopAndBottom() == 0 && windowBorder.getLeftAndRight() == 0) { - ScopedXLock xlock; - Atom hints = Atoms::getIfExists ("_NET_FRAME_EXTENTS"); + ScopedXLock xlock (display); + Atom hints = Atoms::getIfExists (display, "_NET_FRAME_EXTENTS"); if (hints != None) { - GetXProperty prop (windowH, hints, 0, 4, false, XA_CARDINAL); + GetXProperty prop (display, windowH, hints, 0, 4, false, XA_CARDINAL); if (prop.success && prop.actualFormat == 32) { @@ -3105,7 +3165,7 @@ private: int wx = 0, wy = 0; unsigned int ww = 0, wh = 0, bw, bitDepth; - ScopedXLock xlock; + ScopedXLock xlock (display); if (XGetGeometry (display, (::Drawable) windowH, &root, &wx, &wy, &ww, &wh, &bw, &bitDepth)) if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child)) @@ -3123,22 +3183,20 @@ private: //============================================================================== struct DragState { - DragState() - : isText (false), dragging (false), expectingStatus (false), - canDrop (false), targetWindow (None), xdndVersion (-1) + DragState (::Display* d) { if (isText) - allowedTypes.add (Atoms::getCreating ("text/plain")); + allowedTypes.add (Atoms::getCreating (d, "text/plain")); else - allowedTypes.add (Atoms::getCreating ("text/uri-list")); + allowedTypes.add (Atoms::getCreating (d, "text/uri-list")); } - bool isText; - bool dragging; // currently performing outgoing external dnd as Xdnd source, have grabbed mouse - bool expectingStatus; // XdndPosition sent, waiting for XdndStatus - bool canDrop; // target window signals it will accept the drop - Window targetWindow; // potential drop target - int xdndVersion; // negotiated version with target + bool isText = false; + bool dragging = false; // currently performing outgoing external dnd as Xdnd source, have grabbed mouse + bool expectingStatus = false; // XdndPosition sent, waiting for XdndStatus + bool canDrop = false; // target window signals it will accept the drop + Window targetWindow = None; // potential drop target + int xdndVersion = -1; // negotiated version with target Rectangle silentRect; String textOrFiles; Array allowedTypes; @@ -3157,7 +3215,7 @@ private: void resetExternalDragState() { - dragState = DragState(); + dragState = new DragState (display); } void sendDragAndDropMessage (XClientMessageEvent& msg) @@ -3168,7 +3226,7 @@ private: msg.format = 32; msg.data.l[0] = (long) windowH; - ScopedXLock xlock; + ScopedXLock xlock (display); XSendEvent (display, dragAndDropSourceWindow, False, 0, (XEvent*) &msg); } @@ -3180,7 +3238,7 @@ private: msg.format = 32; msg.data.l[0] = (long) windowH; - ScopedXLock xlock; + ScopedXLock xlock (display); return XSendEvent (display, targetWindow, False, 0, (XEvent*) &msg) != 0; } @@ -3189,7 +3247,7 @@ private: XClientMessageEvent msg; zerostruct (msg); - msg.message_type = atoms.XdndDrop; + msg.message_type = atoms->XdndDrop; msg.data.l[2] = CurrentTime; sendExternalDragAndDropMessage (msg, targetWindow); @@ -3200,10 +3258,11 @@ private: XClientMessageEvent msg; zerostruct (msg); - msg.message_type = atoms.XdndEnter; + msg.message_type = atoms->XdndEnter; + msg.data.l[1] = (dragState->xdndVersion << 24); - msg.data.l[1] = (dragState.xdndVersion << 24); - msg.data.l[2] = (long) dragState.allowedTypes[0]; + for (int i = 0; i < 3; ++i) + msg.data.l[i + 2] = (long) dragState->allowedTypes[i]; sendExternalDragAndDropMessage (msg, targetWindow); } @@ -3213,20 +3272,20 @@ private: XClientMessageEvent msg; zerostruct (msg); - msg.message_type = atoms.XdndPosition; + msg.message_type = atoms->XdndPosition; Point mousePos (Desktop::getInstance().getMousePosition()); - if (dragState.silentRect.contains (mousePos)) // we've been asked to keep silent + if (dragState->silentRect.contains (mousePos)) // we've been asked to keep silent return; mousePos = DisplayGeometry::scaledToPhysical (mousePos); msg.data.l[1] = 0; msg.data.l[2] = (mousePos.x << 16) | mousePos.y; msg.data.l[3] = CurrentTime; - msg.data.l[4] = (long) atoms.XdndActionCopy; // this is all JUCE currently supports + msg.data.l[4] = (long) atoms->XdndActionCopy; // this is all JUCE currently supports - dragState.expectingStatus = sendExternalDragAndDropMessage (msg, targetWindow); + dragState->expectingStatus = sendExternalDragAndDropMessage (msg, targetWindow); } void sendDragAndDropStatus (const bool acceptDrop, Atom dropAction) @@ -3234,7 +3293,7 @@ private: XClientMessageEvent msg; zerostruct (msg); - msg.message_type = atoms.XdndStatus; + msg.message_type = atoms->XdndStatus; msg.data.l[1] = (acceptDrop ? 1 : 0) | 2; // 2 indicates that we want to receive position messages msg.data.l[4] = (long) dropAction; @@ -3246,7 +3305,7 @@ private: XClientMessageEvent msg; zerostruct (msg); - msg.message_type = atoms.XdndLeave; + msg.message_type = atoms->XdndLeave; sendExternalDragAndDropMessage (msg, targetWindow); } @@ -3255,13 +3314,13 @@ private: XClientMessageEvent msg; zerostruct (msg); - msg.message_type = atoms.XdndFinished; + msg.message_type = atoms->XdndFinished; sendDragAndDropMessage (msg); } void handleExternalSelectionClear() { - if (dragState.dragging) + if (dragState->dragging) externalResetDragAndDrop(); } @@ -3277,15 +3336,15 @@ private: s.xselection.property = None; s.xselection.time = evt.xselectionrequest.time; - if (dragState.allowedTypes.contains (targetType)) + if (dragState->allowedTypes.contains (targetType)) { s.xselection.property = evt.xselectionrequest.property; xchangeProperty (evt.xselectionrequest.requestor, evt.xselectionrequest.property, targetType, 8, - dragState.textOrFiles.toRawUTF8(), - (int) dragState.textOrFiles.getNumBytesAsUTF8()); + dragState->textOrFiles.toRawUTF8(), + (int) dragState->textOrFiles.getNumBytesAsUTF8()); } XSendEvent (display, evt.xselectionrequest.requestor, True, 0, &s); @@ -3293,39 +3352,39 @@ private: void handleExternalDragAndDropStatus (const XClientMessageEvent& clientMsg) { - if (dragState.expectingStatus) + if (dragState->expectingStatus) { - dragState.expectingStatus = false; - dragState.canDrop = false; - dragState.silentRect = Rectangle(); + dragState->expectingStatus = false; + dragState->canDrop = false; + dragState->silentRect = Rectangle(); if ((clientMsg.data.l[1] & 1) != 0 - && ((Atom) clientMsg.data.l[4] == atoms.XdndActionCopy - || (Atom) clientMsg.data.l[4] == atoms.XdndActionPrivate)) + && ((Atom) clientMsg.data.l[4] == atoms->XdndActionCopy + || (Atom) clientMsg.data.l[4] == atoms->XdndActionPrivate)) { if ((clientMsg.data.l[1] & 2) == 0) // target requests silent rectangle - dragState.silentRect.setBounds ((int) clientMsg.data.l[2] >> 16, + dragState->silentRect.setBounds ((int) clientMsg.data.l[2] >> 16, (int) clientMsg.data.l[2] & 0xffff, (int) clientMsg.data.l[3] >> 16, (int) clientMsg.data.l[3] & 0xffff); - dragState.canDrop = true; + dragState->canDrop = true; } } } void handleExternalDragButtonReleaseEvent() { - if (dragState.dragging) + if (dragState->dragging) XUngrabPointer (display, CurrentTime); - if (dragState.canDrop) + if (dragState->canDrop) { - sendExternalDragAndDropDrop (dragState.targetWindow); + sendExternalDragAndDropDrop (dragState->targetWindow); } else { - sendExternalDragAndDropLeave (dragState.targetWindow); + sendExternalDragAndDropLeave (dragState->targetWindow); externalResetDragAndDrop(); } } @@ -3334,18 +3393,18 @@ private: { Window targetWindow = externalFindDragTargetWindow (RootWindow (display, DefaultScreen (display))); - if (dragState.targetWindow != targetWindow) + if (dragState->targetWindow != targetWindow) { - if (dragState.targetWindow != None) - sendExternalDragAndDropLeave (dragState.targetWindow); + if (dragState->targetWindow != None) + sendExternalDragAndDropLeave (dragState->targetWindow); - dragState.canDrop = false; - dragState.silentRect = Rectangle(); + dragState->canDrop = false; + dragState->silentRect = Rectangle(); if (targetWindow == None) return; - GetXProperty prop (targetWindow, atoms.XdndAware, + GetXProperty prop (display, targetWindow, atoms->XdndAware, 0, 2, false, AnyPropertyType); if (prop.success @@ -3353,19 +3412,19 @@ private: && prop.actualFormat == 32 && prop.numItems == 1) { - dragState.xdndVersion = jmin ((int) prop.data[0], (int) Atoms::DndVersion); + dragState->xdndVersion = jmin ((int) prop.data[0], (int) atoms->DndVersion); } else { - dragState.xdndVersion = -1; + dragState->xdndVersion = -1; return; } sendExternalDragAndDropEnter (targetWindow); - dragState.targetWindow = targetWindow; + dragState->targetWindow = targetWindow; } - if (! dragState.expectingStatus) + if (! dragState->expectingStatus) sendExternalDragAndDropPosition (targetWindow); } @@ -3380,13 +3439,13 @@ private: (int) clientMsg.data.l[2] & 0xffff); dropPos -= bounds.getPosition(); - Atom targetAction = atoms.XdndActionCopy; + Atom targetAction = atoms->XdndActionCopy; - for (int i = numElementsInArray (atoms.allowedActions); --i >= 0;) + for (int i = numElementsInArray (atoms->allowedActions); --i >= 0;) { - if ((Atom) clientMsg.data.l[4] == atoms.allowedActions[i]) + if ((Atom) clientMsg.data.l[4] == atoms->allowedActions[i]) { - targetAction = atoms.allowedActions[i]; + targetAction = atoms->allowedActions[i]; break; } } @@ -3448,8 +3507,8 @@ private: if ((clientMsg.data.l[1] & 1) != 0) { - ScopedXLock xlock; - GetXProperty prop (dragAndDropSourceWindow, atoms.XdndTypeList, 0, 0x8000000L, false, XA_ATOM); + ScopedXLock xlock (display); + GetXProperty prop (display, dragAndDropSourceWindow, atoms->XdndTypeList, 0, 0x8000000L, false, XA_ATOM); if (prop.success && prop.actualType == XA_ATOM @@ -3478,9 +3537,9 @@ private: } for (int i = 0; i < srcMimeTypeAtomList.size() && dragAndDropCurrentMimeType == 0; ++i) - for (int j = 0; j < numElementsInArray (atoms.allowedMimeTypes); ++j) - if (srcMimeTypeAtomList[i] == atoms.allowedMimeTypes[j]) - dragAndDropCurrentMimeType = atoms.allowedMimeTypes[j]; + for (int j = 0; j < numElementsInArray (atoms->allowedMimeTypes); ++j) + if (srcMimeTypeAtomList[i] == atoms->allowedMimeTypes[j]) + dragAndDropCurrentMimeType = atoms->allowedMimeTypes[j]; handleDragAndDropPosition (clientMsg); } @@ -3498,7 +3557,7 @@ private: for (;;) { - GetXProperty prop (evt.xany.window, evt.xselection.property, + GetXProperty prop (display, evt.xany.window, evt.xselection.property, dropData.getSize() / 4, 65536, false, AnyPropertyType); if (! prop.success) @@ -3513,7 +3572,7 @@ private: lines.addLines (dropData.toString()); } - if (Atoms::isMimeTypeFile (dragAndDropCurrentMimeType)) + if (Atoms::isMimeTypeFile (display, dragAndDropCurrentMimeType)) { for (int i = 0; i < lines.size(); ++i) dragInfo.files.add (URL::removeEscapeChars (lines[i].replace ("file://", String(), true))); @@ -3538,11 +3597,11 @@ private: if (dragAndDropSourceWindow != None && dragAndDropCurrentMimeType != None) { - ScopedXLock xlock; + ScopedXLock xlock (display); XConvertSelection (display, - atoms.XdndSelection, + atoms->XdndSelection, dragAndDropCurrentMimeType, - Atoms::getCreating ("JXSelectionWindowProperty"), + Atoms::getCreating (display, "JXSelectionWindowProperty"), windowH, (::Time) clientMsg.data.l[2]); } @@ -3555,7 +3614,7 @@ private: bool dndAwarePropFound = false; for (int i = 0; i < numProperties; ++i) - if (properties[i] == atoms.XdndAware) + if (properties[i] == atoms->XdndAware) dndAwarePropFound = true; if (properties != nullptr) @@ -3584,12 +3643,12 @@ private: bool externalDragInit (bool isText, const String& textOrFiles) { - ScopedXLock xlock; + ScopedXLock xlock (display); resetExternalDragState(); - dragState.isText = isText; - dragState.textOrFiles = textOrFiles; - dragState.targetWindow = windowH; + dragState->isText = isText; + dragState->textOrFiles = textOrFiles; + dragState->targetWindow = windowH; const int pointerGrabMask = Button1MotionMask | ButtonReleaseMask; @@ -3599,14 +3658,14 @@ private: // No other method of changing the pointer seems to work, this call is needed from this very context XChangeActivePointerGrab (display, pointerGrabMask, (Cursor) createDraggingHandCursor(), CurrentTime); - XSetSelectionOwner (display, atoms.XdndSelection, windowH, CurrentTime); + XSetSelectionOwner (display, atoms->XdndSelection, windowH, CurrentTime); // save the available types to XdndTypeList - xchangeProperty (windowH, atoms.XdndTypeList, XA_ATOM, 32, - dragState.allowedTypes.getRawDataPointer(), - dragState.allowedTypes.size()); + xchangeProperty (windowH, atoms->XdndTypeList, XA_ATOM, 32, + dragState->allowedTypes.getRawDataPointer(), + dragState->allowedTypes.size()); - dragState.dragging = true; + dragState->dragging = true; handleExternalDragMotionNotify(); return true; } @@ -3616,16 +3675,16 @@ private: void externalResetDragAndDrop() { - if (dragState.dragging) + if (dragState->dragging) { - ScopedXLock xlock; + ScopedXLock xlock (display); XUngrabPointer (display, CurrentTime); } resetExternalDragState(); } - DragState dragState; + ScopedPointer dragState; DragInfo dragInfo; Atom dragAndDropCurrentMimeType; Window dragAndDropSourceWindow; @@ -3633,7 +3692,7 @@ private: Array srcMimeTypeAtomList; - int pointerMap[5]; + int pointerMap[5] = {}; void initialisePointerMap() { @@ -3672,6 +3731,40 @@ private: ModifierKeys LinuxComponentPeer::currentModifiers; bool LinuxComponentPeer::isActiveApplication = false; Point LinuxComponentPeer::lastMousePos; +::Display* LinuxComponentPeer::display = nullptr; + +//============================================================================== +namespace WindowingHelpers +{ + static void windowMessageReceive (XEvent& event) + { + if (event.xany.window != None) + { + #if JUCE_X11_SUPPORTS_XEMBED + if (! juce_handleXEmbedEvent (nullptr, &event)) + #endif + { + if (auto* peer = LinuxComponentPeer::getPeerFor (event.xany.window)) + peer->handleWindowMessage (event); + } + } + else if (event.xany.type == KeymapNotify) + { + auto& keymapEvent = (const XKeymapEvent&) event.xkeymap; + memcpy (Keys::keyStates, keymapEvent.key_vector, 32); + } + } +} + +struct WindowingCallbackInitialiser +{ + WindowingCallbackInitialiser() + { + dispatchWindowMessage = WindowingHelpers::windowMessageReceive; + } +}; + +static WindowingCallbackInitialiser windowingInitialiser; //============================================================================== JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() @@ -3691,14 +3784,16 @@ void ModifierKeys::updateCurrentModifiers() noexcept ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept { - if (display != nullptr) + ScopedXDisplay xDisplay; + + if (auto display = xDisplay.display) { Window root, child; int x, y, winx, winy; unsigned int mask; int mouseMods = 0; - ScopedXLock xlock; + ScopedXLock xlock (display); if (XQueryPointer (display, RootWindow (display, DefaultScreen (display)), &root, &child, &x, &y, &winx, &winy, &mask) != False) @@ -3733,54 +3828,58 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAtt //============================================================================== void Desktop::Displays::findDisplays (float masterScale) { - DisplayGeometry& geometry = DisplayGeometry::getOrCreateInstance (display, masterScale); + ScopedXDisplay xDisplay; - // add the main display first - int mainDisplayIdx; - for (mainDisplayIdx = 0; mainDisplayIdx < geometry.infos.size(); ++mainDisplayIdx) + if (auto display = xDisplay.display) { - const DisplayGeometry::ExtendedInfo& info = geometry.infos.getReference (mainDisplayIdx); - if (info.isMain) - break; - } + auto& geometry = DisplayGeometry::getOrCreateInstance (display, masterScale); - // no main display found then use the first - if (mainDisplayIdx >= geometry.infos.size()) - mainDisplayIdx = 0; + // add the main display first + int mainDisplayIdx; - // add the main display - { - const DisplayGeometry::ExtendedInfo& info = - geometry.infos.getReference (mainDisplayIdx); - Desktop::Displays::Display d; + for (mainDisplayIdx = 0; mainDisplayIdx < geometry.infos.size(); ++mainDisplayIdx) + { + auto& info = geometry.infos.getReference (mainDisplayIdx); + + if (info.isMain) + break; + } - d.isMain = true; - d.scale = masterScale * info.scale; - d.dpi = info.dpi; + // no main display found then use the first + if (mainDisplayIdx >= geometry.infos.size()) + mainDisplayIdx = 0; - d.totalArea = DisplayGeometry::physicalToScaled (info.totalBounds); - d.userArea = (info.usableBounds / d.scale) + info.topLeftScaled; + // add the main display + { + auto& info = geometry.infos.getReference (mainDisplayIdx); - displays.add (d); - } + Desktop::Displays::Display d; + d.isMain = true; + d.scale = masterScale * info.scale; + d.dpi = info.dpi; + d.totalArea = DisplayGeometry::physicalToScaled (info.totalBounds); + d.userArea = (info.usableBounds / d.scale) + info.topLeftScaled; - for (int i = 0; i < geometry.infos.size(); ++i) - { - // don't add the main display a second time - if (i == mainDisplayIdx) - continue; + displays.add (d); + } - const DisplayGeometry::ExtendedInfo& info = geometry.infos.getReference (i); - Desktop::Displays::Display d; + for (int i = 0; i < geometry.infos.size(); ++i) + { + // don't add the main display a second time + if (i == mainDisplayIdx) + continue; - d.isMain = false; - d.scale = masterScale * info.scale; - d.dpi = info.dpi; + auto& info = geometry.infos.getReference (i); - d.totalArea = DisplayGeometry::physicalToScaled (info.totalBounds); - d.userArea = (info.usableBounds / d.scale) + info.topLeftScaled; + Desktop::Displays::Display d; + d.isMain = false; + d.scale = masterScale * info.scale; + d.dpi = info.dpi; + d.totalArea = DisplayGeometry::physicalToScaled (info.totalBounds); + d.userArea = (info.usableBounds / d.scale) + info.topLeftScaled; - displays.add (d); + displays.add (d); + } } } @@ -3789,13 +3888,18 @@ bool MouseInputSource::SourceList::addSource() { if (sources.size() == 0) { - addSource (0, true); + addSource (0, MouseInputSource::InputSourceType::mouse); return true; } return false; } +bool MouseInputSource::SourceList::canUseTouch() +{ + return false; +} + bool Desktop::canUseSemiTransparentWindows() noexcept { #if JUCE_USE_XRENDER @@ -3803,7 +3907,7 @@ bool Desktop::canUseSemiTransparentWindows() noexcept { int matchedDepth = 0, desiredDepth = 32; - return Visuals::findVisualFormat (desiredDepth, matchedDepth) != 0 + return Visuals::findVisualFormat (display, desiredDepth, matchedDepth) != 0 && matchedDepth == desiredDepth; } #endif @@ -3813,14 +3917,17 @@ bool Desktop::canUseSemiTransparentWindows() noexcept Point MouseInputSource::getCurrentRawMousePosition() { + ScopedXDisplay xDisplay; + auto display = xDisplay.display; + if (display == nullptr) - return Point(); + return {}; Window root, child; int x, y, winx, winy; unsigned int mask; - ScopedXLock xlock; + ScopedXLock xlock (display); if (XQueryPointer (display, RootWindow (display, DefaultScreen (display)), @@ -3836,9 +3943,11 @@ Point MouseInputSource::getCurrentRawMousePosition() void MouseInputSource::setRawMousePosition (Point newPosition) { - if (display != nullptr) + ScopedXDisplay xDisplay; + + if (auto display = xDisplay.display) { - ScopedXLock xlock; + ScopedXLock xlock (display); Window root = RootWindow (display, DefaultScreen (display)); newPosition = DisplayGeometry::scaledToPhysical (newPosition); XWarpPointer (display, None, root, 0, 0, 0, 0, roundToInt (newPosition.getX()), roundToInt (newPosition.getY())); @@ -3864,16 +3973,18 @@ void Desktop::setScreenSaverEnabled (const bool isEnabled) { screenSaverAllowed = isEnabled; - if (display != nullptr) + ScopedXDisplay xDisplay; + + if (auto display = xDisplay.display) { typedef void (*tXScreenSaverSuspend) (Display*, Bool); static tXScreenSaverSuspend xScreenSaverSuspend = nullptr; if (xScreenSaverSuspend == nullptr) - if (void* h = dlopen ("libXss.so", RTLD_GLOBAL | RTLD_NOW)) + if (void* h = dlopen ("libXss.so.1", RTLD_GLOBAL | RTLD_NOW)) xScreenSaverSuspend = (tXScreenSaverSuspend) dlsym (h, "XScreenSaverSuspend"); - ScopedXLock xlock; + ScopedXLock xlock (display); if (xScreenSaverSuspend != nullptr) xScreenSaverSuspend (display, ! isEnabled); } @@ -3886,12 +3997,109 @@ bool Desktop::isScreenSaverEnabled() } //============================================================================== +Image juce_createIconForFile (const File& /* file */) +{ + return {}; +} + +//============================================================================== +void LookAndFeel::playAlertSound() +{ + std::cout << "\a" << std::flush; +} + +//============================================================================== +Rectangle juce_LinuxScaledToPhysicalBounds (ComponentPeer* peer, Rectangle bounds) +{ + if (auto* linuxPeer = dynamic_cast (peer)) + bounds *= linuxPeer->getCurrentScale(); + + return bounds; +} + +void juce_LinuxAddRepaintListener (ComponentPeer* peer, Component* dummy) +{ + if (auto* linuxPeer = dynamic_cast (peer)) + linuxPeer->addOpenGLRepaintListener (dummy); +} + +void juce_LinuxRemoveRepaintListener (ComponentPeer* peer, Component* dummy) +{ + if (auto* linuxPeer = dynamic_cast (peer)) + linuxPeer->removeOpenGLRepaintListener (dummy); +} + +unsigned long juce_createKeyProxyWindow (ComponentPeer* peer) +{ + if (auto* linuxPeer = dynamic_cast (peer)) + return linuxPeer->createKeyProxy(); + + return 0; +} + +void juce_deleteKeyProxyWindow (ComponentPeer* peer) +{ + if (auto* linuxPeer = dynamic_cast (peer)) + linuxPeer->deleteKeyProxy(); +} + +//============================================================================== +#if JUCE_MODAL_LOOPS_PERMITTED +void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* /* associatedComponent */) +{ + AlertWindow::showMessageBox (iconType, title, message); +} +#endif + +void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + AlertWindow::showMessageBoxAsync (iconType, title, message, String(), associatedComponent, callback); +} + +bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + return AlertWindow::showOkCancelBox (iconType, title, message, String(), String(), + associatedComponent, callback); +} + +int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + return AlertWindow::showYesNoCancelBox (iconType, title, message, + String(), String(), String(), + associatedComponent, callback); +} + +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + return AlertWindow::showOkCancelBox (iconType, title, message, TRANS ("Yes"), TRANS ("No"), + associatedComponent, callback); +} + +//============================== X11 - MouseCursor ============================= + void* CustomMouseCursorInfo::create() const { + ScopedXDisplay xDisplay; + auto display = xDisplay.display; + if (display == nullptr) return nullptr; - ScopedXLock xlock; + ScopedXLock xlock (display); const unsigned int imageW = (unsigned int) image.getWidth(); const unsigned int imageH = (unsigned int) image.getHeight(); int hotspotX = hotspot.x; @@ -3914,7 +4122,7 @@ void* CustomMouseCursorInfo::create() const { hasBeenLoaded = true; - if (void* h = dlopen ("libXcursor.so", RTLD_GLOBAL | RTLD_NOW)) + if (void* h = dlopen ("libXcursor.so.1", RTLD_GLOBAL | RTLD_NOW)) { xcursorSupportsARGB = (tXcursorSupportsARGB) dlsym (h, "XcursorSupportsARGB"); xcursorImageCreate = (tXcursorImageCreate) dlsym (h, "XcursorImageCreate"); @@ -4013,15 +4221,23 @@ void* CustomMouseCursorInfo::create() const void MouseCursor::deleteMouseCursor (void* const cursorHandle, const bool) { - if (cursorHandle != nullptr && display != nullptr) + if (cursorHandle != nullptr) { - ScopedXLock xlock; - XFreeCursor (display, (Cursor) cursorHandle); + ScopedXDisplay xDisplay; + + if (auto display = xDisplay.display) + { + ScopedXLock xlock (display); + XFreeCursor (display, (Cursor) cursorHandle); + } } } void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType type) { + ScopedXDisplay xDisplay; + auto display = xDisplay.display; + if (display == nullptr) return None; @@ -4066,13 +4282,13 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty return None; } - ScopedXLock xlock; + ScopedXLock xlock (display); return (void*) XCreateFontCursor (display, shape); } void MouseCursor::showInWindow (ComponentPeer* peer) const { - if (LinuxComponentPeer* const lp = dynamic_cast (peer)) + if (auto* lp = dynamic_cast (peer)) lp->showMouseCursor ((Cursor) getHandle()); } @@ -4082,160 +4298,44 @@ void MouseCursor::showInAllWindows() const showInWindow (ComponentPeer::getPeer (i)); } -//============================================================================== -Image juce_createIconForFile (const File& /* file */) +//=================================== X11 - DND ================================ +static LinuxComponentPeer* getPeerForDragEvent (Component* sourceComp) { - return Image(); + if (sourceComp == nullptr) + if (auto* draggingSource = Desktop::getInstance().getDraggingMouseSource(0)) + sourceComp = draggingSource->getComponentUnderMouse(); + + if (sourceComp != nullptr) + if (auto* lp = dynamic_cast (sourceComp->getPeer())) + return lp; + + jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! + return nullptr; } -//============================================================================== -bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles) +bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles, + Component* sourceComp) { if (files.size() == 0) return false; - if (MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0)) - if (Component* sourceComp = draggingSource->getComponentUnderMouse()) - if (LinuxComponentPeer* const lp = dynamic_cast (sourceComp->getPeer())) - return lp->externalDragFileInit (files, canMoveFiles); + if (auto* lp = getPeerForDragEvent (sourceComp)) + return lp->externalDragFileInit (files, canMoveFiles); // This method must be called in response to a component's mouseDown or mouseDrag event! jassertfalse; return false; } -bool DragAndDropContainer::performExternalDragDropOfText (const String& text) +bool DragAndDropContainer::performExternalDragDropOfText (const String& text, Component* sourceComp) { if (text.isEmpty()) return false; - if (MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0)) - if (Component* sourceComp = draggingSource->getComponentUnderMouse()) - if (LinuxComponentPeer* const lp = dynamic_cast (sourceComp->getPeer())) - return lp->externalDragTextInit (text); + if (auto* lp = getPeerForDragEvent (sourceComp)) + return lp->externalDragTextInit (text); // This method must be called in response to a component's mouseDown or mouseDrag event! jassertfalse; return false; } - -//============================================================================== -void LookAndFeel::playAlertSound() -{ - std::cout << "\a" << std::flush; -} -//============================================================================== -Rectangle juce_LinuxScaledToPhysicalBounds(ComponentPeer* peer, const Rectangle& bounds) -{ - Rectangle retval = bounds; - - if (LinuxComponentPeer* linuxPeer = dynamic_cast (peer)) - retval *= linuxPeer->getCurrentScale(); - - return retval; -} - -void juce_LinuxAddRepaintListener (ComponentPeer* peer, Component* dummy) -{ - if (LinuxComponentPeer* linuxPeer = dynamic_cast (peer)) - linuxPeer->addOpenGLRepaintListener (dummy); -} - -void juce_LinuxRemoveRepaintListener (ComponentPeer* peer, Component* dummy) -{ - if (LinuxComponentPeer* linuxPeer = dynamic_cast (peer)) - linuxPeer->removeOpenGLRepaintListener (dummy); -} - -//============================================================================== -#if JUCE_MODAL_LOOPS_PERMITTED -void JUCE_CALLTYPE NativeMessageBox::showMessageBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* /* associatedComponent */) -{ - AlertWindow::showMessageBox (iconType, title, message); -} -#endif - -void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - AlertWindow::showMessageBoxAsync (iconType, title, message, String(), associatedComponent, callback); -} - -bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - return AlertWindow::showOkCancelBox (iconType, title, message, String(), String(), - associatedComponent, callback); -} - -int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType, - const String& title, const String& message, - Component* associatedComponent, - ModalComponentManager::Callback* callback) -{ - return AlertWindow::showYesNoCancelBox (iconType, title, message, - String(), String(), String(), - associatedComponent, callback); -} - - -//============================================================================== -const int KeyPress::spaceKey = XK_space & 0xff; -const int KeyPress::returnKey = XK_Return & 0xff; -const int KeyPress::escapeKey = XK_Escape & 0xff; -const int KeyPress::backspaceKey = XK_BackSpace & 0xff; -const int KeyPress::leftKey = (XK_Left & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::rightKey = (XK_Right & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::upKey = (XK_Up & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::downKey = (XK_Down & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::pageUpKey = (XK_Page_Up & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::pageDownKey = (XK_Page_Down & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::endKey = (XK_End & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::homeKey = (XK_Home & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::insertKey = (XK_Insert & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::deleteKey = (XK_Delete & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::tabKey = XK_Tab & 0xff; -const int KeyPress::F1Key = (XK_F1 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F2Key = (XK_F2 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F3Key = (XK_F3 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F4Key = (XK_F4 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F5Key = (XK_F5 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F6Key = (XK_F6 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F7Key = (XK_F7 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F8Key = (XK_F8 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F9Key = (XK_F9 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F10Key = (XK_F10 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F11Key = (XK_F11 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F12Key = (XK_F12 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F13Key = (XK_F13 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F14Key = (XK_F14 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F15Key = (XK_F15 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::F16Key = (XK_F16 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad0 = (XK_KP_0 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad1 = (XK_KP_1 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad2 = (XK_KP_2 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad3 = (XK_KP_3 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad4 = (XK_KP_4 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad5 = (XK_KP_5 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad6 = (XK_KP_6 & 0xff) | Keys::extendedKeyModifier; -const int KeyPress::numberPad7 = (XK_KP_7 & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPad8 = (XK_KP_8 & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPad9 = (XK_KP_9 & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadAdd = (XK_KP_Add & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadSubtract = (XK_KP_Subtract & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadMultiply = (XK_KP_Multiply & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadDivide = (XK_KP_Divide & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadSeparator = (XK_KP_Separator & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadDecimalPoint = (XK_KP_Decimal & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadEquals = (XK_KP_Equal & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::numberPadDelete = (XK_KP_Delete & 0xff)| Keys::extendedKeyModifier; -const int KeyPress::playKey = ((int) 0xffeeff00) | Keys::extendedKeyModifier; -const int KeyPress::stopKey = ((int) 0xffeeff01) | Keys::extendedKeyModifier; -const int KeyPress::fastForwardKey = ((int) 0xffeeff02) | Keys::extendedKeyModifier; -const int KeyPress::rewindKey = ((int) 0xffeeff03) | Keys::extendedKeyModifier; diff --git a/source/modules/juce_gui_basics/native/juce_mac_FileChooser.mm b/source/modules/juce_gui_basics/native/juce_mac_FileChooser.mm index 69f4a64b0..f0f99d8d8 100644 --- a/source/modules/juce_gui_basics/native/juce_mac_FileChooser.mm +++ b/source/modules/juce_gui_basics/native/juce_mac_FileChooser.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -211,7 +213,7 @@ void FileChooser::showPlatformDialog (Array& results, } #if defined (MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) - [panel setDirectoryURL: [NSURL fileURLWithPath: juceStringToNS (directory)]]; + [panel setDirectoryURL: createNSURLFromFile (directory)]; [panel setNameFieldStringValue: juceStringToNS (filename)]; if ([panel runModal] == 1 /*NSModalResponseOK*/) diff --git a/source/modules/juce_gui_basics/native/juce_mac_MainMenu.mm b/source/modules/juce_gui_basics/native/juce_mac_MainMenu.mm index 97c3088b4..e2d639195 100644 --- a/source/modules/juce_gui_basics/native/juce_mac_MainMenu.mm +++ b/source/modules/juce_gui_basics/native/juce_mac_MainMenu.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -27,10 +29,6 @@ class JuceMainMenuHandler : private MenuBarModel::Listener, { public: JuceMainMenuHandler() - : currentModel (nullptr), - lastUpdateTime (0), - isOpen (false), - defferedUpdateRequested (false) { static JuceMenuCallbackClass cls; callback = [cls.createInstance() init]; @@ -98,6 +96,20 @@ public: [menu release]; } + void updateTopLevelMenu (NSMenu* menu) + { + NSMenu* superMenu = [menu supermenu]; + auto menuNames = currentModel->getMenuBarNames(); + auto indexOfMenu = (int) [superMenu indexOfItemWithSubmenu: menu]; + [menu removeAllItems]; + auto updatedPopup = currentModel->getMenuForIndex (indexOfMenu - 1, menuNames[indexOfMenu - 1]); + + for (PopupMenu::MenuItemIterator iter (updatedPopup); iter.next();) + addMenuItem (iter, menu, 1, indexOfMenu); + + [menu update]; + } + void menuBarItemsChanged (MenuBarModel*) { if (isOpen) @@ -121,7 +133,7 @@ public: for (int i = 0; i < menuNames.size(); ++i) { - const PopupMenu menu (currentModel->getMenuForIndex (i, menuNames [i])); + const PopupMenu menu (currentModel->getMenuForIndex (i, menuNames[i])); if (i >= [menuBar numberOfItems] - 1) addTopLevelMenu (menuBar, menu, menuNames[i], menuId, i); @@ -136,24 +148,10 @@ public: { if ((info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) == 0 && info.invocationMethod != ApplicationCommandTarget::InvocationInfo::fromKeyPress) - if (NSMenuItem* item = findMenuItemWithTag ([NSApp mainMenu], info.commandID)) + if (auto* item = findMenuItemWithTag ([NSApp mainMenu], info.commandID)) flashMenuBar ([item menu]); } - void updateMenus (NSMenu* menu) - { - if (PopupMenu::dismissAllActiveMenus()) - { - // If we were running a juce menu, then we should let that modal loop finish before allowing - // the OS menus to start their own modal loop - so cancel the menu that was being opened.. - if ([menu respondsToSelector: @selector (cancelTracking)]) - [menu performSelector: @selector (cancelTracking)]; - } - - if (Time::getMillisecondCounter() > lastUpdateTime + 100) - (new AsyncMenuUpdater())->post(); - } - void invoke (int commandId, ApplicationCommandManager* commandManager, int topLevelIndex) const { if (currentModel != nullptr) @@ -166,7 +164,11 @@ public: commandManager->invoke (info, true); } - (new AsyncCommandInvoker (commandId, topLevelIndex))->post(); + MessageManager::callAsync ([=]() + { + if (instance != nullptr) + instance->invokeDirectly (commandId, topLevelIndex); + }); } } @@ -242,23 +244,21 @@ public: if (i.commandManager != nullptr) { - const Array keyPresses (i.commandManager->getKeyMappings() - ->getKeyPressesAssignedToCommand (i.itemID)); - - if (keyPresses.size() > 0) + for (auto& kp : i.commandManager->getKeyMappings()->getKeyPressesAssignedToCommand (i.itemID)) { - const KeyPress& kp = keyPresses.getReference(0); - if (kp != KeyPress::backspaceKey // (adding these is annoying because it flashes the menu bar && kp != KeyPress::deleteKey) // every time you press the key while editing text) { juce_wchar key = kp.getTextCharacter(); + if (key == 0) key = (juce_wchar) kp.getKeyCode(); [item setKeyEquivalent: juceStringToNS (String::charToString (key).toLowerCase())]; [item setKeyEquivalentModifierMask: juceModsToNSMods (kp.getModifiers())]; } + + break; } } } @@ -292,12 +292,12 @@ public: static JuceMainMenuHandler* instance; - MenuBarModel* currentModel; + MenuBarModel* currentModel = nullptr; ScopedPointer extraAppleMenuItems; - uint32 lastUpdateTime; - NSObject* callback; + uint32 lastUpdateTime = 0; + NSObject* callback = nil; String recentItemsMenuName; - bool isOpen, defferedUpdateRequested; + bool isOpen = false, defferedUpdateRequested = false; private: struct RecentFilesMenuItem @@ -419,39 +419,10 @@ private: return m; } - struct AsyncMenuUpdater : public CallbackMessage - { - AsyncMenuUpdater() {} - - void messageCallback() override - { - if (instance != nullptr) - instance->menuBarItemsChanged (nullptr); - } - - JUCE_DECLARE_NON_COPYABLE (AsyncMenuUpdater) - }; - - struct AsyncCommandInvoker : public CallbackMessage - { - AsyncCommandInvoker (int commandId_, int topLevelIndex_) - : commandId (commandId_), topLevelIndex (topLevelIndex_) - {} - - void messageCallback() override - { - if (instance != nullptr) - instance->invokeDirectly (commandId, topLevelIndex); - } - - const int commandId, topLevelIndex; - JUCE_DECLARE_NON_COPYABLE (AsyncCommandInvoker) - }; - //============================================================================== - struct JuceMenuCallbackClass : public ObjCClass + struct JuceMenuCallbackClass : public ObjCClass { - JuceMenuCallbackClass() : ObjCClass ("JUCEMainMenu_") + JuceMenuCallbackClass() : ObjCClass ("JUCEMainMenu_") { addIvar ("owner"); @@ -473,7 +444,7 @@ private: private: static void menuItemInvoked (id self, SEL, NSMenuItem* item) { - JuceMainMenuHandler* const owner = getIvar (self, "owner"); + auto owner = getIvar (self, "owner"); if ([[item representedObject] isKindOfClass: [NSArray class]]) { @@ -481,11 +452,12 @@ private: // our own components, which may have wanted to intercept it. So, rather than dispatching directly, we'll feed it back // into the focused component and let it trigger the menu item indirectly. NSEvent* e = [NSApp currentEvent]; + if ([e type] == NSEventTypeKeyDown || [e type] == NSEventTypeKeyUp) { - if (juce::Component* focused = juce::Component::getCurrentlyFocusedComponent()) + if (auto* focused = juce::Component::getCurrentlyFocusedComponent()) { - if (juce::NSViewComponentPeer* peer = dynamic_cast (focused->getPeer())) + if (auto peer = dynamic_cast (focused->getPeer())) { if ([e type] == NSEventTypeKeyDown) peer->redirectKeyDown (e); @@ -506,10 +478,9 @@ private: } } - static void menuNeedsUpdate (id, SEL, NSMenu* menu) + static void menuNeedsUpdate (id self, SEL, NSMenu* menu) { - if (instance != nullptr) - instance->updateMenus (menu); + getIvar (self, "owner")->updateTopLevelMenu (menu); } }; }; @@ -521,13 +492,13 @@ class TemporaryMainMenuWithStandardCommands { public: TemporaryMainMenuWithStandardCommands() - : oldMenu (MenuBarModel::getMacMainMenu()), oldAppleMenu (nullptr) + : oldMenu (MenuBarModel::getMacMainMenu()) { - if (const PopupMenu* appleMenu = MenuBarModel::getMacExtraAppleItemsMenu()) + if (auto* appleMenu = MenuBarModel::getMacExtraAppleItemsMenu()) oldAppleMenu = new PopupMenu (*appleMenu); - if (JuceMainMenuHandler::instance != nullptr) - oldRecentItems = JuceMainMenuHandler::instance->recentItemsMenuName; + if (auto* handler = JuceMainMenuHandler::instance) + oldRecentItems = handler->recentItemsMenuName; MenuBarModel::setMacMainMenu (nullptr); @@ -555,7 +526,7 @@ public: [menu release]; // use a dummy modal component so that apps can tell that something is currently modal. - dummyModalComponent.enterModalState(); + dummyModalComponent.enterModalState (false); } ~TemporaryMainMenuWithStandardCommands() @@ -564,7 +535,7 @@ public: } private: - MenuBarModel* oldMenu; + MenuBarModel* const oldMenu; ScopedPointer oldAppleMenu; String oldRecentItems; @@ -639,12 +610,14 @@ namespace MainMenuHelpers // this can't be used in a plugin! jassert (JUCEApplicationBase::isStandaloneApp()); - if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance()) + if (auto* app = JUCEApplicationBase::getInstance()) { JUCE_AUTORELEASEPOOL { NSMenu* mainMenu = [[NSMenu alloc] initWithTitle: nsStringLiteral ("MainMenu")]; - NSMenuItem* item = [mainMenu addItemWithTitle: nsStringLiteral ("Apple") action: nil keyEquivalent: nsEmptyString()]; + NSMenuItem* item = [mainMenu addItemWithTitle: nsStringLiteral ("Apple") + action: nil + keyEquivalent: nsEmptyString()]; NSMenu* appMenu = [[NSMenu alloc] initWithTitle: nsStringLiteral ("Apple")]; @@ -695,7 +668,7 @@ void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel, MenuBarModel* MenuBarModel::getMacMainMenu() { - if (JuceMainMenuHandler* mm = JuceMainMenuHandler::instance) + if (auto* mm = JuceMainMenuHandler::instance) return mm->currentModel; return nullptr; @@ -703,7 +676,7 @@ MenuBarModel* MenuBarModel::getMacMainMenu() const PopupMenu* MenuBarModel::getMacExtraAppleItemsMenu() { - if (JuceMainMenuHandler* mm = JuceMainMenuHandler::instance) + if (auto* mm = JuceMainMenuHandler::instance) return mm->extraAppleMenuItems.get(); return nullptr; @@ -716,11 +689,11 @@ static void mainMenuTrackingChanged (bool isTracking) { PopupMenu::dismissAllActiveMenus(); - if (JuceMainMenuHandler* menuHandler = JuceMainMenuHandler::instance) + if (auto* menuHandler = JuceMainMenuHandler::instance) { menuHandler->isOpen = isTracking; - if (MenuBarModel* model = menuHandler->currentModel) + if (auto* model = menuHandler->currentModel) model->handleMenuBarActivate (isTracking); if (menuHandler->defferedUpdateRequested && ! isTracking) @@ -745,7 +718,7 @@ NSMenu* createNSMenu (const PopupMenu& menu, const String& name, { juce_initialiseMacMainMenu(); - if (JuceMainMenuHandler* mm = JuceMainMenuHandler::instance) + if (auto* mm = JuceMainMenuHandler::instance) return mm->createMenu (menu, name, topLevelMenuId, topLevelIndex, addDelegate); jassertfalse; // calling this before making sure the OSX main menu stuff was initialised? diff --git a/source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm b/source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm index 434bcf2cc..36e05219d 100644 --- a/source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm +++ b/source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index da76a50bb..492bea9b1 100644 --- a/source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -59,7 +61,7 @@ static NSRect flippedScreenRect (NSRect r) noexcept } #if JUCE_MODULE_AVAILABLE_juce_opengl -void componentPeerAboutToBeRemovedFromScreen (ComponentPeer&); +void componentPeerAboutToChange (Component&, bool); #endif //============================================================================== @@ -69,21 +71,8 @@ class NSViewComponentPeer : public ComponentPeer, public: NSViewComponentPeer (Component& comp, const int windowStyleFlags, NSView* viewToAttachTo) : ComponentPeer (comp, windowStyleFlags), - window (nil), - view (nil), isSharedWindow (viewToAttachTo != nil), - fullScreen (false), - #if USE_COREGRAPHICS_RENDERING - usingCoreGraphics (true), - #else - usingCoreGraphics (false), - #endif - isZooming (false), - isFirstLiveResize (false), - textWasInserted (false), - isStretchingTop (false), isStretchingLeft (false), - isStretchingBottom (false), isStretchingRight (false), - notificationCenter (nil), lastRepaintTime (Time::getMillisecondCounter()) + lastRepaintTime (Time::getMillisecondCounter()) { appFocusChangeCallback = appFocusChanged; isEventBlockedByModalComps = checkEventBlockedByModalComps; @@ -184,7 +173,10 @@ public: setOwner (view, nullptr); if ([view superview] != nil) + { + redirectWillMoveToWindow (nullptr); [view removeFromSuperview]; + } [view release]; @@ -493,7 +485,7 @@ public: void toBehind (ComponentPeer* other) override { - if (NSViewComponentPeer* const otherPeer = dynamic_cast (other)) + if (auto* otherPeer = dynamic_cast (other)) { if (isSharedWindow) { @@ -585,8 +577,8 @@ public: sendMouseEvent (ev); else // moved into another window which overlaps this one, so trigger an exit - handleMouseEvent (0, Point (-1.0f, -1.0f), currentModifiers, - getMousePressure (ev), getMouseTime (ev)); + handleMouseEvent (MouseInputSource::InputSourceType::mouse, { -1.0f, -1.0f }, currentModifiers, + getMousePressure (ev), MouseInputSource::invalidOrientation, getMouseTime (ev)); showArrowCursorIfNeeded(); } @@ -651,14 +643,14 @@ public: @catch (...) {} - if (wheel.deltaX == 0 && wheel.deltaY == 0) + if (wheel.deltaX == 0.0f && wheel.deltaY == 0.0f) { const float scale = 10.0f / 256.0f; wheel.deltaX = scale * (float) [ev deltaX]; wheel.deltaY = scale * (float) [ev deltaY]; } - handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), wheel); + handleMouseWheel (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), getMouseTime (ev), wheel); } void redirectMagnify (NSEvent* ev) @@ -667,7 +659,7 @@ public: const float invScale = 1.0f - (float) [ev magnification]; if (invScale > 0.0f) - handleMagnifyGesture (0, getMousePos (ev, view), getMouseTime (ev), 1.0f / invScale); + handleMagnifyGesture (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), getMouseTime (ev), 1.0f / invScale); #endif ignoreUnused (ev); } @@ -679,8 +671,8 @@ public: void redirectWillMoveToWindow (NSWindow* newWindow) { #if JUCE_MODULE_AVAILABLE_juce_opengl - if ([view window] == window && newWindow == nullptr) - componentPeerAboutToBeRemovedFromScreen (*this); + if ([view window] == window) + componentPeerAboutToChange (getComponent(), newWindow == nullptr); #else ignoreUnused (newWindow); #endif @@ -689,8 +681,8 @@ public: void sendMouseEvent (NSEvent* ev) { updateModifiers (ev); - handleMouseEvent (0, getMousePos (ev, view), currentModifiers, - getMousePressure (ev), getMouseTime (ev)); + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), currentModifiers, + getMousePressure (ev), MouseInputSource::invalidOrientation, getMouseTime (ev)); } bool handleKeyEvent (NSEvent* ev, bool isKeyDown) @@ -933,12 +925,12 @@ public: void setNeedsDisplayRectangles() { - for (const Rectangle* i = deferredRepaints.begin(), *e = deferredRepaints.end(); i != e; ++i) - [view setNeedsDisplayInRect: makeNSRect (*i)]; + for (auto& i : deferredRepaints) + [view setNeedsDisplayInRect: makeNSRect (i)]; lastRepaintTime = Time::getMillisecondCounter(); deferredRepaints.clear(); - }; + } void invokePaint (LowLevelGraphicsContext& context) { @@ -962,7 +954,7 @@ public: //============================================================================== bool sendModalInputAttemptIfBlocked() { - if (Component* modal = Component::getCurrentlyModalComponent()) + if (auto* modal = Component::getCurrentlyModalComponent()) { if (insideToFrontCall == 0 && (! getComponent().isParentOf (modal)) @@ -1042,8 +1034,8 @@ public: { const float scale = getComponent().getDesktopScaleFactor(); - Rectangle pos = ScalingHelpers::unscaledScreenPosToScaled (scale, convertToRectInt (flippedScreenRect (r))); - Rectangle original = ScalingHelpers::unscaledScreenPosToScaled (scale, convertToRectInt (flippedScreenRect ([window frame]))); + auto pos = ScalingHelpers::unscaledScreenPosToScaled (scale, convertToRectInt (flippedScreenRect (r))); + auto original = ScalingHelpers::unscaledScreenPosToScaled (scale, convertToRectInt (flippedScreenRect ([window frame]))); const Rectangle screenBounds (Desktop::getInstance().getDisplays().getTotalBounds (true)); @@ -1076,8 +1068,8 @@ public: static void showArrowCursorIfNeeded() { - Desktop& desktop = Desktop::getInstance(); - MouseInputSource mouse = desktop.getMainMouseSource(); + auto& desktop = Desktop::getInstance(); + auto mouse = desktop.getMainMouseSource(); if (mouse.getComponentUnderMouse() == nullptr && desktop.findComponentAt (mouse.getScreenPosition().roundToInt()) == nullptr) @@ -1138,9 +1130,8 @@ public: if (layoutData != nullptr) { - if (const UCKeyboardLayout* layoutPtr = (const UCKeyboardLayout*) CFDataGetBytePtr (layoutData)) + if (auto* layoutPtr = (const UCKeyboardLayout*) CFDataGetBytePtr (layoutData)) { - UInt32 keysDown = 0; UniChar buffer[4]; UniCharCount actual; @@ -1214,7 +1205,7 @@ public: static Point getMousePos (NSEvent* e, NSView* view) { NSPoint p = [view convertPoint: [e locationInWindow] fromView: nil]; - return Point ((float) p.x, (float) ([view frame].size.height - p.y)); + return { (float) p.x, (float) ([view frame].size.height - p.y) }; } static int getModifierForButtonNumber (const NSInteger num) @@ -1356,13 +1347,18 @@ public: void textInputRequired (Point, TextInputTarget&) override {} //============================================================================== - NSWindow* window; - NSView* view; - bool isSharedWindow, fullScreen; - bool usingCoreGraphics, isZooming, isFirstLiveResize, textWasInserted; - bool isStretchingTop, isStretchingLeft, isStretchingBottom, isStretchingRight; + NSWindow* window = nil; + NSView* view = nil; + bool isSharedWindow = false, fullScreen = false; + #if USE_COREGRAPHICS_RENDERING + bool usingCoreGraphics = true; + #else + bool usingCoreGraphics = false; + #endif + bool isZooming = false, isFirstLiveResize = false, textWasInserted = false; + bool isStretchingTop = false, isStretchingLeft = false, isStretchingBottom = false, isStretchingRight = false; String stringBeingComposed; - NSNotificationCenter* notificationCenter; + NSNotificationCenter* notificationCenter = nil; RectangleList deferredRepaints; uint32 lastRepaintTime; @@ -1466,7 +1462,7 @@ private: for (int i = ComponentPeer::getNumPeers(); --i >= 0;) { - if (NSViewComponentPeer* peer = dynamic_cast (ComponentPeer::getPeer (i))) + if (auto* peer = dynamic_cast (ComponentPeer::getPeer (i))) { if ([peer->view window] == w) { @@ -1603,43 +1599,39 @@ private: waitUntilDone: NO]; } - static void asyncMouseDown (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectMouseDown (ev); } - static void asyncMouseUp (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectMouseUp (ev); } - static void mouseDragged (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectMouseDrag (ev); } - static void mouseMoved (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectMouseMove (ev); } - static void mouseEntered (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectMouseEnter (ev); } - static void mouseExited (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectMouseExit (ev); } - static void scrollWheel (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectMouseWheel (ev); } - static void magnify (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectMagnify (ev); } - static void copy (id self, SEL, NSObject* s) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectCopy (s); } - static void paste (id self, SEL, NSObject* s) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectPaste (s); } - static void cut (id self, SEL, NSObject* s) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectCut (s); } + static void asyncMouseDown (id self, SEL, NSEvent* ev) { if (auto* p = getOwner (self)) p->redirectMouseDown (ev); } + static void asyncMouseUp (id self, SEL, NSEvent* ev) { if (auto* p = getOwner (self)) p->redirectMouseUp (ev); } + static void mouseDragged (id self, SEL, NSEvent* ev) { if (auto* p = getOwner (self)) p->redirectMouseDrag (ev); } + static void mouseMoved (id self, SEL, NSEvent* ev) { if (auto* p = getOwner (self)) p->redirectMouseMove (ev); } + static void mouseEntered (id self, SEL, NSEvent* ev) { if (auto* p = getOwner (self)) p->redirectMouseEnter (ev); } + static void mouseExited (id self, SEL, NSEvent* ev) { if (auto* p = getOwner (self)) p->redirectMouseExit (ev); } + static void scrollWheel (id self, SEL, NSEvent* ev) { if (auto* p = getOwner (self)) p->redirectMouseWheel (ev); } + static void magnify (id self, SEL, NSEvent* ev) { if (auto* p = getOwner (self)) p->redirectMagnify (ev); } + static void copy (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectCopy (s); } + static void paste (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectPaste (s); } + static void cut (id self, SEL, NSObject* s) { if (auto* p = getOwner (self)) p->redirectCut (s); } + static void willMoveToWindow (id self, SEL, NSWindow* w) { if (auto* p = getOwner (self)) p->redirectWillMoveToWindow (w); } - static void willMoveToWindow (id self, SEL, NSWindow* window) - { - if (NSViewComponentPeer* p = getOwner (self)) p->redirectWillMoveToWindow (window); - } - - static BOOL acceptsFirstMouse (id, SEL, NSEvent*) { return YES; } - static BOOL wantsDefaultClipping (id, SEL) { return YES; } // (this is the default, but may want to customise it in future) - static BOOL worksWhenModal (id self, SEL) { if (NSViewComponentPeer* p = getOwner (self)) return p->worksWhenModal(); return NO; }; + static BOOL acceptsFirstMouse (id, SEL, NSEvent*) { return YES; } + static BOOL wantsDefaultClipping (id, SEL) { return YES; } // (this is the default, but may want to customise it in future) + static BOOL worksWhenModal (id self, SEL) { if (auto* p = getOwner (self)) return p->worksWhenModal(); return NO; } - static void drawRect (id self, SEL, NSRect r) { if (NSViewComponentPeer* p = getOwner (self)) p->drawRect (r); } - static void frameChanged (id self, SEL, NSNotification*) { if (NSViewComponentPeer* p = getOwner (self)) p->redirectMovedOrResized(); } - static void viewDidMoveToWindow (id self, SEL) { if (NSViewComponentPeer* p = getOwner (self)) p->viewMovedToWindow(); } + static void drawRect (id self, SEL, NSRect r) { if (auto* p = getOwner (self)) p->drawRect (r); } + static void frameChanged (id self, SEL, NSNotification*) { if (auto* p = getOwner (self)) p->redirectMovedOrResized(); } + static void viewDidMoveToWindow (id self, SEL) { if (auto* p = getOwner (self)) p->viewMovedToWindow(); } static BOOL isOpaque (id self, SEL) { - NSViewComponentPeer* const owner = getOwner (self); + auto* owner = getOwner (self); return owner == nullptr || owner->getComponent().isOpaque(); } //============================================================================== static void keyDown (id self, SEL, NSEvent* ev) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) { - TextInputTarget* const target = owner->findCurrentTextInputTarget(); + auto* target = owner->findCurrentTextInputTarget(); owner->textWasInserted = false; if (target != nullptr) @@ -1647,7 +1639,7 @@ private: else owner->stringBeingComposed.clear(); - if ((! owner->textWasInserted) && (owner == nullptr || ! owner->redirectKeyDown (ev))) + if (! (owner->textWasInserted || owner->redirectKeyDown (ev))) { objc_super s = { self, [NSView class] }; getMsgSendSuperFn() (&s, @selector (keyDown:), ev); @@ -1657,7 +1649,7 @@ private: static void keyUp (id self, SEL, NSEvent* ev) { - NSViewComponentPeer* const owner = getOwner (self); + auto* owner = getOwner (self); if (owner == nullptr || ! owner->redirectKeyUp (ev)) { @@ -1670,13 +1662,13 @@ private: static void insertText (id self, SEL, id aString) { // This commits multi-byte text when return is pressed, or after every keypress for western keyboards - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) { NSString* newText = [aString isKindOfClass: [NSAttributedString class]] ? [aString string] : aString; if ([newText length] > 0) { - if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + if (auto* target = owner->findCurrentTextInputTarget()) { target->insertTextAtCaret (nsStringToJuce (newText)); owner->textWasInserted = true; @@ -1691,14 +1683,14 @@ private: static void setMarkedText (id self, SEL, id aString, NSRange) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) { owner->stringBeingComposed = nsStringToJuce ([aString isKindOfClass: [NSAttributedString class]] ? [aString string] : aString); - if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + if (auto* target = owner->findCurrentTextInputTarget()) { - const Range currentHighlight (target->getHighlightedRegion()); + auto currentHighlight = target->getHighlightedRegion(); target->insertTextAtCaret (owner->stringBeingComposed); target->setHighlightedRegion (currentHighlight.withLength (owner->stringBeingComposed.length())); owner->textWasInserted = true; @@ -1708,11 +1700,11 @@ private: static void unmarkText (id self, SEL) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) { if (owner->stringBeingComposed.isNotEmpty()) { - if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + if (auto* target = owner->findCurrentTextInputTarget()) { target->insertTextAtCaret (owner->stringBeingComposed); owner->textWasInserted = true; @@ -1725,7 +1717,7 @@ private: static BOOL hasMarkedText (id self, SEL) { - NSViewComponentPeer* const owner = getOwner (self); + auto* owner = getOwner (self); return owner != nullptr && owner->stringBeingComposed.isNotEmpty(); } @@ -1736,9 +1728,9 @@ private: static NSAttributedString* attributedSubstringFromRange (id self, SEL, NSRange theRange) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) { - if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + if (auto* target = owner->findCurrentTextInputTarget()) { const Range r ((int) theRange.location, (int) (theRange.location + theRange.length)); @@ -1752,7 +1744,7 @@ private: static NSRange markedRange (id self, SEL) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) if (owner->stringBeingComposed.isNotEmpty()) return NSMakeRange (0, (NSUInteger) owner->stringBeingComposed.length()); @@ -1761,11 +1753,11 @@ private: static NSRange selectedRange (id self, SEL) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) { - if (TextInputTarget* const target = owner->findCurrentTextInputTarget()) + if (auto* target = owner->findCurrentTextInputTarget()) { - const Range highlight (target->getHighlightedRegion()); + auto highlight = target->getHighlightedRegion(); if (! highlight.isEmpty()) return NSMakeRange ((NSUInteger) highlight.getStart(), @@ -1778,8 +1770,8 @@ private: static NSRect firstRectForCharacterRange (id self, SEL, NSRange) { - if (NSViewComponentPeer* const owner = getOwner (self)) - if (Component* const comp = dynamic_cast (owner->findCurrentTextInputTarget())) + if (auto* owner = getOwner (self)) + if (auto* comp = dynamic_cast (owner->findCurrentTextInputTarget())) return flippedScreenRect (makeNSRect (comp->getScreenBounds())); return NSZeroRect; @@ -1791,13 +1783,13 @@ private: //============================================================================== static void flagsChanged (id self, SEL, NSEvent* ev) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) owner->redirectModKeyChange (ev); } static BOOL becomeFirstResponder (id self, SEL) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) owner->viewFocusGain(); return YES; @@ -1805,7 +1797,7 @@ private: static BOOL resignFirstResponder (id self, SEL) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) owner->viewFocusLoss(); return YES; @@ -1813,7 +1805,7 @@ private: static BOOL acceptsFirstResponder (id self, SEL) { - NSViewComponentPeer* const owner = getOwner (self); + auto* owner = getOwner (self); return owner != nullptr && owner->canBecomeKeyWindow(); } @@ -1825,7 +1817,7 @@ private: static NSDragOperation draggingUpdated (id self, SEL, id sender) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) if (owner->sendDragCallback (0, sender)) return NSDragOperationCopy | NSDragOperationMove | NSDragOperationGeneric; @@ -1839,7 +1831,7 @@ private: static void draggingExited (id self, SEL, id sender) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) owner->sendDragCallback (1, sender); } @@ -1850,7 +1842,7 @@ private: static BOOL performDragOperation (id self, SEL, id sender) { - NSViewComponentPeer* const owner = getOwner (self); + auto* owner = getOwner (self); return owner != nullptr && owner->sendDragCallback (2, sender); } @@ -1892,7 +1884,7 @@ private: //============================================================================== static BOOL canBecomeKeyWindow (id self, SEL) { - NSViewComponentPeer* const owner = getOwner (self); + auto* owner = getOwner (self); return owner != nullptr && owner->canBecomeKeyWindow() @@ -1901,7 +1893,7 @@ private: static BOOL canBecomeMainWindow (id self, SEL) { - NSViewComponentPeer* const owner = getOwner (self); + auto* owner = getOwner (self); return owner != nullptr && owner->canBecomeMainWindow() @@ -1912,19 +1904,19 @@ private: { sendSuperclassMessage (self, @selector (becomeKeyWindow)); - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) owner->becomeKeyWindow(); } static BOOL windowShouldClose (id self, SEL, id /*window*/) { - NSViewComponentPeer* const owner = getOwner (self); + auto* owner = getOwner (self); return owner == nullptr || owner->windowShouldClose(); } static NSRect constrainFrameRect (id self, SEL, NSRect frameRect, NSScreen*) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) frameRect = owner->constrainRect (frameRect); return frameRect; @@ -1932,7 +1924,7 @@ private: static NSSize windowWillResize (id self, SEL, NSWindow*, NSSize proposedFrameSize) { - NSViewComponentPeer* const owner = getOwner (self); + auto* owner = getOwner (self); if (owner == nullptr || owner->isZooming) return proposedFrameSize; @@ -1958,7 +1950,7 @@ private: static void zoom (id self, SEL, id sender) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) { owner->isZooming = true; objc_super s = { self, [NSWindow class] }; @@ -1971,20 +1963,20 @@ private: static void windowWillMove (id self, SEL, NSNotification*) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) if (owner->hasNativeTitleBar()) owner->sendModalInputAttemptIfBlocked(); } static void windowWillStartLiveResize (id self, SEL, NSNotification*) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) owner->liveResizingStart(); } static void windowDidEndLiveResize (id self, SEL, NSNotification*) { - if (NSViewComponentPeer* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) owner->liveResizingEnd(); } }; @@ -2046,19 +2038,24 @@ bool MouseInputSource::SourceList::addSource() { if (sources.size() == 0) { - addSource (0, true); + addSource (0, MouseInputSource::InputSourceType::mouse); return true; } return false; } +bool MouseInputSource::SourceList::canUseTouch() +{ + return false; +} + //============================================================================== void Desktop::setKioskComponent (Component* kioskComp, bool shouldBeEnabled, bool allowMenusAndBars) { #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 - NSViewComponentPeer* const peer = dynamic_cast (kioskComp->getPeer()); + auto* peer = dynamic_cast (kioskComp->getPeer()); jassert (peer != nullptr); // (this should have been checked by the caller) #if defined (MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 diff --git a/source/modules/juce_gui_basics/native/juce_mac_Windowing.mm b/source/modules/juce_gui_basics/native/juce_mac_Windowing.mm index ee976540e..3a6e57390 100644 --- a/source/modules/juce_gui_basics/native/juce_mac_Windowing.mm +++ b/source/modules/juce_gui_basics/native/juce_mac_Windowing.mm @@ -2,42 +2,31 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ } // namespace juce -@interface NSDraggingSourceHelper : NSObject -{ -} -@end - -@implementation NSDraggingSourceHelper - --(NSDragOperation) draggingSession: (NSDraggingSession *)session sourceOperationMaskForDraggingContext: (NSDraggingContext)context -{ - juce::ignoreUnused (session, context); - return NSDragOperationCopy; -} - -@end +#include "../../juce_core/native/juce_osx_ObjCHelpers.h" namespace juce { @@ -160,6 +149,15 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy "Yes", "Cancel", "No", callback != nullptr); } +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* /*associatedComponent*/, + ModalComponentManager::Callback* callback) +{ + return OSXMessageBox::show (iconType, title, message, callback, + "Yes", "No", nullptr, callback != nullptr); +} + //============================================================================== static NSRect getDragRect (NSView* view, NSEvent* event) @@ -170,10 +168,13 @@ static NSRect getDragRect (NSView* view, NSEvent* event) fromView: nil]; } -NSView* getNSViewForDragEvent() +NSView* getNSViewForDragEvent (Component* sourceComp) { - if (auto* draggingSource = Desktop::getInstance().getDraggingMouseSource(0)) - if (auto* sourceComp = draggingSource->getComponentUnderMouse()) + if (sourceComp == nullptr) + if (auto* draggingSource = Desktop::getInstance().getDraggingMouseSource(0)) + sourceComp = draggingSource->getComponentUnderMouse(); + + if (sourceComp != nullptr) return (NSView*) sourceComp->getWindowHandle(); jassertfalse; // This method must be called in response to a component's mouseDown or mouseDrag event! @@ -212,12 +213,12 @@ private: } }; -bool DragAndDropContainer::performExternalDragDropOfText (const String& text) +bool DragAndDropContainer::performExternalDragDropOfText (const String& text, Component* sourceComponent) { if (text.isEmpty()) return false; - if (auto* view = getNSViewForDragEvent()) + if (auto* view = getNSViewForDragEvent (sourceComponent)) { JUCE_AUTORELEASEPOOL { @@ -250,12 +251,33 @@ bool DragAndDropContainer::performExternalDragDropOfText (const String& text) return false; } -bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, bool /*canMoveFiles*/) +class NSDraggingSourceHelper : public ObjCClass > +{ +public: + NSDraggingSourceHelper() + : ObjCClass > ("JUCENSDraggingSourceHelper_") + { + addMethod (@selector (draggingSession:sourceOperationMaskForDraggingContext:), sourceOperationMaskForDraggingContext, "c@:@@"); + + registerClass(); + } + +private: + static NSDragOperation sourceOperationMaskForDraggingContext (id, SEL, NSDraggingSession*, NSDraggingContext) + { + return NSDragOperationCopy; + } +}; + +static NSDraggingSourceHelper draggingSourceHelper; + +bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, bool /*canMoveFiles*/, + Component* sourceComponent) { if (files.isEmpty()) return false; - if (auto* view = getNSViewForDragEvent()) + if (auto* view = getNSViewForDragEvent (sourceComponent)) { JUCE_AUTORELEASEPOOL { @@ -279,7 +301,7 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi [dragItem release]; } - auto* helper = [[NSDraggingSourceHelper alloc] autorelease]; + auto* helper = [draggingSourceHelper.createInstance() autorelease]; if (! [view beginDraggingSessionWithItems: dragItems event: event diff --git a/source/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp b/source/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp index 0e25ac386..53de33836 100644 --- a/source/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp +++ b/source/modules/juce_gui_basics/native/juce_win32_DragAndDrop.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -25,12 +27,11 @@ namespace DragAndDropHelpers { //============================================================================== - class JuceDropSource : public ComBaseClassHelper + struct JuceDropSource : public ComBaseClassHelper { - public: JuceDropSource() {} - JUCE_COMRESULT QueryContinueDrag (BOOL escapePressed, DWORD keys) + JUCE_COMRESULT QueryContinueDrag (BOOL escapePressed, DWORD keys) override { if (escapePressed) return DRAGDROP_S_CANCEL; @@ -41,35 +42,29 @@ namespace DragAndDropHelpers return S_OK; } - JUCE_COMRESULT GiveFeedback (DWORD) + JUCE_COMRESULT GiveFeedback (DWORD) override { return DRAGDROP_S_USEDEFAULTCURSORS; } }; //============================================================================== - class JuceEnumFormatEtc : public ComBaseClassHelper + struct JuceEnumFormatEtc : public ComBaseClassHelper { - public: - JuceEnumFormatEtc (const FORMATETC* const format_) - : format (format_), - index (0) - { - } + JuceEnumFormatEtc (const FORMATETC* f) : format (f) {} - JUCE_COMRESULT Clone (IEnumFORMATETC** result) + JUCE_COMRESULT Clone (IEnumFORMATETC** result) override { if (result == 0) return E_POINTER; - JuceEnumFormatEtc* const newOne = new JuceEnumFormatEtc (format); + auto newOne = new JuceEnumFormatEtc (format); newOne->index = index; - *result = newOne; return S_OK; } - JUCE_COMRESULT Next (ULONG celt, LPFORMATETC lpFormatEtc, ULONG* pceltFetched) + JUCE_COMRESULT Next (ULONG celt, LPFORMATETC lpFormatEtc, ULONG* pceltFetched) override { if (pceltFetched != nullptr) *pceltFetched = 0; @@ -90,7 +85,7 @@ namespace DragAndDropHelpers return S_FALSE; } - JUCE_COMRESULT Skip (ULONG celt) + JUCE_COMRESULT Skip (ULONG celt) override { if (index + (int) celt >= 1) return S_FALSE; @@ -99,7 +94,7 @@ namespace DragAndDropHelpers return S_OK; } - JUCE_COMRESULT Reset() + JUCE_COMRESULT Reset() override { index = 0; return S_OK; @@ -107,7 +102,7 @@ namespace DragAndDropHelpers private: const FORMATETC* const format; - int index; + int index = 0; static void copyFormatEtc (FORMATETC& dest, const FORMATETC& source) { @@ -127,12 +122,8 @@ namespace DragAndDropHelpers class JuceDataObject : public ComBaseClassHelper { public: - JuceDataObject (JuceDropSource* const dropSource_, - const FORMATETC* const format_, - const STGMEDIUM* const medium_) - : dropSource (dropSource_), - format (format_), - medium (medium_) + JuceDataObject (JuceDropSource* s, const FORMATETC* f, const STGMEDIUM* m) + : dropSource (s), format (f), medium (m) { } @@ -152,7 +143,7 @@ namespace DragAndDropHelpers if (format->tymed == TYMED_HGLOBAL) { - const SIZE_T len = GlobalSize (medium->hGlobal); + auto len = GlobalSize (medium->hGlobal); void* const src = GlobalLock (medium->hGlobal); void* const dst = GlobalAlloc (GMEM_FIXED, len); @@ -227,15 +218,15 @@ namespace DragAndDropHelpers if (hDrop != 0) { - LPDROPFILES pDropFiles = (LPDROPFILES) GlobalLock (hDrop); + auto pDropFiles = (LPDROPFILES) GlobalLock (hDrop); pDropFiles->pFiles = sizeof (DROPFILES); pDropFiles->fWide = true; - WCHAR* fname = reinterpret_cast (addBytesToPointer (pDropFiles, sizeof (DROPFILES))); + auto* fname = reinterpret_cast (addBytesToPointer (pDropFiles, sizeof (DROPFILES))); for (int i = 0; i < fileNames.size(); ++i) { - const size_t bytesWritten = fileNames[i].copyToUTF16 (fname, 2048); + auto bytesWritten = fileNames[i].copyToUTF16 (fname, 2048); fname = reinterpret_cast (addBytesToPointer (fname, bytesWritten)); } @@ -249,11 +240,11 @@ namespace DragAndDropHelpers bool performDragDrop (FORMATETC* const format, STGMEDIUM* const medium, const DWORD whatToDo) { - JuceDropSource* const source = new JuceDropSource(); - JuceDataObject* const data = new JuceDataObject (source, format, medium); + auto source = new JuceDropSource(); + auto data = new JuceDataObject (source, format, medium); DWORD effect; - const HRESULT res = DoDragDrop (data, source, whatToDo, &effect); + auto res = DoDragDrop (data, source, whatToDo, &effect); data->Release(); source->Release(); @@ -263,7 +254,7 @@ namespace DragAndDropHelpers } //============================================================================== -bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMove) +bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMove, Component*) { FORMATETC format = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 }; @@ -274,12 +265,12 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi : (DWORD) DROPEFFECT_COPY); } -bool DragAndDropContainer::performExternalDragDropOfText (const String& text) +bool DragAndDropContainer::performExternalDragDropOfText (const String& text, Component*) { FORMATETC format = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM medium = { TYMED_HGLOBAL, { 0 }, 0 }; - const size_t numBytes = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer()); + auto numBytes = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer()); medium.hGlobal = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, numBytes + 2); WCHAR* const data = static_cast (GlobalLock (medium.hGlobal)); diff --git a/source/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp b/source/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp index 83b62df7a..728a4c6d3 100644 --- a/source/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp +++ b/source/modules/juce_gui_basics/native/juce_win32_FileChooser.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -159,14 +161,17 @@ void FileChooser::showPlatformDialog (Array& results, const String& title_ if (extraInfoComponent == nullptr) parentWindow.enterModalState(); - if (currentFileOrDirectory.isDirectory()) + auto parentDirectory = currentFileOrDirectory.getParentDirectory(); + + // Handle nonexistent root directories in the same way as existing ones + if (currentFileOrDirectory.isDirectory() || currentFileOrDirectory.isRoot()) { info.initialPath = currentFileOrDirectory.getFullPathName(); } else { currentFileOrDirectory.getFileName().copyToUTF16 (files, charsAvailableForResult * sizeof (WCHAR)); - info.initialPath = currentFileOrDirectory.getParentDirectory().getFullPathName(); + info.initialPath = parentDirectory.getFullPathName(); } if (selectsDirectory) @@ -216,7 +221,7 @@ void FileChooser::showPlatformDialog (Array& results, const String& title_ flags |= OFN_ENABLEHOOK; info.customComponent = new CustomComponentHolder (extraInfoComponent); - info.customComponent->enterModalState(); + info.customComponent->enterModalState (false); } const size_t filterSpaceNumChars = 2048; diff --git a/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 6963eb552..569c40013 100644 --- a/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -55,54 +57,136 @@ static bool shouldDeactivateTitleBar = true; extern void* getUser32Function (const char*); //============================================================================== -typedef BOOL (WINAPI* UpdateLayeredWinFunc) (HWND, HDC, POINT*, SIZE*, HDC, POINT*, COLORREF, BLENDFUNCTION*, DWORD); -static UpdateLayeredWinFunc updateLayeredWindow = nullptr; +#ifndef WM_NCPOINTERUPDATE + enum + { + WM_NCPOINTERUPDATE = 0x241, + WM_NCPOINTERDOWN = 0x242, + WM_NCPOINTERUP = 0x243, + WM_POINTERUPDATE = 0x245, + WM_POINTERDOWN = 0x246, + WM_POINTERUP = 0x247, + WM_POINTERENTER = 0x249, + WM_POINTERLEAVE = 0x24A, + WM_POINTERACTIVATE = 0x24B, + WM_POINTERCAPTURECHANGED = 0x24C, + WM_TOUCHHITTESTING = 0x24D, + WM_POINTERWHEEL = 0x24E, + WM_POINTERHWHEEL = 0x24F, + WM_POINTERHITTEST = 0x250 + }; -bool Desktop::canUseSemiTransparentWindows() noexcept -{ - if (updateLayeredWindow == nullptr && ! juce_isRunningInWine()) - updateLayeredWindow = (UpdateLayeredWinFunc) getUser32Function ("UpdateLayeredWindow"); + enum + { + PT_TOUCH = 0x00000002, + PT_PEN = 0x00000003 + }; - return updateLayeredWindow != nullptr; -} + enum POINTER_BUTTON_CHANGE_TYPE + { + POINTER_CHANGE_NONE, + POINTER_CHANGE_FIRSTBUTTON_DOWN, + POINTER_CHANGE_FIRSTBUTTON_UP, + POINTER_CHANGE_SECONDBUTTON_DOWN, + POINTER_CHANGE_SECONDBUTTON_UP, + POINTER_CHANGE_THIRDBUTTON_DOWN, + POINTER_CHANGE_THIRDBUTTON_UP, + POINTER_CHANGE_FOURTHBUTTON_DOWN, + POINTER_CHANGE_FOURTHBUTTON_UP, + POINTER_CHANGE_FIFTHBUTTON_DOWN, + POINTER_CHANGE_FIFTHBUTTON_UP + }; -//============================================================================== -#ifndef WM_TOUCH - #define WM_TOUCH 0x0240 - #define TOUCHEVENTF_MOVE 0x0001 - #define TOUCHEVENTF_DOWN 0x0002 - #define TOUCHEVENTF_UP 0x0004 - #define TOUCHEVENTF_PRIMARY 0x0010 - DECLARE_HANDLE (HTOUCHINPUT); - DECLARE_HANDLE (HGESTUREINFO); - - struct TOUCHINPUT + enum + { + PEN_MASK_NONE = 0x00000000, + PEN_MASK_PRESSURE = 0x00000001, + PEN_MASK_ROTATION = 0x00000002, + PEN_MASK_TILT_X = 0x00000004, + PEN_MASK_TILT_Y = 0x00000008 + }; + + enum + { + TOUCH_MASK_NONE = 0x00000000, + TOUCH_MASK_CONTACTAREA = 0x00000001, + TOUCH_MASK_ORIENTATION = 0x00000002, + TOUCH_MASK_PRESSURE = 0x00000004 + }; + + enum + { + POINTER_FLAG_NONE = 0x00000000, + POINTER_FLAG_NEW = 0x00000001, + POINTER_FLAG_INRANGE = 0x00000002, + POINTER_FLAG_INCONTACT = 0x00000004, + POINTER_FLAG_FIRSTBUTTON = 0x00000010, + POINTER_FLAG_SECONDBUTTON = 0x00000020, + POINTER_FLAG_THIRDBUTTON = 0x00000040, + POINTER_FLAG_FOURTHBUTTON = 0x00000080, + POINTER_FLAG_FIFTHBUTTON = 0x00000100, + POINTER_FLAG_PRIMARY = 0x00002000, + POINTER_FLAG_CONFIDENCE = 0x00004000, + POINTER_FLAG_CANCELED = 0x00008000, + POINTER_FLAG_DOWN = 0x00010000, + POINTER_FLAG_UPDATE = 0x00020000, + POINTER_FLAG_UP = 0x00040000, + POINTER_FLAG_WHEEL = 0x00080000, + POINTER_FLAG_HWHEEL = 0x00100000, + POINTER_FLAG_CAPTURECHANGED = 0x00200000, + POINTER_FLAG_HASTRANSFORM = 0x00400000 + }; + + typedef DWORD POINTER_INPUT_TYPE; + typedef UINT32 POINTER_FLAGS; + typedef UINT32 PEN_FLAGS; + typedef UINT32 PEN_MASK; + typedef UINT32 TOUCH_FLAGS; + typedef UINT32 TOUCH_MASK; + + struct POINTER_INFO { - LONG x; - LONG y; - HANDLE hSource; - DWORD dwID; - DWORD dwFlags; - DWORD dwMask; - DWORD dwTime; - ULONG_PTR dwExtraInfo; - DWORD cxContact; - DWORD cyContact; + POINTER_INPUT_TYPE pointerType; + UINT32 pointerId; + UINT32 frameId; + POINTER_FLAGS pointerFlags; + HANDLE sourceDevice; + HWND hwndTarget; + POINT ptPixelLocation; + POINT ptHimetricLocation; + POINT ptPixelLocationRaw; + POINT ptHimetricLocationRaw; + DWORD dwTime; + UINT32 historyCount; + INT32 InputData; + DWORD dwKeyStates; + UINT64 PerformanceCount; + POINTER_BUTTON_CHANGE_TYPE ButtonChangeType; }; - struct GESTUREINFO + struct POINTER_TOUCH_INFO { - UINT cbSize; - DWORD dwFlags; - DWORD dwID; - HWND hwndTarget; - POINTS ptsLocation; - DWORD dwInstanceID; - DWORD dwSequenceID; - ULONGLONG ullArguments; - UINT cbExtraArgs; + POINTER_INFO pointerInfo; + TOUCH_FLAGS touchFlags; + TOUCH_MASK touchMask; + RECT rcContact; + RECT rcContactRaw; + UINT32 orientation; + UINT32 pressure; }; + struct POINTER_PEN_INFO + { + POINTER_INFO pointerInfo; + PEN_FLAGS penFlags; + PEN_MASK penMask; + UINT32 pressure; + UINT32 rotation; + INT32 tiltX; + INT32 tiltY; + }; + + #define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam)) #endif #ifndef MONITOR_DPI_TYPE @@ -155,6 +239,27 @@ static bool canUseMultiTouch() return registerTouchWindow != nullptr; } +typedef BOOL (WINAPI* GetPointerTypeFunc) (UINT32, POINTER_INPUT_TYPE*); +typedef BOOL (WINAPI* GetPointerTouchInfoFunc) (UINT32, POINTER_TOUCH_INFO*); +typedef BOOL (WINAPI* GetPointerPenInfoFunc) (UINT32, POINTER_PEN_INFO*); + +static GetPointerTypeFunc getPointerTypeFunction = nullptr; +static GetPointerTouchInfoFunc getPointerTouchInfo = nullptr; +static GetPointerPenInfoFunc getPointerPenInfo = nullptr; + +static bool canUsePointerAPI = false; + +static void checkForPointerAPI() +{ + getPointerTypeFunction = (GetPointerTypeFunc) getUser32Function ("GetPointerType"); + getPointerTouchInfo = (GetPointerTouchInfoFunc) getUser32Function ("GetPointerTouchInfo"); + getPointerPenInfo = (GetPointerPenInfoFunc) getUser32Function ("GetPointerPenInfo"); + + canUsePointerAPI = (getPointerTypeFunction != nullptr + && getPointerTouchInfo != nullptr + && getPointerPenInfo != nullptr); +} + static Rectangle rectangleFromRECT (const RECT& r) noexcept { return Rectangle::leftTopRightBottom ((int) r.left, (int) r.top, (int) r.right, (int) r.bottom); @@ -227,6 +332,8 @@ double Desktop::getDefaultMasterScale() : 1.0; } +bool Desktop::canUseSemiTransparentWindows() noexcept { return true; } + //============================================================================== Desktop::DisplayOrientation Desktop::getCurrentOrientation() const { @@ -387,7 +494,7 @@ public: ImagePixelData::Ptr clone() override { - WindowsBitmapImage* im = new WindowsBitmapImage (pixelFormat, width, height, false); + auto im = new WindowsBitmapImage (pixelFormat, width, height, false); for (int i = 0; i < height; ++i) memcpy (im->imageData + i * lineStride, imageData + i * lineStride, (size_t) lineStride); @@ -395,15 +502,13 @@ public: return im; } - void blitToWindow (HWND hwnd, HDC dc, const bool transparent, - const int x, const int y, - const uint8 updateLayeredWindowAlpha) noexcept + void blitToWindow (HWND hwnd, HDC dc, bool transparent, int x, int y, uint8 updateLayeredWindowAlpha) noexcept { SetMapMode (dc, MM_TEXT); if (transparent) { - RECT windowBounds = getWindowRect (hwnd); + auto windowBounds = getWindowRect (hwnd); POINT p = { -x, -y }; POINT pos = { windowBounds.left, windowBounds.top }; @@ -416,7 +521,7 @@ public: bf.BlendOp = AC_SRC_OVER; bf.SourceConstantAlpha = updateLayeredWindowAlpha; - updateLayeredWindow (hwnd, 0, &pos, &size, hdc, &p, 0, &bf, 2 /*ULW_ALPHA*/); + UpdateLayeredWindow (hwnd, 0, &pos, &size, hdc, &p, 0, &bf, 2 /*ULW_ALPHA*/); } else { @@ -439,8 +544,8 @@ public: private: static bool isGraphicsCard32Bit() { - HDC dc = GetDC (0); - const int bitsPerPixel = GetDeviceCaps (dc, BITSPIXEL); + auto dc = GetDC (0); + auto bitsPerPixel = GetDeviceCaps (dc, BITSPIXEL); ReleaseDC (0, dc); return bitsPerPixel > 24; } @@ -451,13 +556,13 @@ private: //============================================================================== Image createSnapshotOfNativeWindow (void* nativeWindowHandle) { - HWND hwnd = (HWND) nativeWindowHandle; + auto hwnd = (HWND) nativeWindowHandle; - RECT r = getWindowRect (hwnd); + auto r = getWindowRect (hwnd); const int w = r.right - r.left; const int h = r.bottom - r.top; - WindowsBitmapImage* nativeBitmap = new WindowsBitmapImage (Image::RGB, w, h, true); + auto nativeBitmap = new WindowsBitmapImage (Image::RGB, w, h, true); Image bitmap (nativeBitmap); HDC dc = GetDC (hwnd); @@ -481,8 +586,8 @@ namespace IconConverters if (GetObject (bitmap, sizeof (BITMAP), &bm) && bm.bmWidth > 0 && bm.bmHeight > 0) { - HDC tempDC = GetDC (0); - HDC dc = CreateCompatibleDC (tempDC); + auto tempDC = GetDC (0); + auto dc = CreateCompatibleDC (tempDC); ReleaseDC (0, tempDC); SelectObject (dc, bitmap); @@ -494,7 +599,7 @@ namespace IconConverters { for (int x = bm.bmWidth; --x >= 0;) { - COLORREF col = GetPixel (dc, x, y); + auto col = GetPixel (dc, x, y); imageData.setPixelColour (x, y, Colour ((uint8) GetRValue (col), (uint8) GetGValue (col), @@ -515,8 +620,8 @@ namespace IconConverters if (GetIconInfo (icon, &info)) { - Image mask (createImageFromHBITMAP (info.hbmMask)); - Image image (createImageFromHBITMAP (info.hbmColor)); + auto mask = createImageFromHBITMAP (info.hbmMask); + auto image = createImageFromHBITMAP (info.hbmColor); if (mask.isValid() && image.isValid()) { @@ -524,7 +629,7 @@ namespace IconConverters { for (int x = image.getWidth(); --x >= 0;) { - const float brightness = mask.getPixelAt (x, y).getBrightness(); + auto brightness = mask.getPixelAt (x, y).getBrightness(); if (brightness > 0.0f) image.multiplyAlphaAt (x, y, 1.0f - brightness); @@ -540,7 +645,7 @@ namespace IconConverters HICON createHICONFromImage (const Image& image, const BOOL isIcon, int hotspotX, int hotspotY) { - WindowsBitmapImage* nativeBitmap = new WindowsBitmapImage (Image::ARGB, image.getWidth(), image.getHeight(), true); + auto nativeBitmap = new WindowsBitmapImage (Image::ARGB, image.getWidth(), image.getHeight(), true); Image bitmap (nativeBitmap); { @@ -548,7 +653,7 @@ namespace IconConverters g.drawImageAt (image, 0, 0); } - HBITMAP mask = CreateBitmap (image.getWidth(), image.getHeight(), 1, 1, 0); + auto mask = CreateBitmap (image.getWidth(), image.getHeight(), 1, 1, 0); ICONINFO info; info.fIcon = isIcon; @@ -557,44 +662,23 @@ namespace IconConverters info.hbmMask = mask; info.hbmColor = nativeBitmap->hBitmap; - HICON hi = CreateIconIndirect (&info); + auto hi = CreateIconIndirect (&info); DeleteObject (mask); return hi; } } //============================================================================== -class -#if (! JUCE_MINGW) - __declspec (uuid ("37c994e7-432b-4834-a2f7-dce1f13b834b")) -#endif - ITipInvocation : public IUnknown +JUCE_COMCLASS (ITipInvocation, "37c994e7-432b-4834-a2f7-dce1f13b834b") : public IUnknown { -public: - static const CLSID clsid; + static CLSID getCLSID() noexcept { return { 0x4ce576fa, 0x83dc, 0x4f88, { 0x95, 0x1c, 0x9d, 0x07, 0x82, 0xb4, 0xe3, 0x76 } }; } - virtual ::HRESULT STDMETHODCALLTYPE Toggle (::HWND wnd) = 0; + virtual HRESULT STDMETHODCALLTYPE Toggle (HWND) = 0; }; -#if JUCE_MINGW || (! (defined (_MSC_VER) || defined (__uuidof))) -template <> -struct UUIDGetter +struct OnScreenKeyboard : public DeletedAtShutdown, + private Timer { - static CLSID get() - { - GUID g = {0x37c994e7, 0x432b, 0x4834, {0xa2, 0xf7, 0xdc, 0xe1, 0xf1, 0x3b, 0x83, 0x4b}}; - return g; - } -}; -#endif - -const CLSID ITipInvocation::clsid = {0x4CE576FA, 0x83DC, 0x4f88, {0x95, 0x1C, 0x9D, 0x07, 0x82, 0xB4, 0xE3, 0x76}}; -//============================================================================== -class OnScreenKeyboard : public DeletedAtShutdown, - private Timer -{ -public: - void activate() { shouldBeActive = true; @@ -610,59 +694,83 @@ public: juce_DeclareSingleton_SingleThreaded (OnScreenKeyboard, true) private: - OnScreenKeyboard() - : shouldBeActive (false), reentrant (false) { - tipInvocation.CoCreateInstance (ITipInvocation::clsid, CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER); + tipInvocation.CoCreateInstance (ITipInvocation::getCLSID(), CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER); } void timerCallback() override { stopTimer(); - if (reentrant || tipInvocation == nullptr) return; + if (reentrant || tipInvocation == nullptr) + return; + const ScopedValueSetter setter (reentrant, true, false); const bool isActive = isVisible(); - if (isActive == shouldBeActive) return; - if (! isActive) + if (isActive != shouldBeActive) { - tipInvocation->Toggle(::GetDesktopWindow()); - } - else - { - ::HWND hwnd = ::FindWindow (L"IPTip_Main_Window", NULL); - - if (hwnd != nullptr) - ::PostMessage(hwnd, WM_SYSCOMMAND, (int) SC_CLOSE, 0); + if (! isActive) + { + tipInvocation->Toggle (GetDesktopWindow()); + } + else + { + if (auto hwnd = FindWindow (L"IPTip_Main_Window", NULL)) + PostMessage (hwnd, WM_SYSCOMMAND, (int) SC_CLOSE, 0); + } } } bool isVisible() { - ::HWND hwnd = ::FindWindow (L"IPTip_Main_Window", NULL); - if (hwnd != nullptr) + if (auto hwnd = FindWindow (L"IPTip_Main_Window", NULL)) { - ::LONG style = ::GetWindowLong (hwnd, GWL_STYLE); - return ((style & WS_DISABLED) == 0 && (style & WS_VISIBLE) != 0); + auto style = GetWindowLong (hwnd, GWL_STYLE); + return (style & WS_DISABLED) == 0 && (style & WS_VISIBLE) != 0; } return false; } - bool shouldBeActive, reentrant; + bool shouldBeActive = false, reentrant = false; ComSmartPtr tipInvocation; }; juce_ImplementSingleton_SingleThreaded (OnScreenKeyboard) -#if 0 //============================================================================== -class UWPUIViewSettings +struct HSTRING_PRIVATE; +typedef HSTRING_PRIVATE* HSTRING; + +struct IInspectable : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE GetIids (ULONG* ,IID**) = 0; + virtual HRESULT STDMETHODCALLTYPE GetRuntimeClassName (HSTRING*) = 0; + virtual HRESULT STDMETHODCALLTYPE GetTrustLevel (void*) = 0; +}; + +JUCE_COMCLASS (IUIViewSettingsInterop, "3694dbf9-8f68-44be-8ff5-195c98ede8a6") : public IInspectable +{ + virtual HRESULT STDMETHODCALLTYPE GetForWindow (HWND, REFIID, void**) = 0; +}; + +JUCE_COMCLASS (IUIViewSettings, "c63657f6-8850-470d-88f8-455e16ea2c26") : public IInspectable +{ + enum UserInteractionMode + { + Mouse = 0, + Touch = 1 + }; + + virtual HRESULT STDMETHODCALLTYPE GetUserInteractionMode (UserInteractionMode*) = 0; +}; + + +struct UWPUIViewSettings { -public: UWPUIViewSettings() { ComBaseModule dll (L"api-ms-win-core-winrt-l1-1-0"); @@ -675,21 +783,23 @@ public: deleteHString = (WindowsDeleteStringFuncPtr) ::GetProcAddress (dll.h, "WindowsDeleteString"); if (roInitialize == nullptr || roGetActivationFactory == nullptr - || createHString == nullptr || deleteHString == nullptr) + || createHString == nullptr || deleteHString == nullptr) return; - ::HRESULT status = roInitialize (1); - if (status != S_OK && status != S_FALSE && status != 0x80010106L) + auto status = roInitialize (1); + + if (status != S_OK && status != S_FALSE && (unsigned) status != 0x80010106L) return; LPCWSTR uwpClassName = L"Windows.UI.ViewManagement.UIViewSettings"; HSTRING uwpClassId; if (createHString (uwpClassName, (::UINT32) wcslen (uwpClassName), &uwpClassId) != S_OK - || uwpClassId == nullptr) + || uwpClassId == nullptr) return; - status = roGetActivationFactory (uwpClassId, __uuidof (IUIViewSettingsInterop), (void**) viewSettingsInterop.resetAndGetPointerAddress()); + status = roGetActivationFactory (uwpClassId, __uuidof (IUIViewSettingsInterop), + (void**) viewSettingsInterop.resetAndGetPointerAddress()); deleteHString (uwpClassId); if (status != S_OK || viewSettingsInterop == nullptr) @@ -706,94 +816,33 @@ public: return false; ComSmartPtr viewSettings; - if (viewSettingsInterop->GetForWindow(hWnd, __uuidof (IUIViewSettings), (void**) viewSettings.resetAndGetPointerAddress()) == S_OK - && viewSettings != nullptr) + + if (viewSettingsInterop->GetForWindow (hWnd, __uuidof (IUIViewSettings), + (void**) viewSettings.resetAndGetPointerAddress()) == S_OK + && viewSettings != nullptr) { IUIViewSettings::UserInteractionMode mode; if (viewSettings->GetUserInteractionMode (&mode) == S_OK) - return (mode == IUIViewSettings::Touch); + return mode == IUIViewSettings::Touch; } return false; } private: - struct HSTRING_PRIVATE; - typedef HSTRING_PRIVATE* HSTRING; - - //============================================================================== - class IInspectable : public IUnknown - { - public: - virtual ::HRESULT STDMETHODCALLTYPE GetIids (ULONG* ,IID**) = 0; - virtual ::HRESULT STDMETHODCALLTYPE GetRuntimeClassName(HSTRING*) = 0; - virtual ::HRESULT STDMETHODCALLTYPE GetTrustLevel(void*) = 0; - }; - - //============================================================================== - class - #if (! JUCE_MINGW) - __declspec (uuid ("3694dbf9-8f68-44be-8ff5-195c98ede8a6")) - #endif - IUIViewSettingsInterop : public IInspectable - { - public: - virtual HRESULT STDMETHODCALLTYPE GetForWindow(HWND hwnd, REFIID riid, void **ppv) = 0; - }; - - #if JUCE_MINGW || (! (defined (_MSC_VER) || defined (__uuidof))) - template <> - struct UUIDGetter - { - static CLSID get() - { - GUID g = {0x3694dbf9, 0x8f68, 0x44be, {0x8f, 0xf5, 0x19, 0x5c, 0x98, 0xed, 0xe8, 0xa6}}; - return g; - } - }; - #endif - - //============================================================================== - class - #if (! JUCE_MINGW) - __declspec (uuid ("C63657F6-8850-470D-88F8-455E16EA2C26")) - #endif - IUIViewSettings : public IInspectable - { - public: - enum UserInteractionMode - { - Mouse = 0, - Touch = 1 - }; - - virtual HRESULT STDMETHODCALLTYPE GetUserInteractionMode (UserInteractionMode *value) = 0; - }; - - #if JUCE_MINGW || (! (defined (_MSC_VER) || defined (__uuidof))) - template <> - struct UUIDGetter - { - static CLSID get() - { - GUID g = {0xC63657F6, 0x8850, 0x470D, {0x88, 0xf8, 0x45, 0x5e, 0x16, 0xea, 0x2c, 0x26}}; - return g; - } - }; - #endif - //============================================================================== struct ComBaseModule { - ::HMODULE h; + ComBaseModule() {} + ComBaseModule (LPCWSTR libraryName) : h (::LoadLibrary (libraryName)) {} + ComBaseModule (ComBaseModule&& o) : h (o.h) { o.h = nullptr; } + ~ComBaseModule() { release(); } - ComBaseModule() : h (nullptr) {} - ComBaseModule(LPCWSTR libraryName) : h (::LoadLibrary (libraryName)) {} - ComBaseModule(ComBaseModule&& o) : h (o.h) { o.h = nullptr; } - ~ComBaseModule() { if (h != nullptr) ::FreeLibrary (h); h = nullptr; } + void release() { if (h != nullptr) ::FreeLibrary (h); h = nullptr; } + ComBaseModule& operator= (ComBaseModule&& o) { release(); h = o.h; o.h = nullptr; return *this; } - ComBaseModule& operator=(ComBaseModule&& o) { h = o.h; o.h = nullptr; return *this; } + HMODULE h = {}; }; typedef HRESULT (WINAPI* RoInitializeFuncPtr) (int); @@ -809,14 +858,13 @@ private: WindowsCreateStringFuncPtr createHString; WindowsDeleteStringFuncPtr deleteHString; }; -#endif //============================================================================== class HWNDComponentPeer : public ComponentPeer, private Timer - #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client - , public ModifierKeyReceiver - #endif + #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client + , public ModifierKeyReceiver + #endif { public: enum RenderingEngineType @@ -830,27 +878,13 @@ public: : ComponentPeer (comp, windowStyleFlags), dontRepaint (nonRepainting), parentToAddTo (parent), - currentRenderingEngine (softwareRenderingEngine), - lastPaintTime (0), - lastMagnifySize (0), - fullScreen (false), - isDragging (false), - isMouseOver (false), - hasCreatedCaret (false), - constrainerIsResizing (false), - currentWindowIcon (0), - dropTarget (nullptr), - updateLayeredWindowAlpha (255) - #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client - , modProvider (nullptr) - #endif + currentRenderingEngine (softwareRenderingEngine) { callFunctionIfNotLocked (&createWindowCallback, this); setTitle (component.getName()); if ((windowStyleFlags & windowHasDropShadow) != 0 - && Desktop::canUseSemiTransparentWindows() && ((! hasTitleBar()) || SystemStats::getOperatingSystemType() < SystemStats::WinVista)) { shadower = component.getLookAndFeel().createDropShadowerForComponent (&component); @@ -878,7 +912,7 @@ public: if (dropTarget != nullptr) { - dropTarget->clear(); + dropTarget->peerIsDeleted = true; dropTarget->Release(); dropTarget = nullptr; } @@ -936,18 +970,18 @@ public: { fullScreen = isNowFullScreen; - Rectangle newBounds (windowBorder.addedTo (bounds)); + auto newBounds = windowBorder.addedTo (bounds); if (isUsingUpdateLayeredWindow()) { - if (HWND parentHwnd = GetParent (hwnd)) + if (auto parentHwnd = GetParent (hwnd)) { - RECT parentRect = getWindowRect (parentHwnd); + auto parentRect = getWindowRect (parentHwnd); newBounds.translate (parentRect.left, parentRect.top); } } - const Rectangle oldBounds (getBounds()); + auto oldBounds = getBounds(); const bool hasMoved = (oldBounds.getPosition() != bounds.getPosition()); const bool hasResized = (oldBounds.getWidth() != bounds.getWidth() || oldBounds.getHeight() != bounds.getHeight()); @@ -967,11 +1001,11 @@ public: Rectangle getBounds() const override { - Rectangle bounds (rectangleFromRECT (getWindowRect (hwnd))); + auto bounds = rectangleFromRECT (getWindowRect (hwnd)); - if (HWND parentH = GetParent (hwnd)) + if (auto parentH = GetParent (hwnd)) { - RECT r = getWindowRect (parentH); + auto r = getWindowRect (parentH); bounds.translate (-r.left, -r.top); } @@ -980,10 +1014,10 @@ public: Point getScreenPosition() const { - RECT r = getWindowRect (hwnd); + auto r = getWindowRect (hwnd); - return Point (r.left + windowBorder.getLeft(), - r.top + windowBorder.getTop()); + return { r.left + windowBorder.getLeft(), + r.top + windowBorder.getTop() }; } Point localToGlobal (Point relativePosition) override { return relativePosition + getScreenPosition().toFloat(); } @@ -991,7 +1025,7 @@ public: void setAlpha (float newAlpha) override { - const uint8 intAlpha = (uint8) jlimit (0, 255, (int) (newAlpha * 255.0f)); + auto intAlpha = (uint8) jlimit (0, 255, (int) (newAlpha * 255.0f)); if (component.isOpaque()) { @@ -1042,7 +1076,7 @@ public: if (! fullScreen) { - const Rectangle boundsCopy (lastNonFullscreenBounds); + auto boundsCopy = lastNonFullscreenBounds; if (hasTitleBar()) ShowWindow (hwnd, SW_SHOWNORMAL); @@ -1080,7 +1114,7 @@ public: bool contains (Point localPos, bool trueIfInAChildWindow) const override { - RECT r = getWindowRect (hwnd); + auto r = getWindowRect (hwnd); if (! (isPositiveAndBelow (localPos.x, (int) (r.right - r.left)) && isPositiveAndBelow (localPos.y, (int) (r.bottom - r.top)))) @@ -1133,7 +1167,7 @@ public: void toBehind (ComponentPeer* other) override { - if (HWNDComponentPeer* const otherPeer = dynamic_cast (other)) + if (auto* otherPeer = dynamic_cast (other)) { setMinimised (false); @@ -1176,20 +1210,16 @@ public: ShowCaret (hwnd); SetCaretPos (0, 0); - #if 0 if (uwpViewSettings.isTabletModeActivatedForWindow (hwnd)) OnScreenKeyboard::getInstance()->activate(); - #endif } void dismissPendingTextInput() override { imeHandler.handleSetContext (hwnd, false); - #if 0 if (uwpViewSettings.isTabletModeActivatedForWindow (hwnd)) OnScreenKeyboard::getInstance()->deactivate(); - #endif } void repaint (const Rectangle& area) override @@ -1263,102 +1293,84 @@ public: static ModifierKeys modifiersAtLastCallback; //============================================================================== - class JuceDropTarget : public ComBaseClassHelper + struct FileDropTarget : public ComBaseClassHelper { - public: - JuceDropTarget (HWNDComponentPeer& p) : ownerInfo (new OwnerInfo (p)) {} - - void clear() - { - ownerInfo = nullptr; - } + FileDropTarget (HWNDComponentPeer& p) : peer (p) {} - JUCE_COMRESULT DragEnter (IDataObject* pDataObject, DWORD grfKeyState, POINTL mousePos, DWORD* pdwEffect) + JUCE_COMRESULT DragEnter (IDataObject* pDataObject, DWORD grfKeyState, POINTL mousePos, DWORD* pdwEffect) override { - HRESULT hr = updateFileList (pDataObject); + auto hr = updateFileList (pDataObject); if (FAILED (hr)) return hr; return DragOver (grfKeyState, mousePos, pdwEffect); } - JUCE_COMRESULT DragLeave() + JUCE_COMRESULT DragLeave() override { - if (ownerInfo == nullptr) + if (peerIsDeleted) return S_FALSE; - ownerInfo->owner.handleDragExit (ownerInfo->dragInfo); + peer.handleDragExit (dragInfo); return S_OK; } - JUCE_COMRESULT DragOver (DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect) + JUCE_COMRESULT DragOver (DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect) override { - if (ownerInfo == nullptr) + if (peerIsDeleted) return S_FALSE; - ownerInfo->dragInfo.position = ownerInfo->getMousePos (mousePos).roundToInt(); - const bool wasWanted = ownerInfo->owner.handleDragMove (ownerInfo->dragInfo); - *pdwEffect = wasWanted ? (DWORD) DROPEFFECT_COPY : (DWORD) DROPEFFECT_NONE; + dragInfo.position = getMousePos (mousePos).roundToInt(); + *pdwEffect = peer.handleDragMove (dragInfo) ? (DWORD) DROPEFFECT_COPY + : (DWORD) DROPEFFECT_NONE; return S_OK; } - JUCE_COMRESULT Drop (IDataObject* pDataObject, DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect) + JUCE_COMRESULT Drop (IDataObject* pDataObject, DWORD /*grfKeyState*/, POINTL mousePos, DWORD* pdwEffect) override { HRESULT hr = updateFileList (pDataObject); - if (SUCCEEDED (hr)) - { - ownerInfo->dragInfo.position = ownerInfo->getMousePos (mousePos).roundToInt(); - const bool wasWanted = ownerInfo->owner.handleDragDrop (ownerInfo->dragInfo); - *pdwEffect = wasWanted ? (DWORD) DROPEFFECT_COPY : (DWORD) DROPEFFECT_NONE; - hr = S_OK; - } + if (FAILED (hr)) + return hr; - return hr; + dragInfo.position = getMousePos (mousePos).roundToInt(); + *pdwEffect = peer.handleDragDrop (dragInfo) ? (DWORD) DROPEFFECT_COPY + : (DWORD) DROPEFFECT_NONE; + return S_OK; } + HWNDComponentPeer& peer; + ComponentPeer::DragInfo dragInfo; + bool peerIsDeleted = false; + private: - struct OwnerInfo + Point getMousePos (POINTL mousePos) const { - OwnerInfo (HWNDComponentPeer& p) : owner (p) {} - - Point getMousePos (const POINTL& mousePos) const - { - return owner.globalToLocal (ScalingHelpers::unscaledScreenPosToScaled (owner.getComponent().getDesktopScaleFactor(), - Point (static_cast (mousePos.x), - static_cast (mousePos.y)))); - } + auto& comp = peer.getComponent(); + return comp.getLocalPoint (nullptr, ScalingHelpers::unscaledScreenPosToScaled (comp.getDesktopScaleFactor(), + Point (static_cast (mousePos.x), + static_cast (mousePos.y)))); + } - template - void parseFileList (const CharType* names, const SIZE_T totalLen) + template + void parseFileList (const CharType* names, const SIZE_T totalLen) + { + for (unsigned int i = 0;;) { - unsigned int i = 0; - - for (;;) - { - unsigned int len = 0; - while (i + len < totalLen && names [i + len] != 0) - ++len; + unsigned int len = 0; + while (i + len < totalLen && names [i + len] != 0) + ++len; - if (len == 0) - break; + if (len == 0) + break; - dragInfo.files.add (String (names + i, len)); - i += len + 1; - } + dragInfo.files.add (String (names + i, len)); + i += len + 1; } - - HWNDComponentPeer& owner; - ComponentPeer::DragInfo dragInfo; - - JUCE_DECLARE_NON_COPYABLE (OwnerInfo) - }; - - ScopedPointer ownerInfo; + } struct DroppedData { - DroppedData (IDataObject* const dataObject, const CLIPFORMAT type) - : data (nullptr) + DroppedData (IDataObject* dataObject, CLIPFORMAT type) { FORMATETC format = { type, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM resetMedium = { TYMED_HGLOBAL, { 0 }, 0 }; @@ -1379,16 +1391,16 @@ public: HRESULT error; STGMEDIUM medium; - void* data; + void* data = {}; SIZE_T dataSize; }; HRESULT updateFileList (IDataObject* const dataObject) { - if (ownerInfo == nullptr) + if (peerIsDeleted) return S_FALSE; - ownerInfo->dragInfo.clear(); + dragInfo.clear(); { DroppedData fileData (dataObject, CF_HDROP); @@ -1399,9 +1411,9 @@ public: const void* const names = addBytesToPointer (dropFiles, sizeof (DROPFILES)); if (dropFiles->fWide) - ownerInfo->parseFileList (static_cast (names), fileData.dataSize); + parseFileList (static_cast (names), fileData.dataSize); else - ownerInfo->parseFileList (static_cast (names), fileData.dataSize); + parseFileList (static_cast (names), fileData.dataSize); return S_OK; } @@ -1411,22 +1423,22 @@ public: if (SUCCEEDED (textData.error)) { - ownerInfo->dragInfo.text = String (CharPointer_UTF16 ((const WCHAR*) textData.data), - CharPointer_UTF16 ((const WCHAR*) addBytesToPointer (textData.data, textData.dataSize))); + dragInfo.text = String (CharPointer_UTF16 ((const WCHAR*) textData.data), + CharPointer_UTF16 ((const WCHAR*) addBytesToPointer (textData.data, textData.dataSize))); return S_OK; } return textData.error; } - JUCE_DECLARE_NON_COPYABLE (JuceDropTarget) + JUCE_DECLARE_NON_COPYABLE (FileDropTarget) }; static bool offerKeyMessageToJUCEWindow (MSG& m) { if (m.message == WM_KEYDOWN || m.message == WM_KEYUP) if (Component::getCurrentlyFocusedComponent() != nullptr) - if (HWNDComponentPeer* h = getOwnerOfWindow (m.hwnd)) + if (auto* h = getOwnerOfWindow (m.hwnd)) return m.message == WM_KEYDOWN ? h->doKeyDown (m.wParam) : h->doKeyUp (m.wParam); @@ -1440,30 +1452,29 @@ private: #if JUCE_DIRECT2D ScopedPointer direct2DContext; #endif - uint32 lastPaintTime; - ULONGLONG lastMagnifySize; - bool fullScreen, isDragging, isMouseOver, hasCreatedCaret, constrainerIsResizing; + uint32 lastPaintTime = 0; + ULONGLONG lastMagnifySize = 0; + bool fullScreen = false, isDragging = false, isMouseOver = false, + hasCreatedCaret = false, constrainerIsResizing = false; BorderSize windowBorder; - HICON currentWindowIcon; - JuceDropTarget* dropTarget; - uint8 updateLayeredWindowAlpha; - #if 0 + HICON currentWindowIcon = 0; + FileDropTarget* dropTarget = nullptr; + uint8 updateLayeredWindowAlpha = 255; UWPUIViewSettings uwpViewSettings; - #endif - MultiTouchMapper currentTouches; #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client - ModifierKeyProvider* modProvider; + ModifierKeyProvider* modProvider = nullptr; #endif + static MultiTouchMapper currentTouches; + //============================================================================== - class TemporaryImage : public Timer + struct TemporaryImage : private Timer { - public: TemporaryImage() {} - Image& getImage (const bool transparent, const int w, const int h) + Image& getImage (bool transparent, int w, int h) { - const Image::PixelFormat format = transparent ? Image::ARGB : Image::RGB; + auto format = transparent ? Image::ARGB : Image::RGB; if ((! image.isValid()) || image.getWidth() < w || image.getHeight() < h || image.getFormat() != format) image = Image (new WindowsBitmapImage (format, (w + 31) & ~31, (h + 31) & ~31, false)); @@ -1475,7 +1486,7 @@ private: void timerCallback() override { stopTimer(); - image = Image(); + image = {}; } private: @@ -1497,9 +1508,9 @@ private: String windowClassName ("JUCE_"); windowClassName << String::toHexString (Time::currentTimeMillis()); - HINSTANCE moduleHandle = (HINSTANCE) Process::getCurrentModuleInstanceHandle(); + auto moduleHandle = (HINSTANCE) Process::getCurrentModuleInstanceHandle(); - TCHAR moduleFile [1024] = { 0 }; + TCHAR moduleFile[1024] = { 0 }; GetModuleFileName (moduleHandle, moduleFile, 1024); WORD iconNum = 0; @@ -1538,7 +1549,7 @@ private: static bool isHWNDBlockedByModalComponents (HWND h) { for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) - if (Component* const c = Desktop::getInstance().getComponent (i)) + if (auto* c = Desktop::getInstance().getComponent (i)) if ((! c->isCurrentlyBlockedByAnotherModalComponent()) && IsChild ((HWND) c->getWindowHandle(), h)) return false; @@ -1568,12 +1579,13 @@ private: case WM_NCMOUSEHOVER: case WM_MOUSEHOVER: case WM_TOUCH: - #ifdef WM_POINTERUPDATE case WM_POINTERUPDATE: - case WM_POINTERDOWN: + case WM_NCPOINTERUPDATE: + case WM_POINTERWHEEL: + case WM_POINTERHWHEEL: case WM_POINTERUP: - #endif - return isHWNDBlockedByModalComponents (m.hwnd); + case WM_POINTERACTIVATE: + return isHWNDBlockedByModalComponents(m.hwnd); case WM_NCLBUTTONDOWN: case WM_NCLBUTTONDBLCLK: case WM_NCRBUTTONDOWN: @@ -1588,9 +1600,11 @@ private: case WM_RBUTTONDBLCLK: case WM_KEYDOWN: case WM_SYSKEYDOWN: + case WM_NCPOINTERDOWN: + case WM_POINTERDOWN: if (isHWNDBlockedByModalComponents (m.hwnd)) { - if (Component* const modal = Component::getCurrentlyModalComponent (0)) + if (auto* modal = Component::getCurrentlyModalComponent (0)) modal->inputAttemptWhenModal(); return true; @@ -1653,9 +1667,7 @@ private: if ((styleFlags & windowHasMinimiseButton) != 0) type |= WS_MINIMIZEBOX; if ((styleFlags & windowHasMaximiseButton) != 0) type |= WS_MAXIMIZEBOX; if ((styleFlags & windowIgnoresMouseClicks) != 0) exstyle |= WS_EX_TRANSPARENT; - - if ((styleFlags & windowIsSemiTransparent) != 0 && Desktop::canUseSemiTransparentWindows()) - exstyle |= WS_EX_LAYERED; + if ((styleFlags & windowIsSemiTransparent) != 0) exstyle |= WS_EX_LAYERED; hwnd = CreateWindowEx (exstyle, WindowClassHolder::getInstance()->getWindowClassName(), L"", type, 0, 0, 0, 0, parentToAddTo, 0, @@ -1677,7 +1689,7 @@ private: if (peer == nullptr) peer = this; - dropTarget = new JuceDropTarget (*peer); + dropTarget = new FileDropTarget (*peer); } RegisterDragDrop (hwnd, dropTarget); @@ -1688,12 +1700,13 @@ private: setDPIAwareness(); setMessageFilter(); updateBorderSize(); + checkForPointerAPI(); // Calling this function here is (for some reason) necessary to make Windows // correctly enable the menu items that we specify in the wm_initmenu message. GetSystemMenu (hwnd, false); - const float alpha = component.getAlpha(); + auto alpha = component.getAlpha(); if (alpha < 1.0f) setAlpha (alpha); } @@ -1743,9 +1756,7 @@ private: void setIcon (const Image& newIcon) { - HICON hicon = IconConverters::createHICONFromImage (newIcon, TRUE, 0, 0); - - if (hicon != 0) + if (auto hicon = IconConverters::createHICONFromImage (newIcon, TRUE, 0, 0)) { SendMessage (hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon); SendMessage (hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon); @@ -1761,8 +1772,7 @@ private: { typedef BOOL (WINAPI* ChangeWindowMessageFilterExFunc) (HWND, UINT, DWORD, PVOID); - if (ChangeWindowMessageFilterExFunc changeMessageFilter - = (ChangeWindowMessageFilterExFunc) getUser32Function ("ChangeWindowMessageFilterEx")) + if (auto changeMessageFilter = (ChangeWindowMessageFilterExFunc) getUser32Function ("ChangeWindowMessageFilterEx")) { changeMessageFilter (hwnd, WM_DROPFILES, 1 /*MSGFLT_ALLOW*/, nullptr); changeMessageFilter (hwnd, WM_COPYDATA, 1 /*MSGFLT_ALLOW*/, nullptr); @@ -1783,19 +1793,19 @@ private: { if (IsWindowVisible (hwnd)) { - ChildWindowClippingInfo& info = *(ChildWindowClippingInfo*) context; + auto& info = *(ChildWindowClippingInfo*) context; HWND parent = GetParent (hwnd); if (parent == info.peer->hwnd) { - RECT r = getWindowRect (hwnd); + auto r = getWindowRect (hwnd); POINT pos = { r.left, r.top }; ScreenToClient (GetParent (hwnd), &pos); - Rectangle clip (Rectangle (pos.x, pos.y, - r.right - r.left, - r.bottom - r.top)); + Rectangle clip (pos.x, pos.y, + r.right - r.left, + r.bottom - r.top); info.clip->subtract (clip - info.origin); @@ -1827,33 +1837,35 @@ private: } else #endif + { + HRGN rgn = CreateRectRgn (0, 0, 0, 0); + const int regionType = GetUpdateRgn (hwnd, rgn, false); - HRGN rgn = CreateRectRgn (0, 0, 0, 0); - const int regionType = GetUpdateRgn (hwnd, rgn, false); + PAINTSTRUCT paintStruct; + HDC dc = BeginPaint (hwnd, &paintStruct); // Note this can immediately generate a WM_NCPAINT + // message and become re-entrant, but that's OK - PAINTSTRUCT paintStruct; - HDC dc = BeginPaint (hwnd, &paintStruct); // Note this can immediately generate a WM_NCPAINT - // message and become re-entrant, but that's OK + // if something in a paint handler calls, e.g. a message box, this can become reentrant and + // corrupt the image it's using to paint into, so do a check here. + static bool reentrant = false; + if (! reentrant) + { + const ScopedValueSetter setter (reentrant, true, false); - // if something in a paint handler calls, e.g. a message box, this can become reentrant and - // corrupt the image it's using to paint into, so do a check here. - static bool reentrant = false; - if (! reentrant) - { - const ScopedValueSetter setter (reentrant, true, false); + if (dontRepaint) + component.handleCommandMessage (0); // (this triggers a repaint in the openGL context) + else + performPaint (dc, rgn, regionType, paintStruct); + } - if (dontRepaint) - component.handleCommandMessage (0); // (this triggers a repaint in the openGL context) - else - performPaint (dc, rgn, regionType, paintStruct); - } + DeleteObject (rgn); + EndPaint (hwnd, &paintStruct); - DeleteObject (rgn); - EndPaint (hwnd, &paintStruct); + #if JUCE_MSVC + _fpreset(); // because some graphics cards can unmask FP exceptions + #endif - #if JUCE_MSVC - _fpreset(); // because some graphics cards can unmask FP exceptions - #endif + } lastPaintTime = Time::getMillisecondCounter(); } @@ -1872,7 +1884,7 @@ private: // it's not possible to have a transparent window with a title bar at the moment! jassert (! hasTitleBar()); - RECT r = getWindowRect (hwnd); + auto r = getWindowRect (hwnd); x = y = 0; w = r.right - r.left; h = r.bottom - r.top; @@ -1893,7 +1905,7 @@ private: CombineRgn (rgn, rgn, clipRgn, RGN_AND); DeleteObject (clipRgn); - char rgnData [8192]; + char rgnData[8192]; const DWORD res = GetRegionData (rgn, sizeof (rgnData), (RGNDATA*) rgnData); if (res > 0 && res <= sizeof (rgnData)) @@ -1906,7 +1918,7 @@ private: { needToPaintAll = false; - const RECT* rects = (const RECT*) (rgnData + sizeof (RGNDATAHEADER)); + auto rects = (const RECT*) (rgnData + sizeof (RGNDATAHEADER)); for (int i = (int) ((RGNDATA*) rgnData)->rdh.nCount; --i >= 0;) { @@ -1941,11 +1953,8 @@ private: if (! contextClip.isEmpty()) { if (transparent) - for (const Rectangle* i = contextClip.begin(), * const e = contextClip.end(); i != e; ++i) - offscreenImage.clear (*i); - - // if the component's not opaque, this won't draw properly unless the platform can support this - jassert (Desktop::canUseSemiTransparentWindows() || component.isOpaque()); + for (auto& i : contextClip) + offscreenImage.clear (i); { ScopedPointer context (component.getLookAndFeel() @@ -1963,9 +1972,9 @@ private: } //============================================================================== - void doMouseEvent (Point position, float pressure) + void doMouseEvent (Point position, float pressure, float orientation = 0.0f, ModifierKeys mods = currentModifiers) { - handleMouseEvent (0, position, currentModifiers, pressure, getMouseEventTime()); + handleMouseEvent (MouseInputSource::InputSourceType::mouse, position, mods, pressure, orientation, getMouseEventTime()); } StringArray getAvailableRenderingEngines() override @@ -1986,8 +1995,8 @@ private: void updateDirect2DContext() { if (currentRenderingEngine != direct2DRenderingEngine) - direct2DContext = 0; - else if (direct2DContext == 0) + direct2DContext = nullptr; + else if (direct2DContext == nullptr) direct2DContext = new Direct2DLowLevelGraphicsContext (hwnd); } #endif @@ -2026,10 +2035,22 @@ private: return (GetMessageExtraInfo() & 0xFFFFFF80 /*SIGNATURE_MASK*/) == 0xFF515780 /*MI_WP_SIGNATURE*/; } + static bool areOtherTouchSourcesActive() + { + for (auto& ms : Desktop::getInstance().getMouseSources()) + if (ms.isDragging() && (ms.getType() == MouseInputSource::InputSourceType::touch + || ms.getType() == MouseInputSource::InputSourceType::pen)) + return true; + + return false; + } + void doMouseMove (Point position, bool isMouseDownEvent) { + ModifierKeys modsToSend (currentModifiers); + // this will be handled by WM_TOUCH - if (isTouchEvent()) + if (isTouchEvent() || areOtherTouchSourcesActive()) return; if (! isMouseOver) @@ -2070,17 +2091,21 @@ private: static int minTimeBetweenMouses = getMinTimeBetweenMouseMoves(); const uint32 now = Time::getMillisecondCounter(); + if (! Desktop::getInstance().getMainMouseSource().isDragging()) + modsToSend = modsToSend.withoutMouseButtons(); + if (now >= lastMouseTime + minTimeBetweenMouses) { lastMouseTime = now; - doMouseEvent (position, MouseInputSource::invalidPressure); + doMouseEvent (position, MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, modsToSend); } } void doMouseDown (Point position, const WPARAM wParam) { // this will be handled by WM_TOUCH - if (isTouchEvent()) + if (isTouchEvent() || areOtherTouchSourcesActive()) return; if (GetCapture() != hwnd) @@ -2106,7 +2131,7 @@ private: void doMouseUp (Point position, const WPARAM wParam) { // this will be handled by WM_TOUCH - if (isTouchEvent()) + if (isTouchEvent() || areOtherTouchSourcesActive()) return; updateModifiersFromWParam (wParam); @@ -2146,17 +2171,19 @@ private: void doMouseExit() { isMouseOver = false; - doMouseEvent (getCurrentMousePos(), MouseInputSource::invalidPressure); + + if (! areOtherTouchSourcesActive()) + doMouseEvent (getCurrentMousePos(), MouseInputSource::invalidPressure); } ComponentPeer* findPeerUnderMouse (Point& localPos) { - const Point globalPos (getCurrentMousePosGlobal().roundToInt()); + auto globalPos = getCurrentMousePosGlobal().roundToInt(); // Because Windows stupidly sends all wheel events to the window with the keyboard // focus, we have to redirect them here according to the mouse pos.. POINT p = { globalPos.x, globalPos.y }; - HWNDComponentPeer* peer = getOwnerOfWindow (WindowFromPoint (p)); + auto* peer = getOwnerOfWindow (WindowFromPoint (p)); if (peer == nullptr) peer = this; @@ -2165,6 +2192,25 @@ private: return peer; } + static MouseInputSource::InputSourceType getPointerType (WPARAM wParam) + { + if (getPointerTypeFunction != nullptr) + { + POINTER_INPUT_TYPE pointerType; + + if (getPointerTypeFunction (GET_POINTERID_WPARAM (wParam), &pointerType)) + { + if (pointerType == 2) + return MouseInputSource::InputSourceType::touch; + + if (pointerType == 3) + return MouseInputSource::InputSourceType::pen; + } + } + + return MouseInputSource::InputSourceType::mouse; + } + void doMouseWheel (const WPARAM wParam, const bool isVertical) { updateKeyModifiers(); @@ -2178,8 +2224,8 @@ private: wheel.isInertial = false; Point localPos; - if (ComponentPeer* const peer = findPeerUnderMouse (localPos)) - peer->handleMouseWheel (0, localPos, getMouseEventTime(), wheel); + if (auto* peer = findPeerUnderMouse (localPos)) + peer->handleMouseWheel (getPointerType (wParam), localPos, getMouseEventTime(), wheel); } bool doGestureEvent (LPARAM lParam) @@ -2193,13 +2239,13 @@ private: updateKeyModifiers(); Point localPos; - if (ComponentPeer* const peer = findPeerUnderMouse (localPos)) + if (auto* peer = findPeerUnderMouse (localPos)) { switch (gi.dwID) { case 3: /*GID_ZOOM*/ if (gi.dwFlags != 1 /*GF_BEGIN*/ && lastMagnifySize > 0) - peer->handleMagnifyGesture (0, localPos, getMouseEventTime(), + peer->handleMagnifyGesture (MouseInputSource::InputSourceType::touch, localPos, getMouseEventTime(), (float) (gi.ullArguments / (double) lastMagnifySize)); lastMagnifySize = gi.ullArguments; @@ -2221,7 +2267,7 @@ private: LRESULT doTouchEvent (const int numInputs, HTOUCHINPUT eventHandle) { if ((styleFlags & windowIgnoresMouseClicks) != 0) - if (HWNDComponentPeer* const parent = getOwnerOfWindow (GetParent (hwnd))) + if (auto* parent = getOwnerOfWindow (GetParent (hwnd))) if (parent != this) return parent->doTouchEvent (numInputs, eventHandle); @@ -2231,7 +2277,7 @@ private: { for (int i = 0; i < numInputs; ++i) { - const DWORD flags = inputInfo[i].dwFlags; + auto flags = inputInfo[i].dwFlags; if ((flags & (TOUCHEVENTF_DOWN | TOUCHEVENTF_MOVE | TOUCHEVENTF_UP)) != 0) if (! handleTouchInput (inputInfo[i], (flags & TOUCHEVENTF_DOWN) != 0, (flags & TOUCHEVENTF_UP) != 0)) @@ -2243,16 +2289,17 @@ private: return 0; } - bool handleTouchInput (const TOUCHINPUT& touch, const bool isDown, const bool isUp) + bool handleTouchInput (const TOUCHINPUT& touch, const bool isDown, const bool isUp, + const float touchPressure = MouseInputSource::invalidPressure, + const float orientation = 0.0f) { - bool isCancel = false; + auto isCancel = false; - const int touchIndex = currentTouches.getIndexOfTouch (touch.dwID); - const int64 time = getMouseEventTime(); - const Point pos (globalToLocal (Point (touch.x / 100.0f, - touch.y / 100.0f))); - const float pressure = MouseInputSource::invalidPressure; - ModifierKeys modsToSend (currentModifiers); + const auto touchIndex = currentTouches.getIndexOfTouch (touch.dwID); + const auto time = getMouseEventTime(); + const auto pos = globalToLocal ({ touch.x / 100.0f, touch.y / 100.0f }); + const auto pressure = touchPressure; + auto modsToSend = currentModifiers; if (isDown) { @@ -2260,7 +2307,8 @@ private: modsToSend = currentModifiers; // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. - handleMouseEvent (touchIndex, pos, modsToSend.withoutMouseButtons(), pressure, time); + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend.withoutMouseButtons(), + pressure, orientation, time, {}, touchIndex); if (! isValidPeer (this)) // (in case this component was deleted by the event) return false; @@ -2278,29 +2326,73 @@ private: modsToSend = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); } - if (isCancel) + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend, + pressure, orientation, time, {}, touchIndex); + + if (! isValidPeer (this)) + return false; + + if (isUp) { - currentTouches.clear(); - currentModifiers = currentModifiers.withoutMouseButtons(); + handleMouseEvent (MouseInputSource::InputSourceType::touch, { -10.0f, -10.0f }, currentModifiers.withoutMouseButtons(), + pressure, orientation, time, {}, touchIndex); + + if (! isValidPeer (this)) + return false; + + if (isCancel) + { + currentTouches.clear(); + currentModifiers = currentModifiers.withoutMouseButtons(); + } } - handleMouseEvent (touchIndex, pos, modsToSend, pressure, time); + return true; + } - if (! isValidPeer (this)) // (in case this component was deleted by the event) + bool handlePointerInput (WPARAM wParam, LPARAM lParam, const bool isDown, const bool isUp) + { + if (! canUsePointerAPI) return false; - if (isUp || isCancel) + auto pointerType = getPointerType (wParam); + + if (pointerType == MouseInputSource::InputSourceType::touch) { - handleMouseEvent (touchIndex, Point (-10.0f, -10.0f), currentModifiers, pressure, time); + POINTER_TOUCH_INFO touchInfo; + if (! getPointerTouchInfo (GET_POINTERID_WPARAM (wParam), &touchInfo)) + return false; - if (! isValidPeer (this)) + const auto pressure = touchInfo.touchMask & TOUCH_MASK_PRESSURE ? touchInfo.pressure + : MouseInputSource::invalidPressure; + const auto orientation = touchInfo.touchMask & TOUCH_MASK_ORIENTATION ? degreesToRadians (static_cast (touchInfo.orientation)) + : MouseInputSource::invalidOrientation; + + if (! handleTouchInput (emulateTouchEventFromPointer (lParam, wParam), + isDown, isUp, pressure, orientation)) + return false; + } + else if (pointerType == MouseInputSource::InputSourceType::pen) + { + POINTER_PEN_INFO penInfo; + if (! getPointerPenInfo (GET_POINTERID_WPARAM (wParam), &penInfo)) + return false; + + const auto pressure = (penInfo.penMask & PEN_MASK_PRESSURE) ? penInfo.pressure / 1024.0f : MouseInputSource::invalidPressure; + + if (! handlePenInput (penInfo, globalToLocal (Point (static_cast (GET_X_LPARAM(lParam)), + static_cast (GET_Y_LPARAM(lParam)))), + pressure, isDown, isUp)) return false; } + else + { + return false; + } return true; } - #ifdef WM_POINTERUPDATE TOUCHINPUT emulateTouchEventFromPointer (LPARAM lParam, WPARAM wParam) { TOUCHINPUT touchInput; @@ -2311,7 +2403,57 @@ private: return touchInput; } - #endif + + bool handlePenInput (POINTER_PEN_INFO penInfo, Point pos, const float pressure, bool isDown, bool isUp) + { + const auto time = getMouseEventTime(); + ModifierKeys modsToSend (currentModifiers); + PenDetails penDetails; + + penDetails.rotation = (penInfo.penMask & PEN_MASK_ROTATION) ? degreesToRadians (static_cast (penInfo.rotation)) : MouseInputSource::invalidRotation; + penDetails.tiltX = (penInfo.penMask & PEN_MASK_TILT_X) ? penInfo.tiltX / 90.0f : MouseInputSource::invalidTiltX; + penDetails.tiltY = (penInfo.penMask & PEN_MASK_TILT_Y) ? penInfo.tiltY / 90.0f : MouseInputSource::invalidTiltY; + + auto pInfoFlags = penInfo.pointerInfo.pointerFlags; + + if ((pInfoFlags & POINTER_FLAG_FIRSTBUTTON) != 0) + currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + else if ((pInfoFlags & POINTER_FLAG_SECONDBUTTON) != 0) + currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::rightButtonModifier); + + if (isDown) + { + modsToSend = currentModifiers; + + // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. + handleMouseEvent (MouseInputSource::InputSourceType::pen, pos, modsToSend.withoutMouseButtons(), + pressure, MouseInputSource::invalidOrientation, time, penDetails); + + if (! isValidPeer (this)) // (in case this component was deleted by the event) + return false; + } + else if (isUp || ! (pInfoFlags & POINTER_FLAG_INCONTACT)) + { + modsToSend = modsToSend.withoutMouseButtons(); + } + + handleMouseEvent (MouseInputSource::InputSourceType::pen, pos, modsToSend, pressure, + MouseInputSource::invalidOrientation, time, penDetails); + + if (! isValidPeer (this)) // (in case this component was deleted by the event) + return false; + + if (isUp) + { + handleMouseEvent (MouseInputSource::InputSourceType::pen, { -10.0f, -10.0f }, currentModifiers, + pressure, MouseInputSource::invalidOrientation, time, penDetails); + + if (! isValidPeer (this)) + return false; + } + + return true; + } //============================================================================== void sendModifierKeyChangeIfNeeded() @@ -2530,9 +2672,9 @@ private: { if (isConstrainedNativeWindow()) { - const float scale = getComponent().getDesktopScaleFactor(); - Rectangle pos (ScalingHelpers::unscaledScreenPosToScaled (scale, rectangleFromRECT (r))); - const Rectangle current (getCurrentScaledBounds (scale)); + auto scale = getComponent().getDesktopScaleFactor(); + auto pos = ScalingHelpers::unscaledScreenPosToScaled (scale, rectangleFromRECT (r)); + auto current = getCurrentScaledBounds (scale); constrainer->checkBounds (pos, current, Desktop::getInstance().getDisplays().getTotalBounds (true), @@ -2558,9 +2700,9 @@ private: if ((wp.flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE) && ! Component::isMouseButtonDownAnywhere()) { - const float scale = getComponent().getDesktopScaleFactor(); - Rectangle pos (ScalingHelpers::unscaledScreenPosToScaled (scale, Rectangle (wp.x, wp.y, wp.cx, wp.cy))); - const Rectangle current (getCurrentScaledBounds (scale)); + auto scale = getComponent().getDesktopScaleFactor(); + auto pos = ScalingHelpers::unscaledScreenPosToScaled (scale, Rectangle (wp.x, wp.y, wp.cx, wp.cy)); + auto current = getCurrentScaledBounds (scale); constrainer->checkBounds (pos, current, Desktop::getInstance().getDisplays().getTotalBounds (true), @@ -2587,11 +2729,12 @@ private: bool handlePositionChanged() { - const Point pos (getCurrentMousePos()); + auto pos = getCurrentMousePos(); if (contains (pos.roundToInt(), false)) { - doMouseEvent (pos, MouseInputSource::invalidPressure); + if (! areOtherTouchSourcesActive()) + doMouseEvent (pos, MouseInputSource::invalidPressure); if (! isValidPeer (this)) return true; @@ -2615,7 +2758,7 @@ private: return; } - Component* underMouse = component.getComponentAt (component.getMouseXYRelative()); + auto* underMouse = component.getComponentAt (component.getMouseXYRelative()); if (underMouse == nullptr) underMouse = &component; @@ -2635,7 +2778,7 @@ private: void handlePowerBroadcast (WPARAM wParam) { - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + if (auto* app = JUCEApplicationBase::getInstance()) { switch (wParam) { @@ -2697,14 +2840,13 @@ private: void doSettingChange() { - Desktop& desktop = Desktop::getInstance(); + auto& desktop = Desktop::getInstance(); const_cast (desktop.getDisplays()).refresh(); if (fullScreen && ! isMinimised()) { - const Desktop::Displays::Display& display - = desktop.getDisplays().getDisplayContaining (component.getScreenBounds().getCentre()); + auto& display = desktop.getDisplays().getDisplayContaining (component.getScreenBounds().getCentre()); setWindowPos (hwnd, display.userArea * display.scale, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOSENDCHANGING); @@ -2732,7 +2874,7 @@ private: public: static LRESULT CALLBACK windowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) { - if (HWNDComponentPeer* const peer = getOwnerOfWindow (h)) + if (auto* peer = getOwnerOfWindow (h)) { jassert (isValidPeer (peer)); return peer->peerWindowProc (h, message, wParam, lParam); @@ -2744,16 +2886,18 @@ public: private: static void* callFunctionIfNotLocked (MessageCallbackFunction* callback, void* userData) { - if (MessageManager::getInstance()->currentThreadHasLockedMessageManager()) + auto& mm = *MessageManager::getInstance(); + + if (mm.currentThreadHasLockedMessageManager()) return callback (userData); - return MessageManager::getInstance()->callFunctionOnMessageThread (callback, userData); + return mm.callFunctionOnMessageThread (callback, userData); } static Point getPointFromLParam (LPARAM lParam) noexcept { - return Point (static_cast (GET_X_LPARAM (lParam)), - static_cast (GET_Y_LPARAM (lParam))); + return { static_cast (GET_X_LPARAM (lParam)), + static_cast (GET_Y_LPARAM (lParam)) }; } static Point getCurrentMousePosGlobal() noexcept @@ -2802,13 +2946,25 @@ private: return 1; //============================================================================== - #ifdef WM_POINTERUPDATE - case WM_POINTERUPDATE: handleTouchInput (emulateTouchEventFromPointer (lParam, wParam), false, false); return 0; - case WM_POINTERDOWN: handleTouchInput (emulateTouchEventFromPointer (lParam, wParam), true, false); return 0; - case WM_POINTERUP: handleTouchInput (emulateTouchEventFromPointer (lParam, wParam), false, true); return 0; - #endif + case WM_POINTERUPDATE: + if (handlePointerInput (wParam, lParam, false, false)) + return 0; + break; + + case WM_POINTERDOWN: + if (handlePointerInput (wParam, lParam, true, false)) + return 0; + break; + case WM_POINTERUP: + if (handlePointerInput (wParam, lParam, false, true)) + return 0; + break; + + //============================================================================== case WM_MOUSEMOVE: doMouseMove (getPointFromLParam (lParam), false); return 0; + + case WM_POINTERLEAVE: case WM_MOUSELEAVE: doMouseExit(); return 0; case WM_LBUTTONDOWN: @@ -2819,11 +2975,15 @@ private: case WM_MBUTTONUP: case WM_RBUTTONUP: doMouseUp (getPointFromLParam (lParam), wParam); return 0; + case WM_POINTERWHEEL: case 0x020A: /* WM_MOUSEWHEEL */ doMouseWheel (wParam, true); return 0; + + case WM_POINTERHWHEEL: case 0x020E: /* WM_MOUSEHWHEEL */ doMouseWheel (wParam, false); return 0; case WM_CAPTURECHANGED: doCaptureChanged(); return 0; + case WM_NCPOINTERUPDATE: case WM_NCMOUSEMOVE: if (hasTitleBar()) break; @@ -2936,6 +3096,7 @@ private: break; + case WM_POINTERACTIVATE: case WM_MOUSEACTIVATE: if (! component.getMouseClickGrabsKeyboardFocus()) return MA_NOACTIVATE; @@ -2957,8 +3118,14 @@ private: return 0; + #if JUCE_REMOVE_COMPONENT_FROM_DESKTOP_ON_WM_DESTROY + case WM_DESTROY: + getComponent().removeFromDesktop(); + return 0; + #endif + case WM_QUERYENDSESSION: - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + if (auto* app = JUCEApplicationBase::getInstance()) { app->systemRequestedQuit(); return MessageManager::getInstance()->hasStopMessageBeenSent(); @@ -3062,6 +3229,7 @@ private: break; + case WM_NCPOINTERDOWN: case WM_NCLBUTTONDOWN: handleLeftClickInNCArea (wParam); break; @@ -3104,9 +3272,8 @@ private: } //============================================================================== - class IMEHandler + struct IMEHandler { - public: IMEHandler() { reset(); @@ -3130,7 +3297,7 @@ private: { reset(); - if (TextInputTarget* const target = owner.findCurrentTextInputTarget()) + if (auto* target = owner.findCurrentTextInputTarget()) target->insertTextAtCaret (String()); } @@ -3139,7 +3306,7 @@ private: if (compositionInProgress) { // If this occurs, the user has cancelled the composition, so clear their changes.. - if (TextInputTarget* const target = owner.findCurrentTextInputTarget()) + if (auto* target = owner.findCurrentTextInputTarget()) { target->setHighlightedRegion (compositionRange); target->insertTextAtCaret (String()); @@ -3149,7 +3316,7 @@ private: target->setTemporaryUnderlining (Array >()); } - if (HIMC hImc = ImmGetContext (hWnd)) + if (auto hImc = ImmGetContext (hWnd)) { ImmNotifyIME (hImc, NI_CLOSECANDIDATE, 0, 0); ImmReleaseContext (hWnd, hImc); @@ -3161,34 +3328,34 @@ private: void handleComposition (ComponentPeer& owner, HWND hWnd, const LPARAM lParam) { - TextInputTarget* const target = owner.findCurrentTextInputTarget(); - HIMC hImc = ImmGetContext (hWnd); - - if (target == nullptr || hImc == 0) - return; + if (auto* target = owner.findCurrentTextInputTarget()) + { + if (auto hImc = ImmGetContext (hWnd)) + { + if (compositionRange.getStart() < 0) + compositionRange = Range::emptyRange (target->getHighlightedRegion().getStart()); - if (compositionRange.getStart() < 0) - compositionRange = Range::emptyRange (target->getHighlightedRegion().getStart()); + if ((lParam & GCS_RESULTSTR) != 0) // (composition has finished) + { + replaceCurrentSelection (target, getCompositionString (hImc, GCS_RESULTSTR), + Range::emptyRange (-1)); - if ((lParam & GCS_RESULTSTR) != 0) // (composition has finished) - { - replaceCurrentSelection (target, getCompositionString (hImc, GCS_RESULTSTR), - Range::emptyRange (-1)); + reset(); + target->setTemporaryUnderlining (Array >()); + } + else if ((lParam & GCS_COMPSTR) != 0) // (composition is still in-progress) + { + replaceCurrentSelection (target, getCompositionString (hImc, GCS_COMPSTR), + getCompositionSelection (hImc, lParam)); - reset(); - target->setTemporaryUnderlining (Array >()); - } - else if ((lParam & GCS_COMPSTR) != 0) // (composition is still in-progress) - { - replaceCurrentSelection (target, getCompositionString (hImc, GCS_COMPSTR), - getCompositionSelection (hImc, lParam)); + target->setTemporaryUnderlining (getCompositionUnderlines (hImc, lParam)); + compositionInProgress = true; + } - target->setTemporaryUnderlining (getCompositionUnderlines (hImc, lParam)); - compositionInProgress = true; + moveCandidateWindowToLeftAlignWithSelection (hImc, owner, target); + ImmReleaseContext (hWnd, hImc); + } } - - moveCandidateWindowToLeftAlignWithSelection (hImc, owner, target); - ImmReleaseContext (hWnd, hImc); } private: @@ -3217,7 +3384,7 @@ private: return String (buffer); } - return String(); + return {}; } int getCompositionCaretPos (HIMC hImc, LPARAM lParam, const String& currentIMEString) const @@ -3284,13 +3451,13 @@ private: target->setHighlightedRegion (newSelection); } - Array > getCompositionUnderlines (HIMC hImc, LPARAM lParam) const + Array> getCompositionUnderlines (HIMC hImc, LPARAM lParam) const { - Array > result; + Array> result; if (hImc != 0 && (lParam & GCS_COMPCLAUSE) != 0) { - const int clauseDataSizeBytes = ImmGetCompositionString (hImc, GCS_COMPCLAUSE, 0, 0); + auto clauseDataSizeBytes = ImmGetCompositionString (hImc, GCS_COMPCLAUSE, 0, 0); if (clauseDataSizeBytes > 0) { @@ -3308,9 +3475,9 @@ private: void moveCandidateWindowToLeftAlignWithSelection (HIMC hImc, ComponentPeer& peer, TextInputTarget* target) const { - if (Component* const targetComp = dynamic_cast (target)) + if (auto* targetComp = dynamic_cast (target)) { - const Rectangle area (peer.getComponent().getLocalArea (targetComp, target->getCaretRectangle())); + auto area = peer.getComponent().getLocalArea (targetComp, target->getCaretRectangle()); CANDIDATEFORM pos = { 0, CFS_CANDIDATEPOS, { area.getX(), area.getBottom() }, { 0, 0, 0, 0 } }; ImmSetCandidateWindow (hImc, &pos); @@ -3335,6 +3502,8 @@ private: ModifierKeys HWNDComponentPeer::currentModifiers; ModifierKeys HWNDComponentPeer::modifiersAtLastCallback; +MultiTouchMapper HWNDComponentPeer::currentTouches; + ComponentPeer* Component::createNewPeer (int styleFlags, void* parentHWND) { return new HWNDComponentPeer (*this, styleFlags, (HWND) parentHWND, false); @@ -3374,7 +3543,7 @@ ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept //============================================================================== bool KeyPress::isKeyCurrentlyDown (const int keyCode) { - SHORT k = (SHORT) keyCode; + auto k = (SHORT) keyCode; if ((keyCode & extendedKeyModifier) == 0) { @@ -3407,15 +3576,15 @@ bool offerKeyMessageToJUCEWindow (MSG& m) { return HWNDComponentPeer::offerKey //============================================================================== bool JUCE_CALLTYPE Process::isForegroundProcess() { - HWND fg = GetForegroundWindow(); - - if (fg == 0) - return true; + if (auto fg = GetForegroundWindow()) + { + DWORD processID = 0; + GetWindowThreadProcessId (fg, &processID); - DWORD processID = 0; - GetWindowThreadProcessId (fg, &processID); + return processID == GetCurrentProcessId(); + } - return (processID == GetCurrentProcessId()); + return true; } // N/A on Windows as far as I know. @@ -3472,7 +3641,7 @@ public: int getResult() const { const int r = MessageBox (owner, message.toWideCharPointer(), title.toWideCharPointer(), flags); - return (r == IDYES || r == IDOK) ? 1 : (r == IDNO ? 2 : 0); + return (r == IDYES || r == IDOK) ? 1 : (r == IDNO && (flags & 1) != 0 ? 2 : 0); } void handleAsyncUpdate() override @@ -3558,25 +3727,45 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy return 0; } +int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (AlertWindow::AlertIconType iconType, + const String& title, const String& message, + Component* associatedComponent, + ModalComponentManager::Callback* callback) +{ + ScopedPointer mb (new WindowsMessageBox (iconType, title, message, associatedComponent, + MB_YESNO, callback, callback != nullptr)); + if (callback == nullptr) + return mb->getResult(); + + mb.release(); + return 0; +} + //============================================================================== bool MouseInputSource::SourceList::addSource() { - const int numSources = sources.size(); + auto numSources = sources.size(); if (numSources == 0 || canUseMultiTouch()) { - addSource (numSources, numSources == 0); + addSource (numSources, numSources == 0 ? MouseInputSource::InputSourceType::mouse + : MouseInputSource::InputSourceType::touch); return true; } return false; } +bool MouseInputSource::SourceList::canUseTouch() +{ + return canUseMultiTouch(); +} + Point MouseInputSource::getCurrentRawMousePosition() { POINT mousePos; GetCursorPos (&mousePos); - return Point ((float) mousePos.x, (float) mousePos.y); + return { (float) mousePos.x, (float) mousePos.y }; } void MouseInputSource::setRawMousePosition (Point newPosition) @@ -3636,13 +3825,13 @@ void SystemClipboard::copyTextToClipboard (const String& text) { if (EmptyClipboard() != 0) { - const size_t bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer()) + 4; + auto bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer()) + 4; if (bytesNeeded > 0) { - if (HGLOBAL bufH = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, bytesNeeded + sizeof (WCHAR))) + if (auto bufH = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, bytesNeeded + sizeof (WCHAR))) { - if (WCHAR* const data = static_cast (GlobalLock (bufH))) + if (auto* data = static_cast (GlobalLock (bufH))) { text.copyToUTF16 (data, bytesNeeded); GlobalUnlock (bufH); @@ -3663,9 +3852,9 @@ String SystemClipboard::getTextFromClipboard() if (OpenClipboard (0) != 0) { - if (HANDLE bufH = GetClipboardData (CF_UNICODETEXT)) + if (auto bufH = GetClipboardData (CF_UNICODETEXT)) { - if (const WCHAR* const data = (const WCHAR*) GlobalLock (bufH)) + if (auto* data = (const WCHAR*) GlobalLock (bufH)) { result = String (data, (size_t) (GlobalSize (bufH) / sizeof (WCHAR))); GlobalUnlock (bufH); @@ -3681,7 +3870,7 @@ String SystemClipboard::getTextFromClipboard() //============================================================================== void Desktop::setKioskComponent (Component* kioskModeComp, bool enableOrDisable, bool /*allowMenusAndBars*/) { - if (TopLevelWindow* tlw = dynamic_cast (kioskModeComp)) + if (auto* tlw = dynamic_cast (kioskModeComp)) tlw->setUsingNativeTitleBar (! enableOrDisable); if (enableOrDisable) @@ -3780,7 +3969,8 @@ static HICON extractFileHICON (const File& file) Image juce_createIconForFile (const File& file) { Image image; - if (HICON icon = extractFileHICON (file)) + + if (auto icon = extractFileHICON (file)) { image = IconConverters::createImageFromHICON (icon); DestroyIcon (icon); @@ -3810,7 +4000,7 @@ void* CustomMouseCursorInfo::create() const return IconConverters::createHICONFromImage (im, FALSE, hotspotX, hotspotY); } -void MouseCursor::deleteMouseCursor (void* const cursorHandle, const bool isStandard) +void MouseCursor::deleteMouseCursor (void* cursorHandle, bool isStandard) { if (cursorHandle != nullptr && ! isStandard) DestroyCursor ((HCURSOR) cursorHandle); @@ -3901,7 +4091,7 @@ void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorT //============================================================================== void MouseCursor::showInWindow (ComponentPeer*) const { - HCURSOR c = (HCURSOR) getHandle(); + auto c = (HCURSOR) getHandle(); if (c == 0) c = LoadCursor (0, IDC_ARROW); diff --git a/source/modules/juce_gui_basics/positioning/juce_MarkerList.cpp b/source/modules/juce_gui_basics/positioning/juce_MarkerList.cpp index 0e3495a7e..ee61180f0 100644 --- a/source/modules/juce_gui_basics/positioning/juce_MarkerList.cpp +++ b/source/modules/juce_gui_basics/positioning/juce_MarkerList.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/positioning/juce_MarkerList.h b/source/modules/juce_gui_basics/positioning/juce_MarkerList.h index a19a348db..8d6da7f7e 100644 --- a/source/modules/juce_gui_basics/positioning/juce_MarkerList.h +++ b/source/modules/juce_gui_basics/positioning/juce_MarkerList.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MARKERLIST_H_INCLUDED -#define JUCE_MARKERLIST_H_INCLUDED +#pragma once //============================================================================== @@ -179,6 +180,3 @@ private: JUCE_LEAK_DETECTOR (MarkerList) }; - - -#endif // JUCE_MARKERLIST_H_INCLUDED diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp b/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp index a545acd7a..ce7971693 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp +++ b/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -67,7 +69,6 @@ RelativeCoordinate& RelativeCoordinate::operator= (const RelativeCoordinate& oth return *this; } -#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS RelativeCoordinate::RelativeCoordinate (RelativeCoordinate&& other) noexcept : term (static_cast (other.term)) { @@ -78,7 +79,6 @@ RelativeCoordinate& RelativeCoordinate::operator= (RelativeCoordinate&& other) n term = static_cast (other.term); return *this; } -#endif RelativeCoordinate::RelativeCoordinate (const double absoluteDistanceFromOrigin) : term (absoluteDistanceFromOrigin) diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h b/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h index 91b901da1..507dfcd49 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h +++ b/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RELATIVECOORDINATE_H_INCLUDED -#define JUCE_RELATIVECOORDINATE_H_INCLUDED +#pragma once //============================================================================== @@ -76,11 +77,8 @@ public: RelativeCoordinate (const Expression& expression); RelativeCoordinate (const RelativeCoordinate&); RelativeCoordinate& operator= (const RelativeCoordinate&); - - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS RelativeCoordinate (RelativeCoordinate&&) noexcept; RelativeCoordinate& operator= (RelativeCoordinate&&) noexcept; - #endif /** Creates an absolute position from the parent origin on either the X or Y axis. @@ -177,6 +175,3 @@ private: //============================================================================== Expression term; }; - - -#endif // JUCE_RELATIVECOORDINATE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp b/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp index fc6772bb3..7260710de 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp +++ b/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp @@ -2,31 +2,35 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -class MarkerListScope : public Expression::Scope +struct MarkerListScope : public Expression::Scope { -public: 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)) @@ -38,7 +42,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); @@ -48,7 +52,7 @@ public: { if (scopeName == RelativeCoordinate::Strings::parent) { - if (Component* const parent = component.getParentComponent()) + if (auto* parent = component.getParentComponent()) { visitor.visit (MarkerListScope (*parent)); return; @@ -82,10 +86,7 @@ public: return marker; } -private: Component& component; - - JUCE_DECLARE_NON_COPYABLE (MarkerListScope) }; //============================================================================== @@ -125,9 +126,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); @@ -215,8 +216,6 @@ public: private: RelativeCoordinatePositionerBase& positioner; bool& ok; - - JUCE_DECLARE_NON_COPYABLE (DependencyFinderScope) }; //============================================================================== diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h b/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h index bf9047c52..74abf4360 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h +++ b/source/modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RELATIVECOORDINATEPOSITIONER_H_INCLUDED -#define JUCE_RELATIVECOORDINATEPOSITIONER_H_INCLUDED +#pragma once //============================================================================== @@ -35,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); @@ -43,31 +44,31 @@ 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&); + + // Suppress a VS2013 compiler warning + ComponentScope& operator= (const ComponentScope&) = delete; 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: @@ -77,16 +78,13 @@ 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) }; - - -#endif // JUCE_RELATIVECOORDINATEPOSITIONER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp b/source/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp index 330dd419b..92ad11fc4 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp +++ b/source/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h b/source/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h index cef4d471d..38ab861ea 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h +++ b/source/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RELATIVEPARALLELOGRAM_H_INCLUDED -#define JUCE_RELATIVEPARALLELOGRAM_H_INCLUDED +#pragma once //============================================================================== @@ -60,6 +61,3 @@ public: //============================================================================== RelativePoint topLeft, topRight, bottomLeft; }; - - -#endif // JUCE_RELATIVEPARALLELOGRAM_H_INCLUDED diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp b/source/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp index 21aaf036f..5f9228c20 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp +++ b/source/modules/juce_gui_basics/positioning/juce_RelativePoint.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativePoint.h b/source/modules/juce_gui_basics/positioning/juce_RelativePoint.h index c50ce2f43..cb874f6e2 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativePoint.h +++ b/source/modules/juce_gui_basics/positioning/juce_RelativePoint.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RELATIVEPOINT_H_INCLUDED -#define JUCE_RELATIVEPOINT_H_INCLUDED +#pragma once //============================================================================== @@ -85,6 +86,3 @@ public: // The actual X and Y coords... RelativeCoordinate x, y; }; - - -#endif // JUCE_RELATIVEPOINT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp b/source/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp index 14b1aa348..5f36d46ef 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp +++ b/source/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativePointPath.h b/source/modules/juce_gui_basics/positioning/juce_RelativePointPath.h index 6de294df5..ff628db34 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativePointPath.h +++ b/source/modules/juce_gui_basics/positioning/juce_RelativePointPath.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RELATIVEPOINTPATH_H_INCLUDED -#define JUCE_RELATIVEPOINTPATH_H_INCLUDED +#pragma once //============================================================================== @@ -186,6 +187,3 @@ private: RelativePointPath& operator= (const RelativePointPath&); JUCE_LEAK_DETECTOR (RelativePointPath) }; - - -#endif // JUCE_RELATIVEPOINTPATH_H_INCLUDED diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp b/source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp index 009bb83f4..d2b73580e 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp +++ b/source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h b/source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h index 0e04e2c5d..b634adc65 100644 --- a/source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h +++ b/source/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RELATIVERECTANGLE_H_INCLUDED -#define JUCE_RELATIVERECTANGLE_H_INCLUDED +#pragma once //============================================================================== @@ -102,6 +103,3 @@ public: // The actual rectangle coords... RelativeCoordinate left, right, top, bottom; }; - - -#endif // JUCE_RELATIVERECTANGLE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp b/source/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp index d5095bb79..bbf568a63 100644 --- a/source/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp +++ b/source/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -69,7 +71,7 @@ void BooleanPropertyComponent::paint (Graphics& g) g.setColour (findColour (backgroundColourId)); g.fillRect (button.getBounds()); - g.setColour (findColour (ComboBox::outlineColourId)); + g.setColour (findColour (outlineColourId)); g.drawRect (button.getBounds()); } diff --git a/source/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h b/source/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h index 08ad78c2e..b38c14875 100644 --- a/source/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h +++ b/source/modules/juce_gui_basics/properties/juce_BooleanPropertyComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BOOLEANPROPERTYCOMPONENT_H_INCLUDED -#define JUCE_BOOLEANPROPERTYCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -106,6 +107,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BooleanPropertyComponent) }; - - -#endif // JUCE_BOOLEANPROPERTYCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp b/source/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp index c8e99d7b8..00343f65a 100644 --- a/source/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp +++ b/source/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h b/source/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h index e6b82f525..62cfdfcb6 100644 --- a/source/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h +++ b/source/modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BUTTONPROPERTYCOMPONENT_H_INCLUDED -#define JUCE_BUTTONPROPERTYCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -73,6 +74,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ButtonPropertyComponent) }; - - -#endif // JUCE_BUTTONPROPERTYCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp b/source/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp index b886de928..50437b599 100644 --- a/source/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp +++ b/source/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h b/source/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h index 6f97d5be1..cb3f0adc0 100644 --- a/source/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h +++ b/source/modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CHOICEPROPERTYCOMPONENT_H_INCLUDED -#define JUCE_CHOICEPROPERTYCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -118,8 +119,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChoicePropertyComponent) }; - - - - -#endif // JUCE_CHOICEPROPERTYCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp b/source/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp index aada11838..81ee114e9 100644 --- a/source/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp +++ b/source/modules/juce_gui_basics/properties/juce_PropertyComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/properties/juce_PropertyComponent.h b/source/modules/juce_gui_basics/properties/juce_PropertyComponent.h index 8b1856bec..c6e2ec6e2 100644 --- a/source/modules/juce_gui_basics/properties/juce_PropertyComponent.h +++ b/source/modules/juce_gui_basics/properties/juce_PropertyComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PROPERTYCOMPONENT_H_INCLUDED -#define JUCE_PROPERTYCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -138,6 +139,3 @@ protected: private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyComponent) }; - - -#endif // JUCE_PROPERTYCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp b/source/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp index d13fa0e4b..a12c436a8 100644 --- a/source/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp +++ b/source/modules/juce_gui_basics/properties/juce_PropertyPanel.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/properties/juce_PropertyPanel.h b/source/modules/juce_gui_basics/properties/juce_PropertyPanel.h index aca85988e..24150eb1f 100644 --- a/source/modules/juce_gui_basics/properties/juce_PropertyPanel.h +++ b/source/modules/juce_gui_basics/properties/juce_PropertyPanel.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PROPERTYPANEL_H_INCLUDED -#define JUCE_PROPERTYPANEL_H_INCLUDED +#pragma once //============================================================================== @@ -172,6 +173,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyPanel) }; - - -#endif // JUCE_PROPERTYPANEL_H_INCLUDED diff --git a/source/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp b/source/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp index 46ee985ad..4db6859a7 100644 --- a/source/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp +++ b/source/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h b/source/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h index d45e448b8..b655fbbad 100644 --- a/source/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h +++ b/source/modules/juce_gui_basics/properties/juce_SliderPropertyComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SLIDERPROPERTYCOMPONENT_H_INCLUDED -#define JUCE_SLIDERPROPERTYCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -104,6 +105,3 @@ private: //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SliderPropertyComponent) }; - - -#endif // JUCE_SLIDERPROPERTYCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp b/source/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp index 5a52f9c61..3193f110b 100644 --- a/source/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp +++ b/source/modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -39,7 +41,7 @@ public: bool isInterestedInFileDrag (const StringArray&) override { - return true; + return interestedInFileDrag; } void filesDropped (const StringArray& files, int, int) override @@ -75,10 +77,16 @@ public: repaint(); } + void setInterestedInFileDrag (bool isInterested) + { + interestedInFileDrag = isInterested; + } + private: TextPropertyComponent& owner; int maxChars; bool isMultiline; + bool interestedInFileDrag = true; }; //============================================================================== @@ -167,3 +175,9 @@ void TextPropertyComponent::colourChanged() PropertyComponent::colourChanged(); textEditor->updateColours(); } + +void TextPropertyComponent::setInterestedInFileDrag (bool isInterested) +{ + if (textEditor != nullptr) + textEditor->setInterestedInFileDrag (isInterested); +} diff --git a/source/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h b/source/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h index de9d467dd..5a10ca6f5 100644 --- a/source/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h +++ b/source/modules/juce_gui_basics/properties/juce_TextPropertyComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TEXTPROPERTYCOMPONENT_H_INCLUDED -#define JUCE_TEXTPROPERTYCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -121,6 +122,14 @@ public: */ void removeListener (Listener* listener); + //============================================================================== + /** Sets whether the text property component can have files dropped onto it by an external application. + + The default setting for this is true but you may want to disable this behaviour if you derive + from this class and want your subclass to respond to the file drag. + */ + void setInterestedInFileDrag (bool isInterested); + //============================================================================== /** @internal */ void refresh() override; @@ -144,5 +153,3 @@ private: /** This typedef is just for compatibility with old code and VC6 - newer code should use TextPropertyComponent::Listener instead. */ typedef TextPropertyComponent::Listener TextPropertyComponentListener; #endif - -#endif // JUCE_TEXTPROPERTYCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_ComboBox.cpp b/source/modules/juce_gui_basics/widgets/juce_ComboBox.cpp index e227e7142..fc3e14ff8 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ComboBox.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_ComboBox.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -200,15 +202,15 @@ int ComboBox::getNumItems() const noexcept String ComboBox::getItemText (const int index) const { - if (const PopupMenu::Item* const item = getItemForIndex (index)) + if (auto* item = getItemForIndex (index)) return item->text; - return String(); + return {}; } int ComboBox::getItemId (const int index) const noexcept { - if (const PopupMenu::Item* const item = getItemForIndex (index)) + if (auto* item = getItemForIndex (index)) return item->itemID; return 0; @@ -223,7 +225,7 @@ int ComboBox::indexOfItemId (const int itemId) const noexcept while (iterator.next()) { - PopupMenu::Item &item = iterator.getItem(); + auto& item = iterator.getItem(); if (item.itemID == itemId) return n; @@ -530,24 +532,35 @@ static void comboBoxPopupMenuFinishedCallback (int result, ComboBox* combo) void ComboBox::showPopup() { - PopupMenu::MenuItemIterator iterator (currentMenu, true); - const int selectedId = getSelectedId(); + PopupMenu noChoicesMenu; + const bool hasItems = (currentMenu.getNumItems() > 0); - while (iterator.next()) + if (hasItems) { - PopupMenu::Item &item = iterator.getItem(); + PopupMenu::MenuItemIterator iterator (currentMenu, true); + const int selectedId = getSelectedId(); - if (item.itemID != 0) - item.isTicked = (item.itemID == selectedId); + while (iterator.next()) + { + PopupMenu::Item &item = iterator.getItem(); + + if (item.itemID != 0) + item.isTicked = (item.itemID == selectedId); + } + } + else + { + noChoicesMenu.addItem (1, noChoicesMessage, false, false); } - currentMenu.setLookAndFeel(&getLookAndFeel()); - currentMenu.showMenuAsync (PopupMenu::Options().withTargetComponent (this) - .withItemThatMustBeVisible (getSelectedId()) - .withMinimumWidth (getWidth()) - .withMaximumNumColumns (1) - .withStandardItemHeight (label->getHeight()), - ModalCallbackFunction::forComponent (comboBoxPopupMenuFinishedCallback, this)); + PopupMenu& menuToShow = (hasItems ? currentMenu : noChoicesMenu); + menuToShow.setLookAndFeel (&getLookAndFeel()); + menuToShow.showMenuAsync (PopupMenu::Options().withTargetComponent (this) + .withItemThatMustBeVisible (getSelectedId()) + .withMinimumWidth (getWidth()) + .withMaximumNumColumns (1) + .withStandardItemHeight (label->getHeight()), + ModalCallbackFunction::forComponent (comboBoxPopupMenuFinishedCallback, this)); } //============================================================================== @@ -588,13 +601,12 @@ void ComboBox::mouseUp (const MouseEvent& e2) void ComboBox::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel) { - if (! menuActive && scrollWheelEnabled && e.eventComponent == this && wheel.deltaY != 0) + if (! menuActive && scrollWheelEnabled && e.eventComponent == this && wheel.deltaY != 0.0f) { - const int oldPos = (int) mouseWheelAccumulator; + auto oldPos = (int) mouseWheelAccumulator; mouseWheelAccumulator += wheel.deltaY * 5.0f; - const int delta = oldPos - (int) mouseWheelAccumulator; - if (delta != 0) + if (auto delta = oldPos - (int) mouseWheelAccumulator) nudgeSelectedItem (delta); } else diff --git a/source/modules/juce_gui_basics/widgets/juce_ComboBox.h b/source/modules/juce_gui_basics/widgets/juce_ComboBox.h index 4d0366635..6e6a2b471 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ComboBox.h +++ b/source/modules/juce_gui_basics/widgets/juce_ComboBox.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMBOBOX_H_INCLUDED -#define JUCE_COMBOBOX_H_INCLUDED +#pragma once //============================================================================== @@ -447,5 +448,3 @@ private: /** This typedef is just for compatibility with old code - newer code should use the ComboBox::Listener class directly. */ typedef ComboBox::Listener ComboBoxListener; - -#endif // JUCE_COMBOBOX_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp b/source/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp index 9d7506085..77d2a9807 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_ImageComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/widgets/juce_ImageComponent.h b/source/modules/juce_gui_basics/widgets/juce_ImageComponent.h index 0c7bad43d..3957d58f6 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ImageComponent.h +++ b/source/modules/juce_gui_basics/widgets/juce_ImageComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_IMAGECOMPONENT_H_INCLUDED -#define JUCE_IMAGECOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -73,6 +74,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageComponent) }; - - -#endif // JUCE_IMAGECOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_Label.cpp b/source/modules/juce_gui_basics/widgets/juce_Label.cpp index 0393dda6e..16b9e39bb 100644 --- a/source/modules/juce_gui_basics/widgets/juce_Label.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_Label.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/widgets/juce_Label.h b/source/modules/juce_gui_basics/widgets/juce_Label.h index dfb74ef00..05abf0dc4 100644 --- a/source/modules/juce_gui_basics/widgets/juce_Label.h +++ b/source/modules/juce_gui_basics/widgets/juce_Label.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LABEL_H_INCLUDED -#define JUCE_LABEL_H_INCLUDED +#pragma once //============================================================================== @@ -350,5 +351,3 @@ private: /** This typedef is just for compatibility with old code - newer code should use the Label::Listener class directly. */ typedef Label::Listener LabelListener; - -#endif // JUCE_LABEL_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_ListBox.cpp b/source/modules/juce_gui_basics/widgets/juce_ListBox.cpp index 5aa9ff58a..9c303a980 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ListBox.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_ListBox.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -26,15 +28,11 @@ class ListBox::RowComponent : public Component, public TooltipClient { public: - RowComponent (ListBox& lb) - : owner (lb), row (-1), - selected (false), isDragging (false), selectRowOnMouseUp (false) - { - } + RowComponent (ListBox& lb) : owner (lb) {} void paint (Graphics& g) override { - if (ListBoxModel* m = owner.getModel()) + if (auto* m = owner.getModel()) m->paintListBoxItem (row, g, getWidth(), getHeight(), selected); } @@ -47,7 +45,7 @@ public: selected = nowSelected; } - if (ListBoxModel* m = owner.getModel()) + if (auto* m = owner.getModel()) { setMouseCursor (m->getMouseCursorForRow (row)); @@ -61,48 +59,53 @@ public: } } + void performSelection (const MouseEvent& e, bool isMouseUp) + { + owner.selectRowsBasedOnModifierKeys (row, e.mods, isMouseUp); + + if (auto* m = owner.getModel()) + m->listBoxItemClicked (row, e); + } + + bool isInDragToScrollViewport() const noexcept + { + if (auto* vp = owner.getViewport()) + return vp->isScrollOnDragEnabled() && (vp->canScrollVertically() || vp->canScrollHorizontally()); + + return false; + } + void mouseDown (const MouseEvent& e) override { isDragging = false; + isDraggingToScroll = false; selectRowOnMouseUp = false; if (isEnabled()) { - if (owner.selectOnMouseDown && ! selected) - { - owner.selectRowsBasedOnModifierKeys (row, e.mods, false); - - if (ListBoxModel* m = owner.getModel()) - m->listBoxItemClicked (row, e); - } + if (owner.selectOnMouseDown && ! (selected || isInDragToScrollViewport())) + performSelection (e, false); else - { selectRowOnMouseUp = true; - } } } void mouseUp (const MouseEvent& e) override { - if (isEnabled() && selectRowOnMouseUp && ! isDragging) - { - owner.selectRowsBasedOnModifierKeys (row, e.mods, true); - - if (ListBoxModel* m = owner.getModel()) - m->listBoxItemClicked (row, e); - } + if (isEnabled() && selectRowOnMouseUp && ! (isDragging || isDraggingToScroll)) + performSelection (e, true); } void mouseDoubleClick (const MouseEvent& e) override { - if (ListBoxModel* m = owner.getModel()) - if (isEnabled()) + if (isEnabled()) + if (auto* m = owner.getModel()) m->listBoxItemDoubleClicked (row, e); } void mouseDrag (const MouseEvent& e) override { - if (ListBoxModel* m = owner.getModel()) + if (auto* m = owner.getModel()) { if (isEnabled() && e.mouseWasDraggedSinceMouseDown() && ! isDragging) { @@ -115,7 +118,7 @@ public: if (rowsToDrag.size() > 0) { - const var dragDescription (m->getDragSourceDescription (rowsToDrag)); + auto dragDescription = m->getDragSourceDescription (rowsToDrag); if (! (dragDescription.isVoid() || (dragDescription.isString() && dragDescription.toString().isEmpty()))) { @@ -125,6 +128,10 @@ public: } } } + + if (! isDraggingToScroll) + if (auto* vp = owner.getViewport()) + isDraggingToScroll = vp->isCurrentlyScrollingOnDrag(); } void resized() override @@ -135,18 +142,16 @@ public: String getTooltip() override { - if (ListBoxModel* m = owner.getModel()) + if (auto* m = owner.getModel()) return m->getTooltipForRow (row); - return String(); + return {}; } - ScopedPointer customComponent; - -private: ListBox& owner; - int row; - bool selected, isDragging, selectRowOnMouseUp; + ScopedPointer customComponent; + int row = -1; + bool selected = false, isDragging = false, isDraggingToScroll = false, selectRowOnMouseUp = false; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RowComponent) }; @@ -156,12 +161,11 @@ private: class ListBox::ListViewport : public Viewport { public: - ListViewport (ListBox& lb) - : owner (lb) + ListViewport (ListBox& lb) : owner (lb) { setWantsKeyboardFocus (false); - Component* const content = new Component(); + auto content = new Component(); setViewedComponent (content); content->setWantsKeyboardFocus (false); } @@ -193,7 +197,7 @@ public: { updateVisibleArea (true); - if (ListBoxModel* m = owner.getModel()) + if (auto* m = owner.getModel()) m->listWasScrolled(); } @@ -201,11 +205,11 @@ public: { hasUpdated = false; - Component& content = *getViewedComponent(); - const int newX = content.getX(); - int newY = content.getY(); - const int newW = jmax (owner.minimumRowWidth, getMaximumVisibleWidth()); - const int newH = owner.totalItems * owner.getRowHeight(); + auto& content = *getViewedComponent(); + auto newX = content.getX(); + auto newY = content.getY(); + auto newW = jmax (owner.minimumRowWidth, getMaximumVisibleWidth()); + auto newH = owner.totalItems * owner.getRowHeight(); if (newY + newH < getMaximumVisibleHeight() && newH > getMaximumVisibleHeight()) newY = getMaximumVisibleHeight() - newH; @@ -219,20 +223,20 @@ public: void updateContents() { hasUpdated = true; - const int rowH = owner.getRowHeight(); - Component& content = *getViewedComponent(); + auto rowH = owner.getRowHeight(); + auto& content = *getViewedComponent(); if (rowH > 0) { - const int y = getViewPositionY(); - const int w = content.getWidth(); + auto y = getViewPositionY(); + auto w = content.getWidth(); const int numNeeded = 2 + getMaximumVisibleHeight() / rowH; rows.removeRange (numNeeded, rows.size()); while (numNeeded > rows.size()) { - RowComponent* newRow = new RowComponent (owner); + auto newRow = new RowComponent (owner); rows.add (newRow); content.addAndMakeVisible (newRow); } @@ -245,7 +249,7 @@ public: { const int row = i + firstIndex; - if (RowComponent* const rowComp = getComponentForRow (row)) + if (auto* rowComp = getComponentForRow (row)) { rowComp->setBounds (0, row * rowH, w, rowH); rowComp->update (row, owner.isRowSelected (row)); @@ -331,25 +335,29 @@ public: private: ListBox& owner; OwnedArray rows; - int firstIndex, firstWholeIndex, lastWholeIndex; - bool hasUpdated; + int firstIndex = 0, firstWholeIndex = 0, lastWholeIndex = 0; + bool hasUpdated = false; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ListViewport) }; //============================================================================== -class ListBoxMouseMoveSelector : public MouseListener +struct ListBoxMouseMoveSelector : public MouseListener { -public: ListBoxMouseMoveSelector (ListBox& lb) : owner (lb) { owner.addMouseListener (this, true); } + ~ListBoxMouseMoveSelector() + { + owner.removeMouseListener (this); + } + void mouseMove (const MouseEvent& e) override { - const MouseEvent e2 (e.getEventRelativeTo (&owner)); - owner.selectRow (owner.getRowContainingPosition (e2.x, e2.y), true); + auto pos = e.getEventRelativeTo (&owner).position.toInt(); + owner.selectRow (owner.getRowContainingPosition (pos.x, pos.y), true); } void mouseExit (const MouseEvent& e) override @@ -357,26 +365,14 @@ public: mouseMove (e); } -private: ListBox& owner; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ListBoxMouseMoveSelector) }; //============================================================================== ListBox::ListBox (const String& name, ListBoxModel* const m) - : Component (name), - model (m), - totalItems (0), - rowHeight (22), - minimumRowWidth (0), - outlineThickness (0), - lastRowSelected (-1), - multipleSelection (false), - alwaysFlipSelection (false), - hasDoneInitialUpdate (false), - selectOnMouseDown (true) + : Component (name), model (m) { addAndMakeVisible (viewport = new ListViewport (*this)); @@ -465,7 +461,7 @@ void ListBox::updateContent() if (selected.size() > 0 && selected [selected.size() - 1] >= totalItems) { - selected.removeRange (Range (totalItems, std::numeric_limits::max())); + selected.removeRange ({ totalItems, std::numeric_limits::max() }); lastRowSelected = getSelectedRow (0); selectionChanged = true; } @@ -499,7 +495,7 @@ void ListBox::selectRowInternal (const int row, if (deselectOthersFirst) selected.clear(); - selected.addRange (Range (row, row + 1)); + selected.addRange ({ row, row + 1 }); if (getHeight() == 0 || getWidth() == 0) dontScroll = true; @@ -522,7 +518,7 @@ void ListBox::deselectRow (const int row) { if (selected.contains (row)) { - selected.removeRange (Range (row, row + 1)); + selected.removeRange ({ row, row + 1 }); if (row == lastRowSelected) lastRowSelected = getSelectedRow (0); @@ -536,7 +532,7 @@ void ListBox::setSelectedRows (const SparseSet& setOfRowsToBeSelected, const NotificationType sendNotificationEventToModel) { selected = setOfRowsToBeSelected; - selected.removeRange (Range (totalItems, std::numeric_limits::max())); + selected.removeRange ({ totalItems, std::numeric_limits::max() }); if (! isRowSelected (lastRowSelected)) lastRowSelected = getSelectedRow (0); @@ -560,10 +556,10 @@ void ListBox::selectRangeOfRows (int firstRow, int lastRow, bool dontScrollToSho firstRow = jlimit (0, jmax (0, numRows), firstRow); lastRow = jlimit (0, jmax (0, numRows), lastRow); - selected.addRange (Range (jmin (firstRow, lastRow), - jmax (firstRow, lastRow) + 1)); + selected.addRange ({ jmin (firstRow, lastRow), + jmax (firstRow, lastRow) + 1 }); - selected.removeRange (Range (lastRow, lastRow + 1)); + selected.removeRange ({ lastRow, lastRow + 1 }); } selectRowInternal (lastRow, dontScrollToShowThisRange, false, true); @@ -647,18 +643,15 @@ int ListBox::getRowContainingPosition (const int x, const int y) const noexcept int ListBox::getInsertionIndexForPosition (const int x, const int y) const noexcept { if (isPositiveAndBelow (x, getWidth())) - { - const int row = (viewport->getViewPositionY() + y + rowHeight / 2 - viewport->getY()) / rowHeight; - return jlimit (0, totalItems, row); - } + return jlimit (0, totalItems, (viewport->getViewPositionY() + y + rowHeight / 2 - viewport->getY()) / rowHeight); return -1; } Component* ListBox::getComponentForRowNumber (const int row) const noexcept { - if (RowComponent* const listRowComp = viewport->getComponentForRowIfOnscreen (row)) - return static_cast (listRowComp->customComponent); + if (auto* listRowComp = viewport->getComponentForRowIfOnscreen (row)) + return listRowComp->customComponent; return nullptr; } @@ -668,21 +661,20 @@ int ListBox::getRowNumberOfComponent (Component* const rowComponent) const noexc return viewport->getRowNumberOfComponent (rowComponent); } -Rectangle ListBox::getRowPosition (const int rowNumber, - const bool relativeToComponentTopLeft) const noexcept +Rectangle ListBox::getRowPosition (int rowNumber, bool relativeToComponentTopLeft) const noexcept { - int y = viewport->getY() + rowHeight * rowNumber; + auto y = viewport->getY() + rowHeight * rowNumber; if (relativeToComponentTopLeft) y -= viewport->getViewPositionY(); - return Rectangle (viewport->getX(), y, - viewport->getViewedComponent()->getWidth(), rowHeight); + return { viewport->getX(), y, + viewport->getViewedComponent()->getWidth(), rowHeight }; } void ListBox::setVerticalPosition (const double proportion) { - const int offscreen = viewport->getViewedComponent()->getHeight() - viewport->getHeight(); + auto offscreen = viewport->getViewedComponent()->getHeight() - viewport->getHeight(); viewport->setViewPosition (viewport->getViewPositionX(), jmax (0, roundToInt (proportion * offscreen))); @@ -690,10 +682,10 @@ void ListBox::setVerticalPosition (const double proportion) double ListBox::getVerticalPosition() const { - const int offscreen = viewport->getViewedComponent()->getHeight() - viewport->getHeight(); + auto offscreen = viewport->getViewedComponent()->getHeight() - viewport->getHeight(); - return (offscreen > 0) ? viewport->getViewPositionY() / (double) offscreen - : 0; + return offscreen > 0 ? viewport->getViewPositionY() / (double) offscreen + : 0; } int ListBox::getVisibleRowWidth() const noexcept @@ -796,13 +788,13 @@ void ListBox::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& whee { bool eventWasUsed = false; - if (wheel.deltaX != 0 && viewport->getHorizontalScrollBar()->isVisible()) + if (wheel.deltaX != 0.0f && viewport->getHorizontalScrollBar()->isVisible()) { eventWasUsed = true; viewport->getHorizontalScrollBar()->mouseWheelMove (e, wheel); } - if (wheel.deltaY != 0 && viewport->getVerticalScrollBar()->isVisible()) + if (wheel.deltaY != 0.0f && viewport->getVerticalScrollBar()->isVisible()) { eventWasUsed = true; viewport->getVerticalScrollBar()->mouseWheelMove (e, wheel); @@ -837,20 +829,10 @@ void ListBox::setMinimumContentWidth (const int newMinimumWidth) updateContent(); } -int ListBox::getVisibleContentWidth() const noexcept -{ - return viewport->getMaximumVisibleWidth(); -} +int ListBox::getVisibleContentWidth() const noexcept { return viewport->getMaximumVisibleWidth(); } -ScrollBar* ListBox::getVerticalScrollBar() const noexcept -{ - return viewport->getVerticalScrollBar(); -} - -ScrollBar* ListBox::getHorizontalScrollBar() const noexcept -{ - return viewport->getHorizontalScrollBar(); -} +ScrollBar* ListBox::getVerticalScrollBar() const noexcept { return viewport->getVerticalScrollBar(); } +ScrollBar* ListBox::getHorizontalScrollBar() const noexcept { return viewport->getHorizontalScrollBar(); } void ListBox::colourChanged() { @@ -889,39 +871,42 @@ void ListBox::repaintRow (const int rowNumber) noexcept Image ListBox::createSnapshotOfRows (const SparseSet& rows, int& imageX, int& imageY) { Rectangle imageArea; - const int firstRow = getRowContainingPosition (0, viewport->getY()); + auto firstRow = getRowContainingPosition (0, viewport->getY()); for (int i = getNumRowsOnScreen() + 2; --i >= 0;) { - Component* rowComp = viewport->getComponentForRowIfOnscreen (firstRow + i); - - if (rowComp != nullptr && rows.contains (firstRow + i)) + if (rows.contains (firstRow + i)) { - const Point pos (getLocalPoint (rowComp, Point())); - const Rectangle rowRect (pos.getX(), pos.getY(), rowComp->getWidth(), rowComp->getHeight()); - imageArea = imageArea.getUnion (rowRect); + if (auto* rowComp = viewport->getComponentForRowIfOnscreen (firstRow + i)) + { + auto pos = getLocalPoint (rowComp, Point()); + + imageArea = imageArea.getUnion ({ pos.x, pos.y, rowComp->getWidth(), rowComp->getHeight() }); + } } } imageArea = imageArea.getIntersection (getLocalBounds()); imageX = imageArea.getX(); imageY = imageArea.getY(); + Image snapshot (Image::ARGB, imageArea.getWidth(), imageArea.getHeight(), true); for (int i = getNumRowsOnScreen() + 2; --i >= 0;) { - Component* rowComp = viewport->getComponentForRowIfOnscreen (firstRow + i); - - if (rowComp != nullptr && rows.contains (firstRow + i)) + if (rows.contains (firstRow + i)) { - Graphics g (snapshot); - g.setOrigin (getLocalPoint (rowComp, Point()) - imageArea.getPosition()); - - if (g.reduceClipRegion (rowComp->getLocalBounds())) + if (auto* rowComp = viewport->getComponentForRowIfOnscreen (firstRow + i)) { - g.beginTransparencyLayer (0.6f); - rowComp->paintEntireComponent (g, false); - g.endTransparencyLayer(); + Graphics g (snapshot); + g.setOrigin (getLocalPoint (rowComp, Point()) - imageArea.getPosition()); + + if (g.reduceClipRegion (rowComp->getLocalBounds())) + { + g.beginTransparencyLayer (0.6f); + rowComp->paintEntireComponent (g, false); + g.endTransparencyLayer(); + } } } } @@ -931,13 +916,12 @@ Image ListBox::createSnapshotOfRows (const SparseSet& rows, int& imageX, in void ListBox::startDragAndDrop (const MouseEvent& e, const SparseSet& rowsToDrag, const var& dragDescription, bool allowDraggingToOtherWindows) { - if (DragAndDropContainer* const dragContainer = DragAndDropContainer::findParentDragContainerFor (this)) + if (auto* dragContainer = DragAndDropContainer::findParentDragContainerFor (this)) { int x, y; - Image dragImage = createSnapshotOfRows (rowsToDrag, x, y); + auto dragImage = createSnapshotOfRows (rowsToDrag, x, y); - MouseEvent e2 (e.getEventRelativeTo (this)); - const Point p (x - e2.x, y - e2.y); + auto p = Point (x, y) - e.getEventRelativeTo (this).position.toInt(); dragContainer->startDragging (dragDescription, this, dragImage, allowDraggingToOtherWindows, &p); } else @@ -963,6 +947,6 @@ void ListBoxModel::selectedRowsChanged (int) {} void ListBoxModel::deleteKeyPressed (int) {} void ListBoxModel::returnKeyPressed (int) {} void ListBoxModel::listWasScrolled() {} -var ListBoxModel::getDragSourceDescription (const SparseSet&) { return var(); } -String ListBoxModel::getTooltipForRow (int) { return String(); } +var ListBoxModel::getDragSourceDescription (const SparseSet&) { return {}; } +String ListBoxModel::getTooltipForRow (int) { return {}; } MouseCursor ListBoxModel::getMouseCursorForRow (int) { return MouseCursor::NormalCursor; } diff --git a/source/modules/juce_gui_basics/widgets/juce_ListBox.h b/source/modules/juce_gui_basics/widgets/juce_ListBox.h index 436be0f29..31275dc68 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ListBox.h +++ b/source/modules/juce_gui_basics/widgets/juce_ListBox.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LISTBOX_H_INCLUDED -#define JUCE_LISTBOX_H_INCLUDED +#pragma once //============================================================================== @@ -60,7 +61,7 @@ public: and handle mouse clicks with listBoxItemClicked(). This method will be called whenever a custom component might need to be updated - e.g. - when the table is changed, or TableListBox::updateContent() is called. + when the list is changed, or ListBox::updateContent() is called. If you don't need a custom component for the specified row, then return nullptr. (Bear in mind that even if you're not creating a new component, you may still need to @@ -578,11 +579,11 @@ private: ScopedPointer viewport; ScopedPointer headerComponent; ScopedPointer mouseMoveSelector; - int totalItems, rowHeight, minimumRowWidth; - int outlineThickness; - int lastRowSelected; - bool multipleSelection, alwaysFlipSelection, hasDoneInitialUpdate, selectOnMouseDown; SparseSet selected; + int totalItems = 0, rowHeight = 22, minimumRowWidth = 0; + int outlineThickness = 0; + int lastRowSelected = -1; + bool multipleSelection = false, alwaysFlipSelection = false, hasDoneInitialUpdate = false, selectOnMouseDown = true; void selectRowInternal (int rowNumber, bool dontScrollToShowThisRow, bool deselectOthersFirst, bool isMouseClick); @@ -597,6 +598,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ListBox) }; - - -#endif // JUCE_LISTBOX_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp b/source/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp index bd91e28b7..c0ed84250 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_ProgressBar.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -49,7 +51,7 @@ void ProgressBar::setTextToDisplay (const String& text) void ProgressBar::lookAndFeelChanged() { - setOpaque (findColour (backgroundColourId).isOpaque()); + setOpaque (getLookAndFeel().isProgressBarOpaque (*this)); } void ProgressBar::colourChanged() diff --git a/source/modules/juce_gui_basics/widgets/juce_ProgressBar.h b/source/modules/juce_gui_basics/widgets/juce_ProgressBar.h index 23cffa0bf..5ce9410a3 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ProgressBar.h +++ b/source/modules/juce_gui_basics/widgets/juce_ProgressBar.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PROGRESSBAR_H_INCLUDED -#define JUCE_PROGRESSBAR_H_INCLUDED +#pragma once //============================================================================== @@ -106,6 +107,8 @@ public: */ virtual void drawProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String& textToShow) = 0; + + virtual bool isProgressBarOpaque (ProgressBar&) = 0; }; protected: @@ -130,6 +133,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgressBar) }; - - -#endif // JUCE_PROGRESSBAR_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_Slider.cpp b/source/modules/juce_gui_basics/widgets/juce_Slider.cpp index 86c13d34d..d6b23ea81 100644 --- a/source/modules/juce_gui_basics/widgets/juce_Slider.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_Slider.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -132,15 +134,16 @@ public: // interval setting. numDecimalPlaces = 7; - if (newInt != 0) + if (newInt != 0.0) { int v = std::abs (roundToInt (newInt * 10000000)); - while ((v % 10) == 0) - { - --numDecimalPlaces; - v /= 10; - } + if (v > 0) + while ((v % 10) == 0) + { + --numDecimalPlaces; + v /= 10; + } } // keep the current values inside the new range.. @@ -177,10 +180,10 @@ public: if (style == ThreeValueHorizontal || style == ThreeValueVertical) { - jassert ((double) valueMin.getValue() <= (double) valueMax.getValue()); + jassert (static_cast (valueMin.getValue()) <= static_cast (valueMax.getValue())); - newValue = jlimit ((double) valueMin.getValue(), - (double) valueMax.getValue(), + newValue = jlimit (static_cast (valueMin.getValue()), + static_cast (valueMax.getValue()), newValue); } @@ -217,10 +220,10 @@ public: if (style == TwoValueHorizontal || style == TwoValueVertical) { - if (allowNudgingOfOtherValues && newValue > (double) valueMax.getValue()) + if (allowNudgingOfOtherValues && newValue > static_cast (valueMax.getValue())) setMaxValue (newValue, notification, false); - newValue = jmin ((double) valueMax.getValue(), newValue); + newValue = jmin (static_cast (valueMax.getValue()), newValue); } else { @@ -254,10 +257,10 @@ public: if (style == TwoValueHorizontal || style == TwoValueVertical) { - if (allowNudgingOfOtherValues && newValue < (double) valueMin.getValue()) + if (allowNudgingOfOtherValues && newValue < static_cast (valueMin.getValue())) setMinValue (newValue, notification, false); - newValue = jmax ((double) valueMin.getValue(), newValue); + newValue = jmax (static_cast (valueMin.getValue()), newValue); } else { @@ -402,7 +405,7 @@ public: { const double newValue = owner.snapValue (owner.getValueFromText (label->getText()), notDragging); - if (newValue != (double) currentValue.getValue()) + if (newValue != static_cast (currentValue.getValue())) { DragInProgress drag (*this); setValue (newValue, sendNotificationSync); @@ -665,8 +668,8 @@ public: const float mousePos = isVertical() ? e.position.y : e.position.x; const float normalPosDistance = std::abs (getLinearSliderPos (currentValue.getValue()) - mousePos); - const float minPosDistance = std::abs (getLinearSliderPos (valueMin.getValue()) - 0.1f - mousePos); - const float maxPosDistance = std::abs (getLinearSliderPos (valueMax.getValue()) + 0.1f - mousePos); + const float minPosDistance = std::abs (getLinearSliderPos (valueMin.getValue()) + (isVertical() ? 0.1f : -0.1f) - mousePos); + const float maxPosDistance = std::abs (getLinearSliderPos (valueMax.getValue()) + (isVertical() ? -0.1f : 0.1f) - mousePos); if (isTwoValue) return maxPosDistance <= minPosDistance ? 2 : 1; @@ -791,7 +794,7 @@ public: const double maxSpeed = jmax (200, sliderRegionSize); double speed = jlimit (0.0, maxSpeed, (double) std::abs (mouseDiff)); - if (speed != 0) + if (speed != 0.0) { speed = 0.2 * velocityModeSensitivity * (1.0 + std::sin (double_Pi * (1.5 + jmin (0.5, velocityModeOffset @@ -840,7 +843,7 @@ public: sliderBeingDragged = getThumbIndexAt (e); - minMaxDiff = (double) valueMax.getValue() - (double) valueMin.getValue(); + minMaxDiff = static_cast (valueMax.getValue()) - static_cast (valueMin.getValue()); lastAngle = rotaryParams.startAngleRadians + (rotaryParams.endAngleRadians - rotaryParams.startAngleRadians) @@ -920,7 +923,7 @@ public: if (e.mods.isShiftDown()) setMaxValue (getMinValue() + minMaxDiff, dontSendNotification, true); else - minMaxDiff = (double) valueMax.getValue() - (double) valueMin.getValue(); + minMaxDiff = static_cast (valueMax.getValue()) - static_cast (valueMin.getValue()); } else if (sliderBeingDragged == 2) { @@ -930,7 +933,7 @@ public: if (e.mods.isShiftDown()) setMinValue (getMaxValue() - minMaxDiff, dontSendNotification, true); else - minMaxDiff = (double) valueMax.getValue() - (double) valueMin.getValue(); + minMaxDiff = static_cast (valueMax.getValue()) - static_cast (valueMin.getValue()); } mousePosWhenLastDragged = e.position; @@ -946,7 +949,7 @@ public: { restoreMouseIfHidden(); - if (sendChangeOnlyOnRelease && valueOnMouseDown != (double) currentValue.getValue()) + if (sendChangeOnlyOnRelease && valueOnMouseDown != static_cast (currentValue.getValue())) triggerChangeMessage (sendNotificationAsync); currentDrag = nullptr; @@ -1010,11 +1013,11 @@ public: if (valueBox != nullptr) valueBox->hideEditor (false); - const double value = (double) currentValue.getValue(); + const double value = static_cast (currentValue.getValue()); const double delta = getMouseWheelDelta (value, (std::abs (wheel.deltaX) > std::abs (wheel.deltaY) ? -wheel.deltaX : wheel.deltaY) * (wheel.isReversed ? -1.0f : 1.0f)); - if (delta != 0) + if (delta != 0.0) { const double newValue = value + jmax (interval, std::abs (delta)) * (delta < 0 ? -1.0 : 1.0); @@ -1044,22 +1047,20 @@ public: void restoreMouseIfHidden() { - const Array& mouseSources = Desktop::getInstance().getMouseSources(); - - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) + for (auto& ms : Desktop::getInstance().getMouseSources()) { - if (mi->isUnboundedMouseMovementEnabled()) + if (ms.isUnboundedMouseMovementEnabled()) { - mi->enableUnboundedMouseMovement (false); + ms.enableUnboundedMouseMovement (false); const double pos = sliderBeingDragged == 2 ? getMaxValue() : (sliderBeingDragged == 1 ? getMinValue() - : (double) currentValue.getValue()); + : static_cast (currentValue.getValue())); Point mousePos; if (isRotary()) { - mousePos = mi->getLastMouseDownPosition(); + mousePos = ms.getLastMouseDownPosition(); const float delta = (float) (pixelsForFullDragExtent * (owner.valueToProportionOfLength (valueOnMouseDown) - owner.valueToProportionOfLength (pos))); @@ -1080,7 +1081,7 @@ public: isVertical() ? pixelPos : (owner.getHeight() / 2.0f))); } - mi->setScreenPosition (mousePos); + ms.setScreenPosition (mousePos); } } } diff --git a/source/modules/juce_gui_basics/widgets/juce_Slider.h b/source/modules/juce_gui_basics/widgets/juce_Slider.h index e7cd686d4..fd2d205ed 100644 --- a/source/modules/juce_gui_basics/widgets/juce_Slider.h +++ b/source/modules/juce_gui_basics/widgets/juce_Slider.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SLIDER_H_INCLUDED -#define JUCE_SLIDER_H_INCLUDED +#pragma once //============================================================================== @@ -128,7 +129,7 @@ public: /** Changes the type of slider interface being used. @param newStyle the type of interface - @see setRotaryParameters, setVelocityBasedMode, + @see setRotaryParameters, setVelocityBasedMode */ void setSliderStyle (SliderStyle newStyle); @@ -141,19 +142,22 @@ public: struct RotaryParameters { /** The angle (in radians, clockwise from the top) at which - the slider's minimum value is represented. */ + the slider's minimum value is represented. + */ float startAngleRadians; /** The angle (in radians, clockwise from the top) at which the slider's maximum value is represented. This must be - greater than startAngleRadians. */ + greater than startAngleRadians. + */ float endAngleRadians; /** Determines what happens when a circular drag action rotates beyond the minimum or maximum angle. If true, the value will stop changing until the mouse moves back the way it came; if false, the value will snap back to the value nearest to the mouse. Note that this has - no effect if the drag mode is vertical or horizontal.*/ + no effect if the drag mode is vertical or horizontal. + */ bool stopAtEnd; }; @@ -930,5 +934,3 @@ private: /** This typedef is just for compatibility with old code - newer code should use the Slider::Listener class directly. */ typedef Slider::Listener SliderListener; - -#endif // JUCE_SLIDER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp b/source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp index 8f2fdf5ec..22375b45b 100644 --- a/source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -92,15 +94,15 @@ int TableHeaderComponent::getNumColumns (const bool onlyCountVisibleColumns) con String TableHeaderComponent::getColumnName (const int columnId) const { - if (const ColumnInfo* const ci = getInfoForId (columnId)) + if (auto* ci = getInfoForId (columnId)) return ci->name; - return String(); + return {}; } void TableHeaderComponent::setColumnName (const int columnId, const String& newName) { - if (ColumnInfo* const ci = getInfoForId (columnId)) + if (auto* ci = getInfoForId (columnId)) { if (ci->name != newName) { diff --git a/source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h b/source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h index bcdca74d1..2b0a2fbc7 100644 --- a/source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h +++ b/source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TABLEHEADERCOMPONENT_H_INCLUDED -#define JUCE_TABLEHEADERCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -436,6 +437,3 @@ private: /** This typedef is just for compatibility with old code - newer code should use the TableHeaderComponent::Listener class directly. */ typedef TableHeaderComponent::Listener TableHeaderListener; - - -#endif // JUCE_TABLEHEADERCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_TableListBox.cpp b/source/modules/juce_gui_basics/widgets/juce_TableListBox.cpp index deb7785bb..b9b4b9f2a 100644 --- a/source/modules/juce_gui_basics/widgets/juce_TableListBox.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_TableListBox.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -206,10 +208,10 @@ public: const int columnId = owner.getHeader().getColumnIdAtX (getMouseXYRelative().getX()); if (columnId != 0) - if (TableListBoxModel* m = owner.getModel()) + if (auto* m = owner.getModel()) return m->getCellTooltip (row, columnId); - return String(); + return {}; } Component* findChildComponentForColumn (const int columnId) const @@ -477,8 +479,8 @@ void TableListBoxModel::deleteKeyPressed (int) {} void TableListBoxModel::returnKeyPressed (int) {} void TableListBoxModel::listWasScrolled() {} -String TableListBoxModel::getCellTooltip (int /*rowNumber*/, int /*columnId*/) { return String(); } -var TableListBoxModel::getDragSourceDescription (const SparseSet&) { return var(); } +String TableListBoxModel::getCellTooltip (int /*rowNumber*/, int /*columnId*/) { return {}; } +var TableListBoxModel::getDragSourceDescription (const SparseSet&) { return {}; } Component* TableListBoxModel::refreshComponentForCell (int, int, bool, Component* existingComponentToUpdate) { diff --git a/source/modules/juce_gui_basics/widgets/juce_TableListBox.h b/source/modules/juce_gui_basics/widgets/juce_TableListBox.h index ddfb6b7c1..8454e959c 100644 --- a/source/modules/juce_gui_basics/widgets/juce_TableListBox.h +++ b/source/modules/juce_gui_basics/widgets/juce_TableListBox.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TABLELISTBOX_H_INCLUDED -#define JUCE_TABLELISTBOX_H_INCLUDED +#pragma once //============================================================================== @@ -344,6 +345,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableListBox) }; - - -#endif // JUCE_TABLELISTBOX_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/source/modules/juce_gui_basics/widgets/juce_TextEditor.cpp index 413ac80b1..21fd56ea8 100644 --- a/source/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_TextEditor.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -49,7 +51,7 @@ struct TextAtom return atomText.substring (0, numChars); if (isNewLine()) - return String(); + return {}; return String::repeatedString (String::charToString (passwordCharacter), numChars); } @@ -80,11 +82,11 @@ public: { int i = 0; - if (TextAtom* const lastAtom = atoms.getLast()) + if (auto* lastAtom = atoms.getLast()) { if (! CharacterFunctions::isWhitespace (lastAtom->atomText.getLastCharacter())) { - TextAtom* const first = other.atoms.getUnchecked(0); + auto* first = other.atoms.getUnchecked(0); if (! CharacterFunctions::isWhitespace (first->atomText[0])) { @@ -116,9 +118,8 @@ public: for (int i = 0; i < atoms.size(); ++i) { - TextAtom* const atom = atoms.getUnchecked(i); - - const int nextIndex = index + atom->numChars; + auto* atom = atoms.getUnchecked(i); + auto nextIndex = index + atom->numChars; if (index == indexToBreakAt) { @@ -130,7 +131,7 @@ public: } else if (indexToBreakAt >= index && indexToBreakAt < nextIndex) { - TextAtom* const secondAtom = new TextAtom(); + auto* secondAtom = new TextAtom(); secondAtom->atomText = atom->atomText.substring (indexToBreakAt - index); secondAtom->width = font.getStringWidthFloat (secondAtom->getText (passwordChar)); @@ -164,17 +165,17 @@ public: void appendSubstring (MemoryOutputStream& mo, const Range range) const { int index = 0; - for (int i = 0; i < atoms.size(); ++i) + + for (auto* atom : atoms) { - const TextAtom* const atom = atoms.getUnchecked (i); - const int nextIndex = index + atom->numChars; + auto nextIndex = index + atom->numChars; if (range.getStart() < nextIndex) { if (range.getEnd() <= index) break; - const Range r ((range - index).getIntersectionWith (Range (0, (int) atom->numChars))); + auto r = (range - index).getIntersectionWith (Range (0, (int) atom->numChars)); if (! r.isEmpty()) mo << atom->atomText.substring (r.getStart(), r.getEnd()); @@ -188,8 +189,8 @@ public: { int total = 0; - for (int i = atoms.size(); --i >= 0;) - total += atoms.getUnchecked(i)->numChars; + for (auto* atom : atoms) + total += atom->numChars; return total; } @@ -200,11 +201,8 @@ public: { font = newFont; - for (int i = atoms.size(); --i >= 0;) - { - TextAtom* const atom = atoms.getUnchecked(i); + for (auto* atom : atoms) atom->width = newFont.getStringWidthFloat (atom->getText (passwordChar)); - } } } @@ -216,12 +214,12 @@ public: private: void initialiseAtoms (const String& textToParse, const juce_wchar passwordChar) { - String::CharPointerType text (textToParse.getCharPointer()); + auto text = textToParse.getCharPointer(); while (! text.isEmpty()) { size_t numChars = 0; - String::CharPointerType start (text); + auto start = text; // create a whitespace atom unless it starts with non-ws if (text.isWhitespace() && *text != '\r' && *text != '\n') @@ -261,7 +259,7 @@ private: } } - TextAtom* const atom = atoms.add (new TextAtom()); + auto* atom = atoms.add (new TextAtom()); atom->atomText = String (start, numChars); atom->width = font.getStringWidthFloat (atom->getText (passwordChar)); @@ -278,21 +276,11 @@ class TextEditor::Iterator { public: Iterator (const OwnedArray& sectionList, - const float wrapWidth, - const juce_wchar passwordChar) - : indexInText (0), - lineY (0), - lineHeight (0), - maxDescent (0), - atomX (0), - atomRight (0), - atom (0), - currentSection (nullptr), - sections (sectionList), - sectionIndex (0), - atomIndex (0), + float wrapWidth, juce_wchar passwordChar, float spacing) + : sections (sectionList), wordWrapWidth (wrapWidth), - passwordCharacter (passwordChar) + passwordCharacter (passwordChar), + lineSpacing (spacing) { jassert (wordWrapWidth > 0); @@ -319,6 +307,7 @@ public: atomIndex (other.atomIndex), wordWrapWidth (other.wordWrapWidth), passwordCharacter (other.passwordCharacter), + lineSpacing (other.lineSpacing), tempAtom (other.tempAtom) { } @@ -337,7 +326,7 @@ public: atomX = 0; if (tempAtom.numChars > 0) - lineY += lineHeight; + lineY += lineHeight * lineSpacing; indexInText += tempAtom.numChars; @@ -359,14 +348,15 @@ public: } } - bool forceNewLine = false; - if (sectionIndex >= sections.size()) { moveToEndOfLastAtom(); return false; } - else if (atomIndex >= currentSection->atoms.size() - 1) + + bool forceNewLine = false; + + if (atomIndex >= currentSection->atoms.size() - 1) { if (atomIndex >= currentSection->atoms.size()) { @@ -381,7 +371,7 @@ public: } else { - const TextAtom* const lastAtom = currentSection->atoms.getUnchecked (atomIndex); + auto* lastAtom = currentSection->atoms.getUnchecked (atomIndex); if (! lastAtom->isWhitespace()) { @@ -393,12 +383,12 @@ public: for (int section = sectionIndex + 1; section < sections.size(); ++section) { - const UniformTextSection* const s = sections.getUnchecked (section); + auto* s = sections.getUnchecked (section); if (s->atoms.size() == 0) break; - const TextAtom* const nextAtom = s->atoms.getUnchecked (0); + auto* nextAtom = s->atoms.getUnchecked (0); if (nextAtom->isWhitespace()) break; @@ -472,11 +462,11 @@ public: void beginNewLine() { atomX = 0; - lineY += lineHeight; + lineY += lineHeight * lineSpacing; int tempSectionIndex = sectionIndex; int tempAtomIndex = atomIndex; - const UniformTextSection* section = sections.getUnchecked (tempSectionIndex); + auto* section = sections.getUnchecked (tempSectionIndex); lineHeight = section->font.getHeight(); maxDescent = section->font.getDescent(); @@ -500,7 +490,7 @@ public: checkSize = true; } - const TextAtom* const nextAtom = section->atoms.getUnchecked (tempAtomIndex); + auto* nextAtom = section->atoms.getUnchecked (tempAtomIndex); if (nextAtom == nullptr) break; @@ -547,7 +537,7 @@ public: const float startX = indexToX (selected.getStart()); const float endX = indexToX (selected.getEnd()); - area.add (startX, lineY, endX - startX, lineHeight); + area.add (startX, lineY, endX - startX, lineHeight * lineSpacing); } void drawUnderline (Graphics& g, const Range underline, const Colour colour) const @@ -635,7 +625,8 @@ public: int j; for (j = 0; j < numGlyphs; ++j) { - const PositionedGlyph& pg = g.getGlyph(j); + auto& pg = g.getGlyph(j); + if ((pg.getLeft() + pg.getRight()) / 2 > xToFind) break; } @@ -664,20 +655,21 @@ public: } //============================================================================== - int indexInText; - float lineY, lineHeight, maxDescent; - float atomX, atomRight; - const TextAtom* atom; - const UniformTextSection* currentSection; + int indexInText = 0; + float lineY = 0, lineHeight = 0, maxDescent = 0; + float atomX = 0, atomRight = 0; + const TextAtom* atom = nullptr; + const UniformTextSection* currentSection = nullptr; private: const OwnedArray& sections; - int sectionIndex, atomIndex; + int sectionIndex = 0, atomIndex = 0; const float wordWrapWidth; const juce_wchar passwordCharacter; + const float lineSpacing; TextAtom tempAtom; - Iterator& operator= (const Iterator&); + Iterator& operator= (const Iterator&) = delete; void moveToEndOfLastAtom() { @@ -688,7 +680,7 @@ private: if (atom->isNewLine()) { atomX = 0.0f; - lineY += lineHeight; + lineY += lineHeight * lineSpacing; } } } @@ -783,8 +775,9 @@ public: int getSizeInUnits() override { int n = 16; - for (int i = removedSections.size(); --i >= 0;) - n += removedSections.getUnchecked (i)->getTotalLength(); + + for (auto* s : removedSections) + n += s->getTotalLength(); return n; } @@ -848,10 +841,7 @@ private: class TextEditorViewport : public Viewport { public: - TextEditorViewport (TextEditor& ed) - : owner (ed), lastWordWrapWidth (0), rentrant (false) - { - } + TextEditorViewport (TextEditor& ed) : owner (ed) {} void visibleAreaChanged (const Rectangle&) override { @@ -873,8 +863,8 @@ public: private: TextEditor& owner; - float lastWordWrapWidth; - bool rentrant; + float lastWordWrapWidth = 0; + bool rentrant = false; JUCE_DECLARE_NON_COPYABLE (TextEditorViewport) }; @@ -900,28 +890,6 @@ namespace TextEditorDefs TextEditor::TextEditor (const String& name, const juce_wchar passwordChar) : Component (name), - borderSize (1, 1, 1, 3), - readOnly (false), - caretVisible (true), - multiline (false), - wordWrap (false), - returnKeyStartsNewLine (false), - popupMenuEnabled (true), - selectAllTextWhenFocused (false), - scrollbarVisible (true), - wasFocused (false), - keepCaretOnScreen (true), - tabKeyUsed (false), - menuActive (false), - valueTextNeedsUpdating (false), - consumeEscAndReturnKeys (true), - styleChanged (false), - leftIndent (4), - topIndent (4), - lastTransactionTime (0), - currentFont (14.0f), - totalNumChars (0), - caretPosition (0), passwordCharacter (passwordChar), keyboardType (TextInputTarget::textKeyboard), dragType (notDragging) @@ -941,7 +909,7 @@ TextEditor::TextEditor (const String& name, TextEditor::~TextEditor() { if (wasFocused) - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) peer->dismissPendingTextInput(); textValue.removeListener (textHolder); @@ -1059,14 +1027,15 @@ void TextEditor::setFont (const Font& newFont) scrollToMakeSureCursorIsVisible(); } -void TextEditor::applyFontToAllText (const Font& newFont) +void TextEditor::applyFontToAllText (const Font& newFont, bool changeCurrentFont) { - currentFont = newFont; - const Colour overallColour (findColour (textColourId)); + if (changeCurrentFont) + currentFont = newFont; + + auto overallColour = findColour (textColourId); - for (int i = sections.size(); --i >= 0;) + for (auto* uts : sections) { - UniformTextSection* const uts = sections.getUnchecked (i); uts->setFont (newFont, passwordCharacter); uts->colour = overallColour; } @@ -1077,11 +1046,21 @@ void TextEditor::applyFontToAllText (const Font& newFont) repaint(); } +void TextEditor::applyColourToAllText (const Colour& newColour, bool changeCurrentTextColour) +{ + for (auto* uts : sections) + uts->colour = newColour; + + if (changeCurrentTextColour) + setColour (TextEditor::textColourId, newColour); + else + repaint(); +} + void TextEditor::colourChanged() { setOpaque (findColour (backgroundColourId).isOpaque()); repaint(); - styleChanged = true; } void TextEditor::lookAndFeelChanged() @@ -1195,11 +1174,14 @@ void TextEditor::setText (const String& newText, { const int newLength = newText.length(); - if (newLength != getTotalNumChars() || getText() != newText || styleChanged) + if (newLength != getTotalNumChars() || getText() != newText) { + if (! sendTextChangeMessage) + textValue.removeListener (textHolder); + textValue = newText; - int oldCursorPos = caretPosition; + auto oldCursorPos = caretPosition; const bool cursorWasAtEnd = oldCursorPos >= getTotalNumChars(); clearInternal (nullptr); @@ -1216,13 +1198,13 @@ void TextEditor::setText (const String& newText, if (sendTextChangeMessage) textChanged(); + else + textValue.addListener (textHolder); updateTextHolderSize(); scrollToMakeSureCursorIsVisible(); undoManager.clearUndoHistory(); - styleChanged = false; - repaint(); } } @@ -1276,7 +1258,7 @@ void TextEditor::timerCallbackInt() if (hasKeyboardFocus (false) && ! isCurrentlyBlockedByAnotherModalComponent()) wasFocused = true; - const unsigned int now = Time::getApproximateMillisecondCounter(); + auto now = Time::getApproximateMillisecondCounter(); if (now > lastTransactionTime + 200) newTransaction(); @@ -1292,11 +1274,11 @@ void TextEditor::repaintText (const Range range) if (wordWrapWidth > 0) { - Iterator i (sections, wordWrapWidth, passwordCharacter); + Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing); i.getCharPosition (range.getStart(), x, y, lh); - const int y1 = (int) y; + auto y1 = (int) y; int y2; if (range.getEnd() >= getTotalNumChars()) @@ -1351,8 +1333,7 @@ void TextEditor::scrollEditorToPositionCaret (const int desiredCaretX, { updateCaretPosition(); - - const Rectangle caretPos (getCaretRectangle()); + auto caretPos = getCaretRectangle(); int vx = caretPos.getX() - desiredCaretX; int vy = caretPos.getY() - desiredCaretY; @@ -1387,7 +1368,7 @@ Rectangle TextEditor::getCaretRectangle() float cursorHeight = currentFont.getHeight(); // (in case the text is empty and the call below doesn't set this value) getCharPosition (caretPosition, cursorX, cursorY, cursorHeight); - return Rectangle (roundToInt (cursorX), roundToInt (cursorY), 2, roundToInt (cursorHeight)); + return { roundToInt (cursorX), roundToInt (cursorY), 2, roundToInt (cursorHeight) }; } //============================================================================== @@ -1407,7 +1388,7 @@ void TextEditor::updateTextHolderSize() { float maxWidth = 0.0f; - Iterator i (sections, wordWrapWidth, passwordCharacter); + Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing); while (i.next()) maxWidth = jmax (maxWidth, i.atomRight); @@ -1451,10 +1432,9 @@ void TextEditor::scrollToMakeSureCursorIsVisible() if (keepCaretOnScreen) { - Point viewPos (viewport->getViewPosition()); - const Rectangle caretRect (getCaretRectangle()); - - const Point relativeCursor = caretRect.getPosition() - viewPos; + auto viewPos = viewport->getViewPosition(); + auto caretRect = getCaretRectangle(); + auto relativeCursor = caretRect.getPosition() - viewPos; if (relativeCursor.x < jmax (1, proportionOfWidth (0.05f))) { @@ -1490,11 +1470,11 @@ void TextEditor::moveCaretTo (const int newPosition, const bool isSelecting) { moveCaret (newPosition); - const Range oldSelection (selection); + auto oldSelection = selection; if (dragType == notDragging) { - if (abs (getCaretPosition() - selection.getStart()) < abs (getCaretPosition() - selection.getEnd())) + if (std::abs (getCaretPosition() - selection.getStart()) < std::abs (getCaretPosition() - selection.getEnd())) dragType = draggingSelectionStart; else dragType = draggingSelectionEnd; @@ -1566,7 +1546,7 @@ void TextEditor::copy() { if (passwordCharacter == 0) { - const String selectedText (getHighlightedText()); + auto selectedText = getHighlightedText(); if (selectedText.isNotEmpty()) SystemClipboard::copyTextToClipboard (selectedText); @@ -1577,7 +1557,7 @@ void TextEditor::paste() { if (! isReadOnly()) { - const String clip (SystemClipboard::getTextFromClipboard()); + auto clip = SystemClipboard::getTextFromClipboard(); if (clip.isNotEmpty()) insertTextAtCaret (clip); @@ -1601,10 +1581,10 @@ void TextEditor::drawContent (Graphics& g) if (wordWrapWidth > 0) { g.setOrigin (leftIndent, topIndent); - const Rectangle clip (g.getClipBounds()); + auto clip = g.getClipBounds(); Colour selectedTextColour; - Iterator i (sections, wordWrapWidth, passwordCharacter); + Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing); if (! selection.isEmpty()) { @@ -1648,7 +1628,7 @@ void TextEditor::drawContent (Graphics& g) { const Range underlinedSection = underlinedSections.getReference (j); - Iterator i2 (sections, wordWrapWidth, passwordCharacter); + Iterator i2 (sections, wordWrapWidth, passwordCharacter, lineSpacing); while (i2.next() && i2.lineY < clip.getBottom()) { @@ -1788,8 +1768,8 @@ void TextEditor::mouseDoubleClick (const MouseEvent& e) } else { - const String t (getText()); - const int totalLength = getTotalNumChars(); + auto t = getText(); + auto totalLength = getTotalNumChars(); while (tokenEnd < totalLength) { @@ -1882,7 +1862,7 @@ bool TextEditor::moveCaretUp (bool selecting) if (! isMultiLine()) return moveCaretToStartOfLine (selecting); - const Rectangle caretPos (getCaretRectangle().toFloat()); + auto caretPos = getCaretRectangle().toFloat(); return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getY() - 1.0f), selecting); } @@ -1891,7 +1871,7 @@ bool TextEditor::moveCaretDown (bool selecting) if (! isMultiLine()) return moveCaretToEndOfLine (selecting); - const Rectangle caretPos (getCaretRectangle().toFloat()); + auto caretPos = getCaretRectangle().toFloat(); return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getBottom() + 1.0f), selecting); } @@ -1900,7 +1880,7 @@ bool TextEditor::pageUp (bool selecting) if (! isMultiLine()) return moveCaretToStartOfLine (selecting); - const Rectangle caretPos (getCaretRectangle().toFloat()); + auto caretPos = getCaretRectangle().toFloat(); return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getY() - viewport->getViewHeight()), selecting); } @@ -1909,13 +1889,13 @@ bool TextEditor::pageDown (bool selecting) if (! isMultiLine()) return moveCaretToEndOfLine (selecting); - const Rectangle caretPos (getCaretRectangle().toFloat()); + auto caretPos = getCaretRectangle().toFloat(); return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getBottom() + viewport->getViewHeight()), selecting); } void TextEditor::scrollByLines (int deltaLines) { - if (ScrollBar* scrollbar = viewport->getVerticalScrollBar()) + if (auto* scrollbar = viewport->getVerticalScrollBar()) scrollbar->moveScrollbarInSteps (deltaLines); } @@ -1938,7 +1918,7 @@ bool TextEditor::moveCaretToTop (bool selecting) bool TextEditor::moveCaretToStartOfLine (bool selecting) { - const Rectangle caretPos (getCaretRectangle().toFloat()); + auto caretPos = getCaretRectangle().toFloat(); return moveCaretWithTransaction (indexAtPosition (0.0f, caretPos.getY()), selecting); } @@ -1949,7 +1929,7 @@ bool TextEditor::moveCaretToEnd (bool selecting) bool TextEditor::moveCaretToEndOfLine (bool selecting) { - const Rectangle caretPos (getCaretRectangle().toFloat()); + auto caretPos = getCaretRectangle().toFloat(); return moveCaretWithTransaction (indexAtPosition ((float) textHolder->getWidth(), caretPos.getY()), selecting); } @@ -2084,7 +2064,7 @@ void TextEditor::focusGained (FocusChangeType) repaint(); updateCaretPosition(); - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) if (! isReadOnly()) peer->textInputRequired (peer->globalToLocal (getScreenPosition()), *this); } @@ -2098,7 +2078,7 @@ void TextEditor::focusLost (FocusChangeType) underlinedSections.clear(); - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) peer->dismissPendingTextInput(); updateCaretPosition(); @@ -2306,9 +2286,8 @@ void TextEditor::remove (Range range, UndoManager* const um, const int care if (range.getEnd() <= range.getStart()) break; - UniformTextSection* const section = sections.getUnchecked (i); - - const int nextIndex = index + section->getTotalLength(); + auto* section = sections.getUnchecked (i); + auto nextIndex = index + section->getTotalLength(); if (range.getStart() <= index && range.getEnd() >= nextIndex) removedSections.add (new UniformTextSection (*section)); @@ -2324,19 +2303,19 @@ void TextEditor::remove (Range range, UndoManager* const um, const int care } else { - Range remainingRange (range); + auto remainingRange = range; for (int i = 0; i < sections.size(); ++i) { - UniformTextSection* const section = sections.getUnchecked (i); + auto* section = sections.getUnchecked (i); const int nextIndex = index + section->getTotalLength(); if (remainingRange.getStart() <= index && remainingRange.getEnd() >= nextIndex) { sections.remove (i); - remainingRange.setEnd (remainingRange.getEnd() - (nextIndex - index)); + if (remainingRange.isEmpty()) break; @@ -2374,7 +2353,7 @@ String TextEditor::getText() const String TextEditor::getTextInRange (const Range& range) const { if (range.isEmpty()) - return String(); + return {}; MemoryOutputStream mo; mo.preallocate ((size_t) jmin (getTotalNumChars(), range.getLength())); @@ -2383,8 +2362,8 @@ String TextEditor::getTextInRange (const Range& range) const for (int i = 0; i < sections.size(); ++i) { - const UniformTextSection* const s = sections.getUnchecked (i); - const int nextIndex = index + s->getTotalLength(); + auto* s = sections.getUnchecked (i); + auto nextIndex = index + s->getTotalLength(); if (range.getStart() < nextIndex) { @@ -2429,7 +2408,7 @@ void TextEditor::getCharPosition (const int index, float& cx, float& cy, float& if (wordWrapWidth > 0 && sections.size() > 0) { - Iterator i (sections, wordWrapWidth, passwordCharacter); + Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing); i.getCharPosition (index, cx, cy, lineHeight); } @@ -2446,7 +2425,7 @@ int TextEditor::indexAtPosition (const float x, const float y) if (wordWrapWidth > 0) { - Iterator i (sections, wordWrapWidth, passwordCharacter); + Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing); while (i.next()) { @@ -2470,8 +2449,8 @@ int TextEditor::indexAtPosition (const float x, const float y) //============================================================================== int TextEditor::findWordBreakAfter (const int position) const { - const String t (getTextInRange (Range (position, position + 512))); - const int totalLength = t.length(); + auto t = getTextInRange (Range (position, position + 512)); + auto totalLength = t.length(); int i = 0; while (i < totalLength && CharacterFunctions::isWhitespace (t[i])) @@ -2493,8 +2472,8 @@ int TextEditor::findWordBreakBefore (const int position) const if (position <= 0) return 0; - const int startOfBuffer = jmax (0, position - 512); - const String t (getTextInRange (Range (startOfBuffer, position))); + auto startOfBuffer = jmax (0, position - 512); + auto t = getTextInRange (Range (startOfBuffer, position)); int i = position - startOfBuffer; @@ -2503,7 +2482,7 @@ int TextEditor::findWordBreakBefore (const int position) const if (i > 0) { - const int type = TextEditorDefs::getCharacterCategory (t [i - 1]); + auto type = TextEditorDefs::getCharacterCategory (t [i - 1]); while (i > 0 && type == TextEditorDefs::getCharacterCategory (t [i - 1])) --i; @@ -2527,8 +2506,8 @@ void TextEditor::coalesceSimilarSections() { for (int i = 0; i < sections.size() - 1; ++i) { - UniformTextSection* const s1 = sections.getUnchecked (i); - UniformTextSection* const s2 = sections.getUnchecked (i + 1); + auto* s1 = sections.getUnchecked (i); + auto* s2 = sections.getUnchecked (i + 1); if (s1->font == s2->font && s1->colour == s2->colour) diff --git a/source/modules/juce_gui_basics/widgets/juce_TextEditor.h b/source/modules/juce_gui_basics/widgets/juce_TextEditor.h index fedb00bbd..30a646514 100644 --- a/source/modules/juce_gui_basics/widgets/juce_TextEditor.h +++ b/source/modules/juce_gui_basics/widgets/juce_TextEditor.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TEXTEDITOR_H_INCLUDED -#define JUCE_TEXTEDITOR_H_INCLUDED +#pragma once //============================================================================== @@ -206,8 +207,8 @@ public: textColourId = 0x1000201, /**< The colour that will be used when text is added to the editor. Note that because the editor can contain multiple colours, calling this - method won't change the colour of existing text - to do that, call - applyFontToAllText() after calling this method.*/ + method won't change the colour of existing text - to do that, use + the applyColourToAllText() method */ highlightColourId = 0x1000202, /**< The colour with which to fill the background of highlighted sections of the text - this can be transparent if you don't want to show any @@ -237,16 +238,27 @@ public: void setFont (const Font& newFont); /** Applies a font to all the text in the editor. - This will also set the current font to use for any new text that's added. + + If the changeCurrentFont argument is true then this will also set the + new font as the font to be used for any new text that's added. + @see setFont */ - void applyFontToAllText (const Font& newFont); + void applyFontToAllText (const Font& newFont, bool changeCurrentFont = true); /** Returns the font that's currently being used for new text. + @see setFont */ const Font& getFont() const noexcept { return currentFont; } + /** Applies a colour to all the text in the editor. + + If the changeCurrentTextColour argument is true then this will also set the + new colour as the colour to be used for any new text that's added. + */ + void applyColourToAllText (const Colour& newColour, bool changeCurrentTextColour = true); + //============================================================================== /** If set to true, focusing on the editor will highlight all its text. @@ -463,6 +475,16 @@ public: */ void setScrollToShowCursor (bool shouldScrollToShowCaret); + /** Sets the line spacing of the TextEditor. + + The default (and minimum) value is 1.0 and values > 1.0 will increase the line spacing as a + multiple of the line height e.g. for double-spacing call this method with an argument of 2.0. + */ + void setLineSpacing (float newLineSpacing) noexcept { lineSpacing = jmax (1.0f, newLineSpacing); } + + /** Returns the current line spacing of the TextEditor. */ + float getLineSpacing() const noexcept { return lineSpacing; } + //============================================================================== void moveCaretToEnd(); bool moveCaretLeft (bool moveInWholeWordSteps, bool selecting); @@ -670,32 +692,31 @@ private: ScopedPointer viewport; TextHolderComponent* textHolder; - BorderSize borderSize; - - bool readOnly; - bool caretVisible; - bool multiline; - bool wordWrap; - bool returnKeyStartsNewLine; - bool popupMenuEnabled; - bool selectAllTextWhenFocused; - bool scrollbarVisible; - bool wasFocused; - bool keepCaretOnScreen; - bool tabKeyUsed; - bool menuActive; - bool valueTextNeedsUpdating; - bool consumeEscAndReturnKeys; - bool styleChanged; + BorderSize borderSize { 1, 1, 1, 3 }; + + bool readOnly = false; + bool caretVisible = true; + bool multiline = false; + bool wordWrap = false; + bool returnKeyStartsNewLine = false; + bool popupMenuEnabled = true; + bool selectAllTextWhenFocused = false; + bool scrollbarVisible = true; + bool wasFocused = false; + bool keepCaretOnScreen = true; + bool tabKeyUsed = false; + bool menuActive = false; + bool valueTextNeedsUpdating = false; + bool consumeEscAndReturnKeys = true; UndoManager undoManager; ScopedPointer caret; Range selection; - int leftIndent, topIndent; - unsigned int lastTransactionTime; - Font currentFont; - mutable int totalNumChars; - int caretPosition; + int leftIndent = 4, topIndent = 4; + unsigned int lastTransactionTime = 0; + Font currentFont { 14.0f }; + mutable int totalNumChars = 0; + int caretPosition = 0; OwnedArray sections; String textToShowWhenEmpty; Colour colourForTextWhenEmpty; @@ -703,6 +724,7 @@ private: OptionalScopedPointer inputFilter; Value textValue; VirtualKeyboardType keyboardType; + float lineSpacing = 1.0f; enum { @@ -748,6 +770,3 @@ private: /** This typedef is just for compatibility with old code - newer code should use the TextEditor::Listener class directly. */ typedef TextEditor::Listener TextEditorListener; - - -#endif // JUCE_TEXTEDITOR_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_Toolbar.cpp b/source/modules/juce_gui_basics/widgets/juce_Toolbar.cpp index 5c450d988..a2bab5484 100644 --- a/source/modules/juce_gui_basics/widgets/juce_Toolbar.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_Toolbar.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -175,7 +177,7 @@ public: { for (int i = 0; i < getNumChildComponents(); ++i) { - if (ToolbarItemComponent* const tc = dynamic_cast (getChildComponent (i))) + if (auto* tc = dynamic_cast (getChildComponent (i))) { tc->setVisible (false); const int index = oldIndexes.removeAndReturn (i); @@ -195,9 +197,9 @@ public: int y = indent; int maxX = 0; - for (int i = 0; i < getNumChildComponents(); ++i) + for (auto* c : getChildren()) { - if (ToolbarItemComponent* const tc = dynamic_cast (getChildComponent (i))) + if (auto* tc = dynamic_cast (c)) { int preferredSize = 1, minSize = 1, maxSize = 1; diff --git a/source/modules/juce_gui_basics/widgets/juce_Toolbar.h b/source/modules/juce_gui_basics/widgets/juce_Toolbar.h index 7c0f3dbcb..3799f4b88 100644 --- a/source/modules/juce_gui_basics/widgets/juce_Toolbar.h +++ b/source/modules/juce_gui_basics/widgets/juce_Toolbar.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TOOLBAR_H_INCLUDED -#define JUCE_TOOLBAR_H_INCLUDED +#pragma once class ToolbarItemComponent; class ToolbarItemFactory; @@ -325,6 +326,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Toolbar) }; - - -#endif // JUCE_TOOLBAR_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp index a385c5a1b..707d63d2c 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h index 20271150f..76248b59f 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h +++ b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TOOLBARITEMCOMPONENT_H_INCLUDED -#define JUCE_TOOLBARITEMCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -200,6 +201,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToolbarItemComponent) }; - - -#endif // JUCE_TOOLBARITEMCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h index 95ff06ee1..f9d152004 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h +++ b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemFactory.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TOOLBARITEMFACTORY_H_INCLUDED -#define JUCE_TOOLBARITEMFACTORY_H_INCLUDED +#pragma once //============================================================================== @@ -103,6 +104,3 @@ public: */ virtual ToolbarItemComponent* createItem (int itemId) = 0; }; - - -#endif // JUCE_TOOLBARITEMFACTORY_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp index 233aef6a1..c0b47edb9 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h index 514f09614..8321657d0 100644 --- a/source/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h +++ b/source/modules/juce_gui_basics/widgets/juce_ToolbarItemPalette.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TOOLBARITEMPALETTE_H_INCLUDED -#define JUCE_TOOLBARITEMPALETTE_H_INCLUDED +#pragma once //============================================================================== @@ -71,6 +72,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToolbarItemPalette) }; - - -#endif // JUCE_TOOLBARITEMPALETTE_H_INCLUDED diff --git a/source/modules/juce_gui_basics/widgets/juce_TreeView.cpp b/source/modules/juce_gui_basics/widgets/juce_TreeView.cpp index ef31ea313..3266af6a9 100644 --- a/source/modules/juce_gui_basics/widgets/juce_TreeView.cpp +++ b/source/modules/juce_gui_basics/widgets/juce_TreeView.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -367,15 +369,11 @@ private: static bool isMouseDraggingInChildCompOf (Component* const comp) { - const Array& mouseSources = Desktop::getInstance().getMouseSources(); - - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) - { - if (mi->isDragging()) - if (Component* const underMouse = mi->getComponentUnderMouse()) + for (auto& ms : Desktop::getInstance().getMouseSources()) + if (ms.isDragging()) + if (auto* underMouse = ms.getComponentUnderMouse()) if (comp == underMouse || comp->isParentOf (underMouse)) return true; - } return false; } @@ -642,6 +640,9 @@ void TreeView::restoreOpennessState (const XmlElement& newState, const bool rest { rootItem->restoreOpennessState (newState); + needsRecalculating = true; + recalculateIfNeeded(); + if (newState.hasAttribute ("scrollPos")) viewport->setViewPosition (viewport->getViewPositionX(), newState.getIntAttribute ("scrollPos")); @@ -1156,7 +1157,7 @@ TreeViewItem::~TreeViewItem() String TreeViewItem::getUniqueName() const { - return String(); + return {}; } void TreeViewItem::itemOpennessChanged (bool) @@ -1378,7 +1379,7 @@ void TreeViewItem::itemSelectionChanged (bool) String TreeViewItem::getTooltip() { - return String(); + return {}; } void TreeViewItem::ownerViewChanged (TreeView*) @@ -1387,7 +1388,7 @@ void TreeViewItem::ownerViewChanged (TreeView*) var TreeViewItem::getDragSourceDescription() { - return var(); + return {}; } bool TreeViewItem::isInterestedInFileDrag (const StringArray&) @@ -1599,9 +1600,13 @@ void TreeViewItem::paintRecursively (Graphics& g, int width) } if (mightContainSubItems()) + { + auto backgroundColour = ownerView->findColour (TreeView::backgroundColourId); + paintOpenCloseButton (g, Rectangle ((float) (depth * indentWidth), 0, (float) indentWidth, (float) itemHeight), - Colours::white, + backgroundColour.isTransparent() ? Colours::white : backgroundColour, ownerView->viewport->getContentComp()->isMouseOverButton (this)); + } } if (isOpen()) diff --git a/source/modules/juce_gui_basics/widgets/juce_TreeView.h b/source/modules/juce_gui_basics/widgets/juce_TreeView.h index 75a9a9aae..5bba62aca 100644 --- a/source/modules/juce_gui_basics/widgets/juce_TreeView.h +++ b/source/modules/juce_gui_basics/widgets/juce_TreeView.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TREEVIEW_H_INCLUDED -#define JUCE_TREEVIEW_H_INCLUDED +#pragma once class TreeView; @@ -936,5 +937,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeView) }; - -#endif // JUCE_TREEVIEW_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_AlertWindow.cpp b/source/modules/juce_gui_basics/windows/juce_AlertWindow.cpp index 821229f9e..87983568c 100644 --- a/source/modules/juce_gui_basics/windows/juce_AlertWindow.cpp +++ b/source/modules/juce_gui_basics/windows/juce_AlertWindow.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -173,10 +175,10 @@ TextEditor* AlertWindow::getTextEditor (const String& nameOfTextEditor) const String AlertWindow::getTextEditorContents (const String& nameOfTextEditor) const { - if (TextEditor* const t = getTextEditor (nameOfTextEditor)) + if (auto* t = getTextEditor (nameOfTextEditor)) return t->getText(); - return String(); + return {}; } @@ -213,6 +215,13 @@ class AlertTextComp : public TextEditor public: AlertTextComp (AlertWindow& owner, const String& message, const Font& font) { + if (owner.isColourSpecified (AlertWindow::textColourId)) + setColour (TextEditor::textColourId, owner.findColour (AlertWindow::textColourId)); + + setColour (TextEditor::backgroundColourId, Colours::transparentBlack); + setColour (TextEditor::outlineColourId, Colours::transparentBlack); + setColour (TextEditor::shadowColourId, Colours::transparentBlack); + setReadOnly (true); setMultiLine (true, true); setCaretVisible (false); @@ -224,13 +233,6 @@ public: setText (message, false); bestWidth = 2 * (int) std::sqrt (font.getHeight() * font.getStringWidth (message)); - - if (owner.isColourSpecified (AlertWindow::textColourId)) - setColour (TextEditor::textColourId, owner.findColour (AlertWindow::textColourId)); - - setColour (TextEditor::backgroundColourId, Colours::transparentBlack); - setColour (TextEditor::outlineColourId, Colours::transparentBlack); - setColour (TextEditor::shadowColourId, Colours::transparentBlack); } int getPreferredWidth() const noexcept { return bestWidth; } diff --git a/source/modules/juce_gui_basics/windows/juce_AlertWindow.h b/source/modules/juce_gui_basics/windows/juce_AlertWindow.h index cf1a06f16..ff3e87735 100644 --- a/source/modules/juce_gui_basics/windows/juce_AlertWindow.h +++ b/source/modules/juce_gui_basics/windows/juce_AlertWindow.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ALERTWINDOW_H_INCLUDED -#define JUCE_ALERTWINDOW_H_INCLUDED +#pragma once //============================================================================== @@ -485,5 +486,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AlertWindow) }; - -#endif // JUCE_ALERTWINDOW_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp b/source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp index 4e6094105..6ab46c14d 100644 --- a/source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp +++ b/source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/windows/juce_CallOutBox.h b/source/modules/juce_gui_basics/windows/juce_CallOutBox.h index 1e598eb21..728b14af6 100644 --- a/source/modules/juce_gui_basics/windows/juce_CallOutBox.h +++ b/source/modules/juce_gui_basics/windows/juce_CallOutBox.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CALLOUTBOX_H_INCLUDED -#define JUCE_CALLOUTBOX_H_INCLUDED +#pragma once //============================================================================== @@ -181,6 +182,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallOutBox) }; - - -#endif // JUCE_CALLOUTBOX_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp b/source/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp index 172dc11d5..19e336199 100644 --- a/source/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp +++ b/source/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -25,20 +27,17 @@ static uint32 lastUniquePeerID = 1; //============================================================================== -ComponentPeer::ComponentPeer (Component& comp, const int flags) +ComponentPeer::ComponentPeer (Component& comp, int flags) : component (comp), styleFlags (flags), - constrainer (nullptr), - lastDragAndDropCompUnderMouse (nullptr), - uniqueID (lastUniquePeerID += 2), // increment by 2 so that this can never hit 0 - isWindowMinimised (false) + uniqueID (lastUniquePeerID += 2) // increment by 2 so that this can never hit 0 { Desktop::getInstance().peers.add (this); } ComponentPeer::~ComponentPeer() { - Desktop& desktop = Desktop::getInstance(); + auto& desktop = Desktop::getInstance(); desktop.peers.removeFirstMatchingValue (this); desktop.triggerFocusCallback(); } @@ -56,15 +55,9 @@ ComponentPeer* ComponentPeer::getPeer (const int index) noexcept ComponentPeer* ComponentPeer::getPeerFor (const Component* const component) noexcept { - const Array& peers = Desktop::getInstance().peers; - - for (int i = peers.size(); --i >= 0;) - { - ComponentPeer* const peer = peers.getUnchecked(i); - + for (auto* peer : Desktop::getInstance().peers) if (&(peer->getComponent()) == component) return peer; - } return nullptr; } @@ -85,21 +78,22 @@ bool ComponentPeer::isKioskMode() const } //============================================================================== -void ComponentPeer::handleMouseEvent (int touchIndex, Point pos, ModifierKeys newMods, float newPressure, int64 time) +void ComponentPeer::handleMouseEvent (MouseInputSource::InputSourceType type, Point pos, ModifierKeys newMods, + float newPressure, float newOrientation, int64 time, PenDetails pen, int touchIndex) { - if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex)) - MouseInputSource (*mouse).handleEvent (*this, pos, time, newMods, newPressure); + if (auto* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (type, touchIndex)) + MouseInputSource (*mouse).handleEvent (*this, pos, time, newMods, newPressure, newOrientation, pen); } -void ComponentPeer::handleMouseWheel (int touchIndex, Point pos, int64 time, const MouseWheelDetails& wheel) +void ComponentPeer::handleMouseWheel (MouseInputSource::InputSourceType type, Point pos, int64 time, const MouseWheelDetails& wheel, int touchIndex) { - if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex)) + if (auto* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (type, touchIndex)) MouseInputSource (*mouse).handleWheel (*this, pos, time, wheel); } -void ComponentPeer::handleMagnifyGesture (int touchIndex, Point pos, int64 time, float scaleFactor) +void ComponentPeer::handleMagnifyGesture (MouseInputSource::InputSourceType type, Point pos, int64 time, float scaleFactor, int touchIndex) { - if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex)) + if (auto* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (type, touchIndex)) MouseInputSource (*mouse).handleMagnifyGesture (*this, pos, time, scaleFactor); } @@ -113,7 +107,7 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) if (component.isTransformed()) g.addTransform (component.getTransform()); - const Rectangle peerBounds (getBounds()); + auto peerBounds = getBounds(); if (peerBounds.getWidth() != component.getWidth() || peerBounds.getHeight() != component.getHeight()) // Tweak the scaling so that the component's integer size exactly aligns with the peer's scaled size @@ -162,13 +156,13 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) Component* ComponentPeer::getTargetForKeyPress() { - Component* c = Component::getCurrentlyFocusedComponent(); + auto* c = Component::getCurrentlyFocusedComponent(); if (c == nullptr) c = &component; if (c->isCurrentlyBlockedByAnotherModalComponent()) - if (Component* const currentModalComp = Component::getCurrentlyModalComponent()) + if (auto* currentModalComp = Component::getCurrentlyModalComponent()) c = currentModalComp; return c; @@ -188,11 +182,11 @@ bool ComponentPeer::handleKeyPress (const KeyPress& keyInfo) { bool keyWasUsed = false; - for (Component* target = getTargetForKeyPress(); target != nullptr; target = target->getParentComponent()) + for (auto* target = getTargetForKeyPress(); target != nullptr; target = target->getParentComponent()) { const WeakReference deletionChecker (target); - if (const Array* const keyListeners = target->keyListeners) + if (auto* keyListeners = target->keyListeners.get()) { for (int i = keyListeners->size(); --i >= 0;) { @@ -210,7 +204,7 @@ bool ComponentPeer::handleKeyPress (const KeyPress& keyInfo) if (keyWasUsed || deletionChecker == nullptr) break; - if (Component* const currentlyFocused = Component::getCurrentlyFocusedComponent()) + if (auto* currentlyFocused = Component::getCurrentlyFocusedComponent()) { const bool isTab = (keyInfo == KeyPress::tabKey); const bool isShiftTab = (keyInfo == KeyPress (KeyPress::tabKey, ModifierKeys::shiftModifier, 0)); @@ -234,7 +228,7 @@ bool ComponentPeer::handleKeyUpOrDown (const bool isKeyDown) ModifierKeys::updateCurrentModifiers(); bool keyWasUsed = false; - for (Component* target = getTargetForKeyPress(); target != nullptr; target = target->getParentComponent()) + for (auto* target = getTargetForKeyPress(); target != nullptr; target = target->getParentComponent()) { const WeakReference deletionChecker (target); @@ -243,7 +237,7 @@ bool ComponentPeer::handleKeyUpOrDown (const bool isKeyDown) if (keyWasUsed || deletionChecker == nullptr) break; - if (const Array* const keyListeners = target->keyListeners) + if (auto* keyListeners = target->keyListeners.get()) { for (int i = keyListeners->size(); --i >= 0;) { @@ -264,7 +258,7 @@ void ComponentPeer::handleModifierKeysChange() { ModifierKeys::updateCurrentModifiers(); - Component* target = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); + auto* target = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); if (target == nullptr) target = Component::getCurrentlyFocusedComponent(); @@ -272,16 +266,15 @@ void ComponentPeer::handleModifierKeysChange() if (target == nullptr) target = &component; - if (target != nullptr) - target->internalModifierKeysChanged(); + target->internalModifierKeysChanged(); } TextInputTarget* ComponentPeer::findCurrentTextInputTarget() { - Component* const c = Component::getCurrentlyFocusedComponent(); + auto* c = Component::getCurrentlyFocusedComponent(); if (c == &component || component.isParentOf (c)) - if (TextInputTarget* const ti = dynamic_cast (c)) + if (auto* ti = dynamic_cast (c)) if (ti->isTextInputActive()) return ti; @@ -312,8 +305,8 @@ void ComponentPeer::handleMovedOrResized() { const WeakReference deletionChecker (&component); - Rectangle newBounds (Component::ComponentHelpers::rawPeerPositionToLocal (component, getBounds())); - Rectangle oldBounds (component.getBounds()); + auto newBounds = Component::ComponentHelpers::rawPeerPositionToLocal (component, getBounds()); + auto oldBounds = component.getBounds(); const bool wasMoved = (oldBounds.getPosition() != newBounds.getPosition()); const bool wasResized = (oldBounds.getWidth() != newBounds.getWidth() || oldBounds.getHeight() != newBounds.getHeight()); @@ -451,31 +444,6 @@ namespace DragHelpers return nullptr; } - - // We'll use an async message to deliver the drop, because if the target decides - // to run a modal loop, it can gum-up the operating system.. - class AsyncDropMessage : public CallbackMessage - { - public: - AsyncDropMessage (Component* c, const ComponentPeer::DragInfo& d) : target (c), info (d) {} - - void messageCallback() override - { - if (Component* const c = target.get()) - { - if (isFileDrag (info)) - dynamic_cast (c)->filesDropped (info.files, info.position.x, info.position.y); - else - dynamic_cast (c)->textDropped (info.text, info.position.x, info.position.y); - } - } - - private: - WeakReference target; - const ComponentPeer::DragInfo info; - - JUCE_DECLARE_NON_COPYABLE (AsyncDropMessage) - }; } bool ComponentPeer::handleDragMove (const ComponentPeer::DragInfo& info) @@ -507,7 +475,7 @@ bool ComponentPeer::handleDragMove (const ComponentPeer::DragInfo& info) if (DragHelpers::isSuitableTarget (info, newTarget)) { dragAndDropTargetComponent = newTarget; - const Point pos (newTarget->getLocalPoint (&component, info.position)); + auto pos = newTarget->getLocalPoint (&component, info.position); if (DragHelpers::isFileDrag (info)) dynamic_cast (newTarget)->fileDragEnter (info.files, pos.x, pos.y); @@ -524,7 +492,7 @@ bool ComponentPeer::handleDragMove (const ComponentPeer::DragInfo& info) if (! DragHelpers::isSuitableTarget (info, newTarget)) return false; - const Point pos (newTarget->getLocalPoint (&component, info.position)); + auto pos = newTarget->getLocalPoint (&component, info.position); if (DragHelpers::isFileDrag (info)) dynamic_cast (newTarget)->fileDragMove (info.files, pos.x, pos.y); @@ -549,7 +517,7 @@ bool ComponentPeer::handleDragDrop (const ComponentPeer::DragInfo& info) { handleDragMove (info); - if (Component* const targetComp = dragAndDropTargetComponent) + if (WeakReference targetComp = dragAndDropTargetComponent) { dragAndDropTargetComponent = nullptr; lastDragAndDropCompUnderMouse = nullptr; @@ -564,10 +532,22 @@ bool ComponentPeer::handleDragDrop (const ComponentPeer::DragInfo& info) return true; } - ComponentPeer::DragInfo info2 (info); - info2.position = targetComp->getLocalPoint (&component, info.position); + ComponentPeer::DragInfo infoCopy (info); + infoCopy.position = targetComp->getLocalPoint (&component, info.position); + + // We'll use an async message to deliver the drop, because if the target decides + // to run a modal loop, it can gum-up the operating system.. + MessageManager::callAsync ([=]() + { + if (auto* c = targetComp.get()) + { + if (DragHelpers::isFileDrag (info)) + dynamic_cast (c)->filesDropped (infoCopy.files, infoCopy.position.x, infoCopy.position.y); + else + dynamic_cast (c)->textDropped (infoCopy.text, infoCopy.position.x, infoCopy.position.y); + } + }); - (new DragHelpers::AsyncDropMessage (targetComp, info2))->post(); return true; } } diff --git a/source/modules/juce_gui_basics/windows/juce_ComponentPeer.h b/source/modules/juce_gui_basics/windows/juce_ComponentPeer.h index 427761899..65e46e69c 100644 --- a/source/modules/juce_gui_basics/windows/juce_ComponentPeer.h +++ b/source/modules/juce_gui_basics/windows/juce_ComponentPeer.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COMPONENTPEER_H_INCLUDED -#define JUCE_COMPONENTPEER_H_INCLUDED +#pragma once //============================================================================== @@ -311,9 +312,14 @@ public: virtual void setAlpha (float newAlpha) = 0; //============================================================================== - void handleMouseEvent (int touchIndex, Point positionWithinPeer, ModifierKeys newMods, float pressure, int64 time); - void handleMouseWheel (int touchIndex, Point positionWithinPeer, int64 time, const MouseWheelDetails&); - void handleMagnifyGesture (int touchIndex, Point positionWithinPeer, int64 time, float scaleFactor); + void handleMouseEvent (MouseInputSource::InputSourceType type, Point positionWithinPeer, ModifierKeys newMods, float pressure, + float orientation, int64 time, PenDetails pen = {}, int touchIndex = 0); + + void handleMouseWheel (MouseInputSource::InputSourceType type, Point positionWithinPeer, + int64 time, const MouseWheelDetails&, int touchIndex = 0); + + void handleMagnifyGesture (MouseInputSource::InputSourceType type, Point positionWithinPeer, + int64 time, float scaleFactor, int touchIndex = 0); void handleUserClosingWindow(); @@ -360,18 +366,15 @@ protected: Component& component; const int styleFlags; Rectangle lastNonFullscreenBounds; - ComponentBoundsConstrainer* constrainer; + ComponentBoundsConstrainer* constrainer = nullptr; private: //============================================================================== WeakReference lastFocusedComponent, dragAndDropTargetComponent; - Component* lastDragAndDropCompUnderMouse; + Component* lastDragAndDropCompUnderMouse = nullptr; const uint32 uniqueID; - bool isWindowMinimised; + bool isWindowMinimised = false; Component* getTargetForKeyPress(); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentPeer) }; - - -#endif // JUCE_COMPONENTPEER_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_DialogWindow.cpp b/source/modules/juce_gui_basics/windows/juce_DialogWindow.cpp index 432474932..be3d9e58d 100644 --- a/source/modules/juce_gui_basics/windows/juce_DialogWindow.cpp +++ b/source/modules/juce_gui_basics/windows/juce_DialogWindow.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/windows/juce_DialogWindow.h b/source/modules/juce_gui_basics/windows/juce_DialogWindow.h index 5eb366a2f..44b662b26 100644 --- a/source/modules/juce_gui_basics/windows/juce_DialogWindow.h +++ b/source/modules/juce_gui_basics/windows/juce_DialogWindow.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DIALOGWINDOW_H_INCLUDED -#define JUCE_DIALOGWINDOW_H_INCLUDED +#pragma once //============================================================================== @@ -259,5 +260,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DialogWindow) }; - -#endif // JUCE_DIALOGWINDOW_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp b/source/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp index e94641cbf..f99ae38ec 100644 --- a/source/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp +++ b/source/modules/juce_gui_basics/windows/juce_DocumentWindow.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/windows/juce_DocumentWindow.h b/source/modules/juce_gui_basics/windows/juce_DocumentWindow.h index ea31eb46b..9c48db130 100644 --- a/source/modules/juce_gui_basics/windows/juce_DocumentWindow.h +++ b/source/modules/juce_gui_basics/windows/juce_DocumentWindow.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_DOCUMENTWINDOW_H_INCLUDED -#define JUCE_DOCUMENTWINDOW_H_INCLUDED +#pragma once //============================================================================== @@ -290,6 +291,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DocumentWindow) }; - - -#endif // JUCE_DOCUMENTWINDOW_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_NativeMessageBox.h b/source/modules/juce_gui_basics/windows/juce_NativeMessageBox.h index f03689882..2aa4d49e9 100644 --- a/source/modules/juce_gui_basics/windows/juce_NativeMessageBox.h +++ b/source/modules/juce_gui_basics/windows/juce_NativeMessageBox.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_NATIVEMESSAGEBOX_H_INCLUDED -#define JUCE_NATIVEMESSAGEBOX_H_INCLUDED +#pragma once //============================================================================== /** @@ -156,9 +157,49 @@ public: ModalComponentManager::Callback* callback); #endif + /** Shows a dialog box with two buttons. + + Ideal for yes/no boxes. + + The escape key can be used to trigger the no button. + + If the callback parameter is null, the box is shown modally, and the method will + block until the user has clicked the button (or pressed the escape or return keys). + If the callback parameter is non-null, the box will be displayed and placed into a + modal state, but this method will return immediately, and the callback will be invoked + later when the user dismisses the box. + + @param iconType the type of icon to show + @param title the headline to show at the top of the box + @param message a longer, more descriptive message to show underneath the title + @param associatedComponent if this is non-null, it specifies the component that the + alert window should be associated with. Depending on the look + and feel, this might be used for positioning of the alert window. + @param callback if this is non-null, the box will be launched asynchronously, + returning immediately, and the callback will receive a call to its + modalStateFinished() when the box is dismissed, with its parameter + being 1 if the "yes" button was pressed or 0 for the "no" button was + pressed. The callback object will be owned and deleted by the + system, so make sure that it works safely and doesn't keep any references + to objects that might be deleted before it gets called. + + @returns If the callback parameter has been set, this returns 0. Otherwise, it returns one + of the following values: + - 0 if 'no' was pressed + - 1 if 'yes' was pressed + */ + static int JUCE_CALLTYPE showYesNoBox (AlertWindow::AlertIconType iconType, + const String& title, + const String& message, + #if JUCE_MODAL_LOOPS_PERMITTED + Component* associatedComponent = nullptr, + ModalComponentManager::Callback* callback = nullptr); + #else + Component* associatedComponent, + ModalComponentManager::Callback* callback); + #endif + private: NativeMessageBox() JUCE_DELETED_FUNCTION; JUCE_DECLARE_NON_COPYABLE (NativeMessageBox) }; - -#endif // JUCE_NATIVEMESSAGEBOX_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp b/source/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp index 341acaa6e..00ee3c687 100644 --- a/source/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp +++ b/source/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp @@ -2,52 +2,36 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ ResizableWindow::ResizableWindow (const String& name, bool shouldAddToDesktop) - : TopLevelWindow (name, shouldAddToDesktop), - ownsContentComponent (false), - resizeToFitContent (false), - fullscreen (false), - canDrag (true), - dragStarted (false), - constrainer (nullptr) - #if JUCE_DEBUG - , hasBeenResized (false) - #endif + : TopLevelWindow (name, shouldAddToDesktop) { initialise (shouldAddToDesktop); } ResizableWindow::ResizableWindow (const String& name, Colour bkgnd, bool shouldAddToDesktop) - : TopLevelWindow (name, shouldAddToDesktop), - ownsContentComponent (false), - resizeToFitContent (false), - fullscreen (false), - canDrag (true), - dragStarted (false), - constrainer (nullptr) - #if JUCE_DEBUG - , hasBeenResized (false) - #endif + : TopLevelWindow (name, shouldAddToDesktop) { setBackgroundColour (bkgnd); @@ -56,6 +40,8 @@ ResizableWindow::ResizableWindow (const String& name, Colour bkgnd, bool shouldA ResizableWindow::~ResizableWindow() { + splashScreen.deleteAndZero(); + // Don't delete or remove the resizer components yourself! They're managed by the // ResizableWindow, and you should leave them alone! You may have deleted them // accidentally by careless use of deleteAllChildren()..? @@ -73,6 +59,25 @@ ResizableWindow::~ResizableWindow() void ResizableWindow::initialise (const bool shouldAddToDesktop) { + /* + ========================================================================== + In accordance with the terms of the JUCE 5 End-Use License Agreement, the + JUCE Code in SECTION A cannot be removed, changed or otherwise rendered + ineffective unless you have a JUCE Indie or Pro license, or are using + JUCE under the GPL v3 license. + + End User License Agreement: www.juce.com/juce-5-licence + ========================================================================== + */ + + // BEGIN SECTION A + + #if ! JucePlugin_Build_Standalone + splashScreen = new JUCESplashScreen (*this); + #endif + + // END SECTION A + defaultConstrainer.setMinimumOnscreenAmounts (0x10000, 16, 24, 16); lastNonFullScreenPos.setBounds (50, 50, 256, 256); @@ -237,7 +242,7 @@ void ResizableWindow::childBoundsChanged (Component* child) jassert (child->getWidth() > 0); jassert (child->getHeight() > 0); - const BorderSize borders (getContentComponentBorder()); + auto borders = getContentComponentBorder(); setSize (child->getWidth() + borders.getLeftAndRight(), child->getHeight() + borders.getTopAndBottom()); diff --git a/source/modules/juce_gui_basics/windows/juce_ResizableWindow.h b/source/modules/juce_gui_basics/windows/juce_ResizableWindow.h index c30deb0c5..df44baf66 100644 --- a/source/modules/juce_gui_basics/windows/juce_ResizableWindow.h +++ b/source/modules/juce_gui_basics/windows/juce_ResizableWindow.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RESIZABLEWINDOW_H_INCLUDED -#define JUCE_RESIZABLEWINDOW_H_INCLUDED +#pragma once //============================================================================== @@ -381,14 +382,14 @@ protected: private: //============================================================================== - Component::SafePointer contentComponent; - bool ownsContentComponent, resizeToFitContent, fullscreen, canDrag, dragStarted; + Component::SafePointer contentComponent, splashScreen; + bool ownsContentComponent = false, resizeToFitContent = false, fullscreen = false, canDrag = true, dragStarted = false; ComponentDragger dragger; Rectangle lastNonFullScreenPos; ComponentBoundsConstrainer defaultConstrainer; - ComponentBoundsConstrainer* constrainer; + ComponentBoundsConstrainer* constrainer = nullptr; #if JUCE_DEBUG - bool hasBeenResized; + bool hasBeenResized = false; #endif void initialise (bool addToDesktop); @@ -405,6 +406,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResizableWindow) }; - - -#endif // JUCE_RESIZABLEWINDOW_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp b/source/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp index 4304d3e8c..57b3ba79a 100644 --- a/source/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp +++ b/source/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h b/source/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h index 9ced44771..78e913a90 100644 --- a/source/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h +++ b/source/modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_THREADWITHPROGRESSWINDOW_H_INCLUDED -#define JUCE_THREADWITHPROGRESSWINDOW_H_INCLUDED +#pragma once //============================================================================== @@ -169,5 +170,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ThreadWithProgressWindow) }; - -#endif // JUCE_THREADWITHPROGRESSWINDOW_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp b/source/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp index ef311e8e5..abf71124a 100644 --- a/source/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp +++ b/source/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -80,7 +82,7 @@ void TooltipWindow::displayTip (Point screenPos, const String& tip) repaint(); } - if (Component* const parent = getParentComponent()) + if (auto* parent = getParentComponent()) { updatePosition (tip, parent->getLocalPoint (nullptr, screenPos), parent->getLocalBounds()); @@ -111,7 +113,7 @@ String TooltipWindow::getTipFor (Component* const c) return ttc->getTooltip(); } - return String(); + return {}; } void TooltipWindow::hideTip() @@ -130,7 +132,7 @@ void TooltipWindow::timerCallback() const MouseInputSource mouseSource (desktop.getMainMouseSource()); const unsigned int now = Time::getApproximateMillisecondCounter(); - Component* const newComp = mouseSource.isMouse() ? mouseSource.getComponentUnderMouse() : nullptr; + Component* const newComp = ! mouseSource.isTouch() ? mouseSource.getComponentUnderMouse() : nullptr; const String newTip (getTipFor (newComp)); const bool tipChanged = (newTip != lastTipUnderMouse || newComp != lastComponentUnderMouse); lastComponentUnderMouse = newComp; diff --git a/source/modules/juce_gui_basics/windows/juce_TooltipWindow.h b/source/modules/juce_gui_basics/windows/juce_TooltipWindow.h index 40f7d5a20..42d60a33f 100644 --- a/source/modules/juce_gui_basics/windows/juce_TooltipWindow.h +++ b/source/modules/juce_gui_basics/windows/juce_TooltipWindow.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TOOLTIPWINDOW_H_INCLUDED -#define JUCE_TOOLTIPWINDOW_H_INCLUDED +#pragma once //============================================================================== @@ -136,6 +137,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TooltipWindow) }; - - -#endif // JUCE_TOOLTIPWINDOW_H_INCLUDED diff --git a/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp b/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp index 6f9e3f2bb..c32ea2a37 100644 --- a/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp +++ b/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.h b/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.h index 2f3a60a39..9ee8d9376 100644 --- a/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.h +++ b/source/modules/juce_gui_basics/windows/juce_TopLevelWindow.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_TOPLEVELWINDOW_H_INCLUDED -#define JUCE_TOPLEVELWINDOW_H_INCLUDED +#pragma once //============================================================================== @@ -159,6 +160,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TopLevelWindow) }; - - -#endif // JUCE_TOPLEVELWINDOW_H_INCLUDED diff --git a/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp b/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp index fcf3aeddc..11555a2f0 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp +++ b/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h b/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h index 53ab7ef5e..88111a8e8 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h +++ b/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniser.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CPLUSPLUSCODETOKENISER_H_INCLUDED -#define JUCE_CPLUSPLUSCODETOKENISER_H_INCLUDED +#pragma once //============================================================================== @@ -66,6 +67,3 @@ private: //============================================================================== JUCE_LEAK_DETECTOR (CPlusPlusCodeTokeniser) }; - - -#endif // JUCE_CPLUSPLUSCODETOKENISER_H_INCLUDED diff --git a/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h b/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h index 176e76362..f4ddfdf5e 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h +++ b/source/modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CPLUSPLUSCODETOKENISERFUNCTIONS_H_INCLUDED -#define JUCE_CPLUSPLUSCODETOKENISERFUNCTIONS_H_INCLUDED +#pragma once //============================================================================== @@ -660,6 +661,3 @@ struct CppTokeniserFunctions return mo.toString(); } }; - - -#endif // JUCE_CPLUSPLUSCODETOKENISERFUNCTIONS_H_INCLUDED diff --git a/source/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp b/source/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp index 6662ee8ce..57bc14a2e 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp +++ b/source/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -422,7 +424,7 @@ CodeDocument::Position CodeDocument::Position::movedByLines (const int deltaLine juce_wchar CodeDocument::Position::getCharacter() const { - if (const CodeDocumentLine* const l = owner->lines [line]) + if (auto* l = owner->lines [line]) return l->line [getIndexInLine()]; return 0; @@ -430,10 +432,10 @@ juce_wchar CodeDocument::Position::getCharacter() const String CodeDocument::Position::getLineText() const { - if (const CodeDocumentLine* const l = owner->lines [line]) + if (auto* l = owner->lines [line]) return l->line; - return String(); + return {}; } void CodeDocument::Position::setPositionMaintained (const bool isMaintained) @@ -482,7 +484,7 @@ String CodeDocument::getAllContent() const String CodeDocument::getTextBetween (const Position& start, const Position& end) const { if (end.getPosition() <= start.getPosition()) - return String(); + return {}; const int startLine = start.getLineNumber(); const int endLine = end.getLineNumber(); @@ -492,7 +494,7 @@ String CodeDocument::getTextBetween (const Position& start, const Position& end) if (CodeDocumentLine* const line = lines [startLine]) return line->line.substring (start.getIndexInLine(), end.getIndexInLine()); - return String(); + return {}; } MemoryOutputStream mo; @@ -526,7 +528,7 @@ String CodeDocument::getTextBetween (const Position& start, const Position& end) int CodeDocument::getNumCharacters() const noexcept { - if (const CodeDocumentLine* const lastLine = lines.getLast()) + if (auto* lastLine = lines.getLast()) return lastLine->lineStartInFile + lastLine->lineLength; return 0; @@ -534,10 +536,10 @@ int CodeDocument::getNumCharacters() const noexcept String CodeDocument::getLine (const int lineIndex) const noexcept { - if (const CodeDocumentLine* const line = lines [lineIndex]) + if (auto* line = lines [lineIndex]) return line->line; - return String(); + return {}; } int CodeDocument::getMaximumLineLength() noexcept diff --git a/source/modules/juce_gui_extra/code_editor/juce_CodeDocument.h b/source/modules/juce_gui_extra/code_editor/juce_CodeDocument.h index a5396b783..f0fbd1a00 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_CodeDocument.h +++ b/source/modules/juce_gui_extra/code_editor/juce_CodeDocument.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CODEDOCUMENT_H_INCLUDED -#define JUCE_CODEDOCUMENT_H_INCLUDED +#pragma once class CodeDocumentLine; @@ -412,6 +413,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CodeDocument) }; - - -#endif // JUCE_CODEDOCUMENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp b/source/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp index d3b0d2cdf..c001c9b4e 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp +++ b/source/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -25,9 +27,7 @@ class CodeEditorComponent::CodeEditorLine { public: - CodeEditorLine() noexcept : highlightColumnStart (0), highlightColumnEnd (0) - { - } + CodeEditorLine() noexcept {} bool update (CodeDocument& codeDoc, int lineNum, CodeDocument::Iterator& source, @@ -40,7 +40,7 @@ public: if (tokeniser == nullptr) { - const String line (codeDoc.getLine (lineNum)); + auto line = codeDoc.getLine (lineNum); addToken (newTokens, line, line.length(), -1); } else if (lineNum < codeDoc.getNumLines()) @@ -57,7 +57,7 @@ public: if (selStart.getLineNumber() <= lineNum && selEnd.getLineNumber() >= lineNum) { - const String line (codeDoc.getLine (lineNum)); + auto line = codeDoc.getLine (lineNum); CodeDocument::Position lineStart (codeDoc, lineNum, 0), lineEnd (codeDoc, lineNum + 1, 0); newHighlightStart = indexToColumn (jmax (0, selStart.getPosition() - lineStart.getPosition()), @@ -96,18 +96,17 @@ public: int column = 0; - for (int i = 0; i < tokens.size(); ++i) + for (auto& token : tokens) { const float tokenX = x + column * characterWidth; if (tokenX > rightClip) break; - const SyntaxToken& token = tokens.getReference(i); as.append (token.text.initialSectionNotContaining ("\r\n"), fontToUse, owner.getColourForTokenType (token.tokenType)); column += token.length; } - as.draw (g, Rectangle (x, (float) y, column * characterWidth + 10.0f, (float) lineH)); + as.draw (g, { x, (float) y, column * characterWidth + 10.0f, (float) lineH }); } private: @@ -130,7 +129,7 @@ private: }; Array tokens; - int highlightColumnStart, highlightColumnEnd; + int highlightColumnStart = 0, highlightColumnEnd = 0; static void createTokens (int startPosition, const String& lineText, CodeDocument::Iterator& source, @@ -171,10 +170,9 @@ private: static void replaceTabsWithSpaces (Array& tokens, const int spacesPerTab) { int x = 0; - for (int i = 0; i < tokens.size(); ++i) - { - SyntaxToken& t = tokens.getReference(i); + for (auto& t : tokens) + { for (;;) { const int tabPos = t.text.indexOfChar ('\t'); @@ -227,7 +225,7 @@ namespace CodeEditorHelpers { static int findFirstNonWhitespaceChar (StringRef line) noexcept { - String::CharPointerType t (line.text); + auto t = line.text; int i = 0; while (! t.isEmpty()) @@ -283,7 +281,7 @@ private: class CodeEditorComponent::GutterComponent : public Component { public: - GutterComponent() : firstLine (0), lastNumLines (0) {} + GutterComponent() {} void paint (Graphics& g) override { @@ -293,7 +291,7 @@ public: g.fillAll (editor.findColour (CodeEditorComponent::backgroundColourId) .overlaidWith (editor.findColour (lineNumberBackgroundId))); - const Rectangle clip (g.getClipBounds()); + auto clip = g.getClipBounds(); const int lineH = editor.lineHeight; const float lineHeightFloat = (float) lineH; const int firstLineToDraw = jmax (0, clip.getY() / lineH); @@ -326,31 +324,16 @@ public: } private: - int firstLine, lastNumLines; + int firstLine = 0, lastNumLines = 0; }; //============================================================================== CodeEditorComponent::CodeEditorComponent (CodeDocument& doc, CodeTokeniser* const tokeniser) : document (doc), - firstLineOnScreen (0), - spacesPerTab (4), - lineHeight (0), - linesOnScreen (0), - columnsOnScreen (0), - scrollbarThickness (16), - columnToTryToMaintain (-1), - readOnly (false), - useSpacesForTabs (false), - showLineNumbers (false), - shouldFollowDocumentChanges (false), - xOffset (0), caretPos (doc, 0, 0), selectionStart (doc, 0, 0), selectionEnd (doc, 0, 0), - verticalScrollBar (true), - horizontalScrollBar (false), - appCommandManager (nullptr), codeTokeniser (tokeniser) { pimpl = new Pimpl (*this); @@ -472,20 +455,18 @@ void CodeEditorComponent::resized() void CodeEditorComponent::paint (Graphics& g) { - pimpl->handleUpdateNowIfNeeded(); - g.fillAll (findColour (CodeEditorComponent::backgroundColourId)); - const int gutterSize = getGutterSize(); + auto gutterSize = getGutterSize(); g.reduceClipRegion (gutterSize, 0, verticalScrollBar.getX() - gutterSize, horizontalScrollBar.getY()); g.setFont (font); - const Rectangle clip (g.getClipBounds()); - const int firstLineToDraw = jmax (0, clip.getY() / lineHeight); - const int lastLineToDraw = jmin (lines.size(), clip.getBottom() / lineHeight + 1); - const float x = (float) (gutterSize - xOffset * charWidth); - const float rightClip = (float) clip.getRight(); + auto clip = g.getClipBounds(); + auto firstLineToDraw = jmax (0, clip.getY() / lineHeight); + auto lastLineToDraw = jmin (lines.size(), clip.getBottom() / lineHeight + 1); + auto x = (float) (gutterSize - xOffset * charWidth); + auto rightClip = (float) clip.getRight(); { RectangleList highlightArea; @@ -725,10 +706,11 @@ void CodeEditorComponent::scrollToKeepCaretOnScreen() { if (getWidth() > 0 && getHeight() > 0) { - const int caretLine = caretPos.getLineNumber(); - scrollToKeepLinesOnScreen (Range (caretLine, caretLine)); + auto caretLine = caretPos.getLineNumber(); + scrollToKeepLinesOnScreen ({ caretLine, caretLine }); + + auto column = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine()); - const int column = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine()); if (column >= xOffset + columnsOnScreen - 1) scrollToColumn (column + 1 - columnsOnScreen); else if (column < xOffset) @@ -738,10 +720,10 @@ void CodeEditorComponent::scrollToKeepCaretOnScreen() Rectangle CodeEditorComponent::getCharacterBounds (const CodeDocument::Position& pos) const { - return Rectangle (roundToInt ((getGutterSize() - xOffset * charWidth) + indexToColumn (pos.getLineNumber(), pos.getIndexInLine()) * charWidth), - (pos.getLineNumber() - firstLineOnScreen) * lineHeight, - roundToInt (charWidth), - lineHeight); + return { roundToInt ((getGutterSize() - xOffset * charWidth) + indexToColumn (pos.getLineNumber(), pos.getIndexInLine()) * charWidth), + (pos.getLineNumber() - firstLineOnScreen) * lineHeight, + roundToInt (charWidth), + lineHeight }; } CodeDocument::Position CodeEditorComponent::getPositionAt (int x, int y) @@ -784,8 +766,8 @@ void CodeEditorComponent::insertTabAtCaret() if (useSpacesForTabs) { - const int caretCol = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine()); - const int spacesNeeded = spacesPerTab - (caretCol % spacesPerTab); + auto caretCol = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine()); + auto spacesNeeded = spacesPerTab - (caretCol % spacesPerTab); insertTextAtCaret (String::repeatedString (" ", spacesNeeded)); } else @@ -801,7 +783,7 @@ bool CodeEditorComponent::deleteWhitespaceBackwardsToTabStop() { for (;;) { - const int currentColumn = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine()); + auto currentColumn = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine()); if (currentColumn <= 0 || (currentColumn % spacesPerTab) == 0) break; @@ -809,7 +791,7 @@ bool CodeEditorComponent::deleteWhitespaceBackwardsToTabStop() moveCaretLeft (false, true); } - const String selected (getTextInRange (getHighlightedRegion())); + auto selected = getTextInRange (getHighlightedRegion()); if (selected.isNotEmpty() && selected.trim().isEmpty()) { @@ -843,8 +825,8 @@ void CodeEditorComponent::indentSelectedLines (const int spacesToAdd) for (int line = lineStart; line <= lineEnd; ++line) { - const String lineText (document.getLine (line)); - const int nonWhitespaceStart = CodeEditorHelpers::findFirstNonWhitespaceChar (lineText); + auto lineText = document.getLine (line); + auto nonWhitespaceStart = CodeEditorHelpers::findFirstNonWhitespaceChar (lineText); if (nonWhitespaceStart > 0 || lineText.trimStart().isNotEmpty()) { @@ -870,13 +852,13 @@ void CodeEditorComponent::indentSelectedLines (const int spacesToAdd) void CodeEditorComponent::cut() { - insertText (String()); + insertText ({}); } bool CodeEditorComponent::copyToClipboard() { newTransaction(); - const String selection (document.getTextBetween (selectionStart, selectionEnd)); + auto selection = document.getTextBetween (selectionStart, selectionEnd); if (selection.isNotEmpty()) SystemClipboard::copyTextToClipboard (selection); @@ -895,7 +877,7 @@ bool CodeEditorComponent::cutToClipboard() bool CodeEditorComponent::pasteFromClipboard() { newTransaction(); - const String clip (SystemClipboard::getTextFromClipboard()); + auto clip = SystemClipboard::getTextFromClipboard(); if (clip.isNotEmpty()) insertText (clip); @@ -955,14 +937,14 @@ bool CodeEditorComponent::moveCaretRight (const bool moveInWholeWordSteps, const void CodeEditorComponent::moveLineDelta (const int delta, const bool selecting) { CodeDocument::Position pos (caretPos); - const int newLineNum = pos.getLineNumber() + delta; + auto newLineNum = pos.getLineNumber() + delta; if (columnToTryToMaintain < 0) columnToTryToMaintain = indexToColumn (pos.getLineNumber(), pos.getIndexInLine()); pos.setLineAndIndex (newLineNum, columnToIndex (newLineNum, columnToTryToMaintain)); - const int colToMaintain = columnToTryToMaintain; + auto colToMaintain = columnToTryToMaintain; moveCaretTo (pos, selecting); columnToTryToMaintain = colToMaintain; } @@ -1083,8 +1065,8 @@ bool CodeEditorComponent::deleteBackwards (const bool moveInWholeWordSteps) bool CodeEditorComponent::skipBackwardsToPreviousTab() { - const String currentLineText (caretPos.getLineText().removeCharacters ("\r\n")); - const int currentIndex = caretPos.getIndexInLine(); + auto currentLineText = caretPos.getLineText().removeCharacters ("\r\n"); + auto currentIndex = caretPos.getIndexInLine(); if (currentLineText.isNotEmpty() && currentLineText.length() == currentIndex) { @@ -1175,7 +1157,8 @@ void CodeEditorComponent::setCommandManager (ApplicationCommandManager* newManag //============================================================================== Range CodeEditorComponent::getHighlightedRegion() const { - return Range (selectionStart.getPosition(), selectionEnd.getPosition()); + return { selectionStart.getPosition(), + selectionEnd.getPosition() }; } bool CodeEditorComponent::isHighlightActive() const noexcept @@ -1415,8 +1398,8 @@ void CodeEditorComponent::mouseDoubleClick (const MouseEvent& e) void CodeEditorComponent::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel) { - if ((verticalScrollBar.isVisible() && wheel.deltaY != 0) - || (horizontalScrollBar.isVisible() && wheel.deltaX != 0)) + if ((verticalScrollBar.isVisible() && wheel.deltaY != 0.0f) + || (horizontalScrollBar.isVisible() && wheel.deltaX != 0.0f)) { { MouseWheelDetails w (wheel); @@ -1461,10 +1444,10 @@ String CodeEditorComponent::getTabString (const int numSpaces) const int CodeEditorComponent::indexToColumn (int lineNum, int index) const noexcept { - const String line (document.getLine (lineNum)); - String::CharPointerType t (line.getCharPointer()); - + auto line = document.getLine (lineNum); + auto t = line.getCharPointer(); int col = 0; + for (int i = 0; i < index; ++i) { if (t.isEmpty()) @@ -1484,9 +1467,8 @@ int CodeEditorComponent::indexToColumn (int lineNum, int index) const noexcept int CodeEditorComponent::columnToIndex (int lineNum, int column) const noexcept { - const String line (document.getLine (lineNum)); - String::CharPointerType t (line.getCharPointer()); - + auto line = document.getLine (lineNum); + auto t = line.getCharPointer(); int i = 0, col = 0; while (! t.isEmpty()) @@ -1514,12 +1496,10 @@ void CodeEditorComponent::setFont (const Font& newFont) resized(); } -void CodeEditorComponent::ColourScheme::set (const String& name, const Colour colour) +void CodeEditorComponent::ColourScheme::set (const String& name, Colour colour) { - for (int i = 0; i < types.size(); ++i) + for (auto& tt : types) { - TokenType& tt = types.getReference(i); - if (tt.name == name) { tt.colour = colour; @@ -1568,12 +1548,12 @@ void CodeEditorComponent::updateCachedIterators (int maxLineNum) { for (;;) { - CodeDocument::Iterator& last = *cachedIterators.getLast(); + auto& last = *cachedIterators.getLast(); if (last.getLine() >= maxLineNum) break; - CodeDocument::Iterator* t = new CodeDocument::Iterator (last); + auto* t = new CodeDocument::Iterator (last); cachedIterators.add (t); const int targetLine = jmin (maxLineNum, last.getLine() + linesBetweenCachedSources); @@ -1597,7 +1577,8 @@ void CodeEditorComponent::getIteratorForPosition (int position, CodeDocument::It { for (int i = cachedIterators.size(); --i >= 0;) { - const CodeDocument::Iterator& t = *cachedIterators.getUnchecked (i); + auto& t = *cachedIterators.getUnchecked (i); + if (t.getPosition() <= position) { source = t; @@ -1624,7 +1605,7 @@ CodeEditorComponent::State::State (const CodeEditorComponent& editor) lastCaretPos (editor.getCaretPos().getPosition()), lastSelectionEnd (lastCaretPos) { - const Range selection (editor.getHighlightedRegion()); + auto selection = editor.getHighlightedRegion(); if (lastCaretPos == selection.getStart()) lastSelectionEnd = selection.getEnd(); @@ -1650,8 +1631,7 @@ void CodeEditorComponent::State::restoreState (CodeEditorComponent& editor) cons CodeEditorComponent::State::State (const String& s) { - StringArray tokens; - tokens.addTokens (s, ":", StringRef()); + auto tokens = StringArray::fromTokens (s, ":", {}); lastTopLine = tokens[0].getIntValue(); lastCaretPos = tokens[1].getIntValue(); diff --git a/source/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h b/source/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h index 485c13c54..e0a1265c3 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h +++ b/source/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CODEEDITORCOMPONENT_H_INCLUDED -#define JUCE_CODEEDITORCOMPONENT_H_INCLUDED +#pragma once class CodeTokeniser; @@ -227,7 +228,7 @@ public: Array types; - void set (const String& name, const Colour colour); + void set (const String& name, Colour colour); }; /** Changes the syntax highlighting scheme. @@ -363,18 +364,17 @@ private: CodeDocument& document; Font font; - int firstLineOnScreen, spacesPerTab; - float charWidth; - int lineHeight, linesOnScreen, columnsOnScreen; - int scrollbarThickness, columnToTryToMaintain; - bool readOnly, useSpacesForTabs, showLineNumbers, shouldFollowDocumentChanges; - double xOffset; - + int firstLineOnScreen = 0, spacesPerTab = 4; + float charWidth = 0; + int lineHeight = 0, linesOnScreen = 0, columnsOnScreen = 0; + int scrollbarThickness = 16, columnToTryToMaintain = -1; + bool readOnly = false, useSpacesForTabs = true, showLineNumbers = false, shouldFollowDocumentChanges = false; + double xOffset = 0; CodeDocument::Position caretPos, selectionStart, selectionEnd; ScopedPointer caret; - ScrollBar verticalScrollBar, horizontalScrollBar; - ApplicationCommandManager* appCommandManager; + ScrollBar verticalScrollBar { true }, horizontalScrollBar { false }; + ApplicationCommandManager* appCommandManager = nullptr; class Pimpl; friend class Pimpl; @@ -393,7 +393,7 @@ private: draggingSelectionEnd }; - DragType dragType; + DragType dragType = notDragging; //============================================================================== CodeTokeniser* codeTokeniser; @@ -430,6 +430,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CodeEditorComponent) }; - - -#endif // JUCE_CODEEDITORCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h b/source/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h index b47576e18..18834c725 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h +++ b/source/modules/juce_gui_extra/code_editor/juce_CodeTokeniser.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_CODETOKENISER_H_INCLUDED -#define JUCE_CODETOKENISER_H_INCLUDED +#pragma once //============================================================================== @@ -53,6 +54,3 @@ public: private: JUCE_LEAK_DETECTOR (CodeTokeniser) }; - - -#endif // JUCE_CODETOKENISER_H_INCLUDED diff --git a/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp b/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp index 06613d933..d4d10478e 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp +++ b/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h b/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h index 8b4b8bab3..35f63eef5 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h +++ b/source/modules/juce_gui_extra/code_editor/juce_LuaCodeTokeniser.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LUACODETOKENISER_H_INCLUDED -#define JUCE_LUACODETOKENISER_H_INCLUDED +#pragma once //============================================================================== @@ -59,5 +60,3 @@ private: //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LuaTokeniser) }; - -#endif // JUCE_LUACODETOKENISER_H_INCLUDED diff --git a/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp b/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp index ead51c2e7..974b7ce55 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp +++ b/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h b/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h index e2e0014ff..20d06fba3 100644 --- a/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h +++ b/source/modules/juce_gui_extra/code_editor/juce_XMLCodeTokeniser.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_XMLCODETOKENISER_H_INCLUDED -#define JUCE_XMLCODETOKENISER_H_INCLUDED +#pragma once //============================================================================== @@ -57,6 +58,3 @@ public: private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XmlTokeniser) }; - - -#endif // JUCE_XMLCODETOKENISER_H_INCLUDED diff --git a/source/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp b/source/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp index ca74804c2..4c34585ca 100644 --- a/source/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp +++ b/source/modules/juce_gui_extra/documents/juce_FileBasedDocument.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/documents/juce_FileBasedDocument.h b/source/modules/juce_gui_extra/documents/juce_FileBasedDocument.h index eab3d1e31..1191f93c2 100644 --- a/source/modules/juce_gui_extra/documents/juce_FileBasedDocument.h +++ b/source/modules/juce_gui_extra/documents/juce_FileBasedDocument.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_FILEBASEDDOCUMENT_H_INCLUDED -#define JUCE_FILEBASEDDOCUMENT_H_INCLUDED +#pragma once //============================================================================== @@ -289,6 +290,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileBasedDocument) }; - - -#endif // JUCE_FILEBASEDDOCUMENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h b/source/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h index a59934098..ed1ce9734 100644 --- a/source/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h +++ b/source/modules/juce_gui_extra/embedding/juce_ActiveXControlComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ACTIVEXCONTROLCOMPONENT_H_INCLUDED -#define JUCE_ACTIVEXCONTROLCOMPONENT_H_INCLUDED +#pragma once #if JUCE_WINDOWS || DOXYGEN @@ -108,15 +109,17 @@ public: /** @internal */ void paint (Graphics&) override; + /** @internal */ + intptr_t offerEventToActiveXControl (void*); + static intptr_t offerEventToActiveXControlStatic (void*); + private: class Pimpl; friend struct ContainerDeletePolicy; ScopedPointer control; - bool mouseEventsAllowed; + bool mouseEventsAllowed = true; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ActiveXControlComponent) }; #endif - -#endif // JUCE_ACTIVEXCONTROLCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/embedding/juce_NSViewComponent.h b/source/modules/juce_gui_extra/embedding/juce_NSViewComponent.h index 6903f2cbd..896722bde 100644 --- a/source/modules/juce_gui_extra/embedding/juce_NSViewComponent.h +++ b/source/modules/juce_gui_extra/embedding/juce_NSViewComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_NSVIEWCOMPONENT_H_INCLUDED -#define JUCE_NSVIEWCOMPONENT_H_INCLUDED +#pragma once #if JUCE_MAC || DOXYGEN @@ -84,4 +85,3 @@ private: }; #endif -#endif // JUCE_NSVIEWCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/embedding/juce_UIViewComponent.h b/source/modules/juce_gui_extra/embedding/juce_UIViewComponent.h index ad2d63b27..4558bbd9a 100644 --- a/source/modules/juce_gui_extra/embedding/juce_UIViewComponent.h +++ b/source/modules/juce_gui_extra/embedding/juce_UIViewComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_UIVIEWCOMPONENT_H_INCLUDED -#define JUCE_UIVIEWCOMPONENT_H_INCLUDED +#pragma once #if JUCE_IOS || DOXYGEN @@ -83,4 +84,3 @@ private: }; #endif -#endif // JUCE_UIVIEWCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/embedding/juce_XEmbedComponent.h b/source/modules/juce_gui_extra/embedding/juce_XEmbedComponent.h new file mode 100644 index 000000000..8456e3d8d --- /dev/null +++ b/source/modules/juce_gui_extra/embedding/juce_XEmbedComponent.h @@ -0,0 +1,111 @@ +/* + ============================================================================== + + 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 + +/** @internal */ +bool juce_handleXEmbedEvent (ComponentPeer*, void*); +/** @internal */ +unsigned long juce_getCurrentFocusWindow (ComponentPeer*); + +#if JUCE_LINUX || DOXYGEN + +//============================================================================== +/** + A Linux-specific class that can embed a foreign X11 widget. + + Use this class to embed a foreign X11 widget from other toolkits such as + GTK+ or QT. + + There are two ways to initiate the Xembed protocol. Either the client creates + a window and passes this to the host (client initiated) or the host + creates a window in which the client can reparent it's client widget + (host initiated). XEmbedComponent supports both protocol types. + + This is how you embed a GTK+ widget: if you are using the client + initiated version of the protocol, then create a new gtk widget with + gtk_plug_new (0). Then query the window id of the plug via gtk_plug_get_id(). + Pass this id to the constructor of this class. + + If you are using the host initiated version of the protocol, then first create + the XEmbedComponent using the default constructor. Use getHostWindowID to get + the window id of the host, use this to construct your gtk plug via gtk_plug_new. + + A similar approach can be used to embed QT widgets via QT's QX11EmbedWidget + class. + + Other toolkits or raw X11 widgets should follow the X11 embed protocol: + https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html +*/ +class XEmbedComponent : public Component +{ +public: + //============================================================================== + + /** Creates a JUCE component wrapping a foreign widget + + Use this constructor if you are using the host initiated version + of the XEmbedProtocol. When using this version of the protocol + you must call getHostWindowID() and pass this id to the foreign toolkit. + */ + XEmbedComponent (bool wantsKeyboardFocus = true, + bool allowForeignWidgetToResizeComponent = false); + + /** Create a JUCE component wrapping the foreign widget with id wID + + Use this constructor if you are using the client initiated version + of the XEmbedProtocol. + */ + XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus = true, + bool allowForeignWidgetToResizeComponent = false); + + + /** Destructor. */ + ~XEmbedComponent(); + + /** Use this method to retrieve the host's window id when using the + host initiated version of the XEmbedProtocol + */ + unsigned long getHostWindowID(); + +protected: + //============================================================================== + /** @internal */ + void paint (Graphics&) override; + void focusGained (FocusChangeType) override; + void focusLost (FocusChangeType) override; + void broughtToFront() override; + +private: + friend bool juce::juce_handleXEmbedEvent (ComponentPeer*, void*); + friend unsigned long juce_getCurrentFocusWindow (ComponentPeer*); + + class Pimpl; + friend struct ContainerDeletePolicy; + ScopedPointer pimpl; +}; + +#endif diff --git a/source/modules/juce_gui_extra/juce_gui_extra.cpp b/source/modules/juce_gui_extra/juce_gui_extra.cpp index e103c3ea4..f89e0a86e 100644 --- a/source/modules/juce_gui_extra/juce_gui_extra.cpp +++ b/source/modules/juce_gui_extra/juce_gui_extra.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -31,8 +33,6 @@ #error "Incorrect use of JUCE cpp file" #endif -#include "AppConfig.h" - #define JUCE_CORE_INCLUDE_OBJC_HELPERS 1 #define JUCE_CORE_INCLUDE_COM_SMART_PTR 1 #define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1 @@ -70,6 +70,16 @@ #include #undef SIZEOF #undef KeyPress + + #if JUCE_WEB_BROWSER + #include + #include + #include + #include + #include + #include + #include + #endif #endif //============================================================================== @@ -101,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" @@ -115,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" @@ -125,10 +145,11 @@ namespace juce //============================================================================== #elif JUCE_LINUX + #include "native/juce_linux_XEmbedComponent.cpp" #if JUCE_WEB_BROWSER - #include "native/juce_linux_WebBrowserComponent.cpp" + #include "native/juce_linux_X11_WebBrowserComponent.cpp" #endif - #include "native/juce_linux_SystemTrayIcon.cpp" + #include "native/juce_linux_X11_SystemTrayIcon.cpp" //============================================================================== #elif JUCE_ANDROID @@ -140,6 +161,7 @@ namespace juce #if JUCE_WEB_BROWSER bool WebBrowserComponent::pageAboutToLoad (const String&) { return true; } void WebBrowserComponent::pageFinishedLoading (const String&) {} + bool WebBrowserComponent::pageLoadHadNetworkError (const String&) { return true; } void WebBrowserComponent::windowCloseRequest() {} void WebBrowserComponent::newWindowAttemptingToLoad (const String&) {} #endif diff --git a/source/modules/juce_gui_extra/juce_gui_extra.h b/source/modules/juce_gui_extra/juce_gui_extra.h index bdd5aeba3..c1162ba75 100644 --- a/source/modules/juce_gui_extra/juce_gui_extra.h +++ b/source/modules/juce_gui_extra/juce_gui_extra.h @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -33,7 +35,7 @@ ID: juce_gui_extra vendor: juce - version: 4.3.1 + version: 5.1.1 name: JUCE extended GUI classes description: Miscellaneous GUI classes for specialised tasks. website: http://www.juce.com/juce @@ -47,7 +49,7 @@ *******************************************************************************/ -#ifndef JUCE_GUI_EXTRA_H_INCLUDED +#pragma once #define JUCE_GUI_EXTRA_H_INCLUDED #include @@ -86,6 +88,7 @@ namespace juce #include "embedding/juce_ActiveXControlComponent.h" #include "embedding/juce_NSViewComponent.h" #include "embedding/juce_UIViewComponent.h" +#include "embedding/juce_XEmbedComponent.h" #include "misc/juce_AppleRemote.h" #include "misc/juce_BubbleMessageComponent.h" #include "misc/juce_ColourSelector.h" @@ -99,5 +102,3 @@ namespace juce #include "misc/juce_AnimatedAppComponent.h" } - -#endif // JUCE_GUI_EXTRA_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp b/source/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp index d7c3fae86..6f461d066 100644 --- a/source/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp +++ b/source/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h b/source/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h index 9ad10038f..eeb29e152 100644 --- a/source/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h +++ b/source/modules/juce_gui_extra/misc/juce_AnimatedAppComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_ANIMATEDAPPCOMPONENT_H_INCLUDED -#define JUCE_ANIMATEDAPPCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -71,7 +72,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AnimatedAppComponent) }; - - - -#endif // JUCE_ANIMATEDAPPCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_AppleRemote.h b/source/modules/juce_gui_extra/misc/juce_AppleRemote.h index 6a6506ced..c784e7129 100644 --- a/source/modules/juce_gui_extra/misc/juce_AppleRemote.h +++ b/source/modules/juce_gui_extra/misc/juce_AppleRemote.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_APPLEREMOTE_H_INCLUDED -#define JUCE_APPLEREMOTE_H_INCLUDED +#pragma once //============================================================================== @@ -111,4 +112,3 @@ private: }; #endif -#endif // JUCE_APPLEREMOTE_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp b/source/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp index f4e871515..556dae356 100644 --- a/source/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp +++ b/source/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h b/source/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h index 18e3beb3c..d63e10720 100644 --- a/source/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h +++ b/source/modules/juce_gui_extra/misc/juce_BubbleMessageComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_BUBBLEMESSAGECOMPONENT_H_INCLUDED -#define JUCE_BUBBLEMESSAGECOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -125,6 +126,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BubbleMessageComponent) }; - - -#endif // JUCE_BUBBLEMESSAGECOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_ColourSelector.cpp b/source/modules/juce_gui_extra/misc/juce_ColourSelector.cpp index 3eef3d363..662fa0dc1 100644 --- a/source/modules/juce_gui_extra/misc/juce_ColourSelector.cpp +++ b/source/modules/juce_gui_extra/misc/juce_ColourSelector.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -207,7 +209,7 @@ public: ColourGradient cg; cg.isRadial = false; cg.point1.setXY (0.0f, (float) edge); - cg.point2.setXY (0.0f, (float) (getHeight() - edge)); + cg.point2.setXY (0.0f, (float) getHeight()); for (float i = 0.0f; i <= 1.0f; i += 0.02f) cg.addColour (i, Colour (i, 1.0f, 1.0f, 1.0f)); @@ -513,7 +515,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); } @@ -523,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, @@ -564,7 +566,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/source/modules/juce_gui_extra/misc/juce_ColourSelector.h b/source/modules/juce_gui_extra/misc/juce_ColourSelector.h index 6f2006a69..7530278e9 100644 --- a/source/modules/juce_gui_extra/misc/juce_ColourSelector.h +++ b/source/modules/juce_gui_extra/misc/juce_ColourSelector.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_COLOURSELECTOR_H_INCLUDED -#define JUCE_COLOURSELECTOR_H_INCLUDED +#pragma once //============================================================================== @@ -109,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); //============================================================================== @@ -166,6 +167,3 @@ private: ColourSelector (bool); #endif }; - - -#endif // JUCE_COLOURSELECTOR_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp b/source/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp index efce528b8..88ee4a8e3 100644 --- a/source/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp +++ b/source/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -99,8 +101,8 @@ public: addButton (TRANS("Cancel"), 0); // (avoid return + escape keys getting processed by the buttons..) - for (int i = getNumChildComponents(); --i >= 0;) - getChildComponent (i)->setWantsKeyboardFocus (false); + for (auto* child : getChildren()) + child->setWantsKeyboardFocus (false); setWantsKeyboardFocus (true); grabKeyboardFocus(); @@ -111,7 +113,7 @@ public: lastPress = key; String message (TRANS("Key") + ": " + owner.getDescriptionForKeyPress (key)); - const CommandID previousCommand = owner.getMappings().findCommandForKeyPress (key); + auto previousCommand = owner.getMappings().findCommandForKeyPress (key); if (previousCommand != 0) message << "\n\n(" @@ -146,7 +148,7 @@ public: { if (newKey.isValid()) { - const CommandID previousCommand = owner.getMappings().findCommandForKeyPress (newKey); + auto previousCommand = owner.getMappings().findCommandForKeyPress (newKey); if (previousCommand == 0 || dontAskUser) { @@ -207,14 +209,14 @@ private: class KeyMappingEditorComponent::ItemComponent : public Component { public: - ItemComponent (KeyMappingEditorComponent& kec, const CommandID command) + ItemComponent (KeyMappingEditorComponent& kec, CommandID command) : owner (kec), commandID (command) { setInterceptsMouseClicks (false, true); const bool isReadOnly = owner.isCommandReadOnly (commandID); - const Array keyPresses (owner.getMappings().getKeyPressesAssignedToCommand (commandID)); + auto keyPresses = owner.getMappings().getKeyPressesAssignedToCommand (commandID); for (int i = 0; i < jmin ((int) maxNumAssignments, keyPresses.size()); ++i) addKeyPressButton (owner.getDescriptionForKeyPress (keyPresses.getReference (i)), i, isReadOnly); @@ -224,7 +226,7 @@ public: void addKeyPressButton (const String& desc, const int index, const bool isReadOnly) { - ChangeKeyButton* const b = new ChangeKeyButton (owner, commandID, desc, index); + auto* b = new ChangeKeyButton (owner, commandID, desc, index); keyChangeButtons.add (b); b->setEnabled (! isReadOnly); @@ -248,7 +250,7 @@ public: for (int i = keyChangeButtons.size(); --i >= 0;) { - ChangeKeyButton* const b = keyChangeButtons.getUnchecked(i); + auto* b = keyChangeButtons.getUnchecked(i); b->fitToContent (getHeight() - 2); b->setTopRightPosition (x, 1); @@ -270,7 +272,7 @@ private: class KeyMappingEditorComponent::MappingItem : public TreeViewItem { public: - MappingItem (KeyMappingEditorComponent& kec, const CommandID command) + MappingItem (KeyMappingEditorComponent& kec, CommandID command) : owner (kec), commandID (command) {} @@ -312,13 +314,9 @@ public: if (isNowOpen) { if (getNumSubItems() == 0) - { - const Array commands (owner.getCommandManager().getCommandsInCategory (categoryName)); - - for (int i = 0; i < commands.size(); ++i) - if (owner.shouldCommandBeIncluded (commands.getUnchecked(i))) - addSubItem (new MappingItem (owner, commands.getUnchecked(i))); - } + for (auto command : owner.getCommandManager().getCommandsInCategory (categoryName)) + if (owner.shouldCommandBeIncluded (command)) + addSubItem (new MappingItem (owner, command)); } else { @@ -358,19 +356,16 @@ public: const OpennessRestorer opennessRestorer (*this); clearSubItems(); - const StringArray categories (owner.getCommandManager().getCommandCategories()); - - for (int i = 0; i < categories.size(); ++i) + for (auto category : owner.getCommandManager().getCommandCategories()) { - const Array commands (owner.getCommandManager().getCommandsInCategory (categories[i])); int count = 0; - for (int j = 0; j < commands.size(); ++j) - if (owner.shouldCommandBeIncluded (commands.getUnchecked(j))) + for (auto command : owner.getCommandManager().getCommandsInCategory (category)) + if (owner.shouldCommandBeIncluded (command)) ++count; if (count > 0) - addSubItem (new CategoryItem (owner, categories[i])); + addSubItem (new CategoryItem (owner, category)); } } @@ -457,14 +452,14 @@ void KeyMappingEditorComponent::resized() //============================================================================== bool KeyMappingEditorComponent::shouldCommandBeIncluded (const CommandID commandID) { - const ApplicationCommandInfo* const ci = mappings.getCommandManager().getCommandForID (commandID); + auto* ci = mappings.getCommandManager().getCommandForID (commandID); return ci != nullptr && (ci->flags & ApplicationCommandInfo::hiddenFromKeyEditor) == 0; } bool KeyMappingEditorComponent::isCommandReadOnly (const CommandID commandID) { - const ApplicationCommandInfo* const ci = mappings.getCommandManager().getCommandForID (commandID); + auto* ci = mappings.getCommandManager().getCommandForID (commandID); return ci != nullptr && (ci->flags & ApplicationCommandInfo::readOnlyInKeyEditor) != 0; } diff --git a/source/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h b/source/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h index 831a4e5ab..e4207bc0b 100644 --- a/source/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h +++ b/source/modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_KEYMAPPINGEDITORCOMPONENT_H_INCLUDED -#define JUCE_KEYMAPPINGEDITORCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -129,6 +130,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KeyMappingEditorComponent) }; - - -#endif // JUCE_KEYMAPPINGEDITORCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp b/source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp index b5e653f77..e87c817d9 100644 --- a/source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp +++ b/source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -51,13 +53,13 @@ private: Array alreadyDone; for (int i = TopLevelWindow::getNumTopLevelWindows(); --i >= 0;) - if (Component* c = TopLevelWindow::getTopLevelWindow(i)) + if (auto* c = TopLevelWindow::getTopLevelWindow(i)) repaintAndResizeAllComps (c, alreadyDone); - Desktop& desktop = Desktop::getInstance(); + auto& desktop = Desktop::getInstance(); for (int i = desktop.getNumComponents(); --i >= 0;) - if (Component* c = desktop.getComponent(i)) + if (auto* c = desktop.getComponent(i)) repaintAndResizeAllComps (c, alreadyDone); } @@ -71,7 +73,7 @@ private: for (int i = c->getNumChildComponents(); --i >= 0;) { - if (Component* child = c->getChildComponent(i)) + if (auto* child = c->getChildComponent(i)) { repaintAndResizeAllComps (child, alreadyDone); alreadyDone.add (child); @@ -122,7 +124,7 @@ LiveValueBase::~LiveValueBase() //============================================================================== LivePropertyEditorBase::LivePropertyEditorBase (LiveValueBase& v, CodeDocument& d) - : value (v), resetButton ("reset"), document (d), sourceEditor (document, &tokeniser), wasHex (false) + : value (v), document (d), sourceEditor (document, &tokeniser) { setSize (600, 100); @@ -153,11 +155,11 @@ void LivePropertyEditorBase::paint (Graphics& g) void LivePropertyEditorBase::resized() { - Rectangle r (getLocalBounds().reduced (0, 3).withTrimmedBottom (1)); + auto r = getLocalBounds().reduced (0, 3).withTrimmedBottom (1); - Rectangle left (r.removeFromLeft (jmax (200, r.getWidth() / 3))); + auto left = r.removeFromLeft (jmax (200, r.getWidth() / 3)); - Rectangle top (left.removeFromTop (25)); + auto top = left.removeFromTop (25); resetButton.setBounds (top.removeFromRight (35).reduced (0, 3)); name.setBounds (top); @@ -206,8 +208,8 @@ void LivePropertyEditorBase::selectOriginalValue() void LivePropertyEditorBase::findOriginalValueInCode() { CodeDocument::Position pos (document, value.sourceLine, 0); - String line (pos.getLineText()); - String::CharPointerType p (line.getCharPointer()); + auto line = pos.getLineText(); + auto p = line.getCharPointer(); p = CharacterFunctions::find (p, CharPointer_ASCII ("JUCE_LIVE_CONSTANT")); @@ -231,13 +233,13 @@ void LivePropertyEditorBase::findOriginalValueInCode() if (p.getAndAdvance() == '(') { - String::CharPointerType start (p), end (p); + auto start = p, end = p; int depth = 1; while (! end.isEmpty()) { - const juce_wchar c = end.getAndAdvance(); + auto c = end.getAndAdvance(); if (c == '(') ++depth; if (c == ')') --depth; @@ -326,11 +328,11 @@ public: void updateItems (ValueList& list) { - if (ValueListHolderComponent* l = dynamic_cast (viewport.getViewedComponent())) + if (auto* l = dynamic_cast (viewport.getViewedComponent())) { while (l->getNumChildComponents() < list.values.size()) { - if (LiveValueBase* v = list.values [l->getNumChildComponents()]) + if (auto* v = list.values [l->getNumChildComponents()]) l->addItem (viewport.getMaximumVisibleWidth(), *v, list.getDocument (v->sourceFile)); else break; @@ -344,7 +346,7 @@ public: { DocumentWindow::resized(); - if (ValueListHolderComponent* l = dynamic_cast (viewport.getViewedComponent())) + if (auto* l = dynamic_cast (viewport.getViewedComponent())) l->layout (viewport.getMaximumVisibleWidth()); } @@ -377,7 +379,7 @@ CodeDocument& ValueList::getDocument (const File& file) if (index >= 0) return *documents.getUnchecked (index); - CodeDocument* doc = documents.add (new CodeDocument()); + auto* doc = documents.add (new CodeDocument()); documentFiles.add (file); doc->replaceAllContent (file.loadFileAsString()); doc->clearUndoHistory(); @@ -407,7 +409,7 @@ struct ColourEditorComp : public Component, void mouseDown (const MouseEvent&) override { - ColourSelector* colourSelector = new ColourSelector(); + auto* colourSelector = new ColourSelector(); colourSelector->setName ("Colour"); colourSelector->setCurrentColour (getColour()); colourSelector->addChangeListener (this); @@ -419,7 +421,7 @@ struct ColourEditorComp : public Component, void changeListenerCallback (ChangeBroadcaster* source) override { - if (ColourSelector* cs = dynamic_cast (source)) + if (auto* cs = dynamic_cast (source)) editor.applyNewValue (getAsString (cs->getCurrentColour(), true)); repaint(); @@ -491,9 +493,9 @@ struct BoolSliderComp : public SliderComp void sliderValueChanged (Slider*) override { editor.applyNewValue (slider.getValue() > 0.5 ? "true" : "false"); } }; -Component* createIntegerSlider (LivePropertyEditorBase& editor) { return new SliderComp (editor, false); } -Component* createFloatSlider (LivePropertyEditorBase& editor) { return new SliderComp (editor, true); } -Component* createBoolSlider (LivePropertyEditorBase& editor) { return new BoolSliderComp (editor); } +Component* createIntegerSlider (LivePropertyEditorBase& editor) { return new SliderComp (editor, false); } +Component* createFloatSlider (LivePropertyEditorBase& editor) { return new SliderComp (editor, true); } +Component* createBoolSlider (LivePropertyEditorBase& editor) { return new BoolSliderComp (editor); } } diff --git a/source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h b/source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h index 4978d3e45..c4281b5b0 100644 --- a/source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h +++ b/source/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_LIVECONSTANTEDITOR_H_INCLUDED -#define JUCE_LIVECONSTANTEDITOR_H_INCLUDED +#pragma once #if JUCE_ENABLE_LIVE_CONSTANT_EDITOR && ! DOXYGEN @@ -122,13 +123,13 @@ namespace LiveConstantEditor LiveValueBase& value; Label name; TextEditor valueEditor; - TextButton resetButton; + TextButton resetButton { "reset" }; CodeDocument& document; CPlusPlusCodeTokeniser tokeniser; CodeEditorComponent sourceEditor; CodeDocument::Position valueStart, valueEnd; ScopedPointer customComp; - bool wasHex; + bool wasHex = false; JUCE_DECLARE_NON_COPYABLE (LivePropertyEditorBase) }; @@ -237,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); } @@ -302,6 +309,3 @@ namespace LiveConstantEditor #define JUCE_LIVE_CONSTANT(initialValue) \ (initialValue) #endif - - -#endif // JUCE_LIVECONSTANTEDITOR_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp b/source/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp index 71df77e8d..e6f612e37 100644 --- a/source/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp +++ b/source/modules/juce_gui_extra/misc/juce_PreferencesPanel.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/misc/juce_PreferencesPanel.h b/source/modules/juce_gui_extra/misc/juce_PreferencesPanel.h index 4c059c710..1b399a11e 100644 --- a/source/modules/juce_gui_extra/misc/juce_PreferencesPanel.h +++ b/source/modules/juce_gui_extra/misc/juce_PreferencesPanel.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_PREFERENCESPANEL_H_INCLUDED -#define JUCE_PREFERENCESPANEL_H_INCLUDED +#pragma once //============================================================================== @@ -142,7 +143,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PreferencesPanel) }; - - - -#endif // JUCE_PREFERENCESPANEL_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp b/source/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp index 39d704893..d7470f6c9 100644 --- a/source/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp +++ b/source/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -137,8 +139,7 @@ void RecentlyOpenedFilesList::registerRecentFileNatively (const File& file) #if JUCE_MAC JUCE_AUTORELEASEPOOL { - [[NSDocumentController sharedDocumentController] - noteNewRecentDocumentURL: [NSURL fileURLWithPath: juceStringToNS (file.getFullPathName())]]; + [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: createNSURLFromFile (file)]; } #else ignoreUnused (file); diff --git a/source/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h b/source/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h index 14d4f5141..fadcaf71e 100644 --- a/source/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h +++ b/source/modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_RECENTLYOPENEDFILESLIST_H_INCLUDED -#define JUCE_RECENTLYOPENEDFILESLIST_H_INCLUDED +#pragma once //============================================================================== @@ -159,6 +160,3 @@ private: JUCE_LEAK_DETECTOR (RecentlyOpenedFilesList) }; - - -#endif // JUCE_RECENTLYOPENEDFILESLIST_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_SplashScreen.cpp b/source/modules/juce_gui_extra/misc/juce_SplashScreen.cpp index 2188c6acd..654669091 100644 --- a/source/modules/juce_gui_extra/misc/juce_SplashScreen.cpp +++ b/source/modules/juce_gui_extra/misc/juce_SplashScreen.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/misc/juce_SplashScreen.h b/source/modules/juce_gui_extra/misc/juce_SplashScreen.h index d65d136ab..62dfc5aac 100644 --- a/source/modules/juce_gui_extra/misc/juce_SplashScreen.h +++ b/source/modules/juce_gui_extra/misc/juce_SplashScreen.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SPLASHSCREEN_H_INCLUDED -#define JUCE_SPLASHSCREEN_H_INCLUDED +#pragma once //============================================================================== @@ -150,6 +151,3 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SplashScreen) }; - - -#endif // JUCE_SPLASHSCREEN_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp b/source/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp index 7843aa439..33ae30828 100644 --- a/source/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp +++ b/source/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h b/source/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h index 573ea3c8b..c3f3930bf 100644 --- a/source/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h +++ b/source/modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_SYSTEMTRAYICONCOMPONENT_H_INCLUDED -#define JUCE_SYSTEMTRAYICONCOMPONENT_H_INCLUDED +#pragma once #if JUCE_WINDOWS || JUCE_LINUX || JUCE_MAC || DOXYGEN @@ -99,4 +100,3 @@ private: #endif -#endif // JUCE_SYSTEMTRAYICONCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h b/source/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h index 7cbb81844..f26a7309b 100644 --- a/source/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h +++ b/source/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_WEBBROWSERCOMPONENT_H_INCLUDED -#define JUCE_WEBBROWSERCOMPONENT_H_INCLUDED +#pragma once #if JUCE_WEB_BROWSER || DOXYGEN @@ -80,6 +81,9 @@ public: /** Refreshes the browser. */ void refresh(); + /** Clear cookies that the OS has stored for the WebComponents of this application */ + static void clearCookies(); + //============================================================================== /** This callback is called when the browser is about to navigate to a new location. @@ -93,6 +97,18 @@ public: /** This callback happens when the browser has finished loading a page. */ virtual void pageFinishedLoading (const String& url); + /** This callback happens when a network error was encountered while + trying to load a page. + + You can override this method to show some other error page by calling + goToURL. Return true to allow the browser to carry on to the internal + browser error page. + + The errorInfo contains some platform dependent string describing the + error. + */ + virtual bool pageLoadHadNetworkError (const String& errorInfo); + /** This callback occurs when a script or other activity in the browser asks for the window to be closed. */ @@ -133,4 +149,3 @@ private: #endif -#endif // JUCE_WEBBROWSERCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp b/source/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp index e6bec05ee..c236b4b3f 100644 --- a/source/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp +++ b/source/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -115,3 +117,7 @@ void WebBrowserComponent::visibilityChanged() void WebBrowserComponent::focusGained (FocusChangeType) { } + +void WebBrowserComponent::clearCookies() +{ +} diff --git a/source/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm b/source/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm index f71c8a99d..933f25ccf 100644 --- a/source/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm +++ b/source/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp b/source/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp deleted file mode 100644 index 6de6880e0..000000000 --- a/source/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. - - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 - - Details of these licenses can be found at: www.gnu.org/licenses - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. - - ============================================================================== -*/ - -/* - Sorry.. This class isn't implemented on Linux! -*/ - -//============================================================================== -WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_) - : browser (0), - blankPageShown (false), - unloadPageWhenBrowserIsHidden (unloadPageWhenBrowserIsHidden_) -{ - // Unfortunately, WebBrowserComponent is not implemented for Linux yet! - // This is just a stub implementation without any useful functionality. - jassertfalse; - - setOpaque (true); -} - -WebBrowserComponent::~WebBrowserComponent() -{ -} - -//============================================================================== -void WebBrowserComponent::goToURL (const String& url, - const StringArray* headers, - const MemoryBlock* postData) -{ - lastURL = url; - - if (headers != nullptr) - lastHeaders = *headers; - else - lastHeaders.clear(); - - if (postData != nullptr) - lastPostData = *postData; - else - lastPostData.reset(); - - blankPageShown = false; -} - -void WebBrowserComponent::stop() -{ -} - -void WebBrowserComponent::goBack() -{ - lastURL.clear(); - blankPageShown = false; - -} - -void WebBrowserComponent::goForward() -{ - lastURL.clear(); - -} - -void WebBrowserComponent::refresh() -{ -} - -//============================================================================== -void WebBrowserComponent::paint (Graphics& g) -{ - g.fillAll (Colours::white); -} - -void WebBrowserComponent::checkWindowAssociation() -{ -} - -void WebBrowserComponent::reloadLastURL() -{ - if (lastURL.isNotEmpty()) - { - goToURL (lastURL, &lastHeaders, &lastPostData); - lastURL.clear(); - } -} - -void WebBrowserComponent::parentHierarchyChanged() -{ - checkWindowAssociation(); -} - -void WebBrowserComponent::resized() -{ -} - -void WebBrowserComponent::visibilityChanged() -{ - checkWindowAssociation(); -} - -void WebBrowserComponent::focusGained (FocusChangeType) -{ -} diff --git a/source/modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp b/source/modules/juce_gui_extra/native/juce_linux_X11_SystemTrayIcon.cpp similarity index 72% rename from source/modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp rename to source/modules/juce_gui_extra/native/juce_linux_X11_SystemTrayIcon.cpp index a5224830c..35eed3733 100644 --- a/source/modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp +++ b/source/modules/juce_gui_extra/native/juce_linux_X11_SystemTrayIcon.cpp @@ -2,42 +2,45 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -extern ::Display* display; - //============================================================================== class SystemTrayIconComponent::Pimpl { public: Pimpl (const Image& im, Window windowH) : image (im) { - ScopedXLock xlock; + ScopedXDisplay xDisplay; + auto display = xDisplay.display; + + ScopedXLock xlock (display); Screen* const screen = XDefaultScreenOfDisplay (display); const int screenNumber = XScreenNumberOfScreen (screen); String screenAtom ("_NET_SYSTEM_TRAY_S"); screenAtom << screenNumber; - Atom selectionAtom = XInternAtom (display, screenAtom.toUTF8(), false); + Atom selectionAtom = Atoms::getCreating (display, screenAtom.toUTF8()); XGrabServer (display); Window managerWin = XGetSelectionOwner (display, selectionAtom); @@ -53,7 +56,7 @@ public: XEvent ev = { 0 }; ev.xclient.type = ClientMessage; ev.xclient.window = managerWin; - ev.xclient.message_type = XInternAtom (display, "_NET_SYSTEM_TRAY_OPCODE", False); + ev.xclient.message_type = Atoms::getCreating (display, "_NET_SYSTEM_TRAY_OPCODE"); ev.xclient.format = 32; ev.xclient.data.l[0] = CurrentTime; ev.xclient.data.l[1] = 0 /*SYSTEM_TRAY_REQUEST_DOCK*/; @@ -67,11 +70,11 @@ public: // For older KDE's ... long atomData = 1; - Atom trayAtom = XInternAtom (display, "KWM_DOCKWINDOW", false); + Atom trayAtom = Atoms::getCreating (display, "KWM_DOCKWINDOW"); XChangeProperty (display, windowH, trayAtom, trayAtom, 32, PropModeReplace, (unsigned char*) &atomData, 1); // For more recent KDE's... - trayAtom = XInternAtom (display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", false); + trayAtom = Atoms::getCreating (display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR"); XChangeProperty (display, windowH, trayAtom, XA_WINDOW, 32, PropModeReplace, (unsigned char*) &windowH, 1); // A minimum size must be specified for GNOME and Xfce, otherwise the icon is displayed with a width of 1 diff --git a/source/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp b/source/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp new file mode 100644 index 000000000..07c64fbe2 --- /dev/null +++ b/source/modules/juce_gui_extra/native/juce_linux_X11_WebBrowserComponent.cpp @@ -0,0 +1,823 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +//============================================================================== +extern int juce_gtkWebkitMain (int argc, const char* argv[]); + +class CommandReceiver +{ +public: + struct Responder + { + virtual ~Responder() {} + + virtual void handleCommand (const String& cmd, const var& param) = 0; + virtual void receiverHadError() = 0; + }; + + CommandReceiver (Responder* responderToUse, int inputChannelToUse) + : responder (responderToUse), inChannel (inputChannelToUse) + { + setBlocking (inChannel, false); + } + + static void setBlocking (int fd, bool shouldBlock) + { + int flags = fcntl (fd, F_GETFL); + fcntl (fd, F_SETFL, (shouldBlock ? (flags & ~O_NONBLOCK) + : (flags | O_NONBLOCK))); + } + + int getFd() const { return inChannel; } + + void tryNextRead() + { + while (true) + { + size_t len = (receivingLength ? sizeof (size_t) : bufferLength.len); + + if (! receivingLength) + buffer.realloc (len); + + char* dst = (receivingLength ? bufferLength.data : buffer.getData()); + + ssize_t actual = read (inChannel, &dst[pos], static_cast (len - pos)); + + if (actual < 0) + { + if (errno == EINTR) + continue; + + break; + } + + pos += static_cast (actual); + + if (pos == len) + { + pos = 0; + + if (! receivingLength) + parseJSON (String (buffer.getData(), bufferLength.len)); + + receivingLength = (! receivingLength); + } + } + + if (errno != EAGAIN && errno != EWOULDBLOCK && responder != nullptr) + responder->receiverHadError(); + } + + static void sendCommand (int outChannel, const String& cmd, const var& params) + { + DynamicObject::Ptr obj = new DynamicObject; + + obj->setProperty (getCmdIdentifier(), cmd); + + if (! params.isVoid()) + obj->setProperty (getParamIdentifier(), params); + + String json (JSON::toString (var (obj))); + + size_t jsonLength = static_cast (json.length()); + size_t len = sizeof (size_t) + jsonLength; + + HeapBlock buffer (len); + char* dst = buffer.getData(); + + memcpy (dst, &jsonLength, sizeof (size_t)); + dst += sizeof (size_t); + + memcpy (dst, json.toRawUTF8(), jsonLength); + + ssize_t ret; + + do + { + ret = write (outChannel, buffer.getData(), len); + } while (ret == -1 && errno == EINTR); + } + +private: + void parseJSON (const String& json) + { + var object (JSON::fromString (json)); + + if (! object.isVoid()) + { + String cmd (object.getProperty (getCmdIdentifier(), var()).toString()); + var params (object.getProperty (getParamIdentifier(), var())); + + if (responder != nullptr) + responder->handleCommand (cmd, params); + } + } + + static Identifier getCmdIdentifier() { static Identifier Id ("cmd"); return Id; } + static Identifier getParamIdentifier() { static Identifier Id ("params"); return Id; } + + Responder* responder; + int inChannel; + size_t pos = 0; + bool receivingLength = true; + union { char data [sizeof (size_t)]; size_t len; } bufferLength; + HeapBlock buffer; +}; + +//============================================================================== +class GtkChildProcess : private CommandReceiver::Responder +{ +public: + //============================================================================== + GtkChildProcess (int inChannel, int outChannelToUse) + : outChannel (outChannelToUse), receiver (this, inChannel) + {} + + typedef void (*SetHardwareAcclPolicyFunctionPtr) (WebKitSettings*, int); + + int entry() + { + CommandReceiver::setBlocking (outChannel, true); + + gtk_init (nullptr, nullptr); + + WebKitSettings* settings = webkit_settings_new(); + + // 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; + + plug = gtk_plug_new(0); + GtkWidget* container; + container = gtk_scrolled_window_new (nullptr, nullptr); + + GtkWidget* webviewWidget = webkit_web_view_new_with_settings (settings); + webview = WEBKIT_WEB_VIEW (webviewWidget); + + + gtk_container_add (GTK_CONTAINER (container), webviewWidget); + gtk_container_add (GTK_CONTAINER (plug), container); + + webkit_web_view_load_uri (webview, "about:blank"); + + g_signal_connect (webview, "decide-policy", + G_CALLBACK (decidePolicyCallback), this); + + g_signal_connect (webview, "load-changed", + G_CALLBACK (loadChangedCallback), this); + + g_signal_connect (webview, "load-failed", + G_CALLBACK (loadFailedCallback), this); + + gtk_widget_show_all (plug); + unsigned long wID = (unsigned long) gtk_plug_get_id (GTK_PLUG (plug)); + + + ssize_t ret; + + do { + ret = write (outChannel, &wID, sizeof (wID)); + } while (ret == -1 && errno == EINTR); + + g_unix_fd_add (receiver.getFd(), G_IO_IN, pipeReadyStatic, this); + receiver.tryNextRead(); + + gtk_main(); + return 0; + } + + void goToURL (const var& params) + { + static Identifier urlIdentifier ("url"); + String url (params.getProperty (urlIdentifier, var()).toString()); + + webkit_web_view_load_uri (webview, url.toRawUTF8()); + } + + void handleDecisionResponse (const var& params) + { + WebKitPolicyDecision* decision + = (WebKitPolicyDecision*) ((int64) params.getProperty ("decision_id", var (0))); + bool allow = params.getProperty ("allow", var (false)); + + if (decision != nullptr && decisions.contains (decision)) + { + if (allow) + webkit_policy_decision_use (decision); + else + webkit_policy_decision_ignore (decision); + + decisions.removeAllInstancesOf (decision); + g_object_unref (decision); + } + } + + //============================================================================== + void handleCommand (const String& cmd, const var& params) override + { + if (cmd == "quit") quit(); + else if (cmd == "goToURL") goToURL (params); + else if (cmd == "goBack") webkit_web_view_go_back (webview); + else if (cmd == "goForward") webkit_web_view_go_forward (webview); + else if (cmd == "refresh") webkit_web_view_reload (webview); + else if (cmd == "stop") webkit_web_view_stop_loading (webview); + else if (cmd == "decision") handleDecisionResponse (params); + } + + void receiverHadError() override + { + exit (-1); + } + + //============================================================================== + bool pipeReady (gint fd, GIOCondition) + { + if (fd == receiver.getFd()) + { + receiver.tryNextRead(); + return true; + } + + return false; + } + + void quit() + { + gtk_main_quit(); + } + + bool onNavigation (String frameName, + WebKitNavigationAction* action, + WebKitPolicyDecision* decision) + { + if (decision != nullptr && frameName.isEmpty()) + { + g_object_ref (decision); + decisions.add (decision); + + DynamicObject::Ptr params = new DynamicObject; + + params->setProperty ("url", String (webkit_uri_request_get_uri (webkit_navigation_action_get_request (action)))); + params->setProperty ("decision_id", (int64) decision); + CommandReceiver::sendCommand (outChannel, "pageAboutToLoad", var (params)); + + return true; + } + + return false; + } + + bool onNewWindow (String /*frameName*/, + WebKitNavigationAction* action, + WebKitPolicyDecision* decision) + { + if (decision != nullptr) + { + DynamicObject::Ptr params = new DynamicObject; + + params->setProperty ("url", String (webkit_uri_request_get_uri (webkit_navigation_action_get_request (action)))); + CommandReceiver::sendCommand (outChannel, "newWindowAttemptingToLoad", var (params)); + + // never allow new windows + webkit_policy_decision_ignore (decision); + + return true; + } + + return false; + } + + void onLoadChanged (WebKitLoadEvent loadEvent) + { + if (loadEvent == WEBKIT_LOAD_FINISHED) + { + DynamicObject::Ptr params = new DynamicObject; + + params->setProperty ("url", String (webkit_web_view_get_uri (webview))); + CommandReceiver::sendCommand (outChannel, "pageFinishedLoading", var (params)); + } + } + + bool onDecidePolicy (WebKitPolicyDecision* decision, + WebKitPolicyDecisionType decisionType) + { + switch (decisionType) + { + case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION: + { + WebKitNavigationPolicyDecision* navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION (decision); + const char* frameName = webkit_navigation_policy_decision_get_frame_name (navigationDecision); + + return onNavigation (String (frameName != nullptr ? frameName : ""), + webkit_navigation_policy_decision_get_navigation_action (navigationDecision), + decision); + } + break; + case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION: + { + WebKitNavigationPolicyDecision* navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION (decision); + const char* frameName = webkit_navigation_policy_decision_get_frame_name (navigationDecision); + + return onNewWindow (String (frameName != nullptr ? frameName : ""), + webkit_navigation_policy_decision_get_navigation_action (navigationDecision), + decision); + } + break; + case WEBKIT_POLICY_DECISION_TYPE_RESPONSE: + { + WebKitResponsePolicyDecision *response = WEBKIT_RESPONSE_POLICY_DECISION (decision); + + // for now just always allow response requests + ignoreUnused (response); + webkit_policy_decision_use (decision); + return true; + } + break; + default: + break; + } + + return false; + } + + void onLoadFailed (GError* error) + { + DynamicObject::Ptr params = new DynamicObject; + + params->setProperty ("error", String (error != nullptr ? error->message : "unknown error")); + CommandReceiver::sendCommand (outChannel, "pageLoadHadNetworkError", var (params)); + } + +private: + static gboolean pipeReadyStatic (gint fd, GIOCondition condition, gpointer user) + { + return (reinterpret_cast (user)->pipeReady (fd, condition) ? TRUE : FALSE); + } + + static gboolean decidePolicyCallback (WebKitWebView*, + WebKitPolicyDecision* decision, + WebKitPolicyDecisionType decisionType, + gpointer user) + { + GtkChildProcess& owner = *reinterpret_cast (user); + return (owner.onDecidePolicy (decision, decisionType) ? TRUE : FALSE); + } + + static void loadChangedCallback (WebKitWebView*, + WebKitLoadEvent loadEvent, + gpointer user) + { + GtkChildProcess& owner = *reinterpret_cast (user); + owner.onLoadChanged (loadEvent); + } + + static void loadFailedCallback (WebKitWebView*, + WebKitLoadEvent /*loadEvent*/, + gchar* /*failing_uri*/, + GError* error, + gpointer user) + { + GtkChildProcess& owner = *reinterpret_cast (user); + owner.onLoadFailed (error); + } + + int outChannel; + CommandReceiver receiver; + WebKitWebView* webview = nullptr; + Array decisions; +}; + +//============================================================================== +class WebBrowserComponent::Pimpl : private Thread, private CommandReceiver::Responder +{ +public: + Pimpl (WebBrowserComponent& parent) + : Thread ("Webview"), owner (parent) + {} + + ~Pimpl() + { + quit(); + } + + //============================================================================== + void init() + { + launchChild(); + + int ret = pipe (threadControl); + + ignoreUnused (ret); + jassert (ret == 0); + + CommandReceiver::setBlocking (inChannel, true); + CommandReceiver::setBlocking (outChannel, true); + CommandReceiver::setBlocking (threadControl[0], false); + CommandReceiver::setBlocking (threadControl[1], true); + + unsigned long windowHandle; + ssize_t actual = read (inChannel, &windowHandle, sizeof (windowHandle)); + if (actual != sizeof (windowHandle)) + { + killChild(); + return; + } + + receiver = new CommandReceiver (this, inChannel); + startThread(); + + xembed = new XEmbedComponent (windowHandle); + owner.addAndMakeVisible (xembed); + } + + void quit() + { + if (isThreadRunning()) + { + signalThreadShouldExit(); + + char ignore = 0; + ssize_t ret; + + do + { + ret = write (threadControl[1], &ignore, 1); + } while (ret == -1 && errno == EINTR); + + waitForThreadToExit (-1); + receiver = nullptr; + } + + if (childProcess != 0) + { + CommandReceiver::sendCommand (outChannel, "quit", var()); + killChild(); + } + } + + //============================================================================== + void goToURL (const String& url, const StringArray* headers, const MemoryBlock* postData) + { + DynamicObject::Ptr params = new DynamicObject; + + params->setProperty ("url", url); + + if (headers != nullptr) + params->setProperty ("headers", var (*headers)); + + if (postData != nullptr) + params->setProperty ("postData", var (*postData)); + + CommandReceiver::sendCommand (outChannel, "goToURL", var (params)); + } + + void goBack() { CommandReceiver::sendCommand (outChannel, "goBack", var()); } + void goForward() { CommandReceiver::sendCommand (outChannel, "goForward", var()); } + void refresh() { CommandReceiver::sendCommand (outChannel, "refresh", var()); } + void stop() { CommandReceiver::sendCommand (outChannel, "stop", var()); } + + void resized() + { + if (xembed != nullptr) + xembed->setBounds (owner.getLocalBounds()); + } +private: + //============================================================================== + void killChild() + { + if (childProcess != 0) + { + xembed = nullptr; + + int status = 0, result; + + result = waitpid (childProcess, &status, WNOHANG); + for (int i = 0; i < 15 && (! WIFEXITED(status) || result != childProcess); ++i) + { + Thread::sleep (100); + result = waitpid (childProcess, &status, WNOHANG); + } + + // clean-up any zombies + status = 0; + if (! WIFEXITED(status) || result != childProcess) + { + do + { + kill (childProcess, SIGTERM); + waitpid (childProcess, &status, 0); + } while (! WIFEXITED(status)); + } + + childProcess = 0; + } + } + + void launchChild() + { + int ret; + int inPipe[2], outPipe[2]; + + ret = pipe (inPipe); + ignoreUnused (ret); jassert (ret == 0); + + ret = pipe (outPipe); + ignoreUnused (ret); jassert (ret == 0); + + int pid = fork(); + if (pid == 0) + { + close (inPipe[0]); + close (outPipe[1]); + + HeapBlock argv (5); + StringArray arguments; + + arguments.add (File::getSpecialLocation (File::currentExecutableFile).getFullPathName()); + arguments.add ("--juce-gtkwebkitfork-child"); + arguments.add (String (outPipe[0])); + arguments.add (String (inPipe [1])); + + for (int i = 0; i < arguments.size(); ++i) + argv[i] = arguments[i].toRawUTF8(); + + argv[4] = nullptr; + + #if JUCE_STANDALONE_APPLICATION + execv (arguments[0].toRawUTF8(), (char**) argv.getData()); + #else + juce_gtkWebkitMain (4, (const char**) argv.getData()); + #endif + exit (0); + } + + close (inPipe[1]); + close (outPipe[0]); + + inChannel = inPipe[0]; + outChannel = outPipe[1]; + + childProcess = pid; + } + + void run() override + { + while (! threadShouldExit()) + { + if (shouldExit()) + return; + + receiver->tryNextRead(); + + fd_set set; + FD_ZERO (&set); + FD_SET (threadControl[0], &set); + FD_SET (receiver->getFd(), &set); + + int max_fd = jmax (threadControl[0], receiver->getFd()); + + int result = 0; + + while (result == 0 || (result < 0 && errno == EINTR)) + result = select (max_fd + 1, &set, NULL, NULL, NULL); + + if (result < 0) + break; + } + } + + bool shouldExit() + { + char ignore; + ssize_t result = read (threadControl[0], &ignore, 1); + + return (result != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)); + } + + //============================================================================== + void handleCommandOnMessageThread (const String& cmd, const var& params) + { + String url (params.getProperty ("url", var()).toString()); + + if (cmd == "pageAboutToLoad") handlePageAboutToLoad (url, params); + else if (cmd == "pageFinishedLoading") owner.pageFinishedLoading (url); + else if (cmd == "windowCloseRequest") owner.windowCloseRequest(); + else if (cmd == "newWindowAttemptingToLoad") owner.newWindowAttemptingToLoad (url); + else if (cmd == "pageLoadHadNetworkError") handlePageLoadHadNetworkError (params); + + threadBlocker.signal(); + } + + void handlePageAboutToLoad (const String& url, const var& inputParams) + { + int64 decision_id = inputParams.getProperty ("decision_id", var (0)); + + if (decision_id != 0) + { + DynamicObject::Ptr params = new DynamicObject; + + params->setProperty ("decision_id", decision_id); + params->setProperty ("allow", owner.pageAboutToLoad (url)); + + CommandReceiver::sendCommand (outChannel, "decision", var (params)); + } + } + + void handlePageLoadHadNetworkError (const var& params) + { + String error = params.getProperty ("error", "Unknown error"); + + if (owner.pageLoadHadNetworkError (error)) + goToURL (String ("data:text/plain,") + error, nullptr, nullptr); + } + + void handleCommand (const String& cmd, const var& params) override + { + threadBlocker.reset(); + + (new HandleOnMessageThread (this, cmd, params))->post(); + + // wait until the command has executed on the message thread + // this ensures that Pimpl can never be deleted while the + // message has not been executed yet + threadBlocker.wait (-1); + } + + void receiverHadError() override {} + + //============================================================================== + struct HandleOnMessageThread : public CallbackMessage + { + HandleOnMessageThread (Pimpl* pimpl, const String& cmdToUse, const var& params) + : owner (pimpl), cmdToSend (cmdToUse), paramsToSend (params) + {} + + void messageCallback() override + { + owner->handleCommandOnMessageThread (cmdToSend, paramsToSend); + } + + Pimpl* owner; + String cmdToSend; + var paramsToSend; + }; + +private: + WebBrowserComponent& owner; + ScopedPointer receiver; + int childProcess = 0, inChannel = 0, outChannel = 0; + int threadControl[2]; + ScopedPointer xembed; + WaitableEvent threadBlocker; +}; + +//============================================================================== +WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_) + : browser (new Pimpl (*this)), + blankPageShown (false), + unloadPageWhenBrowserIsHidden (unloadPageWhenBrowserIsHidden_) +{ + setOpaque (true); + + browser->init(); +} + +WebBrowserComponent::~WebBrowserComponent() +{ + if (browser != nullptr) + { + delete browser; + browser = nullptr; + } +} + +//============================================================================== +void WebBrowserComponent::goToURL (const String& url, + const StringArray* headers, + const MemoryBlock* postData) +{ + lastURL = url; + + if (headers != nullptr) + lastHeaders = *headers; + else + lastHeaders.clear(); + + if (postData != nullptr) + lastPostData = *postData; + else + lastPostData.reset(); + + blankPageShown = false; + + browser->goToURL (url, headers, postData); +} + +void WebBrowserComponent::stop() +{ + browser->stop(); +} + +void WebBrowserComponent::goBack() +{ + lastURL.clear(); + blankPageShown = false; + + browser->goBack(); +} + +void WebBrowserComponent::goForward() +{ + lastURL.clear(); + browser->goForward(); +} + +void WebBrowserComponent::refresh() +{ + browser->refresh(); +} + +//============================================================================== +void WebBrowserComponent::paint (Graphics& g) +{ + g.fillAll (Colours::white); +} + +void WebBrowserComponent::checkWindowAssociation() +{ +} + +void WebBrowserComponent::reloadLastURL() +{ + if (lastURL.isNotEmpty()) + { + goToURL (lastURL, &lastHeaders, &lastPostData); + lastURL.clear(); + } +} + +void WebBrowserComponent::parentHierarchyChanged() +{ + checkWindowAssociation(); +} + +void WebBrowserComponent::resized() +{ + if (browser != nullptr) + browser->resized(); +} + +void WebBrowserComponent::visibilityChanged() +{ + checkWindowAssociation(); +} + +void WebBrowserComponent::focusGained (FocusChangeType) +{ +} + +void WebBrowserComponent::clearCookies() +{ + // Currently not implemented on linux as WebBrowserComponent currently does not + // store cookies on linux + jassertfalse; +} + +int juce_gtkWebkitMain (int argc, const char* argv[]) +{ + if (argc != 4) return -1; + + + GtkChildProcess child (String (argv[2]).getIntValue(), + String (argv[3]).getIntValue()); + return child.entry(); +} diff --git a/source/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp b/source/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp new file mode 100644 index 000000000..d50a7704d --- /dev/null +++ b/source/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp @@ -0,0 +1,681 @@ +/* + ============================================================================== + + 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. + + ============================================================================== +*/ + +//============================================================================== +bool juce_handleXEmbedEvent (ComponentPeer*, void*); +Window juce_getCurrentFocusWindow (ComponentPeer*); + +//============================================================================== +unsigned long juce_createKeyProxyWindow (ComponentPeer*); +void juce_deleteKeyProxyWindow (ComponentPeer*); + +//============================================================================== +class XEmbedComponent::Pimpl : private ComponentListener +{ +public: + enum + { + maxXEmbedVersionToSupport = 0 + }; + + enum Flags + { + XEMBED_MAPPED = (1<<0) + }; + + enum + { + XEMBED_EMBEDDED_NOTIFY = 0, + XEMBED_WINDOW_ACTIVATE = 1, + XEMBED_WINDOW_DEACTIVATE = 2, + XEMBED_REQUEST_FOCUS = 3, + XEMBED_FOCUS_IN = 4, + XEMBED_FOCUS_OUT = 5, + XEMBED_FOCUS_NEXT = 6, + XEMBED_FOCUS_PREV = 7, + XEMBED_MODALITY_ON = 10, + XEMBED_MODALITY_OFF = 11, + XEMBED_REGISTER_ACCELERATOR = 12, + XEMBED_UNREGISTER_ACCELERATOR = 13, + XEMBED_ACTIVATE_ACCELERATOR = 14 + }; + + enum + { + XEMBED_FOCUS_CURRENT = 0, + XEMBED_FOCUS_FIRST = 1, + XEMBED_FOCUS_LAST = 2 + }; + + //============================================================================== + class SharedKeyWindow : public ReferenceCountedObject + { + public: + typedef ReferenceCountedObjectPtr Ptr; + + //============================================================================== + Window getHandle() { return keyProxy; } + + static Window getCurrentFocusWindow (ComponentPeer* peerToLookFor) + { + auto& keyWindows = getKeyWindows(); + + if (peerToLookFor != nullptr) + if (auto* foundKeyWindow = keyWindows[peerToLookFor]) + return foundKeyWindow->keyProxy; + + return {}; + } + + static SharedKeyWindow::Ptr getKeyWindowForPeer (ComponentPeer* peerToLookFor) + { + jassert (peerToLookFor != nullptr); + + auto& keyWindows = getKeyWindows(); + auto foundKeyWindow = keyWindows[peerToLookFor]; + + if (foundKeyWindow == nullptr) + { + foundKeyWindow = new SharedKeyWindow (peerToLookFor); + keyWindows.set (peerToLookFor, foundKeyWindow); + } + + return foundKeyWindow; + } + + private: + //============================================================================== + friend struct ContainerDeletePolicy; + + SharedKeyWindow (ComponentPeer* peerToUse) + : keyPeer (peerToUse), + keyProxy (juce_createKeyProxyWindow (keyPeer)) + {} + + ~SharedKeyWindow() + { + juce_deleteKeyProxyWindow (keyPeer); + + auto& keyWindows = getKeyWindows(); + keyWindows.remove (keyPeer); + } + + ComponentPeer* keyPeer; + Window keyProxy; + + static HashMap& getKeyWindows() + { + // store a weak reference to the shared key windows + static HashMap keyWindows; + return keyWindows; + } + }; + +public: + //============================================================================== + Pimpl (XEmbedComponent& parent, Window x11Window, + bool wantsKeyboardFocus, bool isClientInitiated, bool shouldAllowResize) + : owner (parent), atoms (x11display.display), clientInitiated (isClientInitiated), + wantsFocus (wantsKeyboardFocus), allowResize (shouldAllowResize) + { + getWidgets().add (this); + + createHostWindow(); + + if (clientInitiated) + setClient (x11Window, true); + + owner.setWantsKeyboardFocus (wantsFocus); + owner.addComponentListener (this); + } + + ~Pimpl() + { + owner.removeComponentListener (this); + setClient (0, true); + + if (host != 0) + { + auto dpy = getDisplay(); + XDestroyWindow (dpy, host); + XSync (dpy, false); + + const long mask = NoEventMask | KeyPressMask | KeyReleaseMask + | EnterWindowMask | LeaveWindowMask | PointerMotionMask + | KeymapStateMask | ExposureMask | StructureNotifyMask + | FocusChangeMask; + + XEvent event; + while (XCheckWindowEvent (dpy, host, mask, &event) == True) + {} + + host = 0; + } + + getWidgets().removeAllInstancesOf (this); + } + + //============================================================================== + void setClient (Window xembedClient, bool shouldReparent) + { + removeClient(); + + if (xembedClient != 0) + { + auto dpy = getDisplay(); + + client = xembedClient; + + // if the client has initiated the component then keep the clients size + // otherwise the client should use the host's window' size + if (clientInitiated) + { + configureNotify(); + } + else + { + auto newBounds = getX11BoundsFromJuce(); + XResizeWindow (dpy, client, static_cast (newBounds.getWidth()), + static_cast (newBounds.getHeight())); + } + + XSelectInput (dpy, client, StructureNotifyMask | PropertyChangeMask | FocusChangeMask); + getXEmbedMappedFlag(); + + if (shouldReparent) + XReparentWindow (dpy, client, host, 0, 0); + + if (supportsXembed) + sendXEmbedEvent (CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, (long) host, xembedVersion); + + updateMapping(); + } + } + + void focusGained (FocusChangeType changeType) + { + if (client != 0 && supportsXembed && wantsFocus) + { + updateKeyFocus(); + sendXEmbedEvent (CurrentTime, XEMBED_FOCUS_IN, + (changeType == focusChangedByTabKey ? XEMBED_FOCUS_FIRST : XEMBED_FOCUS_CURRENT)); + } + } + + void focusLost (FocusChangeType) + { + if (client != 0 && supportsXembed && wantsFocus) + { + sendXEmbedEvent (CurrentTime, XEMBED_FOCUS_OUT); + updateKeyFocus(); + } + } + + void broughtToFront() + { + if (client != 0 && supportsXembed) + sendXEmbedEvent (CurrentTime, XEMBED_WINDOW_ACTIVATE); + } + + unsigned long getHostWindowID() + { + // You are using the client initiated version of the protocol. You cannot + // retrieve the window id of the host. Please read the documentation for + // the XEmebedComponent class. + jassert (! clientInitiated); + + return host; + } + +private: + //============================================================================== + XEmbedComponent& owner; + Window client = 0, host = 0; + + ScopedXDisplay x11display; + Atoms atoms; + + bool clientInitiated; + bool wantsFocus = false; + bool allowResize = false; + bool supportsXembed = false; + bool hasBeenMapped = false; + int xembedVersion = maxXEmbedVersionToSupport; + + ComponentPeer* lastPeer = nullptr; + SharedKeyWindow::Ptr keyWindow; + + //============================================================================== + void componentParentHierarchyChanged (Component&) override { peerChanged (owner.getPeer()); } + void componentMovedOrResized (Component&, bool, bool) override + { + if (host != 0 && lastPeer != nullptr) + { + auto dpy = getDisplay(); + auto newBounds = getX11BoundsFromJuce(); + XWindowAttributes attr; + + if (XGetWindowAttributes (dpy, host, &attr)) + { + Rectangle currentBounds (attr.x, attr.y, attr.width, attr.height); + if (currentBounds != newBounds) + { + XMoveResizeWindow (dpy, host, newBounds.getX(), newBounds.getY(), + static_cast (newBounds.getWidth()), + static_cast (newBounds.getHeight())); + } + } + + if (client != 0 && XGetWindowAttributes (dpy, client, &attr)) + { + Rectangle currentBounds (attr.x, attr.y, attr.width, attr.height); + + if ((currentBounds.getWidth() != newBounds.getWidth() + || currentBounds.getHeight() != newBounds.getHeight())) + { + XMoveResizeWindow (dpy, client, 0, 0, + static_cast (newBounds.getWidth()), + static_cast (newBounds.getHeight())); + } + } + } + } + + //============================================================================== + void createHostWindow() + { + auto dpy = getDisplay(); + int defaultScreen = XDefaultScreen (dpy); + Window root = RootWindow (dpy, defaultScreen); + + XSetWindowAttributes swa; + swa.border_pixel = 0; + swa.background_pixmap = None; + swa.override_redirect = True; + swa.event_mask = SubstructureNotifyMask | StructureNotifyMask | FocusChangeMask; + + host = XCreateWindow (dpy, root, 0, 0, 1, 1, 0, CopyFromParent, + InputOutput, CopyFromParent, + CWEventMask | CWBorderPixel | CWBackPixmap | CWOverrideRedirect, + &swa); + } + + void removeClient() + { + if (client != 0) + { + auto dpy = getDisplay(); + XSelectInput (dpy, client, 0); + + keyWindow = nullptr; + + int defaultScreen = XDefaultScreen (dpy); + Window root = RootWindow (dpy, defaultScreen); + + if (hasBeenMapped) + { + XUnmapWindow (dpy, client); + hasBeenMapped = false; + } + + XReparentWindow (dpy, client, root, 0, 0); + client = 0; + } + } + + void updateMapping() + { + if (client != 0) + { + const bool shouldBeMapped = getXEmbedMappedFlag(); + + if (shouldBeMapped != hasBeenMapped) + { + hasBeenMapped = shouldBeMapped; + + if (shouldBeMapped) + XMapWindow (getDisplay(), client); + else + XUnmapWindow (getDisplay(), client); + } + } + } + + Window getParentX11Window() + { + if (auto peer = owner.getPeer()) + return reinterpret_cast (peer->getNativeHandle()); + + return {}; + } + + Display* getDisplay() { return reinterpret_cast (x11display.display); } + + //============================================================================== + bool getXEmbedMappedFlag() + { + GetXProperty embedInfo (x11display.display, client, atoms.XembedInfo, 0, 2, false, atoms.XembedInfo); + + if (embedInfo.success && embedInfo.actualFormat == 32 + && embedInfo.numItems >= 2 && embedInfo.data != nullptr) + { + auto* buffer = (long*) embedInfo.data; + + supportsXembed = true; + xembedVersion = jmin ((int) maxXEmbedVersionToSupport, (int) buffer[0]); + + return ((buffer[1] & XEMBED_MAPPED) != 0); + } + else + { + supportsXembed = false; + xembedVersion = maxXEmbedVersionToSupport; + } + + return true; + } + + //============================================================================== + void propertyChanged (const Atom& a) + { + if (a == atoms.XembedInfo) + updateMapping(); + } + + void configureNotify() + { + XWindowAttributes attr; + auto dpy = getDisplay(); + + if (XGetWindowAttributes (dpy, client, &attr)) + { + XWindowAttributes hostAttr; + + if (XGetWindowAttributes (dpy, host, &hostAttr)) + if (attr.width != hostAttr.width || attr.height != hostAttr.height) + XResizeWindow (dpy, host, (unsigned int) attr.width, (unsigned int) attr.height); + + // as the client window is not on any screen yet, we need to guess + // on which screen it might appear to get a scaling factor :-( + auto& displays = Desktop::getInstance().getDisplays(); + auto* peer = owner.getPeer(); + const double scale = (peer != nullptr ? displays.getDisplayContaining (peer->getBounds().getCentre()) + : displays.getMainDisplay()).scale; + + Point topLeftInPeer + = (peer != nullptr ? peer->getComponent().getLocalPoint (&owner, Point (0, 0)) + : owner.getBounds().getTopLeft()); + + Rectangle newBounds (topLeftInPeer.getX(), topLeftInPeer.getY(), + static_cast (static_cast (attr.width) / scale), + static_cast (static_cast (attr.height) / scale)); + + + if (peer != nullptr) + newBounds = owner.getLocalArea (&peer->getComponent(), newBounds); + + jassert (newBounds.getX() == 0 && newBounds.getY() == 0); + + if (newBounds != owner.getLocalBounds()) + owner.setSize (newBounds.getWidth(), newBounds.getHeight()); + } + } + + void peerChanged (ComponentPeer* newPeer) + { + if (newPeer != lastPeer) + { + if (lastPeer != nullptr) + keyWindow = nullptr; + + auto dpy = getDisplay(); + Window rootWindow = RootWindow (dpy, DefaultScreen (dpy)); + Rectangle newBounds = getX11BoundsFromJuce(); + + if (newPeer == nullptr) + XUnmapWindow (dpy, host); + + Window newParent = (newPeer != nullptr ? getParentX11Window() : rootWindow); + XReparentWindow (dpy, host, newParent, newBounds.getX(), newBounds.getY()); + + lastPeer = newPeer; + + if (newPeer != nullptr) + { + if (wantsFocus) + { + keyWindow = SharedKeyWindow::getKeyWindowForPeer (newPeer); + updateKeyFocus(); + } + + componentMovedOrResized (owner, true, true); + XMapWindow (dpy, host); + + broughtToFront(); + } + } + } + + void updateKeyFocus() + { + if (lastPeer != nullptr && lastPeer->isFocused()) + XSetInputFocus (getDisplay(), getCurrentFocusWindow (lastPeer), RevertToParent, CurrentTime); + } + + //============================================================================== + void handleXembedCmd (const ::Time& /*xTime*/, long opcode, long /*detail*/, long /*data1*/, long /*data2*/) + { + switch (opcode) + { + case XEMBED_REQUEST_FOCUS: + if (wantsFocus) + owner.grabKeyboardFocus(); + break; + + case XEMBED_FOCUS_NEXT: + if (wantsFocus) + owner.moveKeyboardFocusToSibling (true); + break; + + case XEMBED_FOCUS_PREV: + if (wantsFocus) + owner.moveKeyboardFocusToSibling (false); + break; + } + } + + bool handleX11Event (const XEvent& e) + { + if (e.xany.window == client && client != 0) + { + switch (e.type) + { + case PropertyNotify: + propertyChanged (e.xproperty.atom); + return true; + + case ConfigureNotify: + if (allowResize) + configureNotify(); + else + MessageManager::callAsync([this] () {componentMovedOrResized (owner, true, true);}); + + return true; + } + } + else if (e.xany.window == host && host != 0) + { + switch (e.type) + { + case ReparentNotify: + if (e.xreparent.parent == host && e.xreparent.window != client) + { + setClient (e.xreparent.window, false); + return true; + } + break; + + case CreateNotify: + if (e.xcreatewindow.parent != e.xcreatewindow.window && e.xcreatewindow.parent == host && e.xcreatewindow.window != client) + { + setClient (e.xcreatewindow.window, false); + return true; + } + break; + + case GravityNotify: + componentMovedOrResized (owner, true, true); + return true; + + case ClientMessage: + if (e.xclient.message_type == atoms.XembedMsgType && e.xclient.format == 32) + { + handleXembedCmd ((::Time) e.xclient.data.l[0], e.xclient.data.l[1], + e.xclient.data.l[2], e.xclient.data.l[3], + e.xclient.data.l[4]); + + return true; + } + break; + } + } + + return false; + } + + void sendXEmbedEvent (const ::Time& xTime, long opcode, + long opcodeMinor = 0, long data1 = 0, long data2 = 0) + { + XClientMessageEvent msg; + auto dpy = getDisplay(); + + ::memset (&msg, 0, sizeof (XClientMessageEvent)); + msg.window = client; + msg.type = ClientMessage; + msg.message_type = atoms.XembedMsgType; + msg.format = 32; + msg.data.l[0] = (long) xTime; + msg.data.l[1] = opcode; + msg.data.l[2] = opcodeMinor; + msg.data.l[3] = data1; + msg.data.l[4] = data2; + + XSendEvent (dpy, client, False, NoEventMask, (XEvent*) &msg); + XSync (dpy, False); + } + + Rectangle getX11BoundsFromJuce() + { + if (auto* peer = owner.getPeer()) + { + auto r = peer->getComponent().getLocalArea (&owner, owner.getLocalBounds()); + auto scale = Desktop::getInstance().getDisplays().getDisplayContaining (peer->localToGlobal (r.getCentre())).scale; + + return r * scale; + } + + return owner.getLocalBounds(); + } + + //============================================================================== + friend bool juce::juce_handleXEmbedEvent (ComponentPeer*, void*); + friend unsigned long juce::juce_getCurrentFocusWindow (ComponentPeer*); + + static Array& getWidgets() + { + static Array i; + return i; + } + + static bool dispatchX11Event (ComponentPeer* p, const XEvent* eventArg) + { + if (eventArg != nullptr) + { + auto& e = *eventArg; + + if (auto w = e.xany.window) + for (auto* widget : getWidgets()) + if (w == widget->host || w == widget->client) + return widget->handleX11Event (e); + } + else + { + for (auto* widget : getWidgets()) + if (widget->owner.getPeer() == p) + widget->peerChanged (nullptr); + } + + return false; + } + + static Window getCurrentFocusWindow (ComponentPeer* p) + { + if (p != nullptr) + { + for (auto* widget : getWidgets()) + if (widget->owner.getPeer() == p && widget->owner.hasKeyboardFocus (false)) + return widget->client; + } + + return SharedKeyWindow::getCurrentFocusWindow (p); + } +}; + +//============================================================================== +XEmbedComponent::XEmbedComponent (bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent) + : pimpl (new Pimpl (*this, 0, wantsKeyboardFocus, false, allowForeignWidgetToResizeComponent)) +{ + setOpaque (true); +} + +XEmbedComponent::XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent) + : pimpl (new Pimpl (*this, wID, wantsKeyboardFocus, true, allowForeignWidgetToResizeComponent)) +{ + setOpaque (true); +} + +XEmbedComponent::~XEmbedComponent() {} + +void XEmbedComponent::paint (Graphics& g) +{ + g.fillAll (Colours::lightgrey); +} + +void XEmbedComponent::focusGained (FocusChangeType changeType) { pimpl->focusGained (changeType); } +void XEmbedComponent::focusLost (FocusChangeType changeType) { pimpl->focusLost (changeType); } +void XEmbedComponent::broughtToFront() { pimpl->broughtToFront(); } +unsigned long XEmbedComponent::getHostWindowID() { return pimpl->getHostWindowID(); } + +//============================================================================== +bool juce_handleXEmbedEvent (ComponentPeer* p, void* e) +{ + return ::XEmbedComponent::Pimpl::dispatchX11Event (p, reinterpret_cast (e)); +} + +unsigned long juce_getCurrentFocusWindow (ComponentPeer* peer) +{ + return (unsigned long) ::XEmbedComponent::Pimpl::getCurrentFocusWindow (peer); +} diff --git a/source/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm b/source/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm index 8ea7979ef..b1283c052 100644 --- a/source/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm +++ b/source/modules/juce_gui_extra/native/juce_mac_AppleRemote.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h b/source/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h index bd1d56456..9d3851243 100644 --- a/source/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h +++ b/source/modules/juce_gui_extra/native/juce_mac_CarbonViewWrapperComponent.h @@ -2,28 +2,29 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -#ifndef JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_H_INCLUDED -#define JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_H_INCLUDED +#pragma once //============================================================================== @@ -340,5 +341,3 @@ void* getCarbonWindow (Component* possibleCarbonComponent) return nullptr; } - -#endif // JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_H_INCLUDED diff --git a/source/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm b/source/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm index 2fcf0e047..d99665091 100644 --- a/source/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm +++ b/source/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ diff --git a/source/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp b/source/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp index 5ed2540b6..49cde5eb2 100644 --- a/source/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp +++ b/source/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -34,9 +36,7 @@ class SystemTrayIconComponent::Pimpl : private Timer { public: Pimpl (SystemTrayIconComponent& iconComp, const Image& im) - : owner (iconComp), statusItem (nil), - statusIcon (MouseCursorHelpers::createNSImage (im)), - view (nil), isHighlighted (false) + : owner (iconComp), statusIcon (MouseCursorHelpers::createNSImage (im)) { static SystemTrayViewClass cls; view = [cls.createInstance() init]; @@ -92,41 +92,43 @@ public: if (owner.isCurrentlyBlockedByAnotherModalComponent()) { if (isLeft || isRight) - if (Component* const current = Component::getCurrentlyModalComponent()) + if (auto* current = Component::getCurrentlyModalComponent()) current->inputAttemptWhenModal(); } else { - ModifierKeys eventMods (ModifierKeys::getCurrentModifiersRealtime()); + auto eventMods = ModifierKeys::getCurrentModifiersRealtime(); if (([e modifierFlags] & NSEventModifierFlagCommand) != 0) eventMods = eventMods.withFlags (ModifierKeys::commandModifier); - const Time now (Time::getCurrentTime()); - - MouseInputSource mouseSource = Desktop::getInstance().getMainMouseSource(); - const float pressure = (float) e.pressure; + auto now = Time::getCurrentTime(); + auto mouseSource = Desktop::getInstance().getMainMouseSource(); + auto pressure = (float) e.pressure; if (isLeft || isRight) // Only mouse up is sent by the OS, so simulate a down/up { setHighlighted (true); startTimer (150); - owner.mouseDown (MouseEvent (mouseSource, Point(), + owner.mouseDown (MouseEvent (mouseSource, {}, eventMods.withFlags (isLeft ? ModifierKeys::leftButtonModifier : ModifierKeys::rightButtonModifier), - pressure, &owner, &owner, now, - Point(), now, 1, false)); - - owner.mouseUp (MouseEvent (mouseSource, Point(), eventMods.withoutMouseButtons(), - pressure, &owner, &owner, now, - Point(), now, 1, false)); + pressure, MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, + MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, + &owner, &owner, now, {}, now, 1, false)); + + owner.mouseUp (MouseEvent (mouseSource, {}, eventMods.withoutMouseButtons(), pressure, + MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, + MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, + &owner, &owner, now, {}, now, 1, false)); } else if (type == NSEventTypeMouseMoved) { - owner.mouseMove (MouseEvent (mouseSource, Point(), eventMods, - pressure, &owner, &owner, now, - Point(), now, 1, false)); + owner.mouseMove (MouseEvent (mouseSource, {}, eventMods, pressure, + MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, + MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, + &owner, &owner, now, {}, now, 1, false)); } } } @@ -143,12 +145,12 @@ public: } SystemTrayIconComponent& owner; - NSStatusItem* statusItem; + NSStatusItem* statusItem = nil; private: - NSImage* statusIcon; - NSControl* view; - bool isHighlighted; + NSImage* statusIcon = nil; + NSControl* view = nil; + bool isHighlighted = false; void setIconSize() { @@ -183,7 +185,7 @@ private: static void frameChanged (id self, SEL, NSNotification*) { - if (Pimpl* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) { NSRect r = [[[owner->statusItem view] window] frame]; NSRect sr = [[[NSScreen screens] objectAtIndex: 0] frame]; @@ -195,7 +197,7 @@ private: private: static void handleEventDown (id self, SEL, NSEvent* e) { - if (Pimpl* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) owner->handleStatusItemAction (e); } @@ -203,7 +205,7 @@ private: { NSRect bounds = [self bounds]; - if (Pimpl* const owner = getOwner (self)) + if (auto* owner = getOwner (self)) [owner->statusItem drawStatusBarBackgroundInRect: bounds withHighlight: owner->isHighlighted]; diff --git a/source/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/source/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index 855d82029..b44fbeb35 100644 --- a/source/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/source/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -2,28 +2,55 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ #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_") @@ -35,6 +62,8 @@ struct DownloadClickDetectorClass : public ObjCClass addMethod (@selector (webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:), decidePolicyForNewWindowAction, "v@:@@@@@"); addMethod (@selector (webView:didFinishLoadForFrame:), didFinishLoadForFrame, "v@:@@"); + addMethod (@selector (webView:didFailLoadWithError:forFrame:), didFailLoadWithError, "v@:@@@"); + addMethod (@selector (webView:didFailProvisionalLoadWithError:forFrame:), didFailLoadWithError, "v@:@@@"); addMethod (@selector (webView:willCloseFrame:), willCloseFrame, "v@:@@"); addMethod (@selector (webView:runOpenPanelForFileButtonWithResultListener:allowMultipleFiles:), runOpenPanel, "v@:@@", @encode (BOOL)); @@ -50,7 +79,7 @@ private: if (NSURL* url = [actionInformation valueForKey: nsStringLiteral ("WebActionOriginalURLKey")]) return nsStringToJuce ([url absoluteString]); - return String(); + return {}; } static void decidePolicyForNavigationAction (id self, SEL, WebView*, NSDictionary* actionInformation, @@ -78,6 +107,20 @@ private: } } + static void didFailLoadWithError (id self, SEL, WebView* sender, NSError* error, WebFrame* frame) + { + if ([frame isEqual: [sender mainFrame]] && error != nullptr && [error code] != NSURLErrorCancelled) + { + String errorString (nsStringToJuce ([error localizedDescription])); + + bool proceedToErrorPage = getOwner (self)->pageLoadHadNetworkError (errorString); + + // WebKit doesn't have an internal error page, so make a really simple one ourselves + if (proceedToErrorPage) + getOwner(self)->goToURL (String ("data:text/plain;charset=UTF-8,") + errorString); + } + } + static void willCloseFrame (id self, SEL, WebView*, WebFrame*) { getOwner (self)->windowCloseRequest(); @@ -92,10 +135,8 @@ private: if (allowMultipleFiles ? chooser.browseForMultipleFilesToOpen() : chooser.browseForFileToOpen()) { - const Array& files = chooser.getResults(); - - for (int i = 0; i < files.size(); ++i) - [resultListener chooseFilename: juceStringToNS (files.getReference(i).getFullPathName())]; + for (auto& f : chooser.getResults()) + [resultListener chooseFilename: juceStringToNS (f.getFullPathName())]; } #else ignoreUnused (resultListener, allowMultipleFiles); @@ -178,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; @@ -421,3 +465,18 @@ void WebBrowserComponent::visibilityChanged() void WebBrowserComponent::focusGained (FocusChangeType) { } + +void WebBrowserComponent::clearCookies() +{ + NSHTTPCookieStorage* storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + + if (NSArray* cookies = [storage cookies]) + { + const NSUInteger n = [cookies count]; + + for (NSUInteger i = 0; i < n; ++i) + [storage deleteCookie: [cookies objectAtIndex: i]]; + } + + [[NSUserDefaults standardUserDefaults] synchronize]; +} diff --git a/source/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp b/source/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp index da8a0c039..188385b63 100644 --- a/source/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp +++ b/source/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp @@ -2,52 +2,39 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ extern int64 getMouseEventTime(); -#if JUCE_MINGW - #define JUCE_COMCLASS(name, guid) \ - template<> struct UUIDGetter<::name> { static CLSID get() { return uuidFromString (guid); } }; - - #ifdef __uuidof - #undef __uuidof - #endif - - #define __uuidof(cls) UUIDGetter<::cls>::get() - -#else - #define JUCE_COMCLASS(name, guid) -#endif - -JUCE_COMCLASS (IOleObject, "00000112-0000-0000-C000-000000000046") -JUCE_COMCLASS (IOleWindow, "00000114-0000-0000-C000-000000000046") -JUCE_COMCLASS (IOleInPlaceSite, "00000119-0000-0000-C000-000000000046") +JUCE_DECLARE_UUID_GETTER (IOleObject, "00000112-0000-0000-C000-000000000046") +JUCE_DECLARE_UUID_GETTER (IOleWindow, "00000114-0000-0000-C000-000000000046") +JUCE_DECLARE_UUID_GETTER (IOleInPlaceSite, "00000119-0000-0000-C000-000000000046") namespace ActiveXHelpers { //============================================================================== - class JuceIStorage : public ComBaseClassHelper + struct JuceIStorage : public ComBaseClassHelper { - public: JuceIStorage() {} JUCE_COMRESULT CreateStream (const WCHAR*, DWORD, DWORD, DWORD, IStream**) { return E_NOTIMPL; } @@ -68,32 +55,38 @@ namespace ActiveXHelpers }; //============================================================================== - class JuceOleInPlaceFrame : public ComBaseClassHelper + struct JuceOleInPlaceFrame : public ComBaseClassHelper { - public: JuceOleInPlaceFrame (HWND hwnd) : window (hwnd) {} - JUCE_COMRESULT GetWindow (HWND* lphwnd) { *lphwnd = window; return S_OK; } - JUCE_COMRESULT ContextSensitiveHelp (BOOL) { return E_NOTIMPL; } - JUCE_COMRESULT GetBorder (LPRECT) { return E_NOTIMPL; } - JUCE_COMRESULT RequestBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; } - JUCE_COMRESULT SetBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; } - JUCE_COMRESULT SetActiveObject (IOleInPlaceActiveObject*, LPCOLESTR) { return S_OK; } - JUCE_COMRESULT InsertMenus (HMENU, LPOLEMENUGROUPWIDTHS) { return E_NOTIMPL; } - JUCE_COMRESULT SetMenu (HMENU, HOLEMENU, HWND) { return S_OK; } - JUCE_COMRESULT RemoveMenus (HMENU) { return E_NOTIMPL; } - JUCE_COMRESULT SetStatusText (LPCOLESTR) { return S_OK; } - JUCE_COMRESULT EnableModeless (BOOL) { return S_OK; } - JUCE_COMRESULT TranslateAccelerator (LPMSG, WORD) { return E_NOTIMPL; } - - private: + JUCE_COMRESULT GetWindow (HWND* lphwnd) { *lphwnd = window; return S_OK; } + JUCE_COMRESULT ContextSensitiveHelp (BOOL) { return E_NOTIMPL; } + JUCE_COMRESULT GetBorder (LPRECT) { return E_NOTIMPL; } + JUCE_COMRESULT RequestBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; } + JUCE_COMRESULT SetBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; } + JUCE_COMRESULT SetActiveObject (IOleInPlaceActiveObject* a, LPCOLESTR) { activeObject = a; return S_OK; } + JUCE_COMRESULT InsertMenus (HMENU, LPOLEMENUGROUPWIDTHS) { return E_NOTIMPL; } + JUCE_COMRESULT SetMenu (HMENU, HOLEMENU, HWND) { return S_OK; } + JUCE_COMRESULT RemoveMenus (HMENU) { return E_NOTIMPL; } + JUCE_COMRESULT SetStatusText (LPCOLESTR) { return S_OK; } + JUCE_COMRESULT EnableModeless (BOOL) { return S_OK; } + JUCE_COMRESULT TranslateAccelerator (LPMSG, WORD) { return E_NOTIMPL; } + + HRESULT OfferKeyTranslation (LPMSG lpmsg) + { + if (activeObject != nullptr) + return activeObject->TranslateAcceleratorW (lpmsg); + + return S_FALSE; + } + HWND window; + ComSmartPtr activeObject; }; //============================================================================== - class JuceIOleInPlaceSite : public ComBaseClassHelper + struct JuceIOleInPlaceSite : public ComBaseClassHelper { - public: JuceIOleInPlaceSite (HWND hwnd) : window (hwnd), frame (new JuceOleInPlaceFrame (window)) @@ -131,17 +124,22 @@ namespace ActiveXHelpers JUCE_COMRESULT DeactivateAndUndo() { return E_NOTIMPL; } JUCE_COMRESULT OnPosRectChange (LPCRECT) { return S_OK; } - private: + LRESULT offerEventToActiveXControl (::MSG& msg) + { + if (frame != nullptr) + return frame->OfferKeyTranslation (&msg); + + return S_FALSE; + } + HWND window; JuceOleInPlaceFrame* frame; }; //============================================================================== - class JuceIOleClientSite : public ComBaseClassHelper + struct JuceIOleClientSite : public ComBaseClassHelper { - public: - JuceIOleClientSite (HWND window) - : inplaceSite (new JuceIOleInPlaceSite (window)) + JuceIOleClientSite (HWND window) : inplaceSite (new JuceIOleInPlaceSite (window)) {} ~JuceIOleClientSite() @@ -168,19 +166,26 @@ namespace ActiveXHelpers JUCE_COMRESULT OnShowWindow (BOOL) { return E_NOTIMPL; } JUCE_COMRESULT RequestNewObjectLayout() { return E_NOTIMPL; } - private: + LRESULT offerEventToActiveXControl (::MSG& msg) + { + if (inplaceSite != nullptr) + return inplaceSite->offerEventToActiveXControl (msg); + + return S_FALSE; + } + JuceIOleInPlaceSite* inplaceSite; }; //============================================================================== static Array activeXComps; - HWND getHWND (const ActiveXControlComponent* const component) + static inline HWND getHWND (const ActiveXControlComponent* const component) { - HWND hwnd = 0; - const IID iid = __uuidof(IOleWindow); + HWND hwnd = {}; + const IID iid = __uuidof (IOleWindow); - if (IOleWindow* const window = (IOleWindow*) component->queryInterface (&iid)) + if (auto* window = (IOleWindow*) component->queryInterface (&iid)) { window->GetWindow (&hwnd); window->Release(); @@ -189,12 +194,8 @@ namespace ActiveXHelpers return hwnd; } - void offerActiveXMouseEventToPeer (ComponentPeer* const peer, HWND hwnd, UINT message, LPARAM lParam) + static inline void offerActiveXMouseEventToPeer (ComponentPeer* peer, HWND hwnd, UINT message, LPARAM lParam) { - RECT activeXRect, peerRect; - GetWindowRect (hwnd, &activeXRect); - GetWindowRect ((HWND) peer->getNativeHandle(), &peerRect); - switch (message) { case WM_MOUSEMOVE: @@ -204,12 +205,20 @@ namespace ActiveXHelpers case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: - peer->handleMouseEvent (0, Point (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left, - GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top).toFloat(), + { + RECT activeXRect, peerRect; + GetWindowRect (hwnd, &activeXRect); + GetWindowRect ((HWND) peer->getNativeHandle(), &peerRect); + + peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, + { (float) (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left), + (float) (GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top) }, ModifierKeys::getCurrentModifiersRealtime(), MouseInputSource::invalidPressure, + MouseInputSource::invalidOrientation, getMouseEventTime()); break; + } default: break; @@ -224,11 +233,8 @@ public: Pimpl (HWND hwnd, ActiveXControlComponent& activeXComp) : ComponentMovementWatcher (&activeXComp), owner (activeXComp), - controlHWND (0), storage (new ActiveXHelpers::JuceIStorage()), - clientSite (new ActiveXHelpers::JuceIOleClientSite (hwnd)), - control (nullptr), - originalWndProc (0) + clientSite (new ActiveXHelpers::JuceIOleClientSite (hwnd)) { } @@ -244,7 +250,7 @@ public: storage->Release(); } - void setControlBounds (const Rectangle& newBounds) const + void setControlBounds (Rectangle newBounds) const { if (controlHWND != 0) MoveWindow (controlHWND, newBounds.getX(), newBounds.getY(), newBounds.getWidth(), newBounds.getHeight(), TRUE); @@ -259,8 +265,8 @@ public: //============================================================================== void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override { - if (ComponentPeer* const peer = owner.getTopLevelComponent()->getPeer()) - setControlBounds (peer->getAreaCoveredBy (owner)); + if (auto* peer = owner.getTopLevelComponent()->getPeer()) + setControlBounds (peer->getAreaCoveredBy(owner)); } void componentPeerChanged() override @@ -277,38 +283,36 @@ public: // intercepts events going to an activeX control, so we can sneakily use the mouse events static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - for (int i = ActiveXHelpers::activeXComps.size(); --i >= 0;) + for (auto* ax : ActiveXHelpers::activeXComps) { - const ActiveXControlComponent* const ax = ActiveXHelpers::activeXComps.getUnchecked(i); - if (ax->control != nullptr && ax->control->controlHWND == hwnd) { switch (message) { - case WM_MOUSEMOVE: - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - case WM_LBUTTONDBLCLK: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONDBLCLK: - if (ax->isShowing()) - { - if (ComponentPeer* const peer = ax->getPeer()) + case WM_MOUSEMOVE: + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + if (ax->isShowing()) { - ActiveXHelpers::offerActiveXMouseEventToPeer (peer, hwnd, message, lParam); + if (auto* peer = ax->getPeer()) + { + ActiveXHelpers::offerActiveXMouseEventToPeer (peer, hwnd, message, lParam); - if (! ax->areMouseEventsAllowed()) - return 0; + if (! ax->areMouseEventsAllowed()) + return 0; + } } - } - break; + break; - default: - break; + default: + break; } return CallWindowProc (ax->control->originalWndProc, hwnd, message, wParam, lParam); @@ -319,16 +323,15 @@ public: } ActiveXControlComponent& owner; - HWND controlHWND; - IStorage* storage; - IOleClientSite* clientSite; - IOleObject* control; - WNDPROC originalWndProc; + HWND controlHWND = {}; + IStorage* storage = nullptr; + ActiveXHelpers::JuceIOleClientSite* clientSite = nullptr; + IOleObject* control = nullptr; + WNDPROC originalWndProc = 0; }; //============================================================================== ActiveXControlComponent::ActiveXControlComponent() - : mouseEventsAllowed (true) { ActiveXHelpers::activeXComps.add (this); } @@ -349,18 +352,18 @@ bool ActiveXControlComponent::createControl (const void* controlIID) { deleteControl(); - if (ComponentPeer* const peer = getPeer()) + if (auto* peer = getPeer()) { - const Rectangle controlBounds (peer->getAreaCoveredBy (*this)); - - HWND hwnd = (HWND) peer->getNativeHandle(); + auto controlBounds = peer->getAreaCoveredBy (*this); + auto hwnd = (HWND) peer->getNativeHandle(); ScopedPointer newControl (new Pimpl (hwnd, *this)); - HRESULT hr; - if ((hr = OleCreate (*(const IID*) controlIID, __uuidof (IOleObject), 1 /*OLERENDER_DRAW*/, 0, - newControl->clientSite, newControl->storage, - (void**) &(newControl->control))) == S_OK) + HRESULT hr = OleCreate (*(const IID*) controlIID, __uuidof (IOleObject), 1 /*OLERENDER_DRAW*/, 0, + newControl->clientSite, newControl->storage, + (void**) &(newControl->control)); + + if (hr == S_OK) { newControl->control->SetHostNames (L"JUCE", 0); @@ -419,3 +422,32 @@ void ActiveXControlComponent::setMouseEventsAllowed (const bool eventsCanReachCo { mouseEventsAllowed = eventsCanReachControl; } + +intptr_t ActiveXControlComponent::offerEventToActiveXControl (void* ptr) +{ + if (control != nullptr && control->clientSite != nullptr) + return (intptr_t) control->clientSite->offerEventToActiveXControl (*reinterpret_cast<::MSG*> (ptr)); + + return S_FALSE; +} + +intptr_t ActiveXControlComponent::offerEventToActiveXControlStatic (void* ptr) +{ + for (auto* ax : ActiveXHelpers::activeXComps) + { + auto result = ax->offerEventToActiveXControl (ptr); + + if (result != S_FALSE) + return result; + } + + return S_FALSE; +} + +LRESULT juce_offerEventToActiveXControl (::MSG& msg) +{ + if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) + return ActiveXControlComponent::offerEventToActiveXControlStatic (&msg); + + return S_FALSE; +} diff --git a/source/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp b/source/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp index b9afe2055..7e3f9e2a6 100644 --- a/source/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp +++ b/source/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp @@ -2,22 +2,24 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ @@ -93,7 +95,7 @@ public: if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN || lParam == WM_LBUTTONDBLCLK || lParam == WM_RBUTTONDBLCLK) { - if (Component* const current = Component::getCurrentlyModalComponent()) + if (auto* current = Component::getCurrentlyModalComponent()) current->inputAttemptWhenModal(); } } @@ -110,9 +112,10 @@ public: const Time eventTime (getMouseEventTime()); - const MouseEvent e (Desktop::getInstance().getMainMouseSource(), - Point(), eventMods, MouseInputSource::invalidPressure, - &owner, &owner, eventTime, Point(), eventTime, 1, false); + const MouseEvent e (Desktop::getInstance().getMainMouseSource(), {}, eventMods, + MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, + MouseInputSource::invalidRotation, MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, + &owner, &owner, eventTime, {}, eventTime, 1, false); if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) { diff --git a/source/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp b/source/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp index 5cccd6c54..5831a9cc0 100644 --- a/source/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp +++ b/source/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp @@ -2,40 +2,37 @@ ============================================================================== This file is part of the JUCE library. - Copyright (c) 2015 - ROLI Ltd. + Copyright (c) 2017 - ROLI Ltd. - Permission is granted to use this software under the terms of either: - a) the GPL v2 (or any later version) - b) the Affero GPL v3 + JUCE is an open source library subject to commercial or open-source + licensing. - Details of these licenses can be found at: www.gnu.org/licenses + 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). - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + 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). - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.juce.com for more information. + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. ============================================================================== */ -JUCE_COMCLASS (DWebBrowserEvents2, "34A715A0-6587-11D0-924A-0020AFC7AC4D") -JUCE_COMCLASS (IConnectionPointContainer, "B196B284-BAB4-101A-B69C-00AA00341D07") -JUCE_COMCLASS (IWebBrowser2, "D30C1661-CDAF-11D0-8A3E-00C04FC9E26E") -JUCE_COMCLASS (WebBrowser, "8856F961-340A-11D0-A96B-00C04FD705A2") +JUCE_DECLARE_UUID_GETTER (DWebBrowserEvents2, "34A715A0-6587-11D0-924A-0020AFC7AC4D") +JUCE_DECLARE_UUID_GETTER (IConnectionPointContainer, "B196B284-BAB4-101A-B69C-00AA00341D07") +JUCE_DECLARE_UUID_GETTER (IWebBrowser2, "D30C1661-CDAF-11D0-8A3E-00C04FC9E26E") +JUCE_DECLARE_UUID_GETTER (WebBrowser, "8856F961-340A-11D0-A96B-00C04FD705A2") class WebBrowserComponent::Pimpl : public ActiveXControlComponent { public: - Pimpl() - : browser (nullptr), - connectionPoint (nullptr), - adviseCookie (0) - { - } + Pimpl() {} ~Pimpl() { @@ -48,25 +45,24 @@ public: void createBrowser() { - CLSID webCLSID = __uuidof (WebBrowser); + auto webCLSID = __uuidof (WebBrowser); createControl (&webCLSID); - GUID iidWebBrowser2 = __uuidof (IWebBrowser2); - GUID iidConnectionPointContainer = __uuidof (IConnectionPointContainer); + auto iidWebBrowser2 = __uuidof (IWebBrowser2); + auto iidConnectionPointContainer = __uuidof (IConnectionPointContainer); browser = (IWebBrowser2*) queryInterface (&iidWebBrowser2); - if (IConnectionPointContainer* connectionPointContainer - = (IConnectionPointContainer*) queryInterface (&iidConnectionPointContainer)) + if (auto connectionPointContainer = (IConnectionPointContainer*) queryInterface (&iidConnectionPointContainer)) { connectionPointContainer->FindConnectionPoint (__uuidof (DWebBrowserEvents2), &connectionPoint); if (connectionPoint != nullptr) { - WebBrowserComponent* const owner = dynamic_cast (getParentComponent()); + auto* owner = dynamic_cast (getParentComponent()); jassert (owner != nullptr); - EventHandler* handler = new EventHandler (*owner); + auto handler = new EventHandler (*owner); connectionPoint->Advise (handler, &adviseCookie); handler->Release(); } @@ -118,7 +114,7 @@ public: } } - BSTR urlBSTR = SysAllocString ((const OLECHAR*) url.toWideCharPointer()); + auto urlBSTR = SysAllocString ((const OLECHAR*) url.toWideCharPointer()); browser->Navigate (urlBSTR, &headerFlags, &frame, &postDataVar, &headersVar); SysFreeString (urlBSTR); @@ -133,11 +129,11 @@ public: } //============================================================================== - IWebBrowser2* browser; + IWebBrowser2* browser = nullptr; private: - IConnectionPoint* connectionPoint; - DWORD adviseCookie; + IConnectionPoint* connectionPoint = nullptr; + DWORD adviseCookie = 0; //============================================================================== struct EventHandler : public ComBaseClassHelper, @@ -173,6 +169,30 @@ private: return S_OK; } + if (dispIdMember == DISPID_NAVIGATEERROR) + { + int statusCode = pDispParams->rgvarg[1].pvarVal->intVal; + *pDispParams->rgvarg[0].pboolVal = VARIANT_FALSE; + + // IWebBrowser2 also reports http status codes here, we need + // report only network erros + if (statusCode < 0) + { + LPTSTR messageBuffer = nullptr; + auto size = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, statusCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &messageBuffer, 0, nullptr); + + String message (messageBuffer, size); + LocalFree (messageBuffer); + + if (! owner.pageLoadHadNetworkError (message)) + *pDispParams->rgvarg[0].pboolVal = VARIANT_TRUE; + } + + return S_OK; + } + if (dispIdMember == 263 /*DISPID_WINDOWCLOSING*/) { owner.windowCloseRequest(); @@ -341,12 +361,12 @@ void WebBrowserComponent::visibilityChanged() void WebBrowserComponent::focusGained (FocusChangeType) { - GUID iidOleObject = __uuidof (IOleObject); - GUID iidOleWindow = __uuidof (IOleWindow); + auto iidOleObject = __uuidof (IOleObject); + auto iidOleWindow = __uuidof (IOleWindow); - if (IOleObject* oleObject = (IOleObject*) browser->queryInterface (&iidOleObject)) + if (auto oleObject = (IOleObject*) browser->queryInterface (&iidOleObject)) { - if (IOleWindow* oleWindow = (IOleWindow*) browser->queryInterface (&iidOleWindow)) + if (auto oleWindow = (IOleWindow*) browser->queryInterface (&iidOleWindow)) { IOleClientSite* oleClientSite = nullptr; @@ -364,3 +384,39 @@ void WebBrowserComponent::focusGained (FocusChangeType) oleObject->Release(); } } + +void WebBrowserComponent::clearCookies() +{ + HeapBlock<::INTERNET_CACHE_ENTRY_INFO> entry; + ::DWORD entrySize = sizeof (::INTERNET_CACHE_ENTRY_INFO); + ::HANDLE urlCacheHandle = ::FindFirstUrlCacheEntry (TEXT ("cookie:"), entry.getData(), &entrySize); + + if (urlCacheHandle == nullptr && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + entry.realloc (1, entrySize); + urlCacheHandle = ::FindFirstUrlCacheEntry (TEXT ("cookie:"), entry.getData(), &entrySize); + } + + if (urlCacheHandle != nullptr) + { + for (;;) + { + ::DeleteUrlCacheEntry (entry.getData()->lpszSourceUrlName); + + if (::FindNextUrlCacheEntry (urlCacheHandle, entry.getData(), &entrySize) == 0) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + entry.realloc (1, entrySize); + + if (::FindNextUrlCacheEntry (urlCacheHandle, entry.getData(), &entrySize) != 0) + continue; + } + + break; + } + } + + FindCloseUrlCache (urlCacheHandle); + } +} diff --git a/source/plugin/Makefile b/source/plugin/Makefile index a6cbc4d99..b2e5ceda6 100644 --- a/source/plugin/Makefile +++ b/source/plugin/Makefile @@ -33,6 +33,7 @@ LIBS += $(MODULEDIR)/jackbridge.a LIBS += $(MODULEDIR)/juce_audio_basics.a LIBS += $(MODULEDIR)/juce_audio_formats.a LIBS += $(MODULEDIR)/juce_core.a +LIBS += $(MODULEDIR)/juce_events.a LIBS += $(MODULEDIR)/lilv.a LIBS += $(MODULEDIR)/native-plugins.a LIBS += $(MODULEDIR)/rtmempool.a @@ -48,7 +49,6 @@ endif ifeq ($(MACOS_OR_WIN32),true) LIBS += $(MODULEDIR)/juce_audio_processors.a LIBS += $(MODULEDIR)/juce_data_structures.a -LIBS += $(MODULEDIR)/juce_events.a LIBS += $(MODULEDIR)/juce_graphics.a LIBS += $(MODULEDIR)/juce_gui_basics.a endif diff --git a/source/utils/CarlaJuceAudioProcessors.cpp b/source/utils/CarlaJuceAudioProcessors.cpp new file mode 100644 index 000000000..89413052c --- /dev/null +++ b/source/utils/CarlaJuceAudioProcessors.cpp @@ -0,0 +1,35 @@ +/* + * Mini version of juce_audio_processors + * Copyright (C) 2014-2017 Filipe Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For a full copy of the GNU General Public License see the doc/GPL.txt file. + */ + +#include "CarlaJuceUtils.hpp" + +// ------------------------------------------------------------------------------------------------------------------- + +#if ! (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)) + +#undef KeyPress +#include "juce_audio_processors/juce_audio_processors.h" + +namespace juce { + +#include "juce_audio_processors/processors/juce_AudioProcessor.cpp" +#include "juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" +#include "juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp" + +} // namespace juce + +#endif // ! CARLA_OS_MAC || CARLA_OS_WIN diff --git a/source/utils/CarlaJuceEvents.cpp b/source/utils/CarlaJuceEvents.cpp deleted file mode 100644 index 5a9e5e358..000000000 --- a/source/utils/CarlaJuceEvents.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Fake juce event thread needed for juce_audio_processors - * Copyright (C) 2014 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ - -#include "CarlaJuceUtils.hpp" - -// ------------------------------------------------------------------------------------------------------------------- - -#if ! (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)) - -#undef KeyPress -#include "juce_audio_processors/juce_audio_processors.h" -#include "juce_events/juce_events.h" - -namespace juce { - -#include "juce_events/broadcasters/juce_ActionBroadcaster.cpp" -#include "juce_events/broadcasters/juce_AsyncUpdater.cpp" -#include "juce_events/messages/juce_DeletedAtShutdown.cpp" -#include "juce_events/messages/juce_MessageManager.cpp" -#include "juce_audio_processors/processors/juce_AudioProcessor.cpp" -#include "juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" -#include "juce_audio_processors/processors/AudioProcessorGraphMultiThreaded.cpp" -#include "juce_audio_processors/utilities/juce_AudioProcessorParameters.cpp" - -class JuceEventsThread : public Thread -{ -public: - JuceEventsThread() - : Thread("JuceEventsThread"), - fInitializing(false), - fLock(), - fQueue() {} - - ~JuceEventsThread() - { - signalThreadShouldExit(); - stopThread(2000); - - const ScopedLock sl(fLock); - CARLA_SAFE_ASSERT(fQueue.size() == 0); - fQueue.clear(); - } - - bool postMessage(MessageManager::MessageBase* const msg) - { - const ScopedLock sl(fLock); - fQueue.add(msg); - return true; - } - - bool isInitializing() const noexcept - { - return fInitializing; - } - -protected: - void run() override - { - /* - * We need to know when we're initializing because MessageManager::setCurrentThreadAsMessageThread() - * calls doPlatformSpecificInitialisation/Shutdown, in which we started this thread previously. - * To avoid a deadlock we do not call start/stopThread if still initializing. - */ - fInitializing = true; - - if (MessageManager* const msgMgr = MessageManager::getInstance()) - msgMgr->setCurrentThreadAsMessageThread(); - - fInitializing = false; - - for (; ! threadShouldExit();) - { - // dispatch messages until no more present, then sleep - for (; dispatchNextInternalMessage();) {} - - sleep(25); - } - } - -private: - volatile bool fInitializing; - CriticalSection fLock; - ReferenceCountedArray fQueue; - - MessageManager::MessageBase::Ptr popNextMessage() - { - const ScopedLock sl(fLock); - return fQueue.removeAndReturn(0); - } - - bool dispatchNextInternalMessage() - { - if (const MessageManager::MessageBase::Ptr msg = popNextMessage()) - { - JUCE_TRY - { - msg->messageCallback(); - return true; - } - JUCE_CATCH_EXCEPTION - } - - return false; - } - - CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JuceEventsThread) -}; - -static JuceEventsThread& getJuceEventsThreadInstance() -{ - static JuceEventsThread sJuceEventsThread; - return sJuceEventsThread; -} - -JUCEApplicationBase::CreateInstanceFunction JUCEApplicationBase::createInstance = nullptr; - -void MessageManager::doPlatformSpecificInitialisation() -{ - JuceEventsThread& juceEventsThread(getJuceEventsThreadInstance()); - - if (! juceEventsThread.isInitializing()) - juceEventsThread.startThread(); -} - -void MessageManager::doPlatformSpecificShutdown() -{ - JuceEventsThread& juceEventsThread(getJuceEventsThreadInstance()); - - if (! juceEventsThread.isInitializing()) - juceEventsThread.stopThread(-1); -} - -bool MessageManager::postMessageToSystemQueue(MessageManager::MessageBase* const message) -{ - JuceEventsThread& juceEventsThread(getJuceEventsThreadInstance()); - return juceEventsThread.postMessage(message); -} - -bool MessageManager::dispatchNextMessageOnSystemQueue(bool) -{ - carla_stderr2("MessageManager::dispatchNextMessageOnSystemQueue() unsupported"); - return false; -} - -} // namespace juce - -#endif // ! CARLA_OS_MAC || CARLA_OS_WIN