| @@ -397,11 +397,9 @@ public: | |||||
| if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &isAlive)) && isAlive == 0) | if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &isAlive)) && isAlive == 0) | ||||
| return; | return; | ||||
| Float64 sr; | |||||
| size = sizeof (sr); | |||||
| pa.mSelector = kAudioDevicePropertyNominalSampleRate; | |||||
| if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &sr))) | |||||
| sampleRate = sr; | |||||
| const double currentRate = getNominalSampleRate(); | |||||
| if (currentRate > 0) | |||||
| sampleRate = currentRate; | |||||
| UInt32 framesPerBuf = (UInt32) bufferSize; | UInt32 framesPerBuf = (UInt32) bufferSize; | ||||
| size = sizeof (framesPerBuf); | size = sizeof (framesPerBuf); | ||||
| @@ -525,6 +523,30 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| double getNominalSampleRate() const | |||||
| { | |||||
| AudioObjectPropertyAddress pa; | |||||
| pa.mSelector = kAudioDevicePropertyNominalSampleRate; | |||||
| pa.mScope = kAudioObjectPropertyScopeGlobal; | |||||
| pa.mElement = kAudioObjectPropertyElementMaster; | |||||
| Float64 sr = 0; | |||||
| UInt32 size = (UInt32) sizeof (sr); | |||||
| return OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, &sr)) ? (double) sr : 0.0; | |||||
| } | |||||
| bool setNominalSampleRate (double newSampleRate) const | |||||
| { | |||||
| if (std::abs (getNominalSampleRate() - newSampleRate) < 1.0) | |||||
| return true; | |||||
| AudioObjectPropertyAddress pa; | |||||
| pa.mSelector = kAudioDevicePropertyNominalSampleRate; | |||||
| pa.mScope = kAudioObjectPropertyScopeGlobal; | |||||
| pa.mElement = kAudioObjectPropertyElementMaster; | |||||
| Float64 sr = newSampleRate; | |||||
| return OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (sr), &sr)); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| String reopen (const BigInteger& inputChannels, | String reopen (const BigInteger& inputChannels, | ||||
| const BigInteger& outputChannels, | const BigInteger& outputChannels, | ||||
| @@ -549,25 +571,23 @@ public: | |||||
| numInputChans = activeInputChans.countNumberOfSetBits(); | numInputChans = activeInputChans.countNumberOfSetBits(); | ||||
| numOutputChans = activeOutputChans.countNumberOfSetBits(); | numOutputChans = activeOutputChans.countNumberOfSetBits(); | ||||
| // set sample rate | |||||
| AudioObjectPropertyAddress pa; | |||||
| pa.mSelector = kAudioDevicePropertyNominalSampleRate; | |||||
| pa.mScope = kAudioObjectPropertyScopeGlobal; | |||||
| pa.mElement = kAudioObjectPropertyElementMaster; | |||||
| Float64 sr = newSampleRate; | |||||
| if (! OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (sr), &sr))) | |||||
| if (! setNominalSampleRate (newSampleRate)) | |||||
| { | { | ||||
| updateDetailsFromDevice(); | |||||
| error = "Couldn't change sample rate"; | error = "Couldn't change sample rate"; | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // change buffer size | // change buffer size | ||||
| UInt32 framesPerBuf = (UInt32) bufferSizeSamples; | |||||
| AudioObjectPropertyAddress pa; | |||||
| pa.mSelector = kAudioDevicePropertyBufferFrameSize; | pa.mSelector = kAudioDevicePropertyBufferFrameSize; | ||||
| pa.mScope = kAudioObjectPropertyScopeGlobal; | |||||
| pa.mElement = kAudioObjectPropertyElementMaster; | |||||
| UInt32 framesPerBuf = (UInt32) bufferSizeSamples; | |||||
| if (! OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (framesPerBuf), &framesPerBuf))) | if (! OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (framesPerBuf), &framesPerBuf))) | ||||
| { | { | ||||
| updateDetailsFromDevice(); | |||||
| error = "Couldn't change buffer size"; | error = "Couldn't change buffer size"; | ||||
| } | } | ||||
| else | else | ||||
| @@ -643,7 +643,7 @@ public: | |||||
| if (metadataValues.size() > 0) | if (metadataValues.size() > 0) | ||||
| { | { | ||||
| // The meta data should have been santised for the AIFF format. | |||||
| // The meta data should have been sanitised for the AIFF format. | |||||
| // If it was originally sourced from a WAV file the MetaDataSource | // If it was originally sourced from a WAV file the MetaDataSource | ||||
| // key should be removed (or set to "AIFF") once this has been done | // key should be removed (or set to "AIFF") once this has been done | ||||
| jassert (metadataValues.getValue ("MetaDataSource", "None") != "WAV"); | jassert (metadataValues.getValue ("MetaDataSource", "None") != "WAV"); | ||||
| @@ -1024,7 +1024,7 @@ public: | |||||
| if (metadataValues.size() > 0) | if (metadataValues.size() > 0) | ||||
| { | { | ||||
| // The meta data should have been santised for the WAV format. | |||||
| // The meta data should have been sanitised for the WAV format. | |||||
| // If it was originally sourced from an AIFF file the MetaDataSource | // If it was originally sourced from an AIFF file the MetaDataSource | ||||
| // key should be removed (or set to "WAV") once this has been done | // key should be removed (or set to "WAV") once this has been done | ||||
| jassert (metadataValues.getValue ("MetaDataSource", "None") != "AIFF"); | jassert (metadataValues.getValue ("MetaDataSource", "None") != "AIFF"); | ||||
| @@ -42,7 +42,7 @@ public: | |||||
| bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; | bool fileMightContainThisPluginType (const String& fileOrIdentifier) override; | ||||
| String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; | String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override; | ||||
| bool pluginNeedsRescanning (const PluginDescription&) override; | bool pluginNeedsRescanning (const PluginDescription&) override; | ||||
| StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive); | |||||
| StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive) override; | |||||
| bool doesPluginStillExist (const PluginDescription&) override; | bool doesPluginStillExist (const PluginDescription&) override; | ||||
| FileSearchPath getDefaultLocationsToSearch() override; | FileSearchPath getDefaultLocationsToSearch() override; | ||||
| bool canScanForPlugins() const override { return true; } | bool canScanForPlugins() const override { return true; } | ||||
| @@ -840,9 +840,9 @@ public: | |||||
| if (audioUnit != nullptr) | if (audioUnit != nullptr) | ||||
| { | { | ||||
| UInt32 paramListSize = 0; | |||||
| UInt32 dummy = 0, paramListSize = 0; | |||||
| AudioUnitGetProperty (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, | AudioUnitGetProperty (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, | ||||
| 0, 0, ¶mListSize); | |||||
| 0, &dummy, ¶mListSize); | |||||
| if (paramListSize > 0) | if (paramListSize > 0) | ||||
| { | { | ||||
| @@ -1145,7 +1145,7 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| int getNumParameters() { return effect != nullptr ? effect->numParams : 0; } | |||||
| int getNumParameters() override { return effect != nullptr ? effect->numParams : 0; } | |||||
| float getParameter (int index) override | float getParameter (int index) override | ||||
| { | { | ||||
| @@ -49,7 +49,7 @@ public: | |||||
| virtual int toInt (const ValueUnion&) const noexcept { return 0; } | virtual int toInt (const ValueUnion&) const noexcept { return 0; } | ||||
| virtual int64 toInt64 (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 double toDouble (const ValueUnion&) const noexcept { return 0; } | ||||
| virtual String toString (const ValueUnion&) const { return String::empty; } | |||||
| virtual String toString (const ValueUnion&) const { return String(); } | |||||
| virtual bool toBool (const ValueUnion&) const noexcept { return false; } | virtual bool toBool (const ValueUnion&) const noexcept { return false; } | ||||
| virtual ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; } | virtual ReferenceCountedObject* toObject (const ValueUnion&) const noexcept { return nullptr; } | ||||
| virtual Array<var>* toArray (const ValueUnion&) const noexcept { return nullptr; } | virtual Array<var>* toArray (const ValueUnion&) const noexcept { return nullptr; } | ||||
| @@ -274,7 +274,7 @@ public: | |||||
| } | } | ||||
| String toString (const ValueUnion& data) const override { return "Object 0x" + String::toHexString ((int) (pointer_sized_int) data.objectValue); } | String toString (const ValueUnion& data) const override { return "Object 0x" + String::toHexString ((int) (pointer_sized_int) data.objectValue); } | ||||
| bool toBool (const ValueUnion& data) const noexcept override { return data.objectValue != 0; } | |||||
| bool toBool (const ValueUnion& data) const noexcept override { return data.objectValue != nullptr; } | |||||
| ReferenceCountedObject* toObject (const ValueUnion& data) const noexcept override { return data.objectValue; } | ReferenceCountedObject* toObject (const ValueUnion& data) const noexcept override { return data.objectValue; } | ||||
| bool isObject() const noexcept override { return true; } | bool isObject() const noexcept override { return true; } | ||||
| @@ -992,7 +992,8 @@ double Expression::evaluate() const | |||||
| double Expression::evaluate (const Expression::Scope& scope) const | double Expression::evaluate (const Expression::Scope& scope) const | ||||
| { | { | ||||
| return term->resolve (scope, 0)->toDouble(); | |||||
| String err; | |||||
| return evaluate (scope, err); | |||||
| } | } | ||||
| double Expression::evaluate (const Scope& scope, String& evaluationError) const | double Expression::evaluate (const Scope& scope, String& evaluationError) const | ||||
| @@ -1038,20 +1039,16 @@ Expression Expression::adjustedToGiveNewResult (const double targetValue, const | |||||
| jassert (termToAdjust != nullptr); | jassert (termToAdjust != nullptr); | ||||
| const Term* const parent = Helpers::findDestinationFor (newTerm, termToAdjust); | |||||
| if (parent == nullptr) | |||||
| if (const Term* parent = Helpers::findDestinationFor (newTerm, termToAdjust)) | |||||
| { | { | ||||
| termToAdjust->value = targetValue; | |||||
| if (const Helpers::TermPtr reverseTerm = parent->createTermToEvaluateInput (scope, termToAdjust, targetValue, newTerm)) | |||||
| termToAdjust->value = Expression (reverseTerm).evaluate (scope); | |||||
| else | |||||
| return Expression (targetValue); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const Helpers::TermPtr reverseTerm (parent->createTermToEvaluateInput (scope, termToAdjust, targetValue, newTerm)); | |||||
| if (reverseTerm == nullptr) | |||||
| return Expression (targetValue); | |||||
| termToAdjust->value = reverseTerm->resolve (scope, 0)->toDouble(); | |||||
| termToAdjust->value = targetValue; | |||||
| } | } | ||||
| return Expression (newTerm.release()); | return Expression (newTerm.release()); | ||||
| @@ -429,7 +429,7 @@ String SystemStats::getFullUserName() | |||||
| String SystemStats::getComputerName() | String SystemStats::getComputerName() | ||||
| { | { | ||||
| TCHAR text [MAX_COMPUTERNAME_LENGTH + 1] = { 0 }; | |||||
| TCHAR text[128] = { 0 }; | |||||
| DWORD len = (DWORD) numElementsInArray (text) - 1; | DWORD len = (DWORD) numElementsInArray (text) - 1; | ||||
| GetComputerName (text, &len); | GetComputerName (text, &len); | ||||
| return String (text, len); | return String (text, len); | ||||
| @@ -26,28 +26,44 @@ | |||||
| ============================================================================== | ============================================================================== | ||||
| */ | */ | ||||
| MACAddress::MACAddress() | |||||
| MACAddress::MACAddress() noexcept | |||||
| { | { | ||||
| zeromem (address, sizeof (address)); | zeromem (address, sizeof (address)); | ||||
| } | } | ||||
| MACAddress::MACAddress (const MACAddress& other) | |||||
| MACAddress::MACAddress (const MACAddress& other) noexcept | |||||
| { | { | ||||
| memcpy (address, other.address, sizeof (address)); | memcpy (address, other.address, sizeof (address)); | ||||
| } | } | ||||
| MACAddress& MACAddress::operator= (const MACAddress& other) | |||||
| MACAddress& MACAddress::operator= (const MACAddress& other) noexcept | |||||
| { | { | ||||
| memcpy (address, other.address, sizeof (address)); | memcpy (address, other.address, sizeof (address)); | ||||
| return *this; | return *this; | ||||
| } | } | ||||
| MACAddress::MACAddress (const uint8 bytes[6]) | |||||
| MACAddress::MACAddress (const uint8 bytes[6]) noexcept | |||||
| { | { | ||||
| memcpy (address, bytes, sizeof (address)); | memcpy (address, bytes, sizeof (address)); | ||||
| } | } | ||||
| MACAddress::MACAddress (StringRef addressString) | |||||
| { | |||||
| MemoryBlock hex; | |||||
| hex.loadFromHexString (addressString); | |||||
| if (hex.getSize() == sizeof (address)) | |||||
| memcpy (address, hex.getData(), sizeof (address)); | |||||
| else | |||||
| zeromem (address, sizeof (address)); | |||||
| } | |||||
| String MACAddress::toString() const | String MACAddress::toString() const | ||||
| { | |||||
| return toString ("-"); | |||||
| } | |||||
| String MACAddress::toString (StringRef separator) const | |||||
| { | { | ||||
| String s; | String s; | ||||
| @@ -56,7 +72,7 @@ String MACAddress::toString() const | |||||
| s << String::toHexString ((int) address[i]).paddedLeft ('0', 2); | s << String::toHexString ((int) address[i]).paddedLeft ('0', 2); | ||||
| if (i < sizeof (address) - 1) | if (i < sizeof (address) - 1) | ||||
| s << '-'; | |||||
| s << separator; | |||||
| } | } | ||||
| return s; | return s; | ||||
| @@ -43,16 +43,22 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates a null address (00-00-00-00-00-00). */ | /** Creates a null address (00-00-00-00-00-00). */ | ||||
| MACAddress(); | |||||
| MACAddress() noexcept; | |||||
| /** Creates a copy of another address. */ | /** Creates a copy of another address. */ | ||||
| MACAddress (const MACAddress&); | |||||
| MACAddress (const MACAddress&) noexcept; | |||||
| /** Creates a copy of another address. */ | /** Creates a copy of another address. */ | ||||
| MACAddress& operator= (const MACAddress&); | |||||
| MACAddress& operator= (const MACAddress&) noexcept; | |||||
| /** Creates an address from 6 bytes. */ | /** Creates an address from 6 bytes. */ | ||||
| explicit MACAddress (const uint8 bytes[6]); | |||||
| explicit MACAddress (const uint8 bytes[6]) noexcept; | |||||
| /** Creates an address from a hex string. | |||||
| If the string isn't a 6-byte hex value, this will just default-initialise | |||||
| the object. | |||||
| */ | |||||
| explicit MACAddress (StringRef address); | |||||
| /** Returns a pointer to the 6 bytes that make up this address. */ | /** Returns a pointer to the 6 bytes that make up this address. */ | ||||
| const uint8* getBytes() const noexcept { return address; } | const uint8* getBytes() const noexcept { return address; } | ||||
| @@ -60,6 +66,9 @@ public: | |||||
| /** Returns a dash-separated string in the form "11-22-33-44-55-66" */ | /** Returns a dash-separated string in the form "11-22-33-44-55-66" */ | ||||
| String toString() const; | String toString() const; | ||||
| /** Returns a hex string of this address, using a custom separator between each byte. */ | |||||
| String toString (StringRef separator) const; | |||||
| /** Returns the address in the lower 6 bytes of an int64. | /** Returns the address in the lower 6 bytes of an int64. | ||||
| This uses a little-endian arrangement, with the first byte of the address being | This uses a little-endian arrangement, with the first byte of the address being | ||||
| @@ -67,13 +67,18 @@ int MemoryInputStream::read (void* const buffer, const int howMany) | |||||
| { | { | ||||
| jassert (buffer != nullptr && howMany >= 0); | jassert (buffer != nullptr && howMany >= 0); | ||||
| const int num = jmin (howMany, (int) (dataSize - position)); | |||||
| if (num <= 0) | |||||
| if (howMany <= 0 || position >= dataSize) | |||||
| return 0; | return 0; | ||||
| memcpy (buffer, addBytesToPointer (data, position), (size_t) num); | |||||
| position += (unsigned int) num; | |||||
| return num; | |||||
| const size_t num = jmin ((size_t) howMany, dataSize - position); | |||||
| if (num > 0) | |||||
| { | |||||
| memcpy (buffer, addBytesToPointer (data, position), num); | |||||
| position += num; | |||||
| } | |||||
| return (int) num; | |||||
| } | } | ||||
| bool MemoryInputStream::isExhausted() | bool MemoryInputStream::isExhausted() | ||||
| @@ -40,6 +40,10 @@ | |||||
| When you create a Value with its default constructor, it acts as a wrapper around a | When you create a Value with its default constructor, it acts as a wrapper around a | ||||
| simple var object, but by creating a Value that refers to a custom subclass of ValueSource, | simple var object, but by creating a Value that refers to a custom subclass of ValueSource, | ||||
| you can map the Value onto any kind of underlying data. | you can map the Value onto any kind of underlying data. | ||||
| Important note! The Value class is not thread-safe! If you're accessing one from | |||||
| multiple threads, then you'll need to use your own synchronisation around any code | |||||
| that accesses it. | |||||
| */ | */ | ||||
| class JUCE_API Value | class JUCE_API Value | ||||
| { | { | ||||
| @@ -222,20 +222,21 @@ namespace CoreTextTypeLayout | |||||
| CFStringRef cfText = text.getText().toCFString(); | CFStringRef cfText = text.getText().toCFString(); | ||||
| CFMutableAttributedStringRef attribString = CFAttributedStringCreateMutable (kCFAllocatorDefault, 0); | CFMutableAttributedStringRef attribString = CFAttributedStringCreateMutable (kCFAllocatorDefault, 0); | ||||
| CFAttributedStringReplaceString (attribString, CFRangeMake(0, 0), cfText); | |||||
| CFAttributedStringReplaceString (attribString, CFRangeMake (0, 0), cfText); | |||||
| CFRelease (cfText); | CFRelease (cfText); | ||||
| const int numCharacterAttributes = text.getNumAttributes(); | const int numCharacterAttributes = text.getNumAttributes(); | ||||
| const CFIndex attribStringLen = CFAttributedStringGetLength (attribString); | |||||
| for (int i = 0; i < numCharacterAttributes; ++i) | for (int i = 0; i < numCharacterAttributes; ++i) | ||||
| { | { | ||||
| const AttributedString::Attribute& attr = *text.getAttribute (i); | const AttributedString::Attribute& attr = *text.getAttribute (i); | ||||
| const int rangeStart = attr.range.getStart(); | |||||
| if (attr.range.getStart() > CFAttributedStringGetLength (attribString)) | |||||
| if (rangeStart >= attribStringLen) | |||||
| continue; | continue; | ||||
| Range<int> range (attr.range); | |||||
| range.setEnd (jmin (range.getEnd(), (int) CFAttributedStringGetLength (attribString))); | |||||
| CFRange range = CFRangeMake (rangeStart, jmin (attr.range.getEnd(), (int) attribStringLen) - rangeStart); | |||||
| if (const Font* const f = attr.getFont()) | if (const Font* const f = attr.getFont()) | ||||
| { | { | ||||
| @@ -243,8 +244,19 @@ namespace CoreTextTypeLayout | |||||
| { | { | ||||
| ctFontRef = getFontWithPointSize (ctFontRef, f->getHeight() * getHeightToPointsFactor (ctFontRef)); | ctFontRef = getFontWithPointSize (ctFontRef, f->getHeight() * getHeightToPointsFactor (ctFontRef)); | ||||
| CFAttributedStringSetAttribute (attribString, CFRangeMake (range.getStart(), range.getLength()), | |||||
| kCTFontAttributeName, ctFontRef); | |||||
| CFAttributedStringSetAttribute (attribString, range, kCTFontAttributeName, ctFontRef); | |||||
| float extraKerning = f->getExtraKerningFactor(); | |||||
| if (extraKerning != 0.0f) | |||||
| { | |||||
| extraKerning *= f->getHeight(); | |||||
| CFNumberRef numberRef = CFNumberCreate (0, kCFNumberFloatType, &extraKerning); | |||||
| CFAttributedStringSetAttribute (attribString, range, kCTKernAttributeName, numberRef); | |||||
| CFRelease (numberRef); | |||||
| } | |||||
| CFRelease (ctFontRef); | CFRelease (ctFontRef); | ||||
| } | } | ||||
| } | } | ||||
| @@ -264,9 +276,7 @@ namespace CoreTextTypeLayout | |||||
| col->getFloatAlpha()); | col->getFloatAlpha()); | ||||
| #endif | #endif | ||||
| CFAttributedStringSetAttribute (attribString, | |||||
| CFRangeMake (range.getStart(), range.getLength()), | |||||
| kCTForegroundColorAttributeName, colour); | |||||
| CFAttributedStringSetAttribute (attribString, range, kCTForegroundColorAttributeName, colour); | |||||
| CGColorRelease (colour); | CGColorRelease (colour); | ||||
| } | } | ||||
| } | } | ||||
| @@ -51,10 +51,10 @@ public: | |||||
| Remember that when the target component is resized, it'll need to move and | Remember that when the target component is resized, it'll need to move and | ||||
| resize this component to keep it in place, as this won't happen automatically. | resize this component to keep it in place, as this won't happen automatically. | ||||
| If the constrainer parameter is non-zero, then this object will be used to enforce | |||||
| If a constrainer object is provided, then this object will be used to enforce | |||||
| limits on the size and position that the component can be stretched to. Make sure | limits on the size and position that the component can be stretched to. Make sure | ||||
| that the constrainer isn't deleted while still in use by this object. If you | that the constrainer isn't deleted while still in use by this object. If you | ||||
| pass a zero in here, no limits will be put on the sizes it can be stretched to. | |||||
| pass a nullptr in here, no limits will be put on the sizes it can be stretched to. | |||||
| @see ComponentBoundsConstrainer | @see ComponentBoundsConstrainer | ||||
| */ | */ | ||||
| @@ -131,7 +131,7 @@ public: | |||||
| /** OSX ONLY - Sets the model that is currently being shown as the main | /** OSX ONLY - Sets the model that is currently being shown as the main | ||||
| menu bar at the top of the screen on the Mac. | menu bar at the top of the screen on the Mac. | ||||
| You can pass 0 to stop the current model being displayed. Be careful | |||||
| You can pass nullptr to stop the current model being displayed. Be careful | |||||
| not to delete a model while it is being used. | not to delete a model while it is being used. | ||||
| An optional extra menu can be specified, containing items to add to the top of | An optional extra menu can be specified, containing items to add to the top of | ||||
| @@ -39,6 +39,14 @@ | |||||
| #define WM_APPCOMMAND 0x0319 | #define WM_APPCOMMAND 0x0319 | ||||
| #endif | #endif | ||||
| #ifndef MI_WP_SIGNATURE | |||||
| #define MI_WP_SIGNATURE 0xFF515700 | |||||
| #endif | |||||
| #ifndef SIGNATURE_MASK | |||||
| #define SIGNATURE_MASK 0xFFFFFF00 | |||||
| #endif | |||||
| extern void juce_repeatLastProcessPriority(); | extern void juce_repeatLastProcessPriority(); | ||||
| extern void juce_checkCurrentlyFocusedTopLevelWindow(); // in juce_TopLevelWindow.cpp | extern void juce_checkCurrentlyFocusedTopLevelWindow(); // in juce_TopLevelWindow.cpp | ||||
| extern bool juce_isRunningInWine(); | extern bool juce_isRunningInWine(); | ||||
| @@ -1706,8 +1714,22 @@ private: | |||||
| return 1000 / 60; // Throttling the incoming mouse-events seems to still be needed in XP.. | return 1000 / 60; // Throttling the incoming mouse-events seems to still be needed in XP.. | ||||
| } | } | ||||
| bool isTouchEvent() noexcept | |||||
| { | |||||
| if (registerTouchWindow == nullptr) | |||||
| return false; | |||||
| LPARAM dw = GetMessageExtraInfo(); | |||||
| // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms703320(v=vs.85).aspx | |||||
| return (dw & SIGNATURE_MASK) == MI_WP_SIGNATURE; | |||||
| } | |||||
| void doMouseMove (Point<float> position) | void doMouseMove (Point<float> position) | ||||
| { | { | ||||
| // this will be handled by WM_TOUCH | |||||
| if (isTouchEvent()) | |||||
| return; | |||||
| if (! isMouseOver) | if (! isMouseOver) | ||||
| { | { | ||||
| isMouseOver = true; | isMouseOver = true; | ||||
| @@ -1744,6 +1766,10 @@ private: | |||||
| void doMouseDown (Point<float> position, const WPARAM wParam) | void doMouseDown (Point<float> position, const WPARAM wParam) | ||||
| { | { | ||||
| // this will be handled by WM_TOUCH | |||||
| if (isTouchEvent()) | |||||
| return; | |||||
| if (GetCapture() != hwnd) | if (GetCapture() != hwnd) | ||||
| SetCapture (hwnd); | SetCapture (hwnd); | ||||
| @@ -1760,6 +1786,10 @@ private: | |||||
| void doMouseUp (Point<float> position, const WPARAM wParam) | void doMouseUp (Point<float> position, const WPARAM wParam) | ||||
| { | { | ||||
| // this will be handled by WM_TOUCH | |||||
| if (isTouchEvent()) | |||||
| return; | |||||
| updateModifiersFromWParam (wParam); | updateModifiersFromWParam (wParam); | ||||
| const bool wasDragging = isDragging; | const bool wasDragging = isDragging; | ||||
| isDragging = false; | isDragging = false; | ||||
| @@ -1879,8 +1909,7 @@ private: | |||||
| const DWORD flags = inputInfo[i].dwFlags; | const DWORD flags = inputInfo[i].dwFlags; | ||||
| if ((flags & (TOUCHEVENTF_DOWN | TOUCHEVENTF_MOVE | TOUCHEVENTF_UP)) != 0) | if ((flags & (TOUCHEVENTF_DOWN | TOUCHEVENTF_MOVE | TOUCHEVENTF_UP)) != 0) | ||||
| if (! handleTouchInput (inputInfo[i], (flags & TOUCHEVENTF_PRIMARY) != 0, | |||||
| (flags & TOUCHEVENTF_DOWN) != 0, (flags & TOUCHEVENTF_UP) != 0)) | |||||
| if (! handleTouchInput (inputInfo[i], (flags & TOUCHEVENTF_DOWN) != 0, (flags & TOUCHEVENTF_UP) != 0)) | |||||
| return 0; // abandon method if this window was deleted by the callback | return 0; // abandon method if this window was deleted by the callback | ||||
| } | } | ||||
| } | } | ||||
| @@ -1889,7 +1918,7 @@ private: | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| bool handleTouchInput (const TOUCHINPUT& touch, const bool isPrimary, const bool isDown, const bool isUp) | |||||
| bool handleTouchInput (const TOUCHINPUT& touch, const bool isDown, const bool isUp) | |||||
| { | { | ||||
| bool isCancel = false; | bool isCancel = false; | ||||
| const int touchIndex = currentTouches.getIndexOfTouch (touch.dwID); | const int touchIndex = currentTouches.getIndexOfTouch (touch.dwID); | ||||
| @@ -1903,13 +1932,10 @@ private: | |||||
| currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); | currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); | ||||
| modsToSend = currentModifiers; | modsToSend = currentModifiers; | ||||
| if (! isPrimary) | |||||
| { | |||||
| // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. | |||||
| handleMouseEvent (touchIndex, pos.toFloat(), modsToSend.withoutMouseButtons(), time); | |||||
| if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||||
| return false; | |||||
| } | |||||
| // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. | |||||
| handleMouseEvent (touchIndex, pos.toFloat(), modsToSend.withoutMouseButtons(), time); | |||||
| if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||||
| return false; | |||||
| } | } | ||||
| else if (isUp) | else if (isUp) | ||||
| { | { | ||||
| @@ -1930,14 +1956,11 @@ private: | |||||
| currentModifiers = currentModifiers.withoutMouseButtons(); | currentModifiers = currentModifiers.withoutMouseButtons(); | ||||
| } | } | ||||
| if (! isPrimary) | |||||
| { | |||||
| handleMouseEvent (touchIndex, pos.toFloat(), modsToSend, time); | |||||
| if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||||
| return false; | |||||
| } | |||||
| handleMouseEvent (touchIndex, pos.toFloat(), modsToSend, time); | |||||
| if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||||
| return false; | |||||
| if ((isUp || isCancel) && ! isPrimary) | |||||
| if (isUp || isCancel) | |||||
| { | { | ||||
| handleMouseEvent (touchIndex, Point<float> (-10.0f, -10.0f), currentModifiers, time); | handleMouseEvent (touchIndex, Point<float> (-10.0f, -10.0f), currentModifiers, time); | ||||
| if (! isValidPeer (this)) | if (! isValidPeer (this)) | ||||
| @@ -309,7 +309,7 @@ TextEditor* Label::createEditorComponent() | |||||
| copyColourIfSpecified (*this, *ed, textWhenEditingColourId, TextEditor::textColourId); | copyColourIfSpecified (*this, *ed, textWhenEditingColourId, TextEditor::textColourId); | ||||
| copyColourIfSpecified (*this, *ed, backgroundWhenEditingColourId, TextEditor::backgroundColourId); | copyColourIfSpecified (*this, *ed, backgroundWhenEditingColourId, TextEditor::backgroundColourId); | ||||
| copyColourIfSpecified (*this, *ed, outlineWhenEditingColourId, TextEditor::outlineColourId); | |||||
| copyColourIfSpecified (*this, *ed, outlineWhenEditingColourId, TextEditor::focusedOutlineColourId); | |||||
| return ed; | return ed; | ||||
| } | } | ||||
| @@ -89,7 +89,7 @@ void AlertWindow::addButton (const String& name, | |||||
| const KeyPress& shortcutKey1, | const KeyPress& shortcutKey1, | ||||
| const KeyPress& shortcutKey2) | const KeyPress& shortcutKey2) | ||||
| { | { | ||||
| TextButton* const b = new TextButton (name, String::empty); | |||||
| TextButton* const b = new TextButton (name, String()); | |||||
| buttons.add (b); | buttons.add (b); | ||||
| b->setWantsKeyboardFocus (true); | b->setWantsKeyboardFocus (true); | ||||
| @@ -143,9 +143,9 @@ void AlertWindow::addTextEditor (const String& name, | |||||
| ed->setColour (TextEditor::outlineColourId, findColour (ComboBox::outlineColourId)); | ed->setColour (TextEditor::outlineColourId, findColour (ComboBox::outlineColourId)); | ||||
| ed->setFont (getLookAndFeel().getAlertWindowMessageFont()); | ed->setFont (getLookAndFeel().getAlertWindowMessageFont()); | ||||
| addAndMakeVisible (ed); | |||||
| ed->setText (initialContents); | ed->setText (initialContents); | ||||
| ed->setCaretPosition (initialContents.length()); | ed->setCaretPosition (initialContents.length()); | ||||
| addAndMakeVisible (ed); | |||||
| textboxNames.add (onScreenLabel); | textboxNames.add (onScreenLabel); | ||||
| updateLayout (false); | updateLayout (false); | ||||
| @@ -165,7 +165,7 @@ String AlertWindow::getTextEditorContents (const String& nameOfTextEditor) const | |||||
| if (TextEditor* const t = getTextEditor (nameOfTextEditor)) | if (TextEditor* const t = getTextEditor (nameOfTextEditor)) | ||||
| return t->getText(); | return t->getText(); | ||||
| return String::empty; | |||||
| return String(); | |||||
| } | } | ||||
| @@ -66,14 +66,14 @@ struct CppTokeniserFunctions | |||||
| static const char* const keywords7Char[] = | static const char* const keywords7Char[] = | ||||
| { "nullptr", "alignas", "alignof", "default", "mutable", "private", | { "nullptr", "alignas", "alignof", "default", "mutable", "private", | ||||
| "typedef", "virtual", "wchar_t", nullptr }; | |||||
| "typedef", "virtual", "wchar_t", "__cdecl", "_Pragma", "uint8_t", nullptr }; | |||||
| static const char* const keywordsOther[] = | static const char* const keywordsOther[] = | ||||
| { "char16_t", "char32_t", "const_cast", "constexpr", "continue", "decltype", "dynamic_cast", | { "char16_t", "char32_t", "const_cast", "constexpr", "continue", "decltype", "dynamic_cast", | ||||
| "explicit", "namespace", "noexcept", "operator", "protected", "register", "reinterpret_cast", | "explicit", "namespace", "noexcept", "operator", "protected", "register", "reinterpret_cast", | ||||
| "static_assert", "static_cast", "template", "thread_local", "typename", "unsigned", "volatile", | "static_assert", "static_cast", "template", "thread_local", "typename", "unsigned", "volatile", | ||||
| "@class", "@dynamic", "@end", "@implementation", "@interface", "@public", "@private", | "@class", "@dynamic", "@end", "@implementation", "@interface", "@public", "@private", | ||||
| "@protected", "@property", "@synthesize", nullptr }; | |||||
| "@protected", "@property", "@synthesize", "__fastcall", "__stdcall", nullptr }; | |||||
| const char* const* k; | const char* const* k; | ||||