| @@ -40,8 +40,6 @@ | |||
| extern ApplicationCommandManager* commandManager; | |||
| //============================================================================== | |||
| static const char* const newLine = "\r\n"; | |||
| const char* const projectItemDragType = "Project Items"; | |||
| const char* const drawableItemDragType = "Drawable Items"; | |||
| const char* const componentItemDragType = "Components"; | |||
| @@ -523,7 +523,7 @@ public: | |||
| protected: | |||
| virtual const String getProjectVersionString() const { return "9.00"; } | |||
| virtual const String getSolutionVersionString() const { return String ("10.00") + newLine + "# Visual C++ Express 2008"; } | |||
| virtual const String getSolutionVersionString() const { return "10.00" + newLine + "# Visual C++ Express 2008"; } | |||
| const File getVCProjFile() const { return getProjectFile (".vcproj"); } | |||
| const File getSLNFile() const { return getProjectFile (".sln"); } | |||
| @@ -847,7 +847,7 @@ public: | |||
| protected: | |||
| const String getProjectVersionString() const { return "8.00"; } | |||
| const String getSolutionVersionString() const { return String ("8.00") + newLine + "# Visual C++ Express 2005"; } | |||
| const String getSolutionVersionString() const { return "8.00" + newLine + "# Visual C++ Express 2005"; } | |||
| JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2005); | |||
| }; | |||
| @@ -1227,10 +1227,10 @@ FileLogger::FileLogger (const File& logFile_, | |||
| } | |||
| String welcome; | |||
| welcome << "\r\n**********************************************************\r\n" | |||
| << welcomeMessage | |||
| << "\r\nLog started: " << Time::getCurrentTime().toString (true, true) | |||
| << "\r\n"; | |||
| welcome << newLine | |||
| << "**********************************************************" << newLine | |||
| << welcomeMessage << newLine | |||
| << "Log started: " << Time::getCurrentTime().toString (true, true) << newLine; | |||
| logMessage (welcome); | |||
| } | |||
| @@ -1246,7 +1246,7 @@ void FileLogger::logMessage (const String& message) | |||
| const ScopedLock sl (logLock); | |||
| FileOutputStream out (logFile, 256); | |||
| out << message << "\r\n"; | |||
| out << message << newLine; | |||
| } | |||
| void FileLogger::trimFileSize (int maxFileSizeBytes) const | |||
| @@ -6745,6 +6745,7 @@ void juce_CheckForDanglingStreams() | |||
| #endif | |||
| OutputStream::OutputStream() | |||
| : newLineString (NewLine::getDefault()) | |||
| { | |||
| #if JUCE_DEBUG | |||
| activeStreams.add (this); | |||
| @@ -6942,6 +6943,11 @@ int OutputStream::writeFromInputStream (InputStream& source, int64 numBytesToWri | |||
| return numWritten; | |||
| } | |||
| void OutputStream::setNewLineString (const String& newLineString_) | |||
| { | |||
| newLineString = newLineString_; | |||
| } | |||
| OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const int number) | |||
| { | |||
| return stream << String (number); | |||
| @@ -6980,6 +6986,11 @@ OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const File& fileTo | |||
| return stream; | |||
| } | |||
| OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const NewLine&) | |||
| { | |||
| return stream << stream.getNewLineString(); | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| /*** End of inlined file: juce_OutputStream.cpp ***/ | |||
| @@ -10175,7 +10186,7 @@ PerformanceCounter::PerformanceCounter (const String& name_, | |||
| String s ("**** Counter for \""); | |||
| s << name_ << "\" started at: " | |||
| << Time::getCurrentTime().toString (true, true) | |||
| << "\r\n"; | |||
| << newLine; | |||
| outputFile.appendText (s, false, false); | |||
| } | |||
| @@ -10219,7 +10230,7 @@ void PerformanceCounter::printStatistics() | |||
| Logger::outputDebugString (s); | |||
| s << "\r\n"; | |||
| s << newLine; | |||
| if (outputFile != File::nonexistent) | |||
| outputFile.appendText (s, false, false); | |||
| @@ -11656,6 +11667,8 @@ BEGIN_JUCE_NAMESPACE | |||
| #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default." | |||
| #endif | |||
| NewLine newLine; | |||
| class StringHolder | |||
| { | |||
| public: | |||
| @@ -12376,6 +12389,11 @@ JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const Str | |||
| return stream; | |||
| } | |||
| JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&) | |||
| { | |||
| return string1 += NewLine::getDefault(); | |||
| } | |||
| int String::indexOfChar (const juce_wchar character) const throw() | |||
| { | |||
| const juce_wchar* t = text; | |||
| @@ -15819,11 +15837,6 @@ namespace XmlOutputFunctions | |||
| out.write (blanks, numSpaces); | |||
| } | |||
| } | |||
| void writeNewLine (OutputStream& out) | |||
| { | |||
| out.write ("\r\n", 2); | |||
| } | |||
| } | |||
| void XmlElement::writeElementAsText (OutputStream& outputStream, | |||
| @@ -15846,7 +15859,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, | |||
| { | |||
| if (lineLen > lineWrapLength && indentationLevel >= 0) | |||
| { | |||
| writeNewLine (outputStream); | |||
| outputStream << newLine; | |||
| writeSpaces (outputStream, attIndent); | |||
| lineLen = 0; | |||
| } | |||
| @@ -15878,7 +15891,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, | |||
| else | |||
| { | |||
| if (indentationLevel >= 0 && ! lastWasTextNode) | |||
| writeNewLine (outputStream); | |||
| outputStream << newLine; | |||
| child->writeElementAsText (outputStream, | |||
| lastWasTextNode ? 0 : (indentationLevel + (indentationLevel >= 0 ? 2 : 0)), lineWrapLength); | |||
| @@ -15890,7 +15903,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, | |||
| if (indentationLevel >= 0 && ! lastWasTextNode) | |||
| { | |||
| writeNewLine (outputStream); | |||
| outputStream << newLine; | |||
| writeSpaces (outputStream, indentationLevel); | |||
| } | |||
| @@ -15935,14 +15948,9 @@ void XmlElement::writeToStream (OutputStream& output, | |||
| output << "<?xml version=\"1.0\" encoding=\"" << encodingType << "\"?>"; | |||
| if (allOnOneLine) | |||
| { | |||
| output.writeByte (' '); | |||
| } | |||
| else | |||
| { | |||
| writeNewLine (output); | |||
| writeNewLine (output); | |||
| } | |||
| output << newLine << newLine; | |||
| } | |||
| if (dtdToUse.isNotEmpty()) | |||
| @@ -15952,13 +15960,13 @@ void XmlElement::writeToStream (OutputStream& output, | |||
| if (allOnOneLine) | |||
| output.writeByte (' '); | |||
| else | |||
| writeNewLine (output); | |||
| output << newLine; | |||
| } | |||
| writeElementAsText (output, allOnOneLine ? -1 : 0, lineWrapLength); | |||
| if (! allOnOneLine) | |||
| writeNewLine (output); | |||
| output << newLine; | |||
| } | |||
| bool XmlElement::writeToFile (const File& file, | |||
| @@ -44121,33 +44129,34 @@ void DrawableButton::resized() | |||
| { | |||
| Button::resized(); | |||
| if (style == ImageRaw) | |||
| { | |||
| currentImage->setOriginWithOriginalSize (Point<float>()); | |||
| } | |||
| else if (currentImage != 0) | |||
| if (currentImage != 0) | |||
| { | |||
| Rectangle<int> imageSpace; | |||
| if (style == ImageOnButtonBackground) | |||
| if (style == ImageRaw) | |||
| { | |||
| imageSpace = getLocalBounds().reduced (getWidth() / 4, getHeight() / 4); | |||
| currentImage->setOriginWithOriginalSize (Point<float>()); | |||
| } | |||
| else | |||
| { | |||
| const int textH = (style == ImageAboveTextLabel) | |||
| ? jmin (16, proportionOfHeight (0.25f)) | |||
| : 0; | |||
| Rectangle<int> imageSpace; | |||
| if (style == ImageOnButtonBackground) | |||
| { | |||
| imageSpace = getLocalBounds().reduced (getWidth() / 4, getHeight() / 4); | |||
| } | |||
| else | |||
| { | |||
| const int textH = (style == ImageAboveTextLabel) ? jmin (16, proportionOfHeight (0.25f)) : 0; | |||
| const int indentX = jmin (edgeIndent, proportionOfWidth (0.3f)); | |||
| const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f)); | |||
| const int indentX = jmin (edgeIndent, proportionOfWidth (0.3f)); | |||
| const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f)); | |||
| imageSpace.setBounds (indentX, indentY, | |||
| getWidth() - indentX * 2, | |||
| getHeight() - indentY * 2 - textH); | |||
| } | |||
| imageSpace.setBounds (indentX, indentY, | |||
| getWidth() - indentX * 2, | |||
| getHeight() - indentY * 2 - textH); | |||
| } | |||
| currentImage->setTransformToFit (imageSpace.toFloat(), RectanglePlacement::centred); | |||
| currentImage->setTransformToFit (imageSpace.toFloat(), RectanglePlacement::centred); | |||
| } | |||
| } | |||
| } | |||
| @@ -64923,7 +64932,6 @@ LookAndFeel::LookAndFeel() | |||
| ScrollBar::backgroundColourId, 0x00000000, | |||
| ScrollBar::thumbColourId, 0xffffffff, | |||
| ScrollBar::trackColourId, 0xffffffff, | |||
| TreeView::linesColourId, 0x4c000000, | |||
| TreeView::backgroundColourId, 0x00000000, | |||
| @@ -65583,9 +65591,20 @@ void LookAndFeel::drawScrollbar (Graphics& g, | |||
| } | |||
| const Colour thumbColour (scrollbar.findColour (ScrollBar::thumbColourId)); | |||
| Colour trackColour1, trackColour2; | |||
| g.setGradientFill (ColourGradient (thumbColour.overlaidWith (Colour (0x44000000)), gx1, gy1, | |||
| thumbColour.overlaidWith (Colour (0x19000000)), gx2, gy2, false)); | |||
| if (scrollbar.isColourSpecified (ScrollBar::trackColourId)) | |||
| { | |||
| trackColour1 = trackColour2 = scrollbar.findColour (ScrollBar::trackColourId); | |||
| } | |||
| else | |||
| { | |||
| trackColour1 = thumbColour.overlaidWith (Colour (0x44000000)); | |||
| trackColour2 = thumbColour.overlaidWith (Colour (0x19000000)); | |||
| } | |||
| g.setGradientFill (ColourGradient (trackColour1, gx1, gy1, | |||
| trackColour2, gx2, gy2, false)); | |||
| g.fillPath (slotPath); | |||
| if (isScrollbarVertical) | |||
| @@ -74513,45 +74532,30 @@ BEGIN_JUCE_NAMESPACE | |||
| class ShadowWindow : public Component | |||
| { | |||
| Component* owner; | |||
| Image shadowImageSections [12]; | |||
| const int type; // 0 = left, 1 = right, 2 = top, 3 = bottom. left + right are full-height | |||
| public: | |||
| ShadowWindow (Component* const owner_, | |||
| const int type_, | |||
| const Image shadowImageSections_ [12]) | |||
| : owner (owner_), | |||
| ShadowWindow (Component& owner, const int type_, const Image shadowImageSections [12]) | |||
| : topLeft (shadowImageSections [type_ * 3]), | |||
| bottomRight (shadowImageSections [type_ * 3 + 1]), | |||
| filler (shadowImageSections [type_ * 3 + 2]), | |||
| type (type_) | |||
| { | |||
| for (int i = 0; i < numElementsInArray (shadowImageSections); ++i) | |||
| shadowImageSections [i] = shadowImageSections_ [i]; | |||
| setInterceptsMouseClicks (false, false); | |||
| if (owner_->isOnDesktop()) | |||
| if (owner.isOnDesktop()) | |||
| { | |||
| setSize (1, 1); // to keep the OS happy by not having zero-size windows | |||
| addToDesktop (ComponentPeer::windowIgnoresMouseClicks | |||
| | ComponentPeer::windowIsTemporary | |||
| | ComponentPeer::windowIgnoresKeyPresses); | |||
| } | |||
| else if (owner_->getParentComponent() != 0) | |||
| else if (owner.getParentComponent() != 0) | |||
| { | |||
| owner_->getParentComponent()->addChildComponent (this); | |||
| owner.getParentComponent()->addChildComponent (this); | |||
| } | |||
| } | |||
| ~ShadowWindow() | |||
| { | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| const Image& topLeft = shadowImageSections [type * 3]; | |||
| const Image& bottomRight = shadowImageSections [type * 3 + 1]; | |||
| const Image& filler = shadowImageSections [type * 3 + 2]; | |||
| g.setOpacity (1.0f); | |||
| if (type < 2) | |||
| @@ -74592,6 +74596,9 @@ public: | |||
| } | |||
| private: | |||
| const Image topLeft, bottomRight, filler; | |||
| const int type; // 0 = left, 1 = right, 2 = top, 3 = bottom. left + right are full-height | |||
| JUCE_DECLARE_NON_COPYABLE (ShadowWindow); | |||
| }; | |||
| @@ -74600,13 +74607,10 @@ DropShadower::DropShadower (const float alpha_, | |||
| const int yOffset_, | |||
| const float blurRadius_) | |||
| : owner (0), | |||
| numShadows (0), | |||
| shadowEdge (jmax (xOffset_, yOffset_) + (int) blurRadius_), | |||
| xOffset (xOffset_), | |||
| yOffset (yOffset_), | |||
| alpha (alpha_), | |||
| blurRadius (blurRadius_), | |||
| inDestructor (false), | |||
| reentrant (false) | |||
| { | |||
| } | |||
| @@ -74616,21 +74620,8 @@ DropShadower::~DropShadower() | |||
| if (owner != 0) | |||
| owner->removeComponentListener (this); | |||
| inDestructor = true; | |||
| deleteShadowWindows(); | |||
| } | |||
| void DropShadower::deleteShadowWindows() | |||
| { | |||
| if (numShadows > 0) | |||
| { | |||
| int i; | |||
| for (i = numShadows; --i >= 0;) | |||
| delete shadowWindows[i]; | |||
| numShadows = 0; | |||
| } | |||
| reentrant = true; | |||
| shadowWindows.clear(); | |||
| } | |||
| void DropShadower::setOwner (Component* componentToFollow) | |||
| @@ -74664,13 +74655,9 @@ void DropShadower::componentBroughtToFront (Component&) | |||
| bringShadowWindowsToFront(); | |||
| } | |||
| void DropShadower::componentChildrenChanged (Component&) | |||
| { | |||
| } | |||
| void DropShadower::componentParentHierarchyChanged (Component&) | |||
| { | |||
| deleteShadowWindows(); | |||
| shadowWindows.clear(); | |||
| updateShadows(); | |||
| } | |||
| @@ -74681,23 +74668,23 @@ void DropShadower::componentVisibilityChanged (Component&) | |||
| void DropShadower::updateShadows() | |||
| { | |||
| if (reentrant || inDestructor || (owner == 0)) | |||
| if (reentrant || owner == 0) | |||
| return; | |||
| reentrant = true; | |||
| ComponentPeer* const nw = owner->getPeer(); | |||
| ComponentPeer* const peer = owner->getPeer(); | |||
| const bool isOwnerVisible = owner->isVisible() && (peer == 0 || ! peer->isMinimised()); | |||
| const bool isOwnerVisible = owner->isVisible() | |||
| && (nw == 0 || ! nw->isMinimised()); | |||
| const bool createShadowWindows = numShadows == 0 | |||
| const bool createShadowWindows = shadowWindows.size() == 0 | |||
| && owner->getWidth() > 0 | |||
| && owner->getHeight() > 0 | |||
| && isOwnerVisible | |||
| && (Desktop::canUseSemiTransparentWindows() | |||
| || owner->getParentComponent() != 0); | |||
| const int shadowEdge = jmax (xOffset, yOffset) + (int) blurRadius; | |||
| if (createShadowWindows) | |||
| { | |||
| // keep a cached version of the image to save doing the gaussian too often | |||
| @@ -74747,18 +74734,15 @@ void DropShadower::updateShadows() | |||
| setShadowImage (bigIm, 11, shadowEdge, shadowEdge, shadowEdge2, ih - shadowEdge); | |||
| for (int i = 0; i < 4; ++i) | |||
| { | |||
| shadowWindows[numShadows] = new ShadowWindow (owner, i, shadowImageSections); | |||
| ++numShadows; | |||
| } | |||
| shadowWindows.add (new ShadowWindow (*owner, i, shadowImageSections)); | |||
| } | |||
| if (numShadows > 0) | |||
| if (shadowWindows.size() >= 4) | |||
| { | |||
| for (int i = numShadows; --i >= 0;) | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| { | |||
| shadowWindows[i]->setAlwaysOnTop (owner->isAlwaysOnTop()); | |||
| shadowWindows[i]->setVisible (isOwnerVisible); | |||
| shadowWindows.getUnchecked(i)->setAlwaysOnTop (owner->isAlwaysOnTop()); | |||
| shadowWindows.getUnchecked(i)->setVisible (isOwnerVisible); | |||
| } | |||
| const int x = owner->getX(); | |||
| @@ -74766,25 +74750,10 @@ void DropShadower::updateShadows() | |||
| const int w = owner->getWidth(); | |||
| const int h = owner->getHeight() + shadowEdge + shadowEdge; | |||
| shadowWindows[0]->setBounds (x - shadowEdge, | |||
| y, | |||
| shadowEdge, | |||
| h); | |||
| shadowWindows[1]->setBounds (x + w, | |||
| y, | |||
| shadowEdge, | |||
| h); | |||
| shadowWindows[2]->setBounds (x, | |||
| y, | |||
| w, | |||
| shadowEdge); | |||
| shadowWindows[3]->setBounds (x, | |||
| owner->getBottom(), | |||
| w, | |||
| shadowEdge); | |||
| shadowWindows.getUnchecked(0)->setBounds (x - shadowEdge, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(1)->setBounds (x + w, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(2)->setBounds (x, y, w, shadowEdge); | |||
| shadowWindows.getUnchecked(3)->setBounds (x, owner->getBottom(), w, shadowEdge); | |||
| } | |||
| reentrant = false; | |||
| @@ -74804,14 +74773,14 @@ void DropShadower::setShadowImage (const Image& src, const int num, const int w, | |||
| void DropShadower::bringShadowWindowsToFront() | |||
| { | |||
| if (! (inDestructor || reentrant)) | |||
| if (! reentrant) | |||
| { | |||
| updateShadows(); | |||
| reentrant = true; | |||
| for (int i = numShadows; --i >= 0;) | |||
| shadowWindows[i]->toBehind (owner); | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| shadowWindows.getUnchecked(i)->toBehind (owner); | |||
| reentrant = false; | |||
| } | |||
| @@ -2804,6 +2804,47 @@ JUCE_API std::basic_ostream <charT, traits>& JUCE_CALLTYPE operator<< (std::basi | |||
| /** Writes a string to an OutputStream as UTF8. */ | |||
| JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text); | |||
| /** This class is used for represent a new-line character sequence. | |||
| To write a new-line to a stream, you can use the predefined 'newLine' variable, e.g. | |||
| @code | |||
| myOutputStream << "Hello World" << newLine << newLine; | |||
| @endcode | |||
| The exact character sequence that will be used for the new-line can be set and | |||
| retrieved with OutputStream::setNewLineString() and OutputStream::getNewLineString(). | |||
| */ | |||
| class NewLine | |||
| { | |||
| public: | |||
| /** Returns the default new-line sequence that the library uses. | |||
| @see OutputStream::setNewLineString() | |||
| */ | |||
| static const char* getDefault() throw() { return "\r\n"; } | |||
| /** Returns the default new-line sequence that the library uses. | |||
| @see getDefault() | |||
| */ | |||
| operator const String() const { return getDefault(); } | |||
| }; | |||
| /** An object representing a new-line, which can be written to a string or stream. | |||
| To write a new-line to a stream, you can use the predefined 'newLine' variable like this: | |||
| @code | |||
| myOutputStream << "Hello World" << newLine << newLine; | |||
| @endcode | |||
| */ | |||
| extern NewLine newLine; | |||
| /** Writes a new-line sequence to a string. | |||
| You can use the predefined object 'newLine' to invoke this, e.g. | |||
| @code | |||
| myString << "Hello World" << newLine << newLine; | |||
| @endcode | |||
| */ | |||
| JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&); | |||
| #endif // __JUCE_STRING_JUCEHEADER__ | |||
| /*** End of inlined file: juce_String.h ***/ | |||
| @@ -6235,8 +6276,19 @@ public: | |||
| */ | |||
| 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 throw() { return newLineString; } | |||
| private: | |||
| String newLineString; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OutputStream); | |||
| }; | |||
| @@ -6258,6 +6310,15 @@ OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& | |||
| /** 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 ***/ | |||
| @@ -50898,8 +50959,6 @@ public: | |||
| /** @internal */ | |||
| void componentBroughtToFront (Component& component); | |||
| /** @internal */ | |||
| void componentChildrenChanged (Component& component); | |||
| /** @internal */ | |||
| void componentParentHierarchyChanged (Component& component); | |||
| /** @internal */ | |||
| void componentVisibilityChanged (Component& component); | |||
| @@ -50907,17 +50966,15 @@ public: | |||
| private: | |||
| Component* owner; | |||
| int numShadows; | |||
| Component* shadowWindows[4]; | |||
| OwnedArray<Component> shadowWindows; | |||
| Image shadowImageSections[12]; | |||
| const int shadowEdge, xOffset, yOffset; | |||
| const int xOffset, yOffset; | |||
| const float alpha, blurRadius; | |||
| bool inDestructor, reentrant; | |||
| bool reentrant; | |||
| void updateShadows(); | |||
| void setShadowImage (const Image& src, int num, int w, int h, int sx, int sy); | |||
| void bringShadowWindowsToFront(); | |||
| void deleteShadowWindows(); | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DropShadower); | |||
| }; | |||
| @@ -51,10 +51,10 @@ FileLogger::FileLogger (const File& logFile_, | |||
| } | |||
| String welcome; | |||
| welcome << "\r\n**********************************************************\r\n" | |||
| << welcomeMessage | |||
| << "\r\nLog started: " << Time::getCurrentTime().toString (true, true) | |||
| << "\r\n"; | |||
| welcome << newLine | |||
| << "**********************************************************" << newLine | |||
| << welcomeMessage << newLine | |||
| << "Log started: " << Time::getCurrentTime().toString (true, true) << newLine; | |||
| logMessage (welcome); | |||
| } | |||
| @@ -71,7 +71,7 @@ void FileLogger::logMessage (const String& message) | |||
| const ScopedLock sl (logLock); | |||
| FileOutputStream out (logFile, 256); | |||
| out << message << "\r\n"; | |||
| out << message << newLine; | |||
| } | |||
| @@ -46,7 +46,7 @@ PerformanceCounter::PerformanceCounter (const String& name_, | |||
| String s ("**** Counter for \""); | |||
| s << name_ << "\" started at: " | |||
| << Time::getCurrentTime().toString (true, true) | |||
| << "\r\n"; | |||
| << newLine; | |||
| outputFile.appendText (s, false, false); | |||
| } | |||
| @@ -90,7 +90,7 @@ void PerformanceCounter::printStatistics() | |||
| Logger::outputDebugString (s); | |||
| s << "\r\n"; | |||
| s << newLine; | |||
| if (outputFile != File::nonexistent) | |||
| outputFile.appendText (s, false, false); | |||
| @@ -119,33 +119,34 @@ void DrawableButton::resized() | |||
| { | |||
| Button::resized(); | |||
| if (style == ImageRaw) | |||
| { | |||
| currentImage->setOriginWithOriginalSize (Point<float>()); | |||
| } | |||
| else if (currentImage != 0) | |||
| if (currentImage != 0) | |||
| { | |||
| Rectangle<int> imageSpace; | |||
| if (style == ImageOnButtonBackground) | |||
| if (style == ImageRaw) | |||
| { | |||
| imageSpace = getLocalBounds().reduced (getWidth() / 4, getHeight() / 4); | |||
| currentImage->setOriginWithOriginalSize (Point<float>()); | |||
| } | |||
| else | |||
| { | |||
| const int textH = (style == ImageAboveTextLabel) | |||
| ? jmin (16, proportionOfHeight (0.25f)) | |||
| : 0; | |||
| Rectangle<int> imageSpace; | |||
| const int indentX = jmin (edgeIndent, proportionOfWidth (0.3f)); | |||
| const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f)); | |||
| if (style == ImageOnButtonBackground) | |||
| { | |||
| imageSpace = getLocalBounds().reduced (getWidth() / 4, getHeight() / 4); | |||
| } | |||
| else | |||
| { | |||
| const int textH = (style == ImageAboveTextLabel) ? jmin (16, proportionOfHeight (0.25f)) : 0; | |||
| imageSpace.setBounds (indentX, indentY, | |||
| getWidth() - indentX * 2, | |||
| getHeight() - indentY * 2 - textH); | |||
| } | |||
| const int indentX = jmin (edgeIndent, proportionOfWidth (0.3f)); | |||
| const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f)); | |||
| imageSpace.setBounds (indentX, indentY, | |||
| getWidth() - indentX * 2, | |||
| getHeight() - indentY * 2 - textH); | |||
| } | |||
| currentImage->setTransformToFit (imageSpace.toFloat(), RectanglePlacement::centred); | |||
| currentImage->setTransformToFit (imageSpace.toFloat(), RectanglePlacement::centred); | |||
| } | |||
| } | |||
| } | |||
| @@ -202,7 +202,6 @@ LookAndFeel::LookAndFeel() | |||
| ScrollBar::backgroundColourId, 0x00000000, | |||
| ScrollBar::thumbColourId, 0xffffffff, | |||
| ScrollBar::trackColourId, 0xffffffff, | |||
| TreeView::linesColourId, 0x4c000000, | |||
| TreeView::backgroundColourId, 0x00000000, | |||
| @@ -870,9 +869,20 @@ void LookAndFeel::drawScrollbar (Graphics& g, | |||
| } | |||
| const Colour thumbColour (scrollbar.findColour (ScrollBar::thumbColourId)); | |||
| Colour trackColour1, trackColour2; | |||
| g.setGradientFill (ColourGradient (thumbColour.overlaidWith (Colour (0x44000000)), gx1, gy1, | |||
| thumbColour.overlaidWith (Colour (0x19000000)), gx2, gy2, false)); | |||
| if (scrollbar.isColourSpecified (ScrollBar::trackColourId)) | |||
| { | |||
| trackColour1 = trackColour2 = scrollbar.findColour (ScrollBar::trackColourId); | |||
| } | |||
| else | |||
| { | |||
| trackColour1 = thumbColour.overlaidWith (Colour (0x44000000)); | |||
| trackColour2 = thumbColour.overlaidWith (Colour (0x19000000)); | |||
| } | |||
| g.setGradientFill (ColourGradient (trackColour1, gx1, gy1, | |||
| trackColour2, gx2, gy2, false)); | |||
| g.fillPath (slotPath); | |||
| if (isScrollbarVertical) | |||
| @@ -38,45 +38,30 @@ BEGIN_JUCE_NAMESPACE | |||
| //============================================================================== | |||
| class ShadowWindow : public Component | |||
| { | |||
| Component* owner; | |||
| Image shadowImageSections [12]; | |||
| const int type; // 0 = left, 1 = right, 2 = top, 3 = bottom. left + right are full-height | |||
| public: | |||
| ShadowWindow (Component* const owner_, | |||
| const int type_, | |||
| const Image shadowImageSections_ [12]) | |||
| : owner (owner_), | |||
| ShadowWindow (Component& owner, const int type_, const Image shadowImageSections [12]) | |||
| : topLeft (shadowImageSections [type_ * 3]), | |||
| bottomRight (shadowImageSections [type_ * 3 + 1]), | |||
| filler (shadowImageSections [type_ * 3 + 2]), | |||
| type (type_) | |||
| { | |||
| for (int i = 0; i < numElementsInArray (shadowImageSections); ++i) | |||
| shadowImageSections [i] = shadowImageSections_ [i]; | |||
| setInterceptsMouseClicks (false, false); | |||
| if (owner_->isOnDesktop()) | |||
| if (owner.isOnDesktop()) | |||
| { | |||
| setSize (1, 1); // to keep the OS happy by not having zero-size windows | |||
| addToDesktop (ComponentPeer::windowIgnoresMouseClicks | |||
| | ComponentPeer::windowIsTemporary | |||
| | ComponentPeer::windowIgnoresKeyPresses); | |||
| } | |||
| else if (owner_->getParentComponent() != 0) | |||
| else if (owner.getParentComponent() != 0) | |||
| { | |||
| owner_->getParentComponent()->addChildComponent (this); | |||
| owner.getParentComponent()->addChildComponent (this); | |||
| } | |||
| } | |||
| ~ShadowWindow() | |||
| { | |||
| } | |||
| void paint (Graphics& g) | |||
| { | |||
| const Image& topLeft = shadowImageSections [type * 3]; | |||
| const Image& bottomRight = shadowImageSections [type * 3 + 1]; | |||
| const Image& filler = shadowImageSections [type * 3 + 2]; | |||
| g.setOpacity (1.0f); | |||
| if (type < 2) | |||
| @@ -117,6 +102,9 @@ public: | |||
| } | |||
| private: | |||
| const Image topLeft, bottomRight, filler; | |||
| const int type; // 0 = left, 1 = right, 2 = top, 3 = bottom. left + right are full-height | |||
| JUCE_DECLARE_NON_COPYABLE (ShadowWindow); | |||
| }; | |||
| @@ -127,13 +115,10 @@ DropShadower::DropShadower (const float alpha_, | |||
| const int yOffset_, | |||
| const float blurRadius_) | |||
| : owner (0), | |||
| numShadows (0), | |||
| shadowEdge (jmax (xOffset_, yOffset_) + (int) blurRadius_), | |||
| xOffset (xOffset_), | |||
| yOffset (yOffset_), | |||
| alpha (alpha_), | |||
| blurRadius (blurRadius_), | |||
| inDestructor (false), | |||
| reentrant (false) | |||
| { | |||
| } | |||
| @@ -143,21 +128,8 @@ DropShadower::~DropShadower() | |||
| if (owner != 0) | |||
| owner->removeComponentListener (this); | |||
| inDestructor = true; | |||
| deleteShadowWindows(); | |||
| } | |||
| void DropShadower::deleteShadowWindows() | |||
| { | |||
| if (numShadows > 0) | |||
| { | |||
| int i; | |||
| for (i = numShadows; --i >= 0;) | |||
| delete shadowWindows[i]; | |||
| numShadows = 0; | |||
| } | |||
| reentrant = true; | |||
| shadowWindows.clear(); | |||
| } | |||
| void DropShadower::setOwner (Component* componentToFollow) | |||
| @@ -191,13 +163,9 @@ void DropShadower::componentBroughtToFront (Component&) | |||
| bringShadowWindowsToFront(); | |||
| } | |||
| void DropShadower::componentChildrenChanged (Component&) | |||
| { | |||
| } | |||
| void DropShadower::componentParentHierarchyChanged (Component&) | |||
| { | |||
| deleteShadowWindows(); | |||
| shadowWindows.clear(); | |||
| updateShadows(); | |||
| } | |||
| @@ -208,23 +176,23 @@ void DropShadower::componentVisibilityChanged (Component&) | |||
| void DropShadower::updateShadows() | |||
| { | |||
| if (reentrant || inDestructor || (owner == 0)) | |||
| if (reentrant || owner == 0) | |||
| return; | |||
| reentrant = true; | |||
| ComponentPeer* const nw = owner->getPeer(); | |||
| const bool isOwnerVisible = owner->isVisible() | |||
| && (nw == 0 || ! nw->isMinimised()); | |||
| ComponentPeer* const peer = owner->getPeer(); | |||
| const bool isOwnerVisible = owner->isVisible() && (peer == 0 || ! peer->isMinimised()); | |||
| const bool createShadowWindows = numShadows == 0 | |||
| const bool createShadowWindows = shadowWindows.size() == 0 | |||
| && owner->getWidth() > 0 | |||
| && owner->getHeight() > 0 | |||
| && isOwnerVisible | |||
| && (Desktop::canUseSemiTransparentWindows() | |||
| || owner->getParentComponent() != 0); | |||
| const int shadowEdge = jmax (xOffset, yOffset) + (int) blurRadius; | |||
| if (createShadowWindows) | |||
| { | |||
| // keep a cached version of the image to save doing the gaussian too often | |||
| @@ -274,18 +242,15 @@ void DropShadower::updateShadows() | |||
| setShadowImage (bigIm, 11, shadowEdge, shadowEdge, shadowEdge2, ih - shadowEdge); | |||
| for (int i = 0; i < 4; ++i) | |||
| { | |||
| shadowWindows[numShadows] = new ShadowWindow (owner, i, shadowImageSections); | |||
| ++numShadows; | |||
| } | |||
| shadowWindows.add (new ShadowWindow (*owner, i, shadowImageSections)); | |||
| } | |||
| if (numShadows > 0) | |||
| if (shadowWindows.size() >= 4) | |||
| { | |||
| for (int i = numShadows; --i >= 0;) | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| { | |||
| shadowWindows[i]->setAlwaysOnTop (owner->isAlwaysOnTop()); | |||
| shadowWindows[i]->setVisible (isOwnerVisible); | |||
| shadowWindows.getUnchecked(i)->setAlwaysOnTop (owner->isAlwaysOnTop()); | |||
| shadowWindows.getUnchecked(i)->setVisible (isOwnerVisible); | |||
| } | |||
| const int x = owner->getX(); | |||
| @@ -293,25 +258,10 @@ void DropShadower::updateShadows() | |||
| const int w = owner->getWidth(); | |||
| const int h = owner->getHeight() + shadowEdge + shadowEdge; | |||
| shadowWindows[0]->setBounds (x - shadowEdge, | |||
| y, | |||
| shadowEdge, | |||
| h); | |||
| shadowWindows[1]->setBounds (x + w, | |||
| y, | |||
| shadowEdge, | |||
| h); | |||
| shadowWindows[2]->setBounds (x, | |||
| y, | |||
| w, | |||
| shadowEdge); | |||
| shadowWindows[3]->setBounds (x, | |||
| owner->getBottom(), | |||
| w, | |||
| shadowEdge); | |||
| shadowWindows.getUnchecked(0)->setBounds (x - shadowEdge, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(1)->setBounds (x + w, y, shadowEdge, h); | |||
| shadowWindows.getUnchecked(2)->setBounds (x, y, w, shadowEdge); | |||
| shadowWindows.getUnchecked(3)->setBounds (x, owner->getBottom(), w, shadowEdge); | |||
| } | |||
| reentrant = false; | |||
| @@ -331,14 +281,14 @@ void DropShadower::setShadowImage (const Image& src, const int num, const int w, | |||
| void DropShadower::bringShadowWindowsToFront() | |||
| { | |||
| if (! (inDestructor || reentrant)) | |||
| if (! reentrant) | |||
| { | |||
| updateShadows(); | |||
| reentrant = true; | |||
| for (int i = numShadows; --i >= 0;) | |||
| shadowWindows[i]->toBehind (owner); | |||
| for (int i = shadowWindows.size(); --i >= 0;) | |||
| shadowWindows.getUnchecked(i)->toBehind (owner); | |||
| reentrant = false; | |||
| } | |||
| @@ -71,8 +71,6 @@ public: | |||
| /** @internal */ | |||
| void componentBroughtToFront (Component& component); | |||
| /** @internal */ | |||
| void componentChildrenChanged (Component& component); | |||
| /** @internal */ | |||
| void componentParentHierarchyChanged (Component& component); | |||
| /** @internal */ | |||
| void componentVisibilityChanged (Component& component); | |||
| @@ -81,17 +79,15 @@ public: | |||
| private: | |||
| //============================================================================== | |||
| Component* owner; | |||
| int numShadows; | |||
| Component* shadowWindows[4]; | |||
| OwnedArray<Component> shadowWindows; | |||
| Image shadowImageSections[12]; | |||
| const int shadowEdge, xOffset, yOffset; | |||
| const int xOffset, yOffset; | |||
| const float alpha, blurRadius; | |||
| bool inDestructor, reentrant; | |||
| bool reentrant; | |||
| void updateShadows(); | |||
| void setShadowImage (const Image& src, int num, int w, int h, int sx, int sy); | |||
| void bringShadowWindowsToFront(); | |||
| void deleteShadowWindows(); | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DropShadower); | |||
| }; | |||
| @@ -52,6 +52,7 @@ void juce_CheckForDanglingStreams() | |||
| //============================================================================== | |||
| OutputStream::OutputStream() | |||
| : newLineString (NewLine::getDefault()) | |||
| { | |||
| #if JUCE_DEBUG | |||
| activeStreams.add (this); | |||
| @@ -250,6 +251,12 @@ int OutputStream::writeFromInputStream (InputStream& source, int64 numBytesToWri | |||
| return numWritten; | |||
| } | |||
| //============================================================================== | |||
| void OutputStream::setNewLineString (const String& newLineString_) | |||
| { | |||
| newLineString = newLineString_; | |||
| } | |||
| //============================================================================== | |||
| OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const int number) | |||
| { | |||
| @@ -289,5 +296,10 @@ OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const File& fileTo | |||
| return stream; | |||
| } | |||
| OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const NewLine&) | |||
| { | |||
| return stream << stream.getNewLineString(); | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -201,8 +201,20 @@ public: | |||
| */ | |||
| 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 throw() { return newLineString; } | |||
| private: | |||
| //============================================================================== | |||
| String newLineString; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OutputStream); | |||
| }; | |||
| @@ -225,5 +237,14 @@ OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& | |||
| /** 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__ | |||
| @@ -46,6 +46,8 @@ BEGIN_JUCE_NAMESPACE | |||
| #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default." | |||
| #endif | |||
| NewLine newLine; | |||
| //============================================================================== | |||
| class StringHolder | |||
| { | |||
| @@ -779,6 +781,11 @@ JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const Str | |||
| return stream; | |||
| } | |||
| JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&) | |||
| { | |||
| return string1 += NewLine::getDefault(); | |||
| } | |||
| //============================================================================== | |||
| int String::indexOfChar (const juce_wchar character) const throw() | |||
| { | |||
| @@ -2167,7 +2174,6 @@ void String::copyToUnicode (juce_wchar* const destBuffer, const int maxCharsToCo | |||
| StringHolder::copyChars (destBuffer, text, jmin (maxCharsToCopy, length())); | |||
| } | |||
| //============================================================================== | |||
| String::Concatenator::Concatenator (String& stringToAppendTo) | |||
| : result (stringToAppendTo), | |||
| @@ -2191,6 +2197,9 @@ void String::Concatenator::append (const String& s) | |||
| } | |||
| } | |||
| //============================================================================== | |||
| //============================================================================== | |||
| #if JUCE_UNIT_TESTS | |||
| #include "../utilities/juce_UnitTest.h" | |||
| @@ -1145,4 +1145,47 @@ JUCE_API std::basic_ostream <charT, traits>& JUCE_CALLTYPE operator<< (std::basi | |||
| JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text); | |||
| //============================================================================== | |||
| /** This class is used for represent a new-line character sequence. | |||
| To write a new-line to a stream, you can use the predefined 'newLine' variable, e.g. | |||
| @code | |||
| myOutputStream << "Hello World" << newLine << newLine; | |||
| @endcode | |||
| The exact character sequence that will be used for the new-line can be set and | |||
| retrieved with OutputStream::setNewLineString() and OutputStream::getNewLineString(). | |||
| */ | |||
| class NewLine | |||
| { | |||
| public: | |||
| /** Returns the default new-line sequence that the library uses. | |||
| @see OutputStream::setNewLineString() | |||
| */ | |||
| static const char* getDefault() throw() { return "\r\n"; } | |||
| /** Returns the default new-line sequence that the library uses. | |||
| @see getDefault() | |||
| */ | |||
| operator const String() const { return getDefault(); } | |||
| }; | |||
| /** An object representing a new-line, which can be written to a string or stream. | |||
| To write a new-line to a stream, you can use the predefined 'newLine' variable like this: | |||
| @code | |||
| myOutputStream << "Hello World" << newLine << newLine; | |||
| @endcode | |||
| */ | |||
| extern NewLine newLine; | |||
| /** Writes a new-line sequence to a string. | |||
| You can use the predefined object 'newLine' to invoke this, e.g. | |||
| @code | |||
| myString << "Hello World" << newLine << newLine; | |||
| @endcode | |||
| */ | |||
| JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const NewLine&); | |||
| #endif // __JUCE_STRING_JUCEHEADER__ | |||
| @@ -261,11 +261,6 @@ namespace XmlOutputFunctions | |||
| out.write (blanks, numSpaces); | |||
| } | |||
| } | |||
| void writeNewLine (OutputStream& out) | |||
| { | |||
| out.write ("\r\n", 2); | |||
| } | |||
| } | |||
| void XmlElement::writeElementAsText (OutputStream& outputStream, | |||
| @@ -288,7 +283,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, | |||
| { | |||
| if (lineLen > lineWrapLength && indentationLevel >= 0) | |||
| { | |||
| writeNewLine (outputStream); | |||
| outputStream << newLine; | |||
| writeSpaces (outputStream, attIndent); | |||
| lineLen = 0; | |||
| } | |||
| @@ -320,7 +315,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, | |||
| else | |||
| { | |||
| if (indentationLevel >= 0 && ! lastWasTextNode) | |||
| writeNewLine (outputStream); | |||
| outputStream << newLine; | |||
| child->writeElementAsText (outputStream, | |||
| lastWasTextNode ? 0 : (indentationLevel + (indentationLevel >= 0 ? 2 : 0)), lineWrapLength); | |||
| @@ -332,7 +327,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream, | |||
| if (indentationLevel >= 0 && ! lastWasTextNode) | |||
| { | |||
| writeNewLine (outputStream); | |||
| outputStream << newLine; | |||
| writeSpaces (outputStream, indentationLevel); | |||
| } | |||
| @@ -377,14 +372,9 @@ void XmlElement::writeToStream (OutputStream& output, | |||
| output << "<?xml version=\"1.0\" encoding=\"" << encodingType << "\"?>"; | |||
| if (allOnOneLine) | |||
| { | |||
| output.writeByte (' '); | |||
| } | |||
| else | |||
| { | |||
| writeNewLine (output); | |||
| writeNewLine (output); | |||
| } | |||
| output << newLine << newLine; | |||
| } | |||
| if (dtdToUse.isNotEmpty()) | |||
| @@ -394,13 +384,13 @@ void XmlElement::writeToStream (OutputStream& output, | |||
| if (allOnOneLine) | |||
| output.writeByte (' '); | |||
| else | |||
| writeNewLine (output); | |||
| output << newLine; | |||
| } | |||
| writeElementAsText (output, allOnOneLine ? -1 : 0, lineWrapLength); | |||
| if (! allOnOneLine) | |||
| writeNewLine (output); | |||
| output << newLine; | |||
| } | |||
| bool XmlElement::writeToFile (const File& file, | |||