diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile index 6650c16363..a626a5a6a1 100644 --- a/Builds/Linux/Makefile +++ b/Builds/Linux/Makefile @@ -253,6 +253,7 @@ OBJECTS := \ $(OBJDIR)/juce_SVGParser_b79416c5.o \ $(OBJDIR)/juce_DropShadowEffect_da52d75.o \ $(OBJDIR)/juce_GlowEffect_c0959893.o \ + $(OBJDIR)/juce_CustomTypeface_b93a3eff.o \ $(OBJDIR)/juce_Font_fa88db26.o \ $(OBJDIR)/juce_GlyphArrangement_f0797295.o \ $(OBJDIR)/juce_TextLayout_d18f700e.o \ @@ -1455,6 +1456,11 @@ $(OBJDIR)/juce_GlowEffect_c0959893.o: ../../src/gui/graphics/effects/juce_GlowEf @echo "Compiling juce_GlowEffect.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_CustomTypeface_b93a3eff.o: ../../src/gui/graphics/fonts/juce_CustomTypeface.cpp + -@mkdir -p $(OBJDIR) + @echo "Compiling juce_CustomTypeface.cpp" + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_Font_fa88db26.o: ../../src/gui/graphics/fonts/juce_Font.cpp -@mkdir -p $(OBJDIR) @echo "Compiling juce_Font.cpp" diff --git a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj index 292112c982..fe321eca00 100644 --- a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj @@ -222,6 +222,7 @@ 645AF66C048A4815F5A8ECDD = { isa = PBXBuildFile; fileRef = 2BFC199D03DEEC329D6A7CB1; }; 38EFE824E76B3BB99824C265 = { isa = PBXBuildFile; fileRef = 32EA297812F1C88B42099501; }; E23C5C51305DC7CE30E4DAB7 = { isa = PBXBuildFile; fileRef = CB649686575473223C859482; }; + 60E1742796432D042C59B9B3 = { isa = PBXBuildFile; fileRef = BA17B023595ECD8166A231D1; }; B92F53BABB6A9AC8348B001E = { isa = PBXBuildFile; fileRef = 78068AA59A5DCFCCAAEA79D0; }; EBC3AA015D24C62FA0307F51 = { isa = PBXBuildFile; fileRef = 61D06B694603F608CDA0703B; }; 803FFCA3DAC0C004A80143B4 = { isa = PBXBuildFile; fileRef = 91CB423DBC5F3CBEDD9CF2EF; }; @@ -859,6 +860,8 @@ CB649686575473223C859482 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GlowEffect.cpp; path = ../../src/gui/graphics/effects/juce_GlowEffect.cpp; sourceTree = SOURCE_ROOT; }; FD1FA4ABB4226372235643E4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_GlowEffect.h; path = ../../src/gui/graphics/effects/juce_GlowEffect.h; sourceTree = SOURCE_ROOT; }; 18DB9BD10F140F132A3279C3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ImageEffectFilter.h; path = ../../src/gui/graphics/effects/juce_ImageEffectFilter.h; sourceTree = SOURCE_ROOT; }; + BA17B023595ECD8166A231D1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_CustomTypeface.cpp; path = ../../src/gui/graphics/fonts/juce_CustomTypeface.cpp; sourceTree = SOURCE_ROOT; }; + 6B4E90767D784246EC4E1944 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CustomTypeface.h; path = ../../src/gui/graphics/fonts/juce_CustomTypeface.h; sourceTree = SOURCE_ROOT; }; 78068AA59A5DCFCCAAEA79D0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Font.cpp; path = ../../src/gui/graphics/fonts/juce_Font.cpp; sourceTree = SOURCE_ROOT; }; 0401EA0E883CCAAAC6960A27 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Font.h; path = ../../src/gui/graphics/fonts/juce_Font.h; sourceTree = SOURCE_ROOT; }; 61D06B694603F608CDA0703B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GlyphArrangement.cpp; path = ../../src/gui/graphics/fonts/juce_GlyphArrangement.cpp; sourceTree = SOURCE_ROOT; }; @@ -1663,6 +1666,8 @@ FD1FA4ABB4226372235643E4, 18DB9BD10F140F132A3279C3 ); name = effects; sourceTree = ""; }; 58FE42C578BFFD1F8F545B39 = { isa = PBXGroup; children = ( + BA17B023595ECD8166A231D1, + 6B4E90767D784246EC4E1944, 78068AA59A5DCFCCAAEA79D0, 0401EA0E883CCAAAC6960A27, 61D06B694603F608CDA0703B, @@ -2260,6 +2265,7 @@ 645AF66C048A4815F5A8ECDD, 38EFE824E76B3BB99824C265, E23C5C51305DC7CE30E4DAB7, + 60E1742796432D042C59B9B3, B92F53BABB6A9AC8348B001E, EBC3AA015D24C62FA0307F51, 803FFCA3DAC0C004A80143B4, diff --git a/Builds/VisualStudio2005/Juce.vcproj b/Builds/VisualStudio2005/Juce.vcproj index 525fa79117..fed4b3606f 100644 --- a/Builds/VisualStudio2005/Juce.vcproj +++ b/Builds/VisualStudio2005/Juce.vcproj @@ -736,6 +736,8 @@ + + diff --git a/Builds/VisualStudio2008/Juce.vcproj b/Builds/VisualStudio2008/Juce.vcproj index 259dfa7533..bd450339c5 100644 --- a/Builds/VisualStudio2008/Juce.vcproj +++ b/Builds/VisualStudio2008/Juce.vcproj @@ -736,6 +736,8 @@ + + diff --git a/Builds/VisualStudio2008_DLL/Juce.vcproj b/Builds/VisualStudio2008_DLL/Juce.vcproj index 7c6a1638d8..cc9a0457da 100644 --- a/Builds/VisualStudio2008_DLL/Juce.vcproj +++ b/Builds/VisualStudio2008_DLL/Juce.vcproj @@ -738,6 +738,8 @@ + + diff --git a/Builds/VisualStudio2010/Juce.vcxproj b/Builds/VisualStudio2010/Juce.vcxproj index d9efa015c6..8948333b41 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj +++ b/Builds/VisualStudio2010/Juce.vcxproj @@ -336,6 +336,7 @@ + @@ -722,6 +723,7 @@ + diff --git a/Builds/VisualStudio2010/Juce.vcxproj.filters b/Builds/VisualStudio2010/Juce.vcxproj.filters index 9b8d58c3b8..c781cef14b 100644 --- a/Builds/VisualStudio2010/Juce.vcxproj.filters +++ b/Builds/VisualStudio2010/Juce.vcxproj.filters @@ -865,6 +865,9 @@ Juce\Source\gui\graphics\effects + + Juce\Source\gui\graphics\fonts + Juce\Source\gui\graphics\fonts @@ -2097,6 +2100,9 @@ Juce\Source\gui\graphics\effects + + Juce\Source\gui\graphics\fonts + Juce\Source\gui\graphics\fonts diff --git a/Builds/iOS/Juce.xcodeproj/project.pbxproj b/Builds/iOS/Juce.xcodeproj/project.pbxproj index 7c91b8ee46..7e5c659503 100644 --- a/Builds/iOS/Juce.xcodeproj/project.pbxproj +++ b/Builds/iOS/Juce.xcodeproj/project.pbxproj @@ -222,6 +222,7 @@ 645AF66C048A4815F5A8ECDD = { isa = PBXBuildFile; fileRef = 2BFC199D03DEEC329D6A7CB1; }; 38EFE824E76B3BB99824C265 = { isa = PBXBuildFile; fileRef = 32EA297812F1C88B42099501; }; E23C5C51305DC7CE30E4DAB7 = { isa = PBXBuildFile; fileRef = CB649686575473223C859482; }; + 60E1742796432D042C59B9B3 = { isa = PBXBuildFile; fileRef = BA17B023595ECD8166A231D1; }; B92F53BABB6A9AC8348B001E = { isa = PBXBuildFile; fileRef = 78068AA59A5DCFCCAAEA79D0; }; EBC3AA015D24C62FA0307F51 = { isa = PBXBuildFile; fileRef = 61D06B694603F608CDA0703B; }; 803FFCA3DAC0C004A80143B4 = { isa = PBXBuildFile; fileRef = 91CB423DBC5F3CBEDD9CF2EF; }; @@ -859,6 +860,8 @@ CB649686575473223C859482 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GlowEffect.cpp; path = ../../src/gui/graphics/effects/juce_GlowEffect.cpp; sourceTree = SOURCE_ROOT; }; FD1FA4ABB4226372235643E4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_GlowEffect.h; path = ../../src/gui/graphics/effects/juce_GlowEffect.h; sourceTree = SOURCE_ROOT; }; 18DB9BD10F140F132A3279C3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ImageEffectFilter.h; path = ../../src/gui/graphics/effects/juce_ImageEffectFilter.h; sourceTree = SOURCE_ROOT; }; + BA17B023595ECD8166A231D1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_CustomTypeface.cpp; path = ../../src/gui/graphics/fonts/juce_CustomTypeface.cpp; sourceTree = SOURCE_ROOT; }; + 6B4E90767D784246EC4E1944 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CustomTypeface.h; path = ../../src/gui/graphics/fonts/juce_CustomTypeface.h; sourceTree = SOURCE_ROOT; }; 78068AA59A5DCFCCAAEA79D0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Font.cpp; path = ../../src/gui/graphics/fonts/juce_Font.cpp; sourceTree = SOURCE_ROOT; }; 0401EA0E883CCAAAC6960A27 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Font.h; path = ../../src/gui/graphics/fonts/juce_Font.h; sourceTree = SOURCE_ROOT; }; 61D06B694603F608CDA0703B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_GlyphArrangement.cpp; path = ../../src/gui/graphics/fonts/juce_GlyphArrangement.cpp; sourceTree = SOURCE_ROOT; }; @@ -1663,6 +1666,8 @@ FD1FA4ABB4226372235643E4, 18DB9BD10F140F132A3279C3 ); name = effects; sourceTree = ""; }; 58FE42C578BFFD1F8F545B39 = { isa = PBXGroup; children = ( + BA17B023595ECD8166A231D1, + 6B4E90767D784246EC4E1944, 78068AA59A5DCFCCAAEA79D0, 0401EA0E883CCAAAC6960A27, 61D06B694603F608CDA0703B, @@ -2264,6 +2269,7 @@ 645AF66C048A4815F5A8ECDD, 38EFE824E76B3BB99824C265, E23C5C51305DC7CE30E4DAB7, + 60E1742796432D042C59B9B3, B92F53BABB6A9AC8348B001E, EBC3AA015D24C62FA0307F51, 803FFCA3DAC0C004A80143B4, diff --git a/Juce.jucer b/Juce.jucer index c7cc527f79..445430c686 100644 --- a/Juce.jucer +++ b/Juce.jucer @@ -1092,6 +1092,10 @@ file="src/gui/graphics/effects/juce_ImageEffectFilter.h"/> + + restoreOpennessState (*oldOpenness); + tree->restoreOpennessState (*oldOpenness, false); } } diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index a667dc549a..e80d7a47b7 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -1500,7 +1500,7 @@ double Random::nextDouble() noexcept return static_cast (nextInt()) / (double) 0xffffffff; } -const BigInteger Random::nextLargeNumber (const BigInteger& maximumValue) +BigInteger Random::nextLargeNumber (const BigInteger& maximumValue) { BigInteger n; @@ -1569,7 +1569,7 @@ double RelativeTime::inHours() const noexcept { return seconds / (60.0 * 60.0 double RelativeTime::inDays() const noexcept { return seconds / (60.0 * 60.0 * 24.0); } double RelativeTime::inWeeks() const noexcept { return seconds / (60.0 * 60.0 * 24.0 * 7.0); } -const String RelativeTime::getDescription (const String& returnValueForZeroTime) const +String RelativeTime::getDescription (const String& returnValueForZeroTime) const { if (seconds < 0.001 && seconds > -0.001) return returnValueForZeroTime; @@ -1677,8 +1677,8 @@ bool operator< (const RelativeTime& t1, const RelativeTime& t2) noexcept { retu bool operator>= (const RelativeTime& t1, const RelativeTime& t2) noexcept { return t1.inSeconds() >= t2.inSeconds(); } bool operator<= (const RelativeTime& t1, const RelativeTime& t2) noexcept { return t1.inSeconds() <= t2.inSeconds(); } -const RelativeTime operator+ (const RelativeTime& t1, const RelativeTime& t2) noexcept { RelativeTime t (t1); return t += t2; } -const RelativeTime operator- (const RelativeTime& t1, const RelativeTime& t2) noexcept { RelativeTime t (t1); return t -= t2; } +RelativeTime operator+ (const RelativeTime& t1, const RelativeTime& t2) noexcept { RelativeTime t (t1); return t += t2; } +RelativeTime operator- (const RelativeTime& t1, const RelativeTime& t2) noexcept { RelativeTime t (t1); return t -= t2; } END_JUCE_NAMESPACE @@ -1766,17 +1766,17 @@ bool Result::operator!= (const Result& other) const noexcept return errorMessage != other.errorMessage; } -const Result Result::ok() noexcept +Result Result::ok() noexcept { return Result (String::empty); } -const Result Result::fail (const String& errorMessage) noexcept +Result Result::fail (const String& errorMessage) noexcept { return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage); } -const String Result::getErrorMessage() const noexcept +const String& Result::getErrorMessage() const noexcept { return errorMessage; } @@ -2075,15 +2075,15 @@ int64 Time::secondsToHighResolutionTicks (const double seconds) noexcept return (int64) (seconds * (double) getHighResolutionTicksPerSecond()); } -const Time JUCE_CALLTYPE Time::getCurrentTime() noexcept +Time JUCE_CALLTYPE Time::getCurrentTime() noexcept { return Time (currentTimeMillis()); } -const String Time::toString (const bool includeDate, - const bool includeTime, - const bool includeSeconds, - const bool use24HourClock) const noexcept +String Time::toString (const bool includeDate, + const bool includeTime, + const bool includeSeconds, + const bool use24HourClock) const noexcept { String result; @@ -2117,7 +2117,7 @@ const String Time::toString (const bool includeDate, return result.trimEnd(); } -const String Time::formatted (const String& format) const +String Time::formatted (const String& format) const { int bufferSize = 128; HeapBlock buffer (128); @@ -2164,7 +2164,7 @@ bool Time::isDaylightSavingTime() const noexcept return TimeHelpers::millisToLocal (millisSinceEpoch).tm_isdst != 0; } -const String Time::getTimeZone() const noexcept +String Time::getTimeZone() const noexcept { String zone[2]; @@ -2204,17 +2204,17 @@ const String Time::getTimeZone() const noexcept return zone[0].substring (0, 3); } -const String Time::getMonthName (const bool threeLetterVersion) const +String Time::getMonthName (const bool threeLetterVersion) const { return getMonthName (getMonth(), threeLetterVersion); } -const String Time::getWeekdayName (const bool threeLetterVersion) const +String Time::getWeekdayName (const bool threeLetterVersion) const { return getWeekdayName (getDayOfWeek(), threeLetterVersion); } -const String Time::getMonthName (int monthNumber, const bool threeLetterVersion) +String Time::getMonthName (int monthNumber, const bool threeLetterVersion) { const char* const shortMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; const char* const longMonthNames[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; @@ -2225,7 +2225,7 @@ const String Time::getMonthName (int monthNumber, const bool threeLetterVersion) : longMonthNames [monthNumber]); } -const String Time::getWeekdayName (int day, const bool threeLetterVersion) +String Time::getWeekdayName (int day, const bool threeLetterVersion) { const char* const shortDayNames[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char* const longDayNames[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; @@ -2239,9 +2239,9 @@ const String Time::getWeekdayName (int day, const bool threeLetterVersion) Time& Time::operator+= (const RelativeTime& delta) { millisSinceEpoch += delta.inMilliseconds(); return *this; } Time& Time::operator-= (const RelativeTime& delta) { millisSinceEpoch -= delta.inMilliseconds(); return *this; } -const Time operator+ (const Time& time, const RelativeTime& delta) { Time t (time); return t += delta; } -const Time operator- (const Time& time, const RelativeTime& delta) { Time t (time); return t -= delta; } -const Time operator+ (const RelativeTime& delta, const Time& time) { Time t (time); return t += delta; } +Time operator+ (const Time& time, const RelativeTime& delta) { Time t (time); return t += delta; } +Time operator- (const Time& time, const RelativeTime& delta) { Time t (time); return t -= delta; } +Time operator+ (const RelativeTime& delta, const Time& time) { Time t (time); return t += delta; } const RelativeTime operator- (const Time& time1, const Time& time2) { return RelativeTime::milliseconds (time1.toMilliseconds() - time2.toMilliseconds()); } bool operator== (const Time& time1, const Time& time2) { return time1.toMilliseconds() == time2.toMilliseconds(); } @@ -2719,7 +2719,7 @@ int BigInteger::toInteger() const noexcept return negative ? -n : n; } -const BigInteger BigInteger::getBitRange (int startBit, int numBits) const +BigInteger BigInteger::getBitRange (int startBit, int numBits) const { BigInteger r; numBits = jmin (numBits, getHighestBit() + 1 - startBit); @@ -3188,33 +3188,24 @@ BigInteger& BigInteger::operator%= (const BigInteger& divisor) return *this; } -BigInteger& BigInteger::operator<<= (int numBitsToShift) -{ - shiftBits (numBitsToShift, 0); - return *this; -} - -BigInteger& BigInteger::operator>>= (int numBitsToShift) -{ - return operator<<= (-numBitsToShift); -} - -BigInteger& BigInteger::operator++() { return operator+= (1); } -BigInteger& BigInteger::operator--() { return operator-= (1); } -const BigInteger BigInteger::operator++ (int) { const BigInteger old (*this); operator+= (1); return old; } -const BigInteger BigInteger::operator-- (int) { const BigInteger old (*this); operator-= (1); return old; } - -const BigInteger BigInteger::operator+ (const BigInteger& other) const { BigInteger b (*this); return b += other; } -const BigInteger BigInteger::operator- (const BigInteger& other) const { BigInteger b (*this); return b -= other; } -const BigInteger BigInteger::operator* (const BigInteger& other) const { BigInteger b (*this); return b *= other; } -const BigInteger BigInteger::operator/ (const BigInteger& other) const { BigInteger b (*this); return b /= other; } -const BigInteger BigInteger::operator| (const BigInteger& other) const { BigInteger b (*this); return b |= other; } -const BigInteger BigInteger::operator& (const BigInteger& other) const { BigInteger b (*this); return b &= other; } -const BigInteger BigInteger::operator^ (const BigInteger& other) const { BigInteger b (*this); return b ^= other; } -const BigInteger BigInteger::operator% (const BigInteger& other) const { BigInteger b (*this); return b %= other; } -const BigInteger BigInteger::operator<< (const int numBits) const { BigInteger b (*this); return b <<= numBits; } -const BigInteger BigInteger::operator>> (const int numBits) const { BigInteger b (*this); return b >>= numBits; } -const BigInteger BigInteger::operator-() const { BigInteger b (*this); b.negate(); return b; } +BigInteger& BigInteger::operator++() { return operator+= (1); } +BigInteger& BigInteger::operator--() { return operator-= (1); } +BigInteger BigInteger::operator++ (int) { const BigInteger old (*this); operator+= (1); return old; } +BigInteger BigInteger::operator-- (int) { const BigInteger old (*this); operator-= (1); return old; } + +BigInteger BigInteger::operator-() const { BigInteger b (*this); b.negate(); return b; } +BigInteger BigInteger::operator+ (const BigInteger& other) const { BigInteger b (*this); return b += other; } +BigInteger BigInteger::operator- (const BigInteger& other) const { BigInteger b (*this); return b -= other; } +BigInteger BigInteger::operator* (const BigInteger& other) const { BigInteger b (*this); return b *= other; } +BigInteger BigInteger::operator/ (const BigInteger& other) const { BigInteger b (*this); return b /= other; } +BigInteger BigInteger::operator| (const BigInteger& other) const { BigInteger b (*this); return b |= other; } +BigInteger BigInteger::operator& (const BigInteger& other) const { BigInteger b (*this); return b &= other; } +BigInteger BigInteger::operator^ (const BigInteger& other) const { BigInteger b (*this); return b ^= other; } +BigInteger BigInteger::operator% (const BigInteger& other) const { BigInteger b (*this); return b %= other; } +BigInteger BigInteger::operator<< (const int numBits) const { BigInteger b (*this); return b <<= numBits; } +BigInteger BigInteger::operator>> (const int numBits) const { BigInteger b (*this); return b >>= numBits; } +BigInteger& BigInteger::operator<<= (const int numBits) { shiftBits (numBits, 0); return *this; } +BigInteger& BigInteger::operator>>= (const int numBits) { shiftBits (-numBits, 0); return *this; } int BigInteger::compare (const BigInteger& other) const noexcept { @@ -3357,7 +3348,7 @@ void BigInteger::shiftBits (int bits, const int startBit) } } -const BigInteger BigInteger::simpleGCD (BigInteger* m, BigInteger* n) +BigInteger BigInteger::simpleGCD (BigInteger* m, BigInteger* n) { while (! m->isZero()) { @@ -3370,7 +3361,7 @@ const BigInteger BigInteger::simpleGCD (BigInteger* m, BigInteger* n) return *n; } -const BigInteger BigInteger::findGreatestCommonDivisor (BigInteger n) const +BigInteger BigInteger::findGreatestCommonDivisor (BigInteger n) const { BigInteger m (*this); @@ -3470,7 +3461,7 @@ OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& return stream << value.toString (10); } -const String BigInteger::toString (const int base, const int minimumNumCharacters) const +String BigInteger::toString (const int base, const int minimumNumCharacters) const { String s; BigInteger v (*this); @@ -3566,7 +3557,7 @@ void BigInteger::parseString (const String& text, const int base) setNegative (text.trimStart().startsWithChar ('-')); } -const MemoryBlock BigInteger::toMemoryBlock() const +MemoryBlock BigInteger::toMemoryBlock() const { const int numBytes = (getHighestBit() + 8) >> 3; MemoryBlock mb ((size_t) numBytes); @@ -3985,8 +3976,8 @@ void PropertySet::clear() } } -const String PropertySet::getValue (const String& keyName, - const String& defaultValue) const noexcept +String PropertySet::getValue (const String& keyName, + const String& defaultValue) const noexcept { const ScopedLock sl (lock); @@ -4216,18 +4207,18 @@ 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 const String toString (const ValueUnion&) const { return String::empty; } + virtual String toString (const ValueUnion&) const { return String::empty; } virtual bool toBool (const ValueUnion&) const noexcept { return false; } virtual ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; } - virtual bool isVoid() const noexcept { return false; } - virtual bool isInt() const noexcept { return false; } - virtual bool isInt64() const noexcept { return false; } - virtual bool isBool() const noexcept { return false; } - virtual bool isDouble() const noexcept { return false; } - virtual bool isString() const noexcept { return false; } - virtual bool isObject() const noexcept { return false; } - virtual bool isMethod() const noexcept { return false; } + virtual bool isVoid() const noexcept { return false; } + virtual bool isInt() const noexcept { return false; } + virtual bool isInt64() const noexcept { return false; } + virtual bool isBool() const noexcept { return false; } + virtual bool isDouble() const noexcept { return false; } + virtual bool isString() const noexcept { return false; } + virtual bool isObject() const noexcept { return false; } + virtual bool isMethod() const noexcept { return false; } virtual void cleanUp (ValueUnion&) const noexcept {} virtual void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest = source; } @@ -4255,7 +4246,7 @@ public: int toInt (const ValueUnion& data) const noexcept { return data.intValue; }; int64 toInt64 (const ValueUnion& data) const noexcept { return (int64) data.intValue; }; double toDouble (const ValueUnion& data) const noexcept { return (double) data.intValue; } - const String toString (const ValueUnion& data) const { return String (data.intValue); } + String toString (const ValueUnion& data) const { return String (data.intValue); } bool toBool (const ValueUnion& data) const noexcept { return data.intValue != 0; } bool isInt() const noexcept { return true; } @@ -4281,7 +4272,7 @@ public: int toInt (const ValueUnion& data) const noexcept { return (int) data.int64Value; }; int64 toInt64 (const ValueUnion& data) const noexcept { return data.int64Value; }; double toDouble (const ValueUnion& data) const noexcept { return (double) data.int64Value; } - const String toString (const ValueUnion& data) const { return String (data.int64Value); } + String toString (const ValueUnion& data) const { return String (data.int64Value); } bool toBool (const ValueUnion& data) const noexcept { return data.int64Value != 0; } bool isInt64() const noexcept { return true; } @@ -4307,7 +4298,7 @@ public: int toInt (const ValueUnion& data) const noexcept { return (int) data.doubleValue; }; int64 toInt64 (const ValueUnion& data) const noexcept { return (int64) data.doubleValue; }; double toDouble (const ValueUnion& data) const noexcept { return data.doubleValue; } - const String toString (const ValueUnion& data) const { return String (data.doubleValue); } + String toString (const ValueUnion& data) const { return String (data.doubleValue); } bool toBool (const ValueUnion& data) const noexcept { return data.doubleValue != 0; } bool isDouble() const noexcept { return true; } @@ -4333,7 +4324,7 @@ public: int toInt (const ValueUnion& data) const noexcept { return data.boolValue ? 1 : 0; }; int64 toInt64 (const ValueUnion& data) const noexcept { return data.boolValue ? 1 : 0; }; double toDouble (const ValueUnion& data) const noexcept { return data.boolValue ? 1.0 : 0.0; } - const String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? '1' : '0'); } + String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? '1' : '0'); } bool toBool (const ValueUnion& data) const noexcept { return data.boolValue; } bool isBool() const noexcept { return true; } @@ -4355,32 +4346,37 @@ public: VariantType_String() noexcept {} static const VariantType_String instance; - void cleanUp (ValueUnion& data) const noexcept { delete data.stringValue; } - void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.stringValue = new String (*source.stringValue); } + void cleanUp (ValueUnion& data) const noexcept { getString (data)-> ~String(); } + void createCopy (ValueUnion& dest, const ValueUnion& source) const { new (dest.stringValue) String (*getString (source)); } - int toInt (const ValueUnion& data) const noexcept { return data.stringValue->getIntValue(); }; - int64 toInt64 (const ValueUnion& data) const noexcept { return data.stringValue->getLargeIntValue(); }; - double toDouble (const ValueUnion& data) const noexcept { return data.stringValue->getDoubleValue(); } - const String toString (const ValueUnion& data) const { return *data.stringValue; } - bool toBool (const ValueUnion& data) const noexcept { return data.stringValue->getIntValue() != 0 - || data.stringValue->trim().equalsIgnoreCase ("true") - || data.stringValue->trim().equalsIgnoreCase ("yes"); } bool isString() const noexcept { return true; } + int toInt (const ValueUnion& data) const noexcept { return getString (data)->getIntValue(); }; + int64 toInt64 (const ValueUnion& data) const noexcept { return getString (data)->getLargeIntValue(); }; + double toDouble (const ValueUnion& data) const noexcept { return getString (data)->getDoubleValue(); } + String toString (const ValueUnion& data) const { return *getString (data); } + bool toBool (const ValueUnion& data) const noexcept { return getString (data)->getIntValue() != 0 + || getString (data)->trim().equalsIgnoreCase ("true") + || getString (data)->trim().equalsIgnoreCase ("yes"); } bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept { - return otherType.toString (otherData) == *data.stringValue; + return otherType.toString (otherData) == *getString (data); } void writeToStream (const ValueUnion& data, OutputStream& output) const { - const int len = data.stringValue->getNumBytesAsUTF8() + 1; + const String* const s = getString (data); + const int len = s->getNumBytesAsUTF8() + 1; + HeapBlock temp (len); + s->copyToUTF8 (temp, len); output.writeCompressedInt (len + 1); output.writeByte (varMarker_String); - HeapBlock temp (len); - data.stringValue->copyToUTF8 (temp, len); output.write (temp, len); } + +private: + static inline const String* getString (const ValueUnion& data) noexcept { return reinterpret_cast (data.stringValue); } + static inline String* getString (ValueUnion& data) noexcept { return reinterpret_cast (data.stringValue); } }; class var::VariantType_Object : public var::VariantType @@ -4392,7 +4388,7 @@ public: void cleanUp (ValueUnion& data) const noexcept { if (data.objectValue != nullptr) data.objectValue->decReferenceCount(); } void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.objectValue = source.objectValue; if (dest.objectValue != nullptr) dest.objectValue->incReferenceCount(); } - const String toString (const ValueUnion& data) const { return "Object 0x" + String::toHexString ((int) (pointer_sized_int) data.objectValue); } + String toString (const ValueUnion& data) const { return "Object 0x" + String::toHexString ((int) (pointer_sized_int) data.objectValue); } bool toBool (const ValueUnion& data) const noexcept { return data.objectValue != 0; } ReferenceCountedObject* toObject (const ValueUnion& data) const noexcept { return data.objectValue; } bool isObject() const noexcept { return true; } @@ -4415,7 +4411,7 @@ public: VariantType_Method() noexcept {} static const VariantType_Method instance; - const String toString (const ValueUnion&) const { return "Method"; } + String toString (const ValueUnion&) const { return "Method"; } bool toBool (const ValueUnion& data) const noexcept { return data.methodValue != 0; } bool isMethod() const noexcept { return true; } @@ -4478,17 +4474,17 @@ var::var (const double value_) noexcept : type (&VariantType_Double::instance) var::var (const String& value_) : type (&VariantType_String::instance) { - value.stringValue = new String (value_); + new (value.stringValue) String (value_); } var::var (const char* const value_) : type (&VariantType_String::instance) { - value.stringValue = new String (value_); + new (value.stringValue) String (value_); } var::var (const wchar_t* const value_) : type (&VariantType_String::instance) { - value.stringValue = new String (value_); + new (value.stringValue) String (value_); } var::var (ReferenceCountedObject* const object) : type (&VariantType_Object::instance) @@ -4504,22 +4500,22 @@ var::var (MethodFunction method_) noexcept : type (&VariantType_Method::instance value.methodValue = method_; } -bool var::isVoid() const noexcept { return type->isVoid(); } -bool var::isInt() const noexcept { return type->isInt(); } -bool var::isInt64() const noexcept { return type->isInt64(); } -bool var::isBool() const noexcept { return type->isBool(); } -bool var::isDouble() const noexcept { return type->isDouble(); } -bool var::isString() const noexcept { return type->isString(); } -bool var::isObject() const noexcept { return type->isObject(); } -bool var::isMethod() const noexcept { return type->isMethod(); } +bool var::isVoid() const noexcept { return type->isVoid(); } +bool var::isInt() const noexcept { return type->isInt(); } +bool var::isInt64() const noexcept { return type->isInt64(); } +bool var::isBool() const noexcept { return type->isBool(); } +bool var::isDouble() const noexcept { return type->isDouble(); } +bool var::isString() const noexcept { return type->isString(); } +bool var::isObject() const noexcept { return type->isObject(); } +bool var::isMethod() const noexcept { return type->isMethod(); } var::operator int() const noexcept { return type->toInt (value); } var::operator int64() const noexcept { return type->toInt64 (value); } var::operator bool() const noexcept { return type->toBool (value); } var::operator float() const noexcept { return (float) type->toDouble (value); } var::operator double() const noexcept { return type->toDouble (value); } -const String var::toString() const { return type->toString (value); } -var::operator const String() const { return type->toString (value); } +String var::toString() const { return type->toString (value); } +var::operator String() const { return type->toString (value); } ReferenceCountedObject* var::getObject() const noexcept { return type->toObject (value); } DynamicObject* var::getDynamicObject() const noexcept { return dynamic_cast (getObject()); } @@ -4562,7 +4558,7 @@ void var::writeToStream (OutputStream& output) const type->writeToStream (value, output); } -const var var::readFromStream (InputStream& input) +var var::readFromStream (InputStream& input) { const int numBytes = input.readCompressedInt(); @@ -4589,60 +4585,57 @@ const var var::readFromStream (InputStream& input) return var::null; } -const var var::operator[] (const Identifier& propertyName) const +var var::operator[] (const Identifier& propertyName) const { DynamicObject* const o = getDynamicObject(); return o != nullptr ? o->getProperty (propertyName) : var::null; } -const var var::invoke (const Identifier& method, const var* arguments, int numArguments) const +var var::invoke (const Identifier& method, const var* arguments, int numArguments) const { DynamicObject* const o = getDynamicObject(); return o != nullptr ? o->invokeMethod (method, arguments, numArguments) : var::null; } -const var var::invoke (const var& targetObject, const var* arguments, int numArguments) const +var var::invokeMethod (DynamicObject* const target, const var* const arguments, const int numArguments) const { - if (isMethod()) - { - DynamicObject* const target = targetObject.getDynamicObject(); + jassert (target != nullptr); - if (target != nullptr) - return (target->*(value.methodValue)) (arguments, numArguments); - } + if (isMethod()) + return (target->*(value.methodValue)) (arguments, numArguments); return var::null; } -const var var::call (const Identifier& method) const +var var::call (const Identifier& method) const { return invoke (method, nullptr, 0); } -const var var::call (const Identifier& method, const var& arg1) const +var var::call (const Identifier& method, const var& arg1) const { return invoke (method, &arg1, 1); } -const var var::call (const Identifier& method, const var& arg1, const var& arg2) const +var var::call (const Identifier& method, const var& arg1, const var& arg2) const { var args[] = { arg1, arg2 }; return invoke (method, args, 2); } -const var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3) +var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3) { var args[] = { arg1, arg2, arg3 }; return invoke (method, args, 3); } -const var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const +var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const { var args[] = { arg1, arg2, arg3, arg4 }; return invoke (method, args, 4); } -const var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const +var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const { var args[] = { arg1, arg2, arg3, arg4, arg5 }; return invoke (method, args, 5); @@ -4744,7 +4737,7 @@ const var& NamedValueSet::operator[] (const Identifier& name) const return var::null; } -const var NamedValueSet::getWithDefault (const Identifier& name, const var& defaultReturnValue) const +var NamedValueSet::getWithDefault (const Identifier& name, const var& defaultReturnValue) const { const var* const v = getVarPointer (name); return v != nullptr ? *v : defaultReturnValue; @@ -4818,7 +4811,7 @@ const Identifier NamedValueSet::getName (const int index) const return v->name; } -const var NamedValueSet::getValueAt (const int index) const +var NamedValueSet::getValueAt (const int index) const { const NamedValue* const v = values[index]; jassert (v != nullptr); @@ -4893,7 +4886,7 @@ const var DynamicObject::invokeMethod (const Identifier& methodName, const var* parameters, int numParameters) { - return properties [methodName].invoke (var (this), parameters, numParameters); + return properties [methodName].invokeMethod (this, parameters, numParameters); } void DynamicObject::setMethod (const Identifier& name, @@ -4924,7 +4917,7 @@ public: virtual Type getType() const noexcept = 0; virtual Term* clone() const = 0; virtual const ReferenceCountedObjectPtr resolve (const Scope&, int recursionDepth) = 0; - virtual const String toString() const = 0; + virtual String toString() const = 0; virtual double toDouble() const { return 0; } virtual int getInputIndexFor (const Term*) const { return -1; } virtual int getOperatorPrecedence() const { return 0; } @@ -4939,7 +4932,7 @@ public: return nullptr; } - virtual const String getName() const + virtual String getName() const { jassertfalse; // You shouldn't call this for an expression that's not actually a function! return String::empty; @@ -5009,7 +5002,7 @@ public: double toDouble() const { return value; } const TermPtr negated() { return new Constant (-value, isResolutionTarget); } - const String toString() const + String toString() const { String s (value); if (isResolutionTarget) @@ -5048,7 +5041,7 @@ public: right->resolve (scope, recursionDepth)->toDouble()), false); } - const String toString() const + String toString() const { String s; @@ -5099,8 +5092,8 @@ public: Type getType() const noexcept { return symbolType; } Term* clone() const { return new SymbolTerm (symbol); } - const String toString() const { return symbol; } - const String getName() const { return symbol; } + String toString() const { return symbol; } + String getName() const { return symbol; } void visitAllSymbols (SymbolVisitor& visitor, const Scope& scope, int recursionDepth) { @@ -5131,7 +5124,7 @@ public: Term* clone() const { return new Function (functionName, parameters); } int getNumInputs() const { return parameters.size(); } Term* getInput (int i) const { return getTermFor (parameters [i]); } - const String getName() const { return functionName; } + String getName() const { return functionName; } const TermPtr resolve (const Scope& scope, int recursionDepth) { @@ -5163,7 +5156,7 @@ public: return -1; } - const String toString() const + String toString() const { if (parameters.size() == 0) return functionName + "()"; @@ -5201,7 +5194,7 @@ public: } Term* clone() const { return new DotOperator (getSymbol(), right); } - const String getName() const { return "."; } + String getName() const { return "."; } int getOperatorPrecedence() const { return 1; } void writeOperator (String& dest) const { dest << '.'; } double performFunction (double, double) const { return 0.0; } @@ -5309,7 +5302,7 @@ public: return new Constant (-input->resolve (scope, recursionDepth)->toDouble(), false); } - const String getName() const { return "-"; } + String getName() const { return "-"; } const TermPtr negated() { return input; } const TermPtr createTermToEvaluateInput (const Scope& scope, const Term* input_, double overallTarget, Term* topLevelTerm) const @@ -5323,7 +5316,7 @@ public: : dest->createTermToEvaluateInput (scope, this, overallTarget, topLevelTerm)); } - const String toString() const + String toString() const { if (input->getOperatorPrecedence() > 0) return "-(" + input->toString() + ")"; @@ -5343,7 +5336,7 @@ public: Term* clone() const { return new Add (left->clone(), right->clone()); } double performFunction (double lhs, double rhs) const { return lhs + rhs; } int getOperatorPrecedence() const { return 3; } - const String getName() const { return "+"; } + String getName() const { return "+"; } void writeOperator (String& dest) const { dest << " + "; } const TermPtr createTermToEvaluateInput (const Scope& scope, const Term* input, double overallTarget, Term* topLevelTerm) const @@ -5367,7 +5360,7 @@ public: Term* clone() const { return new Subtract (left->clone(), right->clone()); } double performFunction (double lhs, double rhs) const { return lhs - rhs; } int getOperatorPrecedence() const { return 3; } - const String getName() const { return "-"; } + String getName() const { return "-"; } void writeOperator (String& dest) const { dest << " - "; } const TermPtr createTermToEvaluateInput (const Scope& scope, const Term* input, double overallTarget, Term* topLevelTerm) const @@ -5393,7 +5386,7 @@ public: Term* clone() const { return new Multiply (left->clone(), right->clone()); } double performFunction (double lhs, double rhs) const { return lhs * rhs; } - const String getName() const { return "*"; } + String getName() const { return "*"; } void writeOperator (String& dest) const { dest << " * "; } int getOperatorPrecedence() const { return 2; } @@ -5417,7 +5410,7 @@ public: Term* clone() const { return new Divide (left->clone(), right->clone()); } double performFunction (double lhs, double rhs) const { return lhs / rhs; } - const String getName() const { return "/"; } + String getName() const { return "/"; } void writeOperator (String& dest) const { dest << " / "; } int getOperatorPrecedence() const { return 2; } @@ -5823,7 +5816,7 @@ Expression::Expression (const String& stringToParse) term = parser.readUpToComma(); } -const Expression Expression::parse (String::CharPointerType& stringToParse) +Expression Expression::parse (String::CharPointerType& stringToParse) { Helpers::Parser parser (stringToParse); return Expression (parser.readUpToComma()); @@ -5860,19 +5853,19 @@ double Expression::evaluate (const Scope& scope, String& evaluationError) const return 0; } -const Expression Expression::operator+ (const Expression& other) const { return Expression (new Helpers::Add (term, other.term)); } -const Expression Expression::operator- (const Expression& other) const { return Expression (new Helpers::Subtract (term, other.term)); } -const Expression Expression::operator* (const Expression& other) const { return Expression (new Helpers::Multiply (term, other.term)); } -const Expression Expression::operator/ (const Expression& other) const { return Expression (new Helpers::Divide (term, other.term)); } -const Expression Expression::operator-() const { return Expression (term->negated()); } -const Expression Expression::symbol (const String& symbol) { return Expression (new Helpers::SymbolTerm (symbol)); } +Expression Expression::operator+ (const Expression& other) const { return Expression (new Helpers::Add (term, other.term)); } +Expression Expression::operator- (const Expression& other) const { return Expression (new Helpers::Subtract (term, other.term)); } +Expression Expression::operator* (const Expression& other) const { return Expression (new Helpers::Multiply (term, other.term)); } +Expression Expression::operator/ (const Expression& other) const { return Expression (new Helpers::Divide (term, other.term)); } +Expression Expression::operator-() const { return Expression (term->negated()); } +Expression Expression::symbol (const String& symbol) { return Expression (new Helpers::SymbolTerm (symbol)); } -const Expression Expression::function (const String& functionName, const Array& parameters) +Expression Expression::function (const String& functionName, const Array& parameters) { return Expression (new Helpers::Function (functionName, parameters)); } -const Expression Expression::adjustedToGiveNewResult (const double targetValue, const Expression::Scope& scope) const +Expression Expression::adjustedToGiveNewResult (const double targetValue, const Expression::Scope& scope) const { ScopedPointer newTerm (term->clone()); @@ -5908,7 +5901,7 @@ const Expression Expression::adjustedToGiveNewResult (const double targetValue, return Expression (newTerm.release()); } -const Expression Expression::withRenamedSymbol (const Expression::Symbol& oldSymbol, const String& newName, const Scope& scope) const +Expression Expression::withRenamedSymbol (const Expression::Symbol& oldSymbol, const String& newName, const Scope& scope) const { jassert (newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_")); @@ -5945,12 +5938,12 @@ void Expression::findReferencedSymbols (Array& results, const Scope& sco {} } -const String Expression::toString() const { return term->toString(); } -bool Expression::usesAnySymbols() const { return Helpers::containsAnySymbols (term); } -Expression::Type Expression::getType() const noexcept { return term->getType(); } -const String Expression::getSymbolOrFunction() const { return term->getName(); } +String Expression::toString() const { return term->toString(); } +bool Expression::usesAnySymbols() const { return Helpers::containsAnySymbols (term); } +Expression::Type Expression::getType() const noexcept { return term->getType(); } +String Expression::getSymbolOrFunction() const { return term->getName(); } int Expression::getNumInputs() const { return term->getNumInputs(); } -const Expression Expression::getInput (int index) const { return Expression (term->getInput (index)); } +Expression Expression::getInput (int index) const { return Expression (term->getInput (index)); } const ReferenceCountedObjectPtr Expression::Term::negated() { @@ -6371,10 +6364,10 @@ MD5::MD5 (InputStream& input, int64 numBytesToRead) MD5::MD5 (const File& file) { - const ScopedPointer fin (file.createInputStream()); + FileInputStream fin (file); - if (fin != nullptr) - processStream (*fin, -1); + if (fin.getStatus().wasOk()) + processStream (fin, -1); else zerostruct (result); } @@ -6544,12 +6537,12 @@ void MD5::ProcessContext::transform (const void* const bufferToTransform) zerostruct (x); } -const MemoryBlock MD5::getRawChecksumData() const +MemoryBlock MD5::getRawChecksumData() const { return MemoryBlock (result, sizeof (result)); } -const String MD5::toHexString() const +String MD5::toHexString() const { return String::toHexString (result, sizeof (result), 0); } @@ -6698,10 +6691,10 @@ namespace PrimesHelpers } } -const BigInteger Primes::createProbablePrime (const int bitLength, - const int certainty, - const int* randomSeeds, - int numRandomSeeds) +BigInteger Primes::createProbablePrime (const int bitLength, + const int certainty, + const int* randomSeeds, + int numRandomSeeds) { using namespace PrimesHelpers; int defaultSeeds [16]; @@ -6826,7 +6819,7 @@ bool RSAKey::operator!= (const RSAKey& other) const noexcept return ! operator== (other); } -const String RSAKey::toString() const +String RSAKey::toString() const { return part1.toString (16) + "," + part2.toString (16); } @@ -6858,7 +6851,7 @@ bool RSAKey::applyToValue (BigInteger& value) const return true; } -const BigInteger RSAKey::findBestCommonDivisor (const BigInteger& p, const BigInteger& q) +BigInteger RSAKey::findBestCommonDivisor (const BigInteger& p, const BigInteger& q) { // try 3, 5, 9, 17, etc first because these only contain 2 bits and so // are fast to divide + multiply @@ -7033,7 +7026,7 @@ double InputStream::readDoubleBigEndian() return n.asDouble; } -const String InputStream::readString() +String InputStream::readString() { MemoryBlock buffer (256); char* data = static_cast (buffer.getData()); @@ -7051,7 +7044,7 @@ const String InputStream::readString() return String::fromUTF8 (data, (int) i); } -const String InputStream::readNextLine() +String InputStream::readNextLine() { MemoryBlock buffer (256); char* data = static_cast (buffer.getData()); @@ -7088,7 +7081,7 @@ int InputStream::readIntoMemoryBlock (MemoryBlock& block, int numBytes) return mo.writeFromInputStream (*this, numBytes); } -const String InputStream::readEntireStreamAsString() +String InputStream::readEntireStreamAsString() { MemoryOutputStream mo; mo.writeFromInputStream (*this, -1); @@ -7492,7 +7485,7 @@ bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResul return false; } -const File DirectoryIterator::getFile() const +const File& DirectoryIterator::getFile() const { if (subIterator != nullptr && subIterator->hasBeenAdvanced) return subIterator->getFile(); @@ -7539,7 +7532,7 @@ File::File (const String& path, int) { } -const File File::createFileWithoutCheckingPath (const String& path) +File File::createFileWithoutCheckingPath (const String& path) { return File (path, 0); } @@ -7563,7 +7556,7 @@ File& File::operator= (const File& other) const File File::nonexistent; -const String File::parseAbsolutePath (const String& p) +String File::parseAbsolutePath (const String& p) { if (p.isEmpty()) return String::empty; @@ -7650,7 +7643,7 @@ const String File::parseAbsolutePath (const String& p) return path; } -const String File::addTrailingSeparator (const String& path) +String File::addTrailingSeparator (const String& path) { return path.endsWithChar (File::separator) ? path : path + File::separator; @@ -7779,7 +7772,7 @@ bool File::copyDirectoryTo (const File& newDirectory) const return false; } -const String File::getPathUpToLastSlash() const +String File::getPathUpToLastSlash() const { const int lastSlash = fullPath.lastIndexOfChar (separator); @@ -7791,12 +7784,12 @@ const String File::getPathUpToLastSlash() const return fullPath; } -const File File::getParentDirectory() const +File File::getParentDirectory() const { return File (getPathUpToLastSlash(), (int) 0); } -const String File::getFileName() const +String File::getFileName() const { return fullPath.substring (fullPath.lastIndexOfChar (separator) + 1); } @@ -7811,7 +7804,7 @@ int64 File::hashCode64() const return fullPath.hashCode64(); } -const String File::getFileNameWithoutExtension() const +String File::getFileNameWithoutExtension() const { const int lastSlash = fullPath.lastIndexOfChar (separator) + 1; const int lastDot = fullPath.lastIndexOfChar ('.'); @@ -7857,7 +7850,7 @@ bool File::isAbsolutePath (const String& path) #endif } -const File File::getChildFile (String relativePath) const +File File::getChildFile (String relativePath) const { if (isAbsolutePath (relativePath)) return File (relativePath); @@ -7904,12 +7897,12 @@ const File File::getChildFile (String relativePath) const return File (addTrailingSeparator (path) + relativePath); } -const File File::getSiblingFile (const String& fileName) const +File File::getSiblingFile (const String& fileName) const { return getParentDirectory().getChildFile (fileName); } -const String File::descriptionOfSizeInBytes (const int64 bytes) +String File::descriptionOfSizeInBytes (const int64 bytes) { if (bytes == 1) return "1 byte"; else if (bytes < 1024) return String (bytes) + " bytes"; @@ -7918,7 +7911,7 @@ const String File::descriptionOfSizeInBytes (const int64 bytes) else return String (bytes / (1024.0 * 1024.0 * 1024.0), 1) + " GB"; } -const Result File::create() const +Result File::create() const { if (exists()) return Result::ok(); @@ -7940,7 +7933,7 @@ const Result File::create() const return r; } -const Result File::createDirectory() const +Result File::createDirectory() const { if (isDirectory()) return Result::ok(); @@ -7975,7 +7968,7 @@ bool File::loadFileAsData (MemoryBlock& destBlock) const return getSize() == in.readIntoMemoryBlock (destBlock); } -const String File::loadFileAsString() const +String File::loadFileAsString() const { if (! existsAsFile()) return String::empty; @@ -8023,9 +8016,9 @@ bool File::containsSubDirectories() const return false; } -const File File::getNonexistentChildFile (const String& prefix_, - const String& suffix, - bool putNumbersInBrackets) const +File File::getNonexistentChildFile (const String& prefix_, + const String& suffix, + bool putNumbersInBrackets) const { File f (getChildFile (prefix_ + suffix)); @@ -8072,7 +8065,7 @@ const File File::getNonexistentChildFile (const String& prefix_, return f; } -const File File::getNonexistentSibling (const bool putNumbersInBrackets) const +File File::getNonexistentSibling (const bool putNumbersInBrackets) const { if (exists()) return getParentDirectory() @@ -8082,7 +8075,7 @@ const File File::getNonexistentSibling (const bool putNumbersInBrackets) const return *this; } -const String File::getFileExtension() const +String File::getFileExtension() const { const int indexOfDot = fullPath.lastIndexOfChar ('.'); @@ -8121,7 +8114,7 @@ bool File::hasFileExtension (const String& possibleSuffix) const return false; } -const File File::withFileExtension (const String& newExtension) const +File File::withFileExtension (const String& newExtension) const { if (fullPath.isEmpty()) return File::nonexistent; @@ -8245,7 +8238,7 @@ bool File::hasIdenticalContentTo (const File& other) const return false; } -const String File::createLegalPathName (const String& original) +String File::createLegalPathName (const String& original) { String s (original); String start; @@ -8260,7 +8253,7 @@ const String File::createLegalPathName (const String& original) .substring (0, 1024); } -const String File::createLegalFileName (const String& original) +String File::createLegalFileName (const String& original) { String s (original.removeCharacters ("\"#@,;:<>*^|?\\/")); @@ -8285,7 +8278,7 @@ const String File::createLegalFileName (const String& original) return s; } -const String File::getRelativePathFrom (const File& dir) const +String File::getRelativePathFrom (const File& dir) const { String thisPath (fullPath); @@ -8348,7 +8341,7 @@ const String File::getRelativePathFrom (const File& dir) const return thisPath; } -const File File::createTempFile (const String& fileNameEnding) +File File::createTempFile (const String& fileNameEnding) { const File tempFile (getSpecialLocation (tempDirectory) .getChildFile ("temp_" + String (Random::getSystemRandom().nextInt())) @@ -8749,12 +8742,12 @@ int FileSearchPath::getNumPaths() const return directories.size(); } -const File FileSearchPath::operator[] (const int index) const +File FileSearchPath::operator[] (const int index) const { return File (directories [index]); } -const String FileSearchPath::toString() const +String FileSearchPath::toString() const { StringArray directories2 (directories); for (int i = directories2.size(); --i >= 0;) @@ -8888,7 +8881,7 @@ bool NamedPipe::isOpen() const return internal != nullptr; } -const String NamedPipe::getName() const +String NamedPipe::getName() const { return currentPipeName; } @@ -9637,7 +9630,7 @@ URL::~URL() namespace URLHelpers { - const String getMangledParameters (const StringPairArray& parameters) + String getMangledParameters (const StringPairArray& parameters) { String p; @@ -9722,7 +9715,7 @@ namespace URLHelpers } } -const String URL::toString (const bool includeGetParameters) const +String URL::toString (const bool includeGetParameters) const { if (includeGetParameters && parameters.size() > 0) return url + "?" + URLHelpers::getMangledParameters (parameters); @@ -9736,7 +9729,7 @@ bool URL::isWellFormed() const return url.isNotEmpty(); } -const String URL::getDomain() const +String URL::getDomain() const { int start = URLHelpers::findStartOfDomain (url); while (url[start] == '/') @@ -9751,7 +9744,7 @@ const String URL::getDomain() const return url.substring (start, end); } -const String URL::getSubPath() const +String URL::getSubPath() const { int start = URLHelpers::findStartOfDomain (url); while (url[start] == '/') @@ -9763,7 +9756,7 @@ const String URL::getSubPath() const : url.substring (startOfPath); } -const String URL::getScheme() const +String URL::getScheme() const { return url.substring (0, URLHelpers::findStartOfDomain (url) - 1); } @@ -9856,7 +9849,7 @@ bool URL::readEntireBinaryStream (MemoryBlock& destData, return false; } -const String URL::readEntireTextStream (const bool usePostCommand) const +String URL::readEntireTextStream (const bool usePostCommand) const { const ScopedPointer in (createInputStream (usePostCommand)); @@ -9913,7 +9906,7 @@ const StringPairArray& URL::getMimeTypesOfUploadFiles() const return mimeTypes; } -const String URL::removeEscapeChars (const String& s) +String URL::removeEscapeChars (const String& s) { String result (s.replaceCharacter ('+', ' ')); @@ -9942,7 +9935,7 @@ const String URL::removeEscapeChars (const String& s) return String::fromUTF8 (utf8.getRawDataPointer(), utf8.size()); } -const String URL::addEscapeChars (const String& s, const bool isParameter) +String URL::addEscapeChars (const String& s, const bool isParameter) { const CharPointer_UTF8 legalChars (isParameter ? "_-.*!'()" : ",$_-.*!'()"); @@ -10198,7 +10191,7 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead) } } -const String BufferedInputStream::readString() +String BufferedInputStream::readString() { if (position >= bufferStart && position < lastReadPos) @@ -10504,13 +10497,13 @@ int MemoryOutputStream::writeFromInputStream (InputStream& source, int64 maxNumB return OutputStream::writeFromInputStream (source, maxNumBytesToWrite); } -const String MemoryOutputStream::toUTF8() const +String MemoryOutputStream::toUTF8() const { const char* const d = static_cast (getData()); return String (CharPointer_UTF8 (d), CharPointer_UTF8 (d + getDataSize())); } -const String MemoryOutputStream::toString() const +String MemoryOutputStream::toString() const { return String::createStringFromData (getData(), (int) getDataSize()); } @@ -10738,7 +10731,7 @@ bool Uuid::isNull() const noexcept return (value.asInt64 [0] == 0) && (value.asInt64 [1] == 0); } -const String Uuid::toString() const +String Uuid::toString() const { return String::toHexString (value.asBytes, sizeof (value.asBytes), 0); } @@ -11471,7 +11464,7 @@ LocalisedStrings::~LocalisedStrings() { } -const String LocalisedStrings::translate (const String& text) const +String LocalisedStrings::translate (const String& text) const { return translations.getValue (text, text); } @@ -11517,7 +11510,7 @@ namespace return startPos; } - const String unescapeString (const String& s) + String unescapeString (const String& s) { return s.replace ("\\\"", "\"") .replace ("\\\'", "\'") @@ -11582,7 +11575,7 @@ LocalisedStrings* LocalisedStrings::getCurrentMappings() return currentMappings; } -const String LocalisedStrings::translateWithCurrentMappings (const String& text) +String LocalisedStrings::translateWithCurrentMappings (const String& text) { const SpinLock::ScopedLockType sl (currentMappingsLock); @@ -11592,7 +11585,7 @@ const String LocalisedStrings::translateWithCurrentMappings (const String& text) return text; } -const String LocalisedStrings::translateWithCurrentMappings (const char* text) +String LocalisedStrings::translateWithCurrentMappings (const char* text) { return translateWithCurrentMappings (String (text)); } @@ -11896,7 +11889,7 @@ String::String (const CharPointer_UTF8& start, const CharPointer_UTF8& end) : String::String (const CharPointer_UTF16& start, const CharPointer_UTF16& end) : text (StringHolder::createFromCharPointer (start, end)) {} String::String (const CharPointer_UTF32& start, const CharPointer_UTF32& end) : text (StringHolder::createFromCharPointer (start, end)) {} -const String String::charToString (const juce_wchar character) +String String::charToString (const juce_wchar character) { String result (PreallocationBytes (CharPointerType::getBytesRequiredFor (character))); CharPointerType t (result.text); @@ -12227,32 +12220,32 @@ String& String::operator+= (const int number) return *this; } -JUCE_API const String JUCE_CALLTYPE operator+ (const char* const string1, const String& string2) +JUCE_API String JUCE_CALLTYPE operator+ (const char* const string1, const String& string2) { String s (string1); return s += string2; } -JUCE_API const String JUCE_CALLTYPE operator+ (const wchar_t* const string1, const String& string2) +JUCE_API String JUCE_CALLTYPE operator+ (const wchar_t* const string1, const String& string2) { String s (string1); return s += string2; } -JUCE_API const String JUCE_CALLTYPE operator+ (const char s1, const String& s2) { return String::charToString (s1) + s2; } -JUCE_API const String JUCE_CALLTYPE operator+ (const wchar_t s1, const String& s2) { return String::charToString (s1) + s2; } +JUCE_API String JUCE_CALLTYPE operator+ (const char s1, const String& s2) { return String::charToString (s1) + s2; } +JUCE_API String JUCE_CALLTYPE operator+ (const wchar_t s1, const String& s2) { return String::charToString (s1) + s2; } #if ! JUCE_NATIVE_WCHAR_IS_UTF32 -JUCE_API const String JUCE_CALLTYPE operator+ (const juce_wchar s1, const String& s2) { return String::charToString (s1) + s2; } +JUCE_API String JUCE_CALLTYPE operator+ (const juce_wchar s1, const String& s2) { return String::charToString (s1) + s2; } #endif -JUCE_API const String JUCE_CALLTYPE operator+ (String s1, const String& s2) { return s1 += s2; } -JUCE_API const String JUCE_CALLTYPE operator+ (String s1, const char* const s2) { return s1 += s2; } -JUCE_API const String JUCE_CALLTYPE operator+ (String s1, const wchar_t* s2) { return s1 += s2; } +JUCE_API String JUCE_CALLTYPE operator+ (String s1, const String& s2) { return s1 += s2; } +JUCE_API String JUCE_CALLTYPE operator+ (String s1, const char* const s2) { return s1 += s2; } +JUCE_API String JUCE_CALLTYPE operator+ (String s1, const wchar_t* s2) { return s1 += s2; } -JUCE_API const String JUCE_CALLTYPE operator+ (String s1, const char s2) { return s1 += s2; } -JUCE_API const String JUCE_CALLTYPE operator+ (String s1, const wchar_t s2) { return s1 += s2; } +JUCE_API String JUCE_CALLTYPE operator+ (String s1, const char s2) { return s1 += s2; } +JUCE_API String JUCE_CALLTYPE operator+ (String s1, const wchar_t s2) { return s1 += s2; } #if ! JUCE_NATIVE_WCHAR_IS_UTF32 -JUCE_API const String JUCE_CALLTYPE operator+ (String s1, const juce_wchar s2) { return s1 += s2; } +JUCE_API String JUCE_CALLTYPE operator+ (String s1, const juce_wchar s2) { return s1 += s2; } #endif JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const char s2) { return s1 += s2; } @@ -12605,7 +12598,7 @@ bool String::matchesWildcard (const String& wildcard, const bool ignoreCase) con } } -const String String::repeatedString (const String& stringToRepeat, int numberOfTimesToRepeat) +String String::repeatedString (const String& stringToRepeat, int numberOfTimesToRepeat) { if (numberOfTimesToRepeat <= 0) return String::empty; @@ -12619,7 +12612,7 @@ const String String::repeatedString (const String& stringToRepeat, int numberOfT return result; } -const String String::paddedLeft (const juce_wchar padCharacter, int minimumLength) const +String String::paddedLeft (const juce_wchar padCharacter, int minimumLength) const { jassert (padCharacter != 0); @@ -12646,7 +12639,7 @@ const String String::paddedLeft (const juce_wchar padCharacter, int minimumLengt return result; } -const String String::paddedRight (const juce_wchar padCharacter, int minimumLength) const +String String::paddedRight (const juce_wchar padCharacter, int minimumLength) const { jassert (padCharacter != 0); @@ -12675,7 +12668,7 @@ const String String::paddedRight (const juce_wchar padCharacter, int minimumLeng return result; } -const String String::replaceSection (int index, int numCharsToReplace, const String& stringToInsert) const +String String::replaceSection (int index, int numCharsToReplace, const String& stringToInsert) const { if (index < 0) { @@ -12741,7 +12734,7 @@ const String String::replaceSection (int index, int numCharsToReplace, const Str return result; } -const String String::replace (const String& stringToReplace, const String& stringToInsert, const bool ignoreCase) const +String String::replace (const String& stringToReplace, const String& stringToInsert, const bool ignoreCase) const { const int stringToReplaceLen = stringToReplace.length(); const int stringToInsertLen = stringToInsert.length(); @@ -12799,7 +12792,7 @@ private: size_t allocatedBytes, bytesWritten; }; -const String String::replaceCharacter (const juce_wchar charToReplace, const juce_wchar charToInsert) const +String String::replaceCharacter (const juce_wchar charToReplace, const juce_wchar charToInsert) const { if (! containsChar (charToReplace)) return *this; @@ -12822,8 +12815,7 @@ const String String::replaceCharacter (const juce_wchar charToReplace, const juc return builder.result; } -const String String::replaceCharacters (const String& charactersToReplace, - const String& charactersToInsertInstead) const +String String::replaceCharacters (const String& charactersToReplace, const String& charactersToInsertInstead) const { StringCreationHelper builder (text); @@ -12906,7 +12898,7 @@ bool String::endsWithIgnoreCase (const String& other) const noexcept return otherEnd == other.text; } -const String String::toUpperCase() const +String String::toUpperCase() const { StringCreationHelper builder (text); @@ -12923,7 +12915,7 @@ const String String::toUpperCase() const return builder.result; } -const String String::toLowerCase() const +String String::toLowerCase() const { StringCreationHelper builder (text); @@ -12945,7 +12937,7 @@ juce_wchar String::getLastCharacter() const noexcept return isEmpty() ? juce_wchar() : text [length() - 1]; } -const String String::substring (int start, const int end) const +String String::substring (int start, const int end) const { if (start < 0) start = 0; @@ -12983,7 +12975,7 @@ const String String::substring (int start, const int end) const return String (t1, t2); } -const String String::substring (int start) const +String String::substring (int start) const { if (start <= 0) return *this; @@ -13001,19 +12993,19 @@ const String String::substring (int start) const return String (t); } -const String String::dropLastCharacters (const int numberToDrop) const +String String::dropLastCharacters (const int numberToDrop) const { return String (text, jmax (0, length() - numberToDrop)); } -const String String::getLastCharacters (const int numCharacters) const +String String::getLastCharacters (const int numCharacters) const { return String (text + jmax (0, length() - jmax (0, numCharacters))); } -const String String::fromFirstOccurrenceOf (const String& sub, - const bool includeSubString, - const bool ignoreCase) const +String String::fromFirstOccurrenceOf (const String& sub, + const bool includeSubString, + const bool ignoreCase) const { const int i = ignoreCase ? indexOfIgnoreCase (sub) : indexOf (sub); @@ -13023,9 +13015,9 @@ const String String::fromFirstOccurrenceOf (const String& sub, return substring (includeSubString ? i : i + sub.length()); } -const String String::fromLastOccurrenceOf (const String& sub, - const bool includeSubString, - const bool ignoreCase) const +String String::fromLastOccurrenceOf (const String& sub, + const bool includeSubString, + const bool ignoreCase) const { const int i = ignoreCase ? lastIndexOfIgnoreCase (sub) : lastIndexOf (sub); @@ -13035,9 +13027,9 @@ const String String::fromLastOccurrenceOf (const String& sub, return substring (includeSubString ? i : i + sub.length()); } -const String String::upToFirstOccurrenceOf (const String& sub, - const bool includeSubString, - const bool ignoreCase) const +String String::upToFirstOccurrenceOf (const String& sub, + const bool includeSubString, + const bool ignoreCase) const { const int i = ignoreCase ? indexOfIgnoreCase (sub) : indexOf (sub); @@ -13047,9 +13039,9 @@ const String String::upToFirstOccurrenceOf (const String& sub, return substring (0, includeSubString ? i + sub.length() : i); } -const String String::upToLastOccurrenceOf (const String& sub, - const bool includeSubString, - const bool ignoreCase) const +String String::upToLastOccurrenceOf (const String& sub, + const bool includeSubString, + const bool ignoreCase) const { const int i = ignoreCase ? lastIndexOfIgnoreCase (sub) : lastIndexOf (sub); @@ -13067,7 +13059,7 @@ bool String::isQuotedString() const || trimmed[0] == '\''; } -const String String::unquoted() const +String String::unquoted() const { const int len = length(); @@ -13081,7 +13073,7 @@ const String String::unquoted() const return substring (dropAtStart, len - dropAtEnd); } -const String String::quoted (const juce_wchar quoteCharacter) const +String String::quoted (const juce_wchar quoteCharacter) const { if (isEmpty()) return charToString (quoteCharacter) + quoteCharacter; @@ -13111,7 +13103,7 @@ static String::CharPointerType findTrimmedEnd (const String::CharPointerType& st return end; } -const String String::trim() const +String String::trim() const { if (isNotEmpty()) { @@ -13129,7 +13121,7 @@ const String String::trim() const return *this; } -const String String::trimStart() const +String String::trimStart() const { if (isNotEmpty()) { @@ -13142,7 +13134,7 @@ const String String::trimStart() const return *this; } -const String String::trimEnd() const +String String::trimEnd() const { if (isNotEmpty()) { @@ -13156,7 +13148,7 @@ const String String::trimEnd() const return *this; } -const String String::trimCharactersAtStart (const String& charactersToTrim) const +String String::trimCharactersAtStart (const String& charactersToTrim) const { CharPointerType t (text); @@ -13166,7 +13158,7 @@ const String String::trimCharactersAtStart (const String& charactersToTrim) cons return t == text ? *this : String (t); } -const String String::trimCharactersAtEnd (const String& charactersToTrim) const +String String::trimCharactersAtEnd (const String& charactersToTrim) const { if (isNotEmpty()) { @@ -13189,7 +13181,7 @@ const String String::trimCharactersAtEnd (const String& charactersToTrim) const return *this; } -const String String::retainCharacters (const String& charactersToRetain) const +String String::retainCharacters (const String& charactersToRetain) const { if (isEmpty()) return empty; @@ -13211,7 +13203,7 @@ const String String::retainCharacters (const String& charactersToRetain) const return builder.result; } -const String String::removeCharacters (const String& charactersToRemove) const +String String::removeCharacters (const String& charactersToRemove) const { if (isEmpty()) return empty; @@ -13232,7 +13224,7 @@ const String String::removeCharacters (const String& charactersToRemove) const return builder.result; } -const String String::initialSectionContainingOnly (const String& permittedCharacters) const +String String::initialSectionContainingOnly (const String& permittedCharacters) const { CharPointerType t (text); @@ -13247,7 +13239,7 @@ const String String::initialSectionContainingOnly (const String& permittedCharac return *this; } -const String String::initialSectionNotContaining (const String& charactersToStopAt) const +String String::initialSectionNotContaining (const String& charactersToStopAt) const { CharPointerType t (text); @@ -13300,7 +13292,7 @@ bool String::containsNonWhitespaceChars() const noexcept } // Note! The format parameter here MUST NOT be a reference, otherwise MS's va_start macro fails to work (but still compiles). -const String String::formatted (const String pf, ... ) +String String::formatted (const String pf, ... ) { size_t bufferSize = 256; @@ -13377,12 +13369,12 @@ double String::getDoubleValue() const noexcept return text.getDoubleValue(); } -static const char* const hexDigits = "0123456789abcdef"; +static const char hexDigits[] = "0123456789abcdef"; template struct HexConverter { - static const String hexToString (Type v) + static String hexToString (Type v) { char buffer[32]; char* const end = buffer + 32; @@ -13415,22 +13407,22 @@ struct HexConverter } }; -const String String::toHexString (const int number) +String String::toHexString (const int number) { return HexConverter ::hexToString ((unsigned int) number); } -const String String::toHexString (const int64 number) +String String::toHexString (const int64 number) { return HexConverter ::hexToString ((uint64) number); } -const String String::toHexString (const short number) +String String::toHexString (const short number) { return toHexString ((int) (unsigned short) number); } -const String String::toHexString (const unsigned char* data, const int size, const int groupSize) +String String::toHexString (const void* const d, const int size, const int groupSize) { if (size <= 0) return empty; @@ -13441,13 +13433,14 @@ const String String::toHexString (const unsigned char* data, const int size, con String s (PreallocationBytes (sizeof (CharPointerType::CharType) * (size_t) numChars)); + const unsigned char* data = static_cast (d); CharPointerType dest (s.text); for (int i = 0; i < size; ++i) { - dest.write ((juce_wchar) hexDigits [(*data) >> 4]); - dest.write ((juce_wchar) hexDigits [(*data) & 0xf]); - ++data; + const unsigned char nextByte = *data++; + dest.write ((juce_wchar) hexDigits [nextByte >> 4]); + dest.write ((juce_wchar) hexDigits [nextByte & 0xf]); if (groupSize > 0 && (i % groupSize) == (groupSize - 1) && i < (size - 1)) dest.write ((juce_wchar) ' '); @@ -13467,7 +13460,7 @@ int64 String::getHexValue64() const noexcept return HexConverter::stringToHex (text); } -const String String::createStringFromData (const void* const data_, const int size) +String String::createStringFromData (const void* const data_, const int size) { const uint8* const data = static_cast (data_); @@ -13625,7 +13618,7 @@ int String::getNumBytesAsUTF8() const noexcept return (int) CharPointer_UTF8::getBytesRequiredFor (text); } -const String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) +String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) { if (buffer != nullptr) { @@ -13695,7 +13688,7 @@ public: } }; - static const String createRandomWideCharString() + static String createRandomWideCharString() { juce_wchar buffer[50] = { 0 }; @@ -14244,7 +14237,7 @@ void StringArray::move (const int currentIndex, int newIndex) noexcept strings.move (currentIndex, newIndex); } -const String StringArray::joinIntoString (const String& separator, int start, int numberToJoin) const +String StringArray::joinIntoString (const String& separator, int start, int numberToJoin) const { const int last = (numberToJoin < 0) ? size() : jmin (size(), start + numberToJoin); @@ -14468,7 +14461,7 @@ const String& StringPairArray::operator[] (const String& key) const return values [keys.indexOf (key, ignoreCase)]; } -const String StringPairArray::getValue (const String& key, const String& defaultReturnValue) const +String StringPairArray::getValue (const String& key, const String& defaultReturnValue) const { const int i = keys.indexOf (key, ignoreCase); @@ -14521,7 +14514,7 @@ void StringPairArray::setIgnoresCase (const bool shouldIgnoreCase) ignoreCase = shouldIgnoreCase; } -const String StringPairArray::getDescription() const +String StringPairArray::getDescription() const { String s; @@ -14772,7 +14765,7 @@ void XmlDocument::setLastError (const String& desc, const bool carryOn) errorOccurred = ! carryOn; } -const String XmlDocument::getFileContents (const String& filename) const +String XmlDocument::getFileContents (const String& filename) const { if (inputSource != nullptr) { @@ -15325,7 +15318,7 @@ void XmlDocument::readEntity (String& result) } } -const String XmlDocument::expandEntity (const String& ent) +String XmlDocument::expandEntity (const String& ent) { if (ent.equalsIgnoreCase ("amp")) return String::charToString ('&'); if (ent.equalsIgnoreCase ("quot")) return String::charToString ('"'); @@ -15350,7 +15343,7 @@ const String XmlDocument::expandEntity (const String& ent) return expandExternalEntity (ent); } -const String XmlDocument::expandExternalEntity (const String& entity) +String XmlDocument::expandExternalEntity (const String& entity) { if (needToLoadDTD) { @@ -15442,7 +15435,7 @@ const String XmlDocument::expandExternalEntity (const String& entity) return entity; } -const String XmlDocument::getParameterEntity (const String& entity) +String XmlDocument::getParameterEntity (const String& entity) { for (int i = 0; i < tokenisedDTD.size(); ++i) { @@ -15726,11 +15719,11 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, } } -const String XmlElement::createDocument (const String& dtdToUse, - const bool allOnOneLine, - const bool includeXmlHeader, - const String& encodingType, - const int lineWrapLength) const +String XmlElement::createDocument (const String& dtdToUse, + const bool allOnOneLine, + const bool includeXmlHeader, + const String& encodingType, + const int lineWrapLength) const { MemoryOutputStream mem (2048); writeToStream (mem, dtdToUse, allOnOneLine, includeXmlHeader, encodingType, lineWrapLength); @@ -15860,7 +15853,7 @@ const String& XmlElement::getStringAttribute (const String& attributeName) const return String::empty; } -const String XmlElement::getStringAttribute (const String& attributeName, const String& defaultReturnValue) const +String XmlElement::getStringAttribute (const String& attributeName, const String& defaultReturnValue) const { for (const XmlAttributeNode* att = attributes; att != nullptr; att = att->nextListItem) if (att->hasName (attributeName)) @@ -16224,7 +16217,7 @@ void XmlElement::setText (const String& newText) jassertfalse; // you can only change the text in a text element, not a normal one. } -const String XmlElement::getAllSubText() const +String XmlElement::getAllSubText() const { if (isTextElement()) return getText(); @@ -16242,8 +16235,8 @@ const String XmlElement::getAllSubText() const return result; } -const String XmlElement::getChildElementAllSubText (const String& childTagName, - const String& defaultReturnValue) const +String XmlElement::getChildElementAllSubText (const String& childTagName, + const String& defaultReturnValue) const { const XmlElement* const child = getChildByName (childTagName); @@ -16748,7 +16741,7 @@ ThreadPoolJob::~ThreadPoolJob() jassert (pool == nullptr || ! pool->contains (this)); } -const String ThreadPoolJob::getJobName() const +String ThreadPoolJob::getJobName() const { return jobName; } @@ -16994,7 +16987,7 @@ bool ThreadPool::removeAllJobs (const bool interruptRunningJobs, return true; } -const StringArray ThreadPool::getNamesOfAllJobs (const bool onlyReturnActiveJobs) const +StringArray ThreadPool::getNamesOfAllJobs (const bool onlyReturnActiveJobs) const { StringArray s; const ScopedLock sl (lock); @@ -17861,7 +17854,7 @@ bool ValueTree::hasType (const Identifier& typeName) const return object != nullptr && object->type == typeName; } -const Identifier ValueTree::getType() const +Identifier ValueTree::getType() const { return object != nullptr ? object->type : Identifier(); } @@ -17890,7 +17883,7 @@ const var& ValueTree::getProperty (const Identifier& name) const return object == nullptr ? var::null : object->getProperty (name); } -const var ValueTree::getProperty (const Identifier& name, const var& defaultReturnValue) const +var ValueTree::getProperty (const Identifier& name, const var& defaultReturnValue) const { return object == nullptr ? defaultReturnValue : object->getProperty (name, defaultReturnValue); } @@ -17925,7 +17918,7 @@ int ValueTree::getNumProperties() const return object == nullptr ? 0 : object->properties.size(); } -const Identifier ValueTree::getPropertyName (const int index) const +Identifier ValueTree::getPropertyName (const int index) const { return object == nullptr ? Identifier() : object->properties.getName (index); @@ -18270,12 +18263,12 @@ Value::~Value() value->valuesWithListeners.removeValue (this); } -const var Value::getValue() const +var Value::getValue() const { return value->getValue(); } -Value::operator const var() const +Value::operator var() const { return getValue(); } @@ -18285,7 +18278,7 @@ void Value::setValue (const var& newValue) value->setValue (newValue); } -const String Value::toString() const +String Value::toString() const { return value->getValue().toString(); } @@ -18768,7 +18761,7 @@ const String ApplicationCommandManager::getDescriptionOfCommand (const CommandID : String::empty; } -const StringArray ApplicationCommandManager::getCommandCategories() const +StringArray ApplicationCommandManager::getCommandCategories() const { StringArray s; @@ -19483,10 +19476,10 @@ void PropertiesFile::propertyChanged() saveIfNeeded(); } -const File PropertiesFile::getDefaultAppSettingsFile (const String& applicationName, - const String& fileNameSuffix, - const String& folderName, - const bool commonToAllUsers) +File PropertiesFile::getDefaultAppSettingsFile (const String& applicationName, + const String& fileNameSuffix, + const String& folderName, + const bool commonToAllUsers) { // mustn't have illegal characters in this name.. jassert (applicationName == File::createLegalFileName (applicationName)); @@ -19827,7 +19820,7 @@ int RecentlyOpenedFilesList::getNumFiles() const return files.size(); } -const File RecentlyOpenedFilesList::getFile (const int index) const +File RecentlyOpenedFilesList::getFile (const int index) const { return File (files [index]); } @@ -19898,7 +19891,7 @@ int RecentlyOpenedFilesList::createPopupMenuItems (PopupMenu& menuToAddTo, return num; } -const String RecentlyOpenedFilesList::toString() const +String RecentlyOpenedFilesList::toString() const { return files.joinIntoString ("\n"); } @@ -20061,12 +20054,12 @@ bool UndoManager::canRedo() const return nextIndex < transactions.size(); } -const String UndoManager::getUndoDescription() const +String UndoManager::getUndoDescription() const { return transactionNames [nextIndex - 1]; } -const String UndoManager::getRedoDescription() const +String UndoManager::getRedoDescription() const { return transactionNames [nextIndex]; } @@ -22007,50 +22000,51 @@ BEGIN_JUCE_NAMESPACE struct AudioThumbnail::MinMaxValue { - char minValue; - char maxValue; - - MinMaxValue() noexcept : minValue (0), maxValue (0) + MinMaxValue() noexcept { + values[0] = 0; + values[1] = 0; } inline void set (const char newMin, const char newMax) noexcept { - minValue = newMin; - maxValue = newMax; + values[0] = newMin; + values[1] = newMax; } + inline char getMinValue() const noexcept { return values[0]; } + inline char getMaxValue() const noexcept { return values[1]; } + inline void setFloat (const float newMin, const float newMax) noexcept { - minValue = (char) jlimit (-128, 127, roundFloatToInt (newMin * 127.0f)); - maxValue = (char) jlimit (-128, 127, roundFloatToInt (newMax * 127.0f)); + values[0] = (char) jlimit (-128, 127, roundFloatToInt (newMin * 127.0f)); + values[1] = (char) jlimit (-128, 127, roundFloatToInt (newMax * 127.0f)); - if (maxValue == minValue) - maxValue = (char) jmin (127, maxValue + 1); + if (values[0] == values[1]) + { + if (values[1] == 127) + values[0]--; + else + values[1]++; + } } inline bool isNonZero() const noexcept { - return maxValue > minValue; + return values[1] > values[0]; } inline int getPeak() const noexcept { - return jmax (std::abs ((int) minValue), - std::abs ((int) maxValue)); + return jmax (std::abs ((int) values[0]), + std::abs ((int) values[1])); } - inline void read (InputStream& input) - { - minValue = input.readByte(); - maxValue = input.readByte(); - } + inline void read (InputStream& input) { input.read (values, 2); } + inline void write (OutputStream& output) { output.write (values, 2); } - inline void write (OutputStream& output) - { - output.writeByte (minValue); - output.writeByte (maxValue); - } +private: + char values[2]; }; class AudioThumbnail::LevelDataSource : public TimeSliceClient @@ -22264,8 +22258,8 @@ public: { const MinMaxValue& v = data.getReference (startSample); - if (v.minValue < mn) mn = v.minValue; - if (v.maxValue > mx) mx = v.maxValue; + if (v.getMinValue() < mn) mn = v.getMinValue(); + if (v.getMaxValue() > mx) mx = v.getMaxValue(); ++startSample; } @@ -22366,8 +22360,8 @@ public: for (int w = clip.getWidth(); --w >= 0;) { if (cacheData->isNonZero()) - g.drawVerticalLine (x, jmax (midY - cacheData->maxValue * vscale - 0.3f, topY), - jmin (midY - cacheData->minValue * vscale + 0.3f, bottomY)); + g.drawVerticalLine (x, jmax (midY - cacheData->getMaxValue() * vscale - 0.3f, topY), + jmin (midY - cacheData->getMinValue() * vscale + 0.3f, bottomY)); ++x; ++cacheData; @@ -22535,10 +22529,12 @@ void AudioThumbnail::createChannels (const int length) channels.add (new ThumbData (length)); } -void AudioThumbnail::loadFrom (InputStream& input) +void AudioThumbnail::loadFrom (InputStream& rawInput) { clear(); + BufferedInputStream input (rawInput, 4096); + if (input.readByte() != 'j' || input.readByte() != 'a' || input.readByte() != 't' || input.readByte() != 'm') return; @@ -22548,7 +22544,7 @@ void AudioThumbnail::loadFrom (InputStream& input) int32 numThumbnailSamples = input.readInt(); // Number of samples in the thumbnail data. numChannels = input.readInt(); // Number of audio channels. sampleRate = input.readInt(); // Source sample rate. - input.skipNextBytes (16); // reserved area + input.skipNextBytes (16); // (reserved) createChannels (numThumbnailSamples); @@ -22727,8 +22723,8 @@ void AudioThumbnail::getApproximateMinMax (const double startTime, const double data->getMinMax (jmax (0, firstThumbIndex), lastThumbIndex, result); } - minValue = result.minValue / 128.0f; - maxValue = result.maxValue / 128.0f; + minValue = result.getMinValue() / 128.0f; + maxValue = result.getMaxValue() / 128.0f; } void AudioThumbnail::drawChannel (Graphics& g, const Rectangle& area, double startTime, @@ -23224,12 +23220,12 @@ const char* const WavAudioFormat::bwavOriginationTime = "bwav origination time" const char* const WavAudioFormat::bwavTimeReference = "bwav time reference"; const char* const WavAudioFormat::bwavCodingHistory = "bwav coding history"; -const StringPairArray WavAudioFormat::createBWAVMetadata (const String& description, - const String& originator, - const String& originatorRef, - const Time& date, - const int64 timeReferenceSamples, - const String& codingHistory) +StringPairArray WavAudioFormat::createBWAVMetadata (const String& description, + const String& originator, + const String& originatorRef, + const Time& date, + const int64 timeReferenceSamples, + const String& codingHistory) { StringPairArray m; @@ -26673,7 +26669,7 @@ void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName) { if (defaultMidiOutputName != deviceName) { - SortedSet oldCallbacks; + Array oldCallbacks; { const ScopedLock sl (audioCallbackLock); @@ -28829,14 +28825,10 @@ namespace MidiFileHelpers { const double diff = (first->message.getTimeStamp() - second->message.getTimeStamp()); - if (diff > 0) - return 1; - else if (diff < 0) - return -1; - else if (first->message.isNoteOff() && second->message.isNoteOn()) - return -1; - else if (first->message.isNoteOn() && second->message.isNoteOff()) - return 1; + if (diff > 0) return 1; + if (diff < 0) return -1; + if (first->message.isNoteOff() && second->message.isNoteOn()) return -1; + if (first->message.isNoteOn() && second->message.isNoteOff()) return 1; return 0; } @@ -29051,7 +29043,6 @@ bool MidiFile::writeTo (OutputStream& out) writeTrack (out, i); out.flush(); - return true; } @@ -29097,7 +29088,7 @@ void MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) mainOut.writeIntBigEndian ((int) ByteOrder::bigEndianInt ("MTrk")); mainOut.writeIntBigEndian ((int) out.getDataSize()); - mainOut.write (out.getData(), (int) out.getDataSize()); + mainOut << out; } END_JUCE_NAMESPACE @@ -29629,9 +29620,9 @@ int MidiMessage::getAfterTouchValue() const noexcept return data[2]; } -const MidiMessage MidiMessage::aftertouchChange (const int channel, - const int noteNum, - const int aftertouchValue) noexcept +MidiMessage MidiMessage::aftertouchChange (const int channel, + const int noteNum, + const int aftertouchValue) noexcept { jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 jassert (isPositiveAndBelow (noteNum, (int) 128)); @@ -29653,8 +29644,7 @@ int MidiMessage::getChannelPressureValue() const noexcept return data[1]; } -const MidiMessage MidiMessage::channelPressureChange (const int channel, - const int pressure) noexcept +MidiMessage MidiMessage::channelPressureChange (const int channel, const int pressure) noexcept { jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 jassert (isPositiveAndBelow (pressure, (int) 128)); @@ -29682,8 +29672,7 @@ int MidiMessage::getProgramChangeNumber() const noexcept return data[1]; } -const MidiMessage MidiMessage::programChange (const int channel, - const int programNumber) noexcept +MidiMessage MidiMessage::programChange (const int channel, const int programNumber) noexcept { jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 @@ -29701,8 +29690,7 @@ int MidiMessage::getPitchWheelValue() const noexcept return data[1] | (data[2] << 7); } -const MidiMessage MidiMessage::pitchWheel (const int channel, - const int position) noexcept +MidiMessage MidiMessage::pitchWheel (const int channel, const int position) noexcept { jassert (channel > 0 && channel <= 16); // valid channels are numbered 1 to 16 jassert (isPositiveAndBelow (position, (int) 0x4000)); @@ -29733,7 +29721,7 @@ int MidiMessage::getControllerValue() const noexcept return data[2]; } -const MidiMessage MidiMessage::controllerEvent (const int channel, const int controllerType, const int value) noexcept +MidiMessage MidiMessage::controllerEvent (const int channel, const int controllerType, const int value) noexcept { // the channel must be between 1 and 16 inclusive jassert (channel > 0 && channel <= 16); @@ -29742,12 +29730,12 @@ const MidiMessage MidiMessage::controllerEvent (const int channel, const int con controllerType & 127, value & 127); } -const MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, const float velocity) noexcept +MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, const float velocity) noexcept { return noteOn (channel, noteNumber, (uint8) (velocity * 127.0f)); } -const MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, const uint8 velocity) noexcept +MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, const uint8 velocity) noexcept { jassert (channel > 0 && channel <= 16); jassert (isPositiveAndBelow (noteNumber, (int) 128)); @@ -29756,7 +29744,7 @@ const MidiMessage MidiMessage::noteOn (const int channel, const int noteNumber, noteNumber & 127, MidiHelpers::validVelocity (velocity)); } -const MidiMessage MidiMessage::noteOff (const int channel, const int noteNumber, uint8 velocity) noexcept +MidiMessage MidiMessage::noteOff (const int channel, const int noteNumber, uint8 velocity) noexcept { jassert (channel > 0 && channel <= 16); jassert (isPositiveAndBelow (noteNumber, (int) 128)); @@ -29765,7 +29753,7 @@ const MidiMessage MidiMessage::noteOff (const int channel, const int noteNumber, noteNumber & 127, MidiHelpers::validVelocity (velocity)); } -const MidiMessage MidiMessage::allNotesOff (const int channel) noexcept +MidiMessage MidiMessage::allNotesOff (const int channel) noexcept { return controllerEvent (channel, 123, 0); } @@ -29775,7 +29763,7 @@ bool MidiMessage::isAllNotesOff() const noexcept return (data[0] & 0xf0) == 0xb0 && data[1] == 123; } -const MidiMessage MidiMessage::allSoundOff (const int channel) noexcept +MidiMessage MidiMessage::allSoundOff (const int channel) noexcept { return controllerEvent (channel, 120, 0); } @@ -29785,12 +29773,12 @@ bool MidiMessage::isAllSoundOff() const noexcept return (data[0] & 0xf0) == 0xb0 && data[1] == 120; } -const MidiMessage MidiMessage::allControllersOff (const int channel) noexcept +MidiMessage MidiMessage::allControllersOff (const int channel) noexcept { return controllerEvent (channel, 121, 0); } -const MidiMessage MidiMessage::masterVolume (const float volume) +MidiMessage MidiMessage::masterVolume (const float volume) { const int vol = jlimit (0, 0x3fff, roundToInt (volume * 0x4000)); @@ -29807,7 +29795,7 @@ bool MidiMessage::isSysEx() const noexcept return *data == 0xf0; } -const MidiMessage MidiMessage::createSysExMessage (const uint8* sysexData, const int dataSize) +MidiMessage MidiMessage::createSysExMessage (const uint8* sysexData, const int dataSize) { HeapBlock m (dataSize + 2); @@ -29866,7 +29854,7 @@ bool MidiMessage::isTextMetaEvent() const noexcept return t > 0 && t < 16; } -const String MidiMessage::getTextFromTextMetaEvent() const +String MidiMessage::getTextFromTextMetaEvent() const { return String (reinterpret_cast (getMetaEventData()), getMetaEventLength()); } @@ -29921,7 +29909,7 @@ double MidiMessage::getTempoMetaEventTickLength (const short timeFormat) const n } } -const MidiMessage MidiMessage::tempoMetaEvent (int microsecondsPerQuarterNote) noexcept +MidiMessage MidiMessage::tempoMetaEvent (int microsecondsPerQuarterNote) noexcept { const uint8 d[] = { 0xff, 81, 3, (uint8) (microsecondsPerQuarterNote >> 16), @@ -29951,7 +29939,7 @@ void MidiMessage::getTimeSignatureInfo (int& numerator, int& denominator) const } } -const MidiMessage MidiMessage::timeSignatureMetaEvent (const int numerator, const int denominator) +MidiMessage MidiMessage::timeSignatureMetaEvent (const int numerator, const int denominator) { int n = 1; int powerOfTwo = 0; @@ -29968,7 +29956,7 @@ const MidiMessage MidiMessage::timeSignatureMetaEvent (const int numerator, cons return MidiMessage (d, 7, 0.0); } -const MidiMessage MidiMessage::midiChannelMetaEvent (const int channel) noexcept +MidiMessage MidiMessage::midiChannelMetaEvent (const int channel) noexcept { const uint8 d[] = { 0xff, 0x20, 0x01, (uint8) jlimit (0, 0xff, channel - 1) }; @@ -29985,7 +29973,7 @@ int MidiMessage::getKeySignatureNumberOfSharpsOrFlats() const noexcept return (int) *getMetaEventData(); } -const MidiMessage MidiMessage::endOfTrack() noexcept +MidiMessage MidiMessage::endOfTrack() noexcept { return MidiMessage (0xff, 0x2f, 0, 0.0); } @@ -29993,30 +29981,30 @@ const MidiMessage MidiMessage::endOfTrack() noexcept bool MidiMessage::isSongPositionPointer() const noexcept { return *data == 0xf2; } int MidiMessage::getSongPositionPointerMidiBeat() const noexcept { return data[1] | (data[2] << 7); } -const MidiMessage MidiMessage::songPositionPointer (const int positionInMidiBeats) noexcept +MidiMessage MidiMessage::songPositionPointer (const int positionInMidiBeats) noexcept { return MidiMessage (0xf2, positionInMidiBeats & 127, (positionInMidiBeats >> 7) & 127); } -bool MidiMessage::isMidiStart() const noexcept { return *data == 0xfa; } -const MidiMessage MidiMessage::midiStart() noexcept { return MidiMessage (0xfa); } +bool MidiMessage::isMidiStart() const noexcept { return *data == 0xfa; } +MidiMessage MidiMessage::midiStart() noexcept { return MidiMessage (0xfa); } -bool MidiMessage::isMidiContinue() const noexcept { return *data == 0xfb; } -const MidiMessage MidiMessage::midiContinue() noexcept { return MidiMessage (0xfb); } +bool MidiMessage::isMidiContinue() const noexcept { return *data == 0xfb; } +MidiMessage MidiMessage::midiContinue() noexcept { return MidiMessage (0xfb); } -bool MidiMessage::isMidiStop() const noexcept { return *data == 0xfc; } -const MidiMessage MidiMessage::midiStop() noexcept { return MidiMessage (0xfc); } +bool MidiMessage::isMidiStop() const noexcept { return *data == 0xfc; } +MidiMessage MidiMessage::midiStop() noexcept { return MidiMessage (0xfc); } -bool MidiMessage::isMidiClock() const noexcept { return *data == 0xf8; } -const MidiMessage MidiMessage::midiClock() noexcept { return MidiMessage (0xf8); } +bool MidiMessage::isMidiClock() const noexcept { return *data == 0xf8; } +MidiMessage MidiMessage::midiClock() noexcept { return MidiMessage (0xf8); } bool MidiMessage::isQuarterFrame() const noexcept { return *data == 0xf1; } int MidiMessage::getQuarterFrameSequenceNumber() const noexcept { return ((int) data[1]) >> 4; } int MidiMessage::getQuarterFrameValue() const noexcept { return ((int) data[1]) & 0x0f; } -const MidiMessage MidiMessage::quarterFrame (const int sequenceNumber, const int value) noexcept +MidiMessage MidiMessage::quarterFrame (const int sequenceNumber, const int value) noexcept { return MidiMessage (0xf1, (sequenceNumber << 4) | value); } @@ -30042,9 +30030,9 @@ void MidiMessage::getFullFrameParameters (int& hours, int& minutes, int& seconds frames = data[8]; } -const MidiMessage MidiMessage::fullFrame (const int hours, const int minutes, - const int seconds, const int frames, - MidiMessage::SmpteTimecodeType timecodeType) +MidiMessage MidiMessage::fullFrame (const int hours, const int minutes, + const int seconds, const int frames, + MidiMessage::SmpteTimecodeType timecodeType) { const uint8 d[] = { 0xf0, 0x7f, 0x7f, 0x01, 0x01, (uint8) ((hours & 0x01f) | (timecodeType << 5)), @@ -30071,7 +30059,7 @@ MidiMessage::MidiMachineControlCommand MidiMessage::getMidiMachineControlCommand return (MidiMachineControlCommand) data[4]; } -const MidiMessage MidiMessage::midiMachineControlCommand (MidiMessage::MidiMachineControlCommand command) +MidiMessage MidiMessage::midiMachineControlCommand (MidiMessage::MidiMachineControlCommand command) { const uint8 d[] = { 0xf0, 0x7f, 0, 6, (uint8) command, 0xf7 }; @@ -30099,7 +30087,7 @@ bool MidiMessage::isMidiMachineControlGoto (int& hours, int& minutes, int& secon return false; } -const MidiMessage MidiMessage::midiMachineControlGoto (int hours, int minutes, int seconds, int frames) +MidiMessage MidiMessage::midiMachineControlGoto (int hours, int minutes, int seconds, int frames) { const uint8 d[] = { 0xf0, 0x7f, 0, 6, 0x44, 6, 1, (uint8) hours, @@ -30111,7 +30099,7 @@ const MidiMessage MidiMessage::midiMachineControlGoto (int hours, int minutes, i return MidiMessage (d, 12, 0.0); } -const String MidiMessage::getMidiNoteName (int note, bool useSharps, bool includeOctaveNumber, int octaveNumForMiddleC) +String MidiMessage::getMidiNoteName (int note, bool useSharps, bool includeOctaveNumber, int octaveNumForMiddleC) { static const char* const sharpNoteNames[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; static const char* const flatNoteNames[] = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" }; @@ -30136,7 +30124,7 @@ const double MidiMessage::getMidiNoteInHertz (int noteNumber, const double frequ return frequencyOfA * pow (2.0, noteNumber / 12.0); } -const String MidiMessage::getGMInstrumentName (const int n) +String MidiMessage::getGMInstrumentName (const int n) { const char* names[] = { @@ -30168,7 +30156,7 @@ const String MidiMessage::getGMInstrumentName (const int n) return isPositiveAndBelow (n, (int) 128) ? names[n] : (const char*) 0; } -const String MidiMessage::getGMInstrumentBankName (const int n) +String MidiMessage::getGMInstrumentBankName (const int n) { const char* names[] = { @@ -30181,7 +30169,7 @@ const String MidiMessage::getGMInstrumentBankName (const int n) return isPositiveAndBelow (n, (int) 16) ? names[n] : (const char*) 0; } -const String MidiMessage::getRhythmInstrumentName (const int n) +String MidiMessage::getRhythmInstrumentName (const int n) { const char* names[] = { @@ -30199,7 +30187,7 @@ const String MidiMessage::getRhythmInstrumentName (const int n) return (n >= 35 && n <= 81) ? names [n - 35] : (const char*) nullptr; } -const String MidiMessage::getControllerName (const int n) +String MidiMessage::getControllerName (const int n) { const char* names[] = { @@ -31444,7 +31432,7 @@ bool PluginDirectoryScanner::skipNextFile() return nextIndex < filesOrIdentifiersToScan.size(); } -const StringArray PluginDirectoryScanner::getDeadMansPedalFile() +StringArray PluginDirectoryScanner::getDeadMansPedalFile() { StringArray lines; @@ -38968,8 +38956,9 @@ void Synthesiser::handleSostenutoPedal (int midiChannel, bool isDown) } } -void Synthesiser::handleSoftPedal (int midiChannel, bool isDown) +void Synthesiser::handleSoftPedal (int midiChannel, bool /*isDown*/) { + (void) midiChannel; jassert (midiChannel > 0 && midiChannel <= 16); } @@ -39649,7 +39638,7 @@ Message::Message() noexcept intParameter2 (0), intParameter3 (0), pointerParameter (nullptr), - messageRecipient (0) + messageRecipient (nullptr) { } @@ -39661,7 +39650,7 @@ Message::Message (const int intParameter1_, intParameter2 (intParameter2_), intParameter3 (intParameter3_), pointerParameter (pointerParameter_), - messageRecipient (0) + messageRecipient (nullptr) { } @@ -41344,25 +41333,25 @@ int Component::getParentHeight() const noexcept int Component::getScreenX() const { return getScreenPosition().getX(); } int Component::getScreenY() const { return getScreenPosition().getY(); } -const Point Component::getScreenPosition() const { return localPointToGlobal (Point()); } -const Rectangle Component::getScreenBounds() const { return localAreaToGlobal (getLocalBounds()); } +Point Component::getScreenPosition() const { return localPointToGlobal (Point()); } +Rectangle Component::getScreenBounds() const { return localAreaToGlobal (getLocalBounds()); } -const Point Component::getLocalPoint (const Component* source, const Point& point) const +Point Component::getLocalPoint (const Component* source, const Point& point) const { return ComponentHelpers::convertCoordinate (this, source, point); } -const Rectangle Component::getLocalArea (const Component* source, const Rectangle& area) const +Rectangle Component::getLocalArea (const Component* source, const Rectangle& area) const { return ComponentHelpers::convertCoordinate (this, source, area); } -const Point Component::localPointToGlobal (const Point& point) const +Point Component::localPointToGlobal (const Point& point) const { return ComponentHelpers::convertCoordinate (nullptr, this, point); } -const Rectangle Component::localAreaToGlobal (const Rectangle& area) const +Rectangle Component::localAreaToGlobal (const Rectangle& area) const { return ComponentHelpers::convertCoordinate (nullptr, this, area); } @@ -41631,7 +41620,7 @@ void Component::setTransform (const AffineTransform& newTransform) } } -const AffineTransform Component::getTransform() const +AffineTransform Component::getTransform() const { return affineTransform != nullptr ? *affineTransform : AffineTransform::identity; } @@ -42347,8 +42336,8 @@ void Component::setPaintingIsUnclipped (const bool shouldPaintWithoutClipping) n flags.dontClipGraphicsFlag = shouldPaintWithoutClipping; } -const Image Component::createComponentSnapshot (const Rectangle& areaToGrab, - const bool clipImageToComponentBounds) +Image Component::createComponentSnapshot (const Rectangle& areaToGrab, + const bool clipImageToComponentBounds) { Rectangle r (areaToGrab); @@ -42502,12 +42491,12 @@ void Component::setPositioner (Positioner* newPositioner) positioner = newPositioner; } -const Rectangle Component::getLocalBounds() const noexcept +Rectangle Component::getLocalBounds() const noexcept { return Rectangle (getWidth(), getHeight()); } -const Rectangle Component::getBoundsInParent() const noexcept +Rectangle Component::getBoundsInParent() const noexcept { return affineTransform == nullptr ? bounds : bounds.toFloat().transformed (*affineTransform).getSmallestIntegerContainer(); @@ -43344,12 +43333,12 @@ bool JUCE_CALLTYPE Component::isMouseButtonDownAnywhere() noexcept return ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(); } -const Point Component::getMouseXYRelative() const +Point Component::getMouseXYRelative() const { return getLocalPoint (nullptr, Desktop::getMousePosition()); } -const Rectangle Component::getParentMonitorArea() const +Rectangle Component::getParentMonitorArea() const { return Desktop::getInstance().getMonitorAreaContaining (getScreenBounds().getCentre()); } @@ -45099,7 +45088,7 @@ void HyperlinkButton::setURL (const URL& newURL) noexcept setTooltip (newURL.toString (false)); } -const Font HyperlinkButton::getFontToUse() const +Font HyperlinkButton::getFontToUse() const { Font f (font); @@ -45210,7 +45199,7 @@ void ImageButton::setImages (const bool resizeButtonNowToFitThisImage, repaint(); } -const Image ImageButton::getCurrentImage() const +Image ImageButton::getCurrentImage() const { if (isDown() || getToggleState()) return getDownImage(); @@ -45221,18 +45210,18 @@ const Image ImageButton::getCurrentImage() const return getNormalImage(); } -const Image ImageButton::getNormalImage() const +Image ImageButton::getNormalImage() const { return normalImage; } -const Image ImageButton::getOverImage() const +Image ImageButton::getOverImage() const { return overImage.isValid() ? overImage : normalImage; } -const Image ImageButton::getDownImage() const +Image ImageButton::getDownImage() const { return downImage.isValid() ? downImage : getOverImage(); @@ -48476,7 +48465,7 @@ int ComboBox::getNumItems() const noexcept return n; } -const String ComboBox::getItemText (const int index) const +String ComboBox::getItemText (const int index) const { const ItemInfo* const item = getItemForIndex (index); @@ -48567,7 +48556,7 @@ void ComboBox::valueChanged (Value&) setSelectedId (currentId.getValue(), false); } -const String ComboBox::getText() const +String ComboBox::getText() const { return label->getText(); } @@ -48616,7 +48605,7 @@ void ComboBox::setTextWhenNothingSelected (const String& newMessage) } } -const String ComboBox::getTextWhenNothingSelected() const +String ComboBox::getTextWhenNothingSelected() const { return textWhenNothingSelected; } @@ -48626,7 +48615,7 @@ void ComboBox::setTextWhenNoChoicesAvailable (const String& newMessage) noChoicesMessage = newMessage; } -const String ComboBox::getTextWhenNoChoicesAvailable() const +String ComboBox::getTextWhenNoChoicesAvailable() const { return noChoicesMessage; } @@ -48894,7 +48883,7 @@ void ImageComponent::setImagePlacement (const RectanglePlacement& newPlacement) } } -const Image ImageComponent::getImage() const +const Image& ImageComponent::getImage() const { return image; } @@ -53152,7 +53141,7 @@ struct TextAtom bool isWhitespace() const { return CharacterFunctions::isWhitespace (atomText[0]); } bool isNewLine() const { return atomText[0] == '\r' || atomText[0] == '\n'; } - const String getText (const juce_wchar passwordCharacter) const + String getText (const juce_wchar passwordCharacter) const { if (passwordCharacter == 0) return atomText; @@ -53161,7 +53150,7 @@ struct TextAtom atomText.length()); } - const String getTrimmedText (const juce_wchar passwordCharacter) const + String getTrimmedText (const juce_wchar passwordCharacter) const { if (passwordCharacter == 0) return atomText.substring (0, numChars); @@ -54210,7 +54199,7 @@ void TextEditor::setSelectAllWhenFocused (const bool b) selectAllTextWhenFocused = b; } -const Font TextEditor::getFont() const +const Font& TextEditor::getFont() const { return currentFont; } @@ -55524,7 +55513,7 @@ void TextEditor::remove (const Range& range, } } -const String TextEditor::getText() const +String TextEditor::getText() const { MemoryOutputStream mo; mo.preallocate (getTotalNumChars()); @@ -55564,7 +55553,7 @@ const String TextEditor::getTextInRange (const Range& range) const return mo.toString(); } -const String TextEditor::getHighlightedText() const +String TextEditor::getHighlightedText() const { return getTextInRange (selection); } @@ -57419,6 +57408,17 @@ TreeViewItem* TreeView::findItemFromIdentifierString (const String& identifierSt return rootItem->findItemFromIdentifierString (identifierString); } +static void addAllSelectedItemIds (TreeViewItem* item, XmlElement& parent) +{ + if (item->isSelected()) + parent.createNewChildElement ("SELECTED")->setAttribute ("id", item->getItemIdentifierString()); + + const int numSubItems = item->getNumSubItems(); + + for (int i = 0; i < numSubItems; ++i) + addAllSelectedItemIds (item->getSubItem(i), parent); +} + XmlElement* TreeView::getOpennessState (const bool alsoIncludeScrollPosition) const { XmlElement* e = nullptr; @@ -57427,14 +57427,19 @@ XmlElement* TreeView::getOpennessState (const bool alsoIncludeScrollPosition) co { e = rootItem->getOpennessState(); - if (e != nullptr && alsoIncludeScrollPosition) - e->setAttribute ("scrollPos", viewport->getViewPositionY()); + if (e != nullptr) + { + if (alsoIncludeScrollPosition) + e->setAttribute ("scrollPos", viewport->getViewPositionY()); + + addAllSelectedItemIds (rootItem, *e); + } } return e; } -void TreeView::restoreOpennessState (const XmlElement& newState) +void TreeView::restoreOpennessState (const XmlElement& newState, const bool restoreStoredSelection) { if (rootItem != nullptr) { @@ -57443,6 +57448,19 @@ void TreeView::restoreOpennessState (const XmlElement& newState) if (newState.hasAttribute ("scrollPos")) viewport->setViewPosition (viewport->getViewPositionX(), newState.getIntAttribute ("scrollPos")); + + if (restoreStoredSelection) + { + clearSelectedItems(); + + forEachXmlChildElementWithTagName (newState, e, "SELECTED") + { + TreeViewItem* const item = rootItem->findItemFromIdentifierString (e->getStringAttribute ("id")); + + if (item != nullptr) + item->setSelected (true, false); + } + } } } @@ -58488,7 +58506,7 @@ TreeViewItem* TreeViewItem::getNextVisibleItem (const bool recurse) const noexce return nullptr; } -const String TreeViewItem::getItemIdentifierString() const +String TreeViewItem::getItemIdentifierString() const { String s; @@ -58509,7 +58527,7 @@ TreeViewItem* TreeViewItem::findItemFromIdentifierString (const String& identifi { const String remainingPath (identifierString.substring (thisId.length() + 1)); - bool wasOpen = isOpen(); + const bool wasOpen = isOpen(); setOpen (true); for (int i = subItems.size(); --i >= 0;) @@ -58770,7 +58788,7 @@ bool DirectoryContentsList::getFileInfo (const int index, return false; } -const File DirectoryContentsList::getFile (const int index) const +File DirectoryContentsList::getFile (const int index) const { const ScopedLock sl (fileListLock); const FileInfo* const info = files [index]; @@ -59015,7 +59033,7 @@ int FileBrowserComponent::getNumSelectedFiles() const noexcept return chosenFiles.size(); } -const File FileBrowserComponent::getSelectedFile (int index) const noexcept +File FileBrowserComponent::getSelectedFile (int index) const noexcept { if ((flags & canSelectDirectories) != 0 && filenameBox.getText().isEmpty()) return currentRoot; @@ -59034,7 +59052,7 @@ bool FileBrowserComponent::currentFileIsValid() const return getSelectedFile (0).exists(); } -const File FileBrowserComponent::getHighlightedFile() const noexcept +File FileBrowserComponent::getHighlightedFile() const noexcept { return fileListComponent->getSelectedFile (0); } @@ -59064,7 +59082,7 @@ bool FileBrowserComponent::isFileOrDirSuitable (const File& f) const && (fileFilter == nullptr || fileFilter->isFileSuitable (f)); } -const File FileBrowserComponent::getRoot() const +const File& FileBrowserComponent::getRoot() const { return currentRoot; } @@ -59533,7 +59551,7 @@ bool FileChooser::showDialog (const bool selectsDirectories, } #endif -const File FileChooser::getResult() const +File FileChooser::getResult() const { // if you've used a multiple-file select, you should use the getResults() method // to retrieve all the files that were chosen. @@ -59842,7 +59860,7 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_FileListComponent.cpp ***/ BEGIN_JUCE_NAMESPACE -const Image juce_createIconForFile (const File& file); +Image juce_createIconForFile (const File& file); FileListComponent::FileListComponent (DirectoryContentsList& listToShow) : ListBox (String::empty, nullptr), @@ -60193,7 +60211,7 @@ void FilenameComponent::fileDragExit (const StringArray&) repaint(); } -const File FilenameComponent::getCurrentFile() const +File FilenameComponent::getCurrentFile() const { File f (filenameBox.getText()); @@ -60229,7 +60247,7 @@ void FilenameComponent::setFilenameIsEditable (const bool shouldBeEditable) filenameBox.setEditableText (shouldBeEditable); } -const StringArray FilenameComponent::getRecentlyUsedFilenames() const +StringArray FilenameComponent::getRecentlyUsedFilenames() const { StringArray names; @@ -60541,7 +60559,7 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_FileTreeComponent.cpp ***/ BEGIN_JUCE_NAMESPACE -const Image juce_createIconForFile (const File& file); +Image juce_createIconForFile (const File& file); class FileListTreeItem : public TreeViewItem, public TimeSliceClient, @@ -61726,7 +61744,7 @@ const KeyPress KeyPress::createFromDescription (const String& desc) return KeyPress (key, ModifierKeys (modifiers), 0); } -const String KeyPress::getTextDescription() const +String KeyPress::getTextDescription() const { String desc; @@ -61776,7 +61794,7 @@ const String KeyPress::getTextDescription() const return desc; } -const String KeyPress::getTextDescriptionWithIcons() const +String KeyPress::getTextDescriptionWithIcons() const { #if JUCE_MAC return getTextDescription().replace ("shift + ", String::charToString (0x21e7)) @@ -65374,7 +65392,7 @@ const String TabbedButtonBar::getCurrentTabName() const return tab == nullptr ? String::empty : tab->name; } -const StringArray TabbedButtonBar::getTabNames() const +StringArray TabbedButtonBar::getTabNames() const { StringArray names; @@ -65758,7 +65776,7 @@ int TabbedComponent::getNumTabs() const return tabs->getNumTabs(); } -const StringArray TabbedComponent::getTabNames() const +StringArray TabbedComponent::getTabNames() const { return tabs->getTabNames(); } @@ -72575,7 +72593,7 @@ MouseEvent::~MouseEvent() noexcept { } -const MouseEvent MouseEvent::getEventRelativeTo (Component* const otherComponent) const noexcept +MouseEvent MouseEvent::getEventRelativeTo (Component* const otherComponent) const noexcept { if (otherComponent == nullptr) { @@ -72589,7 +72607,7 @@ const MouseEvent MouseEvent::getEventRelativeTo (Component* const otherComponent mouseDownTime, numberOfClicks, wasMovedSinceMouseDown); } -const MouseEvent MouseEvent::withNewPosition (const Point& newPosition) const noexcept +MouseEvent MouseEvent::withNewPosition (const Point& newPosition) const noexcept { return MouseEvent (source, newPosition, mods, eventComponent, originalComponent, eventTime, mouseDownPos, mouseDownTime, @@ -73737,7 +73755,7 @@ void PropertyPanel::refreshAll() const propertyHolderComponent->refreshAll(); } -const StringArray PropertyPanel::getSectionNames() const +StringArray PropertyPanel::getSectionNames() const { StringArray s; @@ -77806,7 +77824,7 @@ TextEditor* AlertWindow::getTextEditor (const String& nameOfTextEditor) const return nullptr; } -const String AlertWindow::getTextEditorContents (const String& nameOfTextEditor) const +String AlertWindow::getTextEditorContents (const String& nameOfTextEditor) const { TextEditor* const t = getTextEditor (nameOfTextEditor); return t != nullptr ? t->getText() : String::empty; @@ -80049,7 +80067,7 @@ void ResizableWindow::parentSizeChanged() } } -const String ResizableWindow::getWindowStateAsString() +String ResizableWindow::getWindowStateAsString() { updateLastPos(); return (isFullScreen() ? "fs " : "") + lastNonFullScreenPos.toString(); @@ -80419,7 +80437,7 @@ void TooltipWindow::showFor (const String& tip) toFront (false); } -const String TooltipWindow::getTipFor (Component* const c) +String TooltipWindow::getTipFor (Component* const c) { if (c != nullptr && Process::isForegroundProcess() @@ -81211,7 +81229,7 @@ bool RelativeCoordinate::isDynamic() const return term.usesAnySymbols(); } -const String RelativeCoordinate::toString() const +String RelativeCoordinate::toString() const { return term.toString(); } @@ -81284,7 +81302,7 @@ void RelativePoint::moveToAbsolute (const Point& newPos, const Expression y.moveToAbsolute (newPos.getY(), scope); } -const String RelativePoint::toString() const +String RelativePoint::toString() const { return x.toString() + ", " + y.toString(); } @@ -82311,9 +82329,9 @@ Colour::Colour (const uint8 red, argb.setARGB (0xff, red, green, blue); } -const Colour Colour::fromRGB (const uint8 red, - const uint8 green, - const uint8 blue) noexcept +Colour Colour::fromRGB (const uint8 red, + const uint8 green, + const uint8 blue) noexcept { return Colour (red, green, blue); } @@ -82326,10 +82344,10 @@ Colour::Colour (const uint8 red, argb.setARGB (alpha, red, green, blue); } -const Colour Colour::fromRGBA (const uint8 red, - const uint8 green, - const uint8 blue, - const uint8 alpha) noexcept +Colour Colour::fromRGBA (const uint8 red, + const uint8 green, + const uint8 blue, + const uint8 alpha) noexcept { return Colour (red, green, blue, alpha); } @@ -82342,10 +82360,10 @@ Colour::Colour (const uint8 red, argb.setARGB (ColourHelpers::floatAlphaToInt (alpha), red, green, blue); } -const Colour Colour::fromRGBAFloat (const uint8 red, - const uint8 green, - const uint8 blue, - const float alpha) noexcept +Colour Colour::fromRGBAFloat (const uint8 red, + const uint8 green, + const uint8 blue, + const float alpha) noexcept { return Colour (red, green, blue, alpha); } @@ -82361,10 +82379,10 @@ Colour::Colour (const float hue, argb.setARGB (ColourHelpers::floatAlphaToInt (alpha), r, g, b); } -const Colour Colour::fromHSV (const float hue, - const float saturation, - const float brightness, - const float alpha) noexcept +Colour Colour::fromHSV (const float hue, + const float saturation, + const float brightness, + const float alpha) noexcept { return Colour (hue, saturation, brightness, alpha); } @@ -82406,14 +82424,14 @@ bool Colour::isOpaque() const noexcept return getAlpha() == 0xff; } -const Colour Colour::withAlpha (const uint8 newAlpha) const noexcept +Colour Colour::withAlpha (const uint8 newAlpha) const noexcept { PixelARGB newCol (argb); newCol.setAlpha (newAlpha); return Colour (newCol.getARGB()); } -const Colour Colour::withAlpha (const float newAlpha) const noexcept +Colour Colour::withAlpha (const float newAlpha) const noexcept { jassert (newAlpha >= 0 && newAlpha <= 1.0f); @@ -82422,7 +82440,7 @@ const Colour Colour::withAlpha (const float newAlpha) const noexcept return Colour (newCol.getARGB()); } -const Colour Colour::withMultipliedAlpha (const float alphaMultiplier) const noexcept +Colour Colour::withMultipliedAlpha (const float alphaMultiplier) const noexcept { jassert (alphaMultiplier >= 0); @@ -82431,7 +82449,7 @@ const Colour Colour::withMultipliedAlpha (const float alphaMultiplier) const noe return Colour (newCol.getARGB()); } -const Colour Colour::overlaidWith (const Colour& src) const noexcept +Colour Colour::overlaidWith (const Colour& src) const noexcept { const int destAlpha = getAlpha(); @@ -82458,7 +82476,7 @@ const Colour Colour::overlaidWith (const Colour& src) const noexcept } } -const Colour Colour::interpolatedWith (const Colour& other, float proportionOfOther) const noexcept +Colour Colour::interpolatedWith (const Colour& other, float proportionOfOther) const noexcept { if (proportionOfOther <= 0) return *this; @@ -82548,7 +82566,7 @@ float Colour::getHue() const noexcept return h; } -const Colour Colour::withHue (const float hue) const noexcept +Colour Colour::withHue (const float hue) const noexcept { float h, s, b; getHSB (h, s, b); @@ -82556,7 +82574,7 @@ const Colour Colour::withHue (const float hue) const noexcept return Colour (hue, s, b, getAlpha()); } -const Colour Colour::withRotatedHue (const float amountToRotate) const noexcept +Colour Colour::withRotatedHue (const float amountToRotate) const noexcept { float h, s, b; getHSB (h, s, b); @@ -82571,7 +82589,7 @@ float Colour::getSaturation() const noexcept return s; } -const Colour Colour::withSaturation (const float saturation) const noexcept +Colour Colour::withSaturation (const float saturation) const noexcept { float h, s, b; getHSB (h, s, b); @@ -82579,7 +82597,7 @@ const Colour Colour::withSaturation (const float saturation) const noexcept return Colour (h, saturation, b, getAlpha()); } -const Colour Colour::withMultipliedSaturation (const float amount) const noexcept +Colour Colour::withMultipliedSaturation (const float amount) const noexcept { float h, s, b; getHSB (h, s, b); @@ -82594,7 +82612,7 @@ float Colour::getBrightness() const noexcept return b; } -const Colour Colour::withBrightness (const float brightness) const noexcept +Colour Colour::withBrightness (const float brightness) const noexcept { float h, s, b; getHSB (h, s, b); @@ -82602,7 +82620,7 @@ const Colour Colour::withBrightness (const float brightness) const noexcept return Colour (h, s, brightness, getAlpha()); } -const Colour Colour::withMultipliedBrightness (const float amount) const noexcept +Colour Colour::withMultipliedBrightness (const float amount) const noexcept { float h, s, b; getHSB (h, s, b); @@ -82615,7 +82633,7 @@ const Colour Colour::withMultipliedBrightness (const float amount) const noexcep return Colour (h, s, b, getAlpha()); } -const Colour Colour::brighter (float amount) const noexcept +Colour Colour::brighter (float amount) const noexcept { amount = 1.0f / (1.0f + amount); @@ -82625,7 +82643,7 @@ const Colour Colour::brighter (float amount) const noexcept getAlpha()); } -const Colour Colour::darker (float amount) const noexcept +Colour Colour::darker (float amount) const noexcept { amount = 1.0f / (1.0f + amount); @@ -82635,7 +82653,7 @@ const Colour Colour::darker (float amount) const noexcept getAlpha()); } -const Colour Colour::greyLevel (const float brightness) noexcept +Colour Colour::greyLevel (const float brightness) noexcept { const uint8 level = (uint8) jlimit (0x00, 0xff, roundToInt (brightness * 255.0f)); @@ -82643,15 +82661,15 @@ const Colour Colour::greyLevel (const float brightness) noexcept return Colour (level, level, level); } -const Colour Colour::contrasting (const float amount) const noexcept +Colour Colour::contrasting (const float amount) const noexcept { return overlaidWith ((((int) getRed() + (int) getGreen() + (int) getBlue() >= 3 * 128) ? Colours::black : Colours::white).withAlpha (amount)); } -const Colour Colour::contrasting (const Colour& colour1, - const Colour& colour2) noexcept +Colour Colour::contrasting (const Colour& colour1, + const Colour& colour2) noexcept { const float b1 = colour1.getBrightness(); const float b2 = colour2.getBrightness(); @@ -82675,17 +82693,17 @@ const Colour Colour::contrasting (const Colour& colour1, .withBrightness (best); } -const String Colour::toString() const +String Colour::toString() const { return String::toHexString ((int) argb.getARGB()); } -const Colour Colour::fromString (const String& encodedColourString) +Colour Colour::fromString (const String& encodedColourString) { return Colour ((uint32) encodedColourString.getHexValue32()); } -const String Colour::toDisplayString (const bool includeAlphaValue) const +String Colour::toDisplayString (const bool includeAlphaValue) const { return String::toHexString ((int) (argb.getARGB() & (includeAlphaValue ? 0xffffffff : 0xffffff))) .paddedLeft ('0', includeAlphaValue ? 8 : 6) @@ -82703,9 +82721,9 @@ BEGIN_JUCE_NAMESPACE ColourGradient::ColourGradient() noexcept { -#if JUCE_DEBUG + #if JUCE_DEBUG point1.setX (987654.0f); -#endif + #endif } ColourGradient::ColourGradient (const Colour& colour1, const float x1_, const float y1_, @@ -82798,7 +82816,7 @@ void ColourGradient::setColour (int index, const Colour& newColour) noexcept colours.getReference (index).colour = newColour; } -const Colour ColourGradient::getColourAtPosition (const double position) const 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 @@ -82821,11 +82839,11 @@ const Colour ColourGradient::getColourAtPosition (const double position) const n int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlock & lookupTable) const { -#if JUCE_DEBUG + #if JUCE_DEBUG // trying to use the object without setting its co-ordinates? Have a careful read of // the comments for the constructors. jassert (point1.getX() != 987654.0f); -#endif + #endif const int numEntries = jlimit (1, jmax (1, (colours.size() - 1) << 8), 3 * (int) point1.transformedBy (transform) @@ -84232,7 +84250,7 @@ void Graphics::setFont (const float newFontHeight, const int newFontStyleFlags) context->setFont (f); } -const Font Graphics::getCurrentFont() const +Font Graphics::getCurrentFont() const { return context->getFont(); } @@ -85241,7 +85259,7 @@ void LowLevelGraphicsPostScriptRenderer::setFont (const Font& newFont) stateStack.getLast()->font = newFont; } -const Font LowLevelGraphicsPostScriptRenderer::getFont() +Font LowLevelGraphicsPostScriptRenderer::getFont() { return stateStack.getLast()->font; } @@ -87694,7 +87712,7 @@ void LowLevelGraphicsSoftwareRenderer::setFont (const Font& newFont) currentState->font = newFont; } -const Font LowLevelGraphicsSoftwareRenderer::getFont() +Font LowLevelGraphicsSoftwareRenderer::getFont() { return currentState->font; } @@ -89954,7 +89972,7 @@ DrawableText::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) jassert (state.hasType (valueTreeType)); } -const String DrawableText::ValueTreeWrapper::getText() const +String DrawableText::ValueTreeWrapper::getText() const { return state [text].toString(); } @@ -89969,7 +89987,7 @@ Value DrawableText::ValueTreeWrapper::getTextValue (UndoManager* undoManager) return state.getPropertyAsValue (text, undoManager); } -const Colour DrawableText::ValueTreeWrapper::getColour() const +Colour DrawableText::ValueTreeWrapper::getColour() const { return Colour::fromString (state [colour].toString()); } @@ -89979,7 +89997,7 @@ void DrawableText::ValueTreeWrapper::setColour (const Colour& newColour, UndoMan state.setProperty (colour, newColour.toString(), undoManager); } -const Justification DrawableText::ValueTreeWrapper::getJustification() const +Justification DrawableText::ValueTreeWrapper::getJustification() const { return Justification ((int) state [justification]); } @@ -89989,7 +90007,7 @@ void DrawableText::ValueTreeWrapper::setJustification (const Justification& newJ state.setProperty (justification, newJustification.getFlags(), undoManager); } -const Font DrawableText::ValueTreeWrapper::getFont() const +Font DrawableText::ValueTreeWrapper::getFont() const { return Font::fromString (state [font]); } @@ -90004,7 +90022,7 @@ Value DrawableText::ValueTreeWrapper::getFontValue (UndoManager* undoManager) return state.getPropertyAsValue (font, undoManager); } -const RelativeParallelogram DrawableText::ValueTreeWrapper::getBoundingBox() const +RelativeParallelogram DrawableText::ValueTreeWrapper::getBoundingBox() const { return RelativeParallelogram (state [topLeft].toString(), state [topRight].toString(), state [bottomLeft].toString()); } @@ -90016,7 +90034,7 @@ void DrawableText::ValueTreeWrapper::setBoundingBox (const RelativeParallelogram state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); } -const RelativePoint DrawableText::ValueTreeWrapper::getFontSizeControlPoint() const +RelativePoint DrawableText::ValueTreeWrapper::getFontSizeControlPoint() const { return state [fontSizeAnchor].toString(); } @@ -90947,8 +90965,8 @@ private: cssStyleText = xml.getAllSubText() + "\n" + cssStyleText; } - const String getStyleAttribute (const XmlElement* xml, const String& attributeName, - const String& defaultValue = String::empty) const + String getStyleAttribute (const XmlElement* xml, const String& attributeName, + const String& defaultValue = String::empty) const { if (xml->hasAttribute (attributeName)) return xml->getStringAttribute (attributeName, defaultValue); @@ -90998,7 +91016,7 @@ private: return defaultValue; } - const String getInheritedAttribute (const XmlElement* xml, const String& attributeName) const + String getInheritedAttribute (const XmlElement* xml, const String& attributeName) const { if (xml->hasAttribute (attributeName)) return xml->getStringAttribute (attributeName); @@ -91016,7 +91034,7 @@ private: return CharacterFunctions::isLetter (c) || c == '-'; } - static const String getAttributeFromStyleList (const String& list, const String& attributeName, const String& defaultValue) + static String getAttributeFromStyleList (const String& list, const String& attributeName, const String& defaultValue) { int i = 0; @@ -91689,19 +91707,19 @@ void Font::dupeInternalIfShared() font = new SharedFontInternal (*font); } -const String Font::getDefaultSansSerifFontName() +const String& Font::getDefaultSansSerifFontName() { static const String name (""); return name; } -const String Font::getDefaultSerifFontName() +const String& Font::getDefaultSerifFontName() { static const String name (""); return name; } -const String Font::getDefaultMonospacedFontName() +const String& Font::getDefaultMonospacedFontName() { static const String name (""); return name; @@ -91718,7 +91736,7 @@ void Font::setTypefaceName (const String& faceName) } } -const String Font::getFallbackFontName() +const String& Font::getFallbackFontName() { return FontValues::fallbackFont; } @@ -91800,7 +91818,7 @@ void Font::setBold (const bool shouldBeBold) : (font->styleFlags & ~bold)); } -const Font Font::boldened() const +Font Font::boldened() const { Font f (*this); f.setBold (true); @@ -91818,7 +91836,7 @@ void Font::setItalic (const bool shouldBeItalic) : (font->styleFlags & ~italic)); } -const Font Font::italicised() const +Font Font::italicised() const { Font f (*this); f.setItalic (true); @@ -91901,7 +91919,7 @@ void Font::findFonts (Array& destArray) destArray.add (Font (names[i], FontValues::defaultFontHeight, Font::plain)); } -const String Font::toString() const +String Font::toString() const { String s (getTypefaceName()); @@ -91921,7 +91939,7 @@ const String Font::toString() const return s; } -const Font Font::fromString (const String& fontDescription) +Font Font::fromString (const String& fontDescription) { String name; @@ -93088,6 +93106,14 @@ const Typeface::Ptr Typeface::getFallbackTypeface() return t; } +END_JUCE_NAMESPACE + +/*** End of inlined file: juce_Typeface.cpp ***/ + + +/*** Start of inlined file: juce_CustomTypeface.cpp ***/ +BEGIN_JUCE_NAMESPACE + class CustomTypeface::GlyphInfo { public: @@ -93498,7 +93524,7 @@ EdgeTable* CustomTypeface::getEdgeTableForGlyph (int glyphNumber, const AffineTr END_JUCE_NAMESPACE -/*** End of inlined file: juce_Typeface.cpp ***/ +/*** End of inlined file: juce_CustomTypeface.cpp ***/ /*** Start of inlined file: juce_AffineTransform.cpp ***/ @@ -93562,7 +93588,7 @@ bool AffineTransform::isIdentity() const noexcept const AffineTransform AffineTransform::identity; -const AffineTransform AffineTransform::followedBy (const AffineTransform& other) const noexcept +AffineTransform AffineTransform::followedBy (const AffineTransform& other) const noexcept { return AffineTransform (other.mat00 * mat00 + other.mat01 * mat10, other.mat00 * mat01 + other.mat01 * mat11, @@ -93572,19 +93598,19 @@ const AffineTransform AffineTransform::followedBy (const AffineTransform& other) other.mat10 * mat02 + other.mat11 * mat12 + other.mat12); } -const AffineTransform AffineTransform::translated (const float dx, const float dy) const noexcept +AffineTransform AffineTransform::translated (const float dx, const float dy) const noexcept { return AffineTransform (mat00, mat01, mat02 + dx, mat10, mat11, mat12 + dy); } -const AffineTransform AffineTransform::translation (const float dx, const float dy) noexcept +AffineTransform AffineTransform::translation (const float dx, const float dy) noexcept { return AffineTransform (1.0f, 0, dx, 0, 1.0f, dy); } -const AffineTransform AffineTransform::rotated (const float rad) const noexcept +AffineTransform AffineTransform::rotated (const float rad) const noexcept { const float cosRad = std::cos (rad); const float sinRad = std::sin (rad); @@ -93597,7 +93623,7 @@ const AffineTransform AffineTransform::rotated (const float rad) const noexcept sinRad * mat02 + cosRad * mat12); } -const AffineTransform AffineTransform::rotation (const float rad) noexcept +AffineTransform AffineTransform::rotation (const float rad) noexcept { const float cosRad = std::cos (rad); const float sinRad = std::sin (rad); @@ -93606,7 +93632,7 @@ const AffineTransform AffineTransform::rotation (const float rad) noexcept sinRad, cosRad, 0); } -const AffineTransform AffineTransform::rotation (const float rad, const float pivotX, const float pivotY) noexcept +AffineTransform AffineTransform::rotation (const float rad, const float pivotX, const float pivotY) noexcept { const float cosRad = std::cos (rad); const float sinRad = std::sin (rad); @@ -93615,44 +93641,44 @@ const AffineTransform AffineTransform::rotation (const float rad, const float pi sinRad, cosRad, -sinRad * pivotX + -cosRad * pivotY + pivotY); } -const AffineTransform AffineTransform::rotated (const float angle, const float pivotX, const float pivotY) const noexcept +AffineTransform AffineTransform::rotated (const float angle, const float pivotX, const float pivotY) const noexcept { return followedBy (rotation (angle, pivotX, pivotY)); } -const AffineTransform AffineTransform::scaled (const float factorX, const float factorY) const noexcept +AffineTransform AffineTransform::scaled (const float factorX, const float factorY) const noexcept { return AffineTransform (factorX * mat00, factorX * mat01, factorX * mat02, factorY * mat10, factorY * mat11, factorY * mat12); } -const AffineTransform AffineTransform::scale (const float factorX, const float factorY) noexcept +AffineTransform AffineTransform::scale (const float factorX, const float factorY) noexcept { return AffineTransform (factorX, 0, 0, 0, factorY, 0); } -const AffineTransform AffineTransform::scaled (const float factorX, const float factorY, +AffineTransform AffineTransform::scaled (const float factorX, const float factorY, const float pivotX, const float pivotY) const noexcept { return AffineTransform (factorX * mat00, factorX * mat01, factorX * mat02 + pivotX * (1.0f - factorX), factorY * mat10, factorY * mat11, factorY * mat12 + pivotY * (1.0f - factorY)); } -const AffineTransform AffineTransform::scale (const float factorX, const float factorY, +AffineTransform AffineTransform::scale (const float factorX, const float factorY, const float pivotX, const float pivotY) noexcept { return AffineTransform (factorX, 0, pivotX * (1.0f - factorX), 0, factorY, pivotY * (1.0f - factorY)); } -const AffineTransform AffineTransform::shear (float shearX, float shearY) noexcept +AffineTransform AffineTransform::shear (float shearX, float shearY) noexcept { return AffineTransform (1.0f, shearX, 0, shearY, 1.0f, 0); } -const AffineTransform AffineTransform::sheared (const float shearX, const float shearY) const noexcept +AffineTransform AffineTransform::sheared (const float shearX, const float shearY) const noexcept { return AffineTransform (mat00 + shearX * mat10, mat01 + shearX * mat11, @@ -93662,7 +93688,7 @@ const AffineTransform AffineTransform::sheared (const float shearX, const float shearY * mat02 + mat12); } -const AffineTransform AffineTransform::inverted() const noexcept +AffineTransform AffineTransform::inverted() const noexcept { double determinant = (mat00 * mat11 - mat10 * mat01); @@ -93690,17 +93716,17 @@ bool AffineTransform::isSingularity() const noexcept return (mat00 * mat11 - mat10 * mat01) == 0; } -const AffineTransform AffineTransform::fromTargetPoints (const float x00, const float y00, - const float x10, const float y10, - const float x01, const float y01) noexcept +AffineTransform AffineTransform::fromTargetPoints (const float x00, const float y00, + const float x10, const float y10, + const float x01, const float y01) noexcept { return AffineTransform (x10 - x00, x01 - x00, x00, y10 - y00, y01 - y00, y00); } -const AffineTransform AffineTransform::fromTargetPoints (const float sx1, const float sy1, const float tx1, const float ty1, - const float sx2, const float sy2, const float tx2, const float ty2, - const float sx3, const float sy3, const float tx3, const float ty3) noexcept +AffineTransform AffineTransform::fromTargetPoints (const float sx1, const float sy1, const float tx1, const float ty1, + const float sx2, const float sy2, const float tx2, const float ty2, + const float sx3, const float sy3, const float tx3, const float ty3) noexcept { return fromTargetPoints (sx1, sy1, sx2, sy2, sx3, sy3) .inverted() @@ -93736,7 +93762,7 @@ namespace PathHelpers { const float ellipseAngularIncrement = 0.05f; - const String nextToken (String::CharPointerType& t) + String nextToken (String::CharPointerType& t) { t = t.findEndOfWhitespace(); @@ -93884,14 +93910,14 @@ bool Path::isEmpty() const noexcept return true; } -const Rectangle Path::getBounds() const noexcept +Rectangle Path::getBounds() const noexcept { return Rectangle (pathXMin, pathYMin, pathXMax - pathXMin, pathYMax - pathYMin); } -const Rectangle Path::getBoundsTransformed (const AffineTransform& transform) const noexcept +Rectangle Path::getBoundsTransformed (const AffineTransform& transform) const noexcept { return getBounds().transformed (transform); } @@ -94025,7 +94051,7 @@ void Path::closeSubPath() } } -const Point Path::getCurrentPosition() const +Point Path::getCurrentPosition() const { int i = (int) numElements - 1; @@ -94600,10 +94626,10 @@ void Path::applyTransform (const AffineTransform& transform) noexcept } } -const AffineTransform Path::getTransformToScaleToFit (const float x, const float y, - const float w, const float h, - const bool preserveProportions, - const Justification& justification) const +AffineTransform Path::getTransformToScaleToFit (const float x, const float y, + const float w, const float h, + const bool preserveProportions, + const Justification& justification) const { Rectangle bounds (getBounds()); @@ -94704,7 +94730,7 @@ bool Path::intersectsLine (const Line& line, const float tolerance) return false; } -const Line Path::getClippedLine (const Line& line, const bool keepSectionOutsidePath) const +Line Path::getClippedLine (const Line& line, const bool keepSectionOutsidePath) const { Line result (line); const bool startInside = contains (line.getStart()); @@ -94746,7 +94772,7 @@ float Path::getLength (const AffineTransform& transform) const return length; } -const Point Path::getPointAlongPath (float distanceFromStart, const AffineTransform& transform) const +Point Path::getPointAlongPath (float distanceFromStart, const AffineTransform& transform) const { PathFlatteningIterator i (*this, transform); @@ -94790,7 +94816,7 @@ float Path::getNearestPoint (const Point& targetPoint, Point& poin return bestPosition; } -const Path Path::createPathWithRoundedCorners (const float cornerRadius) const +Path Path::createPathWithRoundedCorners (const float cornerRadius) const { if (cornerRadius <= 0.01f) return *this; @@ -95061,7 +95087,7 @@ void Path::writePathToStream (OutputStream& dest) const dest.writeByte ('e'); // marks the end-of-path } -const String Path::toString() const +String Path::toString() const { MemoryOutputStream s (2048); if (! useNonZeroWinding) @@ -96289,7 +96315,7 @@ void RectangleList::clear() rects.clearQuick(); } -const Rectangle RectangleList::getRectangle (const int index) const noexcept +Rectangle RectangleList::getRectangle (const int index) const noexcept { if (isPositiveAndBelow (index, rects.size())) return rects.getReference (index); @@ -96687,7 +96713,7 @@ bool RectangleList::intersects (const RectangleList& other) const noexcept return false; } -const Rectangle RectangleList::getBounds() const noexcept +Rectangle RectangleList::getBounds() const noexcept { if (rects.size() <= 1) { @@ -96730,7 +96756,7 @@ void RectangleList::offsetAll (const int dx, const int dy) noexcept } } -const Path RectangleList::toPath() const +Path RectangleList::toPath() const { Path p; @@ -96853,7 +96879,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SubsectionSharedImage); }; -const Image Image::getClippedImage (const Rectangle& area) const +Image Image::getClippedImage (const Rectangle& area) const { if (area.contains (getBounds())) return *this; @@ -96910,7 +96936,7 @@ void Image::duplicateIfShared() image = image->clone(); } -const Image Image::rescaled (const int newWidth, const int newHeight, const Graphics::ResamplingQuality quality) const +Image Image::rescaled (const int newWidth, const int newHeight, const Graphics::ResamplingQuality quality) const { if (image == nullptr || (image->width == newWidth && image->height == newHeight)) return *this; @@ -96924,7 +96950,7 @@ const Image Image::rescaled (const int newWidth, const int newHeight, const Grap return newImage; } -const Image Image::convertedToFormat (PixelFormat newFormat) const +Image Image::convertedToFormat (PixelFormat newFormat) const { if (image == nullptr || newFormat == image->format) return *this; @@ -97358,7 +97384,7 @@ public: clearSingletonInstance(); } - const Image getFromHashCode (const int64 hashCode) + Image getFromHashCode (const int64 hashCode) { const ScopedLock sl (lock); @@ -97435,7 +97461,7 @@ private: juce_ImplementSingleton_SingleThreaded (ImageCache::Pimpl); -const Image ImageCache::getFromHashCode (const int64 hashCode) +Image ImageCache::getFromHashCode (const int64 hashCode) { if (Pimpl::getInstanceWithoutCreating() != nullptr) return Pimpl::getInstanceWithoutCreating()->getFromHashCode (hashCode); @@ -97448,7 +97474,7 @@ void ImageCache::addImageToCache (const Image& image, const int64 hashCode) Pimpl::getInstance()->addImageToCache (image, hashCode); } -const Image ImageCache::getFromFile (const File& file) +Image ImageCache::getFromFile (const File& file) { const int64 hashCode = file.hashCode64(); Image image (getFromHashCode (hashCode)); @@ -97462,7 +97488,7 @@ const Image ImageCache::getFromFile (const File& file) return image; } -const Image ImageCache::getFromMemory (const void* imageData, const int dataSize) +Image ImageCache::getFromMemory (const void* imageData, const int dataSize) { const int64 hashCode = (int64) (pointer_sized_int) imageData; Image image (getFromHashCode (hashCode)); @@ -97743,7 +97769,7 @@ ImageFileFormat* ImageFileFormat::findImageFormatForStream (InputStream& input) return nullptr; } -const Image ImageFileFormat::loadFrom (InputStream& input) +Image ImageFileFormat::loadFrom (InputStream& input) { ImageFileFormat* const format = findImageFormatForStream (input); @@ -97753,7 +97779,7 @@ const Image ImageFileFormat::loadFrom (InputStream& input) return Image::null; } -const Image ImageFileFormat::loadFrom (const File& file) +Image ImageFileFormat::loadFrom (const File& file) { InputStream* const in = file.createInputStream(); @@ -97766,7 +97792,7 @@ const Image ImageFileFormat::loadFrom (const File& file) return Image::null; } -const Image ImageFileFormat::loadFrom (const void* rawData, const int numBytes) +Image ImageFileFormat::loadFrom (const void* rawData, const int numBytes) { if (rawData != nullptr && numBytes > 4) { @@ -97786,7 +97812,7 @@ END_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE #if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER - const Image juce_loadWithCoreImage (InputStream& input); + Image juce_loadWithCoreImage (InputStream& input); #else class GIFLoader @@ -97831,8 +97857,8 @@ public: if (input.read (buf, 9) == 9) { - imageWidth = makeWord (buf[4], buf[5]); - imageHeight = makeWord (buf[6], buf[7]); + imageWidth = (int) ByteOrder::littleEndianShort (buf + 4); + imageHeight = (int) ByteOrder::littleEndianShort (buf + 6); numColours = 2 << (buf[8] & 7); @@ -97879,8 +97905,8 @@ private: { if (input.read (b, 4) == 4) { - w = makeWord (b[0], b[1]); - h = makeWord (b[2], b[3]); + w = (int) ByteOrder::littleEndianShort (b); + h = (int) ByteOrder::littleEndianShort (b + 2); return w > 0 && h > 0; } } @@ -98171,8 +98197,6 @@ private: return true; } - static inline int makeWord (const int a, const int b) { return (b << 8) | a; } - JUCE_DECLARE_NON_COPYABLE (GIFLoader); }; @@ -98181,7 +98205,7 @@ private: GIFImageFormat::GIFImageFormat() {} GIFImageFormat::~GIFImageFormat() {} -const String GIFImageFormat::getFormatName() { return "GIF"; } +String GIFImageFormat::getFormatName() { return "GIF"; } bool GIFImageFormat::canUnderstand (InputStream& in) { @@ -98193,7 +98217,7 @@ bool GIFImageFormat::canUnderstand (InputStream& in) && header[2] == 'F'; } -const Image GIFImageFormat::decodeImage (InputStream& in) +Image GIFImageFormat::decodeImage (InputStream& in) { #if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER return juce_loadWithCoreImage (in); @@ -217618,10 +217642,7 @@ void JPEGImageFormat::setQuality (const float newQuality) quality = newQuality; } -const String JPEGImageFormat::getFormatName() -{ - return "JPEG"; -} +String JPEGImageFormat::getFormatName() { return "JPEG"; } bool JPEGImageFormat::canUnderstand (InputStream& in) { @@ -217640,10 +217661,10 @@ bool JPEGImageFormat::canUnderstand (InputStream& in) } #if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER - const Image juce_loadWithCoreImage (InputStream& input); + Image juce_loadWithCoreImage (InputStream& input); #endif -const Image JPEGImageFormat::decodeImage (InputStream& in) +Image JPEGImageFormat::decodeImage (InputStream& in) { #if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER return juce_loadWithCoreImage (in); @@ -243330,10 +243351,7 @@ namespace PNGHelpers PNGImageFormat::PNGImageFormat() {} PNGImageFormat::~PNGImageFormat() {} -const String PNGImageFormat::getFormatName() -{ - return "PNG"; -} +String PNGImageFormat::getFormatName() { return "PNG"; } bool PNGImageFormat::canUnderstand (InputStream& in) { @@ -243347,10 +243365,10 @@ bool PNGImageFormat::canUnderstand (InputStream& in) } #if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER - const Image juce_loadWithCoreImage (InputStream& input); + Image juce_loadWithCoreImage (InputStream& input); #endif -const Image PNGImageFormat::decodeImage (InputStream& in) +Image PNGImageFormat::decodeImage (InputStream& in) { #if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER return juce_loadWithCoreImage (in); @@ -244593,7 +244611,7 @@ namespace WindowsFileHelpers return GetDriveType (getDriveFromPath (path).toWideCharPointer()); } - const File getSpecialFolderPath (int type) + File getSpecialFolderPath (int type) { WCHAR path [MAX_PATH + 256]; @@ -244603,7 +244621,7 @@ namespace WindowsFileHelpers return File::nonexistent; } - const Result getResultForLastError() + Result getResultForLastError() { TCHAR messageBuffer [256] = { 0 }; @@ -244708,7 +244726,7 @@ bool File::moveInternal (const File& dest) const return MoveFile (fullPath.toWideCharPointer(), dest.getFullPathName().toWideCharPointer()) != 0; } -const Result File::createDirectoryInternal (const String& fileName) const +Result File::createDirectoryInternal (const String& fileName) const { return CreateDirectory (fileName.toWideCharPointer(), 0) ? Result::ok() : WindowsFileHelpers::getResultForLastError(); @@ -244925,7 +244943,7 @@ void File::findFileSystemRoots (Array& destArray) destArray.add (roots [i]); } -const String File::getVolumeLabel() const +String File::getVolumeLabel() const { TCHAR dest[64]; if (! GetVolumeInformation (WindowsFileHelpers::getDriveFromPath (getFullPathName()).toWideCharPointer(), dest, @@ -244988,7 +245006,7 @@ bool File::isOnRemovableDrive() const || n == DRIVE_RAMDISK; } -const File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType type) +File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType type) { int csidlType = 0; @@ -245039,7 +245057,7 @@ const File JUCE_CALLTYPE File::getSpecialLocation (const SpecialLocationType typ return WindowsFileHelpers::getSpecialFolderPath (csidlType); } -const File File::getCurrentWorkingDirectory() +File File::getCurrentWorkingDirectory() { WCHAR dest [MAX_PATH + 256]; dest[0] = 0; @@ -245052,7 +245070,7 @@ bool File::setAsCurrentWorkingDirectory() const return SetCurrentDirectory (getFullPathName().toWideCharPointer()) != FALSE; } -const String File::getVersion() const +String File::getVersion() const { String result; @@ -245078,7 +245096,7 @@ const String File::getVersion() const return result; } -const File File::getLinkedTarget() const +File File::getLinkedTarget() const { File result (*this); String p (getFullPathName()); @@ -245632,14 +245650,18 @@ private: if (sessionHandle != 0) { // break up the url.. - TCHAR file[1024], server[1024]; + TCHAR file[1024], server[1024], username[1024], password[1024]; URL_COMPONENTS uc = { 0 }; uc.dwStructSize = sizeof (uc); - uc.dwUrlPathLength = sizeof (file); - uc.dwHostNameLength = sizeof (server); uc.lpszUrlPath = file; + uc.dwUrlPathLength = numElementsInArray (file); uc.lpszHostName = server; + uc.dwHostNameLength = numElementsInArray (server); + uc.lpszUserName = username; + uc.dwUserNameLength = numElementsInArray (username); + uc.lpszPassword = password; + uc.dwPasswordLength = numElementsInArray (password); if (InternetCrackUrl (address.toWideCharPointer(), 0, 0, &uc)) { @@ -245670,7 +245692,7 @@ private: } #else connection = InternetConnect (sessionHandle, uc.lpszHostName, uc.nPort, - _T(""), _T(""), + uc.lpszUserName, uc.lpszPassword, isFtp ? INTERNET_SERVICE_FTP : INTERNET_SERVICE_HTTP, 0, 0); @@ -246405,7 +246427,7 @@ static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW*, int t return 1; } -const StringArray Font::findAllTypefaceNames() +StringArray Font::findAllTypefaceNames() { StringArray results; HDC dc = CreateCompatibleDC (0); @@ -246995,7 +247017,7 @@ public: currentState->setFont (newFont); } - const Font getFont() + Font getFont() { return currentState->font; } @@ -247906,7 +247928,7 @@ private: namespace IconConverters { - const Image createImageFromHBITMAP (HBITMAP bitmap) + Image createImageFromHBITMAP (HBITMAP bitmap) { Image im; @@ -247945,7 +247967,7 @@ namespace IconConverters return im; } - const Image createImageFromHICON (HICON icon) + Image createImageFromHICON (HICON icon) { ICONINFO info; @@ -250465,7 +250487,7 @@ void Desktop::getCurrentMonitorPositions (Array >& monitorCoords } } -const Image juce_createIconForFile (const File& file) +Image juce_createIconForFile (const File& file) { Image image; WORD iconNum = 0; @@ -251146,7 +251168,7 @@ void SystemClipboard::copyTextToClipboard (const String& text) } } -const String SystemClipboard::getTextFromClipboard() +String SystemClipboard::getTextFromClipboard() { String result; @@ -260318,7 +260340,7 @@ void JUCE_CALLTYPE Thread::sleep (int millisecs) const juce_wchar File::separator = '/'; const String File::separatorString ("/"); -const File File::getCurrentWorkingDirectory() +File File::getCurrentWorkingDirectory() { HeapBlock heapBuffer; @@ -260391,12 +260413,12 @@ namespace *isReadOnly = access (path.toUTF8(), W_OK) != 0; } - const Result getResultForErrno() + Result getResultForErrno() { return Result::fail (String (strerror (errno))); } - const Result getResultForReturnValue (int value) + Result getResultForReturnValue (int value) { return value == -1 ? getResultForErrno() : Result::ok(); } @@ -260519,7 +260541,7 @@ bool File::moveInternal (const File& dest) const return false; } -const Result File::createDirectoryInternal (const String& fileName) const +Result File::createDirectoryInternal (const String& fileName) const { return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777)); } @@ -260673,7 +260695,7 @@ MemoryMappedFile::~MemoryMappedFile() close (fileHandle); } -const File juce_getExecutableFile() +File juce_getExecutableFile() { #if JUCE_ANDROID return File (android.appFile); @@ -260702,7 +260724,7 @@ int64 File::getVolumeTotalSize() const return 0; } -const String File::getVolumeLabel() const +String File::getVolumeLabel() const { #if JUCE_MAC struct VolAttrBuf @@ -261095,7 +261117,7 @@ bool File::isHidden() const namespace { - const File juce_readlink (const String& file, const File& defaultFile) + File juce_readlink (const String& file, const File& defaultFile) { const int size = 8192; HeapBlock buffer; @@ -261110,14 +261132,14 @@ namespace } } -const File File::getLinkedTarget() const +File File::getLinkedTarget() const { return juce_readlink (getFullPathName().toUTF8(), *this); } const char* juce_Argv0 = nullptr; // referenced from juce_Application.cpp -const File File::getSpecialLocation (const SpecialLocationType type) +File File::getSpecialLocation (const SpecialLocationType type) { switch (type) { @@ -261185,7 +261207,7 @@ const File File::getSpecialLocation (const SpecialLocationType type) return File::nonexistent; } -const String File::getVersion() const +String File::getVersion() const { return String::empty; // xxx not yet implemented } @@ -261831,11 +261853,11 @@ private: return String::empty; } - static const MemoryBlock createRequestHeader (const String& hostName, const int hostPort, - const String& proxyName, const int proxyPort, - const String& hostPath, const String& originalURL, - const String& headers, const MemoryBlock& postData, - const bool isPost) + static MemoryBlock createRequestHeader (const String& hostName, const int hostPort, + const String& proxyName, const int proxyPort, + const String& hostPath, const String& originalURL, + const String& headers, const MemoryBlock& postData, + const bool isPost) { String header (isPost ? "POST " : "GET "); @@ -261973,12 +261995,12 @@ const String SystemStats::getOperatingSystemName() bool SystemStats::isOperatingSystem64Bit() { -#if JUCE_64BIT + #if JUCE_64BIT return true; -#else + #else //xxx not sure how to find this out?.. return false; -#endif + #endif } namespace LinuxStatsHelpers @@ -262052,9 +262074,9 @@ const String SystemStats::getComputerName() SystemStats::CPUFlags::CPUFlags() { const String flags (LinuxStatsHelpers::getCpuInfo ("flags")); - hasMMX = flags.contains ("mmx"); - hasSSE = flags.contains ("sse"); - hasSSE2 = flags.contains ("sse2"); + hasMMX = flags.contains ("mmx"); + hasSSE = flags.contains ("sse"); + hasSSE2 = flags.contains ("sse2"); has3DNow = flags.contains ("3dnow"); numCpus = LinuxStatsHelpers::getCpuInfo ("processor").getIntValue() + 1; @@ -262387,7 +262409,7 @@ void SystemClipboard::copyTextToClipboard (const String& clipText) XSetSelectionOwner (display, ClipboardHelpers::atom_CLIPBOARD, juce_messageWindowHandle, CurrentTime); } -const String SystemClipboard::getTextFromClipboard() +String SystemClipboard::getTextFromClipboard() { ClipboardHelpers::initSelectionAtoms(); @@ -263360,7 +263382,7 @@ const Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) return new FreetypeTypeface (font); } -const StringArray Font::findAllTypefaceNames() +StringArray Font::findAllTypefaceNames() { StringArray s; FreeTypeInterface::getInstance()->getFamilyNames (s); @@ -264049,11 +264071,11 @@ public: } // blit results to screen. -#if JUCE_USE_XSHM + #if JUCE_USE_XSHM if (usingXShm) XShmPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh, True); else -#endif + #endif XPutImage (display, (::Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh); } @@ -264064,13 +264086,12 @@ private: HeapBlock imageData16Bit; int pixelStride, lineStride; uint8* imageData; - GC gc; -#if JUCE_USE_XSHM + #if JUCE_USE_XSHM XShmSegmentInfo segmentInfo; bool usingXShm; -#endif + #endif static int getShiftNeeded (const uint32 mask) noexcept { @@ -266447,7 +266468,7 @@ void MouseCursor::showInAllWindows() const showInWindow (ComponentPeer::getPeer (i)); } -const Image juce_createIconForFile (const File& file) +Image juce_createIconForFile (const File& file) { return Image::null; } @@ -268211,10 +268232,6 @@ public: { } - ~JackAudioIODeviceType() - { - } - void scanForDevices() { hasScanned = true; @@ -269252,25 +269269,25 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s) void SystemClipboard::copyTextToClipboard (const String& text) { -#if JUCE_IOS + #if JUCE_IOS [[UIPasteboard generalPasteboard] setValue: juceStringToNS (text) forPasteboardType: @"public.text"]; -#else + #else [[NSPasteboard generalPasteboard] declareTypes: [NSArray arrayWithObject: NSStringPboardType] owner: nil]; [[NSPasteboard generalPasteboard] setString: juceStringToNS (text) forType: NSStringPboardType]; -#endif + #endif } -const String SystemClipboard::getTextFromClipboard() +String SystemClipboard::getTextFromClipboard() { -#if JUCE_IOS + #if JUCE_IOS NSString* text = [[UIPasteboard generalPasteboard] valueForPasteboardType: @"public.text"]; -#else + #else NSString* text = [[NSPasteboard generalPasteboard] stringForType: NSStringPboardType]; -#endif + #endif return text == nil ? String::empty : nsStringToJuce (text); @@ -270361,7 +270378,7 @@ void JUCE_CALLTYPE Thread::sleep (int millisecs) const juce_wchar File::separator = '/'; const String File::separatorString ("/"); -const File File::getCurrentWorkingDirectory() +File File::getCurrentWorkingDirectory() { HeapBlock heapBuffer; @@ -270434,12 +270451,12 @@ namespace *isReadOnly = access (path.toUTF8(), W_OK) != 0; } - const Result getResultForErrno() + Result getResultForErrno() { return Result::fail (String (strerror (errno))); } - const Result getResultForReturnValue (int value) + Result getResultForReturnValue (int value) { return value == -1 ? getResultForErrno() : Result::ok(); } @@ -270562,7 +270579,7 @@ bool File::moveInternal (const File& dest) const return false; } -const Result File::createDirectoryInternal (const String& fileName) const +Result File::createDirectoryInternal (const String& fileName) const { return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777)); } @@ -270716,7 +270733,7 @@ MemoryMappedFile::~MemoryMappedFile() close (fileHandle); } -const File juce_getExecutableFile() +File juce_getExecutableFile() { #if JUCE_ANDROID return File (android.appFile); @@ -270745,7 +270762,7 @@ int64 File::getVolumeTotalSize() const return 0; } -const String File::getVolumeLabel() const +String File::getVolumeLabel() const { #if JUCE_MAC struct VolAttrBuf @@ -271194,7 +271211,7 @@ bool File::isHidden() const const char* juce_Argv0 = nullptr; // referenced from juce_Application.cpp -const File File::getSpecialLocation (const SpecialLocationType type) +File File::getSpecialLocation (const SpecialLocationType type) { JUCE_AUTORELEASEPOOL String resultPath; @@ -271275,7 +271292,7 @@ const File File::getSpecialLocation (const SpecialLocationType type) return File::nonexistent; } -const String File::getVersion() const +String File::getVersion() const { JUCE_AUTORELEASEPOOL String result; @@ -271298,7 +271315,7 @@ const String File::getVersion() const return result; } -const File File::getLinkedTarget() const +File File::getLinkedTarget() const { #if JUCE_IOS || (defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_ALLOWED >= MAC_OS_X_VERSION_10_5) NSString* dest = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath: juceStringToNS (getFullPathName()) error: nil]; @@ -272831,7 +272848,7 @@ const Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) return new MacTypeface (font); } -const StringArray Font::findAllTypefaceNames() +StringArray Font::findAllTypefaceNames() { StringArray names; @@ -273447,7 +273464,7 @@ public: } } - const Font getFont() + Font getFont() { return state->font; } @@ -273680,7 +273697,7 @@ LowLevelGraphicsContext* CoreGraphicsImage::createLowLevelContext() } #if USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER -const Image juce_loadWithCoreImage (InputStream& input) +Image juce_loadWithCoreImage (InputStream& input) { MemoryBlock data; input.readIntoMemoryBlock (data, -1); @@ -274701,7 +274718,7 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) return new UIViewComponentPeer (this, styleFlags, (UIView*) windowToAttachTo); } -const Image juce_createIconForFile (const File& file) +Image juce_createIconForFile (const File& file) { return Image::null; } @@ -277871,7 +277888,7 @@ const Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) return new MacTypeface (font); } -const StringArray Font::findAllTypefaceNames() +StringArray Font::findAllTypefaceNames() { StringArray names; @@ -278487,7 +278504,7 @@ public: } } - const Font getFont() + Font getFont() { return state->font; } @@ -278720,7 +278737,7 @@ LowLevelGraphicsContext* CoreGraphicsImage::createLowLevelContext() } #if USE_COREGRAPHICS_RENDERING && ! DONT_USE_COREIMAGE_LOADER -const Image juce_loadWithCoreImage (InputStream& input) +Image juce_loadWithCoreImage (InputStream& input) { MemoryBlock data; input.readIntoMemoryBlock (data, -1); @@ -280432,7 +280449,7 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) return new NSViewComponentPeer (this, styleFlags, (NSView*) windowToAttachTo); } -const Image juce_createIconForFile (const File& file) +Image juce_createIconForFile (const File& file) { JUCE_AUTORELEASEPOOL @@ -286900,7 +286917,7 @@ void SystemClipboard::copyTextToClipboard (const String& text) android.activity.callVoidMethod (android.setClipboardContent, t.get()); } -const String SystemClipboard::getTextFromClipboard() +String SystemClipboard::getTextFromClipboard() { const LocalRef text ((jstring) android.activity.callObjectMethod (android.getClipboardContent)); return juceString (text); @@ -287220,7 +287237,7 @@ void JUCE_CALLTYPE Thread::sleep (int millisecs) const juce_wchar File::separator = '/'; const String File::separatorString ("/"); -const File File::getCurrentWorkingDirectory() +File File::getCurrentWorkingDirectory() { HeapBlock heapBuffer; @@ -287293,12 +287310,12 @@ namespace *isReadOnly = access (path.toUTF8(), W_OK) != 0; } - const Result getResultForErrno() + Result getResultForErrno() { return Result::fail (String (strerror (errno))); } - const Result getResultForReturnValue (int value) + Result getResultForReturnValue (int value) { return value == -1 ? getResultForErrno() : Result::ok(); } @@ -287421,7 +287438,7 @@ bool File::moveInternal (const File& dest) const return false; } -const Result File::createDirectoryInternal (const String& fileName) const +Result File::createDirectoryInternal (const String& fileName) const { return getResultForReturnValue (mkdir (fileName.toUTF8(), 0777)); } @@ -287575,7 +287592,7 @@ MemoryMappedFile::~MemoryMappedFile() close (fileHandle); } -const File juce_getExecutableFile() +File juce_getExecutableFile() { #if JUCE_ANDROID return File (android.appFile); @@ -287604,7 +287621,7 @@ int64 File::getVolumeTotalSize() const return 0; } -const String File::getVolumeLabel() const +String File::getVolumeLabel() const { #if JUCE_MAC struct VolAttrBuf @@ -287964,7 +287981,7 @@ bool File::isHidden() const namespace { - const File juce_readlink (const String& file, const File& defaultFile) + File juce_readlink (const String& file, const File& defaultFile) { const int size = 8192; HeapBlock buffer; @@ -287979,12 +287996,12 @@ namespace } } -const File File::getLinkedTarget() const +File File::getLinkedTarget() const { return juce_readlink (getFullPathName().toUTF8(), *this); } -const File File::getSpecialLocation (const SpecialLocationType type) +File File::getSpecialLocation (const SpecialLocationType type) { switch (type) { @@ -288020,7 +288037,7 @@ const File File::getSpecialLocation (const SpecialLocationType type) return File::nonexistent; } -const String File::getVersion() const +String File::getVersion() const { return String::empty; } @@ -288614,7 +288631,7 @@ void MessageManager::stopDispatchLoop() // compiled on its own). #if JUCE_INCLUDED_FILE -const StringArray Font::findAllTypefaceNames() +StringArray Font::findAllTypefaceNames() { StringArray results; @@ -289160,7 +289177,7 @@ public: } } - const Font getFont() + Font getFont() { return currentState->font; } @@ -290187,7 +290204,7 @@ JUCE_JNI_CALLBACK (JuceAppActivity, setScreenSize, void, (JNIEnv* env, jobject a Desktop::getInstance().refreshMonitorSizes(); } -const Image juce_createIconForFile (const File& file) +Image juce_createIconForFile (const File& file) { return Image::null; } diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 734f056a65..04b3a3b992 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 94 +#define JUCE_BUILDNUMBER 95 /** Current Juce version number. @@ -4305,7 +4305,7 @@ public: String (const CharPointer_ASCII& text); /** Creates a string from a single character. */ - static const String charToString (juce_wchar character); + static String charToString (juce_wchar character); /** Destructor. */ ~String() noexcept; @@ -4736,7 +4736,7 @@ public: this index are returned @see fromFirstOccurrenceOf, dropLastCharacters, getLastCharacters, upToFirstOccurrenceOf */ - const String substring (int startIndex, int endIndex) const; + String substring (int startIndex, int endIndex) const; /** Returns a section of the string, starting from a given position. @@ -4746,7 +4746,7 @@ public: @returns the substring from startIndex up to the end of the string @see dropLastCharacters, getLastCharacters, fromFirstOccurrenceOf, upToFirstOccurrenceOf, fromLastOccurrenceOf */ - const String substring (int startIndex) const; + String substring (int startIndex) const; /** Returns a version of this string with a number of characters removed from the end. @@ -4757,7 +4757,7 @@ public: original string will be returned. @see substring, fromFirstOccurrenceOf, upToFirstOccurrenceOf, fromLastOccurrenceOf, getLastCharacter */ - const String dropLastCharacters (int numberToDrop) const; + String dropLastCharacters (int numberToDrop) const; /** Returns a number of characters from the end of the string. @@ -4766,7 +4766,7 @@ public: @see substring, dropLastCharacters, getLastCharacter */ - const String getLastCharacters (int numCharacters) const; + String getLastCharacters (int numCharacters) const; /** Returns a section of the string starting from a given substring. @@ -4783,8 +4783,8 @@ public: @see upToFirstOccurrenceOf, fromLastOccurrenceOf */ - const String fromFirstOccurrenceOf (const String& substringToStartFrom, - bool includeSubStringInResult, + String fromFirstOccurrenceOf (const String& substringToStartFrom, + bool includeSubStringInResult, bool ignoreCase) const; /** Returns a section of the string starting from the last occurrence of a given substring. @@ -4795,9 +4795,9 @@ public: @see fromFirstOccurrenceOf, upToLastOccurrenceOf */ - const String fromLastOccurrenceOf (const String& substringToFind, - bool includeSubStringInResult, - bool ignoreCase) const; + String fromLastOccurrenceOf (const String& substringToFind, + bool includeSubStringInResult, + bool ignoreCase) const; /** Returns the start of this string, up to the first occurrence of a substring. @@ -4812,9 +4812,9 @@ public: @see upToLastOccurrenceOf, fromFirstOccurrenceOf */ - const String upToFirstOccurrenceOf (const String& substringToEndWith, - bool includeSubStringInResult, - bool ignoreCase) const; + String upToFirstOccurrenceOf (const String& substringToEndWith, + bool includeSubStringInResult, + bool ignoreCase) const; /** Returns the start of this string, up to the last occurrence of a substring. @@ -4823,18 +4823,18 @@ public: @see upToFirstOccurrenceOf, fromFirstOccurrenceOf */ - const String upToLastOccurrenceOf (const String& substringToFind, - bool includeSubStringInResult, - bool ignoreCase) const; + String upToLastOccurrenceOf (const String& substringToFind, + bool includeSubStringInResult, + bool ignoreCase) const; /** Returns a copy of this string with any whitespace characters removed from the start and end. */ - const String trim() const; + String trim() const; /** Returns a copy of this string with any whitespace characters removed from the start. */ - const String trimStart() const; + String trimStart() const; /** Returns a copy of this string with any whitespace characters removed from the end. */ - const String trimEnd() const; + String trimEnd() const; /** Returns a copy of this string, having removed a specified set of characters from its start. Characters are removed from the start of the string until it finds one that is not in the @@ -4842,7 +4842,7 @@ public: @param charactersToTrim the set of characters to remove. @see trim, trimStart, trimCharactersAtEnd */ - const String trimCharactersAtStart (const String& charactersToTrim) const; + String trimCharactersAtStart (const String& charactersToTrim) const; /** Returns a copy of this string, having removed a specified set of characters from its end. Characters are removed from the end of the string until it finds one that is not in the @@ -4850,13 +4850,13 @@ public: @param charactersToTrim the set of characters to remove. @see trim, trimEnd, trimCharactersAtStart */ - const String trimCharactersAtEnd (const String& charactersToTrim) const; + String trimCharactersAtEnd (const String& charactersToTrim) const; /** Returns an upper-case version of this string. */ - const String toUpperCase() const; + String toUpperCase() const; /** Returns an lower-case version of this string. */ - const String toLowerCase() const; + String toLowerCase() const; /** Replaces a sub-section of the string with another string. @@ -4873,9 +4873,9 @@ public: @param stringToInsert the new string to insert at startIndex after the characters have been removed. */ - const String replaceSection (int startIndex, - int numCharactersToReplace, - const String& stringToInsert) const; + String replaceSection (int startIndex, + int numCharactersToReplace, + const String& stringToInsert) const; /** Replaces all occurrences of a substring with another string. @@ -4884,13 +4884,13 @@ public: Note that this is a const method, and won't alter the string itself. */ - const String replace (const String& stringToReplace, - const String& stringToInsertInstead, - bool ignoreCase = false) const; + String replace (const String& stringToReplace, + const String& stringToInsertInstead, + bool ignoreCase = false) const; /** Returns a string with all occurrences of a character replaced with a different one. */ - const String replaceCharacter (juce_wchar characterToReplace, - juce_wchar characterToInsertInstead) const; + String replaceCharacter (juce_wchar characterToReplace, + juce_wchar characterToInsertInstead) const; /** Replaces a set of characters with another set. @@ -4902,8 +4902,8 @@ public: Note that this is a const method, and won't affect the string itself. */ - const String replaceCharacters (const String& charactersToReplace, - const String& charactersToInsertInstead) const; + String replaceCharacters (const String& charactersToReplace, + const String& charactersToInsertInstead) const; /** Returns a version of this string that only retains a fixed set of characters. @@ -4914,7 +4914,7 @@ public: Note that this is a const method, and won't alter the string itself. */ - const String retainCharacters (const String& charactersToRetain) const; + String retainCharacters (const String& charactersToRetain) const; /** Returns a version of this string with a set of characters removed. @@ -4925,14 +4925,14 @@ public: Note that this is a const method, and won't alter the string itself. */ - const String removeCharacters (const String& charactersToRemove) const; + String removeCharacters (const String& charactersToRemove) const; /** Returns a section from the start of the string that only contains a certain set of characters. This returns the leftmost section of the string, up to (and not including) the first character that doesn't appear in the string passed in. */ - const String initialSectionContainingOnly (const String& permittedCharacters) const; + String initialSectionContainingOnly (const String& permittedCharacters) const; /** Returns a section from the start of the string that only contains a certain set of characters. @@ -4940,7 +4940,7 @@ public: first character that occurs in the string passed in. (If none of the specified characters are found in the string, the return value will just be the original string). */ - const String initialSectionNotContaining (const String& charactersToStopAt) const; + String initialSectionNotContaining (const String& charactersToStopAt) const; /** Checks whether the string might be in quotation marks. @@ -4960,7 +4960,7 @@ public: @see isQuotedString, quoted */ - const String unquoted() const; + String unquoted() const; /** Adds quotation marks around a string. @@ -4973,25 +4973,25 @@ public: @param quoteCharacter the character to add at the start and end @see isQuotedString, unquoted */ - const String quoted (juce_wchar quoteCharacter = '"') const; + String quoted (juce_wchar quoteCharacter = '"') const; /** Creates a string which is a version of a string repeated and joined together. @param stringToRepeat the string to repeat @param numberOfTimesToRepeat how many times to repeat it */ - static const String repeatedString (const String& stringToRepeat, - int numberOfTimesToRepeat); + static String repeatedString (const String& stringToRepeat, + int numberOfTimesToRepeat); /** Returns a copy of this string with the specified character repeatedly added to its beginning until the total length is at least the minimum length specified. */ - const String paddedLeft (juce_wchar padCharacter, int minimumLength) const; + String paddedLeft (juce_wchar padCharacter, int minimumLength) const; /** Returns a copy of this string with the specified character repeatedly added to its end until the total length is at least the minimum length specified. */ - const String paddedRight (juce_wchar padCharacter, int minimumLength) const; + String paddedRight (juce_wchar padCharacter, int minimumLength) const; /** Creates a string from data in an unknown format. @@ -5001,7 +5001,7 @@ public: Should be able to handle Unicode endianness correctly, by looking at the first two bytes. */ - static const String createStringFromData (const void* data, int size); + static String createStringFromData (const void* data, int size); /** Creates a String from a printf-style parameter list. @@ -5014,7 +5014,7 @@ 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 const String formatted (const String formatString, ... ); + static String formatted (const String formatString, ... ); // Numeric conversions.. @@ -5138,13 +5138,13 @@ public: int64 getHexValue64() const noexcept; /** Creates a string representing this 32-bit value in hexadecimal. */ - static const String toHexString (int number); + static String toHexString (int number); /** Creates a string representing this 64-bit value in hexadecimal. */ - static const String toHexString (int64 number); + static String toHexString (int64 number); /** Creates a string representing this 16-bit value in hexadecimal. */ - static const String toHexString (short number); + static String toHexString (short number); /** Creates a string containing a hex dump of a block of binary data. @@ -5155,9 +5155,7 @@ public: group size 1 looks like: "be a1 c2 ff", group size 2 looks like "bea1 c2ff". */ - static const String toHexString (const unsigned char* data, - int size, - int groupSize = 1); + static String toHexString (const void* data, int size, int groupSize = 1); /** Returns the character pointer currently being used to store this string. @@ -5220,7 +5218,7 @@ public: /** Creates a String from a UTF-8 encoded buffer. If the size is < 0, it'll keep reading until it hits a zero. */ - static const String fromUTF8 (const char* utf8buffer, int bufferSizeBytes = -1); + static String fromUTF8 (const char* utf8buffer, int bufferSizeBytes = -1); /** Returns the number of bytes required to represent this string as UTF8. The number returned does NOT include the trailing zero. @@ -5346,31 +5344,31 @@ private: }; /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (const char* string1, const String& string2); +JUCE_API String JUCE_CALLTYPE operator+ (const char* string1, const String& string2); /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (const wchar_t* string1, const String& string2); +JUCE_API String JUCE_CALLTYPE operator+ (const wchar_t* string1, const String& string2); /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (char string1, const String& string2); +JUCE_API String JUCE_CALLTYPE operator+ (char string1, const String& string2); /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (wchar_t string1, const String& string2); +JUCE_API String JUCE_CALLTYPE operator+ (wchar_t string1, const String& string2); #if ! JUCE_NATIVE_WCHAR_IS_UTF32 /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (juce_wchar string1, const String& string2); +JUCE_API String JUCE_CALLTYPE operator+ (juce_wchar string1, const String& string2); #endif /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const String& string2); +JUCE_API String JUCE_CALLTYPE operator+ (String string1, const String& string2); /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const char* string2); +JUCE_API String JUCE_CALLTYPE operator+ (String string1, const char* string2); /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2); +JUCE_API String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2); /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); +JUCE_API String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend); +JUCE_API String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend); #if ! JUCE_NATIVE_WCHAR_IS_UTF32 /** Concatenates two strings. */ -JUCE_API const String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); +JUCE_API String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); #endif /** Appends a character at the end of a string. */ @@ -7840,68 +7838,7 @@ private: #ifndef __JUCE_IDENTIFIER_JUCEHEADER__ #define __JUCE_IDENTIFIER_JUCEHEADER__ - -/*** Start of inlined file: juce_StringPool.h ***/ -#ifndef __JUCE_STRINGPOOL_JUCEHEADER__ -#define __JUCE_STRINGPOOL_JUCEHEADER__ - -/** - A StringPool holds a set of shared strings, which reduces storage overheads and improves - comparison speed when dealing with many duplicate strings. - - When you add a string to a pool using getPooledString, it'll return a character - array containing the same string. This array is owned by the pool, and the same array - is returned every time a matching string is asked for. This means that it's trivial to - compare two pooled strings for equality, as you can simply compare their pointers. It - also cuts down on storage if you're using many copies of the same string. -*/ -class JUCE_API StringPool -{ -public: - - /** Creates an empty pool. */ - StringPool() noexcept; - - /** Destructor */ - ~StringPool(); - - /** Returns a pointer to a copy of the string that is passed in. - - The pool will always return the same pointer when asked for a string that matches it. - The pool will own all the pointers that it returns, deleting them when the pool itself - is deleted. - */ - const String::CharPointerType getPooledString (const String& original); - - /** Returns a pointer to a copy of the string that is passed in. - - The pool will always return the same pointer when asked for a string that matches it. - The pool will own all the pointers that it returns, deleting them when the pool itself - is deleted. - */ - const String::CharPointerType getPooledString (const char* original); - - /** Returns a pointer to a copy of the string that is passed in. - - The pool will always return the same pointer when asked for a string that matches it. - The pool will own all the pointers that it returns, deleting them when the pool itself - is deleted. - */ - const String::CharPointerType getPooledString (const wchar_t* original); - - /** Returns the number of strings in the pool. */ - int size() const noexcept; - - /** Returns one of the strings in the pool, by index. */ - const String::CharPointerType operator[] (int index) const noexcept; - -private: - Array strings; -}; - -#endif // __JUCE_STRINGPOOL_JUCEHEADER__ - -/*** End of inlined file: juce_StringPool.h ***/ +class StringPool; /** Represents a string identifier, designed for accessing properties by name. @@ -7946,7 +7883,7 @@ public: inline bool operator!= (const Identifier& other) const noexcept { return name != other.name; } /** Returns this identifier as a string. */ - const String toString() const { return name; } + String toString() const { return name; } /** Returns this identifier's raw string pointer. */ operator const String::CharPointerType() const noexcept { return name; } @@ -7999,7 +7936,7 @@ public: /** Returns the default new-line sequence that the library uses. @see getDefault() */ - operator const String() const { return getDefault(); } + operator String() const { return getDefault(); } }; /** A predefined object representing a new-line, which can be written to a string or stream. @@ -8023,214 +7960,233 @@ JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&); /*** End of inlined file: juce_NewLine.h ***/ - -/*** Start of inlined file: juce_InputStream.h ***/ -#ifndef __JUCE_INPUTSTREAM_JUCEHEADER__ -#define __JUCE_INPUTSTREAM_JUCEHEADER__ - - -/*** Start of inlined file: juce_MemoryBlock.h ***/ -#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ -#define __JUCE_MEMORYBLOCK_JUCEHEADER__ +class InputStream; +class MemoryBlock; +class File; /** - A class to hold a resizable block of raw data. + The base class for streams that write data to some kind of destination. + + Input and output streams are used throughout the library - subclasses can override + some or all of the virtual functions to implement their behaviour. + @see InputStream, MemoryOutputStream, FileOutputStream */ -class JUCE_API MemoryBlock +class JUCE_API OutputStream { -public: +protected: - /** Create an uninitialised block with 0 size. */ - MemoryBlock() noexcept; + OutputStream(); - /** Creates a memory block with a given initial size. +public: + /** Destructor. - @param initialSize the size of block to create - @param initialiseToZero whether to clear the memory or just leave it uninitialised + Some subclasses might want to do things like call flush() during their + destructors. */ - MemoryBlock (const size_t initialSize, - bool initialiseToZero = false); + virtual ~OutputStream(); - /** Creates a copy of another memory block. */ - MemoryBlock (const MemoryBlock& other); + /** If the stream is using a buffer, this will ensure it gets written + out to the destination. */ + virtual void flush() = 0; - /** Creates a memory block using a copy of a block of data. + /** Tries to move the stream's output position. - @param dataToInitialiseFrom some data to copy into this block - @param sizeInBytes how much space to use - */ - MemoryBlock (const void* dataToInitialiseFrom, size_t sizeInBytes); + Not all streams will be able to seek to a new position - this will return + false if it fails to work. - /** Destructor. */ - ~MemoryBlock() noexcept; + @see getPosition + */ + virtual bool setPosition (int64 newPosition) = 0; - /** Copies another memory block onto this one. + /** Returns the stream's current position. - This block will be resized and copied to exactly match the other one. + @see setPosition */ - MemoryBlock& operator= (const MemoryBlock& other); + virtual int64 getPosition() = 0; - /** Compares two memory blocks. + /** Writes a block of data to the stream. - @returns true only if the two blocks are the same size and have identical contents. + When creating a subclass of OutputStream, this is the only write method + that needs to be overloaded - the base class has methods for writing other + types of data which use this to do the work. + + @returns false if the write operation fails for some reason */ - bool operator== (const MemoryBlock& other) const noexcept; + virtual bool write (const void* dataToWrite, + int howManyBytes) = 0; - /** Compares two memory blocks. + /** Writes a single byte to the stream. - @returns true if the two blocks are different sizes or have different contents. + @see InputStream::readByte */ - bool operator!= (const MemoryBlock& other) const noexcept; + virtual void writeByte (char byte); - /** Returns true if the data in this MemoryBlock matches the raw bytes passed-in. + /** Writes a boolean to the stream as a single byte. + This is encoded as a binary byte (not as text) with a value of 1 or 0. + @see InputStream::readBool */ - bool matches (const void* data, size_t dataSize) const noexcept; + virtual void writeBool (bool boolValue); - /** Returns a void pointer to the data. + /** Writes a 16-bit integer to the stream in a little-endian byte order. + This will write two bytes to the stream: (value & 0xff), then (value >> 8). + @see InputStream::readShort + */ + virtual void writeShort (short value); - Note that the pointer returned will probably become invalid when the - block is resized. + /** Writes a 16-bit integer to the stream in a big-endian byte order. + This will write two bytes to the stream: (value >> 8), then (value & 0xff). + @see InputStream::readShortBigEndian */ - void* getData() const noexcept { return data; } + virtual void writeShortBigEndian (short value); - /** Returns a byte from the memory block. + /** Writes a 32-bit integer to the stream in a little-endian byte order. + @see InputStream::readInt + */ + virtual void writeInt (int value); - This returns a reference, so you can also use it to set a byte. + /** Writes a 32-bit integer to the stream in a big-endian byte order. + @see InputStream::readIntBigEndian */ - template - char& operator[] (const Type offset) const noexcept { return data [offset]; } + virtual void writeIntBigEndian (int value); - /** Returns the block's current allocated size, in bytes. */ - size_t getSize() const noexcept { return size; } + /** Writes a 64-bit integer to the stream in a little-endian byte order. + @see InputStream::readInt64 + */ + virtual void writeInt64 (int64 value); - /** Resizes the memory block. + /** Writes a 64-bit integer to the stream in a big-endian byte order. + @see InputStream::readInt64BigEndian + */ + virtual void writeInt64BigEndian (int64 value); - This will try to keep as much of the block's current content as it can, - and can optionally be made to clear any new space that gets allocated at - the end of the block. + /** Writes a 32-bit floating point value to the stream in a binary format. + The binary 32-bit encoding of the float is written as a little-endian int. + @see InputStream::readFloat + */ + virtual void writeFloat (float value); - @param newSize the new desired size for the block - @param initialiseNewSpaceToZero if the block gets enlarged, this determines - whether to clear the new section or just leave it - uninitialised - @see ensureSize + /** Writes a 32-bit floating point value to the stream in a binary format. + The binary 32-bit encoding of the float is written as a big-endian int. + @see InputStream::readFloatBigEndian */ - void setSize (const size_t newSize, - bool initialiseNewSpaceToZero = false); + virtual void writeFloatBigEndian (float value); - /** Increases the block's size only if it's smaller than a given size. + /** Writes a 64-bit floating point value to the stream in a binary format. + The eight raw bytes of the double value are written out as a little-endian 64-bit int. + @see InputStream::readDouble + */ + virtual void writeDouble (double value); - @param minimumSize if the block is already bigger than this size, no action - will be taken; otherwise it will be increased to this size - @param initialiseNewSpaceToZero if the block gets enlarged, this determines - whether to clear the new section or just leave it - uninitialised - @see setSize + /** Writes a 64-bit floating point value to the stream in a binary format. + The eight raw bytes of the double value are written out as a big-endian 64-bit int. + @see InputStream::readDoubleBigEndian */ - void ensureSize (const size_t minimumSize, - bool initialiseNewSpaceToZero = false); + virtual void writeDoubleBigEndian (double value); - /** Fills the entire memory block with a repeated byte value. + /** Writes a byte to the output stream a given number of times. */ + virtual void writeRepeatedByte (uint8 byte, int numTimesToRepeat); - This is handy for clearing a block of memory to zero. - */ - void fillWith (uint8 valueToUse) noexcept; + /** Writes a condensed binary encoding of a 32-bit integer. - /** Adds another block of data to the end of this one. + If you're storing a lot of integers which are unlikely to have very large values, + this can save a lot of space, because values under 0xff will only take up 2 bytes, + under 0xffff only 3 bytes, etc. - This block's size will be increased accordingly. - */ - void append (const void* data, size_t numBytes); + The format used is: number of significant bytes + up to 4 bytes in little-endian order. - /** Exchanges the contents of this and another memory block. - No actual copying is required for this, so it's very fast. + @see InputStream::readCompressedInt */ - void swapWith (MemoryBlock& other) noexcept; + virtual void writeCompressedInt (int value); - /** Copies data into this MemoryBlock from a memory address. + /** Stores a string in the stream in a binary format. - @param srcData the memory location of the data to copy into this block - @param destinationOffset the offset in this block at which the data being copied should begin - @param numBytes how much to copy in (if this goes beyond the size of the memory block, - it will be clipped so not to do anything nasty) - */ - void copyFrom (const void* srcData, - int destinationOffset, - size_t numBytes) noexcept; + This isn't the method to use if you're trying to append text to the end of a + text-file! It's intended for storing a string so that it can be retrieved later + by InputStream::readString(). - /** Copies data from this MemoryBlock to a memory address. + It writes the string to the stream as UTF8, including the null termination character. - @param destData the memory location to write to - @param sourceOffset the offset within this block from which the copied data will be read - @param numBytes how much to copy (if this extends beyond the limits of the memory block, - zeros will be used for that portion of the data) + For appending text to a file, instead use writeText, or operator<< + + @see InputStream::readString, writeText, operator<< */ - void copyTo (void* destData, - int sourceOffset, - size_t numBytes) const noexcept; + virtual void writeString (const String& text); - /** Chops out a section of the block. + /** Writes a string of text to the stream. - This will remove a section of the memory block and close the gap around it, - shifting any subsequent data downwards and reducing the size of the block. + It can either write the text as UTF-8 or UTF-16, and can also add the UTF-16 byte-order-mark + bytes (0xff, 0xfe) to indicate the endianness (these should only be used at the start + of a file). - If the range specified goes beyond the size of the block, it will be clipped. + The method also replaces '\\n' characters in the text with '\\r\\n'. */ - void removeSection (size_t startByte, size_t numBytesToRemove); - - /** Attempts to parse the contents of the block as a zero-terminated string of 8-bit - characters in the system's default encoding. */ - const String toString() const; + virtual void writeText (const String& text, + bool asUTF16, + bool writeUTF16ByteOrderMark); - /** Parses a string of hexadecimal numbers and writes this data into the memory block. + /** Reads data from an input stream and writes it to this stream. - The block will be resized to the number of valid bytes read from the string. - Non-hex characters in the string will be ignored. + @param source the stream to read from + @param maxNumBytesToWrite the number of bytes to read from the stream (if this is + less than zero, it will keep reading until the input + is exhausted) + */ + virtual int writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite); - @see String::toHexString() + /** Sets the string that will be written to the stream when the writeNewLine() + method is called. + By default this will be set the the value of NewLine::getDefault(). */ - void loadFromHexString (const String& sourceHexString); + void setNewLineString (const String& newLineString); - /** Sets a number of bits in the memory block, treating it as a long binary sequence. */ - void setBitRange (size_t bitRangeStart, - size_t numBits, - int binaryNumberToApply) noexcept; + /** Returns the current new-line string that was set by setNewLineString(). */ + const String& getNewLineString() const noexcept { return newLineString; } - /** Reads a number of bits from the memory block, treating it as one long binary sequence */ - int getBitRange (size_t bitRangeStart, - size_t numBitsToRead) const noexcept; +private: - /** Returns a string of characters that represent the binary contents of this block. + String newLineString; - Uses a 64-bit encoding system to allow binary data to be turned into a string - of simple non-extended characters, e.g. for storage in XML. + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OutputStream); +}; - @see fromBase64Encoding - */ - const String toBase64Encoding() const; +/** Writes a number to a stream as 8-bit characters in the default system encoding. */ +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, int number); - /** Takes a string of encoded characters and turns it into binary data. +/** Writes a number to a stream as 8-bit characters in the default system encoding. */ +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, double number); - The string passed in must have been created by to64BitEncoding(), and this - block will be resized to recreate the original data block. +/** Writes a character to a stream. */ +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, char character); - @see toBase64Encoding - */ - bool fromBase64Encoding (const String& encodedString); +/** Writes a null-terminated text string to a stream. */ +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const char* text); -private: +/** Writes a block of data from a MemoryBlock to a stream. */ +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& data); - HeapBlock data; - size_t size; - static const char* const encodingTable; +/** Writes the contents of a file to a stream. */ +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const File& fileToRead); - JUCE_LEAK_DETECTOR (MemoryBlock); -}; +/** Writes a new-line to a stream. + You can use the predefined symbol 'newLine' to invoke this, e.g. + @code + myOutputStream << "Hello World" << newLine << newLine; + @endcode + @see OutputStream::setNewLineString +*/ +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const NewLine&); -#endif // __JUCE_MEMORYBLOCK_JUCEHEADER__ +#endif // __JUCE_OUTPUTSTREAM_JUCEHEADER__ -/*** End of inlined file: juce_MemoryBlock.h ***/ +/*** End of inlined file: juce_OutputStream.h ***/ + + +/*** Start of inlined file: juce_InputStream.h ***/ +#ifndef __JUCE_INPUTSTREAM_JUCEHEADER__ +#define __JUCE_INPUTSTREAM_JUCEHEADER__ + +class MemoryBlock; /** The base class for streams that read data. @@ -8415,7 +8371,7 @@ public: following the line-feed, but the linefeeds aren't included in the string that is returned. */ - virtual const String readNextLine(); + virtual String readNextLine(); /** Reads a zero-terminated UTF8 string from the stream. @@ -8424,14 +8380,14 @@ public: @see OutputStream::writeString, readEntireStreamAsString */ - virtual const String readString(); + virtual String readString(); /** Tries to read the whole stream and turn it into a string. This will read from the stream's current position until the end-of-stream, and will try to make an educated guess about whether it's unicode or an 8-bit encoding. */ - virtual const String readEntireStreamAsString(); + virtual String readEntireStreamAsString(); /** Reads from the stream and appends the data to a MemoryBlock. @@ -8484,225 +8440,6 @@ private: /*** End of inlined file: juce_InputStream.h ***/ -class File; - -/** - The base class for streams that write data to some kind of destination. - - Input and output streams are used throughout the library - subclasses can override - some or all of the virtual functions to implement their behaviour. - - @see InputStream, MemoryOutputStream, FileOutputStream -*/ -class JUCE_API OutputStream -{ -protected: - - OutputStream(); - -public: - /** Destructor. - - Some subclasses might want to do things like call flush() during their - destructors. - */ - virtual ~OutputStream(); - - /** If the stream is using a buffer, this will ensure it gets written - out to the destination. */ - virtual void flush() = 0; - - /** Tries to move the stream's output position. - - Not all streams will be able to seek to a new position - this will return - false if it fails to work. - - @see getPosition - */ - virtual bool setPosition (int64 newPosition) = 0; - - /** Returns the stream's current position. - - @see setPosition - */ - virtual int64 getPosition() = 0; - - /** Writes a block of data to the stream. - - When creating a subclass of OutputStream, this is the only write method - that needs to be overloaded - the base class has methods for writing other - types of data which use this to do the work. - - @returns false if the write operation fails for some reason - */ - virtual bool write (const void* dataToWrite, - int howManyBytes) = 0; - - /** Writes a single byte to the stream. - - @see InputStream::readByte - */ - virtual void writeByte (char byte); - - /** Writes a boolean to the stream as a single byte. - This is encoded as a binary byte (not as text) with a value of 1 or 0. - @see InputStream::readBool - */ - virtual void writeBool (bool boolValue); - - /** Writes a 16-bit integer to the stream in a little-endian byte order. - This will write two bytes to the stream: (value & 0xff), then (value >> 8). - @see InputStream::readShort - */ - virtual void writeShort (short value); - - /** Writes a 16-bit integer to the stream in a big-endian byte order. - This will write two bytes to the stream: (value >> 8), then (value & 0xff). - @see InputStream::readShortBigEndian - */ - virtual void writeShortBigEndian (short value); - - /** Writes a 32-bit integer to the stream in a little-endian byte order. - @see InputStream::readInt - */ - virtual void writeInt (int value); - - /** Writes a 32-bit integer to the stream in a big-endian byte order. - @see InputStream::readIntBigEndian - */ - virtual void writeIntBigEndian (int value); - - /** Writes a 64-bit integer to the stream in a little-endian byte order. - @see InputStream::readInt64 - */ - virtual void writeInt64 (int64 value); - - /** Writes a 64-bit integer to the stream in a big-endian byte order. - @see InputStream::readInt64BigEndian - */ - virtual void writeInt64BigEndian (int64 value); - - /** Writes a 32-bit floating point value to the stream in a binary format. - The binary 32-bit encoding of the float is written as a little-endian int. - @see InputStream::readFloat - */ - virtual void writeFloat (float value); - - /** Writes a 32-bit floating point value to the stream in a binary format. - The binary 32-bit encoding of the float is written as a big-endian int. - @see InputStream::readFloatBigEndian - */ - virtual void writeFloatBigEndian (float value); - - /** Writes a 64-bit floating point value to the stream in a binary format. - The eight raw bytes of the double value are written out as a little-endian 64-bit int. - @see InputStream::readDouble - */ - virtual void writeDouble (double value); - - /** Writes a 64-bit floating point value to the stream in a binary format. - The eight raw bytes of the double value are written out as a big-endian 64-bit int. - @see InputStream::readDoubleBigEndian - */ - virtual void writeDoubleBigEndian (double value); - - /** Writes a byte to the output stream a given number of times. */ - virtual void writeRepeatedByte (uint8 byte, int numTimesToRepeat); - - /** Writes a condensed binary encoding of a 32-bit integer. - - If you're storing a lot of integers which are unlikely to have very large values, - this can save a lot of space, because values under 0xff will only take up 2 bytes, - under 0xffff only 3 bytes, etc. - - The format used is: number of significant bytes + up to 4 bytes in little-endian order. - - @see InputStream::readCompressedInt - */ - virtual void writeCompressedInt (int value); - - /** Stores a string in the stream in a binary format. - - This isn't the method to use if you're trying to append text to the end of a - text-file! It's intended for storing a string so that it can be retrieved later - by InputStream::readString(). - - It writes the string to the stream as UTF8, including the null termination character. - - For appending text to a file, instead use writeText, or operator<< - - @see InputStream::readString, writeText, operator<< - */ - virtual void writeString (const String& text); - - /** Writes a string of text to the stream. - - It can either write the text as UTF-8 or UTF-16, and can also add the UTF-16 byte-order-mark - bytes (0xff, 0xfe) to indicate the endianness (these should only be used at the start - of a file). - - The method also replaces '\\n' characters in the text with '\\r\\n'. - */ - virtual void writeText (const String& text, - bool asUTF16, - bool writeUTF16ByteOrderMark); - - /** Reads data from an input stream and writes it to this stream. - - @param source the stream to read from - @param maxNumBytesToWrite the number of bytes to read from the stream (if this is - less than zero, it will keep reading until the input - is exhausted) - */ - virtual int writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite); - - /** Sets the string that will be written to the stream when the writeNewLine() - method is called. - By default this will be set the the value of NewLine::getDefault(). - */ - void setNewLineString (const String& newLineString); - - /** Returns the current new-line string that was set by setNewLineString(). */ - const String& getNewLineString() const noexcept { return newLineString; } - -private: - - String newLineString; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OutputStream); -}; - -/** Writes a number to a stream as 8-bit characters in the default system encoding. */ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, int number); - -/** Writes a number to a stream as 8-bit characters in the default system encoding. */ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, double number); - -/** Writes a character to a stream. */ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, char character); - -/** Writes a null-terminated text string to a stream. */ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const char* text); - -/** Writes a block of data from a MemoryBlock to a stream. */ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& data); - -/** Writes the contents of a file to a stream. */ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const File& fileToRead); - -/** Writes a new-line to a stream. - You can use the predefined symbol 'newLine' to invoke this, e.g. - @code - myOutputStream << "Hello World" << newLine << newLine; - @endcode - @see OutputStream::setNewLineString -*/ -OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const NewLine&); - -#endif // __JUCE_OUTPUTSTREAM_JUCEHEADER__ - -/*** End of inlined file: juce_OutputStream.h ***/ - #ifndef DOXYGEN class ReferenceCountedObject; class DynamicObject; @@ -8762,8 +8499,8 @@ public: operator bool() const noexcept; operator float() const noexcept; operator double() const noexcept; - operator const String() const; - const String toString() const; + operator String() const; + String toString() const; ReferenceCountedObject* getObject() const noexcept; DynamicObject* getDynamicObject() const noexcept; @@ -8785,29 +8522,25 @@ public: The data in the stream must have been written using writeToStream(), or this will have unpredictable results. */ - static const var readFromStream (InputStream& input); + static var readFromStream (InputStream& input); /** If this variant is an object, this returns one of its properties. */ - const var operator[] (const Identifier& propertyName) const; + var operator[] (const Identifier& propertyName) const; /** If this variant is an object, this invokes one of its methods with no arguments. */ - const var call (const Identifier& method) const; + var call (const Identifier& method) const; /** If this variant is an object, this invokes one of its methods with one argument. */ - const var call (const Identifier& method, const var& arg1) const; + var call (const Identifier& method, const var& arg1) const; /** If this variant is an object, this invokes one of its methods with 2 arguments. */ - const var call (const Identifier& method, const var& arg1, const var& arg2) const; + var call (const Identifier& method, const var& arg1, const var& arg2) const; /** If this variant is an object, this invokes one of its methods with 3 arguments. */ - const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3); + var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3); /** If this variant is an object, this invokes one of its methods with 4 arguments. */ - const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; + var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; /** If this variant is an object, this invokes one of its methods with 5 arguments. */ - const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; - + var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; /** If this variant is an object, this invokes one of its methods with a list of arguments. */ - const var invoke (const Identifier& method, const var* arguments, int numArguments) const; - - /** If this variant is a method pointer, this invokes it on a target object. */ - const var invoke (const var& targetObject, const var* arguments, int numArguments) const; + var invoke (const Identifier& method, const var* arguments, int numArguments) const; /** Returns true if this var has the same value as the one supplied. Note that this ignores the type, so a string var "123" and an integer var with the @@ -8823,26 +8556,16 @@ public: bool equalsWithSameType (const var& other) const noexcept; private: - class VariantType; - friend class VariantType; - class VariantType_Void; - friend class VariantType_Void; - class VariantType_Int; - friend class VariantType_Int; - class VariantType_Int64; - friend class VariantType_Int64; - class VariantType_Double; - friend class VariantType_Double; - class VariantType_Float; - friend class VariantType_Float; - class VariantType_Bool; - friend class VariantType_Bool; - class VariantType_String; - friend class VariantType_String; - class VariantType_Object; - friend class VariantType_Object; - class VariantType_Method; - friend class VariantType_Method; + + class VariantType; friend class VariantType; + class VariantType_Void; friend class VariantType_Void; + class VariantType_Int; friend class VariantType_Int; + class VariantType_Int64; friend class VariantType_Int64; + class VariantType_Double; friend class VariantType_Double; + class VariantType_Bool; friend class VariantType_Bool; + class VariantType_String; friend class VariantType_String; + class VariantType_Object; friend class VariantType_Object; + class VariantType_Method; friend class VariantType_Method; union ValueUnion { @@ -8850,13 +8573,16 @@ private: int64 int64Value; bool boolValue; double doubleValue; - String* stringValue; + char stringValue [sizeof (String)]; ReferenceCountedObject* objectValue; MethodFunction methodValue; }; const VariantType* type; ValueUnion value; + + friend class DynamicObject; + var invokeMethod (DynamicObject*, const var*, int) const; }; /** Compares the values of two var objects, using the var::equals() comparison. */ @@ -9230,7 +8956,7 @@ public: /** Tries to return the named value, but if no such value is found, this will instead return the supplied default value. */ - const var getWithDefault (const Identifier& name, const var& defaultReturnValue) const; + var getWithDefault (const Identifier& name, const var& defaultReturnValue) const; /** Changes or adds a named value. @returns true if a value was changed or added; false if the @@ -9255,7 +8981,7 @@ public: /** Returns the value of the item at a given index. The index must be between 0 and size() - 1. */ - const var getValueAt (int index) const; + var getValueAt (int index) const; /** Removes all values. */ void clear(); @@ -10629,7 +10355,7 @@ public: /** Generates a simple hash from an integer. */ static int generateHash (const int key, const int upperLimit) noexcept { return std::abs (key) % upperLimit; } /** Generates a simple hash from a string. */ - static int generateHash (const String& key, const int upperLimit) noexcept { return key.hashCode() % upperLimit; } + static int generateHash (const String& key, const int upperLimit) noexcept { return (int) (((uint32) key.hashCode()) % upperLimit); } /** Generates a simple hash from a variant. */ static int generateHash (const var& key, const int upperLimit) noexcept { return generateHash (key.toString(), upperLimit); } }; @@ -11324,9 +11050,9 @@ public: @param numberOfElements how many elements to join together. If this is less than zero, all available elements will be used. */ - const String joinIntoString (const String& separatorString, - int startIndex = 0, - int numberOfElements = -1) const; + String joinIntoString (const String& separatorString, + int startIndex = 0, + int numberOfElements = -1) const; /** Sorts the array into alphabetical order. @@ -11409,7 +11135,7 @@ public: @see operator[] */ - const String getValue (const String& key, const String& defaultReturnValue) const; + String getValue (const String& key, const String& defaultReturnValue) const; /** Returns a list of all keys in the array. */ const StringArray& getAllKeys() const noexcept { return keys; } @@ -11453,10 +11179,9 @@ public: void setIgnoresCase (bool shouldIgnoreCase); /** Returns a descriptive string containing the items. - This is handy for dumping the contents of an array. */ - const String getDescription() const; + String getDescription() const; /** Reduces the amount of storage being used by the array. @@ -11600,7 +11325,7 @@ public: @see inMilliseconds, inSeconds, inMinutes, inHours, inDays, inWeeks */ - const String getDescription (const String& returnValueForZeroTime = "0") const; + String getDescription (const String& returnValueForZeroTime = "0") const; /** Adds another RelativeTime to this one. */ const RelativeTime& operator+= (const RelativeTime& timeToAdd) noexcept; @@ -11631,9 +11356,9 @@ bool operator>= (const RelativeTime& t1, const RelativeTime& t2) noexcept; bool operator<= (const RelativeTime& t1, const RelativeTime& t2) noexcept; /** Adds two RelativeTimes together. */ -const RelativeTime operator+ (const RelativeTime& t1, const RelativeTime& t2) noexcept; +RelativeTime operator+ (const RelativeTime& t1, const RelativeTime& t2) noexcept; /** Subtracts two RelativeTimes. */ -const RelativeTime operator- (const RelativeTime& t1, const RelativeTime& t2) noexcept; +RelativeTime operator- (const RelativeTime& t1, const RelativeTime& t2) noexcept; #endif // __JUCE_RELATIVETIME_JUCEHEADER__ @@ -11708,7 +11433,7 @@ public: @see currentTimeMillis */ - static const Time JUCE_CALLTYPE getCurrentTime() noexcept; + static Time JUCE_CALLTYPE getCurrentTime() noexcept; /** Returns the time as a number of milliseconds. @@ -11737,7 +11462,7 @@ public: it'll return the long form, e.g. "January" @see getMonth */ - const String getMonthName (bool threeLetterVersion) const; + String getMonthName (bool threeLetterVersion) const; /** Returns the day of the month. @@ -11756,7 +11481,7 @@ public: @param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if false, it'll return the full version, e.g. "Tuesday". */ - const String getWeekdayName (bool threeLetterVersion) const; + String getWeekdayName (bool threeLetterVersion) const; /** Returns the number of hours since midnight. @@ -11802,7 +11527,7 @@ public: bool isDaylightSavingTime() const noexcept; /** Returns a 3-character string to indicate the local timezone. */ - const String getTimeZone() const noexcept; + String getTimeZone() const noexcept; /** Quick way of getting a string version of a date and time. @@ -11816,10 +11541,10 @@ public: hour notation. @see formatted */ - const String toString (bool includeDate, - bool includeTime, - bool includeSeconds = true, - bool use24HourClock = false) const noexcept; + String toString (bool includeDate, + bool includeTime, + bool includeSeconds = true, + bool use24HourClock = false) const noexcept; /** Converts this date/time to a string with a user-defined format. @@ -11852,7 +11577,7 @@ public: @see toString */ - const String formatted (const String& format) const; + String formatted (const String& format) const; /** Adds a RelativeTime to this time. */ Time& operator+= (const RelativeTime& delta); @@ -11872,8 +11597,8 @@ public: @param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if false, it'll return the full version, e.g. "Tuesday". */ - static const String getWeekdayName (int dayNumber, - bool threeLetterVersion); + static String getWeekdayName (int dayNumber, + bool threeLetterVersion); /** Returns the name of one of the months. @@ -11881,8 +11606,8 @@ public: @param threeLetterVersion if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false it'll return the long form, e.g. "January" */ - static const String getMonthName (int monthNumber, - bool threeLetterVersion); + static String getMonthName (int monthNumber, + bool threeLetterVersion); // Static methods for getting system timers directly.. @@ -11974,12 +11699,12 @@ private: }; /** Adds a RelativeTime to a Time. */ -JUCE_API const Time operator+ (const Time& time, const RelativeTime& delta); +JUCE_API Time operator+ (const Time& time, const RelativeTime& delta); /** Adds a RelativeTime to a Time. */ -JUCE_API const Time operator+ (const RelativeTime& delta, const Time& time); +JUCE_API Time operator+ (const RelativeTime& delta, const Time& time); /** Subtracts a RelativeTime from a Time. */ -JUCE_API const Time operator- (const Time& time, const RelativeTime& delta); +JUCE_API Time operator- (const Time& time, const RelativeTime& delta); /** Returns the relative time difference between two times. */ JUCE_API const RelativeTime operator- (const Time& time1, const Time& time2); @@ -12001,6 +11726,210 @@ JUCE_API bool operator>= (const Time& time1, const Time& time2); /*** End of inlined file: juce_Time.h ***/ +/*** Start of inlined file: juce_MemoryBlock.h ***/ +#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ +#define __JUCE_MEMORYBLOCK_JUCEHEADER__ + +/** + A class to hold a resizable block of raw data. + +*/ +class JUCE_API MemoryBlock +{ +public: + + /** Create an uninitialised block with 0 size. */ + MemoryBlock() noexcept; + + /** Creates a memory block with a given initial size. + + @param initialSize the size of block to create + @param initialiseToZero whether to clear the memory or just leave it uninitialised + */ + MemoryBlock (const size_t initialSize, + bool initialiseToZero = false); + + /** Creates a copy of another memory block. */ + MemoryBlock (const MemoryBlock& other); + + /** Creates a memory block using a copy of a block of data. + + @param dataToInitialiseFrom some data to copy into this block + @param sizeInBytes how much space to use + */ + MemoryBlock (const void* dataToInitialiseFrom, size_t sizeInBytes); + + /** Destructor. */ + ~MemoryBlock() noexcept; + + /** Copies another memory block onto this one. + + This block will be resized and copied to exactly match the other one. + */ + MemoryBlock& operator= (const MemoryBlock& other); + + /** Compares two memory blocks. + + @returns true only if the two blocks are the same size and have identical contents. + */ + bool operator== (const MemoryBlock& other) const noexcept; + + /** Compares two memory blocks. + + @returns true if the two blocks are different sizes or have different contents. + */ + bool operator!= (const MemoryBlock& other) const noexcept; + + /** Returns true if the data in this MemoryBlock matches the raw bytes passed-in. + */ + bool matches (const void* data, size_t dataSize) const noexcept; + + /** Returns a void pointer to the data. + + Note that the pointer returned will probably become invalid when the + block is resized. + */ + void* getData() const noexcept { return data; } + + /** Returns a byte from the memory block. + + This returns a reference, so you can also use it to set a byte. + */ + template + char& operator[] (const Type offset) const noexcept { return data [offset]; } + + /** Returns the block's current allocated size, in bytes. */ + size_t getSize() const noexcept { return size; } + + /** Resizes the memory block. + + This will try to keep as much of the block's current content as it can, + and can optionally be made to clear any new space that gets allocated at + the end of the block. + + @param newSize the new desired size for the block + @param initialiseNewSpaceToZero if the block gets enlarged, this determines + whether to clear the new section or just leave it + uninitialised + @see ensureSize + */ + void setSize (const size_t newSize, + bool initialiseNewSpaceToZero = false); + + /** Increases the block's size only if it's smaller than a given size. + + @param minimumSize if the block is already bigger than this size, no action + will be taken; otherwise it will be increased to this size + @param initialiseNewSpaceToZero if the block gets enlarged, this determines + whether to clear the new section or just leave it + uninitialised + @see setSize + */ + void ensureSize (const size_t minimumSize, + bool initialiseNewSpaceToZero = false); + + /** Fills the entire memory block with a repeated byte value. + + This is handy for clearing a block of memory to zero. + */ + void fillWith (uint8 valueToUse) noexcept; + + /** Adds another block of data to the end of this one. + + This block's size will be increased accordingly. + */ + void append (const void* data, size_t numBytes); + + /** Exchanges the contents of this and another memory block. + No actual copying is required for this, so it's very fast. + */ + void swapWith (MemoryBlock& other) noexcept; + + /** Copies data into this MemoryBlock from a memory address. + + @param srcData the memory location of the data to copy into this block + @param destinationOffset the offset in this block at which the data being copied should begin + @param numBytes how much to copy in (if this goes beyond the size of the memory block, + it will be clipped so not to do anything nasty) + */ + void copyFrom (const void* srcData, + int destinationOffset, + size_t numBytes) noexcept; + + /** Copies data from this MemoryBlock to a memory address. + + @param destData the memory location to write to + @param sourceOffset the offset within this block from which the copied data will be read + @param numBytes how much to copy (if this extends beyond the limits of the memory block, + zeros will be used for that portion of the data) + */ + void copyTo (void* destData, + int sourceOffset, + size_t numBytes) const noexcept; + + /** Chops out a section of the block. + + This will remove a section of the memory block and close the gap around it, + shifting any subsequent data downwards and reducing the size of the block. + + If the range specified goes beyond the size of the block, it will be clipped. + */ + void removeSection (size_t startByte, size_t numBytesToRemove); + + /** Attempts to parse the contents of the block as a zero-terminated string of 8-bit + characters in the system's default encoding. */ + const String toString() const; + + /** Parses a string of hexadecimal numbers and writes this data into the memory block. + + The block will be resized to the number of valid bytes read from the string. + Non-hex characters in the string will be ignored. + + @see String::toHexString() + */ + void loadFromHexString (const String& sourceHexString); + + /** Sets a number of bits in the memory block, treating it as a long binary sequence. */ + void setBitRange (size_t bitRangeStart, + size_t numBits, + int binaryNumberToApply) noexcept; + + /** Reads a number of bits from the memory block, treating it as one long binary sequence */ + int getBitRange (size_t bitRangeStart, + size_t numBitsToRead) const noexcept; + + /** Returns a string of characters that represent the binary contents of this block. + + Uses a 64-bit encoding system to allow binary data to be turned into a string + of simple non-extended characters, e.g. for storage in XML. + + @see fromBase64Encoding + */ + const String toBase64Encoding() const; + + /** Takes a string of encoded characters and turns it into binary data. + + The string passed in must have been created by to64BitEncoding(), and this + block will be resized to recreate the original data block. + + @see toBase64Encoding + */ + bool fromBase64Encoding (const String& encodedString); + +private: + + HeapBlock data; + size_t size; + static const char* const encodingTable; + + JUCE_LEAK_DETECTOR (MemoryBlock); +}; + +#endif // __JUCE_MEMORYBLOCK_JUCEHEADER__ + +/*** End of inlined file: juce_MemoryBlock.h ***/ + + /*** Start of inlined file: juce_Result.h ***/ #ifndef __JUCE_RESULT_JUCEHEADER__ #define __JUCE_RESULT_JUCEHEADER__ @@ -12011,7 +11940,7 @@ JUCE_API bool operator>= (const Time& time1, const Time& time2); E.g. @code - const Result myOperation() + Result myOperation() { if (doSomeKindOfFoobar()) return Result::ok(); @@ -12037,13 +11966,13 @@ class Result public: /** Creates and returns a 'successful' result. */ - static const Result ok() noexcept; + static Result ok() noexcept; /** Creates a 'failure' result. If you pass a blank error message in here, a default "Unknown Error" message will be used instead. */ - static const Result fail (const String& errorMessage) noexcept; + static Result fail (const String& errorMessage) noexcept; /** Returns true if this result indicates a success. */ bool wasOk() const noexcept; @@ -12067,7 +11996,7 @@ public: /** Returns the error message that was set when this result was created. For a successful result, this will be an empty string; */ - const String getErrorMessage() const noexcept; + const String& getErrorMessage() const noexcept; Result (const Result& other); Result& operator= (const Result& other); @@ -12187,7 +12116,7 @@ public: So for example 100 would return "100 bytes", 2000 would return "2 KB", 2000000 would produce "2 MB", etc. */ - static const String descriptionOfSizeInBytes (int64 bytes); + static String descriptionOfSizeInBytes (int64 bytes); /** Returns the complete, absolute path of this file. @@ -12215,7 +12144,7 @@ public: @see getFullPathName, getFileNameWithoutExtension */ - const String getFileName() const; + String getFileName() const; /** Creates a relative path that refers to a file relatively to a given directory. @@ -12232,7 +12161,7 @@ public: If it doesn't exist, it's assumed to be a directory. @see getChildFile, isAbsolutePath */ - const String getRelativePathFrom (const File& directoryToBeRelativeTo) const; + String getRelativePathFrom (const File& directoryToBeRelativeTo) const; /** Returns the file's extension. @@ -12242,7 +12171,7 @@ public: @see hasFileExtension, withFileExtension, getFileNameWithoutExtension */ - const String getFileExtension() const; + String getFileExtension() const; /** Checks whether the file has a given extension. @@ -12268,7 +12197,7 @@ public: @see getFileName, getFileExtension, hasFileExtension, getFileNameWithoutExtension */ - const File withFileExtension (const String& newExtension) const; + File withFileExtension (const String& newExtension) const; /** Returns the last part of the filename, without its file extension. @@ -12276,7 +12205,7 @@ public: @see getFileName, getFileExtension, hasFileExtension, withFileExtension */ - const String getFileNameWithoutExtension() const; + String getFileNameWithoutExtension() const; /** Returns a 32-bit hash-code that identifies this file. @@ -12305,7 +12234,7 @@ public: @see getSiblingFile, getParentDirectory, getRelativePathFrom, isAChildOf */ - const File getChildFile (String relativePath) const; + File getChildFile (String relativePath) const; /** Returns a file which is in the same directory as this one. @@ -12313,13 +12242,13 @@ public: @see getChildFile, getParentDirectory */ - const File getSiblingFile (const String& siblingFileName) const; + File getSiblingFile (const String& siblingFileName) const; /** Returns the directory that contains this file or directory. e.g. for "/moose/fish/foo.txt" this will return "/moose/fish". */ - const File getParentDirectory() const; + File getParentDirectory() const; /** Checks whether a file is somewhere inside a directory. @@ -12349,9 +12278,9 @@ public: format "prefix(number)suffix", if false, it will leave the brackets out. */ - const File getNonexistentChildFile (const String& prefix, - const String& suffix, - bool putNumbersInBrackets = true) const; + File getNonexistentChildFile (const String& prefix, + const String& suffix, + bool putNumbersInBrackets = true) const; /** Chooses a filename for a sibling file to this one that doesn't already exist. @@ -12362,7 +12291,7 @@ public: @param putNumbersInBrackets whether to add brackets around the numbers that get appended to the new filename. */ - const File getNonexistentSibling (bool putNumbersInBrackets = true) const; + File getNonexistentSibling (bool putNumbersInBrackets = true) const; /** Compares the pathnames for two files. */ bool operator== (const File& otherFile) const; @@ -12404,7 +12333,7 @@ public: If this file isn't actually link, it'll just return itself. */ - const File getLinkedTarget() const; + File getLinkedTarget() const; /** Returns the last modification time of this file. @@ -12457,7 +12386,7 @@ public: executables, bundles, dlls, etc. If no version is available, this will return an empty string. */ - const String getVersion() const; + String getVersion() const; /** Creates an empty file if it doesn't already exist. @@ -12469,7 +12398,7 @@ public: @returns true if the file has been created (or if it already existed). @see createDirectory */ - const Result create() const; + Result create() const; /** Creates a new directory for this filename. @@ -12480,7 +12409,7 @@ public: an error message if it failed. @see create */ - const Result createDirectory() const; + Result createDirectory() const; /** Deletes a file. @@ -12645,7 +12574,7 @@ public: This makes use of InputStream::readEntireStreamAsString, which should automatically cope with unicode/acsii file formats. */ - const String loadFileAsString() const; + String loadFileAsString() const; /** Appends a block of binary data to the end of the file. @@ -12726,7 +12655,7 @@ public: @returns the volume label of the drive, or an empty string if this isn't possible */ - const String getVolumeLabel() const; + String getVolumeLabel() const; /** Returns the serial number of the volume on which this file lives. @@ -12875,7 +12804,7 @@ public: @see SpecialLocationType */ - static const File JUCE_CALLTYPE getSpecialLocation (const SpecialLocationType type); + static File JUCE_CALLTYPE getSpecialLocation (const SpecialLocationType type); /** Returns a temporary file in the system's temp directory. @@ -12883,13 +12812,13 @@ public: To get the temp folder, you can use getSpecialLocation (File::tempDirectory). */ - static const File createTempFile (const String& fileNameEnding); + static File createTempFile (const String& fileNameEnding); /** Returns the current working directory. @see setAsCurrentWorkingDirectory */ - static const File getCurrentWorkingDirectory(); + static File getCurrentWorkingDirectory(); /** Sets the current working directory to be this file. @@ -12922,7 +12851,7 @@ public: @see createLegalPathName */ - static const String createLegalFileName (const String& fileNameToFix); + static String createLegalFileName (const String& fileNameToFix); /** Removes illegal characters from a pathname. @@ -12931,7 +12860,7 @@ public: @see createLegalFileName */ - static const String createLegalPathName (const String& pathNameToFix); + static String createLegalPathName (const String& pathNameToFix); /** Indicates whether filenames are case-sensitive on the current operating system. */ @@ -12946,10 +12875,10 @@ public: Best to avoid this unless you really know what you're doing. */ - static const File createFileWithoutCheckingPath (const String& path); + static File createFileWithoutCheckingPath (const String& path); /** Adds a separator character to the end of a path if it doesn't already have one. */ - static const String addTrailingSeparator (const String& path); + static String addTrailingSeparator (const String& path); private: @@ -12958,16 +12887,16 @@ private: // internal way of contructing a file without checking the path friend class DirectoryIterator; File (const String&, int); - const String getPathUpToLastSlash() const; + String getPathUpToLastSlash() const; - const Result createDirectoryInternal (const String& fileName) const; + Result createDirectoryInternal (const String& fileName) const; bool copyInternal (const File& dest) const; bool moveInternal (const File& dest) const; bool setFileTimesInternal (int64 modificationTime, int64 accessTime, int64 creationTime) const; void getFileTimesInternal (int64& modificationTime, int64& accessTime, int64& creationTime) const; bool setFileReadOnlyInternal (bool shouldBeReadOnly) const; - static const String parseAbsolutePath (const String& path); + static String parseAbsolutePath (const String& path); JUCE_LEAK_DETECTOR (File); }; @@ -13129,11 +13058,11 @@ public: determines how lists of attributes get broken up @see writeToStream, writeToFile */ - const String createDocument (const String& dtdToUse, - bool allOnOneLine = false, - bool includeXmlHeader = true, - const String& encodingType = "UTF-8", - int lineWrapLength = 60) const; + String createDocument (const String& dtdToUse, + bool allOnOneLine = false, + bool includeXmlHeader = true, + const String& encodingType = "UTF-8", + int lineWrapLength = 60) const; /** Writes the document to a stream as UTF-8. @@ -13240,8 +13169,8 @@ public: @param defaultReturnValue a value to return if the element doesn't have an attribute with this name */ - const String getStringAttribute (const String& attributeName, - const String& defaultReturnValue) const; + String getStringAttribute (const String& attributeName, + const String& defaultReturnValue) const; /** Compares the value of a named attribute with a value passed-in. @@ -13588,7 +13517,7 @@ public: @see isTextElement, getChildElementAllSubText, getText, addTextElement */ - const String getAllSubText() const; + String getAllSubText() const; /** Returns all the sub-text of a named child element. @@ -13598,8 +13527,8 @@ public: @see getAllSubText */ - const String getChildElementAllSubText (const String& childTagName, - const String& defaultReturnValue) const; + String getChildElementAllSubText (const String& childTagName, + const String& defaultReturnValue) const; /** Appends a section of text to this element. @@ -13695,8 +13624,8 @@ public: @param keyName the name of the property to retrieve @param defaultReturnValue a value to return if the named property doesn't actually exist */ - const String getValue (const String& keyName, - const String& defaultReturnValue = String::empty) const noexcept; + String getValue (const String& keyName, + const String& defaultReturnValue = String::empty) const noexcept; /** Returns one of the properties as an integer. @@ -15226,14 +15155,14 @@ public: } /** Returns the range that lies between two positions (in either order). */ - static const Range between (const ValueType position1, const ValueType position2) noexcept + static Range between (const ValueType position1, const ValueType position2) noexcept { return (position1 < position2) ? Range (position1, position2) : Range (position2, position1); } /** Returns a range with the specified start position and a length of zero. */ - static const Range emptyRange (const ValueType start) noexcept + static Range emptyRange (const ValueType start) noexcept { return Range (start, start); } @@ -15265,13 +15194,13 @@ public: If the new start position is higher than the current end of the range, the end point will be pushed along to equal it, returning an empty range at the new position. */ - const Range withStart (const ValueType newStart) const noexcept + Range withStart (const ValueType newStart) const noexcept { return Range (newStart, jmax (newStart, end)); } /** Returns a range with the same length as this one, but moved to have the given start position. */ - const Range movedToStartAt (const ValueType newStart) const noexcept + Range movedToStartAt (const ValueType newStart) const noexcept { return Range (newStart, end + (newStart - start)); } @@ -15291,13 +15220,13 @@ public: If the new end position is below the current start of the range, the start point will be pushed back to equal the new end point. */ - const Range withEnd (const ValueType newEnd) const noexcept + Range withEnd (const ValueType newEnd) const noexcept { return Range (jmin (start, newEnd), newEnd); } /** Returns a range with the same length as this one, but moved to have the given start position. */ - const Range movedToEndAt (const ValueType newEnd) const noexcept + Range movedToEndAt (const ValueType newEnd) const noexcept { return Range (start + (newEnd - end), newEnd); } @@ -15313,7 +15242,7 @@ public: /** Returns a range with the same start as this one, but a different length. Lengths less than zero are treated as zero. */ - const Range withLength (const ValueType newLength) const noexcept + Range withLength (const ValueType newLength) const noexcept { return Range (start, start + newLength); } @@ -15337,14 +15266,14 @@ public: /** Returns a range that is equal to this one with an amount added to its start and end. */ - const Range operator+ (const ValueType amountToAdd) const noexcept + Range operator+ (const ValueType amountToAdd) const noexcept { return Range (start + amountToAdd, end + amountToAdd); } /** Returns a range that is equal to this one with the specified amount subtracted from its start and end. */ - const Range operator- (const ValueType amountToSubtract) const noexcept + Range operator- (const ValueType amountToSubtract) const noexcept { return Range (start - amountToSubtract, end - amountToSubtract); } @@ -15378,14 +15307,14 @@ public: /** Returns the range that is the intersection of the two ranges, or an empty range with an undefined start position if they don't overlap. */ - const Range getIntersectionWith (const Range& other) const noexcept + Range getIntersectionWith (const Range& other) const noexcept { return Range (jmax (start, other.start), jmin (end, other.end)); } /** Returns the smallest range that contains both this one and the other one. */ - const Range getUnionWith (const Range& other) const noexcept + Range getUnionWith (const Range& other) const noexcept { return Range (jmin (start, other.start), jmax (end, other.end)); @@ -15401,7 +15330,7 @@ public: will be the new range, shifted forwards or backwards so that it doesn't extend beyond this one, but keeping its original length. */ - const Range constrainRange (const Range& rangeToConstrain) const noexcept + Range constrainRange (const Range& rangeToConstrain) const noexcept { const ValueType otherLen = rangeToConstrain.getLength(); return getLength() <= otherLen @@ -16237,16 +16166,16 @@ public: ~Value(); /** Returns the current value. */ - const var getValue() const; + var getValue() const; /** Returns the current value. */ - operator const var() const; + operator var() const; /** Returns the value as a string. This is alternative to writing things like "myValue.getValue().toString()". */ - const String toString() const; + String toString() const; /** Sets the current value. @@ -16718,7 +16647,7 @@ public: @see undo */ - const String getUndoDescription() const; + String getUndoDescription() const; /** Tries to roll-back the last transaction. @@ -16771,7 +16700,7 @@ public: @see redo */ - const String getRedoDescription() const; + String getRedoDescription() const; /** Tries to redo the last transaction that was undone. @@ -16891,7 +16820,7 @@ public: The type is specified when the ValueTree is created. @see hasType */ - const Identifier getType() const; + Identifier getType() const; /** Returns true if the node has this type. The comparison is case-sensitive. @@ -16910,7 +16839,7 @@ public: You can also use operator[] and getProperty to get a property. @see var, getProperty, setProperty, hasProperty */ - const var getProperty (const Identifier& name, const var& defaultReturnValue) const; + var getProperty (const Identifier& name, const var& defaultReturnValue) const; /** Returns the value of a named property. If no such property has been set, this will return a void variant. This is the same as @@ -16949,7 +16878,7 @@ public: /** Returns the identifier of the property with a given index. @see getNumProperties */ - const Identifier getPropertyName (int index) const; + Identifier getPropertyName (int index) const; /** Returns a Value object that can be used to control and respond to one of the tree's properties. @@ -17349,7 +17278,7 @@ public: void logMessage (const String& message); - const File getLogFile() const { return logFile; } + File getLogFile() const { return logFile; } /** Helper function to create a log file in the correct place for this platform. @@ -18362,7 +18291,7 @@ public: @returns a 32 character hex string. */ - const String toString() const; + String toString() const; /** Creates an ID from an encoded string version. @@ -18522,10 +18451,10 @@ public: ~MD5(); /** Returns the checksum as a 16-byte block of data. */ - const MemoryBlock getRawChecksumData() const; + MemoryBlock getRawChecksumData() const; /** Returns the checksum as a 32-digit hex string. */ - const String toHexString() const; + String toHexString() const; /** Compares this to another MD5. */ bool operator== (const MD5& other) const; @@ -18550,7 +18479,7 @@ private: void finish (void* result); }; - void processStream (InputStream& input, int64 numBytesToRead); + void processStream (InputStream&, int64 numBytesToRead); JUCE_LEAK_DETECTOR (MD5); }; @@ -18666,7 +18595,7 @@ public: e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits. @see getBitRangeAsInt */ - const BigInteger getBitRange (int startBit, int numBits) const; + BigInteger getBitRange (int startBit, int numBits) const; /** Returns a range of bits as an integer value. @@ -18727,20 +18656,20 @@ public: BigInteger& operator>>= (int numBitsToShift); BigInteger& operator++(); BigInteger& operator--(); - const BigInteger operator++ (int); - const BigInteger operator-- (int); - - const BigInteger operator-() const; - const BigInteger operator+ (const BigInteger& other) const; - const BigInteger operator- (const BigInteger& other) const; - const BigInteger operator* (const BigInteger& other) const; - const BigInteger operator/ (const BigInteger& other) const; - const BigInteger operator| (const BigInteger& other) const; - const BigInteger operator& (const BigInteger& other) const; - const BigInteger operator^ (const BigInteger& other) const; - const BigInteger operator% (const BigInteger& other) const; - const BigInteger operator<< (int numBitsToShift) const; - const BigInteger operator>> (int numBitsToShift) const; + BigInteger operator++ (int); + BigInteger operator-- (int); + + BigInteger operator-() const; + BigInteger operator+ (const BigInteger& other) const; + BigInteger operator- (const BigInteger& other) const; + BigInteger operator* (const BigInteger& other) const; + BigInteger operator/ (const BigInteger& other) const; + BigInteger operator| (const BigInteger& other) const; + BigInteger operator& (const BigInteger& other) const; + BigInteger operator^ (const BigInteger& other) const; + BigInteger operator% (const BigInteger& other) const; + BigInteger operator<< (int numBitsToShift) const; + BigInteger operator>> (int numBitsToShift) const; bool operator== (const BigInteger& other) const noexcept; bool operator!= (const BigInteger& other) const noexcept; @@ -18776,7 +18705,7 @@ public: /** Returns the largest value that will divide both this value and the one passed-in. */ - const BigInteger findGreatestCommonDivisor (BigInteger other) const; + BigInteger findGreatestCommonDivisor (BigInteger other) const; /** Performs a combined exponent and modulo operation. @@ -18811,7 +18740,7 @@ public: If minimumNumCharacters is greater than 0, the returned string will be padded with leading zeros to reach at least that length. */ - const String toString (int base, int minimumNumCharacters = 1) const; + String toString (int base, int minimumNumCharacters = 1) const; /** Reads the numeric value from a string. @@ -18827,7 +18756,7 @@ public: @see loadFromMemoryBlock */ - const MemoryBlock toMemoryBlock() const; + MemoryBlock toMemoryBlock() const; /** Converts a block of raw data into a number. @@ -18847,7 +18776,7 @@ private: void ensureSize (int numVals); void shiftLeft (int bits, int startBit); void shiftRight (int bits, int startBit); - static const BigInteger simpleGCD (BigInteger* m, BigInteger* n); + static BigInteger simpleGCD (BigInteger* m, BigInteger* n); static inline int bitToIndex (const int bit) noexcept { return bit >> 5; } static inline uint32 bitToMask (const int bit) noexcept { return 1 << (bit & 31); } @@ -18887,10 +18816,10 @@ public: which to seed the random number generation, improving the security of the keys generated. */ - static const BigInteger createProbablePrime (int bitLength, - int certainty, - const int* randomSeeds = 0, - int numRandomSeeds = 0); + static BigInteger createProbablePrime (int bitLength, + int certainty, + const int* randomSeeds = 0, + int numRandomSeeds = 0); /** Tests a number to see if it's prime. @@ -18952,7 +18881,7 @@ public: This can be reloaded using the constructor that takes a string. */ - const String toString() const; + String toString() const; /** Encodes or decodes a value. @@ -18994,7 +18923,7 @@ protected: private: - static const BigInteger findBestCommonDivisor (const BigInteger& p, const BigInteger& q); + static BigInteger findBestCommonDivisor (const BigInteger& p, const BigInteger& q); JUCE_LEAK_DETECTOR (RSAKey); }; @@ -19086,7 +19015,7 @@ public: The result of this call is only valid after a call to next() has returned true. */ - const File getFile() const; + const File& getFile() const; /** Returns a guess of how far through the search the iterator has got. @@ -19172,7 +19101,7 @@ public: The result will be ok if the file opened successfully. If an error occurs while opening or reading from the file, this will contain an error message. */ - const Result getStatus() const { return status; } + Result getStatus() const { return status; } int64 getTotalLength(); int read (void* destBuffer, int maxBytesToRead); @@ -19246,7 +19175,7 @@ public: The result will be ok if the file opened successfully. If an error occurs while opening or writing to the file, this will contain an error message. */ - const Result getStatus() const { return status; } + Result getStatus() const { return status; } /** Returns true if the stream couldn't be opened for some reason. @see getResult() @@ -19335,10 +19264,10 @@ public: @see getNumPaths */ - const File operator[] (int index) const; + File operator[] (int index) const; /** Returns the search path as a semicolon-separated list of directories. */ - const String toString() const; + String toString() const; /** Adds a new directory to the search path. @@ -19532,7 +19461,7 @@ public: bool isOpen() const; /** Returns the last name that was used to try to open this pipe. */ - const String getName() const; + String getName() const; /** Reads data from the pipe. @@ -19671,10 +19600,10 @@ public: ~TemporaryFile(); /** Returns the temporary file. */ - const File getFile() const { return temporaryFile; } + const File& getFile() const { return temporaryFile; } /** Returns the target file that was specified in the constructor. */ - const File getTargetFile() const { return targetFile; } + const File& getTargetFile() const { return targetFile; } /** Tries to move the temporary file to overwrite the target file that was specified in the constructor. @@ -19948,9 +19877,9 @@ private: ScopedPointer streamToDelete; ScopedPointer inputSource; -#if JUCE_DEBUG + #if JUCE_DEBUG int numOpenStreams; -#endif + #endif void init(); int findEndOfZipEntryTable (InputStream& input, int& numEntries); @@ -20307,6 +20236,9 @@ private: #ifndef __JUCE_URL_JUCEHEADER__ #define __JUCE_URL_JUCEHEADER__ +class InputStream; +class XmlElement; + /** Represents a URL and has a bunch of useful functions to manipulate it. @@ -20338,7 +20270,7 @@ public: withParameter() method, then the string will have these appended on the end and url-encoded. */ - const String toString (bool includeGetParameters) const; + String toString (bool includeGetParameters) const; /** True if it seems to be valid. */ bool isWellFormed() const; @@ -20347,20 +20279,20 @@ public: E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com". */ - const String getDomain() const; + String getDomain() const; /** Returns the path part of the URL. E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar". */ - const String getSubPath() const; + String getSubPath() const; /** Returns the scheme of the URL. E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't include the colon). */ - const String getScheme() const; + String getScheme() const; /** Returns a new version of this URL that uses a different sub-path. @@ -20430,7 +20362,7 @@ public: /** Returns the data that was set using withPOSTData(). */ - const String getPostData() const { return postData; } + String getPostData() const { return postData; } /** Tries to launch the system's default browser to open the URL. @@ -20509,7 +20441,7 @@ public: a GET command if this is false) @see readEntireBinaryStream, readEntireXmlStream */ - const String readEntireTextStream (bool usePostCommand = false) const; + String readEntireTextStream (bool usePostCommand = false) const; /** Tries to download the entire contents of this URL and parse it as XML. @@ -20539,8 +20471,8 @@ public: @see removeEscapeChars */ - static const String addEscapeChars (const String& stringToAddEscapeCharsTo, - bool isParameter); + static String addEscapeChars (const String& stringToAddEscapeCharsTo, + bool isParameter); /** Replaces any escape character sequences in a string with their original character codes. @@ -20551,7 +20483,7 @@ public: @see addEscapeChars */ - static const String removeEscapeChars (const String& stringToRemoveEscapeCharsFrom); + static String removeEscapeChars (const String& stringToRemoveEscapeCharsFrom); private: @@ -20738,7 +20670,7 @@ public: int64 getPosition(); bool setPosition (int64 newPosition); int read (void* destBuffer, int maxBytesToRead); - const String readString(); + String readString(); bool isExhausted(); private: @@ -21074,12 +21006,12 @@ public: void preallocate (size_t bytesToPreallocate); /** Returns a String created from the (UTF8) data that has been written to the stream. */ - const String toUTF8() const; + String toUTF8() const; /** Attempts to detect the encoding of the data and convert it to a string. @see String::createStringFromData */ - const String toString() const; + String toString() const; /** If the stream is writing to a user-supplied MemoryBlock, this will trim any excess capacity off the block, so that its length matches the amount of actual data that @@ -21227,24 +21159,24 @@ public: explicit Expression (const String& stringToParse); /** Returns a string version of the expression. */ - const String toString() const; + String toString() const; /** Returns an expression which is an addtion operation of two existing expressions. */ - const Expression operator+ (const Expression& other) const; + Expression operator+ (const Expression& other) const; /** Returns an expression which is a subtraction operation of two existing expressions. */ - const Expression operator- (const Expression& other) const; + Expression operator- (const Expression& other) const; /** Returns an expression which is a multiplication operation of two existing expressions. */ - const Expression operator* (const Expression& other) const; + Expression operator* (const Expression& other) const; /** Returns an expression which is a division operation of two existing expressions. */ - const Expression operator/ (const Expression& other) const; + Expression operator/ (const Expression& other) const; /** Returns an expression which performs a negation operation on an existing expression. */ - const Expression operator-() const; + Expression operator-() const; /** Returns an Expression which is an identifier reference. */ - static const Expression symbol (const String& symbol); + static Expression symbol (const String& symbol); /** Returns an Expression which is a function call. */ - static const Expression function (const String& functionName, const Array& parameters); + static Expression function (const String& functionName, const Array& parameters); /** Returns an Expression which parses a string from a character pointer, and updates the pointer to indicate where it finished. @@ -21255,7 +21187,7 @@ public: If there's a syntax error in the string, this will throw a ParseError exception. @throws ParseError */ - static const Expression parse (String::CharPointerType& stringToParse); + static Expression parse (String::CharPointerType& stringToParse); /** When evaluating an Expression object, this class is used to resolve symbols and perform functions that the expression uses. @@ -21334,7 +21266,7 @@ public: @throws Expression::EvaluationError */ - const Expression adjustedToGiveNewResult (double targetValue, const Scope& scope) const; + Expression adjustedToGiveNewResult (double targetValue, const Scope& scope) const; /** Represents a symbol that is used in an Expression. */ struct Symbol @@ -21348,7 +21280,7 @@ public: }; /** Returns a copy of this expression in which all instances of a given symbol have been renamed. */ - const Expression withRenamedSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope) const; + Expression withRenamedSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope) const; /** Returns true if this expression makes use of the specified symbol. If a suitable scope is supplied, the search will dereference and recursively check @@ -21390,7 +21322,7 @@ public: Type getType() const noexcept; /** If this expression is a symbol, function or operator, this returns its identifier. */ - const String getSymbolOrFunction() const; + String getSymbolOrFunction() const; /** Returns the number of inputs to this expression. @see getInput @@ -21400,7 +21332,7 @@ public: /** Retrieves one of the inputs to this expression. @see getNumInputs */ - const Expression getInput (int index) const; + Expression getInput (int index) const; private: @@ -21498,7 +21430,7 @@ public: @returns a random value in the range 0 to (maximumValue - 1). */ - const BigInteger nextLargeNumber (const BigInteger& maximumValue); + BigInteger nextLargeNumber (const BigInteger& maximumValue); /** Sets a range of bits in a BigInteger to random values. */ void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits); @@ -21877,7 +21809,7 @@ public: @see setCurrentMappings, getCurrentMappings */ - static const String translateWithCurrentMappings (const String& text); + static String translateWithCurrentMappings (const String& text); /** Tries to translate a string using the currently selected set of mappings. @@ -21888,13 +21820,13 @@ public: @see setCurrentMappings, getCurrentMappings */ - static const String translateWithCurrentMappings (const char* text); + static String translateWithCurrentMappings (const char* text); /** Attempts to look up a string and return its localised version. If the string isn't found in the list, the original string will be returned. */ - const String translate (const String& text) const; + String translate (const String& text) const; /** Returns the name of the language specified in the translation file. @@ -21903,7 +21835,7 @@ public: language: german @endcode */ - const String getLanguageName() const { return languageName; } + String getLanguageName() const { return languageName; } /** Returns the list of suitable country codes listed in the translation file. @@ -21952,6 +21884,69 @@ private: #endif #ifndef __JUCE_STRINGPOOL_JUCEHEADER__ +/*** Start of inlined file: juce_StringPool.h ***/ +#ifndef __JUCE_STRINGPOOL_JUCEHEADER__ +#define __JUCE_STRINGPOOL_JUCEHEADER__ + +/** + A StringPool holds a set of shared strings, which reduces storage overheads and improves + comparison speed when dealing with many duplicate strings. + + When you add a string to a pool using getPooledString, it'll return a character + array containing the same string. This array is owned by the pool, and the same array + is returned every time a matching string is asked for. This means that it's trivial to + compare two pooled strings for equality, as you can simply compare their pointers. It + also cuts down on storage if you're using many copies of the same string. +*/ +class JUCE_API StringPool +{ +public: + + /** Creates an empty pool. */ + StringPool() noexcept; + + /** Destructor */ + ~StringPool(); + + /** Returns a pointer to a copy of the string that is passed in. + + The pool will always return the same pointer when asked for a string that matches it. + The pool will own all the pointers that it returns, deleting them when the pool itself + is deleted. + */ + const String::CharPointerType getPooledString (const String& original); + + /** Returns a pointer to a copy of the string that is passed in. + + The pool will always return the same pointer when asked for a string that matches it. + The pool will own all the pointers that it returns, deleting them when the pool itself + is deleted. + */ + const String::CharPointerType getPooledString (const char* original); + + /** Returns a pointer to a copy of the string that is passed in. + + The pool will always return the same pointer when asked for a string that matches it. + The pool will own all the pointers that it returns, deleting them when the pool itself + is deleted. + */ + const String::CharPointerType getPooledString (const wchar_t* original); + + /** Returns the number of strings in the pool. */ + int size() const noexcept; + + /** Returns one of the strings in the pool, by index. */ + const String::CharPointerType operator[] (int index) const noexcept; + +private: + Array strings; +}; + +#endif // __JUCE_STRINGPOOL_JUCEHEADER__ + +/*** End of inlined file: juce_StringPool.h ***/ + + #endif #ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__ @@ -21959,6 +21954,8 @@ private: #ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__ #define __JUCE_XMLDOCUMENT_JUCEHEADER__ +class InputSource; + /** Parses a text-based XML document and creates an XmlElement object from it. @@ -22092,10 +22089,10 @@ private: void readQuotedString (String& result); void readEntity (String& result); - const String getFileContents (const String& filename) const; - const String expandEntity (const String& entity); - const String expandExternalEntity (const String& entity); - const String getParameterEntity (const String& entity); + String getFileContents (const String& filename) const; + String expandEntity (const String& entity); + String expandExternalEntity (const String& entity); + String getParameterEntity (const String& entity); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (XmlDocument); }; @@ -22667,7 +22664,7 @@ public: This is the name that gets set in the constructor. */ - const String getThreadName() const { return threadName_; } + const String& getThreadName() const { return threadName_; } /** Changes the name of the caller thread. Different OSes may place different length or content limits on this name. @@ -22998,7 +22995,7 @@ public: /** Returns the name of this job. @see setJobName */ - const String getJobName() const; + String getJobName() const; /** Changes the job's name. @see getJobName @@ -23205,7 +23202,7 @@ public: If onlyReturnActiveJobs is true, only the ones currently running are returned. */ - const StringArray getNamesOfAllJobs (bool onlyReturnActiveJobs) const; + StringArray getNamesOfAllJobs (bool onlyReturnActiveJobs) const; /** Changes the priority of all the threads. @@ -23964,71 +23961,71 @@ public: } /** Returns a new transform which is the same as this one followed by a translation. */ - const AffineTransform translated (float deltaX, - float deltaY) const noexcept; + AffineTransform translated (float deltaX, + float deltaY) const noexcept; /** Returns a new transform which is a translation. */ - static const AffineTransform translation (float deltaX, - float deltaY) noexcept; + static AffineTransform translation (float deltaX, + float deltaY) noexcept; /** Returns a transform which is the same as this one followed by a rotation. The rotation is specified by a number of radians to rotate clockwise, centred around the origin (0, 0). */ - const AffineTransform rotated (float angleInRadians) const noexcept; + AffineTransform rotated (float angleInRadians) const noexcept; /** Returns a transform which is the same as this one followed by a rotation about a given point. The rotation is specified by a number of radians to rotate clockwise, centred around the co-ordinates passed in. */ - const AffineTransform rotated (float angleInRadians, - float pivotX, - float pivotY) const noexcept; + AffineTransform rotated (float angleInRadians, + float pivotX, + float pivotY) const noexcept; /** Returns a new transform which is a rotation about (0, 0). */ - static const AffineTransform rotation (float angleInRadians) noexcept; + static AffineTransform rotation (float angleInRadians) noexcept; /** Returns a new transform which is a rotation about a given point. */ - static const AffineTransform rotation (float angleInRadians, - float pivotX, - float pivotY) noexcept; + static AffineTransform rotation (float angleInRadians, + float pivotX, + float pivotY) noexcept; /** Returns a transform which is the same as this one followed by a re-scaling. The scaling is centred around the origin (0, 0). */ - const AffineTransform scaled (float factorX, - float factorY) const noexcept; + AffineTransform scaled (float factorX, + float factorY) const noexcept; /** Returns a transform which is the same as this one followed by a re-scaling. The scaling is centred around the origin provided. */ - const AffineTransform scaled (float factorX, float factorY, - float pivotX, float pivotY) const noexcept; + AffineTransform scaled (float factorX, float factorY, + float pivotX, float pivotY) const noexcept; /** Returns a new transform which is a re-scale about the origin. */ - static const AffineTransform scale (float factorX, - float factorY) noexcept; + static AffineTransform scale (float factorX, + float factorY) noexcept; /** Returns a new transform which is a re-scale centred around the point provided. */ - static const AffineTransform scale (float factorX, float factorY, - float pivotX, float pivotY) noexcept; + static AffineTransform scale (float factorX, float factorY, + float pivotX, float pivotY) noexcept; /** Returns a transform which is the same as this one followed by a shear. The shear is centred around the origin (0, 0). */ - const AffineTransform sheared (float shearX, float shearY) const noexcept; + AffineTransform sheared (float shearX, float shearY) const noexcept; /** Returns a shear transform, centred around the origin (0, 0). */ - static const AffineTransform shear (float shearX, float shearY) noexcept; + static AffineTransform shear (float shearX, float shearY) noexcept; /** Returns a matrix which is the inverse operation of this one. Some matrices don't have an inverse - in this case, the method will just return an identity transform. */ - const AffineTransform inverted() const noexcept; + AffineTransform inverted() const noexcept; /** Returns the transform that will map three known points onto three coordinates that are supplied. @@ -24036,18 +24033,18 @@ public: This returns the transform that will transform (0, 0) into (x00, y00), (1, 0) to (x10, y10), and (0, 1) to (x01, y01). */ - static const AffineTransform fromTargetPoints (float x00, float y00, - float x10, float y10, - float x01, float y01) noexcept; + static AffineTransform fromTargetPoints (float x00, float y00, + float x10, float y10, + float x01, float y01) noexcept; /** Returns the transform that will map three specified points onto three target points. */ - static const AffineTransform fromTargetPoints (float sourceX1, float sourceY1, float targetX1, float targetY1, - float sourceX2, float sourceY2, float targetX2, float targetY2, - float sourceX3, float sourceY3, float targetX3, float targetY3) noexcept; + static AffineTransform fromTargetPoints (float sourceX1, float sourceY1, float targetX1, float targetY1, + float sourceX2, float sourceY2, float targetX2, float targetY2, + float sourceX3, float sourceY3, float targetX3, float targetY3) noexcept; /** Returns the result of concatenating another transformation after this one. */ - const AffineTransform followedBy (const AffineTransform& other) const noexcept; + AffineTransform followedBy (const AffineTransform& other) const noexcept; /** Returns true if this transform has no effect on points. */ bool isIdentity() const noexcept; @@ -24140,10 +24137,10 @@ public: inline void setY (const ValueType newY) noexcept { y = newY; } /** Returns a point which has the same Y position as this one, but a new X. */ - const Point withX (const ValueType newX) const noexcept { return Point (newX, y); } + Point withX (const ValueType newX) const noexcept { return Point (newX, y); } /** Returns a point which has the same X position as this one, but a new Y. */ - const Point withY (const ValueType newY) const noexcept { return Point (x, newY); } + Point withY (const ValueType newY) const noexcept { return Point (x, newY); } /** Changes the point's x and y co-ordinates. */ void setXY (const ValueType newX, const ValueType newY) noexcept { x = newX; y = newY; } @@ -24152,34 +24149,34 @@ public: void addXY (const ValueType xToAdd, const ValueType yToAdd) noexcept { x += xToAdd; y += yToAdd; } /** Returns a point with a given offset from this one. */ - const Point translated (const ValueType xDelta, const ValueType yDelta) const noexcept { return Point (x + xDelta, y + yDelta); } + Point translated (const ValueType xDelta, const ValueType yDelta) const noexcept { return Point (x + xDelta, y + yDelta); } /** Adds two points together. */ - const Point operator+ (const Point& other) const noexcept { return Point (x + other.x, y + other.y); } + Point operator+ (const Point& other) const noexcept { return Point (x + other.x, y + other.y); } /** Adds another point's co-ordinates to this one. */ Point& operator+= (const Point& other) noexcept { x += other.x; y += other.y; return *this; } /** Subtracts one points from another. */ - const Point operator- (const Point& other) const noexcept { return Point (x - other.x, y - other.y); } + Point operator- (const Point& other) const noexcept { return Point (x - other.x, y - other.y); } /** Subtracts another point's co-ordinates to this one. */ Point& operator-= (const Point& other) noexcept { x -= other.x; y -= other.y; return *this; } /** Returns a point whose coordinates are multiplied by a given value. */ - const Point operator* (const ValueType multiplier) const noexcept { return Point (x * multiplier, y * multiplier); } + Point operator* (const ValueType multiplier) const noexcept { return Point (x * multiplier, y * multiplier); } /** Multiplies the point's co-ordinates by a value. */ Point& operator*= (const ValueType multiplier) noexcept { x *= multiplier; y *= multiplier; return *this; } /** Returns a point whose coordinates are divided by a given value. */ - const Point operator/ (const ValueType divisor) const noexcept { return Point (x / divisor, y / divisor); } + Point operator/ (const ValueType divisor) const noexcept { return Point (x / divisor, y / divisor); } /** Divides the point's co-ordinates by a value. */ Point& operator/= (const ValueType divisor) noexcept { x /= divisor; y /= divisor; return *this; } /** Returns the inverse of this point. */ - const Point operator-() const noexcept { return Point (-x, -y); } + Point operator-() const noexcept { return Point (-x, -y); } /** Returns the straight-line distance between this point and another one. */ ValueType getDistanceFromOrigin() const noexcept { return juce_hypot (x, y); } @@ -24198,14 +24195,14 @@ public: @param radius the radius of the circle. @param angle the angle of the point, in radians clockwise from the 12 o'clock position. */ - const Point getPointOnCircumference (const float radius, const float angle) const noexcept { return Point (x + radius * std::sin (angle), + Point getPointOnCircumference (const float radius, const float angle) const noexcept { return Point (x + radius * std::sin (angle), y - radius * std::cos (angle)); } /** Taking this point to be the centre of an ellipse, this returns a point on its circumference. @param radiusX the horizontal radius of the circle. @param radiusY the vertical radius of the circle. @param angle the angle of the point, in radians clockwise from the 12 o'clock position. */ - const Point getPointOnCircumference (const float radiusX, const float radiusY, const float angle) const noexcept { return Point (x + radiusX * std::sin (angle), + Point getPointOnCircumference (const float radiusX, const float radiusY, const float angle) const noexcept { return Point (x + radiusX * std::sin (angle), y - radiusY * std::cos (angle)); } /** Uses a transform to change the point's co-ordinates. @@ -24215,20 +24212,20 @@ public: void applyTransform (const AffineTransform& transform) noexcept { transform.transformPoint (x, y); } /** Returns the position of this point, if it is transformed by a given AffineTransform. */ - const Point transformedBy (const AffineTransform& transform) const noexcept { return Point (transform.mat00 * x + transform.mat01 * y + transform.mat02, - transform.mat10 * x + transform.mat11 * y + transform.mat12); } + Point transformedBy (const AffineTransform& transform) const noexcept { return Point (transform.mat00 * x + transform.mat01 * y + transform.mat02, + transform.mat10 * x + transform.mat11 * y + transform.mat12); } /** Casts this point to a Point object. */ - const Point toInt() const noexcept { return Point (static_cast (x), static_cast (y)); } + Point toInt() const noexcept { return Point (static_cast (x), static_cast (y)); } /** Casts this point to a Point object. */ - const Point toFloat() const noexcept { return Point (static_cast (x), static_cast (y)); } + Point toFloat() const noexcept { return Point (static_cast (x), static_cast (y)); } /** Casts this point to a Point object. */ - const Point toDouble() const noexcept { return Point (static_cast (x), static_cast (y)); } + Point toDouble() const noexcept { return Point (static_cast (x), static_cast (y)); } /** Returns the point as a string in the form "x, y". */ - const String toString() const { return String (x) + ", " + String (y); } + String toString() const { return String (x) + ", " + String (y); } private: @@ -24485,13 +24482,13 @@ public: The x and y positions of the event that is returned will have been adjusted to be relative to the new component. */ - const MouseEvent getEventRelativeTo (Component* otherComponent) const noexcept; + MouseEvent getEventRelativeTo (Component* otherComponent) const noexcept; /** Creates a copy of this event with a different position. All other members of the event object are the same, but the x and y are replaced with these new values. */ - const MouseEvent withNewPosition (const Point& newPosition) const noexcept; + MouseEvent withNewPosition (const Point& newPosition) const noexcept; /** Changes the application-wide setting for the double-click time limit. @@ -24739,14 +24736,14 @@ public: To store a keypress in a file, use this method, along with createFromDescription() to retrieve it later. */ - const String getTextDescription() const; + String getTextDescription() const; /** Creates a textual description of the key combination, using unicode icon symbols if possible. On OSX, this uses the Apple symbols for command, option, shift, etc, instead of the textual modifier key descriptions that are returned by getTextDescription() */ - const String getTextDescriptionWithIcons() const; + String getTextDescriptionWithIcons() const; /** Checks whether the user is currently holding down the keys that make up this KeyPress. @@ -24983,385 +24980,454 @@ public: #ifndef __JUCE_TYPEFACE_JUCEHEADER__ #define __JUCE_TYPEFACE_JUCEHEADER__ - -/*** Start of inlined file: juce_Path.h ***/ -#ifndef __JUCE_PATH_JUCEHEADER__ -#define __JUCE_PATH_JUCEHEADER__ - - -/*** Start of inlined file: juce_Line.h ***/ -#ifndef __JUCE_LINE_JUCEHEADER__ -#define __JUCE_LINE_JUCEHEADER__ +class Path; +class Font; +class EdgeTable; +class AffineTransform; /** - Represents a line. + A typeface represents a size-independent font. - This class contains a bunch of useful methods for various geometric - tasks. + This base class is abstract, but calling createSystemTypefaceFor() will return + a platform-specific subclass that can be used. - The ValueType template parameter should be a primitive type - float or double - are what it's designed for. Integer types will work in a basic way, but some methods - that perform mathematical operations may not compile, or they may not produce - sensible results. + The CustomTypeface subclass allow you to build your own typeface, and to + load and save it in the Juce typeface format. - @see Point, Rectangle, Path, Graphics::drawLine + Normally you should never need to deal directly with Typeface objects - the Font + class does everything you typically need for rendering text. + + @see CustomTypeface, Font */ -template -class Line +class JUCE_API Typeface : public ReferenceCountedObject { public: - /** Creates a line, using (0, 0) as its start and end points. */ - Line() noexcept {} + /** A handy typedef for a pointer to a typeface. */ + typedef ReferenceCountedObjectPtr Ptr; - /** Creates a copy of another line. */ - Line (const Line& other) noexcept - : start (other.start), - end (other.end) - { - } + /** Returns the name of the typeface. + @see Font::getTypefaceName + */ + const String& getName() const noexcept { return name; } - /** Creates a line based on the co-ordinates of its start and end points. */ - Line (ValueType startX, ValueType startY, ValueType endX, ValueType endY) noexcept - : start (startX, startY), - end (endX, endY) - { - } + /** Creates a new system typeface. */ + static const Ptr createSystemTypefaceFor (const Font& font); - /** Creates a line from its start and end points. */ - Line (const Point& startPoint, - const Point& endPoint) noexcept - : start (startPoint), - end (endPoint) - { - } + /** Destructor. */ + virtual ~Typeface(); - /** Copies a line from another one. */ - Line& operator= (const Line& other) noexcept - { - start = other.start; - end = other.end; - return *this; - } + /** Returns true if this typeface can be used to render the specified font. + When called, the font will already have been checked to make sure that its name and + style flags match the typeface. + */ + virtual bool isSuitableForFont (const Font&) const { return true; } - /** Destructor. */ - ~Line() noexcept {} + /** Returns the ascent of the font, as a proportion of its height. + The height is considered to always be normalised as 1.0, so this will be a + value less that 1.0, indicating the proportion of the font that lies above + its baseline. + */ + virtual float getAscent() const = 0; - /** Returns the x co-ordinate of the line's start point. */ - inline ValueType getStartX() const noexcept { return start.getX(); } + /** Returns the descent of the font, as a proportion of its height. + The height is considered to always be normalised as 1.0, so this will be a + value less that 1.0, indicating the proportion of the font that lies below + its baseline. + */ + virtual float getDescent() const = 0; - /** Returns the y co-ordinate of the line's start point. */ - inline ValueType getStartY() const noexcept { return start.getY(); } + /** Measures the width of a line of text. - /** Returns the x co-ordinate of the line's end point. */ - inline ValueType getEndX() const noexcept { return end.getX(); } + The distance returned is based on the font having an normalised height of 1.0. - /** Returns the y co-ordinate of the line's end point. */ - inline ValueType getEndY() const noexcept { return end.getY(); } + You should never need to call this directly! Use Font::getStringWidth() instead! + */ + virtual float getStringWidth (const String& text) = 0; - /** Returns the line's start point. */ - inline const Point& getStart() const noexcept { return start; } + /** Converts a line of text into its glyph numbers and their positions. - /** Returns the line's end point. */ - inline const Point& getEnd() const noexcept { return end; } + The distances returned are based on the font having an normalised height of 1.0. - /** Changes this line's start point */ - void setStart (ValueType newStartX, ValueType newStartY) noexcept { start.setXY (newStartX, newStartY); } + You should never need to call this directly! Use Font::getGlyphPositions() instead! + */ + virtual void getGlyphPositions (const String& text, Array & glyphs, Array& xOffsets) = 0; - /** Changes this line's end point */ - void setEnd (ValueType newEndX, ValueType newEndY) noexcept { end.setXY (newEndX, newEndY); } + /** Returns the outline for a glyph. - /** Changes this line's start point */ - void setStart (const Point& newStart) noexcept { start = newStart; } + The path returned will be normalised to a font height of 1.0. + */ + virtual bool getOutlineForGlyph (int glyphNumber, Path& path) = 0; - /** Changes this line's end point */ - void setEnd (const Point& newEnd) noexcept { end = newEnd; } + /** Returns a new EdgeTable that contains the path for the givem glyph, with the specified transform applied. */ + virtual EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform) = 0; - /** Returns a line that is the same as this one, but with the start and end reversed, */ - const Line reversed() const noexcept { return Line (end, start); } + /** Returns true if the typeface uses hinting. */ + virtual bool isHinted() const { return false; } - /** Applies an affine transform to the line's start and end points. */ - void applyTransform (const AffineTransform& transform) noexcept - { - start.applyTransform (transform); - end.applyTransform (transform); - } + /** Changes the number of fonts that are cached in memory. */ + static void setTypefaceCacheSize (int numFontsToCache); - /** Returns the length of the line. */ - ValueType getLength() const noexcept { return start.getDistanceFrom (end); } +protected: - /** Returns true if the line's start and end x co-ordinates are the same. */ - bool isVertical() const noexcept { return start.getX() == end.getX(); } + String name; + bool isFallbackFont; - /** Returns true if the line's start and end y co-ordinates are the same. */ - bool isHorizontal() const noexcept { return start.getY() == end.getY(); } + explicit Typeface (const String& name) noexcept; - /** Returns the line's angle. + static const Ptr getFallbackTypeface(); - This value is the number of radians clockwise from the 3 o'clock direction, - where the line's start point is considered to be at the centre. - */ - ValueType getAngle() const noexcept { return start.getAngleToPoint (end); } +private: + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Typeface); +}; - /** Compares two lines. */ - bool operator== (const Line& other) const noexcept { return start == other.start && end == other.end; } +#endif // __JUCE_TYPEFACE_JUCEHEADER__ - /** Compares two lines. */ - bool operator!= (const Line& other) const noexcept { return start != other.start || end != other.end; } +/*** End of inlined file: juce_Typeface.h ***/ - /** Finds the intersection between two lines. +class LowLevelGraphicsContext; - @param line the other line - @param intersection the position of the point where the lines meet (or - where they would meet if they were infinitely long) - the intersection (if the lines intersect). If the lines - are parallel, this will just be set to the position - of one of the line's endpoints. - @returns true if the line segments intersect; false if they dont. Even if they - don't intersect, the intersection co-ordinates returned will still - be valid +/** + Represents a particular font, including its size, style, etc. + + Apart from the typeface to be used, a Font object also dictates whether + the font is bold, italic, underlined, how big it is, and its kerning and + horizontal scale factor. + + @see Typeface +*/ +class JUCE_API Font +{ +public: + + /** A combination of these values is used by the constructor to specify the + style of font to use. */ - bool intersects (const Line& line, Point& intersection) const noexcept + enum FontStyleFlags { - return findIntersection (start, end, line.start, line.end, intersection); - } + plain = 0, /**< indicates a plain, non-bold, non-italic version of the font. @see setStyleFlags */ + bold = 1, /**< boldens the font. @see setStyleFlags */ + italic = 2, /**< finds an italic version of the font. @see setStyleFlags */ + underlined = 4 /**< underlines the font. @see setStyleFlags */ + }; - /** Finds the intersection between two lines. + /** Creates a sans-serif font in a given size. - @param line the line to intersect with - @returns the point at which the lines intersect, even if this lies beyond the end of the lines + @param fontHeight the height in pixels (can be fractional) + @param styleFlags the style to use - this can be a combination of the + Font::bold, Font::italic and Font::underlined, or + just Font::plain for the normal style. + @see FontStyleFlags, getDefaultSansSerifFontName */ - const Point getIntersection (const Line& line) const noexcept - { - Point p; - findIntersection (start, end, line.start, line.end, p); - return p; - } + Font (float fontHeight, int styleFlags = plain); - /** Returns the location of the point which is a given distance along this line. + /** Creates a font with a given typeface and parameters. - @param distanceFromStart the distance to move along the line from its - start point. This value can be negative or longer - than the line itself - @see getPointAlongLineProportionally + @param typefaceName the name of the typeface to use + @param fontHeight the height in pixels (can be fractional) + @param styleFlags the style to use - this can be a combination of the + Font::bold, Font::italic and Font::underlined, or + just Font::plain for the normal style. + @see FontStyleFlags, getDefaultSansSerifFontName */ - const Point getPointAlongLine (ValueType distanceFromStart) const noexcept - { - return start + (end - start) * (distanceFromStart / getLength()); - } + Font (const String& typefaceName, float fontHeight, int styleFlags); - /** Returns a point which is a certain distance along and to the side of this line. + /** Creates a copy of another Font object. */ + Font (const Font& other) noexcept; - This effectively moves a given distance along the line, then another distance - perpendicularly to this, and returns the resulting position. + /** Creates a font for a typeface. */ + Font (const Typeface::Ptr& typeface); - @param distanceFromStart the distance to move along the line from its - start point. This value can be negative or longer - than the line itself - @param perpendicularDistance how far to move sideways from the line. If you're - looking along the line from its start towards its - end, then a positive value here will move to the - right, negative value move to the left. + /** Creates a basic sans-serif font at a default height. + + You should use one of the other constructors for creating a font that you're planning + on drawing with - this constructor is here to help initialise objects before changing + the font's settings later. */ - const Point getPointAlongLine (ValueType distanceFromStart, - ValueType perpendicularDistance) const noexcept - { - const Point delta (end - start); - const double length = juce_hypot ((double) delta.getX(), - (double) delta.getY()); - if (length <= 0) - return start; + Font(); - return Point (start.getX() + (ValueType) ((delta.getX() * distanceFromStart - delta.getY() * perpendicularDistance) / length), - start.getY() + (ValueType) ((delta.getY() * distanceFromStart + delta.getX() * perpendicularDistance) / length)); - } + /** Copies this font from another one. */ + Font& operator= (const Font& other) noexcept; - /** Returns the location of the point which is a given distance along this line - proportional to the line's length. + bool operator== (const Font& other) const noexcept; + bool operator!= (const Font& other) const noexcept; - @param proportionOfLength the distance to move along the line from its - start point, in multiples of the line's length. - So a value of 0.0 will return the line's start point - and a value of 1.0 will return its end point. (This value - can be negative or greater than 1.0). - @see getPointAlongLine + /** Destructor. */ + ~Font() noexcept; + + /** Changes the name of the typeface family. + + e.g. "Arial", "Courier", etc. + + This may also be set to Font::getDefaultSansSerifFontName(), Font::getDefaultSerifFontName(), + or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font names, + but are generic names that are used to represent the various default fonts. + If you need to know the exact typeface name being used, you can call + Font::getTypeface()->getTypefaceName(), which will give you the platform-specific name. + + If a suitable font isn't found on the machine, it'll just use a default instead. */ - const Point getPointAlongLineProportionally (ValueType proportionOfLength) const noexcept - { - return start + (end - start) * proportionOfLength; - } + void setTypefaceName (const String& faceName); - /** Returns the smallest distance between this line segment and a given point. + /** Returns the name of the typeface family that this font uses. - So if the point is close to the line, this will return the perpendicular - distance from the line; if the point is a long way beyond one of the line's - end-point's, it'll return the straight-line distance to the nearest end-point. + e.g. "Arial", "Courier", etc. - pointOnLine receives the position of the point that is found. + This may also be set to Font::getDefaultSansSerifFontName(), Font::getDefaultSerifFontName(), + or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font names, + but are generic names that are used to represent the various default fonts. - @returns the point's distance from the line - @see getPositionAlongLineOfNearestPoint + If you need to know the exact typeface name being used, you can call + Font::getTypeface()->getTypefaceName(), which will give you the platform-specific name. */ - ValueType getDistanceFromPoint (const Point& targetPoint, - Point& pointOnLine) const noexcept - { - const Point delta (end - start); - const double length = delta.getX() * delta.getX() + delta.getY() * delta.getY(); + const String& getTypefaceName() const noexcept { return font->typefaceName; } - if (length > 0) - { - const double prop = ((targetPoint.getX() - start.getX()) * delta.getX() - + (targetPoint.getY() - start.getY()) * delta.getY()) / length; + /** Returns a typeface name that represents the default sans-serif font. - if (prop >= 0 && prop <= 1.0) - { - pointOnLine = start + delta * (ValueType) prop; - return targetPoint.getDistanceFrom (pointOnLine); - } - } + This is also the typeface that will be used when a font is created without + specifying any typeface details. - const float fromStart = targetPoint.getDistanceFrom (start); - const float fromEnd = targetPoint.getDistanceFrom (end); + Note that this method just returns a generic placeholder string that means "the default + sans-serif font" - it's not the actual name of this font. To get the actual name, use + getPlatformDefaultFontNames() or LookAndFeel::getTypefaceForFont(). - if (fromStart < fromEnd) - { - pointOnLine = start; - return fromStart; - } - else - { - pointOnLine = end; - return fromEnd; - } - } + @see setTypefaceName, getDefaultSerifFontName, getDefaultMonospacedFontName + */ + static const String& getDefaultSansSerifFontName(); - /** Finds the point on this line which is nearest to a given point, and - returns its position as a proportional position along the line. + /** Returns a typeface name that represents the default sans-serif font. - @returns a value 0 to 1.0 which is the distance along this line from the - line's start to the point which is nearest to the point passed-in. To - turn this number into a position, use getPointAlongLineProportionally(). - @see getDistanceFromPoint, getPointAlongLineProportionally + Note that this method just returns a generic placeholder string that means "the default + serif font" - it's not the actual name of this font. To get the actual name, use + getPlatformDefaultFontNames() or LookAndFeel::getTypefaceForFont(). + + @see setTypefaceName, getDefaultSansSerifFontName, getDefaultMonospacedFontName */ - ValueType findNearestProportionalPositionTo (const Point& point) const noexcept - { - const Point delta (end - start); - const double length = delta.getX() * delta.getX() + delta.getY() * delta.getY(); + static const String& getDefaultSerifFontName(); - return length <= 0 ? 0 - : jlimit ((ValueType) 0, (ValueType) 1, - (ValueType) (((point.getX() - start.getX()) * delta.getX() - + (point.getY() - start.getY()) * delta.getY()) / length)); - } + /** Returns a typeface name that represents the default sans-serif font. - /** Finds the point on this line which is nearest to a given point. - @see getDistanceFromPoint, findNearestProportionalPositionTo + Note that this method just returns a generic placeholder string that means "the default + monospaced font" - it's not the actual name of this font. To get the actual name, use + getPlatformDefaultFontNames() or LookAndFeel::getTypefaceForFont(). + + @see setTypefaceName, getDefaultSansSerifFontName, getDefaultSerifFontName */ - const Point findNearestPointTo (const Point& point) const noexcept - { - return getPointAlongLineProportionally (findNearestProportionalPositionTo (point)); - } + static const String& getDefaultMonospacedFontName(); - /** Returns true if the given point lies above this line. + /** Returns the typeface names of the default fonts on the current platform. */ + static void getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& defaultFallback); - The return value is true if the point's y coordinate is less than the y - coordinate of this line at the given x (assuming the line extends infinitely - in both directions). + /** Returns the total height of this font. + + This is the maximum height, from the top of the ascent to the bottom of the + descenders. + + @see setHeight, setHeightWithoutChangingWidth, getAscent */ - bool isPointAbove (const Point& point) const noexcept - { - return start.getX() != end.getX() - && point.getY() < ((end.getY() - start.getY()) - * (point.getX() - start.getX())) / (end.getX() - start.getX()) + start.getY(); - } + float getHeight() const noexcept { return font->height; } - /** Returns a shortened copy of this line. + /** Changes the font's height. - This will chop off part of the start of this line by a certain amount, (leaving the - end-point the same), and return the new line. + @see getHeight, setHeightWithoutChangingWidth */ - const Line withShortenedStart (ValueType distanceToShortenBy) const noexcept - { - return Line (getPointAlongLine (jmin (distanceToShortenBy, getLength())), end); - } + void setHeight (float newHeight); - /** Returns a shortened copy of this line. + /** Changes the font's height without changing its width. - This will chop off part of the end of this line by a certain amount, (leaving the - start-point the same), and return the new line. + This alters the horizontal scale to compensate for the change in height. */ - const Line withShortenedEnd (ValueType distanceToShortenBy) const noexcept - { - const ValueType length = getLength(); - return Line (start, getPointAlongLine (length - jmin (distanceToShortenBy, length))); - } + void setHeightWithoutChangingWidth (float newHeight); -private: + /** Returns the height of the font above its baseline. - Point start, end; + This is the maximum height from the baseline to the top. - static bool findIntersection (const Point& p1, const Point& p2, - const Point& p3, const Point& p4, - Point& intersection) noexcept - { - if (p2 == p3) - { - intersection = p2; - return true; - } + @see getHeight, getDescent + */ + float getAscent() const; - const Point d1 (p2 - p1); - const Point d2 (p4 - p3); - const ValueType divisor = d1.getX() * d2.getY() - d2.getX() * d1.getY(); + /** Returns the amount that the font descends below its baseline. - if (divisor == 0) - { - if (! (d1.isOrigin() || d2.isOrigin())) - { - if (d1.getY() == 0 && d2.getY() != 0) - { - const ValueType along = (p1.getY() - p3.getY()) / d2.getY(); - intersection = p1.withX (p3.getX() + along * d2.getX()); - return along >= 0 && along <= (ValueType) 1; - } - else if (d2.getY() == 0 && d1.getY() != 0) - { - const ValueType along = (p3.getY() - p1.getY()) / d1.getY(); - intersection = p3.withX (p1.getX() + along * d1.getX()); - return along >= 0 && along <= (ValueType) 1; - } - else if (d1.getX() == 0 && d2.getX() != 0) - { - const ValueType along = (p1.getX() - p3.getX()) / d2.getX(); - intersection = p1.withY (p3.getY() + along * d2.getY()); - return along >= 0 && along <= (ValueType) 1; - } - else if (d2.getX() == 0 && d1.getX() != 0) - { - const ValueType along = (p3.getX() - p1.getX()) / d1.getX(); - intersection = p3.withY (p1.getY() + along * d1.getY()); - return along >= 0 && along <= (ValueType) 1; - } - } + This is calculated as (getHeight() - getAscent()). - intersection = (p2 + p3) / (ValueType) 2; - return false; - } + @see getAscent, getHeight + */ + float getDescent() const; - const ValueType along1 = ((p1.getY() - p3.getY()) * d2.getX() - (p1.getX() - p3.getX()) * d2.getY()) / divisor; - intersection = p1 + d1 * along1; + /** Returns the font's style flags. - if (along1 < 0 || along1 > (ValueType) 1) - return false; + This will return a bitwise-or'ed combination of values from the FontStyleFlags + enum, to describe whether the font is bold, italic, etc. - const ValueType along2 = ((p1.getY() - p3.getY()) * d1.getX() - (p1.getX() - p3.getX()) * d1.getY()) / divisor; - return along2 >= 0 && along2 <= (ValueType) 1; - } + @see FontStyleFlags + */ + int getStyleFlags() const noexcept { return font->styleFlags; } + + /** Changes the font's style. + + @param newFlags a bitwise-or'ed combination of values from the FontStyleFlags + enum, to set the font's properties + @see FontStyleFlags + */ + void setStyleFlags (int newFlags); + + /** Makes the font bold or non-bold. */ + void setBold (bool shouldBeBold); + /** Returns a copy of this font with the bold attribute set. */ + Font boldened() const; + /** Returns true if the font is bold. */ + bool isBold() const noexcept; + + /** Makes the font italic or non-italic. */ + void setItalic (bool shouldBeItalic); + /** Returns a copy of this font with the italic attribute set. */ + Font italicised() const; + /** Returns true if the font is italic. */ + bool isItalic() const noexcept; + + /** Makes the font underlined or non-underlined. */ + void setUnderline (bool shouldBeUnderlined); + /** Returns true if the font is underlined. */ + bool isUnderlined() const noexcept; + + /** Changes the font's horizontal scale factor. + + @param scaleFactor a value of 1.0 is the normal scale, less than this will be + narrower, greater than 1.0 will be stretched out. + */ + void setHorizontalScale (float scaleFactor); + + /** Returns the font's horizontal scale. + + A value of 1.0 is the normal scale, less than this will be narrower, greater + than 1.0 will be stretched out. + + @see setHorizontalScale + */ + float getHorizontalScale() const noexcept { return font->horizontalScale; } + + /** Changes the font's kerning. + + @param extraKerning a multiple of the font's height that will be added + to space between the characters. So a value of zero is + normal spacing, positive values spread the letters out, + negative values make them closer together. + */ + void setExtraKerningFactor (float extraKerning); + + /** Returns the font's kerning. + + This is the extra space added between adjacent characters, as a proportion + of the font's height. + + A value of zero is normal spacing, positive values will spread the letters + out more, and negative values make them closer together. + */ + float getExtraKerningFactor() const noexcept { return font->kerning; } + + /** Changes all the font's characteristics with one call. */ + void setSizeAndStyle (float newHeight, + int newStyleFlags, + float newHorizontalScale, + float newKerningAmount); + + /** Returns the total width of a string as it would be drawn using this font. + + For a more accurate floating-point result, use getStringWidthFloat(). + */ + int getStringWidth (const String& text) const; + + /** Returns the total width of a string as it would be drawn using this font. + + @see getStringWidth + */ + float getStringWidthFloat (const String& text) const; + + /** Returns the series of glyph numbers and their x offsets needed to represent a string. + + An extra x offset is added at the end of the run, to indicate where the right hand + edge of the last character is. + */ + void getGlyphPositions (const String& text, Array & glyphs, Array & xOffsets) const; + + /** Returns the typeface used by this font. + + Note that the object returned may go out of scope if this font is deleted + or has its style changed. + */ + Typeface* getTypeface() const; + + /** Creates an array of Font objects to represent all the fonts on the system. + + If you just need the names of the typefaces, you can also use + findAllTypefaceNames() instead. + + @param results the array to which new Font objects will be added. + */ + static void findFonts (Array& results); + + /** Returns a list of all the available typeface names. + + The names returned can be passed into setTypefaceName(). + + You can use this instead of findFonts() if you only need their names, and not + font objects. + */ + static StringArray findAllTypefaceNames(); + + /** Returns the name of the typeface to be used for rendering glyphs that aren't found + in the requested typeface. + */ + static const String& getFallbackFontName(); + + /** Sets the (platform-specific) name of the typeface to use to find glyphs that aren't + available in whatever font you're trying to use. + */ + static void setFallbackFontName (const String& name); + + /** Creates a string to describe this font. + The string will contain information to describe the font's typeface, size, and + style. To recreate the font from this string, use fromString(). + */ + String toString() const; + + /** Recreates a font from its stringified encoding. + This method takes a string that was created by toString(), and recreates the + original font. + */ + static Font fromString (const String& fontDescription); + +private: + + friend class FontGlyphAlphaMap; + friend class TypefaceCache; + + class SharedFontInternal : public ReferenceCountedObject + { + public: + SharedFontInternal (float height, int styleFlags) noexcept; + SharedFontInternal (const String& typefaceName, float height, int styleFlags) noexcept; + SharedFontInternal (const Typeface::Ptr& typeface) noexcept; + SharedFontInternal (const SharedFontInternal& other) noexcept; + + bool operator== (const SharedFontInternal&) const noexcept; + + String typefaceName; + float height, horizontalScale, kerning, ascent; + int styleFlags; + Typeface::Ptr typeface; + }; + + ReferenceCountedObjectPtr font; + void dupeInternalIfShared(); + + JUCE_LEAK_DETECTOR (Font); }; -#endif // __JUCE_LINE_JUCEHEADER__ +#endif // __JUCE_FONT_JUCEHEADER__ -/*** End of inlined file: juce_Line.h ***/ +/*** End of inlined file: juce_Font.h ***/ /*** Start of inlined file: juce_Rectangle.h ***/ @@ -25425,8 +25491,8 @@ public: The right and bottom values must be larger than the left and top ones, or the resulting rectangle will have a negative size. */ - static const Rectangle leftTopRightBottom (const ValueType left, const ValueType top, - const ValueType right, const ValueType bottom) noexcept + static Rectangle leftTopRightBottom (const ValueType left, const ValueType top, + const ValueType right, const ValueType bottom) noexcept { return Rectangle (left, top, right - left, bottom - top); } @@ -25469,7 +25535,7 @@ public: ValueType getCentreY() const noexcept { return y + h / (ValueType) 2; } /** Returns the centre point of the rectangle. */ - const Point getCentre() const noexcept { return Point (x + w / (ValueType) 2, y + h / (ValueType) 2); } + Point getCentre() const noexcept { return Point (x + w / (ValueType) 2, 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, @@ -25477,7 +25543,7 @@ public: ValueType getAspectRatio (const bool widthOverHeight = true) const noexcept { return widthOverHeight ? w / h : h / w; } /** Returns the rectangle's top-left position as a Point. */ - const Point getPosition() const noexcept { return Point (x, y); } + Point getPosition() const noexcept { return Point (x, y); } /** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */ void setPosition (const Point& newPos) noexcept { x = newPos.getX(); y = newPos.getY(); } @@ -25486,28 +25552,28 @@ public: void setPosition (const ValueType newX, const ValueType newY) noexcept { x = newX; y = newY; } /** Returns a rectangle with the same size as this one, but a new position. */ - const Rectangle withPosition (const ValueType newX, const ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); } + Rectangle withPosition (const ValueType newX, const ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); } /** Returns a rectangle with the same size as this one, but a new position. */ - const Rectangle withPosition (const Point& newPos) const noexcept { return Rectangle (newPos.getX(), newPos.getY(), w, h); } + Rectangle withPosition (const Point& newPos) const noexcept { return Rectangle (newPos.getX(), newPos.getY(), w, h); } /** Returns the rectangle's top-left position as a Point. */ - const Point getTopLeft() const noexcept { return getPosition(); } + Point getTopLeft() const noexcept { return getPosition(); } /** Returns the rectangle's top-right position as a Point. */ - const Point getTopRight() const noexcept { return Point (x + w, y); } + Point getTopRight() const noexcept { return Point (x + w, y); } /** Returns the rectangle's bottom-left position as a Point. */ - const Point getBottomLeft() const noexcept { return Point (x, y + h); } + Point getBottomLeft() const noexcept { return Point (x, y + h); } /** Returns the rectangle's bottom-right position as a Point. */ - const Point getBottomRight() const noexcept { return Point (x + w, y + h); } + Point getBottomRight() const noexcept { return Point (x + w, y + h); } /** Changes the rectangle's size, leaving the position of its top-left corner unchanged. */ void setSize (const ValueType newWidth, const ValueType newHeight) noexcept { w = newWidth; h = newHeight; } /** Returns a rectangle with the same position as this one, but a new size. */ - const Rectangle withSize (const ValueType newWidth, const ValueType newHeight) const noexcept { return Rectangle (x, y, newWidth, newHeight); } + Rectangle withSize (const ValueType newWidth, const ValueType newHeight) const noexcept { return Rectangle (x, y, newWidth, newHeight); } /** Changes all the rectangle's co-ordinates. */ void setBounds (const ValueType newX, const ValueType newY, @@ -25529,16 +25595,16 @@ public: void setHeight (const ValueType newHeight) noexcept { h = newHeight; } /** Returns a rectangle which has the same size and y-position as this one, but with a different x-position. */ - const Rectangle withX (const ValueType newX) const noexcept { return Rectangle (newX, y, w, h); } + Rectangle withX (const ValueType newX) const noexcept { return Rectangle (newX, y, w, h); } /** Returns a rectangle which has the same size and x-position as this one, but with a different y-position. */ - const Rectangle withY (const ValueType newY) const noexcept { return Rectangle (x, newY, w, h); } + Rectangle withY (const ValueType newY) const noexcept { return Rectangle (x, newY, w, h); } /** Returns a rectangle which has the same position and height as this one, but with a different width. */ - const Rectangle withWidth (const ValueType newWidth) const noexcept { return Rectangle (x, y, newWidth, h); } + Rectangle withWidth (const ValueType newWidth) const noexcept { return Rectangle (x, y, newWidth, h); } /** Returns a rectangle which has the same position and width as this one, but with a different height. */ - const Rectangle withHeight (const ValueType newHeight) const noexcept { return Rectangle (x, y, w, newHeight); } + Rectangle withHeight (const ValueType newHeight) const noexcept { return Rectangle (x, y, w, 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. @@ -25554,7 +25620,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 */ - const Rectangle withLeft (const ValueType newLeft) const noexcept { return Rectangle (newLeft, y, jmax (ValueType(), x + w - newLeft), h); } + Rectangle withLeft (const ValueType newLeft) const noexcept { return Rectangle (newLeft, y, jmax (ValueType(), 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. @@ -25570,7 +25636,7 @@ public: If the new y is beyond the bottom of the current rectangle, the height will be set to zero. @see setTop */ - const Rectangle withTop (const ValueType newTop) const noexcept { return Rectangle (x, newTop, w, jmax (ValueType(), y + h - newTop)); } + Rectangle withTop (const ValueType newTop) const noexcept { return Rectangle (x, newTop, w, jmax (ValueType(), 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. @@ -25586,7 +25652,7 @@ public: If the new right edge is below the current left-hand edge, the width will be set to zero. @see setRight */ - const Rectangle withRight (const ValueType newRight) const noexcept { return Rectangle (jmin (x, newRight), y, jmax (ValueType(), newRight - x), h); } + Rectangle withRight (const ValueType newRight) const noexcept { return Rectangle (jmin (x, newRight), y, jmax (ValueType(), newRight - 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. @@ -25602,7 +25668,7 @@ public: If the new y is beyond the bottom of the current rectangle, the height will be set to zero. @see setBottom */ - const Rectangle withBottom (const ValueType newBottom) const noexcept { return Rectangle (x, jmin (y, newBottom), w, jmax (ValueType(), newBottom - y)); } + Rectangle withBottom (const ValueType newBottom) const noexcept { return Rectangle (x, jmin (y, newBottom), w, jmax (ValueType(), newBottom - y)); } /** Moves the rectangle's position by adding amount to its x and y co-ordinates. */ void translate (const ValueType deltaX, @@ -25613,14 +25679,14 @@ public: } /** Returns a rectangle which is the same as this one moved by a given amount. */ - const Rectangle translated (const ValueType deltaX, - const ValueType deltaY) const noexcept + Rectangle translated (const ValueType deltaX, + const ValueType deltaY) const noexcept { return Rectangle (x + deltaX, y + deltaY, w, h); } /** Returns a rectangle which is the same as this one moved by a given amount. */ - const Rectangle operator+ (const Point& deltaPosition) const noexcept + Rectangle operator+ (const Point& deltaPosition) const noexcept { return Rectangle (x + deltaPosition.getX(), y + deltaPosition.getY(), w, h); } @@ -25633,7 +25699,7 @@ public: } /** Returns a rectangle which is the same as this one moved by a given amount. */ - const Rectangle operator- (const Point& deltaPosition) const noexcept + Rectangle operator- (const Point& deltaPosition) const noexcept { return Rectangle (x - deltaPosition.getX(), y - deltaPosition.getY(), w, h); } @@ -25663,8 +25729,8 @@ public: Effectively, the rectangle returned is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2). @see expand, reduce, reduced */ - const Rectangle expanded (const ValueType deltaX, - const ValueType deltaY) const noexcept + Rectangle expanded (const ValueType deltaX, + const ValueType deltaY) const noexcept { const ValueType nw = jmax (ValueType(), w + deltaX * 2); const ValueType nh = jmax (ValueType(), h + deltaY * 2); @@ -25687,8 +25753,8 @@ public: Effectively, the rectangle returned is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2). @see reduce, expand, expanded */ - const Rectangle reduced (const ValueType deltaX, - const ValueType deltaY) const noexcept + Rectangle reduced (const ValueType deltaX, + const ValueType deltaY) const noexcept { return expanded (-deltaX, -deltaY); } @@ -25702,7 +25768,7 @@ public: If amountToRemove is greater than the height of this rectangle, it'll be clipped to that value. */ - const Rectangle removeFromTop (const ValueType amountToRemove) noexcept + Rectangle removeFromTop (const ValueType amountToRemove) noexcept { const Rectangle r (x, y, w, jmin (amountToRemove, h)); y += r.h; h -= r.h; @@ -25718,7 +25784,7 @@ public: If amountToRemove is greater than the width of this rectangle, it'll be clipped to that value. */ - const Rectangle removeFromLeft (const ValueType amountToRemove) noexcept + Rectangle removeFromLeft (const ValueType amountToRemove) noexcept { const Rectangle r (x, y, jmin (amountToRemove, w), h); x += r.w; w -= r.w; @@ -25734,7 +25800,7 @@ public: If amountToRemove is greater than the width of this rectangle, it'll be clipped to that value. */ - const Rectangle removeFromRight (ValueType amountToRemove) noexcept + Rectangle removeFromRight (ValueType amountToRemove) noexcept { amountToRemove = jmin (amountToRemove, w); const Rectangle r (x + w - amountToRemove, y, amountToRemove, h); @@ -25751,7 +25817,7 @@ public: If amountToRemove is greater than the height of this rectangle, it'll be clipped to that value. */ - const Rectangle removeFromBottom (ValueType amountToRemove) noexcept + Rectangle removeFromBottom (ValueType amountToRemove) noexcept { amountToRemove = jmin (amountToRemove, h); const Rectangle r (x, y + h - amountToRemove, w, amountToRemove); @@ -25793,7 +25859,7 @@ public: } /** Returns the nearest point to the specified point that lies within this rectangle. */ - const Point getConstrainedPoint (const Point& point) const noexcept + Point getConstrainedPoint (const Point& point) const noexcept { return Point (jlimit (x, x + w, point.getX()), jlimit (y, y + h, point.getY())); @@ -25813,7 +25879,7 @@ public: If the two rectangles don't overlap, the rectangle returned will be empty. */ - const Rectangle getIntersection (const Rectangle& other) const noexcept + Rectangle getIntersection (const Rectangle& other) const noexcept { const ValueType nx = jmax (x, other.x); const ValueType ny = jmax (y, other.y); @@ -25857,7 +25923,7 @@ public: If either this or the other rectangle are empty, they will not be counted as part of the resulting region. */ - const Rectangle getUnion (const Rectangle& other) const noexcept + Rectangle getUnion (const Rectangle& other) const noexcept { if (other.isEmpty()) return *this; if (isEmpty()) return other; @@ -25932,7 +25998,7 @@ public: This should only be used on floating point rectangles. */ - const Rectangle transformed (const AffineTransform& transform) const noexcept + Rectangle transformed (const AffineTransform& transform) const noexcept { float x1 = x, y1 = y; float x2 = x + w, y2 = y; @@ -25965,7 +26031,7 @@ public: } /** Returns the smallest Rectangle that can contain a set of points. */ - static const Rectangle findAreaContainingPoints (const Point* const points, const int numPoints) noexcept + static Rectangle findAreaContainingPoints (const Point* const points, const int numPoints) noexcept { if (numPoints == 0) return Rectangle(); @@ -26032,7 +26098,7 @@ public: @see fromString */ - const String toString() const + String toString() const { String s; s.preallocateBytes (32); @@ -26050,7 +26116,7 @@ public: @see toString */ - static const Rectangle fromString (const String& stringVersion) + static Rectangle fromString (const String& stringVersion) { StringArray toks; toks.addTokens (stringVersion.trim(), ",; \t\r\n", String::empty); @@ -26071,214 +26137,601 @@ private: /*** End of inlined file: juce_Rectangle.h ***/ -/*** Start of inlined file: juce_Justification.h ***/ -#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__ -#define __JUCE_JUSTIFICATION_JUCEHEADER__ - -/** - Represents a type of justification to be used when positioning graphical items. - - e.g. it indicates whether something should be placed top-left, top-right, - centred, etc. - - It is used in various places wherever this kind of information is needed. -*/ -class JUCE_API Justification -{ -public: - - /** Creates a Justification object using a combination of flags. */ - inline Justification (int flags_) noexcept : flags (flags_) {} +/*** Start of inlined file: juce_PathStrokeType.h ***/ +#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__ +#define __JUCE_PATHSTROKETYPE_JUCEHEADER__ - /** Creates a copy of another Justification object. */ - Justification (const Justification& other) noexcept; - /** Copies another Justification object. */ - Justification& operator= (const Justification& other) noexcept; +/*** Start of inlined file: juce_Path.h ***/ +#ifndef __JUCE_PATH_JUCEHEADER__ +#define __JUCE_PATH_JUCEHEADER__ - bool operator== (const Justification& other) const noexcept { return flags == other.flags; } - bool operator!= (const Justification& other) const noexcept { return flags != other.flags; } - /** Returns the raw flags that are set for this Justification object. */ - inline int getFlags() const noexcept { return flags; } +/*** Start of inlined file: juce_Line.h ***/ +#ifndef __JUCE_LINE_JUCEHEADER__ +#define __JUCE_LINE_JUCEHEADER__ - /** Tests a set of flags for this object. +/** + Represents a line. - @returns true if any of the flags passed in are set on this object. - */ - inline bool testFlags (int flagsToTest) const noexcept { return (flags & flagsToTest) != 0; } + This class contains a bunch of useful methods for various geometric + tasks. - /** Returns just the flags from this object that deal with vertical layout. */ - int getOnlyVerticalFlags() const noexcept; + The ValueType template parameter should be a primitive type - float or double + are what it's designed for. Integer types will work in a basic way, but some methods + that perform mathematical operations may not compile, or they may not produce + sensible results. - /** Returns just the flags from this object that deal with horizontal layout. */ - int getOnlyHorizontalFlags() const noexcept; + @see Point, Rectangle, Path, Graphics::drawLine +*/ +template +class Line +{ +public: - /** Adjusts the position of a rectangle to fit it into a space. + /** Creates a line, using (0, 0) as its start and end points. */ + Line() noexcept {} - The (x, y) position of the rectangle will be updated to position it inside the - given space according to the justification flags. - */ - template - void applyToRectangle (ValueType& x, ValueType& y, ValueType w, ValueType h, - ValueType spaceX, ValueType spaceY, ValueType spaceW, ValueType spaceH) const noexcept + /** Creates a copy of another line. */ + Line (const Line& other) noexcept + : start (other.start), + end (other.end) { - x = spaceX; - if ((flags & horizontallyCentred) != 0) x += (spaceW - w) / (ValueType) 2; - else if ((flags & right) != 0) x += spaceW - w; + } - y = spaceY; - if ((flags & verticallyCentred) != 0) y += (spaceH - h) / (ValueType) 2; - else if ((flags & bottom) != 0) y += spaceH - h; + /** Creates a line based on the co-ordinates of its start and end points. */ + Line (ValueType startX, ValueType startY, ValueType endX, ValueType endY) noexcept + : start (startX, startY), + end (endX, endY) + { } - /** Returns the new position of a rectangle that has been justified to fit within a given space. - */ - template - const Rectangle appliedToRectangle (const Rectangle& areaToAdjust, - const Rectangle& targetSpace) const noexcept + /** Creates a line from its start and end points. */ + Line (const Point& startPoint, + const Point& endPoint) noexcept + : start (startPoint), + end (endPoint) { - ValueType x = areaToAdjust.getX(), y = areaToAdjust.getY(); - applyToRectangle (x, y, areaToAdjust.getWidth(), areaToAdjust.getHeight(), - targetSpace.getX(), targetSpace.getY(), targetSpace.getWidth(), targetSpace.getHeight()); - return areaToAdjust.withPosition (x, y); } - /** Flag values that can be combined and used in the constructor. */ - enum + /** Copies a line from another one. */ + Line& operator= (const Line& other) noexcept { + start = other.start; + end = other.end; + return *this; + } - /** Indicates that the item should be aligned against the left edge of the available space. */ - left = 1, + /** Destructor. */ + ~Line() noexcept {} - /** Indicates that the item should be aligned against the right edge of the available space. */ - right = 2, + /** Returns the x co-ordinate of the line's start point. */ + inline ValueType getStartX() const noexcept { return start.getX(); } - /** Indicates that the item should be placed in the centre between the left and right - sides of the available space. */ - horizontallyCentred = 4, + /** Returns the y co-ordinate of the line's start point. */ + inline ValueType getStartY() const noexcept { return start.getY(); } - /** Indicates that the item should be aligned against the top edge of the available space. */ - top = 8, + /** Returns the x co-ordinate of the line's end point. */ + inline ValueType getEndX() const noexcept { return end.getX(); } - /** Indicates that the item should be aligned against the bottom edge of the available space. */ - bottom = 16, + /** Returns the y co-ordinate of the line's end point. */ + inline ValueType getEndY() const noexcept { return end.getY(); } - /** Indicates that the item should be placed in the centre between the top and bottom - sides of the available space. */ - verticallyCentred = 32, + /** Returns the line's start point. */ + inline const Point& getStart() const noexcept { return start; } - /** Indicates that lines of text should be spread out to fill the maximum width - available, so that both margins are aligned vertically. - */ - horizontallyJustified = 64, + /** Returns the line's end point. */ + inline const Point& getEnd() const noexcept { return end; } - /** Indicates that the item should be centred vertically and horizontally. - This is equivalent to (horizontallyCentred | verticallyCentred) - */ - centred = 36, + /** Changes this line's start point */ + void setStart (ValueType newStartX, ValueType newStartY) noexcept { start.setXY (newStartX, newStartY); } - /** Indicates that the item should be centred vertically but placed on the left hand side. - This is equivalent to (left | verticallyCentred) - */ - centredLeft = 33, + /** Changes this line's end point */ + void setEnd (ValueType newEndX, ValueType newEndY) noexcept { end.setXY (newEndX, newEndY); } - /** Indicates that the item should be centred vertically but placed on the right hand side. - This is equivalent to (right | verticallyCentred) - */ - centredRight = 34, + /** Changes this line's start point */ + void setStart (const Point& newStart) noexcept { start = newStart; } - /** Indicates that the item should be centred horizontally and placed at the top. - This is equivalent to (horizontallyCentred | top) - */ - centredTop = 12, + /** Changes this line's end point */ + void setEnd (const Point& newEnd) noexcept { end = newEnd; } - /** Indicates that the item should be centred horizontally and placed at the bottom. - This is equivalent to (horizontallyCentred | bottom) - */ - centredBottom = 20, + /** Returns a line that is the same as this one, but with the start and end reversed, */ + const Line reversed() const noexcept { return Line (end, start); } - /** Indicates that the item should be placed in the top-left corner. - This is equivalent to (left | top) - */ - topLeft = 9, + /** Applies an affine transform to the line's start and end points. */ + void applyTransform (const AffineTransform& transform) noexcept + { + start.applyTransform (transform); + end.applyTransform (transform); + } - /** Indicates that the item should be placed in the top-right corner. - This is equivalent to (right | top) - */ - topRight = 10, + /** Returns the length of the line. */ + ValueType getLength() const noexcept { return start.getDistanceFrom (end); } - /** Indicates that the item should be placed in the bottom-left corner. - This is equivalent to (left | bottom) - */ - bottomLeft = 17, + /** Returns true if the line's start and end x co-ordinates are the same. */ + bool isVertical() const noexcept { return start.getX() == end.getX(); } - /** Indicates that the item should be placed in the bottom-left corner. - This is equivalent to (right | bottom) - */ - bottomRight = 18 - }; + /** Returns true if the line's start and end y co-ordinates are the same. */ + bool isHorizontal() const noexcept { return start.getY() == end.getY(); } -private: + /** Returns the line's angle. - int flags; -}; + This value is the number of radians clockwise from the 3 o'clock direction, + where the line's start point is considered to be at the centre. + */ + ValueType getAngle() const noexcept { return start.getAngleToPoint (end); } -#endif // __JUCE_JUSTIFICATION_JUCEHEADER__ + /** Compares two lines. */ + bool operator== (const Line& other) const noexcept { return start == other.start && end == other.end; } -/*** End of inlined file: juce_Justification.h ***/ + /** Compares two lines. */ + bool operator!= (const Line& other) const noexcept { return start != other.start || end != other.end; } -class Image; + /** Finds the intersection between two lines. -/** - A path is a sequence of lines and curves that may either form a closed shape - or be open-ended. + @param line the other line + @param intersection the position of the point where the lines meet (or + where they would meet if they were infinitely long) + the intersection (if the lines intersect). If the lines + are parallel, this will just be set to the position + of one of the line's endpoints. + @returns true if the line segments intersect; false if they dont. Even if they + don't intersect, the intersection co-ordinates returned will still + be valid + */ + bool intersects (const Line& line, Point& intersection) const noexcept + { + return findIntersection (start, end, line.start, line.end, intersection); + } - To use a path, you can create an empty one, then add lines and curves to it - to create shapes, then it can be rendered by a Graphics context or used - for geometric operations. + /** Finds the intersection between two lines. - e.g. @code - Path myPath; + @param line the line to intersect with + @returns the point at which the lines intersect, even if this lies beyond the end of the lines + */ + Point getIntersection (const Line& line) const noexcept + { + Point p; + findIntersection (start, end, line.start, line.end, p); + return p; + } - myPath.startNewSubPath (10.0f, 10.0f); // move the current position to (10, 10) - myPath.lineTo (100.0f, 200.0f); // draw a line from here to (100, 200) - myPath.quadraticTo (0.0f, 150.0f, 5.0f, 50.0f); // draw a curve that ends at (5, 50) - myPath.closeSubPath(); // close the subpath with a line back to (10, 10) + /** Returns the location of the point which is a given distance along this line. - // add an ellipse as well, which will form a second sub-path within the path.. - myPath.addEllipse (50.0f, 50.0f, 40.0f, 30.0f); + @param distanceFromStart the distance to move along the line from its + start point. This value can be negative or longer + than the line itself + @see getPointAlongLineProportionally + */ + Point getPointAlongLine (ValueType distanceFromStart) const noexcept + { + return start + (end - start) * (distanceFromStart / getLength()); + } - // double the width of the whole thing.. - myPath.applyTransform (AffineTransform::scale (2.0f, 1.0f)); + /** Returns a point which is a certain distance along and to the side of this line. - // and draw it to a graphics context with a 5-pixel thick outline. - g.strokePath (myPath, PathStrokeType (5.0f)); + This effectively moves a given distance along the line, then another distance + perpendicularly to this, and returns the resulting position. - @endcode + @param distanceFromStart the distance to move along the line from its + start point. This value can be negative or longer + than the line itself + @param perpendicularDistance how far to move sideways from the line. If you're + looking along the line from its start towards its + end, then a positive value here will move to the + right, negative value move to the left. + */ + Point getPointAlongLine (ValueType distanceFromStart, + ValueType perpendicularDistance) const noexcept + { + const Point delta (end - start); + const double length = juce_hypot ((double) delta.getX(), + (double) delta.getY()); + if (length <= 0) + return start; - A path object can actually contain multiple sub-paths, which may themselves - be open or closed. + return Point (start.getX() + (ValueType) ((delta.getX() * distanceFromStart - delta.getY() * perpendicularDistance) / length), + start.getY() + (ValueType) ((delta.getY() * distanceFromStart + delta.getX() * perpendicularDistance) / length)); + } - @see PathFlatteningIterator, PathStrokeType, Graphics -*/ -class JUCE_API Path -{ -public: + /** Returns the location of the point which is a given distance along this line + proportional to the line's length. - /** Creates an empty path. */ - Path(); + @param proportionOfLength the distance to move along the line from its + start point, in multiples of the line's length. + So a value of 0.0 will return the line's start point + and a value of 1.0 will return its end point. (This value + can be negative or greater than 1.0). + @see getPointAlongLine + */ + Point getPointAlongLineProportionally (ValueType proportionOfLength) const noexcept + { + return start + (end - start) * proportionOfLength; + } - /** Creates a copy of another path. */ - Path (const Path& other); + /** Returns the smallest distance between this line segment and a given point. - /** Destructor. */ - ~Path(); + So if the point is close to the line, this will return the perpendicular + distance from the line; if the point is a long way beyond one of the line's + end-point's, it'll return the straight-line distance to the nearest end-point. - /** Copies this path from another one. */ - Path& operator= (const Path& other); + pointOnLine receives the position of the point that is found. - bool operator== (const Path& other) const noexcept; + @returns the point's distance from the line + @see getPositionAlongLineOfNearestPoint + */ + ValueType getDistanceFromPoint (const Point& targetPoint, + Point& pointOnLine) const noexcept + { + const Point delta (end - start); + const double length = delta.getX() * delta.getX() + delta.getY() * delta.getY(); + + if (length > 0) + { + const double prop = ((targetPoint.getX() - start.getX()) * delta.getX() + + (targetPoint.getY() - start.getY()) * delta.getY()) / length; + + if (prop >= 0 && prop <= 1.0) + { + pointOnLine = start + delta * (ValueType) prop; + return targetPoint.getDistanceFrom (pointOnLine); + } + } + + const float fromStart = targetPoint.getDistanceFrom (start); + const float fromEnd = targetPoint.getDistanceFrom (end); + + if (fromStart < fromEnd) + { + pointOnLine = start; + return fromStart; + } + else + { + pointOnLine = end; + return fromEnd; + } + } + + /** Finds the point on this line which is nearest to a given point, and + returns its position as a proportional position along the line. + + @returns a value 0 to 1.0 which is the distance along this line from the + line's start to the point which is nearest to the point passed-in. To + turn this number into a position, use getPointAlongLineProportionally(). + @see getDistanceFromPoint, getPointAlongLineProportionally + */ + ValueType findNearestProportionalPositionTo (const Point& point) const noexcept + { + const Point delta (end - start); + const double length = delta.getX() * delta.getX() + delta.getY() * delta.getY(); + + return length <= 0 ? 0 + : jlimit ((ValueType) 0, (ValueType) 1, + (ValueType) (((point.getX() - start.getX()) * delta.getX() + + (point.getY() - start.getY()) * delta.getY()) / length)); + } + + /** Finds the point on this line which is nearest to a given point. + @see getDistanceFromPoint, findNearestProportionalPositionTo + */ + Point findNearestPointTo (const Point& point) const noexcept + { + return getPointAlongLineProportionally (findNearestProportionalPositionTo (point)); + } + + /** Returns true if the given point lies above this line. + + The return value is true if the point's y coordinate is less than the y + coordinate of this line at the given x (assuming the line extends infinitely + in both directions). + */ + bool isPointAbove (const Point& point) const noexcept + { + return start.getX() != end.getX() + && point.getY() < ((end.getY() - start.getY()) + * (point.getX() - start.getX())) / (end.getX() - start.getX()) + start.getY(); + } + + /** Returns a shortened copy of this line. + + This will chop off part of the start of this line by a certain amount, (leaving the + end-point the same), and return the new line. + */ + Line withShortenedStart (ValueType distanceToShortenBy) const noexcept + { + return Line (getPointAlongLine (jmin (distanceToShortenBy, getLength())), end); + } + + /** Returns a shortened copy of this line. + + This will chop off part of the end of this line by a certain amount, (leaving the + start-point the same), and return the new line. + */ + Line withShortenedEnd (ValueType distanceToShortenBy) const noexcept + { + const ValueType length = getLength(); + return Line (start, getPointAlongLine (length - jmin (distanceToShortenBy, length))); + } + +private: + + Point start, end; + + static bool findIntersection (const Point& p1, const Point& p2, + const Point& p3, const Point& p4, + Point& intersection) noexcept + { + if (p2 == p3) + { + intersection = p2; + return true; + } + + const Point d1 (p2 - p1); + const Point d2 (p4 - p3); + const ValueType divisor = d1.getX() * d2.getY() - d2.getX() * d1.getY(); + + if (divisor == 0) + { + if (! (d1.isOrigin() || d2.isOrigin())) + { + if (d1.getY() == 0 && d2.getY() != 0) + { + const ValueType along = (p1.getY() - p3.getY()) / d2.getY(); + intersection = p1.withX (p3.getX() + along * d2.getX()); + return along >= 0 && along <= (ValueType) 1; + } + else if (d2.getY() == 0 && d1.getY() != 0) + { + const ValueType along = (p3.getY() - p1.getY()) / d1.getY(); + intersection = p3.withX (p1.getX() + along * d1.getX()); + return along >= 0 && along <= (ValueType) 1; + } + else if (d1.getX() == 0 && d2.getX() != 0) + { + const ValueType along = (p1.getX() - p3.getX()) / d2.getX(); + intersection = p1.withY (p3.getY() + along * d2.getY()); + return along >= 0 && along <= (ValueType) 1; + } + else if (d2.getX() == 0 && d1.getX() != 0) + { + const ValueType along = (p3.getX() - p1.getX()) / d1.getX(); + intersection = p3.withY (p1.getY() + along * d1.getY()); + return along >= 0 && along <= (ValueType) 1; + } + } + + intersection = (p2 + p3) / (ValueType) 2; + return false; + } + + const ValueType along1 = ((p1.getY() - p3.getY()) * d2.getX() - (p1.getX() - p3.getX()) * d2.getY()) / divisor; + intersection = p1 + d1 * along1; + + if (along1 < 0 || along1 > (ValueType) 1) + return false; + + const ValueType along2 = ((p1.getY() - p3.getY()) * d1.getX() - (p1.getX() - p3.getX()) * d1.getY()) / divisor; + return along2 >= 0 && along2 <= (ValueType) 1; + } +}; + +#endif // __JUCE_LINE_JUCEHEADER__ + +/*** End of inlined file: juce_Line.h ***/ + + +/*** Start of inlined file: juce_Justification.h ***/ +#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__ +#define __JUCE_JUSTIFICATION_JUCEHEADER__ + +/** + Represents a type of justification to be used when positioning graphical items. + + e.g. it indicates whether something should be placed top-left, top-right, + centred, etc. + + It is used in various places wherever this kind of information is needed. +*/ +class JUCE_API Justification +{ +public: + + /** Creates a Justification object using a combination of flags. */ + inline Justification (int flags_) noexcept : flags (flags_) {} + + /** Creates a copy of another Justification object. */ + Justification (const Justification& other) noexcept; + + /** Copies another Justification object. */ + Justification& operator= (const Justification& other) noexcept; + + bool operator== (const Justification& other) const noexcept { return flags == other.flags; } + bool operator!= (const Justification& other) const noexcept { return flags != other.flags; } + + /** Returns the raw flags that are set for this Justification object. */ + inline int getFlags() const noexcept { return flags; } + + /** Tests a set of flags for this object. + + @returns true if any of the flags passed in are set on this object. + */ + inline bool testFlags (int flagsToTest) const noexcept { return (flags & flagsToTest) != 0; } + + /** Returns just the flags from this object that deal with vertical layout. */ + int getOnlyVerticalFlags() const noexcept; + + /** Returns just the flags from this object that deal with horizontal layout. */ + int getOnlyHorizontalFlags() const noexcept; + + /** Adjusts the position of a rectangle to fit it into a space. + + The (x, y) position of the rectangle will be updated to position it inside the + given space according to the justification flags. + */ + template + void applyToRectangle (ValueType& x, ValueType& y, ValueType w, ValueType h, + ValueType spaceX, ValueType spaceY, ValueType spaceW, ValueType spaceH) const noexcept + { + x = spaceX; + if ((flags & horizontallyCentred) != 0) x += (spaceW - w) / (ValueType) 2; + else if ((flags & right) != 0) x += spaceW - w; + + y = spaceY; + if ((flags & verticallyCentred) != 0) y += (spaceH - h) / (ValueType) 2; + else if ((flags & bottom) != 0) y += spaceH - h; + } + + /** Returns the new position of a rectangle that has been justified to fit within a given space. + */ + template + const Rectangle appliedToRectangle (const Rectangle& areaToAdjust, + const Rectangle& targetSpace) const noexcept + { + ValueType x = areaToAdjust.getX(), y = areaToAdjust.getY(); + applyToRectangle (x, y, areaToAdjust.getWidth(), areaToAdjust.getHeight(), + targetSpace.getX(), targetSpace.getY(), targetSpace.getWidth(), targetSpace.getHeight()); + return areaToAdjust.withPosition (x, y); + } + + /** Flag values that can be combined and used in the constructor. */ + enum + { + + /** Indicates that the item should be aligned against the left edge of the available space. */ + left = 1, + + /** Indicates that the item should be aligned against the right edge of the available space. */ + right = 2, + + /** Indicates that the item should be placed in the centre between the left and right + sides of the available space. */ + horizontallyCentred = 4, + + /** Indicates that the item should be aligned against the top edge of the available space. */ + top = 8, + + /** Indicates that the item should be aligned against the bottom edge of the available space. */ + bottom = 16, + + /** Indicates that the item should be placed in the centre between the top and bottom + sides of the available space. */ + verticallyCentred = 32, + + /** Indicates that lines of text should be spread out to fill the maximum width + available, so that both margins are aligned vertically. + */ + horizontallyJustified = 64, + + /** Indicates that the item should be centred vertically and horizontally. + This is equivalent to (horizontallyCentred | verticallyCentred) + */ + centred = 36, + + /** Indicates that the item should be centred vertically but placed on the left hand side. + This is equivalent to (left | verticallyCentred) + */ + centredLeft = 33, + + /** Indicates that the item should be centred vertically but placed on the right hand side. + This is equivalent to (right | verticallyCentred) + */ + centredRight = 34, + + /** Indicates that the item should be centred horizontally and placed at the top. + This is equivalent to (horizontallyCentred | top) + */ + centredTop = 12, + + /** Indicates that the item should be centred horizontally and placed at the bottom. + This is equivalent to (horizontallyCentred | bottom) + */ + centredBottom = 20, + + /** Indicates that the item should be placed in the top-left corner. + This is equivalent to (left | top) + */ + topLeft = 9, + + /** Indicates that the item should be placed in the top-right corner. + This is equivalent to (right | top) + */ + topRight = 10, + + /** Indicates that the item should be placed in the bottom-left corner. + This is equivalent to (left | bottom) + */ + bottomLeft = 17, + + /** Indicates that the item should be placed in the bottom-left corner. + This is equivalent to (right | bottom) + */ + bottomRight = 18 + }; + +private: + + int flags; +}; + +#endif // __JUCE_JUSTIFICATION_JUCEHEADER__ + +/*** End of inlined file: juce_Justification.h ***/ + +class Image; +class InputStream; +class OutputStream; + +/** + A path is a sequence of lines and curves that may either form a closed shape + or be open-ended. + + To use a path, you can create an empty one, then add lines and curves to it + to create shapes, then it can be rendered by a Graphics context or used + for geometric operations. + + e.g. @code + Path myPath; + + myPath.startNewSubPath (10.0f, 10.0f); // move the current position to (10, 10) + myPath.lineTo (100.0f, 200.0f); // draw a line from here to (100, 200) + myPath.quadraticTo (0.0f, 150.0f, 5.0f, 50.0f); // draw a curve that ends at (5, 50) + myPath.closeSubPath(); // close the subpath with a line back to (10, 10) + + // add an ellipse as well, which will form a second sub-path within the path.. + myPath.addEllipse (50.0f, 50.0f, 40.0f, 30.0f); + + // double the width of the whole thing.. + myPath.applyTransform (AffineTransform::scale (2.0f, 1.0f)); + + // and draw it to a graphics context with a 5-pixel thick outline. + g.strokePath (myPath, PathStrokeType (5.0f)); + + @endcode + + A path object can actually contain multiple sub-paths, which may themselves + be open or closed. + + @see PathFlatteningIterator, PathStrokeType, Graphics +*/ +class JUCE_API Path +{ +public: + + /** Creates an empty path. */ + Path(); + + /** Creates a copy of another path. */ + Path (const Path& other); + + /** Destructor. */ + ~Path(); + + /** Copies this path from another one. */ + Path& operator= (const Path& other); + + bool operator== (const Path& other) const noexcept; bool operator!= (const Path& other) const noexcept; /** Returns true if the path doesn't contain any lines or curves. */ @@ -26286,12 +26739,12 @@ public: /** Returns the smallest rectangle that contains all points within the path. */ - const Rectangle getBounds() const noexcept; + Rectangle getBounds() const noexcept; /** Returns the smallest rectangle that contains all points within the path after it's been transformed with the given tranasform matrix. */ - const Rectangle getBoundsTransformed (const AffineTransform& transform) const noexcept; + Rectangle getBoundsTransformed (const AffineTransform& transform) const noexcept; /** Checks whether a point lies within the path. @@ -26350,7 +26803,7 @@ public: that will be kept; if false its the section inside the path */ - const Line getClippedLine (const Line& line, bool keepSectionOutsidePath) const; + Line getClippedLine (const Line& line, bool keepSectionOutsidePath) const; /** Returns the length of the path. @see getPointAlongPath @@ -26362,8 +26815,8 @@ public: end point. @see getLength */ - const Point getPointAlongPath (float distanceFromStart, - const AffineTransform& transform = AffineTransform::identity) const; + Point getPointAlongPath (float distanceFromStart, + const AffineTransform& transform = AffineTransform::identity) const; /** Finds the point along the path which is nearest to a given position. This sets pointOnPath to the nearest point, and returns the distance of this point from the start @@ -26495,7 +26948,7 @@ public: /** Returns the last point that was added to the path by one of the drawing methods. */ - const Point getCurrentPosition() const; + Point getCurrentPosition() const; /** Adds a rectangle to the path. The rectangle is added as a new sub-path. (Any currently open paths will be left open). @@ -26794,16 +27247,16 @@ public: @see applyTransform, scaleToFit */ - const AffineTransform getTransformToScaleToFit (float x, float y, float width, float height, - bool preserveProportions, - const Justification& justificationType = Justification::centred) const; + AffineTransform getTransformToScaleToFit (float x, float y, float width, float height, + bool preserveProportions, + const Justification& justificationType = Justification::centred) const; /** Creates a version of this path where all sharp corners have been replaced by curves. Wherever two lines meet at an angle, this will replace the corner with a curve of the given radius. */ - const Path createPathWithRoundedCorners (float cornerRadius) const; + Path createPathWithRoundedCorners (float cornerRadius) const; /** Changes the winding-rule to be used when filling the path. @@ -26901,7 +27354,7 @@ public: /** Creates a string containing a textual representation of this path. @see restoreFromString */ - const String toString() const; + String toString() const; /** Restores this path from a string that was created with the toString() method. @see toString() @@ -26930,669 +27383,112 @@ private: /*** End of inlined file: juce_Path.h ***/ -class Font; -class EdgeTable; - -/** A typeface represents a size-independent font. - - This base class is abstract, but calling createSystemTypefaceFor() will return - a platform-specific subclass that can be used. - - The CustomTypeface subclass allow you to build your own typeface, and to - load and save it in the Juce typeface format. +/** + Describes a type of stroke used to render a solid outline along a path. - Normally you should never need to deal directly with Typeface objects - the Font - class does everything you typically need for rendering text. + A PathStrokeType object can be used directly to create the shape of an outline + around a path, and is used by Graphics::strokePath to specify the type of + stroke to draw. - @see CustomTypeface, Font + @see Path, Graphics::strokePath */ -class JUCE_API Typeface : public ReferenceCountedObject +class JUCE_API PathStrokeType { public: - /** A handy typedef for a pointer to a typeface. */ - typedef ReferenceCountedObjectPtr Ptr; - - /** Returns the name of the typeface. - @see Font::getTypefaceName - */ - const String getName() const noexcept { return name; } - - /** Creates a new system typeface. */ - static const Ptr createSystemTypefaceFor (const Font& font); - - /** Destructor. */ - virtual ~Typeface(); + /** The type of shape to use for the corners between two adjacent line segments. */ + enum JointStyle + { + mitered, /**< Indicates that corners should be drawn with sharp joints. + Note that for angles that curve back on themselves, drawing a + mitre could require extending the point too far away from the + path, so a mitre limit is imposed and any corners that exceed it + are drawn as bevelled instead. */ + curved, /**< Indicates that corners should be drawn as rounded-off. */ + beveled /**< Indicates that corners should be drawn with a line flattening their + outside edge. */ + }; - /** Returns true if this typeface can be used to render the specified font. - When called, the font will already have been checked to make sure that its name and - style flags match the typeface. - */ - virtual bool isSuitableForFont (const Font&) const { return true; } + /** The type shape to use for the ends of lines. */ + enum EndCapStyle + { + butt, /**< Ends of lines are flat and don't extend beyond the end point. */ + square, /**< Ends of lines are flat, but stick out beyond the end point for half + the thickness of the stroke. */ + rounded /**< Ends of lines are rounded-off with a circular shape. */ + }; - /** Returns the ascent of the font, as a proportion of its height. - The height is considered to always be normalised as 1.0, so this will be a - value less that 1.0, indicating the proportion of the font that lies above - its baseline. - */ - virtual float getAscent() const = 0; + /** Creates a stroke type. - /** Returns the descent of the font, as a proportion of its height. - The height is considered to always be normalised as 1.0, so this will be a - value less that 1.0, indicating the proportion of the font that lies below - its baseline. + @param strokeThickness the width of the line to use + @param jointStyle the type of joints to use for corners + @param endStyle the type of end-caps to use for the ends of open paths. */ - virtual float getDescent() const = 0; + PathStrokeType (float strokeThickness, + JointStyle jointStyle = mitered, + EndCapStyle endStyle = butt) noexcept; - /** Measures the width of a line of text. + /** Createes a copy of another stroke type. */ + PathStrokeType (const PathStrokeType& other) noexcept; - The distance returned is based on the font having an normalised height of 1.0. + /** Copies another stroke onto this one. */ + PathStrokeType& operator= (const PathStrokeType& other) noexcept; - You should never need to call this directly! Use Font::getStringWidth() instead! - */ - virtual float getStringWidth (const String& text) = 0; + /** Destructor. */ + ~PathStrokeType() noexcept; - /** Converts a line of text into its glyph numbers and their positions. + /** Applies this stroke type to a path and returns the resultant stroke as another Path. - The distances returned are based on the font having an normalised height of 1.0. + @param destPath the resultant stroked outline shape will be copied into this path. + Note that it's ok for the source and destination Paths to be + the same object, so you can easily turn a path into a stroked version + of itself. + @param sourcePath the path to use as the source + @param transform an optional transform to apply to the points from the source path + as they are being used + @param extraAccuracy if this is greater than 1.0, it will subdivide the path to + a higher resolution, which improves the quality if you'll later want + to enlarge the stroked path. So for example, if you're planning on drawing + the stroke at 3x the size that you're creating it, you should set this to 3. - You should never need to call this directly! Use Font::getGlyphPositions() instead! + @see createDashedStroke */ - virtual void getGlyphPositions (const String& text, Array & glyphs, Array& xOffsets) = 0; + void createStrokedPath (Path& destPath, + const Path& sourcePath, + const AffineTransform& transform = AffineTransform::identity, + float extraAccuracy = 1.0f) const; - /** Returns the outline for a glyph. + /** Applies this stroke type to a path, creating a dashed line. - The path returned will be normalised to a font height of 1.0. + This is similar to createStrokedPath, but uses the array passed in to + break the stroke up into a series of dashes. + + @param destPath the resultant stroked outline shape will be copied into this path. + Note that it's ok for the source and destination Paths to be + the same object, so you can easily turn a path into a stroked version + of itself. + @param sourcePath the path to use as the source + @param dashLengths An array of alternating on/off lengths. E.g. { 2, 3, 4, 5 } will create + a line of length 2, then skip a length of 3, then add a line of length 4, + skip 5, and keep repeating this pattern. + @param numDashLengths The number of lengths in the dashLengths array. This should really be + an even number, otherwise the pattern will get out of step as it + repeats. + @param transform an optional transform to apply to the points from the source path + as they are being used + @param extraAccuracy if this is greater than 1.0, it will subdivide the path to + a higher resolution, which improves the quality if you'll later want + to enlarge the stroked path. So for example, if you're planning on drawing + the stroke at 3x the size that you're creating it, you should set this to 3. */ - virtual bool getOutlineForGlyph (int glyphNumber, Path& path) = 0; + void createDashedStroke (Path& destPath, + const Path& sourcePath, + const float* dashLengths, + int numDashLengths, + const AffineTransform& transform = AffineTransform::identity, + float extraAccuracy = 1.0f) const; - /** Returns a new EdgeTable that contains the path for the givem glyph, with the specified transform applied. */ - virtual EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform) = 0; - - /** Returns true if the typeface uses hinting. */ - virtual bool isHinted() const { return false; } - - /** Changes the number of fonts that are cached in memory. */ - static void setTypefaceCacheSize (int numFontsToCache); - -protected: - - String name; - bool isFallbackFont; - - explicit Typeface (const String& name) noexcept; - - static const Ptr getFallbackTypeface(); - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Typeface); -}; - -/** A typeface that can be populated with custom glyphs. - - You can create a CustomTypeface if you need one that contains your own glyphs, - or if you need to load a typeface from a Juce-formatted binary stream. - - If you want to create a copy of a native face, you can use addGlyphsFromOtherTypeface() - to copy glyphs into this face. - - @see Typeface, Font -*/ -class JUCE_API CustomTypeface : public Typeface -{ -public: - - /** Creates a new, empty typeface. */ - CustomTypeface(); - - /** Loads a typeface from a previously saved stream. - The stream must have been created by writeToStream(). - @see writeToStream - */ - explicit CustomTypeface (InputStream& serialisedTypefaceStream); - - /** Destructor. */ - ~CustomTypeface(); - - /** Resets this typeface, deleting all its glyphs and settings. */ - void clear(); - - /** Sets the vital statistics for the typeface. - @param name the typeface's name - @param ascent the ascent - this is normalised to a height of 1.0 and this is - the value that will be returned by Typeface::getAscent(). The - descent is assumed to be (1.0 - ascent) - @param isBold should be true if the typeface is bold - @param isItalic should be true if the typeface is italic - @param defaultCharacter the character to be used as a replacement if there's - no glyph available for the character that's being drawn - */ - void setCharacteristics (const String& name, float ascent, - bool isBold, bool isItalic, - juce_wchar defaultCharacter) noexcept; - - /** Adds a glyph to the typeface. - - The path that is passed in is normalised so that the font height is 1.0, and its - origin is the anchor point of the character on its baseline. - - The width is the nominal width of the character, and any extra kerning values that - are specified will be added to this width. - */ - void addGlyph (juce_wchar character, const Path& path, float width) noexcept; - - /** Specifies an extra kerning amount to be used between a pair of characters. - The amount will be added to the nominal width of the first character when laying out a string. - */ - void addKerningPair (juce_wchar char1, juce_wchar char2, float extraAmount) noexcept; - - /** Adds a range of glyphs from another typeface. - This will attempt to pull in the paths and kerning information from another typeface and - add it to this one. - */ - void addGlyphsFromOtherTypeface (Typeface& typefaceToCopy, juce_wchar characterStartIndex, int numCharacters) noexcept; - - /** Saves this typeface as a Juce-formatted font file. - A CustomTypeface can be created to reload the data that is written - see the CustomTypeface - constructor. - */ - bool writeToStream (OutputStream& outputStream); - - // The following methods implement the basic Typeface behaviour. - float getAscent() const; - float getDescent() const; - float getStringWidth (const String& text); - void getGlyphPositions (const String& text, Array & glyphs, Array& xOffsets); - bool getOutlineForGlyph (int glyphNumber, Path& path); - EdgeTable* getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform); - int getGlyphForCharacter (juce_wchar character); - -protected: - - juce_wchar defaultCharacter; - float ascent; - bool isBold, isItalic; - - /** If a subclass overrides this, it can load glyphs into the font on-demand. - When methods such as getGlyphPositions() or getOutlineForGlyph() are asked for a - particular character and there's no corresponding glyph, they'll call this - method so that a subclass can try to add that glyph, returning true if it - manages to do so. - */ - virtual bool loadGlyphIfPossible (juce_wchar characterNeeded); - -private: - - class GlyphInfo; - friend class OwnedArray; - OwnedArray glyphs; - short lookupTable [128]; - - GlyphInfo* findGlyph (const juce_wchar character, bool loadIfNeeded) noexcept; - GlyphInfo* findGlyphSubstituting (juce_wchar character) noexcept; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomTypeface); -}; - -#endif // __JUCE_TYPEFACE_JUCEHEADER__ - -/*** End of inlined file: juce_Typeface.h ***/ - -class LowLevelGraphicsContext; - -/** - Represents a particular font, including its size, style, etc. - - Apart from the typeface to be used, a Font object also dictates whether - the font is bold, italic, underlined, how big it is, and its kerning and - horizontal scale factor. - - @see Typeface -*/ -class JUCE_API Font -{ -public: - - /** A combination of these values is used by the constructor to specify the - style of font to use. - */ - enum FontStyleFlags - { - plain = 0, /**< indicates a plain, non-bold, non-italic version of the font. @see setStyleFlags */ - bold = 1, /**< boldens the font. @see setStyleFlags */ - italic = 2, /**< finds an italic version of the font. @see setStyleFlags */ - underlined = 4 /**< underlines the font. @see setStyleFlags */ - }; - - /** Creates a sans-serif font in a given size. - - @param fontHeight the height in pixels (can be fractional) - @param styleFlags the style to use - this can be a combination of the - Font::bold, Font::italic and Font::underlined, or - just Font::plain for the normal style. - @see FontStyleFlags, getDefaultSansSerifFontName - */ - Font (float fontHeight, int styleFlags = plain); - - /** Creates a font with a given typeface and parameters. - - @param typefaceName the name of the typeface to use - @param fontHeight the height in pixels (can be fractional) - @param styleFlags the style to use - this can be a combination of the - Font::bold, Font::italic and Font::underlined, or - just Font::plain for the normal style. - @see FontStyleFlags, getDefaultSansSerifFontName - */ - Font (const String& typefaceName, float fontHeight, int styleFlags); - - /** Creates a copy of another Font object. */ - Font (const Font& other) noexcept; - - /** Creates a font for a typeface. */ - Font (const Typeface::Ptr& typeface); - - /** Creates a basic sans-serif font at a default height. - - You should use one of the other constructors for creating a font that you're planning - on drawing with - this constructor is here to help initialise objects before changing - the font's settings later. - */ - Font(); - - /** Copies this font from another one. */ - Font& operator= (const Font& other) noexcept; - - bool operator== (const Font& other) const noexcept; - bool operator!= (const Font& other) const noexcept; - - /** Destructor. */ - ~Font() noexcept; - - /** Changes the name of the typeface family. - - e.g. "Arial", "Courier", etc. - - This may also be set to Font::getDefaultSansSerifFontName(), Font::getDefaultSerifFontName(), - or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font names, - but are generic names that are used to represent the various default fonts. - If you need to know the exact typeface name being used, you can call - Font::getTypeface()->getTypefaceName(), which will give you the platform-specific name. - - If a suitable font isn't found on the machine, it'll just use a default instead. - */ - void setTypefaceName (const String& faceName); - - /** Returns the name of the typeface family that this font uses. - - e.g. "Arial", "Courier", etc. - - This may also be set to Font::getDefaultSansSerifFontName(), Font::getDefaultSerifFontName(), - or Font::getDefaultMonospacedFontName(), which are not actual platform-specific font names, - but are generic names that are used to represent the various default fonts. - - If you need to know the exact typeface name being used, you can call - Font::getTypeface()->getTypefaceName(), which will give you the platform-specific name. - */ - const String& getTypefaceName() const noexcept { return font->typefaceName; } - - /** Returns a typeface name that represents the default sans-serif font. - - This is also the typeface that will be used when a font is created without - specifying any typeface details. - - Note that this method just returns a generic placeholder string that means "the default - sans-serif font" - it's not the actual name of this font. To get the actual name, use - getPlatformDefaultFontNames() or LookAndFeel::getTypefaceForFont(). - - @see setTypefaceName, getDefaultSerifFontName, getDefaultMonospacedFontName - */ - static const String getDefaultSansSerifFontName(); - - /** Returns a typeface name that represents the default sans-serif font. - - Note that this method just returns a generic placeholder string that means "the default - serif font" - it's not the actual name of this font. To get the actual name, use - getPlatformDefaultFontNames() or LookAndFeel::getTypefaceForFont(). - - @see setTypefaceName, getDefaultSansSerifFontName, getDefaultMonospacedFontName - */ - static const String getDefaultSerifFontName(); - - /** Returns a typeface name that represents the default sans-serif font. - - Note that this method just returns a generic placeholder string that means "the default - monospaced font" - it's not the actual name of this font. To get the actual name, use - getPlatformDefaultFontNames() or LookAndFeel::getTypefaceForFont(). - - @see setTypefaceName, getDefaultSansSerifFontName, getDefaultSerifFontName - */ - static const String getDefaultMonospacedFontName(); - - /** Returns the typeface names of the default fonts on the current platform. */ - static void getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& defaultFallback); - - /** Returns the total height of this font. - - This is the maximum height, from the top of the ascent to the bottom of the - descenders. - - @see setHeight, setHeightWithoutChangingWidth, getAscent - */ - float getHeight() const noexcept { return font->height; } - - /** Changes the font's height. - - @see getHeight, setHeightWithoutChangingWidth - */ - void setHeight (float newHeight); - - /** Changes the font's height without changing its width. - - This alters the horizontal scale to compensate for the change in height. - */ - void setHeightWithoutChangingWidth (float newHeight); - - /** Returns the height of the font above its baseline. - - This is the maximum height from the baseline to the top. - - @see getHeight, getDescent - */ - float getAscent() const; - - /** Returns the amount that the font descends below its baseline. - - This is calculated as (getHeight() - getAscent()). - - @see getAscent, getHeight - */ - float getDescent() const; - - /** Returns the font's style flags. - - This will return a bitwise-or'ed combination of values from the FontStyleFlags - enum, to describe whether the font is bold, italic, etc. - - @see FontStyleFlags - */ - int getStyleFlags() const noexcept { return font->styleFlags; } - - /** Changes the font's style. - - @param newFlags a bitwise-or'ed combination of values from the FontStyleFlags - enum, to set the font's properties - @see FontStyleFlags - */ - void setStyleFlags (int newFlags); - - /** Makes the font bold or non-bold. */ - void setBold (bool shouldBeBold); - /** Returns a copy of this font with the bold attribute set. */ - const Font boldened() const; - /** Returns true if the font is bold. */ - bool isBold() const noexcept; - - /** Makes the font italic or non-italic. */ - void setItalic (bool shouldBeItalic); - /** Returns a copy of this font with the italic attribute set. */ - const Font italicised() const; - /** Returns true if the font is italic. */ - bool isItalic() const noexcept; - - /** Makes the font underlined or non-underlined. */ - void setUnderline (bool shouldBeUnderlined); - /** Returns true if the font is underlined. */ - bool isUnderlined() const noexcept; - - /** Changes the font's horizontal scale factor. - - @param scaleFactor a value of 1.0 is the normal scale, less than this will be - narrower, greater than 1.0 will be stretched out. - */ - void setHorizontalScale (float scaleFactor); - - /** Returns the font's horizontal scale. - - A value of 1.0 is the normal scale, less than this will be narrower, greater - than 1.0 will be stretched out. - - @see setHorizontalScale - */ - float getHorizontalScale() const noexcept { return font->horizontalScale; } - - /** Changes the font's kerning. - - @param extraKerning a multiple of the font's height that will be added - to space between the characters. So a value of zero is - normal spacing, positive values spread the letters out, - negative values make them closer together. - */ - void setExtraKerningFactor (float extraKerning); - - /** Returns the font's kerning. - - This is the extra space added between adjacent characters, as a proportion - of the font's height. - - A value of zero is normal spacing, positive values will spread the letters - out more, and negative values make them closer together. - */ - float getExtraKerningFactor() const noexcept { return font->kerning; } - - /** Changes all the font's characteristics with one call. */ - void setSizeAndStyle (float newHeight, - int newStyleFlags, - float newHorizontalScale, - float newKerningAmount); - - /** Returns the total width of a string as it would be drawn using this font. - - For a more accurate floating-point result, use getStringWidthFloat(). - */ - int getStringWidth (const String& text) const; - - /** Returns the total width of a string as it would be drawn using this font. - - @see getStringWidth - */ - float getStringWidthFloat (const String& text) const; - - /** Returns the series of glyph numbers and their x offsets needed to represent a string. - - An extra x offset is added at the end of the run, to indicate where the right hand - edge of the last character is. - */ - void getGlyphPositions (const String& text, Array & glyphs, Array & xOffsets) const; - - /** Returns the typeface used by this font. - - Note that the object returned may go out of scope if this font is deleted - or has its style changed. - */ - Typeface* getTypeface() const; - - /** Creates an array of Font objects to represent all the fonts on the system. - - If you just need the names of the typefaces, you can also use - findAllTypefaceNames() instead. - - @param results the array to which new Font objects will be added. - */ - static void findFonts (Array& results); - - /** Returns a list of all the available typeface names. - - The names returned can be passed into setTypefaceName(). - - You can use this instead of findFonts() if you only need their names, and not - font objects. - */ - static const StringArray findAllTypefaceNames(); - - /** Returns the name of the typeface to be used for rendering glyphs that aren't found - in the requested typeface. - */ - static const String getFallbackFontName(); - - /** Sets the (platform-specific) name of the typeface to use to find glyphs that aren't - available in whatever font you're trying to use. - */ - static void setFallbackFontName (const String& name); - - /** Creates a string to describe this font. - The string will contain information to describe the font's typeface, size, and - style. To recreate the font from this string, use fromString(). - */ - const String toString() const; - - /** Recreates a font from its stringified encoding. - This method takes a string that was created by toString(), and recreates the - original font. - */ - static const Font fromString (const String& fontDescription); - -private: - - friend class FontGlyphAlphaMap; - friend class TypefaceCache; - - class SharedFontInternal : public ReferenceCountedObject - { - public: - SharedFontInternal (float height, int styleFlags) noexcept; - SharedFontInternal (const String& typefaceName, float height, int styleFlags) noexcept; - SharedFontInternal (const Typeface::Ptr& typeface) noexcept; - SharedFontInternal (const SharedFontInternal& other) noexcept; - - bool operator== (const SharedFontInternal&) const noexcept; - - String typefaceName; - float height, horizontalScale, kerning, ascent; - int styleFlags; - Typeface::Ptr typeface; - }; - - ReferenceCountedObjectPtr font; - void dupeInternalIfShared(); - - JUCE_LEAK_DETECTOR (Font); -}; - -#endif // __JUCE_FONT_JUCEHEADER__ - -/*** End of inlined file: juce_Font.h ***/ - - -/*** Start of inlined file: juce_PathStrokeType.h ***/ -#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__ -#define __JUCE_PATHSTROKETYPE_JUCEHEADER__ - -/** - Describes a type of stroke used to render a solid outline along a path. - - A PathStrokeType object can be used directly to create the shape of an outline - around a path, and is used by Graphics::strokePath to specify the type of - stroke to draw. - - @see Path, Graphics::strokePath -*/ -class JUCE_API PathStrokeType -{ -public: - - /** The type of shape to use for the corners between two adjacent line segments. */ - enum JointStyle - { - mitered, /**< Indicates that corners should be drawn with sharp joints. - Note that for angles that curve back on themselves, drawing a - mitre could require extending the point too far away from the - path, so a mitre limit is imposed and any corners that exceed it - are drawn as bevelled instead. */ - curved, /**< Indicates that corners should be drawn as rounded-off. */ - beveled /**< Indicates that corners should be drawn with a line flattening their - outside edge. */ - }; - - /** The type shape to use for the ends of lines. */ - enum EndCapStyle - { - butt, /**< Ends of lines are flat and don't extend beyond the end point. */ - square, /**< Ends of lines are flat, but stick out beyond the end point for half - the thickness of the stroke. */ - rounded /**< Ends of lines are rounded-off with a circular shape. */ - }; - - /** Creates a stroke type. - - @param strokeThickness the width of the line to use - @param jointStyle the type of joints to use for corners - @param endStyle the type of end-caps to use for the ends of open paths. - */ - PathStrokeType (float strokeThickness, - JointStyle jointStyle = mitered, - EndCapStyle endStyle = butt) noexcept; - - /** Createes a copy of another stroke type. */ - PathStrokeType (const PathStrokeType& other) noexcept; - - /** Copies another stroke onto this one. */ - PathStrokeType& operator= (const PathStrokeType& other) noexcept; - - /** Destructor. */ - ~PathStrokeType() noexcept; - - /** Applies this stroke type to a path and returns the resultant stroke as another Path. - - @param destPath the resultant stroked outline shape will be copied into this path. - Note that it's ok for the source and destination Paths to be - the same object, so you can easily turn a path into a stroked version - of itself. - @param sourcePath the path to use as the source - @param transform an optional transform to apply to the points from the source path - as they are being used - @param extraAccuracy if this is greater than 1.0, it will subdivide the path to - a higher resolution, which improves the quality if you'll later want - to enlarge the stroked path. So for example, if you're planning on drawing - the stroke at 3x the size that you're creating it, you should set this to 3. - - @see createDashedStroke - */ - void createStrokedPath (Path& destPath, - const Path& sourcePath, - const AffineTransform& transform = AffineTransform::identity, - float extraAccuracy = 1.0f) const; - - /** Applies this stroke type to a path, creating a dashed line. - - This is similar to createStrokedPath, but uses the array passed in to - break the stroke up into a series of dashes. - - @param destPath the resultant stroked outline shape will be copied into this path. - Note that it's ok for the source and destination Paths to be - the same object, so you can easily turn a path into a stroked version - of itself. - @param sourcePath the path to use as the source - @param dashLengths An array of alternating on/off lengths. E.g. { 2, 3, 4, 5 } will create - a line of length 2, then skip a length of 3, then add a line of length 4, - skip 5, and keep repeating this pattern. - @param numDashLengths The number of lengths in the dashLengths array. This should really be - an even number, otherwise the pattern will get out of step as it - repeats. - @param transform an optional transform to apply to the points from the source path - as they are being used - @param extraAccuracy if this is greater than 1.0, it will subdivide the path to - a higher resolution, which improves the quality if you'll later want - to enlarge the stroked path. So for example, if you're planning on drawing - the stroke at 3x the size that you're creating it, you should set this to 3. - */ - void createDashedStroke (Path& destPath, - const Path& sourcePath, - const float* dashLengths, - int numDashLengths, - const AffineTransform& transform = AffineTransform::identity, - float extraAccuracy = 1.0f) const; - - /** Applies this stroke type to a path and returns the resultant stroke as another Path. + /** Applies this stroke type to a path and returns the resultant stroke as another Path. @param destPath the resultant stroked outline shape will be copied into this path. Note that it's ok for the source and destination Paths to be @@ -28267,9 +28163,9 @@ public: uint8 blue) noexcept; /** Creates an opaque colour using 8-bit red, green and blue values */ - static const Colour fromRGB (uint8 red, - uint8 green, - uint8 blue) noexcept; + static Colour fromRGB (uint8 red, + uint8 green, + uint8 blue) noexcept; /** Creates a colour using 8-bit red, green, blue and alpha values. */ Colour (uint8 red, @@ -28278,10 +28174,10 @@ public: uint8 alpha) noexcept; /** Creates a colour using 8-bit red, green, blue and alpha values. */ - static const Colour fromRGBA (uint8 red, - uint8 green, - uint8 blue, - uint8 alpha) noexcept; + static Colour fromRGBA (uint8 red, + uint8 green, + uint8 blue, + uint8 alpha) noexcept; /** Creates a colour from 8-bit red, green, and blue values, and a floating-point alpha. @@ -28294,10 +28190,10 @@ public: float alpha) noexcept; /** Creates a colour using 8-bit red, green, blue and float alpha values. */ - static const Colour fromRGBAFloat (uint8 red, - uint8 green, - uint8 blue, - float alpha) noexcept; + static Colour fromRGBAFloat (uint8 red, + uint8 green, + uint8 blue, + float alpha) noexcept; /** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha. @@ -28326,10 +28222,10 @@ public: An alpha of 0x00 is completely transparent, alpha of 0xff is opaque. Values outside the valid range will be clipped. */ - static const Colour fromHSV (float hue, - float saturation, - float brightness, - float alpha) noexcept; + static Colour fromHSV (float hue, + float saturation, + float brightness, + float alpha) noexcept; /** Destructor. */ ~Colour() noexcept; @@ -28414,30 +28310,30 @@ public: bool isTransparent() const noexcept; /** Returns a colour that's the same colour as this one, but with a new alpha value. */ - const Colour withAlpha (uint8 newAlpha) const noexcept; + Colour withAlpha (uint8 newAlpha) const noexcept; /** Returns a colour that's the same colour as this one, but with a new alpha value. */ - const Colour withAlpha (float newAlpha) const noexcept; + Colour withAlpha (float newAlpha) const noexcept; /** Returns a colour that's the same colour as this one, but with a modified alpha value. The new colour's alpha will be this object's alpha multiplied by the value passed-in. */ - const Colour withMultipliedAlpha (float alphaMultiplier) const noexcept; + Colour withMultipliedAlpha (float alphaMultiplier) const noexcept; /** Returns a colour that is the result of alpha-compositing a new colour over this one. If the foreground colour is semi-transparent, it is blended onto this colour accordingly. */ - const Colour overlaidWith (const Colour& foregroundColour) const noexcept; + Colour overlaidWith (const Colour& foregroundColour) const noexcept; /** Returns a colour that lies somewhere between this one and another. If amountOfOther is zero, the result is 100% this colour, if amountOfOther is 1.0, the result is 100% of the other colour. */ - const Colour interpolatedWith (const Colour& other, float proportionOfOther) const noexcept; + Colour interpolatedWith (const Colour& other, float proportionOfOther) const noexcept; /** Returns the colour's hue component. The value returned is in the range 0.0 to 1.0 @@ -28462,15 +28358,15 @@ public: float& brightness) const noexcept; /** Returns a copy of this colour with a different hue. */ - const Colour withHue (float newHue) const noexcept; + Colour withHue (float newHue) const noexcept; /** Returns a copy of this colour with a different saturation. */ - const Colour withSaturation (float newSaturation) const noexcept; + Colour withSaturation (float newSaturation) const noexcept; /** Returns a copy of this colour with a different brightness. @see brighter, darker, withMultipliedBrightness */ - const Colour withBrightness (float newBrightness) const noexcept; + Colour withBrightness (float newBrightness) const noexcept; /** Returns a copy of this colour with it hue rotated. @@ -28478,21 +28374,21 @@ public: @see brighter, darker, withMultipliedBrightness */ - const Colour withRotatedHue (float amountToRotate) const noexcept; + Colour withRotatedHue (float amountToRotate) const noexcept; /** Returns a copy of this colour with its saturation multiplied by the given value. The new colour's saturation is (this->getSaturation() * multiplier) (the result is clipped to legal limits). */ - const Colour withMultipliedSaturation (float multiplier) const noexcept; + Colour withMultipliedSaturation (float multiplier) const noexcept; /** Returns a copy of this colour with its brightness multiplied by the given value. The new colour's saturation is (this->getBrightness() * multiplier) (the result is clipped to legal limits). */ - const Colour withMultipliedBrightness (float amount) const noexcept; + Colour withMultipliedBrightness (float amount) const noexcept; /** Returns a brighter version of this colour. @@ -28500,7 +28396,7 @@ public: unchanged, and higher values make it brighter @see withMultipliedBrightness */ - const Colour brighter (float amountBrighter = 0.4f) const noexcept; + Colour brighter (float amountBrighter = 0.4f) const noexcept; /** Returns a darker version of this colour. @@ -28508,7 +28404,7 @@ public: unchanged, and higher values make it darker @see withMultipliedBrightness */ - const Colour darker (float amountDarker = 0.4f) const noexcept; + Colour darker (float amountDarker = 0.4f) const noexcept; /** Returns a colour that will be clearly visible against this colour. @@ -28517,7 +28413,7 @@ public: that's just a little bit lighter; Colours::black.contrasting (1.0f) will return white; Colours::white.contrasting (1.0f) will return black, etc. */ - const Colour contrasting (float amount = 1.0f) const noexcept; + Colour contrasting (float amount = 1.0f) const noexcept; /** Returns a colour that contrasts against two colours. @@ -28525,27 +28421,27 @@ public: Handy for things like choosing a highlight colour in text editors, etc. */ - static const Colour contrasting (const Colour& colour1, - const Colour& colour2) noexcept; + static Colour contrasting (const Colour& colour1, + const Colour& colour2) noexcept; /** Returns an opaque shade of grey. @param brightness the level of grey to return - 0 is black, 1.0 is white */ - static const Colour greyLevel (float brightness) noexcept; + static Colour greyLevel (float brightness) noexcept; /** Returns a stringified version of this colour. The string can be turned back into a colour using the fromString() method. */ - const String toString() const; + String toString() const; /** Reads the colour from a string that was created with toString(). */ - static const Colour fromString (const String& encodedColourString); + static Colour fromString (const String& encodedColourString); /** Returns the colour as a hex string in the form RRGGBB or AARRGGBB. */ - const String toDisplayString (bool includeAlphaValue) const; + String toDisplayString (bool includeAlphaValue) const; private: @@ -28728,7 +28624,7 @@ public: /** Returns the an interpolated colour at any position along the gradient. @param position the position along the gradient, between 0 and 1 */ - const Colour getColourAtPosition (double position) const noexcept; + Colour getColourAtPosition (double position) const noexcept; /** Creates a set of interpolated premultiplied ARGB values. This will resize the HeapBlock, fill it with the colours, and will return the number of @@ -29013,7 +28909,7 @@ public: void setFont (float newFontHeight, int fontStyleFlags = Font::plain); /** Returns the currently selected font. */ - const Font getCurrentFont() const; + Font getCurrentFont() const; /** Draws a one-line text string. @@ -29768,8 +29664,8 @@ public: Note that if the new size is identical to the existing image, this will just return a reference to the original image, and won't actually create a duplicate. */ - const Image rescaled (int newWidth, int newHeight, - Graphics::ResamplingQuality quality = Graphics::mediumResamplingQuality) const; + Image rescaled (int newWidth, int newHeight, + Graphics::ResamplingQuality quality = Graphics::mediumResamplingQuality) const; /** Returns a version of this image with a different image format. @@ -29778,7 +29674,7 @@ public: Note that if the new format is no different to the current one, this will just return a reference to the original image, and won't actually create a copy. */ - const Image convertedToFormat (PixelFormat newFormat) const; + Image convertedToFormat (PixelFormat newFormat) const; /** Makes sure that no other Image objects share the same underlying data as this one. @@ -29804,7 +29700,7 @@ public: The area passed-in will be clipped to the bounds of this image, so this may return a smaller image than the area you asked for, or even a null image if the area was out-of-bounds. */ - const Image getClippedImage (const Rectangle& area) const; + Image getClippedImage (const Rectangle& area) const; /** Returns the colour of one of the pixels in the image. @@ -30064,7 +29960,7 @@ public: @returns the rectangle at the index, or an empty rectangle if the index is out-of-range. */ - const Rectangle getRectangle (int index) const noexcept; + Rectangle getRectangle (int index) const noexcept; /** Removes all rectangles to leave an empty region. */ void clear(); @@ -30183,7 +30079,7 @@ public: bool intersects (const RectangleList& other) const noexcept; /** Returns the smallest rectangle that can enclose the whole of this region. */ - const Rectangle getBounds() const noexcept; + Rectangle getBounds() const noexcept; /** Optimises the list into a minimum number of constituent rectangles. @@ -30197,7 +30093,7 @@ public: void offsetAll (int dx, int dy) noexcept; /** Creates a Path object to represent this region. */ - const Path toPath() const; + Path toPath() const; /** An iterator for accessing all the rectangles in a RectangleList. */ class JUCE_API Iterator @@ -30314,7 +30210,7 @@ public: void setRight (ValueType newRightGap) noexcept { right = newRightGap; } /** Returns a rectangle with these borders removed from it. */ - const Rectangle subtractedFrom (const Rectangle& original) const noexcept + Rectangle subtractedFrom (const Rectangle& original) const noexcept { return Rectangle (original.getX() + left, original.getY() + top, @@ -30329,7 +30225,7 @@ public: } /** Returns a rectangle with these borders added around it. */ - const Rectangle addedTo (const Rectangle& original) const noexcept + Rectangle addedTo (const Rectangle& original) const noexcept { return Rectangle (original.getX() - left, original.getY() - top, @@ -31002,7 +30898,7 @@ public: int getRight() const noexcept { return bounds.getRight(); } /** Returns the component's top-left position as a Point. */ - const Point getPosition() const noexcept { return bounds.getPosition(); } + Point getPosition() const noexcept { return bounds.getPosition(); } /** Returns the y coordinate of the bottom edge of this component. This is a distance in pixels from the top edge of the component's parent. @@ -31026,7 +30922,7 @@ public: This is like getBounds(), but returns the rectangle in local coordinates, In practice, it'll return a rectangle with position (0, 0), and the same size as this component. */ - const Rectangle getLocalBounds() const noexcept; + Rectangle getLocalBounds() const noexcept; /** Returns the area of this component's parent which this component covers. @@ -31035,7 +30931,7 @@ public: the smallest rectangle that fully covers the component's transformed bounding box. If this component has no parent, the return value will simply be the same as getBounds(). */ - const Rectangle getBoundsInParent() const noexcept; + Rectangle getBoundsInParent() const noexcept; /** Returns the region of this component that's not obscured by other, opaque components. @@ -31061,12 +30957,12 @@ public: /** Returns the position of this component's top-left corner relative to the screen's top-left. @see getScreenBounds */ - const Point getScreenPosition() const; + Point getScreenPosition() const; /** Returns the bounds of this component, relative to the screen's top-left. @see getScreenPosition */ - const Rectangle getScreenBounds() const; + Rectangle getScreenBounds() const; /** Converts a point to be relative to this component's coordinate space. @@ -31074,8 +30970,8 @@ public: component. If the sourceComponent parameter is null, the source point is assumed to be a global screen coordinate. */ - const Point getLocalPoint (const Component* sourceComponent, - const Point& pointRelativeToSourceComponent) const; + Point getLocalPoint (const Component* sourceComponent, + const Point& pointRelativeToSourceComponent) const; /** Converts a rectangle to be relative to this component's coordinate space. @@ -31087,13 +30983,13 @@ public: may not actually be rectanglular when converted to the target space, so in that situation this will return the smallest rectangle that fully contains the transformed area. */ - const Rectangle getLocalArea (const Component* sourceComponent, - const Rectangle& areaRelativeToSourceComponent) const; + Rectangle getLocalArea (const Component* sourceComponent, + const Rectangle& areaRelativeToSourceComponent) const; /** Converts a point relative to this component's top-left into a screen coordinate. @see getLocalPoint, localAreaToGlobal */ - const Point localPointToGlobal (const Point& localPoint) const; + Point localPointToGlobal (const Point& localPoint) const; /** Converts a rectangle from this component's coordinate space to a screen coordinate. @@ -31102,7 +30998,7 @@ public: the smallest rectangle that fully contains the transformed area. @see getLocalPoint, localPointToGlobal */ - const Rectangle localAreaToGlobal (const Rectangle& localArea) const; + Rectangle localAreaToGlobal (const Rectangle& localArea) const; /** Moves the component to a new position. @@ -31315,7 +31211,7 @@ public: For more details about transforms, see setTransform(). @see setTransform */ - const AffineTransform getTransform() const; + AffineTransform getTransform() const; /** Returns true if a non-identity transform is being applied to this component. For more details about transforms, see setTransform(). @@ -31355,7 +31251,7 @@ public: monitors, it will return the area of the monitor that contains the component's centre. */ - const Rectangle getParentMonitorArea() const; + Rectangle getParentMonitorArea() const; /** Returns the number of child components that this component contains. @@ -31709,8 +31605,8 @@ public: @see paintEntireComponent */ - const Image createComponentSnapshot (const Rectangle& areaToGrab, - bool clipImageToComponentBounds = true); + Image createComponentSnapshot (const Rectangle& areaToGrab, + bool clipImageToComponentBounds = true); /** Draws this component and all its subcomponents onto the specified graphics context. @@ -32462,7 +32358,7 @@ public: /** Returns the mouse's current position, relative to this component. The return value is relative to the component's top-left corner. */ - const Point getMouseXYRelative() const; + Point getMouseXYRelative() const; /** Called when this component's size has been changed. @@ -34586,7 +34482,7 @@ public: @see getCommandsInCategory() */ - const StringArray getCommandCategories() const; + StringArray getCommandCategories() const; /** Returns a list of all the command UIDs in a particular category. @@ -34862,7 +34758,7 @@ public: void setNeedsToBeSaved (bool needsToBeSaved); /** Returns the file that's being used. */ - const File getFile() const { return file; } + File getFile() const { return file; } /** Handy utility to create a properties file in whatever the standard OS-specific location is for these things. @@ -34902,10 +34798,10 @@ public: only the current user. Use this to choose whether you're saving settings that are common or user-specific. */ - static const File getDefaultAppSettingsFile (const String& applicationName, - const String& fileNameSuffix, - const String& folderName, - bool commonToAllUsers); + static File getDefaultAppSettingsFile (const String& applicationName, + const String& fileNameSuffix, + const String& folderName, + bool commonToAllUsers); protected: virtual void propertyChanged(); @@ -37887,12 +37783,12 @@ public: This just makes it easier than using the property names directly, and it fills out the time and date in the right format. */ - static const StringPairArray createBWAVMetadata (const String& description, - const String& originator, - const String& originatorRef, - const Time& dateAndTime, - const int64 timeReferenceSamples, - const String& codingHistory); + static StringPairArray createBWAVMetadata (const String& description, + const String& originator, + const String& originatorRef, + const Time& dateAndTime, + const int64 timeReferenceSamples, + const String& codingHistory); const Array getPossibleSampleRates(); const Array getPossibleBitDepths(); @@ -39572,7 +39468,6 @@ private: #define __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__ class AudioDeviceManager; -class Component; /** Represents a type of audio driver, such as DirectSound, ASIO, CoreAudio, etc. @@ -39895,7 +39790,7 @@ public: @param velocity in the range 0 to 1.0 @see isNoteOn */ - static const MidiMessage noteOn (int channel, int noteNumber, float velocity) noexcept; + static MidiMessage noteOn (int channel, int noteNumber, float velocity) noexcept; /** Creates a key-down message (using an integer velocity). @@ -39904,7 +39799,7 @@ public: @param velocity in the range 0 to 127 @see isNoteOn */ - static const MidiMessage noteOn (int channel, int noteNumber, uint8 velocity) noexcept; + static MidiMessage noteOn (int channel, int noteNumber, uint8 velocity) noexcept; /** Returns true if this message is a 'key-up' event. @@ -39922,7 +39817,7 @@ public: @param velocity in the range 0 to 127 @see isNoteOff */ - static const MidiMessage noteOff (int channel, int noteNumber, uint8 velocity = 0) noexcept; + static MidiMessage noteOff (int channel, int noteNumber, uint8 velocity = 0) noexcept; /** Returns true if this message is a 'key-down' or 'key-up' event. @@ -40016,7 +39911,7 @@ public: @param programNumber the midi program number, 0 to 127 @see isProgramChange, getGMInstrumentName */ - static const MidiMessage programChange (int channel, int programNumber) noexcept; + static MidiMessage programChange (int channel, int programNumber) noexcept; /** Returns true if the message is a pitch-wheel move. @@ -40040,7 +39935,7 @@ public: @param position the wheel position, in the range 0 to 16383 @see isPitchWheel */ - static const MidiMessage pitchWheel (int channel, int position) noexcept; + static MidiMessage pitchWheel (int channel, int position) noexcept; /** Returns true if the message is an aftertouch event. @@ -40068,9 +39963,9 @@ public: @param aftertouchAmount the amount of aftertouch, 0 to 127 @see isAftertouch */ - static const MidiMessage aftertouchChange (int channel, - int noteNumber, - int aftertouchAmount) noexcept; + static MidiMessage aftertouchChange (int channel, + int noteNumber, + int aftertouchAmount) noexcept; /** Returns true if the message is a channel-pressure change event. @@ -40095,7 +39990,7 @@ public: @param pressure the pressure, 0 to 127 @see isChannelPressure */ - static const MidiMessage channelPressureChange (int channel, int pressure) noexcept; + static MidiMessage channelPressureChange (int channel, int pressure) noexcept; /** Returns true if this is a midi controller message. @@ -40135,9 +40030,9 @@ public: @param value the controller value @see isController */ - static const MidiMessage controllerEvent (int channel, - int controllerType, - int value) noexcept; + static MidiMessage controllerEvent (int channel, + int controllerType, + int value) noexcept; /** Checks whether this message is an all-notes-off message. @@ -40156,20 +40051,20 @@ public: @param channel the midi channel, in the range 1 to 16 @see isAllNotesOff */ - static const MidiMessage allNotesOff (int channel) noexcept; + 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 const MidiMessage allSoundOff (int channel) noexcept; + static MidiMessage allSoundOff (int channel) noexcept; /** Creates an all-controllers-off message. @param channel the midi channel, in the range 1 to 16 */ - static const MidiMessage allControllersOff (int channel) noexcept; + static MidiMessage allControllersOff (int channel) noexcept; /** Returns true if this event is a meta-event. @@ -40213,7 +40108,7 @@ public: @see isEndOfTrackMetaEvent */ - static const MidiMessage endOfTrack() noexcept; + static MidiMessage endOfTrack() noexcept; /** Returns true if this is an 'track name' meta-event. @@ -40231,7 +40126,7 @@ public: @see isTextMetaEvent */ - const String getTextFromTextMetaEvent() const; + String getTextFromTextMetaEvent() const; /** Returns true if this is a 'tempo' meta-event. @@ -40257,7 +40152,7 @@ public: @see isTempoMetaEvent */ - static const MidiMessage tempoMetaEvent (int microsecondsPerQuarterNote) noexcept; + static MidiMessage tempoMetaEvent (int microsecondsPerQuarterNote) noexcept; /** Returns true if this is a 'time-signature' meta-event. @@ -40275,7 +40170,7 @@ public: @see isTimeSignatureMetaEvent */ - static const MidiMessage timeSignatureMetaEvent (int numerator, int denominator); + static MidiMessage timeSignatureMetaEvent (int numerator, int denominator); /** Returns true if this is a 'key-signature' meta-event. @@ -40310,7 +40205,7 @@ public: @param channel the midi channel, in the range 1 to 16 @see isMidiChannelMetaEvent */ - static const MidiMessage midiChannelMetaEvent (int channel) noexcept; + static MidiMessage midiChannelMetaEvent (int channel) noexcept; /** Returns true if this is an active-sense message. */ bool isActiveSense() const noexcept; @@ -40322,7 +40217,7 @@ public: bool isMidiStart() const noexcept; /** Creates a midi start event. */ - static const MidiMessage midiStart() noexcept; + static MidiMessage midiStart() noexcept; /** Returns true if this is a midi continue event. @@ -40331,7 +40226,7 @@ public: bool isMidiContinue() const noexcept; /** Creates a midi continue event. */ - static const MidiMessage midiContinue() noexcept; + static MidiMessage midiContinue() noexcept; /** Returns true if this is a midi stop event. @@ -40340,7 +40235,7 @@ public: bool isMidiStop() const noexcept; /** Creates a midi stop event. */ - static const MidiMessage midiStop() noexcept; + static MidiMessage midiStop() noexcept; /** Returns true if this is a midi clock event. @@ -40349,7 +40244,7 @@ public: bool isMidiClock() const noexcept; /** Creates a midi clock event. */ - static const MidiMessage midiClock() noexcept; + static MidiMessage midiClock() noexcept; /** Returns true if this is a song-position-pointer message. @@ -40371,7 +40266,7 @@ public: @see isSongPositionPointer, getSongPositionPointerMidiBeat */ - static const MidiMessage songPositionPointer (int positionInMidiBeats) noexcept; + static MidiMessage songPositionPointer (int positionInMidiBeats) noexcept; /** Returns true if this is a quarter-frame midi timecode message. @@ -40399,7 +40294,7 @@ public: @param sequenceNumber a value 0 to 7 for the upper nybble of the message's data byte @param value a value 0 to 15 for the lower nybble of the message's data byte */ - static const MidiMessage quarterFrame (int sequenceNumber, int value) noexcept; + static MidiMessage quarterFrame (int sequenceNumber, int value) noexcept; /** SMPTE timecode types. @@ -40430,11 +40325,11 @@ public: /** Creates a full-frame MTC message. */ - static const MidiMessage fullFrame (int hours, - int minutes, - int seconds, - int frames, - SmpteTimecodeType timecodeType); + static MidiMessage fullFrame (int hours, + int minutes, + int seconds, + int frames, + SmpteTimecodeType timecodeType); /** Types of MMC command. @@ -40467,7 +40362,7 @@ public: /** Creates an MMC message. */ - static const MidiMessage midiMachineControlCommand (MidiMachineControlCommand command); + static MidiMessage midiMachineControlCommand (MidiMachineControlCommand command); /** Checks whether this is an MMC "goto" message. @@ -40486,23 +40381,23 @@ public: @see isMidiMachineControlGoto */ - static const MidiMessage midiMachineControlGoto (int hours, - int minutes, - int seconds, - int frames); + static MidiMessage midiMachineControlGoto (int hours, + int minutes, + int seconds, + int frames); /** Creates a master-volume change message. @param volume the volume, 0 to 1.0 */ - static const MidiMessage masterVolume (float volume); + static MidiMessage masterVolume (float volume); /** Creates a system-exclusive message. The data passed in is wrapped with header and tail bytes of 0xf0 and 0xf7. */ - static const MidiMessage createSysExMessage (const uint8* sysexData, - int dataSize); + static MidiMessage createSysExMessage (const uint8* sysexData, + int dataSize); /** Reads a midi variable-length integer. @@ -40533,10 +40428,10 @@ public: @see getMidiNoteInHertz */ - static const String getMidiNoteName (int noteNumber, - bool useSharps, - bool includeOctaveNumber, - int octaveNumForMiddleC); + static String getMidiNoteName (int noteNumber, + bool useSharps, + bool includeOctaveNumber, + int octaveNumForMiddleC); /** Returns the frequency of a midi note number. @@ -40550,25 +40445,25 @@ public: @param midiInstrumentNumber the program number 0 to 127 @see getProgramChangeNumber */ - static const String getGMInstrumentName (int midiInstrumentNumber); + static String getGMInstrumentName (int midiInstrumentNumber); /** Returns the name of a bank of GM instruments. @param midiBankNumber the bank, 0 to 15 */ - static const String getGMInstrumentBankName (int midiBankNumber); + static String getGMInstrumentBankName (int midiBankNumber); /** Returns the standard name of a channel 10 percussion sound. @param midiNoteNumber the key number, 35 to 81 */ - static const String getRhythmInstrumentName (int midiNoteNumber); + static String getRhythmInstrumentName (int midiNoteNumber); /** Returns the name of a controller type number. @see getControllerNumber */ - static const String getControllerName (int controllerNumber); + static String getControllerName (int controllerNumber); private: @@ -41080,11853 +40975,11855 @@ private: /*** End of inlined file: juce_MidiOutput.h ***/ +/** + Manages the state of some audio and midi i/o devices. -/*** Start of inlined file: juce_ComboBox.h ***/ -#ifndef __JUCE_COMBOBOX_JUCEHEADER__ -#define __JUCE_COMBOBOX_JUCEHEADER__ - - -/*** Start of inlined file: juce_Label.h ***/ -#ifndef __JUCE_LABEL_JUCEHEADER__ -#define __JUCE_LABEL_JUCEHEADER__ - - -/*** Start of inlined file: juce_TextEditor.h ***/ -#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ -#define __JUCE_TEXTEDITOR_JUCEHEADER__ - - -/*** Start of inlined file: juce_Viewport.h ***/ -#ifndef __JUCE_VIEWPORT_JUCEHEADER__ -#define __JUCE_VIEWPORT_JUCEHEADER__ - - -/*** Start of inlined file: juce_ScrollBar.h ***/ -#ifndef __JUCE_SCROLLBAR_JUCEHEADER__ -#define __JUCE_SCROLLBAR_JUCEHEADER__ - + This class keeps tracks of a currently-selected audio device, through + with which it continuously streams data from an audio callback, as well as + one or more midi inputs. -/*** Start of inlined file: juce_Button.h ***/ -#ifndef __JUCE_BUTTON_JUCEHEADER__ -#define __JUCE_BUTTON_JUCEHEADER__ + The idea is that your application will create one global instance of this object, + and let it take care of creating and deleting specific types of audio devices + internally. So when the device is changed, your callbacks will just keep running + without having to worry about this. + The manager can save and reload all of its device settings as XML, which + makes it very easy for you to save and reload the audio setup of your + application. -/*** Start of inlined file: juce_TooltipWindow.h ***/ -#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ -#define __JUCE_TOOLTIPWINDOW_JUCEHEADER__ + And to make it easy to let the user change its settings, there's a component + to do just that - the AudioDeviceSelectorComponent class, which contains a set of + device selection/sample-rate/latency controls. + To use an AudioDeviceManager, create one, and use initialise() to set it up. Then + call addAudioCallback() to register your audio callback with it, and use that to process + your audio data. -/*** Start of inlined file: juce_TooltipClient.h ***/ -#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__ -#define __JUCE_TOOLTIPCLIENT_JUCEHEADER__ + The manager also acts as a handy hub for incoming midi messages, allowing a + listener to register for messages from either a specific midi device, or from whatever + the current default midi input device is. The listener then doesn't have to worry about + re-registering with different midi devices if they are changed or deleted. -/** - Components that want to use pop-up tooltips should implement this interface. + And yet another neat trick is that amount of CPU time being used is measured and + available with the getCpuUsage() method. - A TooltipWindow will wait for the mouse to hover over a component that - implements the TooltipClient interface, and when it finds one, it will display - the tooltip returned by its getTooltip() method. + The AudioDeviceManager is a ChangeBroadcaster, and will send a change message to + listeners whenever one of its settings is changed. - @see TooltipWindow, SettableTooltipClient + @see AudioDeviceSelectorComponent, AudioIODevice, AudioIODeviceType */ -class JUCE_API TooltipClient +class JUCE_API AudioDeviceManager : public ChangeBroadcaster { public: - /** Destructor. */ - virtual ~TooltipClient() {} - - /** Returns the string that this object wants to show as its tooltip. */ - virtual const String getTooltip() = 0; -}; - -/** - An implementation of TooltipClient that stores the tooltip string and a method - for changing it. - This makes it easy to add a tooltip to a custom component, by simply adding this - as a base class and calling setTooltip(). - - Many of the Juce widgets already use this as a base class to implement their - tooltips. + /** Creates a default AudioDeviceManager. - @see TooltipClient, TooltipWindow -*/ -class JUCE_API SettableTooltipClient : public TooltipClient -{ -public: + Initially no audio device will be selected. You should call the initialise() method + and register an audio callback with setAudioCallback() before it'll be able to + actually make any noise. + */ + AudioDeviceManager(); /** Destructor. */ - virtual ~SettableTooltipClient() {} + ~AudioDeviceManager(); - /** Assigns a new tooltip to this object. */ - virtual void setTooltip (const String& newTooltip) { tooltipString = newTooltip; } + /** + This structure holds a set of properties describing the current audio setup. - /** Returns the tooltip assigned to this object. */ - virtual const String getTooltip() { return tooltipString; } + An AudioDeviceManager uses this class to save/load its current settings, and to + specify your preferred options when opening a device. -protected: - SettableTooltipClient() {} + @see AudioDeviceManager::setAudioDeviceSetup(), AudioDeviceManager::initialise() + */ + struct JUCE_API AudioDeviceSetup + { + /** Creates an AudioDeviceSetup object. -private: - String tooltipString; -}; + The default constructor sets all the member variables to indicate default values. + You can then fill-in any values you want to before passing the object to + AudioDeviceManager::initialise(). + */ + AudioDeviceSetup(); -#endif // __JUCE_TOOLTIPCLIENT_JUCEHEADER__ + bool operator== (const AudioDeviceSetup& other) const; -/*** End of inlined file: juce_TooltipClient.h ***/ + /** The name of the audio device used for output. + The name has to be one of the ones listed by the AudioDeviceManager's currently + selected device type. + This may be the same as the input device. + An empty string indicates the default device. + */ + String outputDeviceName; -/** - A window that displays a pop-up tooltip when the mouse hovers over another component. + /** The name of the audio device used for input. + This may be the same as the output device. + An empty string indicates the default device. + */ + String inputDeviceName; - To enable tooltips in your app, just create a single instance of a TooltipWindow - object. + /** The current sample rate. + This rate is used for both the input and output devices. + A value of 0 indicates the default rate. + */ + double sampleRate; - The TooltipWindow object will then stay invisible, waiting until the mouse - hovers for the specified length of time - it will then see if it's currently - over a component which implements the TooltipClient interface, and if so, - it will make itself visible to show the tooltip in the appropriate place. + /** The buffer size, in samples. + This buffer size is used for both the input and output devices. + A value of 0 indicates the default buffer size. + */ + int bufferSize; - @see TooltipClient, SettableTooltipClient -*/ -class JUCE_API TooltipWindow : public Component, - private Timer -{ -public: + /** The set of active input channels. + The bits that are set in this array indicate the channels of the + input device that are active. + If useDefaultInputChannels is true, this value is ignored. + */ + BigInteger inputChannels; - /** Creates a tooltip window. + /** If this is true, it indicates that the inputChannels array + should be ignored, and instead, the device's default channels + should be used. + */ + bool useDefaultInputChannels; - Make sure your app only creates one instance of this class, otherwise you'll - get multiple overlaid tooltips appearing. The window will initially be invisible - and will make itself visible when it needs to display a tip. + /** The set of active output channels. + The bits that are set in this array indicate the channels of the + input device that are active. + If useDefaultOutputChannels is true, this value is ignored. + */ + BigInteger outputChannels; - To change the style of tooltips, see the LookAndFeel class for its tooltip - methods. + /** If this is true, it indicates that the outputChannels array + should be ignored, and instead, the device's default channels + should be used. + */ + bool useDefaultOutputChannels; + }; - @param parentComponent if set to 0, the TooltipWindow will appear on the desktop, - otherwise the tooltip will be added to the given parent - component. - @param millisecondsBeforeTipAppears the time for which the mouse has to stay still - before a tooltip will be shown + /** Opens a set of audio devices ready for use. - @see TooltipClient, LookAndFeel::drawTooltip, LookAndFeel::getTooltipSize - */ - explicit TooltipWindow (Component* parentComponent = nullptr, - int millisecondsBeforeTipAppears = 700); + This will attempt to open either a default audio device, or one that was + previously saved as XML. - /** Destructor. */ - ~TooltipWindow(); + @param numInputChannelsNeeded a minimum number of input channels needed + by your app. + @param numOutputChannelsNeeded a minimum number of output channels to open + @param savedState either a previously-saved state that was produced + by createStateXml(), or 0 if you want the manager + to choose the best device to open. + @param selectDefaultDeviceOnFailure if true, then if the device specified in the XML + fails to open, then a default device will be used + instead. If false, then on failure, no device is + opened. + @param preferredDefaultDeviceName if this is not empty, and there's a device with this + name, then that will be used as the default device + (assuming that there wasn't one specified in the XML). + The string can actually be a simple wildcard, containing "*" + and "?" characters + @param preferredSetupOptions if this is non-null, the structure will be used as the + set of preferred settings when opening the device. If you + use this parameter, the preferredDefaultDeviceName + field will be ignored - /** Changes the time before the tip appears. - This lets you change the value that was set in the constructor. + @returns an error message if anything went wrong, or an empty string if it worked ok. */ - void setMillisecondsBeforeTipAppears (int newTimeMs = 700) noexcept; + const String initialise (int numInputChannelsNeeded, + int numOutputChannelsNeeded, + const XmlElement* savedState, + bool selectDefaultDeviceOnFailure, + const String& preferredDefaultDeviceName = String::empty, + const AudioDeviceSetup* preferredSetupOptions = 0); - /** A set of colour IDs to use to change the colour of various aspects of the tooltip. + /** Returns some XML representing the current state of the manager. - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. + This stores the current device, its samplerate, block size, etc, and + can be restored later with initialise(). - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + Note that this can return a null pointer if no settings have been explicitly changed + (i.e. if the device manager has just been left in its default state). */ - enum ColourIds - { - backgroundColourId = 0x1001b00, /**< The colour to fill the background with. */ - textColourId = 0x1001c00, /**< The colour to use for the text. */ - outlineColourId = 0x1001c10 /**< The colour to use to draw an outline around the tooltip. */ - }; - -private: - - int millisecondsBeforeTipAppears; - Point lastMousePos; - int mouseClicks; - unsigned int lastCompChangeTime, lastHideTime; - Component* lastComponentUnderMouse; - bool changedCompsSinceShown; - String tipShowing, lastTipUnderMouse; - - void paint (Graphics& g); - void mouseEnter (const MouseEvent& e); - void timerCallback(); - - static const String getTipFor (Component* c); - void showFor (const String& tip); - void hide(); - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TooltipWindow); -}; - -#endif // __JUCE_TOOLTIPWINDOW_JUCEHEADER__ - -/*** End of inlined file: juce_TooltipWindow.h ***/ + XmlElement* createStateXml() const; -#if JUCE_VC6 - #define Listener ButtonListener -#endif + /** Returns the current device properties that are in use. -/** - A base class for buttons. + @see setAudioDeviceSetup + */ + void getAudioDeviceSetup (AudioDeviceSetup& setup); - This contains all the logic for button behaviours such as enabling/disabling, - responding to shortcut keystrokes, auto-repeating when held down, toggle-buttons - and radio groups, etc. + /** Changes the current device or its settings. - @see TextButton, DrawableButton, ToggleButton -*/ -class JUCE_API Button : public Component, - public SettableTooltipClient, - public ApplicationCommandManagerListener, - public ValueListener, - private KeyListener -{ -protected: + If you want to change a device property, like the current sample rate or + block size, you can call getAudioDeviceSetup() to retrieve the current + settings, then tweak the appropriate fields in the AudioDeviceSetup structure, + and pass it back into this method to apply the new settings. - /** Creates a button. + @param newSetup the settings that you'd like to use + @param treatAsChosenDevice if this is true and if the device opens correctly, these new + settings will be taken as having been explicitly chosen by the + user, and the next time createStateXml() is called, these settings + will be returned. If it's false, then the device is treated as a + temporary or default device, and a call to createStateXml() will + return either the last settings that were made with treatAsChosenDevice + as true, or the last XML settings that were passed into initialise(). + @returns an error message if anything went wrong, or an empty string if it worked ok. - @param buttonName the text to put in the button (the component's name is also - initially set to this string, but these can be changed later - using the setName() and setButtonText() methods) + @see getAudioDeviceSetup */ - explicit Button (const String& buttonName); - -public: - /** Destructor. */ - virtual ~Button(); + const String setAudioDeviceSetup (const AudioDeviceSetup& newSetup, + bool treatAsChosenDevice); - /** Changes the button's text. + /** Returns the currently-active audio device. */ + AudioIODevice* getCurrentAudioDevice() const noexcept { return currentAudioDevice; } - @see getButtonText + /** Returns the type of audio device currently in use. + @see setCurrentAudioDeviceType */ - void setButtonText (const String& newText); - - /** Returns the text displayed in the button. + const String getCurrentAudioDeviceType() const { return currentDeviceType; } - @see setButtonText + /** Returns the currently active audio device type object. + Don't keep a copy of this pointer - it's owned by the device manager and could + change at any time. */ - const String getButtonText() const { return text; } + AudioIODeviceType* getCurrentDeviceTypeObject() const; - /** Returns true if the button is currently being held down by the mouse. + /** Changes the class of audio device being used. - @see isOver - */ - bool isDown() const noexcept; + This switches between, e.g. ASIO and DirectSound. On the Mac you probably won't ever call + this because there's only one type: CoreAudio. - /** Returns true if the mouse is currently over the button. + For a list of types, see getAvailableDeviceTypes(). + */ + void setCurrentAudioDeviceType (const String& type, + bool treatAsChosenDevice); - This will be also be true if the mouse is being held down. + /** Closes the currently-open device. - @see isDown + You can call restartLastAudioDevice() later to reopen it in the same state + that it was just in. */ - bool isOver() const noexcept; + void closeAudioDevice(); - /** A button has an on/off state associated with it, and this changes that. + /** Tries to reload the last audio device that was running. - By default buttons are 'off' and for simple buttons that you click to perform - an action you won't change this. Toggle buttons, however will want to - change their state when turned on or off. + Note that this only reloads the last device that was running before + closeAudioDevice() was called - it doesn't reload any kind of saved-state, + and can only be called after a device has been opened with SetAudioDevice(). - @param shouldBeOn whether to set the button's toggle state to be on or - off. If it's a member of a button group, this will - always try to turn it on, and to turn off any other - buttons in the group - @param sendChangeNotification if true, a callback will be made to clicked(); if false - the button will be repainted but no notification will - be sent - @see getToggleState, setRadioGroupId + If a device is already open, this call will do nothing. */ - void setToggleState (bool shouldBeOn, - bool sendChangeNotification); + void restartLastAudioDevice(); - /** Returns true if the button in 'on'. + /** Registers an audio callback to be used. - By default buttons are 'off' and for simple buttons that you click to perform - an action you won't change this. Toggle buttons, however will want to - change their state when turned on or off. + The manager will redirect callbacks from whatever audio device is currently + in use to all registered callback objects. If more than one callback is + active, they will all be given the same input data, and their outputs will + be summed. - @see setToggleState - */ - bool getToggleState() const noexcept { return isOn.getValue(); } + If necessary, this method will invoke audioDeviceAboutToStart() on the callback + object before returning. - /** Returns the Value object that represents the botton's toggle state. - You can use this Value object to connect the button's state to external values or setters, - either by taking a copy of the Value, or by using Value::referTo() to make it point to - your own Value object. - @see getToggleState, Value + To remove a callback, use removeAudioCallback(). */ - Value& getToggleStateValue() { return isOn; } + void addAudioCallback (AudioIODeviceCallback* newCallback); - /** This tells the button to automatically flip the toggle state when - the button is clicked. + /** Deregisters a previously added callback. - If set to true, then before the clicked() callback occurs, the toggle-state - of the button is flipped. + If necessary, this method will invoke audioDeviceStopped() on the callback + object before returning. + + @see addAudioCallback */ - void setClickingTogglesState (bool shouldToggle) noexcept; + void removeAudioCallback (AudioIODeviceCallback* callback); - /** Returns true if this button is set to be an automatic toggle-button. + /** Returns the average proportion of available CPU being spent inside the audio callbacks. - This returns the last value that was passed to setClickingTogglesState(). + Returns a value between 0 and 1.0 */ - bool getClickingTogglesState() const noexcept; - - /** Enables the button to act as a member of a mutually-exclusive group - of 'radio buttons'. + double getCpuUsage() const; - If the group ID is set to a non-zero number, then this button will - act as part of a group of buttons with the same ID, only one of - which can be 'on' at the same time. Note that when it's part of - a group, clicking a toggle-button that's 'on' won't turn it off. + /** Enables or disables a midi input device. - To find other buttons with the same ID, this button will search through - its sibling components for ToggleButtons, so all the buttons for a - particular group must be placed inside the same parent component. + The list of devices can be obtained with the MidiInput::getDevices() method. - Set the group ID back to zero if you want it to act as a normal toggle - button again. + Any incoming messages from enabled input devices will be forwarded on to all the + listeners that have been registered with the addMidiInputCallback() method. They + can either register for messages from a particular device, or from just the + "default" midi input. - @see getRadioGroupId - */ - void setRadioGroupId (int newGroupId); + Routing the midi input via an AudioDeviceManager means that when a listener + registers for the default midi input, this default device can be changed by the + manager without the listeners having to know about it or re-register. - /** Returns the ID of the group to which this button belongs. + It also means that a listener can stay registered for a midi input that is disabled + or not present, so that when the input is re-enabled, the listener will start + receiving messages again. - (See setRadioGroupId() for an explanation of this). + @see addMidiInputCallback, isMidiInputEnabled */ - int getRadioGroupId() const noexcept { return radioGroupId; } + void setMidiInputEnabled (const String& midiInputDeviceName, bool enabled); - /** - Used to receive callbacks when a button is clicked. + /** Returns true if a given midi input device is being used. - @see Button::addListener, Button::removeListener + @see setMidiInputEnabled */ - class JUCE_API Listener - { - public: - /** Destructor. */ - virtual ~Listener() {} - - /** Called when the button is clicked. */ - virtual void buttonClicked (Button* button) = 0; + bool isMidiInputEnabled (const String& midiInputDeviceName) const; - /** Called when the button's state changes. */ - virtual void buttonStateChanged (Button*) {} - }; + /** Registers a listener for callbacks when midi events arrive from a midi input. - /** Registers a listener to receive events when this button's state changes. - If the listener is already registered, this will not register it again. - @see removeListener - */ - void addListener (Listener* newListener); + The device name can be empty to indicate that it wants events from whatever the + current "default" device is. Or it can be the name of one of the midi input devices + (see MidiInput::getDevices() for the names). - /** Removes a previously-registered button listener - @see addListener + Only devices which are enabled (see the setMidiInputEnabled() method) will have their + events forwarded on to listeners. */ - void removeListener (Listener* listener); - - /** Causes the button to act as if it's been clicked. - - This will asynchronously make the button draw itself going down and up, and - will then call back the clicked() method as if mouse was clicked on it. + void addMidiInputCallback (const String& midiInputDeviceName, + MidiInputCallback* callback); - @see clicked + /** Removes a listener that was previously registered with addMidiInputCallback(). */ - virtual void triggerClick(); - - /** Sets a command ID for this button to automatically invoke when it's clicked. + void removeMidiInputCallback (const String& midiInputDeviceName, + MidiInputCallback* callback); - When the button is pressed, it will use the given manager to trigger the - command ID. + /** Sets a midi output device to use as the default. - Obviously be careful that the ApplicationCommandManager doesn't get deleted - before this button is. To disable the command triggering, call this method and - pass 0 for the parameters. + The list of devices can be obtained with the MidiOutput::getDevices() method. - If generateTooltip is true, then the button's tooltip will be automatically - generated based on the name of this command and its current shortcut key. + The specified device will be opened automatically and can be retrieved with the + getDefaultMidiOutput() method. - @see addShortcut, getCommandID + Pass in an empty string to deselect all devices. For the default device, you + can use MidiOutput::getDevices() [MidiOutput::getDefaultDeviceIndex()]. + + @see getDefaultMidiOutput, getDefaultMidiOutputName */ - void setCommandToTrigger (ApplicationCommandManager* commandManagerToUse, - int commandID, - bool generateTooltip); + void setDefaultMidiOutput (const String& deviceName); - /** Returns the command ID that was set by setCommandToTrigger(). + /** Returns the name of the default midi output. + + @see setDefaultMidiOutput, getDefaultMidiOutput */ - int getCommandID() const noexcept { return commandID; } + const String getDefaultMidiOutputName() const { return defaultMidiOutputName; } - /** Assigns a shortcut key to trigger the button. + /** Returns the current default midi output device. - The button registers itself with its top-level parent component for keypresses. + If no device has been selected, or the device can't be opened, this will + return 0. - Note that a different way of linking buttons to keypresses is by using the - setCommandToTrigger() method to invoke a command. + @see getDefaultMidiOutputName + */ + MidiOutput* getDefaultMidiOutput() const noexcept { return defaultMidiOutput; } - @see clearShortcuts + /** Returns a list of the types of device supported. */ - void addShortcut (const KeyPress& key); + const OwnedArray & getAvailableDeviceTypes(); - /** Removes all key shortcuts that had been set for this button. + /** Creates a list of available types. - @see addShortcut + This will add a set of new AudioIODeviceType objects to the specified list, to + represent each available types of device. + + You can override this if your app needs to do something specific, like avoid + using DirectSound devices, etc. */ - void clearShortcuts(); + virtual void createAudioDeviceTypes (OwnedArray & types); - /** Returns true if the given keypress is a shortcut for this button. + /** Plays a beep through the current audio device. - @see addShortcut + This is here to allow the audio setup UI panels to easily include a "test" + button so that the user can check where the audio is coming from. */ - bool isRegisteredForShortcut (const KeyPress& key) const; + void playTestSound(); - /** Sets an auto-repeat speed for the button when it is held down. + /** Turns on level-measuring. - (Auto-repeat is disabled by default). + When enabled, the device manager will measure the peak input level + across all channels, and you can get this level by calling getCurrentInputLevel(). - @param initialDelayInMillisecs how long to wait after the mouse is pressed before - triggering the next click. If this is zero, auto-repeat - is disabled - @param repeatDelayInMillisecs the frequently subsequent repeated clicks should be - triggered - @param minimumDelayInMillisecs if this is greater than 0, the auto-repeat speed will - get faster, the longer the button is held down, up to the - minimum interval specified here + This is mainly intended for audio setup UI panels to use to create a mic + level display, so that the user can check that they've selected the right + device. + + A simple filter is used to make the level decay smoothly, but this is + only intended for giving rough feedback, and not for any kind of accurate + measurement. */ - void setRepeatSpeed (int initialDelayInMillisecs, - int repeatDelayInMillisecs, - int minimumDelayInMillisecs = -1) noexcept; + void enableInputLevelMeasurement (bool enableMeasurement); - /** Sets whether the button click should happen when the mouse is pressed or released. + /** Returns the current input level. - By default the button is only considered to have been clicked when the mouse is - released, but setting this to true will make it call the clicked() method as soon - as the button is pressed. + To use this, you must first enable it by calling enableInputLevelMeasurement(). - This is useful if the button is being used to show a pop-up menu, as it allows - the click to be used as a drag onto the menu. + See enableInputLevelMeasurement() for more info. */ - void setTriggeredOnMouseDown (bool isTriggeredOnMouseDown) noexcept; + double getCurrentInputLevel() const; - /** Returns the number of milliseconds since the last time the button - went into the 'down' state. + /** Returns the a lock that can be used to synchronise access to the audio callback. + Obviously while this is locked, you're blocking the audio thread from running, so + it must only be used for very brief periods when absolutely necessary. */ - uint32 getMillisecondsSinceButtonDown() const noexcept; - - /** Sets the tooltip for this button. + CriticalSection& getAudioCallbackLock() noexcept { return audioCallbackLock; } - @see TooltipClient, TooltipWindow + /** Returns the a lock that can be used to synchronise access to the midi callback. + Obviously while this is locked, you're blocking the midi system from running, so + it must only be used for very brief periods when absolutely necessary. */ - void setTooltip (const String& newTooltip); + CriticalSection& getMidiCallbackLock() noexcept { return midiCallbackLock; } - // (implementation of the TooltipClient method) - const String getTooltip(); +private: - /** A combination of these flags are used by setConnectedEdges(). - */ - enum ConnectedEdgeFlags - { - ConnectedOnLeft = 1, - ConnectedOnRight = 2, - ConnectedOnTop = 4, - ConnectedOnBottom = 8 - }; + OwnedArray availableDeviceTypes; + OwnedArray lastDeviceTypeConfigs; - /** Hints about which edges of the button might be connected to adjoining buttons. + AudioDeviceSetup currentSetup; + ScopedPointer currentAudioDevice; + Array callbacks; + int numInputChansNeeded, numOutputChansNeeded; + String currentDeviceType; + BigInteger inputChannels, outputChannels; + ScopedPointer lastExplicitSettings; + mutable bool listNeedsScanning; + bool useInputNames; + int inputLevelMeasurementEnabledCount; + double inputLevel; + ScopedPointer testSound; + int testSoundPosition; + AudioSampleBuffer tempBuffer; - The value passed in is a bitwise combination of any of the values in the - ConnectedEdgeFlags enum. + StringArray midiInsFromXml; + OwnedArray enabledMidiInputs; + Array midiCallbacks; + StringArray midiCallbackDevices; + String defaultMidiOutputName; + ScopedPointer defaultMidiOutput; + CriticalSection audioCallbackLock, midiCallbackLock; - E.g. if you are placing two buttons adjacent to each other, you could use this to - indicate which edges are touching, and the LookAndFeel might choose to drawn them - without rounded corners on the edges that connect. It's only a hint, so the - LookAndFeel can choose to ignore it if it's not relevent for this type of - button. - */ - void setConnectedEdges (int connectedEdgeFlags); + double cpuUsageMs, timeToCpuScale; - /** Returns the set of flags passed into setConnectedEdges(). */ - int getConnectedEdgeFlags() const noexcept { return connectedEdgeFlags; } + class CallbackHandler : public AudioIODeviceCallback, + public MidiInputCallback + { + public: + void audioDeviceIOCallback (const float**, int, float**, int, int); + void audioDeviceAboutToStart (AudioIODevice*); + void audioDeviceStopped(); + void handleIncomingMidiMessage (MidiInput*, const MidiMessage&); - /** Indicates whether the button adjoins another one on its left edge. - @see setConnectedEdges - */ - bool isConnectedOnLeft() const noexcept { return (connectedEdgeFlags & ConnectedOnLeft) != 0; } + AudioDeviceManager* owner; + }; - /** Indicates whether the button adjoins another one on its right edge. - @see setConnectedEdges - */ - bool isConnectedOnRight() const noexcept { return (connectedEdgeFlags & ConnectedOnRight) != 0; } + CallbackHandler callbackHandler; + friend class CallbackHandler; - /** Indicates whether the button adjoins another one on its top edge. - @see setConnectedEdges - */ - bool isConnectedOnTop() const noexcept { return (connectedEdgeFlags & ConnectedOnTop) != 0; } + void audioDeviceIOCallbackInt (const float** inputChannelData, int totalNumInputChannels, + float** outputChannelData, int totalNumOutputChannels, int numSamples); + void audioDeviceAboutToStartInt (AudioIODevice*); + void audioDeviceStoppedInt(); + void handleIncomingMidiMessageInt (MidiInput*, const MidiMessage&); - /** Indicates whether the button adjoins another one on its bottom edge. - @see setConnectedEdges - */ - bool isConnectedOnBottom() const noexcept { return (connectedEdgeFlags & ConnectedOnBottom) != 0; } + const String restartDevice (int blockSizeToUse, double sampleRateToUse, + const BigInteger& ins, const BigInteger& outs); + void stopDevice(); - /** Used by setState(). */ - enum ButtonState - { - buttonNormal, - buttonOver, - buttonDown - }; + void updateXml(); - /** Can be used to force the button into a particular state. + void createDeviceTypesIfNeeded(); + void scanDevicesIfNeeded(); + void deleteCurrentDevice(); + double chooseBestSampleRate (double preferred) const; + int chooseBestBufferSize (int preferred) const; + void insertDefaultDeviceNames (AudioDeviceSetup& setup) const; - This only changes the button's appearance, it won't trigger a click, or stop any mouse-clicks - from happening. + AudioIODeviceType* findType (const String& inputName, const String& outputName); - The state that you set here will only last until it is automatically changed when the mouse - enters or exits the button, or the mouse-button is pressed or released. - */ - void setState (const ButtonState newState); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDeviceManager); +}; - // These are deprecated - please use addListener() and removeListener() instead! - JUCE_DEPRECATED (void addButtonListener (Listener*)); - JUCE_DEPRECATED (void removeButtonListener (Listener*)); +#endif // __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__ -protected: +/*** End of inlined file: juce_AudioDeviceManager.h ***/ - /** This method is called when the button has been clicked. - Subclasses can override this to perform whatever they actions they need - to do. +#endif +#ifndef __JUCE_AUDIOIODEVICE_JUCEHEADER__ - Alternatively, a ButtonListener can be added to the button, and these listeners - will be called when the click occurs. +#endif +#ifndef __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__ - @see triggerClick - */ - virtual void clicked(); +#endif +#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ - /** This method is called when the button has been clicked. +#endif +#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ - By default it just calls clicked(), but you might want to override it to handle - things like clicking when a modifier key is pressed, etc. +#endif +#ifndef __JUCE_DECIBELS_JUCEHEADER__ - @see ModifierKeys - */ - virtual void clicked (const ModifierKeys& modifiers); +/*** Start of inlined file: juce_Decibels.h ***/ +#ifndef __JUCE_DECIBELS_JUCEHEADER__ +#define __JUCE_DECIBELS_JUCEHEADER__ - /** Subclasses should override this to actually paint the button's contents. +/** + This class contains some helpful static methods for dealing with decibel values. +*/ +class Decibels +{ +public: - It's better to use this than the paint method, because it gives you information - about the over/down state of the button. + /** Converts a dBFS value to its equivalent gain level. - @param g the graphics context to use - @param isMouseOverButton true if the button is either in the 'over' or - 'down' state - @param isButtonDown true if the button should be drawn in the 'down' position + A gain of 1.0 = 0 dB, and lower gains map onto negative decibel values. Any + decibel value lower than minusInfinityDb will return a gain of 0. */ - virtual void paintButton (Graphics& g, - bool isMouseOverButton, - bool isButtonDown) = 0; + template + static Type decibelsToGain (const Type decibels, + const Type minusInfinityDb = (Type) defaultMinusInfinitydB) + { + return decibels > minusInfinityDb ? powf ((Type) 10.0, decibels * (Type) 0.05) + : Type(); + } - /** Called when the button's up/down/over state changes. + /** Converts a gain level into a dBFS value. - Subclasses can override this if they need to do something special when the button - goes up or down. + A gain of 1.0 = 0 dB, and lower gains map onto negative decibel values. + If the gain is 0 (or negative), then the method will return the value + provided as minusInfinityDb. + */ + template + static Type gainToDecibels (const Type gain, + const Type minusInfinityDb = (Type) defaultMinusInfinitydB) + { + return gain > Type() ? jmax (minusInfinityDb, (Type) std::log10 (gain) * (Type) 20.0) + : minusInfinityDb; + } - @see isDown, isOver + /** Converts a decibel reading to a string, with the 'dB' suffix. + If the decibel value is lower than minusInfinityDb, the return value will + be "-INF dB". */ - virtual void buttonStateChanged(); + template + static const String toString (const Type decibels, + const int decimalPlaces = 2, + const Type minusInfinityDb = (Type) defaultMinusInfinitydB) + { + String s; - /** @internal */ - virtual void internalClickCallback (const ModifierKeys& modifiers); - /** @internal */ - void handleCommandMessage (int commandId); - /** @internal */ - void mouseEnter (const MouseEvent& e); - /** @internal */ - void mouseExit (const MouseEvent& e); - /** @internal */ - void mouseDown (const MouseEvent& e); - /** @internal */ - void mouseDrag (const MouseEvent& e); - /** @internal */ - void mouseUp (const MouseEvent& e); - /** @internal */ - bool keyPressed (const KeyPress& key); - /** @internal */ - bool keyPressed (const KeyPress& key, Component* originatingComponent); - /** @internal */ - bool keyStateChanged (bool isKeyDown, Component* originatingComponent); - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void parentHierarchyChanged(); - /** @internal */ - void visibilityChanged(); - /** @internal */ - void focusGained (FocusChangeType cause); - /** @internal */ - void focusLost (FocusChangeType cause); - /** @internal */ - void enablementChanged(); - /** @internal */ - void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo&); - /** @internal */ - void applicationCommandListChanged(); - /** @internal */ - void valueChanged (Value& value); + if (decibels <= minusInfinityDb) + { + s = "-INF dB"; + } + else + { + if (decibels >= Type()) + s << '+'; -private: + s << String (decibels, decimalPlaces) << " dB"; + } - Array shortcuts; - WeakReference keySource; - String text; - ListenerList buttonListeners; + return s; + } - class RepeatTimer; - friend class RepeatTimer; - friend class ScopedPointer ; - ScopedPointer repeatTimer; - uint32 buttonPressTime, lastRepeatTime; - ApplicationCommandManager* commandManagerToUse; - int autoRepeatDelay, autoRepeatSpeed, autoRepeatMinimumDelay; - int radioGroupId, commandID, connectedEdgeFlags; - ButtonState buttonState; +private: - Value isOn; - bool lastToggleState : 1; - bool clickTogglesState : 1; - bool needsToRelease : 1; - bool needsRepainting : 1; - bool isKeyDown : 1; - bool triggerOnMouseDown : 1; - bool generateTooltip : 1; + enum + { + defaultMinusInfinitydB = -100 + }; - void repeatTimerCallback(); - RepeatTimer& getRepeatTimer(); + Decibels(); // This class can't be instantiated, it's just a holder for static methods.. + JUCE_DECLARE_NON_COPYABLE (Decibels); +}; - ButtonState updateState(); - ButtonState updateState (bool isOver, bool isDown); - bool isShortcutPressed() const; - void turnOffOtherButtonsInGroup (bool sendChangeNotification); +#endif // __JUCE_DECIBELS_JUCEHEADER__ - void flashButtonState(); - void sendClickMessage (const ModifierKeys& modifiers); - void sendStateMessage(); +/*** End of inlined file: juce_Decibels.h ***/ - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Button); -}; -#ifndef DOXYGEN - /** This typedef is just for compatibility with old code and VC6 - newer code should use Button::Listener instead. */ - typedef Button::Listener ButtonListener; #endif +#ifndef __JUCE_IIRFILTER_JUCEHEADER__ -#if JUCE_VC6 - #undef Listener #endif +#ifndef __JUCE_REVERB_JUCEHEADER__ -#endif // __JUCE_BUTTON_JUCEHEADER__ +#endif +#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__ -/*** End of inlined file: juce_Button.h ***/ +#endif +#ifndef __JUCE_MIDIFILE_JUCEHEADER__ -/** - A scrollbar component. +/*** Start of inlined file: juce_MidiFile.h ***/ +#ifndef __JUCE_MIDIFILE_JUCEHEADER__ +#define __JUCE_MIDIFILE_JUCEHEADER__ - To use a scrollbar, set up its total range using the setRangeLimits() method - this - sets the range of values it can represent. Then you can use setCurrentRange() to - change the position and size of the scrollbar's 'thumb'. - Registering a ScrollBar::Listener with the scrollbar will allow you to find out when - the user moves it, and you can use the getCurrentRangeStart() to find out where - they moved it to. +/*** Start of inlined file: juce_MidiMessageSequence.h ***/ +#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ +#define __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ - The scrollbar will adjust its own visibility according to whether its thumb size - allows it to actually be scrolled. +/** + A sequence of timestamped midi messages. - For most purposes, it's probably easier to use a ViewportContainer or ListBox - instead of handling a scrollbar directly. + This allows the sequence to be manipulated, and also to be read from and + written to a standard midi file. - @see ScrollBar::Listener + @see MidiMessage, MidiFile */ -class JUCE_API ScrollBar : public Component, - public AsyncUpdater, - private Timer +class JUCE_API MidiMessageSequence { public: - /** Creates a Scrollbar. + /** Creates an empty midi sequence object. */ + MidiMessageSequence(); - @param isVertical whether it should be a vertical or horizontal bar - @param buttonsAreVisible whether to show the up/down or left/right buttons - */ - ScrollBar (bool isVertical, - bool buttonsAreVisible = true); + /** Creates a copy of another sequence. */ + MidiMessageSequence (const MidiMessageSequence& other); - /** Destructor. */ - ~ScrollBar(); + /** Replaces this sequence with another one. */ + MidiMessageSequence& operator= (const MidiMessageSequence& other); - /** Returns true if the scrollbar is vertical, false if it's horizontal. */ - bool isVertical() const noexcept { return vertical; } + /** Destructor. */ + ~MidiMessageSequence(); - /** Changes the scrollbar's direction. + /** Structure used to hold midi events in the sequence. - You'll also need to resize the bar appropriately - this just changes its internal - layout. + These structures act as 'handles' on the events as they are moved about in + the list, and make it quick to find the matching note-offs for note-on events. - @param shouldBeVertical true makes it vertical; false makes it horizontal. + @see MidiMessageSequence::getEventPointer */ - void setOrientation (bool shouldBeVertical); - - /** Shows or hides the scrollbar's buttons. */ - void setButtonVisibility (bool buttonsAreVisible); - - /** Tells the scrollbar whether to make itself invisible when not needed. + class MidiEventHolder + { + public: - The default behaviour is for a scrollbar to become invisible when the thumb - fills the whole of its range (i.e. when it can't be moved). Setting this - value to false forces the bar to always be visible. - @see autoHides() - */ - void setAutoHide (bool shouldHideWhenFullRange); + /** Destructor. */ + ~MidiEventHolder(); - /** Returns true if this scrollbar is set to auto-hide when its thumb is as big - as its maximum range. - @see setAutoHide - */ - bool autoHides() const noexcept; + /** The message itself, whose timestamp is used to specify the event's time. + */ + MidiMessage message; - /** Sets the minimum and maximum values that the bar will move between. + /** The matching note-off event (if this is a note-on event). - The bar's thumb will always be constrained so that the entire thumb lies - within this range. + If this isn't a note-on, this pointer will be null. - @see setCurrentRange - */ - void setRangeLimits (const Range& newRangeLimit); + Use the MidiMessageSequence::updateMatchedPairs() method to keep these + note-offs up-to-date after events have been moved around in the sequence + or deleted. + */ + MidiEventHolder* noteOffObject; - /** Sets the minimum and maximum values that the bar will move between. + private: - The bar's thumb will always be constrained so that the entire thumb lies - within this range. + friend class MidiMessageSequence; + MidiEventHolder (const MidiMessage& message); + JUCE_LEAK_DETECTOR (MidiEventHolder); + }; - @see setCurrentRange - */ - void setRangeLimits (double minimum, double maximum); + /** Clears the sequence. */ + void clear(); - /** Returns the current limits on the thumb position. - @see setRangeLimits - */ - const Range getRangeLimit() const noexcept { return totalRange; } + /** Returns the number of events in the sequence. */ + int getNumEvents() const; - /** Returns the lower value that the thumb can be set to. + /** Returns a pointer to one of the events. */ + MidiEventHolder* getEventPointer (int index) const; - This is the value set by setRangeLimits(). - */ - double getMinimumRangeLimit() const noexcept { return totalRange.getStart(); } + /** Returns the time of the note-up that matches the note-on at this index. - /** Returns the upper value that the thumb can be set to. + If the event at this index isn't a note-on, it'll just return 0. - This is the value set by setRangeLimits(). + @see MidiMessageSequence::MidiEventHolder::noteOffObject */ - double getMaximumRangeLimit() const noexcept { return totalRange.getEnd(); } + double getTimeOfMatchingKeyUp (int index) const; - /** Changes the position of the scrollbar's 'thumb'. + /** Returns the index of the note-up that matches the note-on at this index. - If this method call actually changes the scrollbar's position, it will trigger an - asynchronous call to ScrollBar::Listener::scrollBarMoved() for all the listeners that - are registered. + If the event at this index isn't a note-on, it'll just return -1. - @see getCurrentRange. setCurrentRangeStart + @see MidiMessageSequence::MidiEventHolder::noteOffObject */ - void setCurrentRange (const Range& newRange); - - /** Changes the position of the scrollbar's 'thumb'. + int getIndexOfMatchingKeyUp (int index) const; - This sets both the position and size of the thumb - to just set the position without - changing the size, you can use setCurrentRangeStart(). + /** Returns the index of an event. */ + int getIndexOf (MidiEventHolder* event) const; - If this method call actually changes the scrollbar's position, it will trigger an - asynchronous call to ScrollBar::Listener::scrollBarMoved() for all the listeners that - are registered. + /** Returns the index of the first event on or after the given timestamp. - @param newStart the top (or left) of the thumb, in the range - getMinimumRangeLimit() <= newStart <= getMaximumRangeLimit(). If the - value is beyond these limits, it will be clipped. - @param newSize the size of the thumb, such that - getMinimumRangeLimit() <= newStart + newSize <= getMaximumRangeLimit(). If the - size is beyond these limits, it will be clipped. - @see setCurrentRangeStart, getCurrentRangeStart, getCurrentRangeSize + If the time is beyond the end of the sequence, this will return the + number of events. */ - void setCurrentRange (double newStart, double newSize); + int getNextIndexAtTime (double timeStamp) const; - /** Moves the bar's thumb position. + /** Returns the timestamp of the first event in the sequence. - This will move the thumb position without changing the thumb size. Note - that the maximum thumb start position is (getMaximumRangeLimit() - getCurrentRangeSize()). + @see getEndTime + */ + double getStartTime() const; - If this method call actually changes the scrollbar's position, it will trigger an - asynchronous call to ScrollBar::Listener::scrollBarMoved() for all the listeners that - are registered. + /** Returns the timestamp of the last event in the sequence. - @see setCurrentRange + @see getStartTime */ - void setCurrentRangeStart (double newStart); + double getEndTime() const; - /** Returns the current thumb range. - @see getCurrentRange, setCurrentRange - */ - const Range getCurrentRange() const noexcept { return visibleRange; } + /** Returns the timestamp of the event at a given index. - /** Returns the position of the top of the thumb. - @see getCurrentRange, setCurrentRangeStart + If the index is out-of-range, this will return 0.0 */ - double getCurrentRangeStart() const noexcept { return visibleRange.getStart(); } + double getEventTime (int index) const; - /** Returns the current size of the thumb. - @see getCurrentRange, setCurrentRange - */ - double getCurrentRangeSize() const noexcept { return visibleRange.getLength(); } + /** Inserts a midi message into the sequence. - /** Sets the amount by which the up and down buttons will move the bar. + The index at which the new message gets inserted will depend on its timestamp, + because the sequence is kept sorted. - The value here is in terms of the total range, and is added or subtracted - from the thumb position when the user clicks an up/down (or left/right) button. + 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 */ - void setSingleStepSize (double newSingleStepSize); + void addEvent (const MidiMessage& newMessage, + double timeAdjustment = 0); - /** Moves the scrollbar by a number of single-steps. + /** Deletes one of the events in the sequence. - This will move the bar by a multiple of its single-step interval (as - specified using the setSingleStepSize() method). + Remember to call updateMatchedPairs() after removing events. - A positive value here will move the bar down or to the right, a negative - value moves it up or to the left. + @param index the index of the event to delete + @param deleteMatchingNoteUp whether to also remove the matching note-off + if the event you're removing is a note-on */ - void moveScrollbarInSteps (int howManySteps); + void deleteEvent (int index, bool deleteMatchingNoteUp); - /** Moves the scroll bar up or down in pages. + /** Merges another sequence into this one. - This will move the bar by a multiple of its current thumb size, effectively - doing a page-up or down. + Remember to call updateMatchedPairs() after using this method. - A positive value here will move the bar down or to the right, a negative - value moves it up or to the left. + @param other the sequence to add from + @param timeAdjustmentDelta an amount to add to the timestamps of the midi events + as they are read from the other sequence + @param firstAllowableDestTime events will not be added if their time is earlier + than this time. (This is after their time has been adjusted + by the timeAdjustmentDelta) + @param endOfAllowableDestTimes events will not be added if their time is equal to + or greater than this time. (This is after their time has + been adjusted by the timeAdjustmentDelta) */ - void moveScrollbarInPages (int howManyPages); + void addSequence (const MidiMessageSequence& other, + double timeAdjustmentDelta, + double firstAllowableDestTime, + double endOfAllowableDestTimes); - /** Scrolls to the top (or left). + /** Makes sure all the note-on and note-off pairs are up-to-date. - This is the same as calling setCurrentRangeStart (getMinimumRangeLimit()); + Call this after moving messages about or deleting/adding messages, and it + will scan the list and make sure all the note-offs in the MidiEventHolder + structures are pointing at the correct ones. */ - void scrollToTop(); + void updateMatchedPairs(); - /** Scrolls to the bottom (or right). + /** Copies all the messages for a particular midi channel to another sequence. - This is the same as calling setCurrentRangeStart (getMaximumRangeLimit() - getCurrentRangeSize()); + @param channelNumberToExtract the midi channel to look for, in the range 1 to 16 + @param destSequence the sequence that the chosen events should be copied to + @param alsoIncludeMetaEvents if true, any meta-events (which don't apply to a specific + channel) will also be copied across. + @see extractSysExMessages */ - void scrollToBottom(); - - /** Changes the delay before the up and down buttons autorepeat when they are held - down. + void extractMidiChannelMessages (int channelNumberToExtract, + MidiMessageSequence& destSequence, + bool alsoIncludeMetaEvents) const; - For an explanation of what the parameters are for, see Button::setRepeatSpeed(). + /** Copies all midi sys-ex messages to another sequence. - @see Button::setRepeatSpeed + @param destSequence this is the sequence to which any sys-exes in this sequence + will be added + @see extractMidiChannelMessages */ - void setButtonRepeatSpeed (int initialDelayInMillisecs, - int repeatDelayInMillisecs, - int minimumDelayInMillisecs = -1); - - /** A set of colour IDs to use to change the colour of various aspects of the component. + void extractSysExMessages (MidiMessageSequence& destSequence) const; - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. + /** Removes any messages in this sequence that have a specific midi channel. - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + @param channelNumberToRemove the midi channel to look for, in the range 1 to 16 */ - enum ColourIds - { - backgroundColourId = 0x1000300, /**< The background colour of the scrollbar. */ - thumbColourId = 0x1000400, /**< A base colour to use for the thumb. The look and feel will probably use variations on this colour. */ - trackColourId = 0x1000401 /**< A base colour to use for the slot area of the bar. The look and feel will probably use variations on this colour. */ - }; + void deleteMidiChannelMessages (int channelNumberToRemove); - /** - A class for receiving events from a ScrollBar. + /** Removes any sys-ex messages from this sequence. + */ + void deleteSysExMessages(); - You can register a ScrollBar::Listener with a ScrollBar using the ScrollBar::addListener() - method, and it will be called when the bar's position changes. + /** Adds an offset to the timestamps of all events in the sequence. - @see ScrollBar::addListener, ScrollBar::removeListener + @param deltaTime the amount to add to each timestamp. */ - class JUCE_API Listener - { - public: - /** Destructor. */ - virtual ~Listener() {} + void addTimeToMessages (double deltaTime); - /** Called when a ScrollBar is moved. + /** Scans through the sequence to determine the state of any midi controllers at + a given time. - @param scrollBarThatHasMoved the bar that has moved - @param newRangeStart the new range start of this bar - */ - virtual void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, - double newRangeStart) = 0; - }; + This will create a sequence of midi controller changes that can be + used to set all midi controllers to the state they would be in at the + specified time within this sequence. - /** Registers a listener that will be called when the scrollbar is moved. */ - void addListener (Listener* listener); + As well as controllers, it will also recreate the midi program number + and pitch bend position. - /** Deregisters a previously-registered listener. */ - void removeListener (Listener* listener); + @param channelNumber the midi channel to look for, in the range 1 to 16. Controllers + for other channels will be ignored. + @param time the time at which you want to find out the state - there are + no explicit units for this time measurement, it's the same units + as used for the timestamps of the messages + @param resultMessages an array to which midi controller-change messages will be added. This + will be the minimum number of controller changes to recreate the + state at the required time. + */ + void createControllerUpdatesForTime (int channelNumber, double time, + OwnedArray& resultMessages); + + /** Swaps this sequence with another one. */ + void swapWith (MidiMessageSequence& other) noexcept; /** @internal */ - bool keyPressed (const KeyPress& key); - /** @internal */ - void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); - /** @internal */ - void lookAndFeelChanged(); - /** @internal */ - void handleAsyncUpdate(); - /** @internal */ - void mouseDown (const MouseEvent& e); - /** @internal */ - void mouseDrag (const MouseEvent& e); - /** @internal */ - void mouseUp (const MouseEvent& e); - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void resized(); + static int compareElements (const MidiMessageSequence::MidiEventHolder* first, + const MidiMessageSequence::MidiEventHolder* second) noexcept; private: - Range totalRange, visibleRange; - double singleStepSize, dragStartRange; - int thumbAreaStart, thumbAreaSize, thumbStart, thumbSize; - int dragStartMousePos, lastMousePos; - int initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs; - bool vertical, isDraggingThumb, autohides; - class ScrollbarButton; - friend class ScopedPointer; - ScopedPointer upButton, downButton; - ListenerList listeners; + friend class MidiFile; + OwnedArray list; - void updateThumbPosition(); - void timerCallback(); + void sort(); - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScrollBar); + JUCE_LEAK_DETECTOR (MidiMessageSequence); }; -/** 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_JUCEHEADER__ +#endif // __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ -/*** End of inlined file: juce_ScrollBar.h ***/ +/*** End of inlined file: juce_MidiMessageSequence.h ***/ /** - A Viewport is used to contain a larger child component, and allows the child - to be automatically scrolled around. + Reads/writes standard midi format files. - To use a Viewport, just create one and set the component that goes inside it - using the setViewedComponent() method. When the child component changes size, - the Viewport will adjust its scrollbars accordingly. + To read a midi file, create a MidiFile object and call its readFrom() method. You + can then get the individual midi tracks from it using the getTrack() method. - A subclass of the viewport can be created which will receive calls to its - visibleAreaChanged() method when the subcomponent changes position or size. + To write a file, create a MidiFile object, add some MidiMessageSequence objects + to it using the addTrack() method, and then call its writeTo() method to stream + it out. + @see MidiMessageSequence */ -class JUCE_API Viewport : public Component, - private ComponentListener, - private ScrollBar::Listener +class JUCE_API MidiFile { public: - /** Creates a Viewport. - - The viewport is initially empty - use the setViewedComponent() method to - add a child component for it to manage. + /** Creates an empty MidiFile object. */ - explicit Viewport (const String& componentName = String::empty); + MidiFile(); /** Destructor. */ - ~Viewport(); - - /** Sets the component that this viewport will contain and scroll around. - - This will add the given component to this Viewport and position it at (0, 0). + ~MidiFile(); - (Don't add or remove any child components directly using the normal - Component::addChildComponent() methods). + /** Returns the number of tracks in the file. - @param newViewedComponent the component to add to this viewport, or null to remove - the current component. - @param deleteComponentWhenNoLongerNeeded if true, the component will be deleted - automatically when the viewport is deleted or when a different - component is added. If false, the caller must manage the lifetime - of the component - @see getViewedComponent + @see getTrack, addTrack */ - void setViewedComponent (Component* newViewedComponent, - bool deleteComponentWhenNoLongerNeeded = true); + int getNumTracks() const noexcept; - /** Returns the component that's currently being used inside the Viewport. + /** Returns a pointer to one of the tracks in the file. - @see setViewedComponent + @returns a pointer to the track, or 0 if the index is out-of-range + @see getNumTracks, addTrack */ - Component* getViewedComponent() const noexcept { return contentComp; } - - /** Changes the position of the viewed component. + const MidiMessageSequence* getTrack (int index) const noexcept; - The inner component will be moved so that the pixel at the top left of - the viewport will be the pixel at position (xPixelsOffset, yPixelsOffset) - within the inner component. + /** Adds a midi track to the file. - This will update the scrollbars and might cause a call to visibleAreaChanged(). + This will make its own internal copy of the sequence that is passed-in. - @see getViewPositionX, getViewPositionY, setViewPositionProportionately + @see getNumTracks, getTrack */ - void setViewPosition (int xPixelsOffset, int yPixelsOffset); - - /** Changes the position of the viewed component. - - The inner component will be moved so that the pixel at the top left of - the viewport will be the pixel at the specified coordinates within the - inner component. + void addTrack (const MidiMessageSequence& trackSequence); - This will update the scrollbars and might cause a call to visibleAreaChanged(). + /** Removes all midi tracks from the file. - @see getViewPositionX, getViewPositionY, setViewPositionProportionately + @see getNumTracks */ - void setViewPosition (const Point& newPosition); - - /** Changes the view position as a proportion of the distance it can move. + void clear(); - The values here are from 0.0 to 1.0 - where (0, 0) would put the - visible area in the top-left, and (1, 1) would put it as far down and - to the right as it's possible to go whilst keeping the child component - on-screen. - */ - void setViewPositionProportionately (double proportionX, double proportionY); + /** Returns the raw time format code that will be written to a stream. - /** If the specified position is at the edges of the viewport, this method scrolls - the viewport to bring that position nearer to the centre. + After reading a midi file, this method will return the time-format that + was read from the file's header. It can be changed using the setTicksPerQuarterNote() + or setSmpteTimeFormat() methods. - Call this if you're dragging an object inside a viewport and want to make it scroll - when the user approaches an edge. You might also find Component::beginDragAutoRepeat() - useful when auto-scrolling. + If the value returned is positive, it indicates the number of midi ticks + per quarter-note - see setTicksPerQuarterNote(). - @param mouseX the x position, relative to the Viewport's top-left - @param mouseY the y position, relative to the Viewport's top-left - @param distanceFromEdge specifies how close to an edge the position needs to be - before the viewport should scroll in that direction - @param maximumSpeed the maximum number of pixels that the viewport is allowed - to scroll by. - @returns true if the viewport was scrolled + It it's negative, the upper byte indicates the frames-per-second (but negative), and + the lower byte is the number of ticks per frame - see setSmpteTimeFormat(). */ - bool autoScroll (int mouseX, int mouseY, int distanceFromEdge, int maximumSpeed); + short getTimeFormat() const noexcept; - /** Returns the position within the child component of the top-left of its visible area. - */ - const Point getViewPosition() const noexcept { return lastVisibleArea.getPosition(); } + /** Sets the time format to use when this file is written to a stream. - /** Returns the position within the child component of the top-left of its visible area. - @see getViewWidth, setViewPosition - */ - int getViewPositionX() const noexcept { return lastVisibleArea.getX(); } + If this is called, the file will be written as bars/beats using the + specified resolution, rather than SMPTE absolute times, as would be + used if setSmpteTimeFormat() had been called instead. - /** Returns the position within the child component of the top-left of its visible area. - @see getViewHeight, setViewPosition + @param ticksPerQuarterNote e.g. 96, 960 + @see setSmpteTimeFormat */ - int getViewPositionY() const noexcept { return lastVisibleArea.getY(); } - - /** Returns the width of the visible area of the child component. + void setTicksPerQuarterNote (int ticksPerQuarterNote) noexcept; - This may be less than the width of this Viewport if there's a vertical scrollbar - or if the child component is itself smaller. - */ - int getViewWidth() const noexcept { return lastVisibleArea.getWidth(); } + /** Sets the time format to use when this file is written to a stream. - /** Returns the height of the visible area of the child component. + If this is called, the file will be written using absolute times, rather + than bars/beats as would be the case if setTicksPerBeat() had been called + instead. - This may be less than the height of this Viewport if there's a horizontal scrollbar - or if the child component is itself smaller. + @param framesPerSecond must be 24, 25, 29 or 30 + @param subframeResolution the sub-second resolution, e.g. 4 (midi time code), + 8, 10, 80 (SMPTE bit resolution), or 100. For millisecond + timing, setSmpteTimeFormat (25, 40) + @see setTicksPerBeat */ - int getViewHeight() const noexcept { return lastVisibleArea.getHeight(); } - - /** Returns the width available within this component for the contents. + void setSmpteTimeFormat (int framesPerSecond, + int subframeResolution) noexcept; - This will be the width of the viewport component minus the width of a - vertical scrollbar (if visible). - */ - int getMaximumVisibleWidth() const; + /** Makes a list of all the tempo-change meta-events from all tracks in the midi file. - /** Returns the height available within this component for the contents. + Useful for finding the positions of all the tempo changes in a file. - This will be the height of the viewport component minus the space taken up - by a horizontal scrollbar (if visible). + @param tempoChangeEvents a list to which all the events will be added */ - int getMaximumVisibleHeight() const; - - /** Callback method that is called when the visible area changes. + void findAllTempoEvents (MidiMessageSequence& tempoChangeEvents) const; - This will be called when the visible area is moved either be scrolling or - by calls to setViewPosition(), etc. - */ - virtual void visibleAreaChanged (const Rectangle& newVisibleArea); + /** Makes a list of all the time-signature meta-events from all tracks in the midi file. - /** Turns scrollbars on or off. + Useful for finding the positions of all the tempo changes in a file. - If set to false, the scrollbars won't ever appear. When true (the default) - they will appear only when needed. + @param timeSigEvents a list to which all the events will be added */ - void setScrollBarsShown (bool showVerticalScrollbarIfNeeded, - bool showHorizontalScrollbarIfNeeded); + void findAllTimeSigEvents (MidiMessageSequence& timeSigEvents) const; - /** True if the vertical scrollbar is enabled. - @see setScrollBarsShown - */ - bool isVerticalScrollBarShown() const noexcept { return showVScrollbar; } + /** Returns the latest timestamp in any of the tracks. - /** True if the horizontal scrollbar is enabled. - @see setScrollBarsShown + (Useful for finding the length of the file). */ - 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. + double getLastTimestamp() const; - @see LookAndFeel::getDefaultScrollbarWidth - */ - void setScrollBarThickness (int thickness); + /** Reads a midi file format stream. - /** Returns the thickness of the scrollbars. + After calling this, you can get the tracks that were read from the file by using the + getNumTracks() and getTrack() methods. - @see setScrollBarThickness - */ - int getScrollBarThickness() const; + The timestamps of the midi events in the tracks will represent their positions in + terms of midi ticks. To convert them to seconds, use the convertTimestampTicksToSeconds() + method. - /** Changes the distance that a single-step click on a scrollbar button - will move the viewport. + @returns true if the stream was read successfully */ - void setSingleStepSizes (int stepX, int stepY); + bool readFrom (InputStream& sourceStream); - /** Shows or hides the buttons on any scrollbars that are used. + /** Writes the midi tracks as a standard midi file. - @see ScrollBar::setButtonVisibility + @returns true if the operation succeeded. */ - void setScrollBarButtonVisibility (bool buttonsVisible); + bool writeTo (OutputStream& destStream); - /** Returns a pointer to the scrollbar component being used. - Handy if you need to customise the bar somehow. - */ - ScrollBar* getVerticalScrollBar() noexcept { return &verticalScrollBar; } + /** Converts the timestamp of all the midi events from midi ticks to seconds. - /** Returns a pointer to the scrollbar component being used. - Handy if you need to customise the bar somehow. + This will use the midi time format and tempo/time signature info in the + tracks to convert all the timestamps to absolute values in seconds. */ - ScrollBar* getHorizontalScrollBar() noexcept { return &horizontalScrollBar; } - - /** @internal */ - void resized(); - /** @internal */ - void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart); - /** @internal */ - void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); - /** @internal */ - bool keyPressed (const KeyPress& key); - /** @internal */ - void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); - /** @internal */ - bool useMouseWheelMoveIfNeeded (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); + void convertTimestampTicksToSeconds(); private: - WeakReference contentComp; - Rectangle lastVisibleArea; - int scrollBarThickness; - int singleStepX, singleStepY; - bool showHScrollbar, showVScrollbar, deleteContent; - Component contentHolder; - ScrollBar verticalScrollBar; - ScrollBar horizontalScrollBar; - - void updateVisibleArea(); - void deleteContentComp(); - - #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // If you get an error here, it's because this method's parameters have changed! See the new definition above.. - virtual int visibleAreaChanged (int, int, int, int) { return 0; } - #endif - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Viewport); -}; - -#endif // __JUCE_VIEWPORT_JUCEHEADER__ - -/*** End of inlined file: juce_Viewport.h ***/ - + OwnedArray tracks; + short timeFormat; -/*** Start of inlined file: juce_PopupMenu.h ***/ -#ifndef __JUCE_POPUPMENU_JUCEHEADER__ -#define __JUCE_POPUPMENU_JUCEHEADER__ + void readNextTrack (const uint8* data, int size); + void writeTrack (OutputStream& mainOut, int trackNum); -/** Creates and displays a popup-menu. + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiFile); +}; - To show a popup-menu, you create one of these, add some items to it, then - call its show() method, which returns the id of the item the user selects. +#endif // __JUCE_MIDIFILE_JUCEHEADER__ - E.g. @code - void MyWidget::mouseDown (const MouseEvent& e) - { - PopupMenu m; - m.addItem (1, "item 1"); - m.addItem (2, "item 2"); +/*** End of inlined file: juce_MidiFile.h ***/ - const int result = m.show(); - if (result == 0) - { - // user dismissed the menu without picking anything - } - else if (result == 1) - { - // user picked item 1 - } - else if (result == 2) - { - // user picked item 2 - } - } - @endcode +#endif +#ifndef __JUCE_MIDIINPUT_JUCEHEADER__ - Submenus are easy too: @code +#endif +#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ - void MyWidget::mouseDown (const MouseEvent& e) - { - PopupMenu subMenu; - subMenu.addItem (1, "item 1"); - subMenu.addItem (2, "item 2"); +/*** Start of inlined file: juce_MidiKeyboardState.h ***/ +#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ +#define __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ - PopupMenu mainMenu; - mainMenu.addItem (3, "item 3"); - mainMenu.addSubMenu ("other choices", subMenu); +class MidiKeyboardState; - const int result = m.show(); +/** + Receives events from a MidiKeyboardState object. - ...etc - } - @endcode + @see MidiKeyboardState */ -class JUCE_API PopupMenu +class JUCE_API MidiKeyboardStateListener { public: - /** Creates an empty popup menu. */ - PopupMenu(); - - /** Creates a copy of another menu. */ - PopupMenu (const PopupMenu& other); - - /** Destructor. */ - ~PopupMenu(); - - /** Copies this menu from another one. */ - PopupMenu& operator= (const PopupMenu& other); - - /** Resets the menu, removing all its items. */ - void clear(); + MidiKeyboardStateListener() noexcept {} + virtual ~MidiKeyboardStateListener() {} - /** Appends a new text item for this menu to show. + /** Called when one of the MidiKeyboardState's keys is pressed. - @param itemResultId the number that will be returned from the show() method - if the user picks this item. The value should never be - zero, because that's used to indicate that the user didn't - select anything. - @param itemText the text to show. - @param isActive if false, the item will be shown 'greyed-out' and can't be - picked - @param isTicked if true, the item will be shown with a tick next to it - @param iconToUse if this is non-zero, it should be an image that will be - displayed to the left of the item. This method will take its - own copy of the image passed-in, so there's no need to keep - it hanging around. + This will be called synchronously when the state is either processing a + buffer in its MidiKeyboardState::processNextMidiBuffer() method, or + when a note is being played with its MidiKeyboardState::noteOn() method. - @see addSeparator, addColouredItem, addCustomItem, addSubMenu + Note that this callback could happen from an audio callback thread, so be + careful not to block, and avoid any UI activity in the callback. */ - void addItem (int itemResultId, - const String& itemText, - bool isActive = true, - bool isTicked = false, - const Image& iconToUse = Image::null); - - /** Adds an item that represents one of the commands in a command manager object. + virtual void handleNoteOn (MidiKeyboardState* source, + int midiChannel, int midiNoteNumber, float velocity) = 0; - @param commandManager the manager to use to trigger the command and get information - about it - @param commandID the ID of the command - @param displayName if this is non-empty, then this string will be used instead of - the command's registered name - */ - void addCommandItem (ApplicationCommandManager* commandManager, - int commandID, - const String& displayName = String::empty); + /** Called when one of the MidiKeyboardState's keys is released. - /** Appends a text item with a special colour. + This will be called synchronously when the state is either processing a + buffer in its MidiKeyboardState::processNextMidiBuffer() method, or + when a note is being played with its MidiKeyboardState::noteOff() method. - This is the same as addItem(), but specifies a colour to use for the - text, which will override the default colours that are used by the - current look-and-feel. See addItem() for a description of the parameters. + Note that this callback could happen from an audio callback thread, so be + careful not to block, and avoid any UI activity in the callback. */ - void addColouredItem (int itemResultId, - const String& itemText, - const Colour& itemTextColour, - bool isActive = true, - bool isTicked = false, - const Image& iconToUse = Image::null); + virtual void handleNoteOff (MidiKeyboardState* source, + int midiChannel, int midiNoteNumber) = 0; +}; - /** Appends a custom menu item that can't be used to trigger a result. +/** + Represents a piano keyboard, keeping track of which keys are currently pressed. - This will add a user-defined component to use as a menu item. Unlike the - addCustomItem() method that takes a PopupMenu::CustomComponent, this version - can't trigger a result from it, so doesn't take a menu ID. It also doesn't - delete the component when it's finished, so it's the caller's responsibility - to manage the component that is passed-in. + This object can parse a stream of midi events, using them to update its idea + of which keys are pressed for each individiual midi channel. - if triggerMenuItemAutomaticallyWhenClicked is true, the menu itself will handle - detection of a mouse-click on your component, and use that to trigger the - menu ID specified in itemResultId. If this is false, the menu item can't - be triggered, so itemResultId is not used. + When keys go up or down, it can broadcast these events to listener objects. - @see CustomComponent - */ - void addCustomItem (int itemResultId, - Component* customComponent, - int idealWidth, int idealHeight, - bool triggerMenuItemAutomaticallyWhenClicked); + It also allows key up/down events to be triggered with its noteOn() and noteOff() + methods, and midi messages for these events will be merged into the + midi stream that gets processed by processNextMidiBuffer(). +*/ +class JUCE_API MidiKeyboardState +{ +public: - /** Appends a sub-menu. + MidiKeyboardState(); + ~MidiKeyboardState(); - If the menu that's passed in is empty, it will appear as an inactive item. - */ - void addSubMenu (const String& subMenuName, - const PopupMenu& subMenu, - bool isActive = true, - const Image& iconToUse = Image::null, - bool isTicked = false); + /** Resets the state of the object. - /** Appends a separator to the menu, to help break it up into sections. + All internal data for all the channels is reset, but no events are sent as a + result. - The menu class is smart enough not to display separators at the top or bottom - of the menu, and it will replace mutliple adjacent separators with a single - one, so your code can be quite free and easy about adding these, and it'll - always look ok. + If you want to release any keys that are currently down, and to send out note-up + midi messages for this, use the allNotesOff() method instead. */ - void addSeparator(); + void reset(); - /** Adds a non-clickable text item to the menu. + /** Returns true if the given midi key is currently held down for the given midi channel. - This is a bold-font items which can be used as a header to separate the items - into named groups. + The channel number must be between 1 and 16. If you want to see if any notes are + on for a range of channels, use the isNoteOnForChannels() method. */ - void addSectionHeader (const String& title); + bool isNoteOn (int midiChannel, int midiNoteNumber) const noexcept; - /** Returns the number of items that the menu currently contains. + /** Returns true if the given midi key is currently held down on any of a set of midi channels. - (This doesn't count separators). + The channel mask has a bit set for each midi channel you want to test for - bit + 0 = midi channel 1, bit 1 = midi channel 2, etc. + + If a note is on for at least one of the specified channels, this returns true. */ - int getNumItems() const noexcept; + bool isNoteOnForChannels (int midiChannelMask, int midiNoteNumber) const noexcept; - /** Returns true if the menu contains a command item that triggers the given command. */ - bool containsCommandItem (int commandID) const; + /** Turns a specified note on. - /** Returns true if the menu contains any items that can be used. */ - bool containsAnyActiveItems() const noexcept; + This will cause a suitable midi note-on event to be injected into the midi buffer during the + next call to processNextMidiBuffer(). - /** Class used to create a set of options to pass to the show() method. - You can chain together a series of calls to this class's methods to create - a set of whatever options you want to specify. - E.g. @code - PopupMenu menu; - ... - menu.showMenu (PopupMenu::Options().withMaximumWidth (100), - .withMaximumNumColumns (3) - .withTargetComponent (myComp)); - @endcode + It will also trigger a synchronous callback to the listeners to tell them that the key has + gone down. */ - class JUCE_API Options - { - public: - Options(); - - const Options withTargetComponent (Component* targetComponent) const; - const Options withTargetScreenArea (const Rectangle& targetArea) const; - const Options withMinimumWidth (int minWidth) const; - const Options withMaximumNumColumns (int maxNumColumns) const; - const Options withStandardItemHeight (int standardHeight) const; - const Options withItemThatMustBeVisible (int idOfItemToBeVisible) const; - - private: - friend class PopupMenu; - Rectangle targetArea; - Component* targetComponent; - int visibleItemID, minWidth, maxColumns, standardHeight; - }; + void noteOn (int midiChannel, int midiNoteNumber, float velocity); - #if JUCE_MODAL_LOOPS_PERMITTED - /** Displays the menu and waits for the user to pick something. + /** Turns a specified note off. - This will display the menu modally, and return the ID of the item that the - user picks. If they click somewhere off the menu to get rid of it without - choosing anything, this will return 0. + This will cause a suitable midi note-off event to be injected into the midi buffer during the + next call to processNextMidiBuffer(). - The current location of the mouse will be used as the position to show the - menu - to explicitly set the menu's position, use showAt() instead. Depending - on where this point is on the screen, the menu will appear above, below or - to the side of the point. + It will also trigger a synchronous callback to the listeners to tell them that the key has + gone up. - @param itemIdThatMustBeVisible if you set this to the ID of one of the menu items, - then when the menu first appears, it will make sure - that this item is visible. So if the menu has too many - items to fit on the screen, it will be scrolled to a - position where this item is visible. - @param minimumWidth a minimum width for the menu, in pixels. It may be wider - than this if some items are too long to fit. - @param maximumNumColumns if there are too many items to fit on-screen in a single - vertical column, the menu may be laid out as a series of - columns - this is the maximum number allowed. To use the - default value for this (probably about 7), you can pass - in zero. - @param standardItemHeight if this is non-zero, it will be used as the standard - height for menu items (apart from custom items) - @param callback if this is non-zero, the menu will be launched asynchronously, - returning immediately, and the callback will receive a - call when the menu is either dismissed or has an item - selected. This object will be owned and deleted by the - system, so make sure that it works safely and that any - pointers that it uses are safely within scope. - @see showAt + But if the note isn't acutally down for the given channel, this method will in fact do nothing. */ - int show (int itemIdThatMustBeVisible = 0, - int minimumWidth = 0, - int maximumNumColumns = 0, - int standardItemHeight = 0, - ModalComponentManager::Callback* callback = nullptr); - - /** Displays the menu at a specific location. + void noteOff (int midiChannel, int midiNoteNumber); - This is the same as show(), but uses a specific location (in global screen - co-ordinates) rather than the current mouse position. + /** This will turn off any currently-down notes for the given midi channel. - The screenAreaToAttachTo parameter indicates a screen area to which the menu - will be adjacent. Depending on where this is, the menu will decide which edge to - attach itself to, in order to fit itself fully on-screen. If you just want to - trigger a menu at a specific point, you can pass in a rectangle of size (0, 0) - with the position that you want. + If you pass 0 for the midi channel, it will in fact turn off all notes on all channels. - @see show() + Calling this method will make calls to noteOff(), so can trigger synchronous callbacks + and events being added to the midi stream. */ - int showAt (const Rectangle& screenAreaToAttachTo, - int itemIdThatMustBeVisible = 0, - int minimumWidth = 0, - int maximumNumColumns = 0, - int standardItemHeight = 0, - ModalComponentManager::Callback* callback = nullptr); + void allNotesOff (int midiChannel); - /** Displays the menu as if it's attached to a component such as a button. + /** Looks at a key-up/down event and uses it to update the state of this object. - This is similar to showAt(), but will position it next to the given component, e.g. - so that the menu's edge is aligned with that of the component. This is intended for - things like buttons that trigger a pop-up menu. + To process a buffer full of midi messages, use the processNextMidiBuffer() method + instead. */ - int showAt (Component* componentToAttachTo, - int itemIdThatMustBeVisible = 0, - int minimumWidth = 0, - int maximumNumColumns = 0, - int standardItemHeight = 0, - ModalComponentManager::Callback* callback = nullptr); + void processNextMidiEvent (const MidiMessage& message); - /** Displays and runs the menu modally, with a set of options. - */ - int showMenu (const Options& options); - #endif + /** Scans a midi stream for up/down events and adds its own events to it. - /** Runs the menu asynchronously, with a user-provided callback that will receive the result. */ - void showMenuAsync (const Options& options, - ModalComponentManager::Callback* callback); + This will look for any up/down events and use them to update the internal state, + synchronously making suitable callbacks to the listeners. - /** Closes any menus that are currently open. + If injectIndirectEvents is true, then midi events to produce the recent noteOn() + and noteOff() calls will be added into the buffer. - This might be useful if you have a situation where your window is being closed - by some means other than a user action, and you'd like to make sure that menus - aren't left hanging around. - */ - static bool JUCE_CALLTYPE dismissAllActiveMenus(); + Only the section of the buffer whose timestamps are between startSample and + (startSample + numSamples) will be affected, and any events added will be placed + between these times. - /** Specifies a look-and-feel for the menu and any sub-menus that it has. + If you're going to use this method, you'll need to keep calling it regularly for + it to work satisfactorily. - This can be called before show() if you need a customised menu. Be careful - not to delete the LookAndFeel object before the menu has been deleted. + To process a single midi event at a time, use the processNextMidiEvent() method + instead. */ - void setLookAndFeel (LookAndFeel* newLookAndFeel); - - /** A set of colour IDs to use to change the colour of various aspects of the menu. + void processNextMidiBuffer (MidiBuffer& buffer, + int startSample, + int numSamples, + bool injectIndirectEvents); - These constants can be used either via the LookAndFeel::setColour() - method for the look and feel that is set for this menu with setLookAndFeel() + /** Registers a listener for callbacks when keys go up or down. - @see setLookAndFeel, LookAndFeel::setColour, LookAndFeel::findColour + @see removeListener */ - enum ColourIds - { - backgroundColourId = 0x1000700, /**< The colour to fill the menu's background with. */ - textColourId = 0x1000600, /**< The colour for normal menu item text, (unless the - colour is specified when the item is added). */ - headerTextColourId = 0x1000601, /**< The colour for section header item text (see the - addSectionHeader() method). */ - highlightedBackgroundColourId = 0x1000900, /**< The colour to fill the background of the currently - highlighted menu item. */ - highlightedTextColourId = 0x1000800, /**< The colour to use for the text of the currently - highlighted item. */ - }; + void addListener (MidiKeyboardStateListener* listener); - /** - Allows you to iterate through the items in a pop-up menu, and examine - their properties. + /** Deregisters a listener. - To use this, just create one and repeatedly call its next() method. When this - returns true, all the member variables of the iterator are filled-out with - information describing the menu item. When it returns false, the end of the - list has been reached. + @see addListener */ - class JUCE_API MenuItemIterator - { - public: - - /** Creates an iterator that will scan through the items in the specified - menu. - - Be careful not to add any items to a menu while it is being iterated, - or things could get out of step. - */ - MenuItemIterator (const PopupMenu& menu); + void removeListener (MidiKeyboardStateListener* listener); - /** Destructor. */ - ~MenuItemIterator(); +private: - /** Returns true if there is another item, and sets up all this object's - member variables to reflect that item's properties. - */ - bool next(); + CriticalSection lock; + uint16 noteStates [128]; + MidiBuffer eventsToAdd; + Array listeners; - String itemName; - const PopupMenu* subMenu; - int itemId; - bool isSeparator; - bool isTicked; - bool isEnabled; - bool isCustomComponent; - bool isSectionHeader; - const Colour* customColour; - Image customImage; - ApplicationCommandManager* commandManager; + void noteOnInternal (int midiChannel, int midiNoteNumber, float velocity); + void noteOffInternal (int midiChannel, int midiNoteNumber); - private: + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiKeyboardState); +}; - const PopupMenu& menu; - int index; +#endif // __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MenuItemIterator); - }; +/*** End of inlined file: juce_MidiKeyboardState.h ***/ - /** A user-defined copmonent that can be used as an item in a popup menu. - @see PopupMenu::addCustomItem - */ - class JUCE_API CustomComponent : public Component, - public ReferenceCountedObject - { - public: - /** Creates a custom item. - If isTriggeredAutomatically is true, then the menu will automatically detect - a mouse-click on this component and use that to invoke the menu item. If it's - false, then it's up to your class to manually trigger the item when it wants to. - */ - CustomComponent (bool isTriggeredAutomatically = true); - /** Destructor. */ - ~CustomComponent(); +#endif +#ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__ - /** Returns a rectangle with the size that this component would like to have. +#endif +#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ - Note that the size which this method returns isn't necessarily the one that - the menu will give it, as the items will be stretched to have a uniform width. - */ - virtual void getIdealSize (int& idealWidth, int& idealHeight) = 0; +/*** Start of inlined file: juce_MidiMessageCollector.h ***/ +#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ +#define __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ - /** Dismisses the menu, indicating that this item has been chosen. +/** + Collects incoming realtime MIDI messages and turns them into blocks suitable for + processing by a block-based audio callback. - This will cause the menu to exit from its modal state, returning - this item's id as the result. - */ - void triggerMenuItem(); + The class can also be used as either a MidiKeyboardStateListener or a MidiInputCallback + so it can easily use a midi input or keyboard component as its source. - /** Returns true if this item should be highlighted because the mouse is over it. - You can call this method in your paint() method to find out whether - to draw a highlight. - */ - bool isItemHighlighted() const noexcept { return isHighlighted; } + @see MidiMessage, MidiInput +*/ +class JUCE_API MidiMessageCollector : public MidiKeyboardStateListener, + public MidiInputCallback +{ +public: - /** @internal */ - bool isTriggeredAutomatically() const noexcept { return triggeredAutomatically; } - /** @internal */ - void setHighlighted (bool shouldBeHighlighted); + /** Creates a MidiMessageCollector. */ + MidiMessageCollector(); - private: + /** Destructor. */ + ~MidiMessageCollector(); - bool isHighlighted, triggeredAutomatically; + /** Clears any messages from the queue. - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomComponent); - }; + You need to call this method before starting to use the collector, so that + it knows the correct sample rate to use. + */ + void reset (double sampleRate); - /** Appends a custom menu item. + /** Takes an incoming real-time message and adds it to the queue. - This will add a user-defined component to use as a menu item. The component - passed in will be deleted by this menu when it's no longer needed. + The message's timestamp is taken, and it will be ready for retrieval as part + of the block returned by the next call to removeNextBlockOfMessages(). - @see CustomComponent + This method is fully thread-safe when overlapping calls are made with + removeNextBlockOfMessages(). */ - void addCustomItem (int itemResultId, CustomComponent* customComponent); - -private: + void addMessageToQueue (const MidiMessage& message); - class Item; - class ItemComponent; - class Window; + /** Removes all the pending messages from the queue as a buffer. - friend class MenuItemIterator; - friend class ItemComponent; - friend class Window; - friend class CustomComponent; - friend class MenuBarComponent; - friend class OwnedArray ; - friend class OwnedArray ; - friend class ScopedPointer ; + This will also correct the messages' timestamps to make sure they're in + the range 0 to numSamples - 1. - OwnedArray items; - LookAndFeel* lookAndFeel; - bool separatorPending; + This call should be made regularly by something like an audio processing + callback, because the time that it happens is used in calculating the + midi event positions. - void addSeparatorIfPending(); - Component* createWindow (const Options&, ApplicationCommandManager**) const; - int showWithOptionalCallback (const Options&, ModalComponentManager::Callback*, bool); + This method is fully thread-safe when overlapping calls are made with + addMessageToQueue(). + */ + void removeNextBlockOfMessages (MidiBuffer& destBuffer, int numSamples); - JUCE_LEAK_DETECTOR (PopupMenu); -}; + /** @internal */ + void handleNoteOn (MidiKeyboardState* source, int midiChannel, int midiNoteNumber, float velocity); + /** @internal */ + void handleNoteOff (MidiKeyboardState* source, int midiChannel, int midiNoteNumber); + /** @internal */ + void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message); -#endif // __JUCE_POPUPMENU_JUCEHEADER__ +private: -/*** End of inlined file: juce_PopupMenu.h ***/ + double lastCallbackTime; + CriticalSection midiCallbackLock; + MidiBuffer incomingMessages; + double sampleRate; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiMessageCollector); +}; -/*** Start of inlined file: juce_TextInputTarget.h ***/ -#ifndef __JUCE_TEXTINPUTTARGET_JUCEHEADER__ -#define __JUCE_TEXTINPUTTARGET_JUCEHEADER__ +#endif // __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ -/** - An abstract base class which can be implemented by components that function as - text editors. +/*** End of inlined file: juce_MidiMessageCollector.h ***/ - This class allows different types of text editor component to provide a uniform - interface, which can be used by things like OS-specific input methods, on-screen - keyboards, etc. -*/ -class JUCE_API TextInputTarget -{ -public: - /** */ - TextInputTarget() {} +#endif +#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ - /** Destructor. */ - virtual ~TextInputTarget() {} +#endif +#ifndef __JUCE_MIDIOUTPUT_JUCEHEADER__ - /** Returns true if this input target is currently accepting input. - For example, a text editor might return false if it's in read-only mode. - */ - virtual bool isTextInputActive() const = 0; +#endif +#ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__ - /** Returns the extents of the selected text region, or an empty range if - nothing is selected, - */ - virtual const Range getHighlightedRegion() const = 0; +/*** Start of inlined file: juce_AudioUnitPluginFormat.h ***/ +#ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__ +#define __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__ - /** Sets the currently-selected text region. */ - virtual void setHighlightedRegion (const Range& newRange) = 0; - /** Sets a number of temporarily underlined sections. - This is needed by MS Windows input method UI. - */ - virtual void setTemporaryUnderlining (const Array >& underlinedRegions) = 0; +/*** Start of inlined file: juce_AudioPluginFormat.h ***/ +#ifndef __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__ +#define __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__ - /** Returns a specified sub-section of the text. */ - virtual const String getTextInRange (const Range& range) const = 0; - /** Inserts some text, overwriting the selected text region, if there is one. */ - virtual void insertTextAtCaret (const String& textToInsert) = 0; +/*** Start of inlined file: juce_AudioPluginInstance.h ***/ +#ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ +#define __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ - /** Returns the position of the caret, relative to the component's origin. */ - virtual const Rectangle getCaretRectangle() = 0; -}; -#endif // __JUCE_TEXTINPUTTARGET_JUCEHEADER__ +/*** Start of inlined file: juce_AudioProcessor.h ***/ +#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__ +#define __JUCE_AUDIOPROCESSOR_JUCEHEADER__ -/*** End of inlined file: juce_TextInputTarget.h ***/ +/*** Start of inlined file: juce_AudioProcessorEditor.h ***/ +#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ +#define __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ -/*** Start of inlined file: juce_CaretComponent.h ***/ -#ifndef __JUCE_CARETCOMPONENT_JUCEHEADER__ -#define __JUCE_CARETCOMPONENT_JUCEHEADER__ +class AudioProcessor; /** + Base class for the component that acts as the GUI for an AudioProcessor. + + Derive your editor component from this class, and create an instance of it + by overriding the AudioProcessor::createEditor() method. + + @see AudioProcessor, GenericAudioProcessorEditor */ -class JUCE_API CaretComponent : public Component, - public Timer +class JUCE_API AudioProcessorEditor : public Component { -public: +protected: - /** Creates the caret component. - The keyFocusOwner is an optional component which the caret will check, making - itself visible only when the keyFocusOwner has keyboard focus. + /** Creates an editor for the specified processor. */ - CaretComponent (Component* keyFocusOwner); + AudioProcessorEditor (AudioProcessor* owner); +public: /** Destructor. */ - ~CaretComponent(); - - /** Sets the caret's position to place it next to the given character. - The area is the rectangle containing the entire character that the caret is - positioned on, so by default a vertical-line caret may choose to just show itself - at the left of this area. You can override this method to customise its size. - This method will also force the caret to reset its timer and become visible (if - appropriate), so that as it moves, you can see where it is. - */ - virtual void setCaretPosition (const Rectangle& characterArea); - - /** A set of colour IDs to use to change the colour of various aspects of the caret. - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - caretColourId = 0x1000204, /**< The colour with which to draw the caret. */ - }; + ~AudioProcessorEditor(); - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void timerCallback(); + /** Returns a pointer to the processor that this editor represents. */ + AudioProcessor* getAudioProcessor() const noexcept { return owner; } private: - Component* owner; - bool shouldBeShown() const; - JUCE_DECLARE_NON_COPYABLE (CaretComponent); + AudioProcessor* const owner; + + JUCE_DECLARE_NON_COPYABLE (AudioProcessorEditor); }; -#endif // __JUCE_CARETCOMPONENT_JUCEHEADER__ +#endif // __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ -/*** End of inlined file: juce_CaretComponent.h ***/ +/*** End of inlined file: juce_AudioProcessorEditor.h ***/ + + +/*** Start of inlined file: juce_AudioProcessorListener.h ***/ +#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ +#define __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ + +class AudioProcessor; /** - A component containing text that can be edited. + Base class for listeners that want to know about changes to an AudioProcessor. - A TextEditor can either be in single- or multi-line mode, and supports mixed - fonts and colours. + Use AudioProcessor::addListener() to register your listener with an AudioProcessor. - @see TextEditor::Listener, Label + @see AudioProcessor */ -class JUCE_API TextEditor : public Component, - public TextInputTarget, - public SettableTooltipClient +class JUCE_API AudioProcessorListener { public: - /** Creates a new, empty text editor. - - @param componentName the name to pass to the component for it to use as its name - @param passwordCharacter if this is not zero, this character will be used as a replacement - for all characters that are drawn on screen - e.g. to create - a password-style textbox containing circular blobs instead of text, - you could set this value to 0x25cf, which is the unicode character - for a black splodge (not all fonts include this, though), or 0x2022, - which is a bullet (probably the best choice for linux). - */ - explicit TextEditor (const String& componentName = String::empty, - juce_wchar passwordCharacter = 0); - /** Destructor. */ - virtual ~TextEditor(); - - /** Puts the editor into either multi- or single-line mode. - - By default, the editor will be in single-line mode, so use this if you need a multi-line - editor. - - See also the setReturnKeyStartsNewLine() method, which will also need to be turned - on if you want a multi-line editor with line-breaks. + virtual ~AudioProcessorListener() {} - @see isMultiLine, setReturnKeyStartsNewLine - */ - void setMultiLine (bool shouldBeMultiLine, - bool shouldWordWrap = true); + /** Receives a callback when a parameter is changed. - /** Returns true if the editor is in multi-line mode. + IMPORTANT NOTE: this will be called synchronously when a parameter changes, and + many audio processors will change their parameter during their audio callback. + This means that not only has your handler code got to be completely thread-safe, + but it's also got to be VERY fast, and avoid blocking. If you need to handle + this event on your message thread, use this callback to trigger an AsyncUpdater + or ChangeBroadcaster which you can respond to on the message thread. */ - bool isMultiLine() const; + virtual void audioProcessorParameterChanged (AudioProcessor* processor, + int parameterIndex, + float newValue) = 0; - /** Changes the behaviour of the return key. + /** Called to indicate that something else in the plugin has changed, like its + program, number of parameters, etc. - If set to true, the return key will insert a new-line into the text; if false - it will trigger a call to the TextEditor::Listener::textEditorReturnKeyPressed() - method. By default this is set to false, and when true it will only insert - new-lines when in multi-line mode (see setMultiLine()). + IMPORTANT NOTE: this will be called synchronously, and many audio processors will + call it during their audio callback. This means that not only has your handler code + got to be completely thread-safe, but it's also got to be VERY fast, and avoid + blocking. If you need to handle this event on your message thread, use this callback + to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the + message thread. */ - void setReturnKeyStartsNewLine (bool shouldStartNewLine); - - /** Returns the value set by setReturnKeyStartsNewLine(). + virtual void audioProcessorChanged (AudioProcessor* processor) = 0; - See setReturnKeyStartsNewLine() for more info. - */ - bool getReturnKeyStartsNewLine() const { return returnKeyStartsNewLine; } + /** Indicates that a parameter change gesture has started. - /** Indicates whether the tab key should be accepted and used to input a tab character, - or whether it gets ignored. + E.g. if the user is dragging a slider, this would be called when they first + press the mouse button, and audioProcessorParameterChangeGestureEnd would be + called when they release it. - By default the tab key is ignored, so that it can be used to switch keyboard focus - between components. - */ - void setTabKeyUsedAsCharacter (bool shouldTabKeyBeUsed); + IMPORTANT NOTE: this will be called synchronously, and many audio processors will + call it during their audio callback. This means that not only has your handler code + got to be completely thread-safe, but it's also got to be VERY fast, and avoid + blocking. If you need to handle this event on your message thread, use this callback + to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the + message thread. - /** Returns true if the tab key is being used for input. - @see setTabKeyUsedAsCharacter + @see audioProcessorParameterChangeGestureEnd */ - bool isTabKeyUsedAsCharacter() const { return tabKeyUsed; } + virtual void audioProcessorParameterChangeGestureBegin (AudioProcessor* processor, + int parameterIndex); - /** Changes the editor to read-only mode. + /** Indicates that a parameter change gesture has finished. - By default, the text editor is not read-only. If you're making it read-only, you - might also want to call setCaretVisible (false) to get rid of the caret. + E.g. if the user is dragging a slider, this would be called when they release + the mouse button. - The text can still be highlighted and copied when in read-only mode. + IMPORTANT NOTE: this will be called synchronously, and many audio processors will + call it during their audio callback. This means that not only has your handler code + got to be completely thread-safe, but it's also got to be VERY fast, and avoid + blocking. If you need to handle this event on your message thread, use this callback + to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the + message thread. - @see isReadOnly, setCaretVisible + @see audioProcessorParameterChangeGestureBegin */ - void setReadOnly (bool shouldBeReadOnly); + virtual void audioProcessorParameterChangeGestureEnd (AudioProcessor* processor, + int parameterIndex); +}; - /** Returns true if the editor is in read-only mode. - */ - bool isReadOnly() const; +#endif // __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ - /** Makes the caret visible or invisible. - By default the caret is visible. - @see setCaretColour, setCaretPosition - */ - void setCaretVisible (bool shouldBeVisible); +/*** End of inlined file: juce_AudioProcessorListener.h ***/ - /** Returns true if the caret is enabled. - @see setCaretVisible - */ - bool isCaretVisible() const { return caret != nullptr; } - /** Enables/disables a vertical scrollbar. +/*** Start of inlined file: juce_AudioPlayHead.h ***/ +#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ +#define __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ - (This only applies when in multi-line mode). When the text gets too long to fit - in the component, a scrollbar can appear to allow it to be scrolled. Even when - this is enabled, the scrollbar will be hidden unless it's needed. +/** + A subclass of AudioPlayHead can supply information about the position and + status of a moving play head during audio playback. - By default the scrollbar is enabled. - */ - void setScrollbarsShown (bool shouldBeEnabled); + One of these can be supplied to an AudioProcessor object so that it can find + out about the position of the audio that it is rendering. - /** Returns true if scrollbars are enabled. - @see setScrollbarsShown - */ - bool areScrollbarsShown() const { return scrollbarVisible; } + @see AudioProcessor::setPlayHead, AudioProcessor::getPlayHead +*/ +class JUCE_API AudioPlayHead +{ +protected: - /** Changes the password character used to disguise the text. + AudioPlayHead() {} - @param passwordCharacter if this is not zero, this character will be used as a replacement - for all characters that are drawn on screen - e.g. to create - a password-style textbox containing circular blobs instead of text, - you could set this value to 0x25cf, which is the unicode character - for a black splodge (not all fonts include this, though), or 0x2022, - which is a bullet (probably the best choice for linux). - */ - void setPasswordCharacter (juce_wchar passwordCharacter); +public: + virtual ~AudioPlayHead() {} - /** Returns the current password character. - @see setPasswordCharacter + /** Frame rate types. */ + enum FrameRateType + { + fps24 = 0, + fps25 = 1, + fps2997 = 2, + fps30 = 3, + fps2997drop = 4, + fps30drop = 5, + fpsUnknown = 99 + }; + + /** This structure is filled-in by the AudioPlayHead::getCurrentPosition() method. */ - juce_wchar getPasswordCharacter() const { return passwordCharacter; } + struct CurrentPositionInfo + { + /** The tempo in BPM */ + double bpm; - /** Allows a right-click menu to appear for the editor. + /** Time signature numerator, e.g. the 3 of a 3/4 time sig */ + int timeSigNumerator; + /** Time signature denominator, e.g. the 4 of a 3/4 time sig */ + int timeSigDenominator; - (This defaults to being enabled). + /** The current play position, in seconds from the start of the edit. */ + double timeInSeconds; - If enabled, right-clicking (or command-clicking on the Mac) will pop up a menu - of options such as cut/copy/paste, undo/redo, etc. - */ - void setPopupMenuEnabled (bool menuEnabled); + /** For timecode, the position of the start of the edit, in seconds from 00:00:00:00. */ + double editOriginTime; - /** Returns true if the right-click menu is enabled. - @see setPopupMenuEnabled - */ - bool isPopupMenuEnabled() const { return popupMenuEnabled; } + /** The current play position in pulses-per-quarter-note. - /** Returns true if a popup-menu is currently being displayed. - */ - bool isPopupMenuCurrentlyActive() const { return menuActive; } + This is the number of quarter notes since the edit start. + */ + double ppqPosition; - /** A set of colour IDs to use to change the colour of various aspects of the editor. + /** The position of the start of the last bar, in pulses-per-quarter-note. - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. + This is the number of quarter notes from the start of the edit to the + start of the current bar. - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - backgroundColourId = 0x1000200, /**< The colour to use for the text component's background - this can be - transparent if necessary. */ + Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If + it's not available, the value will be 0. + */ + double ppqPositionOfLastBarStart; - 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.*/ + /** The video frame rate, if applicable. */ + FrameRateType frameRate; - 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 - highlighting.*/ + /** True if the transport is currently playing. */ + bool isPlaying; - highlightedTextColourId = 0x1000203, /**< The colour with which to draw the text in highlighted sections. */ + /** True if the transport is currently recording. - outlineColourId = 0x1000205, /**< If this is non-transparent, it will be used to draw a box around - the edge of the component. */ + (When isRecording is true, then isPlaying will also be true). + */ + bool isRecording; - focusedOutlineColourId = 0x1000206, /**< If this is non-transparent, it will be used to draw a box around - the edge of the component when it has focus. */ + bool operator== (const CurrentPositionInfo& other) const noexcept; + bool operator!= (const CurrentPositionInfo& other) const noexcept; - shadowColourId = 0x1000207, /**< If this is non-transparent, it'll be used to draw an inner shadow - around the edge of the editor. */ + void resetToDefault(); }; - /** Sets the font to use for newly added text. - - This will change the font that will be used next time any text is added or entered - into the editor. It won't change the font of any existing text - to do that, use - applyFontToAllText() instead. - - @see applyFontToAllText + /** Fills-in the given structure with details about the transport's + position at the start of the current processing block. */ - void setFont (const Font& newFont); + virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0; +}; - /** Applies a font to all the text in the editor. +#endif // __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ - This will also set the current font to use for any new text that's added. +/*** End of inlined file: juce_AudioPlayHead.h ***/ - @see setFont - */ - void applyFontToAllText (const Font& newFont); +/** + Base class for audio processing filters or plugins. - /** Returns the font that's currently being used for new text. + This is intended to act as a base class of audio filter that is general enough to + be wrapped as a VST, AU, RTAS, etc, or used internally. - @see setFont - */ - const Font getFont() const; + It is also used by the plugin hosting code as the wrapper around an instance + of a loaded plugin. - /** If set to true, focusing on the editor will highlight all its text. + Derive your filter class from this base class, and if you're building a plugin, + you should implement a global function called createPluginFilter() which creates + and returns a new instance of your subclass. +*/ +class JUCE_API AudioProcessor +{ +protected: - (Set to false by default). + /** Constructor. - This is useful for boxes where you expect the user to re-enter all the - text when they focus on the component, rather than editing what's already there. + You can also do your initialisation tasks in the initialiseFilterInfo() + call, which will be made after this object has been created. */ - void setSelectAllWhenFocused (bool b); + AudioProcessor(); - /** Sets limits on the characters that can be entered. +public: + /** Destructor. */ + virtual ~AudioProcessor(); - @param maxTextLength if this is > 0, it sets a maximum length limit; if 0, no - limit is set - @param allowedCharacters if this is non-empty, then only characters that occur in - this string are allowed to be entered into the editor. + /** Returns the name of this processor. */ - void setInputRestrictions (int maxTextLength, - const String& allowedCharacters = String::empty); + virtual const String getName() const = 0; - /** When the text editor is empty, it can be set to display a message. + /** Called before playback starts, to let the filter prepare itself. - This is handy for things like telling the user what to type in the box - the - string is only displayed, it's not taken to actually be the contents of - the editor. - */ - void setTextToShowWhenEmpty (const String& text, const Colour& colourToUse); + The sample rate is the target sample rate, and will remain constant until + playback stops. - /** Changes the size of the scrollbars that are used. + The estimatedSamplesPerBlock value is a HINT about the typical number of + samples that will be processed for each callback, but isn't any kind + of guarantee. The actual block sizes that the host uses may be different + each time the callback happens, and may be more or less than this value. + */ + virtual void prepareToPlay (double sampleRate, + int estimatedSamplesPerBlock) = 0; - Handy if you need smaller scrollbars for a small text box. + /** Called after playback has stopped, to let the filter free up any resources it + no longer needs. */ - void setScrollBarThickness (int newThicknessPixels); + virtual void releaseResources() = 0; - /** Shows or hides the buttons on any scrollbars that are used. + /** Renders the next block. - @see ScrollBar::setButtonVisibility - */ - void setScrollBarButtonVisibility (bool buttonsVisible); + When this method is called, the buffer contains a number of channels which is + at least as great as the maximum number of input and output channels that + this filter is using. It will be filled with the filter's input data and + should be replaced with the filter's output. - /** - Receives callbacks from a TextEditor component when it changes. + So for example if your filter has 2 input channels and 4 output channels, then + the buffer will contain 4 channels, the first two being filled with the + input data. Your filter should read these, do its processing, and replace + the contents of all 4 channels with its output. - @see TextEditor::addListener - */ - class JUCE_API Listener - { - public: - /** Destructor. */ - virtual ~Listener() {} + Or if your filter has 5 inputs and 2 outputs, the buffer will have 5 channels, + all filled with data, and your filter should overwrite the first 2 of these + with its output. But be VERY careful not to write anything to the last 3 + channels, as these might be mapped to memory that the host assumes is read-only! - /** Called when the user changes the text in some way. */ - virtual void textEditorTextChanged (TextEditor& editor); + Note that if you have more outputs than inputs, then only those channels that + correspond to an input channel are guaranteed to contain sensible data - e.g. + in the case of 2 inputs and 4 outputs, the first two channels contain the input, + but the last two channels may contain garbage, so you should be careful not to + let this pass through without being overwritten or cleared. - /** Called when the user presses the return key. */ - virtual void textEditorReturnKeyPressed (TextEditor& editor); + Also note that the buffer may have more channels than are strictly necessary, + but your should only read/write from the ones that your filter is supposed to + be using. - /** Called when the user presses the escape key. */ - virtual void textEditorEscapeKeyPressed (TextEditor& editor); + The number of samples in these buffers is NOT guaranteed to be the same for every + callback, and may be more or less than the estimated value given to prepareToPlay(). + Your code must be able to cope with variable-sized blocks, or you're going to get + clicks and crashes! - /** Called when the text editor loses focus. */ - virtual void textEditorFocusLost (TextEditor& editor); - }; + If the filter is receiving a midi input, then the midiMessages array will be filled + with the midi messages for this block. Each message's timestamp will indicate the + message's time, as a number of samples from the start of the block. - /** Registers a listener to be told when things happen to the text. + Any messages left in the midi buffer when this method has finished are assumed to + be the filter's midi output. This means that your filter should be careful to + clear any incoming messages from the array if it doesn't want them to be passed-on. - @see removeListener + Be very careful about what you do in this callback - it's going to be called by + the audio thread, so any kind of interaction with the UI is absolutely + out of the question. If you change a parameter in here and need to tell your UI to + update itself, the best way is probably to inherit from a ChangeBroadcaster, let + the UI components register as listeners, and then call sendChangeMessage() inside the + processBlock() method to send out an asynchronous message. You could also use + the AsyncUpdater class in a similar way. */ - void addListener (Listener* newListener); - - /** Deregisters a listener. + virtual void processBlock (AudioSampleBuffer& buffer, + MidiBuffer& midiMessages) = 0; - @see addListener - */ - void removeListener (Listener* listenerToRemove); + /** Returns the current AudioPlayHead object that should be used to find + out the state and position of the playhead. - /** Returns the entire contents of the editor. */ - const String getText() const; + You can call this from your processBlock() method, and use the AudioPlayHead + object to get the details about the time of the start of the block currently + being processed. - /** Returns a section of the contents of the editor. */ - const String getTextInRange (const Range& textRange) const; + If the host hasn't supplied a playhead object, this will return 0. + */ + AudioPlayHead* getPlayHead() const noexcept { return playHead; } - /** Returns true if there are no characters in the editor. + /** Returns the current sample rate. - This is more efficient than calling getText().isEmpty(). + This can be called from your processBlock() method - it's not guaranteed + to be valid at any other time, and may return 0 if it's unknown. */ - bool isEmpty() const; + double getSampleRate() const noexcept { return sampleRate; } - /** Sets the entire content of the editor. + /** Returns the current typical block size that is being used. - This will clear the editor and insert the given text (using the current text colour - and font). You can set the current text colour using - @code setColour (TextEditor::textColourId, ...); - @endcode + This can be called from your processBlock() method - it's not guaranteed + to be valid at any other time. - @param newText the text to add - @param sendTextChangeMessage if true, this will cause a change message to - be sent to all the listeners. - @see insertText + Remember it's not the ONLY block size that may be used when calling + processBlock, it's just the normal one. The actual block sizes used may be + larger or smaller than this, and will vary between successive calls. */ - void setText (const String& newText, - bool sendTextChangeMessage = true); + int getBlockSize() const noexcept { return blockSize; } - /** Returns a Value object that can be used to get or set the text. + /** Returns the number of input channels that the host will be sending the filter. - Bear in mind that this operate quite slowly if your text box contains large - amounts of text, as it needs to dynamically build the string that's involved. It's - best used for small text boxes. - */ - Value& getTextValue(); + If writing a plugin, your JucePluginCharacteristics.h file should specify the + number of channels that your filter would prefer to have, and this method lets + you know how many the host is actually using. - /** Inserts some text at the current caret position. + Note that this method is only valid during or after the prepareToPlay() + method call. Until that point, the number of channels will be unknown. + */ + int getNumInputChannels() const noexcept { return numInputChannels; } - If a section of the text is highlighted, it will be replaced by - this string, otherwise it will be inserted. + /** Returns the number of output channels that the host will be sending the filter. - To delete a section of text, you can use setHighlightedRegion() to - highlight it, and call insertTextAtCursor (String::empty). + If writing a plugin, your JucePluginCharacteristics.h file should specify the + number of channels that your filter would prefer to have, and this method lets + you know how many the host is actually using. - @see setCaretPosition, getCaretPosition, setHighlightedRegion + Note that this method is only valid during or after the prepareToPlay() + method call. Until that point, the number of channels will be unknown. */ - void insertTextAtCaret (const String& textToInsert); + int getNumOutputChannels() const noexcept { return numOutputChannels; } - /** Deletes all the text from the editor. */ - void clear(); + /** Returns the name of one of the input channels, as returned by the host. - /** Deletes the currently selected region. - This doesn't copy the deleted section to the clipboard - if you need to do that, call copy() first. - @see copy, paste, SystemClipboard + The host might not supply very useful names for channels, and this might be + something like "1", "2", "left", "right", etc. */ - void cut(); + virtual const String getInputChannelName (int channelIndex) const = 0; - /** Copies the currently selected region to the clipboard. - @see cut, paste, SystemClipboard - */ - void copy(); + /** Returns the name of one of the output channels, as returned by the host. - /** Pastes the contents of the clipboard into the editor at the caret position. - @see cut, copy, SystemClipboard + The host might not supply very useful names for channels, and this might be + something like "1", "2", "left", "right", etc. */ - void paste(); + virtual const String getOutputChannelName (int channelIndex) const = 0; - /** Moves the caret to be in front of a given character. + /** Returns true if the specified channel is part of a stereo pair with its neighbour. */ + virtual bool isInputChannelStereoPair (int index) const = 0; - @see getCaretPosition - */ - void setCaretPosition (int newIndex); + /** Returns true if the specified channel is part of a stereo pair with its neighbour. */ + virtual bool isOutputChannelStereoPair (int index) const = 0; - /** Returns the current index of the caret. + /** This returns the number of samples delay that the filter imposes on the audio + passing through it. - @see setCaretPosition + The host will call this to find the latency - the filter itself should set this value + by calling setLatencySamples() as soon as it can during its initialisation. */ - int getCaretPosition() const; - - /** Attempts to scroll the text editor so that the caret ends up at - a specified position. + int getLatencySamples() const noexcept { return latencySamples; } - This won't affect the caret's position within the text, it tries to scroll - the entire editor vertically and horizontally so that the caret is sitting - at the given position (relative to the top-left of this component). + /** The filter should call this to set the number of samples delay that it introduces. - Depending on the amount of text available, it might not be possible to - scroll far enough for the caret to reach this exact position, but it - will go as far as it can in that direction. + The filter should call this as soon as it can during initialisation, and can call it + later if the value changes. */ - void scrollEditorToPositionCaret (int desiredCaretX, int desiredCaretY); + void setLatencySamples (int newLatency); - /** Get the graphical position of the caret. + /** Returns true if the processor wants midi messages. */ + virtual bool acceptsMidi() const = 0; - The rectangle returned is relative to the component's top-left corner. - @see scrollEditorToPositionCaret - */ - const Rectangle getCaretRectangle(); + /** Returns true if the processor produces midi messages. */ + virtual bool producesMidi() const = 0; - /** Selects a section of the text. */ - void setHighlightedRegion (const Range& newSelection); + /** This returns a critical section that will automatically be locked while the host + is calling the processBlock() method. - /** Returns the range of characters that are selected. - If nothing is selected, this will return an empty range. - @see setHighlightedRegion + Use it from your UI or other threads to lock access to variables that are used + by the process callback, but obviously be careful not to keep it locked for + too long, because that could cause stuttering playback. If you need to do something + that'll take a long time and need the processing to stop while it happens, use the + suspendProcessing() method instead. + + @see suspendProcessing */ - const Range getHighlightedRegion() const { return selection; } + const CriticalSection& getCallbackLock() const noexcept { return callbackLock; } - /** Returns the section of text that is currently selected. */ - const String getHighlightedText() const; + /** Enables and disables the processing callback. - /** Finds the index of the character at a given position. + If you need to do something time-consuming on a thread and would like to make sure + the audio processing callback doesn't happen until you've finished, use this + to disable the callback and re-enable it again afterwards. - The co-ordinates are relative to the component's top-left. - */ - int getTextIndexAt (int x, int y); + E.g. + @code + void loadNewPatch() + { + suspendProcessing (true); - /** Counts the number of characters in the text. + ..do something that takes ages.. - This is quicker than getting the text as a string if you just need to know - the length. - */ - int getTotalNumChars() const; + suspendProcessing (false); + } + @endcode - /** Returns the total width of the text, as it is currently laid-out. + If the host tries to make an audio callback while processing is suspended, the + filter will return an empty buffer, but won't block the audio thread like it would + do if you use the getCallbackLock() critical section to synchronise access. - This may be larger than the size of the TextEditor, and can change when - the TextEditor is resized or the text changes. - */ - int getTextWidth() const; + If you're going to use this, your processBlock() method must call isSuspended() and + check whether it's suspended or not. If it is, then it should skip doing any real + processing, either emitting silence or passing the input through unchanged. - /** Returns the maximum height of the text, as it is currently laid-out. + @see getCallbackLock + */ + void suspendProcessing (bool shouldBeSuspended); - This may be larger than the size of the TextEditor, and can change when - the TextEditor is resized or the text changes. + /** Returns true if processing is currently suspended. + @see suspendProcessing */ - int getTextHeight() const; + bool isSuspended() const noexcept { return suspended; } - /** Changes the size of the gap at the top and left-edge of the editor. + /** A plugin can override this to be told when it should reset any playing voices. - By default there's a gap of 4 pixels. + The default implementation does nothing, but a host may call this to tell the + plugin that it should stop any tails or sounds that have been left running. */ - void setIndents (int newLeftIndent, int newTopIndent); + virtual void reset(); - /** Changes the size of border left around the edge of the component. + /** Returns true if the processor is being run in an offline mode for rendering. - @see getBorder - */ - void setBorder (const BorderSize& border); + If the processor is being run live on realtime signals, this returns false. + If the mode is unknown, this will assume it's realtime and return false. - /** Returns the size of border around the edge of the component. + This value may be unreliable until the prepareToPlay() method has been called, + and could change each time prepareToPlay() is called. - @see setBorder + @see setNonRealtime() */ - const BorderSize getBorder() const; + bool isNonRealtime() const noexcept { return nonRealtime; } - /** Used to disable the auto-scrolling which keeps the caret visible. + /** Called by the host to tell this processor whether it's being used in a non-realime + capacity for offline rendering or bouncing. - If true (the default), the editor will scroll when the caret moves offscreen. If - set to false, it won't. + Whatever value is passed-in will be */ - void setScrollToShowCursor (bool shouldScrollToShowCaret); + void setNonRealtime (bool isNonRealtime) noexcept; - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void paintOverChildren (Graphics& g); - /** @internal */ - void mouseDown (const MouseEvent& e); - /** @internal */ - void mouseUp (const MouseEvent& e); - /** @internal */ - void mouseDrag (const MouseEvent& e); - /** @internal */ - void mouseDoubleClick (const MouseEvent& e); - /** @internal */ - void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); - /** @internal */ - bool keyPressed (const KeyPress& key); - /** @internal */ - bool keyStateChanged (bool isKeyDown); - /** @internal */ - void focusGained (FocusChangeType cause); - /** @internal */ - void focusLost (FocusChangeType cause); - /** @internal */ - void resized(); - /** @internal */ - void enablementChanged(); - /** @internal */ - void colourChanged(); - /** @internal */ - void lookAndFeelChanged(); - /** @internal */ - bool isTextInputActive() const; - /** @internal */ - void setTemporaryUnderlining (const Array >&); + /** Creates the filter's UI. - bool moveCaretLeft (bool moveInWholeWordSteps, bool selecting); - bool moveCaretRight (bool moveInWholeWordSteps, bool selecting); - bool moveCaretUp (bool selecting); - bool moveCaretDown (bool selecting); - bool pageUp (bool selecting); - bool pageDown (bool selecting); - bool scrollDown(); - bool scrollUp(); - bool moveCaretToTop (bool selecting); - bool moveCaretToStartOfLine (bool selecting); - bool moveCaretToEnd (bool selecting); - bool moveCaretToEndOfLine (bool selecting); - bool deleteBackwards (bool moveInWholeWordSteps); - bool deleteForwards (bool moveInWholeWordSteps); - bool copyToClipboard(); - bool cutToClipboard(); - bool pasteFromClipboard(); - bool selectAll(); - bool undo(); - bool redo(); + This can return 0 if you want a UI-less filter, in which case the host may create + a generic UI that lets the user twiddle the parameters directly. - /** This adds the items to the popup menu. + If you do want to pass back a component, the component should be created and set to + the correct size before returning it. If you implement this method, you must + also implement the hasEditor() method and make it return true. - By default it adds the cut/copy/paste items, but you can override this if - you need to replace these with your own items. + Remember not to do anything silly like allowing your filter to keep a pointer to + the component that gets created - it could be deleted later without any warning, which + would make your pointer into a dangler. Use the getActiveEditor() method instead. - If you want to add your own items to the existing ones, you can override this, - call the base class's addPopupMenuItems() method, then append your own items. + The correct way to handle the connection between an editor component and its + filter is to use something like a ChangeBroadcaster so that the editor can + register itself as a listener, and be told when a change occurs. This lets them + safely unregister themselves when they are deleted. - When the menu has been shown, performPopupMenuAction() will be called to - perform the item that the user has chosen. + Here are a few things to bear in mind when writing an editor: - The default menu items will be added using item IDs in the range - 0x7fff0000 - 0x7fff1000, so you should avoid those values for your own - menu IDs. + - Initially there won't be an editor, until the user opens one, or they might + not open one at all. Your filter mustn't rely on it being there. + - An editor object may be deleted and a replacement one created again at any time. + - It's safe to assume that an editor will be deleted before its filter. - If this was triggered by a mouse-click, the mouseClickEvent parameter will be - a pointer to the info about it, or may be null if the menu is being triggered - by some other means. + @see hasEditor + */ + virtual AudioProcessorEditor* createEditor() = 0; - @see performPopupMenuAction, setPopupMenuEnabled, isPopupMenuEnabled + /** Your filter must override this and return true if it can create an editor component. + @see createEditor */ - virtual void addPopupMenuItems (PopupMenu& menuToAddTo, - const MouseEvent* mouseClickEvent); + virtual bool hasEditor() const = 0; - /** This is called to perform one of the items that was shown on the popup menu. + /** Returns the active editor, if there is one. - If you've overridden addPopupMenuItems(), you should also override this - to perform the actions that you've added. + Bear in mind this can return 0, even if an editor has previously been + opened. + */ + AudioProcessorEditor* getActiveEditor() const noexcept { return activeEditor; } - If you've overridden addPopupMenuItems() but have still left the default items - on the menu, remember to call the superclass's performPopupMenuAction() - so that it can perform the default actions if that's what the user clicked on. + /** Returns the active editor, or if there isn't one, it will create one. - @see addPopupMenuItems, setPopupMenuEnabled, isPopupMenuEnabled + This may call createEditor() internally to create the component. */ - virtual void performPopupMenuAction (int menuItemID); + AudioProcessorEditor* createEditorIfNeeded(); -protected: + /** This must return the correct value immediately after the object has been + created, and mustn't change the number of parameters later. + */ + virtual int getNumParameters() = 0; - /** Scrolls the minimum distance needed to get the caret into view. */ - void scrollToMakeSureCursorIsVisible(); + /** Returns the name of a particular parameter. */ + virtual const String getParameterName (int parameterIndex) = 0; - /** @internal */ - void moveCaret (int newCaretPos); + /** Called by the host to find out the value of one of the filter's parameters. - /** @internal */ - void moveCaretTo (int newPosition, bool isSelecting); + The host will expect the value returned to be between 0 and 1.0. - /** Used internally to dispatch a text-change message. */ - void textChanged(); + This could be called quite frequently, so try to make your code efficient. + It's also likely to be called by non-UI threads, so the code in here should + be thread-aware. + */ + virtual float getParameter (int parameterIndex) = 0; - /** Begins a new transaction in the UndoManager. */ - void newTransaction(); + /** Returns the value of a parameter as a text string. */ + virtual const String getParameterText (int parameterIndex) = 0; - /** Used internally to trigger an undo or redo. */ - void doUndoRedo (bool isRedo); + /** The host will call this method to change the value of one of the filter's parameters. - /** Can be overridden to intercept return key presses directly */ - virtual void returnPressed(); + The host may call this at any time, including during the audio processing + callback, so the filter has to process this very fast and avoid blocking. - /** Can be overridden to intercept escape key presses directly */ - virtual void escapePressed(); + If you want to set the value of a parameter internally, e.g. from your + editor component, then don't call this directly - instead, use the + setParameterNotifyingHost() method, which will also send a message to + the host telling it about the change. If the message isn't sent, the host + won't be able to automate your parameters properly. - /** @internal */ - void handleCommandMessage (int commandId); + The value passed will be between 0 and 1.0. + */ + virtual void setParameter (int parameterIndex, + float newValue) = 0; -private: + /** Your filter can call this when it needs to change one of its parameters. - class Iterator; - class UniformTextSection; - class TextHolderComponent; - class InsertAction; - class RemoveAction; - friend class InsertAction; - friend class RemoveAction; + This could happen when the editor or some other internal operation changes + a parameter. This method will call the setParameter() method to change the + value, and will then send a message to the host telling it about the change. - ScopedPointer viewport; - TextHolderComponent* textHolder; - BorderSize borderSize; + Note that to make sure the host correctly handles automation, you should call + the beginParameterChangeGesture() and endParameterChangeGesture() methods to + tell the host when the user has started and stopped changing the parameter. + */ + void setParameterNotifyingHost (int parameterIndex, + float newValue); - bool readOnly : 1; - bool multiline : 1; - bool wordWrap : 1; - bool returnKeyStartsNewLine : 1; - bool popupMenuEnabled : 1; - bool selectAllTextWhenFocused : 1; - bool scrollbarVisible : 1; - bool wasFocused : 1; - bool keepCaretOnScreen : 1; - bool tabKeyUsed : 1; - bool menuActive : 1; - bool valueTextNeedsUpdating : 1; + /** Returns true if the host can automate this parameter. - UndoManager undoManager; - ScopedPointer caret; - int maxTextLength; - Range selection; - int leftIndent, topIndent; - unsigned int lastTransactionTime; - Font currentFont; - mutable int totalNumChars; - int caretPosition; - Array sections; - String textToShowWhenEmpty; - Colour colourForTextWhenEmpty; - juce_wchar passwordCharacter; - Value textValue; + By default, this returns true for all parameters. + */ + virtual bool isParameterAutomatable (int parameterIndex) const; - enum - { - notDragging, - draggingSelectionStart, - draggingSelectionEnd - } dragType; + /** Should return true if this parameter is a "meta" parameter. - String allowedCharacters; - ListenerList listeners; - Array > underlinedSections; + A meta-parameter is a parameter that changes other params. It is used + by some hosts (e.g. AudioUnit hosts). - void coalesceSimilarSections(); - void splitSection (int sectionIndex, int charToSplitAt); - void clearInternal (UndoManager* um); - void insert (const String& text, int insertIndex, const Font& font, - const Colour& colour, UndoManager* um, int caretPositionToMoveTo); - void reinsert (int insertIndex, const Array & sections); - void remove (const Range& range, UndoManager* um, int caretPositionToMoveTo); - void getCharPosition (int index, float& x, float& y, float& lineHeight) const; - void updateCaretPosition(); - void textWasChangedByValue(); - int indexAtPosition (float x, float y); - int findWordBreakAfter (int position) const; - int findWordBreakBefore (int position) const; - bool moveCaretWithTransation (int newPos, bool selecting); - friend class TextHolderComponent; - friend class TextEditorViewport; - void drawContent (Graphics& g); - void updateTextHolderSize(); - float getWordWrapWidth() const; - void timerCallbackInt(); - void repaintText (const Range& range); - void scrollByLines (int deltaLines); - bool undoOrRedo (bool shouldUndo); - UndoManager* getUndoManager() noexcept; + By default this returns false. + */ + virtual bool isMetaParameter (int parameterIndex) const; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextEditor); -}; + /** Sends a signal to the host to tell it that the user is about to start changing this + parameter. -/** This typedef is just for compatibility with old code - newer code should use the TextEditor::Listener class directly. */ -typedef TextEditor::Listener TextEditorListener; + This allows the host to know when a parameter is actively being held by the user, and + it may use this information to help it record automation. -#endif // __JUCE_TEXTEDITOR_JUCEHEADER__ + If you call this, it must be matched by a later call to endParameterChangeGesture(). + */ + void beginParameterChangeGesture (int parameterIndex); -/*** End of inlined file: juce_TextEditor.h ***/ + /** Tells the host that the user has finished changing this parameter. -#if JUCE_VC6 - #define Listener ButtonListener -#endif + This allows the host to know when a parameter is actively being held by the user, and + it may use this information to help it record automation. -/** - A component that displays a text string, and can optionally become a text - editor when clicked. -*/ -class JUCE_API Label : public Component, - public SettableTooltipClient, - protected TextEditorListener, - private ComponentListener, - private ValueListener -{ -public: + A call to this method must follow a call to beginParameterChangeGesture(). + */ + void endParameterChangeGesture (int parameterIndex); - /** Creates a Label. + /** The filter can call this when something (apart from a parameter value) has changed. - @param componentName the name to give the component - @param labelText the text to show in the label + It sends a hint to the host that something like the program, number of parameters, + etc, has changed, and that it should update itself. */ - Label (const String& componentName = String::empty, - const String& labelText = String::empty); + void updateHostDisplay(); - /** Destructor. */ - ~Label(); + /** Returns the number of preset programs the filter supports. - /** Changes the label text. + The value returned must be valid as soon as this object is created, and + must not change over its lifetime. - If broadcastChangeMessage is true and the new text is different to the current - text, then the class will broadcast a change message to any Label::Listener objects - that are registered. + This value shouldn't be less than 1. */ - void setText (const String& newText, bool broadcastChangeMessage); - - /** Returns the label's current text. + virtual int getNumPrograms() = 0; - @param returnActiveEditorContents if this is true and the label is currently - being edited, then this method will return the - text as it's being shown in the editor. If false, - then the value returned here won't be updated until - the user has finished typing and pressed the return - key. + /** Returns the number of the currently active program. */ - const String getText (bool returnActiveEditorContents = false) const; + virtual int getCurrentProgram() = 0; - /** Returns the text content as a Value object. - You can call Value::referTo() on this object to make the label read and control - a Value object that you supply. + /** Called by the host to change the current program. */ - Value& getTextValue() { return textValue; } + virtual void setCurrentProgram (int index) = 0; - /** Changes the font to use to draw the text. + /** Must return the name of a given program. */ + virtual const String getProgramName (int index) = 0; - @see getFont + /** Called by the host to rename a program. */ - void setFont (const Font& newFont); + virtual void changeProgramName (int index, const String& newName) = 0; - /** Returns the font currently being used. + /** The host will call this method when it wants to save the filter's internal state. - @see setFont + This must copy any info about the filter's state into the block of memory provided, + so that the host can store this and later restore it using setStateInformation(). + + Note that there's also a getCurrentProgramStateInformation() method, which only + stores the current program, not the state of the entire filter. + + See also the helper function copyXmlToBinary() for storing settings as XML. + + @see getCurrentProgramStateInformation */ - const Font& getFont() const noexcept; + virtual void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData) = 0; - /** A set of colour IDs to use to change the colour of various aspects of the label. + /** The host will call this method if it wants to save the state of just the filter's + current program. - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. + Unlike getStateInformation, this should only return the current program's state. - Note that you can also use the constants from TextEditor::ColourIds to change the - colour of the text editor that is opened when a label is editable. + Not all hosts support this, and if you don't implement it, the base class + method just calls getStateInformation() instead. If you do implement it, be + sure to also implement getCurrentProgramStateInformation. - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + @see getStateInformation, setCurrentProgramStateInformation */ - enum ColourIds - { - backgroundColourId = 0x1000280, /**< The background colour to fill the label with. */ - textColourId = 0x1000281, /**< The colour for the text. */ - outlineColourId = 0x1000282 /**< An optional colour to use to draw a border around the label. - Leave this transparent to not have an outline. */ - }; + virtual void getCurrentProgramStateInformation (JUCE_NAMESPACE::MemoryBlock& destData); - /** Sets the style of justification to be used for positioning the text. + /** This must restore the filter's state from a block of data previously created + using getStateInformation(). - (The default is Justification::centredLeft) - */ - void setJustificationType (const Justification& justification); + Note that there's also a setCurrentProgramStateInformation() method, which tries + to restore just the current program, not the state of the entire filter. - /** Returns the type of justification, as set in setJustificationType(). */ - const Justification getJustificationType() const noexcept { return justification; } + See also the helper function getXmlFromBinary() for loading settings as XML. - /** Changes the gap that is left between the edge of the component and the text. - By default there's a small gap left at the sides of the component to allow for - the drawing of the border, but you can change this if necessary. + @see setCurrentProgramStateInformation */ - void setBorderSize (int horizontalBorder, int verticalBorder); + virtual void setStateInformation (const void* data, int sizeInBytes) = 0; - /** Returns the size of the horizontal gap being left around the text. - */ - int getHorizontalBorderSize() const noexcept { return horizontalBorderSize; } + /** The host will call this method if it wants to restore the state of just the filter's + current program. - /** Returns the size of the vertical gap being left around the text. + Not all hosts support this, and if you don't implement it, the base class + method just calls setStateInformation() instead. If you do implement it, be + sure to also implement getCurrentProgramStateInformation. + + @see setStateInformation, getCurrentProgramStateInformation */ - int getVerticalBorderSize() const noexcept { return verticalBorderSize; } + virtual void setCurrentProgramStateInformation (const void* data, int sizeInBytes); - /** Makes this label "stick to" another component. + /** Adds a listener that will be called when an aspect of this processor changes. */ + void addListener (AudioProcessorListener* newListener); - This will cause the label to follow another component around, staying - either to its left or above it. + /** Removes a previously added listener. */ + void removeListener (AudioProcessorListener* listenerToRemove); - @param owner the component to follow - @param onLeft if true, the label will stay on the left of its component; if - false, it will stay above it. + /** Tells the processor to use this playhead object. + The processor will not take ownership of the object, so the caller must delete it when + it is no longer being used. */ - void attachToComponent (Component* owner, bool onLeft); + void setPlayHead (AudioPlayHead* newPlayHead) noexcept; - /** If this label has been attached to another component using attachToComponent, this - returns the other component. + /** Not for public use - this is called before deleting an editor component. */ + void editorBeingDeleted (AudioProcessorEditor* editor) noexcept; - Returns 0 if the label is not attached. - */ - Component* getAttachedComponent() const; + /** Not for public use - this is called to initialise the processor before playing. */ + void setPlayConfigDetails (int numIns, int numOuts, + double sampleRate, + int blockSize) noexcept; - /** If the label is attached to the left of another component, this returns true. +protected: - Returns false if the label is above the other component. This is only relevent if - attachToComponent() has been called. + /** Helper function that just converts an xml element into a binary blob. + + Use this in your filter's getStateInformation() method if you want to + store its state as xml. + + Then use getXmlFromBinary() to reverse this operation and retrieve the XML + from a binary blob. */ - bool isAttachedOnLeft() const noexcept { return leftOfOwnerComp; } + static void copyXmlToBinary (const XmlElement& xml, + JUCE_NAMESPACE::MemoryBlock& destData); - /** Specifies the minimum amount that the font can be squashed horizantally before it starts - using ellipsis. + /** Retrieves an XML element that was stored as binary with the copyXmlToBinary() method. - @see Graphics::drawFittedText + This might return 0 if the data's unsuitable or corrupted. Otherwise it will return + an XmlElement object that the caller must delete when no longer needed. */ - void setMinimumHorizontalScale (float newScale); + static XmlElement* getXmlFromBinary (const void* data, int sizeInBytes); - float getMinimumHorizontalScale() const noexcept { return minimumHorizontalScale; } + /** @internal */ + AudioPlayHead* playHead; - /** - A class for receiving events from a Label. + /** @internal */ + void sendParamChangeMessageToListeners (int parameterIndex, float newValue); - You can register a Label::Listener with a Label using the Label::addListener() - method, and it will be called when the text of the label changes, either because - of a call to Label::setText() or by the user editing the text (if the label is - editable). +private: + Array listeners; + Component::SafePointer activeEditor; + double sampleRate; + int blockSize, numInputChannels, numOutputChannels, latencySamples; + bool suspended, nonRealtime; + CriticalSection callbackLock, listenerLock; - @see Label::addListener, Label::removeListener - */ - class JUCE_API Listener - { - public: - /** Destructor. */ - virtual ~Listener() {} + #if JUCE_DEBUG + BigInteger changingParams; + #endif - /** Called when a Label's text has changed. - */ - virtual void labelTextChanged (Label* labelThatHasChanged) = 0; - }; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessor); +}; - /** Registers a listener that will be called when the label's text changes. */ - void addListener (Listener* listener); +#endif // __JUCE_AUDIOPROCESSOR_JUCEHEADER__ - /** Deregisters a previously-registered listener. */ - void removeListener (Listener* listener); +/*** End of inlined file: juce_AudioProcessor.h ***/ - /** Makes the label turn into a TextEditor when clicked. - By default this is turned off. +/*** Start of inlined file: juce_PluginDescription.h ***/ +#ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ +#define __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ - If turned on, then single- or double-clicking will turn the label into - an editor. If the user then changes the text, then the ChangeBroadcaster - base class will be used to send change messages to any listeners that - have registered. +/** + A small class to represent some facts about a particular type of plugin. - If the user changes the text, the textWasEdited() method will be called - afterwards, and subclasses can override this if they need to do anything - special. + This class is for storing and managing the details about a plugin without + actually having to load an instance of it. - @param editOnSingleClick if true, just clicking once on the label will start editing the text - @param editOnDoubleClick if true, a double-click is needed to start editing - @param lossOfFocusDiscardsChanges if true, clicking somewhere else while the text is being - edited will discard any changes; if false, then this will - commit the changes. - @see showEditor, setEditorColours, TextEditor + A KnownPluginList contains a list of PluginDescription objects. + + @see KnownPluginList +*/ +class JUCE_API PluginDescription +{ +public: + + PluginDescription(); + PluginDescription (const PluginDescription& other); + PluginDescription& operator= (const PluginDescription& other); + ~PluginDescription(); + + /** The name of the plugin. */ + String name; + + /** A more descriptive name for the plugin. + This may be the same as the 'name' field, but some plugins may provide an + alternative name. */ - void setEditable (bool editOnSingleClick, - bool editOnDoubleClick = false, - bool lossOfFocusDiscardsChanges = false); + String descriptiveName; - /** Returns true if this option was set using setEditable(). */ - bool isEditableOnSingleClick() const noexcept { return editSingleClick; } + /** The plugin format, e.g. "VST", "AudioUnit", etc. + */ + String pluginFormatName; - /** Returns true if this option was set using setEditable(). */ - bool isEditableOnDoubleClick() const noexcept { return editDoubleClick; } + /** A category, such as "Dynamics", "Reverbs", etc. + */ + String category; - /** Returns true if this option has been set in a call to setEditable(). */ - bool doesLossOfFocusDiscardChanges() const noexcept { return lossOfFocusDiscardsChanges; } + /** The manufacturer. */ + String manufacturerName; - /** Returns true if the user can edit this label's text. */ - bool isEditable() const noexcept { return editSingleClick || editDoubleClick; } + /** The version. This string doesn't have any particular format. */ + String version; - /** Makes the editor appear as if the label had been clicked by the user. + /** Either the file containing the plugin module, or some other unique way + of identifying it. - @see textWasEdited, setEditable + E.g. for an AU, this would be an ID string that the component manager + could use to retrieve the plugin. For a VST, it's the file path. */ - void showEditor(); + String fileOrIdentifier; - /** Hides the editor if it was being shown. + /** The last time the plugin file was changed. + This is handy when scanning for new or changed plugins. + */ + Time lastFileModTime; - @param discardCurrentEditorContents if true, the label's text will be - reset to whatever it was before the editor - was shown; if false, the current contents of the - editor will be used to set the label's text - before it is hidden. + /** A unique ID for the plugin. + + Note that this might not be unique between formats, e.g. a VST and some + other format might actually have the same id. + + @see createIdentifierString */ - void hideEditor (bool discardCurrentEditorContents); + int uid; - /** Returns true if the editor is currently focused and active. */ - bool isBeingEdited() const noexcept; + /** True if the plugin identifies itself as a synthesiser. */ + bool isInstrument; -protected: + /** The number of inputs. */ + int numInputChannels; - /** Creates the TextEditor component that will be used when the user has clicked on the label. - Subclasses can override this if they need to customise this component in some way. + /** The number of outputs. */ + int numOutputChannels; + + /** Returns true if the two descriptions refer the the same plugin. + + This isn't quite as simple as them just having the same file (because of + shell plugins). */ - virtual TextEditor* createEditorComponent(); + bool isDuplicateOf (const PluginDescription& other) const; - /** Called after the user changes the text. */ - virtual void textWasEdited(); + /** Returns a string that can be saved and used to uniquely identify the + plugin again. - /** Called when the text has been altered. */ - virtual void textWasChanged(); + This contains less info than the XML encoding, and is independent of the + plugin's file location, so can be used to store a plugin ID for use + across different machines. + */ + const String createIdentifierString() const; - /** Called when the text editor has just appeared, due to a user click or other focus change. */ - virtual void editorShown (TextEditor* editorComponent); + /** Creates an XML object containing these details. - /** Called when the text editor is going to be deleted, after editing has finished. */ - virtual void editorAboutToBeHidden (TextEditor* editorComponent); + @see loadFromXml + */ + XmlElement* createXml() const; - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void resized(); - /** @internal */ - void mouseUp (const MouseEvent& e); - /** @internal */ - void mouseDoubleClick (const MouseEvent& e); - /** @internal */ - void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); - /** @internal */ - void componentParentHierarchyChanged (Component& component); - /** @internal */ - void componentVisibilityChanged (Component& component); - /** @internal */ - void inputAttemptWhenModal(); - /** @internal */ - void focusGained (FocusChangeType); - /** @internal */ - void enablementChanged(); - /** @internal */ - KeyboardFocusTraverser* createFocusTraverser(); - /** @internal */ - void textEditorTextChanged (TextEditor& editor); - /** @internal */ - void textEditorReturnKeyPressed (TextEditor& editor); - /** @internal */ - void textEditorEscapeKeyPressed (TextEditor& editor); - /** @internal */ - void textEditorFocusLost (TextEditor& editor); - /** @internal */ - void colourChanged(); - /** @internal */ - void valueChanged (Value&); + /** Reloads the info in this structure from an XML record that was previously + saved with createXML(). + + Returns true if the XML was a valid plugin description. + */ + bool loadFromXml (const XmlElement& xml); private: - Value textValue; - String lastTextValue; - Font font; - Justification justification; - ScopedPointer editor; - ListenerList listeners; - WeakReference ownerComponent; - int horizontalBorderSize, verticalBorderSize; - float minimumHorizontalScale; - bool editSingleClick : 1; - bool editDoubleClick : 1; - bool lossOfFocusDiscardsChanges : 1; - bool leftOfOwnerComp : 1; + JUCE_LEAK_DETECTOR (PluginDescription); +}; - bool updateFromTextEditorContents (TextEditor&); - void callChangeListeners(); +#endif // __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Label); -}; +/*** End of inlined file: juce_PluginDescription.h ***/ -/** This typedef is just for compatibility with old code - newer code should use the Label::Listener class directly. */ -typedef Label::Listener LabelListener; +/** + Base class for an active instance of a plugin. -#if JUCE_VC6 - #undef Listener -#endif + This derives from the AudioProcessor class, and adds some extra functionality + that helps when wrapping dynamically loaded plugins. -#endif // __JUCE_LABEL_JUCEHEADER__ + @see AudioProcessor, AudioPluginFormat +*/ +class JUCE_API AudioPluginInstance : public AudioProcessor +{ +public: -/*** End of inlined file: juce_Label.h ***/ + /** Destructor. -#if JUCE_VC6 - #define Listener SliderListener -#endif + Make sure that you delete any UI components that belong to this plugin before + deleting the plugin. + */ + virtual ~AudioPluginInstance(); -/** - A component that lets the user choose from a drop-down list of choices. + /** Fills-in the appropriate parts of this plugin description object. + */ + virtual void fillInPluginDescription (PluginDescription& description) const = 0; - The combo-box has a list of text strings, each with an associated id number, - that will be shown in the drop-down list when the user clicks on the component. + /** Returns a pointer to some kind of platform-specific data about the plugin. - The currently selected choice is displayed in the combo-box, and this can - either be read-only text, or editable. + E.g. For a VST, this value can be cast to an AEffect*. For an AudioUnit, it can be + cast to an AudioUnit handle. + */ + virtual void* getPlatformSpecificData(); - To find out when the user selects a different item or edits the text, you - can register a ComboBox::Listener to receive callbacks. +protected: - @see ComboBox::Listener + AudioPluginInstance(); + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginInstance); +}; + +#endif // __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ + +/*** End of inlined file: juce_AudioPluginInstance.h ***/ + +class PluginDescription; + +/** + The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc. + + Use the static getNumFormats() and getFormat() calls to find the types + of format that are available. */ -class JUCE_API ComboBox : public Component, - public SettableTooltipClient, - public LabelListener, // (can't use Label::Listener due to idiotic VC2005 bug) - public ValueListener, - private AsyncUpdater +class JUCE_API AudioPluginFormat { public: - /** Creates a combo-box. + /** Destructor. */ + virtual ~AudioPluginFormat(); - On construction, the text field will be empty, so you should call the - setSelectedId() or setText() method to choose the initial value before - displaying it. + /** Returns the format name. - @param componentName the name to set for the component (see Component::setName()) + E.g. "VST", "AudioUnit", etc. */ - explicit ComboBox (const String& componentName = String::empty); + virtual const String getName() const = 0; - /** Destructor. */ - ~ComboBox(); + /** This tries to create descriptions for all the plugin types available in + a binary module file. - /** Sets whether the test in the combo-box is editable. + The file will be some kind of DLL or bundle. - The default state for a new ComboBox is non-editable, and can only be changed - by choosing from the drop-down list. + Normally there will only be one type returned, but some plugins + (e.g. VST shells) can use a single DLL to create a set of different plugin + subtypes, so in that case, each subtype is returned as a separate object. */ - void setEditableText (bool isEditable); + virtual void findAllTypesForFile (OwnedArray & results, + const String& fileOrIdentifier) = 0; - /** Returns true if the text is directly editable. - @see setEditableText + /** Tries to recreate a type from a previously generated PluginDescription. + + @see PluginDescription::createInstance */ - bool isTextEditable() const noexcept; + virtual AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc) = 0; - /** Sets the style of justification to be used for positioning the text. + /** Should do a quick check to see if this file or directory might be a plugin of + this format. + + This is for searching for potential files, so it shouldn't actually try to + load the plugin or do anything time-consuming. + */ + virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0; - The default is Justification::centredLeft. The text is displayed using a - Label component inside the ComboBox. + /** Returns a readable version of the name of the plugin that this identifier refers to. */ - void setJustificationType (const Justification& justification); + virtual const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0; - /** Returns the current justification for the text box. - @see setJustificationType + /** Checks whether this plugin could possibly be loaded. + + It doesn't actually need to load it, just to check whether the file or component + still exists. */ - const Justification getJustificationType() const noexcept; + virtual bool doesPluginStillExist (const PluginDescription& desc) = 0; - /** Adds an item to be shown in the drop-down list. + /** Searches a suggested set of directories for any plugins in this format. - @param newItemText the text of the item to show in the list - @param newItemId an associated ID number that can be set or retrieved - see - getSelectedId() and setSelectedId(). Note that this value can not - be 0! - @see setItemEnabled, addSeparator, addSectionHeading, removeItem, getNumItems, getItemText, getItemId + The path might be ignored, e.g. by AUs, which are found by the OS rather + than manually. */ - void addItem (const String& newItemText, int newItemId); + virtual const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, + bool recursive) = 0; - /** Adds a separator line to the drop-down list. + /** Returns the typical places to look for this kind of plugin. - This is like adding a separator to a popup menu. See PopupMenu::addSeparator(). + Note that if this returns no paths, it means that the format can't be scanned-for + (i.e. it's an internal format that doesn't live in files) */ - void addSeparator(); + virtual const FileSearchPath getDefaultLocationsToSearch() = 0; - /** Adds a heading to the drop-down list, so that you can group the items into - different sections. +protected: - The headings are indented slightly differently to set them apart from the - items on the list, and obviously can't be selected. You might want to add - separators between your sections too. + AudioPluginFormat() noexcept; - @see addItem, addSeparator - */ - void addSectionHeading (const String& headingName); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormat); +}; - /** This allows items in the drop-down list to be selectively disabled. +#endif // __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__ - When you add an item, it's enabled by default, but you can call this - method to change its status. +/*** End of inlined file: juce_AudioPluginFormat.h ***/ - If you disable an item which is already selected, this won't change the - current selection - it just stops the user choosing that item from the list. - */ - void setItemEnabled (int itemId, bool shouldBeEnabled); +#if JUCE_PLUGINHOST_AU && JUCE_MAC - /** Returns true if the given item is enabled. */ - bool isItemEnabled (int itemId) const noexcept; +/** + Implements a plugin format manager for AudioUnits. +*/ +class JUCE_API AudioUnitPluginFormat : public AudioPluginFormat +{ +public: - /** Changes the text for an existing item. - */ - void changeItemText (int itemId, const String& newText); + AudioUnitPluginFormat(); + ~AudioUnitPluginFormat(); - /** Removes all the items from the drop-down list. + const String getName() const { return "AudioUnit"; } + void findAllTypesForFile (OwnedArray & results, const String& fileOrIdentifier); + AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); + bool fileMightContainThisPluginType (const String& fileOrIdentifier); + const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier); + const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, bool recursive); + bool doesPluginStillExist (const PluginDescription& desc); + const FileSearchPath getDefaultLocationsToSearch(); - If this call causes the content to be cleared, then a change-message - will be broadcast unless dontSendChangeMessage is true. +private: - @see addItem, removeItem, getNumItems - */ - void clear (bool dontSendChangeMessage = false); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioUnitPluginFormat); +}; - /** Returns the number of items that have been added to the list. +#endif - Note that this doesn't include headers or separators. - */ - int getNumItems() const noexcept; +#endif // __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__ - /** Returns the text for one of the items in the list. +/*** End of inlined file: juce_AudioUnitPluginFormat.h ***/ - Note that this doesn't include headers or separators. - @param index the item's index from 0 to (getNumItems() - 1) - */ - const String getItemText (int index) const; +#endif +#ifndef __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__ - /** Returns the ID for one of the items in the list. +/*** Start of inlined file: juce_DirectXPluginFormat.h ***/ +#ifndef __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__ +#define __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__ - Note that this doesn't include headers or separators. +#if JUCE_PLUGINHOST_DX && JUCE_WINDOWS - @param index the item's index from 0 to (getNumItems() - 1) - */ - int getItemId (int index) const noexcept; +// Sorry, this file is just a placeholder at the moment!... - /** Returns the index in the list of a particular item ID. - If no such ID is found, this will return -1. - */ - int indexOfItemId (int itemId) const noexcept; +/** + Implements a plugin format manager for DirectX plugins. +*/ +class JUCE_API DirectXPluginFormat : public AudioPluginFormat +{ +public: - /** Returns the ID of the item that's currently shown in the box. + DirectXPluginFormat(); + ~DirectXPluginFormat(); - If no item is selected, or if the text is editable and the user - has entered something which isn't one of the items in the list, then - this will return 0. + const String getName() const { return "DirectX"; } + void findAllTypesForFile (OwnedArray & results, const String& fileOrIdentifier); + AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); + bool fileMightContainThisPluginType (const String& fileOrIdentifier); + const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) { return fileOrIdentifier; } + const FileSearchPath getDefaultLocationsToSearch(); - @see setSelectedId, getSelectedItemIndex, getText - */ - int getSelectedId() const noexcept; +private: + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectXPluginFormat); +}; - /** Returns a Value object that can be used to get or set the selected item's ID. +#endif - You can call Value::referTo() on this object to make the combo box control - another Value object. - */ - Value& getSelectedIdAsValue() { return currentId; } +#endif // __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__ - /** Sets one of the items to be the current selection. +/*** End of inlined file: juce_DirectXPluginFormat.h ***/ - This will set the ComboBox's text to that of the item that matches - this ID. - @param newItemId the new item to select - @param dontSendChangeMessage if set to true, this method won't trigger a - change notification - @see getSelectedId, setSelectedItemIndex, setText - */ - void setSelectedId (int newItemId, bool dontSendChangeMessage = false); +#endif +#ifndef __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__ - /** Returns the index of the item that's currently shown in the box. +/*** Start of inlined file: juce_LADSPAPluginFormat.h ***/ +#ifndef __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__ +#define __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__ - If no item is selected, or if the text is editable and the user - has entered something which isn't one of the items in the list, then - this will return -1. +#if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX - @see setSelectedItemIndex, getSelectedId, getText - */ - int getSelectedItemIndex() const; +// Sorry, this file is just a placeholder at the moment!... - /** Sets one of the items to be the current selection. +/** + Implements a plugin format manager for DirectX plugins. +*/ +class JUCE_API LADSPAPluginFormat : public AudioPluginFormat +{ +public: - This will set the ComboBox's text to that of the item at the given - index in the list. + LADSPAPluginFormat(); + ~LADSPAPluginFormat(); - @param newItemIndex the new item to select - @param dontSendChangeMessage if set to true, this method won't trigger a - change notification - @see getSelectedItemIndex, setSelectedId, setText - */ - void setSelectedItemIndex (int newItemIndex, bool dontSendChangeMessage = false); + const String getName() const { return "LADSPA"; } + void findAllTypesForFile (OwnedArray & results, const String& fileOrIdentifier); + AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); + bool fileMightContainThisPluginType (const String& fileOrIdentifier); + const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) { return fileOrIdentifier; } + const FileSearchPath getDefaultLocationsToSearch(); - /** Returns the text that is currently shown in the combo-box's text field. +private: + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LADSPAPluginFormat); +}; - If the ComboBox has editable text, then this text may have been edited - by the user; otherwise it will be one of the items from the list, or - possibly an empty string if nothing was selected. +#endif - @see setText, getSelectedId, getSelectedItemIndex - */ - const String getText() const; +#endif // __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__ - /** Sets the contents of the combo-box's text field. +/*** End of inlined file: juce_LADSPAPluginFormat.h ***/ - The text passed-in will be set as the current text regardless of whether - it is one of the items in the list. If the current text isn't one of the - items, then getSelectedId() will return -1, otherwise it wil return - the approriate ID. - @param newText the text to select - @param dontSendChangeMessage if set to true, this method won't trigger a - change notification - @see getText - */ - void setText (const String& newText, bool dontSendChangeMessage = false); +#endif +#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__ - /** Programmatically opens the text editor to allow the user to edit the current item. +/*** Start of inlined file: juce_VSTMidiEventList.h ***/ +#ifdef __aeffect__ - This is the same effect as when the box is clicked-on. - @see Label::showEditor(); - */ - void showEditor(); +#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__ +#define __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__ - /** Pops up the combo box's list. */ - void showPopup(); +/** Holds a set of VSTMidiEvent objects and makes it easy to add + events to the list. - /** - A class for receiving events from a ComboBox. + This is used by both the VST hosting code and the plugin wrapper. +*/ +class VSTMidiEventList +{ +public: - You can register a ComboBox::Listener with a ComboBox using the ComboBox::addListener() - method, and it will be called when the selected item in the box changes. + VSTMidiEventList() + : numEventsUsed (0), numEventsAllocated (0) + { + } - @see ComboBox::addListener, ComboBox::removeListener - */ - class JUCE_API Listener + ~VSTMidiEventList() { - public: - /** Destructor. */ - virtual ~Listener() {} + freeEvents(); + } - /** Called when a ComboBox has its selected item changed. */ - virtual void comboBoxChanged (ComboBox* comboBoxThatHasChanged) = 0; - }; + void clear() + { + numEventsUsed = 0; - /** Registers a listener that will be called when the box's content changes. */ - void addListener (Listener* listener); + if (events != nullptr) + events->numEvents = 0; + } - /** Deregisters a previously-registered listener. */ - void removeListener (Listener* listener); + void addEvent (const void* const midiData, const int numBytes, const int frameOffset) + { + ensureSize (numEventsUsed + 1); - /** Sets a message to display when there is no item currently selected. + VstMidiEvent* const e = (VstMidiEvent*) (events->events [numEventsUsed]); + events->numEvents = ++numEventsUsed; - @see getTextWhenNothingSelected - */ - void setTextWhenNothingSelected (const String& newMessage); + if (numBytes <= 4) + { + if (e->type == kVstSysExType) + { + delete[] (((VstMidiSysexEvent*) e)->sysexDump); + e->type = kVstMidiType; + e->byteSize = sizeof (VstMidiEvent); + e->noteLength = 0; + e->noteOffset = 0; + e->detune = 0; + e->noteOffVelocity = 0; + } - /** Returns the text that is shown when no item is selected. + e->deltaFrames = frameOffset; + memcpy (e->midiData, midiData, numBytes); + } + else + { + VstMidiSysexEvent* const se = (VstMidiSysexEvent*) e; - @see setTextWhenNothingSelected - */ - const String getTextWhenNothingSelected() const; + if (se->type == kVstSysExType) + delete[] se->sysexDump; - /** Sets the message to show when there are no items in the list, and the user clicks - on the drop-down box. + se->sysexDump = new char [numBytes]; + memcpy (se->sysexDump, midiData, numBytes); - By default it just says "no choices", but this lets you change it to something more - meaningful. - */ - void setTextWhenNoChoicesAvailable (const String& newMessage); + se->type = kVstSysExType; + se->byteSize = sizeof (VstMidiSysexEvent); + se->deltaFrames = frameOffset; + se->flags = 0; + se->dumpBytes = numBytes; + se->resvd1 = 0; + se->resvd2 = 0; + } + } - /** Returns the text shown when no items have been added to the list. - @see setTextWhenNoChoicesAvailable - */ - const String getTextWhenNoChoicesAvailable() const; + // Handy method to pull the events out of an event buffer supplied by the host + // or plugin. + static void addEventsToMidiBuffer (const VstEvents* events, MidiBuffer& dest) + { + for (int i = 0; i < events->numEvents; ++i) + { + const VstEvent* const e = events->events[i]; - /** Gives the ComboBox a tooltip. */ - void setTooltip (const String& newTooltip); + if (e != nullptr) + { + if (e->type == kVstMidiType) + { + dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiEvent*) e)->midiData, + 4, e->deltaFrames); + } + else if (e->type == kVstSysExType) + { + dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiSysexEvent*) e)->sysexDump, + (int) ((const VstMidiSysexEvent*) e)->dumpBytes, + e->deltaFrames); + } + } + } + } - /** A set of colour IDs to use to change the colour of various aspects of the combo box. + void ensureSize (int numEventsNeeded) + { + if (numEventsNeeded > numEventsAllocated) + { + numEventsNeeded = (numEventsNeeded + 32) & ~31; - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. + const int size = 20 + sizeof (VstEvent*) * numEventsNeeded; - To change the colours of the menu that pops up + if (events == nullptr) + events.calloc (size, 1); + else + events.realloc (size, 1); - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds + for (int i = numEventsAllocated; i < numEventsNeeded; ++i) + events->events[i] = allocateVSTEvent(); + + numEventsAllocated = numEventsNeeded; + } + } + + void freeEvents() { - backgroundColourId = 0x1000b00, /**< The background colour to fill the box with. */ - textColourId = 0x1000a00, /**< The colour for the text in the box. */ - outlineColourId = 0x1000c00, /**< The colour for an outline around the box. */ - buttonColourId = 0x1000d00, /**< The base colour for the button (a LookAndFeel class will probably use variations on this). */ - arrowColourId = 0x1000e00, /**< The colour for the arrow shape that pops up the menu */ - }; + if (events != nullptr) + { + for (int i = numEventsAllocated; --i >= 0;) + freeVSTEvent (events->events[i]); - /** @internal */ - void labelTextChanged (Label*); - /** @internal */ - void enablementChanged(); - /** @internal */ - void colourChanged(); - /** @internal */ - void focusGained (Component::FocusChangeType cause); - /** @internal */ - void focusLost (Component::FocusChangeType cause); - /** @internal */ - void handleAsyncUpdate(); - /** @internal */ - const String getTooltip() { return label->getTooltip(); } - /** @internal */ - void mouseDown (const MouseEvent&); - /** @internal */ - void mouseDrag (const MouseEvent&); - /** @internal */ - void mouseUp (const MouseEvent&); - /** @internal */ - void lookAndFeelChanged(); - /** @internal */ - void paint (Graphics&); - /** @internal */ - void resized(); - /** @internal */ - bool keyStateChanged (bool isKeyDown); - /** @internal */ - bool keyPressed (const KeyPress&); - /** @internal */ - void valueChanged (Value&); + events.free(); + numEventsUsed = 0; + numEventsAllocated = 0; + } + } + + HeapBlock events; private: + int numEventsUsed, numEventsAllocated; - struct ItemInfo + static VstEvent* allocateVSTEvent() { - ItemInfo (const String& name, int itemId, bool isEnabled, bool isHeading); - bool isSeparator() const noexcept; - bool isRealItem() const noexcept; + VstEvent* const e = (VstEvent*) ::calloc (1, sizeof (VstMidiEvent) > sizeof (VstMidiSysexEvent) ? sizeof (VstMidiEvent) + : sizeof (VstMidiSysexEvent)); + e->type = kVstMidiType; + e->byteSize = sizeof (VstMidiEvent); + return e; + } - String name; - int itemId; - bool isEnabled : 1, isHeading : 1; - }; + static void freeVSTEvent (VstEvent* e) + { + if (e->type == kVstSysExType) + delete[] (((VstMidiSysexEvent*) e)->sysexDump); - OwnedArray items; - Value currentId; - int lastCurrentId; - bool isButtonDown, separatorPending, menuActive, textIsCustom; - ListenerList listeners; - ScopedPointer