diff --git a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_MSVC.h b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_MSVC.h index bbfb0924f1..b1f1c4ee69 100644 --- a/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_MSVC.h +++ b/extras/Jucer (experimental)/Source/Project/jucer_ProjectExport_MSVC.h @@ -1284,6 +1284,11 @@ protected: link->createNewChildElement ("EnableCOMDATFolding")->addTextElement ("true"); } + String extraLinkerOptions (getExtraLinkerFlags().toString()); + if (extraLinkerOptions.isNotEmpty()) + link->createNewChildElement ("AdditionalOptions")->addTextElement (replacePreprocessorTokens (config, extraLinkerOptions).trim() + + " %(AdditionalOptions)"); + XmlElement* bsc = group->createNewChildElement ("Bscmake"); bsc->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); bsc->createNewChildElement ("OutputFile")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc")); diff --git a/extras/audio plugins/demo/Source/PluginProcessor.cpp b/extras/audio plugins/demo/Source/PluginProcessor.cpp index f3a8e9a764..50356489ca 100644 --- a/extras/audio plugins/demo/Source/PluginProcessor.cpp +++ b/extras/audio plugins/demo/Source/PluginProcessor.cpp @@ -135,21 +135,11 @@ private: JuceDemoPluginAudioProcessor::JuceDemoPluginAudioProcessor() : delayBuffer (2, 12000) { - // Set up parameters and default values.. - AudioProcessorParameter* gainParam = new AudioProcessorParameter ("gain"); - gainParam->resetWithDefault (1.0); - parameters.add (gainParam); + // Set up some default values.. + gain = 1.0f; + delay = 0.5f; - AudioProcessorParameter* delayParam = new AudioProcessorParameter ("delay"); - delayParam->resetWithDefault (0.5); - parameters.add (delayParam); - - AudioProcessorParameter* cutOffParam = new AudioProcessorParameter ("cutoff", AudioProcessorParameter::hertz); - cutOffParam->setRange (Range (20.0, 20000.0)); - cutOffParam->resetWithDefault (10000.0); - parameters.add (cutOffParam); - - lastUIWidth = 600; + lastUIWidth = 400; lastUIHeight = 200; lastPosInfo.resetToDefault(); @@ -160,8 +150,6 @@ JuceDemoPluginAudioProcessor::JuceDemoPluginAudioProcessor() synth.addVoice (new SineWaveVoice()); // These voices will play our custom sine-wave sounds.. synth.addSound (new SineWaveSound()); - - zeromem (lastSample, sizeof (lastSample)); } JuceDemoPluginAudioProcessor::~JuceDemoPluginAudioProcessor() @@ -171,7 +159,7 @@ JuceDemoPluginAudioProcessor::~JuceDemoPluginAudioProcessor() //============================================================================== int JuceDemoPluginAudioProcessor::getNumParameters() { - return parameters.size(); + return totalNumParams; } float JuceDemoPluginAudioProcessor::getParameter (int index) @@ -179,8 +167,12 @@ float JuceDemoPluginAudioProcessor::getParameter (int index) // This method will be called by the host, probably on the audio thread, so // it's absolutely time-critical. Don't use critical sections or anything // UI-related, or anything at all that may block in any way! - jassert (parameters [index] != 0); - parameters.getUnchecked (index)->getValue(); + switch (index) + { + case gainParam: return gain; + case delayParam: return delay; + default: return 0.0f; + } } void JuceDemoPluginAudioProcessor::setParameter (int index, float newValue) @@ -188,14 +180,24 @@ void JuceDemoPluginAudioProcessor::setParameter (int index, float newValue) // This method will be called by the host, probably on the audio thread, so // it's absolutely time-critical. Don't use critical sections or anything // UI-related, or anything at all that may block in any way! - jassert (parameters [index] != 0); - parameters.getUnchecked (index)->setValue (newValue); + switch (index) + { + case gainParam: gain = newValue; break; + case delayParam: delay = newValue; break; + default: break; + } } const String JuceDemoPluginAudioProcessor::getParameterName (int index) { - jassert (parameters [index] != 0); - return parameters.getUnchecked (index)->getName(); + switch (index) + { + case gainParam: return "gain"; + case delayParam: return "delay"; + default: break; + } + + return String::empty; } const String JuceDemoPluginAudioProcessor::getParameterText (int index) @@ -203,26 +205,6 @@ const String JuceDemoPluginAudioProcessor::getParameterText (int index) return String (getParameter (index), 2); } -int JuceDemoPluginAudioProcessor::indexOfParameter (const String& parameterName) const -{ - for (int i = parameters.size(); --i >= 0;) - if (parameters.getUnchecked(i)->getName() == name) - return i; - - return -1; -} - -AudioProcessorParameter* JuceDemoPluginAudioProcessor::getParameterObject (int index) const -{ - return parameters [index]; -} - -AudioProcessorParameter* JuceDemoPluginAudioProcessor::getParameterWithName (const String& parameterName) const -{ - return parameters [indexOfParameter (parameterName)]; -} - - //============================================================================== void JuceDemoPluginAudioProcessor::prepareToPlay (double sampleRate, int /*samplesPerBlock*/) { @@ -251,12 +233,6 @@ void JuceDemoPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, Midi { const int numSamples = buffer.getNumSamples(); int channel, dp = 0; - float gain = getParameter (0); - float delay = getParameter (1); - float cutOff = getParameter (2); - - // Get one-pole filter coefficient - const float filterCoeff = (float_Pi * cutOff / getSampleRate()); // Go through the incoming data, and apply our gain to it... for (channel = 0; channel < getNumInputChannels(); ++channel) @@ -279,12 +255,7 @@ void JuceDemoPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, Midi for (int i = 0; i < numSamples; ++i) { const float in = channelData[i]; - - // filter delay data - lastSample [channel] += filterCoeff * (delayData[dp] - lastSample [channel]); - - // add to output buffers - channelData[i] += lastSample [channel]; + channelData[i] += delayData[dp]; delayData[dp] = (delayData[dp] + in) * delay; if (++dp > delayBuffer.getNumSamples()) dp = 0; @@ -332,12 +303,8 @@ void JuceDemoPluginAudioProcessor::getStateInformation (MemoryBlock& destData) // add some attributes to it.. xml.setAttribute ("uiWidth", lastUIWidth); xml.setAttribute ("uiHeight", lastUIHeight); - - for (int i = 0; i < parameters.size(); ++i) - { - const AudioProcessorParameter* const p = parameters.getUnchecked(i); - xml.setAttribute (p->getName(), p->getValue()); - } + xml.setAttribute ("gain", gain); + xml.setAttribute ("delay", delay); // then use this helper function to stuff it into the binary blob and return it.. copyXmlToBinary (xml, destData); @@ -356,16 +323,12 @@ void JuceDemoPluginAudioProcessor::setStateInformation (const void* data, int si // make sure that it's actually our type of XML object.. if (xmlState->hasTagName ("MYPLUGINSETTINGS")) { - // ok, now pull out our plugin-specific attributes.. + // ok, now pull out our parameters.. lastUIWidth = xmlState->getIntAttribute ("uiWidth", lastUIWidth); lastUIHeight = xmlState->getIntAttribute ("uiHeight", lastUIHeight); - // and all the parameters. - for (int i = 0; i < parameters.size(); ++i) - { - const AudioProcessorParameter* const p = parameters.getUnchecked(i); - p->setValue (xmlState->getDoubleAttribute (p->getName(), p->getDefault())); - } + gain = (float) xmlState->getDoubleAttribute ("gain", gain); + delay = (float) xmlState->getDoubleAttribute ("delay", delay); } } } diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 20dccb6833..60d15c68aa 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -13484,6 +13484,11 @@ CharPointer_UTF32 String::toUTF32() const return StringEncodingConverter ::convert (*this); } +const wchar_t* String::toWideCharPointer() const +{ + return (const wchar_t*) StringEncodingConverter ::convert (*this).getAddress(); +} + template struct StringCopier { @@ -64770,6 +64775,7 @@ Viewport::Viewport (const String& componentName) singleStepY (16), showHScrollbar (true), showVScrollbar (true), + deleteContent (true), verticalScrollBar (true), horizontalScrollBar (false) { @@ -64798,18 +64804,26 @@ void Viewport::visibleAreaChanged (const Rectangle&) void Viewport::deleteContentComp() { - // This sets the content comp to a null pointer before deleting the old one, in case - // anything tries to use the old one while it's in mid-deletion.. - ScopedPointer oldCompDeleter (contentComp); - contentComp = 0; + if (deleteContent) + { + // This sets the content comp to a null pointer before deleting the old one, in case + // anything tries to use the old one while it's in mid-deletion.. + ScopedPointer oldCompDeleter (contentComp); + contentComp = 0; + } + else + { + contentComp = 0; + } } -void Viewport::setViewedComponent (Component* const newViewedComponent) +void Viewport::setViewedComponent (Component* const newViewedComponent, const bool deleteComponentWhenNoLongerNeeded) { if (contentComp.get() != newViewedComponent) { deleteContentComp(); contentComp = newViewedComponent; + deleteContent = deleteComponentWhenNoLongerNeeded; if (contentComp != 0) { @@ -261960,25 +261974,19 @@ class LinuxComponentPeer : public ComponentPeer { public: - LinuxComponentPeer (Component* const component, const int windowStyleFlags) + LinuxComponentPeer (Component* const component, const int windowStyleFlags, Window parentToAddTo)) : ComponentPeer (component, windowStyleFlags), - windowH (0), - parentWindow (0), - wx (0), - wy (0), - ww (0), - wh (0), - fullScreen (false), - mapped (false), - visual (0), - depth (0) + windowH (0), parentWindow (0), + wx (0), wy (0), ww (0), wh (0), + fullScreen (false), mapped (false), + visual (0), depth (0) { // it's dangerous to create a window on a thread other than the message thread.. jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); repainter = new LinuxRepaintManager (this); - createWindow(); + createWindow (parentToAddTo); setTitle (component->getName()); } @@ -263337,7 +263345,7 @@ private: (unsigned char*) &netHints, numHints); } - void createWindow() + void createWindow (Window parentToAddTo) { ScopedXLock xlock; Atoms::initialiseAtoms(); @@ -263367,7 +263375,7 @@ private: swa.colormap = colormap; swa.event_mask = getAllEventsMask(); - windowH = XCreateWindow (display, root, + windowH = XCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root, 0, 0, 1, 1, 0, depth, InputOutput, visual, CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask, @@ -263862,9 +263870,9 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); } -ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) +ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo) { - return new LinuxComponentPeer (this, styleFlags); + return new LinuxComponentPeer (this, styleFlags, (Window) nativeWindowToAttachTo); } // (this callback is hooked up in the messaging code) diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 891753d429..405d86c939 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 43 +#define JUCE_BUILDNUMBER 44 /** Current Juce version number. @@ -4462,17 +4462,13 @@ public: // Comparison methods.. /** Returns true if the string contains no characters. - Note that there's also an isNotEmpty() method to help write readable code. - @see containsNonWhitespaceChars() */ inline bool isEmpty() const throw() { return text[0] == 0; } /** Returns true if the string contains at least one character. - Note that there's also an isEmpty() method to help write readable code. - @see containsNonWhitespaceChars() */ inline bool isNotEmpty() const throw() { return text[0] != 0; } @@ -4487,30 +4483,26 @@ public: bool equalsIgnoreCase (const char* other) const throw(); /** Case-sensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compare (const String& other) const throw(); /** Case-sensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compare (const char* other) const throw(); /** Case-sensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compare (const wchar_t* other) const throw(); /** Case-insensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compareIgnoreCase (const String& other) const throw(); @@ -4519,9 +4511,8 @@ public: The comparison used here is case-insensitive and ignores leading non-alphanumeric characters, making it good for sorting human-readable strings. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compareLexicographically (const String& other) const throw(); @@ -4612,7 +4603,6 @@ public: int indexOfWholeWordIgnoreCase (const String& wordToLookFor) const throw(); /** Looks for any of a set of characters in the string. - Uses a case-sensitive comparison. @returns true if the string contains any of the characters from @@ -4621,7 +4611,6 @@ public: bool containsAnyOf (const String& charactersItMightContain) const throw(); /** Looks for a set of characters in the string. - Uses a case-sensitive comparison. @returns Returns false if any of the characters in this string do not occur in @@ -4765,7 +4754,6 @@ public: const juce_wchar operator[] (int index) const throw(); /** Returns the final character of the string. - If the string is empty this will return 0. */ juce_wchar getLastCharacter() const throw(); @@ -4873,8 +4861,10 @@ public: /** Returns a copy of this string with any whitespace characters removed from the start and end. */ const String trim() const; + /** Returns a copy of this string with any whitespace characters removed from the start. */ const String trimStart() const; + /** Returns a copy of this string with any whitespace characters removed from the end. */ const String trimEnd() const; @@ -5052,7 +5042,9 @@ public: here because of the popular unrest that was stirred-up when I tried to remove it... If you're really determined to use it, at least make sure that you never, ever, - pass any String objects to it as parameters. + pass any String objects to it as parameters. And bear in mind that internally, depending + 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, ... ); @@ -5243,6 +5235,20 @@ public: */ CharPointer_UTF32 toUTF32() const; + /** Returns a pointer to a wchar_t version of this string. + + Because it returns a reference to the string's internal data, the pointer + that is returned must not be stored anywhere, as it can be deleted whenever the + string changes. + + Bear in mind that the wchar_t type is different on different platforms, so on + Windows, this will be equivalent to calling toUTF16(), on unix it'll be the same + as calling toUTF32(), etc. + + @see getCharPointer, toUTF8, toUTF16, toUTF32 + */ + const wchar_t* toWideCharPointer() const; + /** Creates a String from a UTF-8 encoded buffer. If the size is < 0, it'll keep reading until it hits a zero. */ @@ -6828,14 +6834,10 @@ public: const ElementType* e = data.elements.getData(); const ElementType* const end = e + numUsed; - while (e != end) - { + for (; e != end; ++e) if (elementToLookFor == *e) return static_cast (e - data.elements.getData()); - ++e; - } - return -1; } @@ -6850,14 +6852,10 @@ public: const ElementType* e = data.elements.getData(); const ElementType* const end = e + numUsed; - while (e != end) - { + for (; e != end; ++e) if (elementToLookFor == *e) return true; - ++e; - } - return false; } @@ -7239,17 +7237,15 @@ public: void removeValue (ParameterType valueToRemove) { const ScopedLockType lock (getLock()); - ElementType* e = data.elements; + ElementType* const e = data.elements; - for (int i = numUsed; --i >= 0;) + for (int i = 0; i < numUsed; ++i) { - if (valueToRemove == *e) + if (valueToRemove == e[i]) { - remove (static_cast (e - data.elements.getData())); + remove (i); break; } - - ++e; } } @@ -9467,14 +9463,10 @@ public: ObjectClass* const* e = data.elements.getData(); ObjectClass* const* const end = e + numUsed; - while (e != end) - { + for (; e != end; ++e) if (objectToLookFor == *e) return static_cast (e - data.elements.getData()); - ++e; - } - return -1; } @@ -9489,14 +9481,10 @@ public: ObjectClass* const* e = data.elements.getData(); ObjectClass* const* const end = e + numUsed; - while (e != end) - { + for (; e != end; ++e) if (objectToLookFor == *e) return true; - ++e; - } - return false; } @@ -9859,17 +9847,15 @@ public: const bool deleteObject = true) { const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements.getData(); + ObjectClass** const e = data.elements.getData(); - for (int i = numUsed; --i >= 0;) + for (int i = 0; i < numUsed; ++i) { - if (objectToRemove == *e) + if (objectToRemove == e[i]) { - remove (static_cast (e - data.elements.getData()), deleteObject); + remove (i, deleteObject); break; } - - ++e; } } @@ -12139,7 +12125,7 @@ private: */ #define forEachXmlChildElement(parentXmlElement, childElementVariableName) \ \ - for (XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ + for (JUCE_NAMESPACE::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ childElementVariableName != 0; \ childElementVariableName = childElementVariableName->getNextElement()) @@ -12168,7 +12154,7 @@ private: */ #define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \ \ - for (XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ + for (JUCE_NAMESPACE::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ childElementVariableName != 0; \ childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName)) @@ -40661,18 +40647,21 @@ public: /** 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). + This will add the given component to this Viewport and position it at (0, 0). (Don't add or remove any child components directly using the normal Component::addChildComponent() methods). - @param newViewedComponent the component to add to this viewport (this pointer - may be null). The component passed in will be deleted - by the Viewport when it's no longer needed + @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 */ - void setViewedComponent (Component* newViewedComponent); + void setViewedComponent (Component* newViewedComponent, + bool deleteComponentWhenNoLongerNeeded = true); /** Returns the component that's currently being used inside the Viewport. @@ -40851,7 +40840,7 @@ private: Rectangle lastVisibleArea; int scrollBarThickness; int singleStepX, singleStepY; - bool showHScrollbar, showVScrollbar; + bool showHScrollbar, showVScrollbar, deleteContent; Component contentHolder; ScrollBar verticalScrollBar; ScrollBar horizontalScrollBar; @@ -43210,7 +43199,7 @@ public: static Type gainToDecibels (const Type gain, const Type minusInfinityDb = (Type) defaultMinusInfinitydB) { - return gain > Type() ? jmax (minusInfinityDb, (Type) std::log (gain) * (Type) 20.0) + return gain > Type() ? jmax (minusInfinityDb, (Type) std::log10 (gain) * (Type) 20.0) : minusInfinityDb; } diff --git a/src/audio/dsp/juce_Decibels.h b/src/audio/dsp/juce_Decibels.h index 758008c1e3..24348b6b23 100644 --- a/src/audio/dsp/juce_Decibels.h +++ b/src/audio/dsp/juce_Decibels.h @@ -57,7 +57,7 @@ public: static Type gainToDecibels (const Type gain, const Type minusInfinityDb = (Type) defaultMinusInfinitydB) { - return gain > Type() ? jmax (minusInfinityDb, (Type) std::log (gain) * (Type) 20.0) + return gain > Type() ? jmax (minusInfinityDb, (Type) std::log10 (gain) * (Type) 20.0) : minusInfinityDb; } diff --git a/src/containers/juce_Array.h b/src/containers/juce_Array.h index 017406d03f..0ecb6dc166 100644 --- a/src/containers/juce_Array.h +++ b/src/containers/juce_Array.h @@ -303,14 +303,10 @@ public: const ElementType* e = data.elements.getData(); const ElementType* const end = e + numUsed; - while (e != end) - { + for (; e != end; ++e) if (elementToLookFor == *e) return static_cast (e - data.elements.getData()); - ++e; - } - return -1; } @@ -325,14 +321,10 @@ public: const ElementType* e = data.elements.getData(); const ElementType* const end = e + numUsed; - while (e != end) - { + for (; e != end; ++e) if (elementToLookFor == *e) return true; - ++e; - } - return false; } @@ -716,17 +708,15 @@ public: void removeValue (ParameterType valueToRemove) { const ScopedLockType lock (getLock()); - ElementType* e = data.elements; + ElementType* const e = data.elements; - for (int i = numUsed; --i >= 0;) + for (int i = 0; i < numUsed; ++i) { - if (valueToRemove == *e) + if (valueToRemove == e[i]) { - remove (static_cast (e - data.elements.getData())); + remove (i); break; } - - ++e; } } diff --git a/src/containers/juce_OwnedArray.h b/src/containers/juce_OwnedArray.h index 4735f3d881..839017a976 100644 --- a/src/containers/juce_OwnedArray.h +++ b/src/containers/juce_OwnedArray.h @@ -170,14 +170,10 @@ public: ObjectClass* const* e = data.elements.getData(); ObjectClass* const* const end = e + numUsed; - while (e != end) - { + for (; e != end; ++e) if (objectToLookFor == *e) return static_cast (e - data.elements.getData()); - ++e; - } - return -1; } @@ -192,14 +188,10 @@ public: ObjectClass* const* e = data.elements.getData(); ObjectClass* const* const end = e + numUsed; - while (e != end) - { + for (; e != end; ++e) if (objectToLookFor == *e) return true; - ++e; - } - return false; } @@ -564,17 +556,15 @@ public: const bool deleteObject = true) { const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements.getData(); + ObjectClass** const e = data.elements.getData(); - for (int i = numUsed; --i >= 0;) + for (int i = 0; i < numUsed; ++i) { - if (objectToRemove == *e) + if (objectToRemove == e[i]) { - remove (static_cast (e - data.elements.getData()), deleteObject); + remove (i, deleteObject); break; } - - ++e; } } diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 0954cac304..b302e2c08c 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 43 +#define JUCE_BUILDNUMBER 44 /** Current Juce version number. diff --git a/src/gui/components/layout/juce_Viewport.cpp b/src/gui/components/layout/juce_Viewport.cpp index becc2ab050..66829bd7d1 100644 --- a/src/gui/components/layout/juce_Viewport.cpp +++ b/src/gui/components/layout/juce_Viewport.cpp @@ -39,6 +39,7 @@ Viewport::Viewport (const String& componentName) singleStepY (16), showHScrollbar (true), showVScrollbar (true), + deleteContent (true), verticalScrollBar (true), horizontalScrollBar (false) { @@ -69,18 +70,26 @@ void Viewport::visibleAreaChanged (const Rectangle&) //============================================================================== void Viewport::deleteContentComp() { - // This sets the content comp to a null pointer before deleting the old one, in case - // anything tries to use the old one while it's in mid-deletion.. - ScopedPointer oldCompDeleter (contentComp); - contentComp = 0; + if (deleteContent) + { + // This sets the content comp to a null pointer before deleting the old one, in case + // anything tries to use the old one while it's in mid-deletion.. + ScopedPointer oldCompDeleter (contentComp); + contentComp = 0; + } + else + { + contentComp = 0; + } } -void Viewport::setViewedComponent (Component* const newViewedComponent) +void Viewport::setViewedComponent (Component* const newViewedComponent, const bool deleteComponentWhenNoLongerNeeded) { if (contentComp.get() != newViewedComponent) { deleteContentComp(); contentComp = newViewedComponent; + deleteContent = deleteComponentWhenNoLongerNeeded; if (contentComp != 0) { diff --git a/src/gui/components/layout/juce_Viewport.h b/src/gui/components/layout/juce_Viewport.h index c8d41cf9b8..da4144d6ff 100644 --- a/src/gui/components/layout/juce_Viewport.h +++ b/src/gui/components/layout/juce_Viewport.h @@ -61,18 +61,21 @@ public: //============================================================================== /** 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). + This will add the given component to this Viewport and position it at (0, 0). (Don't add or remove any child components directly using the normal Component::addChildComponent() methods). - @param newViewedComponent the component to add to this viewport (this pointer - may be null). The component passed in will be deleted - by the Viewport when it's no longer needed + @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 */ - void setViewedComponent (Component* newViewedComponent); + void setViewedComponent (Component* newViewedComponent, + bool deleteComponentWhenNoLongerNeeded = true); /** Returns the component that's currently being used inside the Viewport. @@ -256,7 +259,7 @@ private: Rectangle lastVisibleArea; int scrollBarThickness; int singleStepX, singleStepY; - bool showHScrollbar, showVScrollbar; + bool showHScrollbar, showVScrollbar, deleteContent; Component contentHolder; ScrollBar verticalScrollBar; ScrollBar horizontalScrollBar; diff --git a/src/native/linux/juce_linux_Windowing.cpp b/src/native/linux/juce_linux_Windowing.cpp index fd41ab9a1a..7c990cc086 100644 --- a/src/native/linux/juce_linux_Windowing.cpp +++ b/src/native/linux/juce_linux_Windowing.cpp @@ -747,25 +747,19 @@ class LinuxComponentPeer : public ComponentPeer { public: //============================================================================== - LinuxComponentPeer (Component* const component, const int windowStyleFlags) + LinuxComponentPeer (Component* const component, const int windowStyleFlags, Window parentToAddTo)) : ComponentPeer (component, windowStyleFlags), - windowH (0), - parentWindow (0), - wx (0), - wy (0), - ww (0), - wh (0), - fullScreen (false), - mapped (false), - visual (0), - depth (0) + windowH (0), parentWindow (0), + wx (0), wy (0), ww (0), wh (0), + fullScreen (false), mapped (false), + visual (0), depth (0) { // it's dangerous to create a window on a thread other than the message thread.. jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); repainter = new LinuxRepaintManager (this); - createWindow(); + createWindow (parentToAddTo); setTitle (component->getName()); } @@ -2130,7 +2124,7 @@ private: (unsigned char*) &netHints, numHints); } - void createWindow() + void createWindow (Window parentToAddTo) { ScopedXLock xlock; Atoms::initialiseAtoms(); @@ -2160,7 +2154,7 @@ private: swa.colormap = colormap; swa.event_mask = getAllEventsMask(); - windowH = XCreateWindow (display, root, + windowH = XCreateWindow (display, parentToAddTo != 0 ? parentToAddTo : root, 0, 0, 1, 1, 0, depth, InputOutput, visual, CWBorderPixel | CWColormap | CWBackPixmap | CWEventMask, @@ -2661,9 +2655,9 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable } //============================================================================== -ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) +ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAttachTo) { - return new LinuxComponentPeer (this, styleFlags); + return new LinuxComponentPeer (this, styleFlags, (Window) nativeWindowToAttachTo); } diff --git a/src/text/juce_String.cpp b/src/text/juce_String.cpp index 92cefb61f9..cb9f0aea25 100644 --- a/src/text/juce_String.cpp +++ b/src/text/juce_String.cpp @@ -2118,6 +2118,11 @@ CharPointer_UTF32 String::toUTF32() const return StringEncodingConverter ::convert (*this); } +const wchar_t* String::toWideCharPointer() const +{ + return (const wchar_t*) StringEncodingConverter ::convert (*this).getAddress(); +} + //============================================================================== template struct StringCopier diff --git a/src/text/juce_String.h b/src/text/juce_String.h index b9e07dc7f0..8e2fc5dfea 100644 --- a/src/text/juce_String.h +++ b/src/text/juce_String.h @@ -283,17 +283,13 @@ public: // Comparison methods.. /** Returns true if the string contains no characters. - Note that there's also an isNotEmpty() method to help write readable code. - @see containsNonWhitespaceChars() */ inline bool isEmpty() const throw() { return text[0] == 0; } /** Returns true if the string contains at least one character. - Note that there's also an isEmpty() method to help write readable code. - @see containsNonWhitespaceChars() */ inline bool isNotEmpty() const throw() { return text[0] != 0; } @@ -308,30 +304,26 @@ public: bool equalsIgnoreCase (const char* other) const throw(); /** Case-sensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compare (const String& other) const throw(); /** Case-sensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compare (const char* other) const throw(); /** Case-sensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compare (const wchar_t* other) const throw(); /** Case-insensitive comparison with another string. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compareIgnoreCase (const String& other) const throw(); @@ -340,9 +332,8 @@ public: The comparison used here is case-insensitive and ignores leading non-alphanumeric characters, making it good for sorting human-readable strings. - @returns 0 if the two strings are identical; negative if this string - comes before the other one alphabetically, or positive if it - comes after it. + @returns 0 if the two strings are identical; negative if this string comes before + the other one alphabetically, or positive if it comes after it. */ int compareLexicographically (const String& other) const throw(); @@ -433,7 +424,6 @@ public: int indexOfWholeWordIgnoreCase (const String& wordToLookFor) const throw(); /** Looks for any of a set of characters in the string. - Uses a case-sensitive comparison. @returns true if the string contains any of the characters from @@ -442,7 +432,6 @@ public: bool containsAnyOf (const String& charactersItMightContain) const throw(); /** Looks for a set of characters in the string. - Uses a case-sensitive comparison. @returns Returns false if any of the characters in this string do not occur in @@ -589,7 +578,6 @@ public: const juce_wchar operator[] (int index) const throw(); /** Returns the final character of the string. - If the string is empty this will return 0. */ juce_wchar getLastCharacter() const throw(); @@ -700,8 +688,10 @@ public: //============================================================================== /** Returns a copy of this string with any whitespace characters removed from the start and end. */ const String trim() const; + /** Returns a copy of this string with any whitespace characters removed from the start. */ const String trimStart() const; + /** Returns a copy of this string with any whitespace characters removed from the end. */ const String trimEnd() const; @@ -884,7 +874,9 @@ public: here because of the popular unrest that was stirred-up when I tried to remove it... If you're really determined to use it, at least make sure that you never, ever, - pass any String objects to it as parameters. + pass any String objects to it as parameters. And bear in mind that internally, depending + 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, ... ); @@ -1077,6 +1069,20 @@ public: */ CharPointer_UTF32 toUTF32() const; + /** Returns a pointer to a wchar_t version of this string. + + Because it returns a reference to the string's internal data, the pointer + that is returned must not be stored anywhere, as it can be deleted whenever the + string changes. + + Bear in mind that the wchar_t type is different on different platforms, so on + Windows, this will be equivalent to calling toUTF16(), on unix it'll be the same + as calling toUTF32(), etc. + + @see getCharPointer, toUTF8, toUTF16, toUTF32 + */ + const wchar_t* toWideCharPointer() const; + //============================================================================== /** Creates a String from a UTF-8 encoded buffer. If the size is < 0, it'll keep reading until it hits a zero. diff --git a/src/text/juce_XmlElement.h b/src/text/juce_XmlElement.h index 9aa35b744e..25c5458b41 100644 --- a/src/text/juce_XmlElement.h +++ b/src/text/juce_XmlElement.h @@ -53,7 +53,7 @@ */ #define forEachXmlChildElement(parentXmlElement, childElementVariableName) \ \ - for (XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ + for (JUCE_NAMESPACE::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ childElementVariableName != 0; \ childElementVariableName = childElementVariableName->getNextElement()) @@ -82,7 +82,7 @@ */ #define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \ \ - for (XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ + for (JUCE_NAMESPACE::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ childElementVariableName != 0; \ childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName))