| @@ -64,7 +64,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 86 | |||||
| #define JUCE_BUILDNUMBER 87 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -1394,41 +1394,41 @@ private: | |||||
| inline uint16 ByteOrder::swap (uint16 n) | inline uint16 ByteOrder::swap (uint16 n) | ||||
| { | { | ||||
| #if JUCE_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic! | |||||
| #if JUCE_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic! | |||||
| return static_cast <uint16> (_byteswap_ushort (n)); | return static_cast <uint16> (_byteswap_ushort (n)); | ||||
| #else | |||||
| #else | |||||
| return static_cast <uint16> ((n << 8) | (n >> 8)); | return static_cast <uint16> ((n << 8) | (n >> 8)); | ||||
| #endif | |||||
| #endif | |||||
| } | } | ||||
| inline uint32 ByteOrder::swap (uint32 n) | inline uint32 ByteOrder::swap (uint32 n) | ||||
| { | { | ||||
| #if JUCE_MAC || JUCE_IOS | |||||
| #if JUCE_MAC || JUCE_IOS | |||||
| return OSSwapInt32 (n); | return OSSwapInt32 (n); | ||||
| #elif JUCE_GCC | |||||
| #elif JUCE_GCC | |||||
| asm("bswap %%eax" : "=a"(n) : "a"(n)); | asm("bswap %%eax" : "=a"(n) : "a"(n)); | ||||
| return n; | return n; | ||||
| #elif JUCE_USE_INTRINSICS | |||||
| #elif JUCE_USE_INTRINSICS | |||||
| return _byteswap_ulong (n); | return _byteswap_ulong (n); | ||||
| #else | |||||
| #else | |||||
| __asm { | __asm { | ||||
| mov eax, n | mov eax, n | ||||
| bswap eax | bswap eax | ||||
| mov n, eax | mov n, eax | ||||
| } | } | ||||
| return n; | return n; | ||||
| #endif | |||||
| #endif | |||||
| } | } | ||||
| inline uint64 ByteOrder::swap (uint64 value) | inline uint64 ByteOrder::swap (uint64 value) | ||||
| { | { | ||||
| #if JUCE_MAC || JUCE_IOS | |||||
| #if JUCE_MAC || JUCE_IOS | |||||
| return OSSwapInt64 (value); | return OSSwapInt64 (value); | ||||
| #elif JUCE_USE_INTRINSICS | |||||
| #elif JUCE_USE_INTRINSICS | |||||
| return _byteswap_uint64 (value); | return _byteswap_uint64 (value); | ||||
| #else | |||||
| #else | |||||
| return (((int64) swap ((uint32) value)) << 32) | swap ((uint32) (value >> 32)); | return (((int64) swap ((uint32) value)) << 32) | swap ((uint32) (value >> 32)); | ||||
| #endif | |||||
| #endif | |||||
| } | } | ||||
| #if JUCE_LITTLE_ENDIAN | #if JUCE_LITTLE_ENDIAN | ||||
| @@ -10294,6 +10294,8 @@ private: | |||||
| String name, value; | String name, value; | ||||
| XmlAttributeNode* next; | XmlAttributeNode* next; | ||||
| bool hasName (const String& name) const throw(); | |||||
| private: | private: | ||||
| XmlAttributeNode& operator= (const XmlAttributeNode&); | XmlAttributeNode& operator= (const XmlAttributeNode&); | ||||
| }; | }; | ||||
| @@ -17680,6 +17682,16 @@ private: | |||||
| @endcode | @endcode | ||||
| Or you can use the static helper methods for quick parsing.. | |||||
| @code | |||||
| XmlElement* xml = XmlDocument::parse (myXmlFile); | |||||
| if (xml != 0 && xml->hasTagName ("foobar")) | |||||
| { | |||||
| ...etc | |||||
| @endcode | |||||
| @see XmlElement | @see XmlElement | ||||
| */ | */ | ||||
| class JUCE_API XmlDocument | class JUCE_API XmlDocument | ||||
| @@ -17687,16 +17699,12 @@ class JUCE_API XmlDocument | |||||
| public: | public: | ||||
| /** Creates an XmlDocument from the xml text. | /** Creates an XmlDocument from the xml text. | ||||
| The text doesn't actually get parsed until the getDocumentElement() method is | |||||
| called. | |||||
| The text doesn't actually get parsed until the getDocumentElement() method is called. | |||||
| */ | */ | ||||
| XmlDocument (const String& documentText); | XmlDocument (const String& documentText); | ||||
| /** Creates an XmlDocument from a file. | /** Creates an XmlDocument from a file. | ||||
| The text doesn't actually get parsed until the getDocumentElement() method is | |||||
| called. | |||||
| The text doesn't actually get parsed until the getDocumentElement() method is called. | |||||
| */ | */ | ||||
| XmlDocument (const File& file); | XmlDocument (const File& file); | ||||
| @@ -17709,6 +17717,9 @@ public: | |||||
| parse error, it may returns 0 (and you can find out the error using | parse error, it may returns 0 (and you can find out the error using | ||||
| the getLastParseError() method). | the getLastParseError() method). | ||||
| See also the parse() methods, which provide a shorthand way to quickly | |||||
| parse a file or string. | |||||
| @param onlyReadOuterDocumentElement if true, the parser will only read the | @param onlyReadOuterDocumentElement if true, the parser will only read the | ||||
| first section of the file, and will only | first section of the file, and will only | ||||
| return the outer document element - this | return the outer document element - this | ||||
| @@ -17749,6 +17760,18 @@ public: | |||||
| */ | */ | ||||
| void setEmptyTextElementsIgnored (bool shouldBeIgnored) throw(); | void setEmptyTextElementsIgnored (bool shouldBeIgnored) throw(); | ||||
| /** A handy static method that parses a file. | |||||
| This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it. | |||||
| @returns a new XmlElement which the caller will need to delete, or null if there was an error. | |||||
| */ | |||||
| static XmlElement* parse (const File& file); | |||||
| /** A handy static method that parses some XML data. | |||||
| This is a shortcut for creating an XmlDocument object and calling getDocumentElement() on it. | |||||
| @returns a new XmlElement which the caller will need to delete, or null if there was an error. | |||||
| */ | |||||
| static XmlElement* parse (const String& xmlData); | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| @@ -17756,7 +17779,6 @@ private: | |||||
| const juce_wchar* input; | const juce_wchar* input; | ||||
| bool outOfData, errorOccurred; | bool outOfData, errorOccurred; | ||||
| bool identifierLookupTable [128]; | |||||
| String lastError, dtdText; | String lastError, dtdText; | ||||
| StringArray tokenisedDTD; | StringArray tokenisedDTD; | ||||
| bool needToLoadDTD, ignoreEmptyTextElements; | bool needToLoadDTD, ignoreEmptyTextElements; | ||||
| @@ -17771,8 +17793,6 @@ private: | |||||
| int findNextTokenLength() throw(); | int findNextTokenLength() throw(); | ||||
| void readQuotedString (String& result); | void readQuotedString (String& result); | ||||
| void readEntity (String& result); | void readEntity (String& result); | ||||
| static bool isXmlIdentifierCharSlow (juce_wchar c) throw(); | |||||
| bool isXmlIdentifierChar (juce_wchar c) const throw(); | |||||
| const String getFileContents (const String& filename) const; | const String getFileContents (const String& filename) const; | ||||
| const String expandEntity (const String& entity); | const String expandEntity (const String& entity); | ||||
| @@ -22624,9 +22644,12 @@ public: | |||||
| protected: | protected: | ||||
| String name; | String name; | ||||
| bool isFallbackFont; | |||||
| explicit Typeface (const String& name) throw(); | explicit Typeface (const String& name) throw(); | ||||
| static const Ptr getFallbackTypeface(); | |||||
| private: | private: | ||||
| Typeface (const Typeface&); | Typeface (const Typeface&); | ||||
| Typeface& operator= (const Typeface&); | Typeface& operator= (const Typeface&); | ||||
| @@ -22873,7 +22896,7 @@ public: | |||||
| static const String getDefaultMonospacedFontName(); | static const String getDefaultMonospacedFontName(); | ||||
| /** Returns the typeface names of the default fonts on the current platform. */ | /** Returns the typeface names of the default fonts on the current platform. */ | ||||
| static void getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed); | |||||
| static void getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& defaultFallback); | |||||
| /** Returns the total height of this font. | /** Returns the total height of this font. | ||||
| @@ -25951,6 +25974,9 @@ public: | |||||
| */ | */ | ||||
| void attachCallback (Component* component, Callback* callback); | void attachCallback (Component* component, Callback* callback); | ||||
| /** Brings any modal components to the front. */ | |||||
| void bringModalComponentsToFront(); | |||||
| /** Runs the event loop until the currently topmost modal component is dismissed, and | /** Runs the event loop until the currently topmost modal component is dismissed, and | ||||
| returns the exit code for that component. | returns the exit code for that component. | ||||
| */ | */ | ||||
| @@ -26272,20 +26298,19 @@ public: | |||||
| const Rectangle<int> getScreenBounds() const; | const Rectangle<int> getScreenBounds() const; | ||||
| /** Converts a position relative to this component's top-left into a screen co-ordinate. | /** Converts a position relative to this component's top-left into a screen co-ordinate. | ||||
| @see globalPositionToRelative, relativePositionToOtherComponent | @see globalPositionToRelative, relativePositionToOtherComponent | ||||
| */ | */ | ||||
| const Point<int> relativePositionToGlobal (const Point<int>& relativePosition) const; | const Point<int> relativePositionToGlobal (const Point<int>& relativePosition) const; | ||||
| /** Converts a screen co-ordinate into a position relative to this component's top-left. | /** Converts a screen co-ordinate into a position relative to this component's top-left. | ||||
| @see relativePositionToGlobal, relativePositionToOtherComponent | @see relativePositionToGlobal, relativePositionToOtherComponent | ||||
| */ | */ | ||||
| const Point<int> globalPositionToRelative (const Point<int>& screenPosition) const; | const Point<int> globalPositionToRelative (const Point<int>& screenPosition) const; | ||||
| /** Converts a position relative to this component's top-left into a position | /** Converts a position relative to this component's top-left into a position | ||||
| relative to another component's top-left. | relative to another component's top-left. | ||||
| If the targetComponent parameter is null, the coordinate is converted to global screen | |||||
| coordinates. | |||||
| @see relativePositionToGlobal, globalPositionToRelative | @see relativePositionToGlobal, globalPositionToRelative | ||||
| */ | */ | ||||
| const Point<int> relativePositionToOtherComponent (const Component* targetComponent, | const Point<int> relativePositionToOtherComponent (const Component* targetComponent, | ||||
| @@ -27133,7 +27158,8 @@ public: | |||||
| if you want to force the system to check that the cursor being displayed is | if you want to force the system to check that the cursor being displayed is | ||||
| up-to-date (even if the mouse is just sitting there), call this method. | up-to-date (even if the mouse is just sitting there), call this method. | ||||
| This isn't needed if you're only using setMouseCursor(). | |||||
| (If you're changing the cursor using setMouseCursor(), you don't need to bother | |||||
| calling this). | |||||
| */ | */ | ||||
| void updateMouseCursor() const; | void updateMouseCursor() const; | ||||
| @@ -27968,8 +27994,6 @@ private: | |||||
| void grabFocusInternal (const FocusChangeType cause, bool canTryParent = true); | void grabFocusInternal (const FocusChangeType cause, bool canTryParent = true); | ||||
| static void giveAwayFocus(); | static void giveAwayFocus(); | ||||
| void sendEnablementChangeMessage(); | void sendEnablementChangeMessage(); | ||||
| static void* runModalLoopCallback (void*); | |||||
| static void bringModalComponentToFront(); | |||||
| void subtractObscuredRegions (RectangleList& result, const Point<int>& delta, | void subtractObscuredRegions (RectangleList& result, const Point<int>& delta, | ||||
| const Rectangle<int>& clipRect, const Component* const compToAvoid) const; | const Rectangle<int>& clipRect, const Component* const compToAvoid) const; | ||||
| void clipObscuredRegions (Graphics& g, const Rectangle<int>& clipRect, int deltaX, int deltaY) const; | void clipObscuredRegions (Graphics& g, const Rectangle<int>& clipRect, int deltaX, int deltaY) const; | ||||
| @@ -53251,7 +53275,7 @@ protected: | |||||
| private: | private: | ||||
| Array <Component::SafePointer<Component> > contentComponents; | |||||
| OwnedArray <Component::SafePointer<Component> > contentComponents; | |||||
| Component::SafePointer<Component> panelComponent; | Component::SafePointer<Component> panelComponent; | ||||
| int tabDepth; | int tabDepth; | ||||
| int outlineThickness, edgeIndent; | int outlineThickness, edgeIndent; | ||||
| @@ -59264,8 +59288,6 @@ public: | |||||
| */ | */ | ||||
| static bool isValidPeer (const ComponentPeer* peer) throw(); | static bool isValidPeer (const ComponentPeer* peer) throw(); | ||||
| static void bringModalComponentToFront(); | |||||
| virtual const StringArray getAvailableRenderingEngines(); | virtual const StringArray getAvailableRenderingEngines(); | ||||
| virtual int getCurrentRenderingEngine() throw(); | virtual int getCurrentRenderingEngine() throw(); | ||||
| virtual void setCurrentRenderingEngine (int index); | virtual void setCurrentRenderingEngine (int index); | ||||
| @@ -107,41 +107,41 @@ private: | |||||
| inline uint16 ByteOrder::swap (uint16 n) | inline uint16 ByteOrder::swap (uint16 n) | ||||
| { | { | ||||
| #if JUCE_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic! | |||||
| #if JUCE_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic! | |||||
| return static_cast <uint16> (_byteswap_ushort (n)); | return static_cast <uint16> (_byteswap_ushort (n)); | ||||
| #else | |||||
| #else | |||||
| return static_cast <uint16> ((n << 8) | (n >> 8)); | return static_cast <uint16> ((n << 8) | (n >> 8)); | ||||
| #endif | |||||
| #endif | |||||
| } | } | ||||
| inline uint32 ByteOrder::swap (uint32 n) | inline uint32 ByteOrder::swap (uint32 n) | ||||
| { | { | ||||
| #if JUCE_MAC || JUCE_IOS | |||||
| #if JUCE_MAC || JUCE_IOS | |||||
| return OSSwapInt32 (n); | return OSSwapInt32 (n); | ||||
| #elif JUCE_GCC | |||||
| #elif JUCE_GCC | |||||
| asm("bswap %%eax" : "=a"(n) : "a"(n)); | asm("bswap %%eax" : "=a"(n) : "a"(n)); | ||||
| return n; | return n; | ||||
| #elif JUCE_USE_INTRINSICS | |||||
| #elif JUCE_USE_INTRINSICS | |||||
| return _byteswap_ulong (n); | return _byteswap_ulong (n); | ||||
| #else | |||||
| #else | |||||
| __asm { | __asm { | ||||
| mov eax, n | mov eax, n | ||||
| bswap eax | bswap eax | ||||
| mov n, eax | mov n, eax | ||||
| } | } | ||||
| return n; | return n; | ||||
| #endif | |||||
| #endif | |||||
| } | } | ||||
| inline uint64 ByteOrder::swap (uint64 value) | inline uint64 ByteOrder::swap (uint64 value) | ||||
| { | { | ||||
| #if JUCE_MAC || JUCE_IOS | |||||
| #if JUCE_MAC || JUCE_IOS | |||||
| return OSSwapInt64 (value); | return OSSwapInt64 (value); | ||||
| #elif JUCE_USE_INTRINSICS | |||||
| #elif JUCE_USE_INTRINSICS | |||||
| return _byteswap_uint64 (value); | return _byteswap_uint64 (value); | ||||
| #else | |||||
| #else | |||||
| return (((int64) swap ((uint32) value)) << 32) | swap ((uint32) (value >> 32)); | return (((int64) swap ((uint32) value)) << 32) | swap ((uint32) (value >> 32)); | ||||
| #endif | |||||
| #endif | |||||
| } | } | ||||
| #if JUCE_LITTLE_ENDIAN | #if JUCE_LITTLE_ENDIAN | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 86 | |||||
| #define JUCE_BUILDNUMBER 87 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -777,9 +777,7 @@ int Component::getScreenY() const | |||||
| const Point<int> Component::getScreenPosition() const | const Point<int> Component::getScreenPosition() const | ||||
| { | { | ||||
| return (parentComponent_ != 0) ? parentComponent_->getScreenPosition() + getPosition() | |||||
| : (flags.hasHeavyweightPeerFlag ? getPeer()->getScreenPosition() | |||||
| : getPosition()); | |||||
| return relativePositionToGlobal (Point<int>()); | |||||
| } | } | ||||
| const Rectangle<int> Component::getScreenBounds() const | const Rectangle<int> Component::getScreenBounds() const | ||||
| @@ -789,20 +787,7 @@ const Rectangle<int> Component::getScreenBounds() const | |||||
| const Point<int> Component::relativePositionToGlobal (const Point<int>& relativePosition) const | const Point<int> Component::relativePositionToGlobal (const Point<int>& relativePosition) const | ||||
| { | { | ||||
| const Component* c = this; | |||||
| Point<int> p (relativePosition); | |||||
| do | |||||
| { | |||||
| if (c->flags.hasHeavyweightPeerFlag) | |||||
| return c->getPeer()->relativePositionToGlobal (p); | |||||
| p += c->getPosition(); | |||||
| c = c->parentComponent_; | |||||
| } | |||||
| while (c != 0); | |||||
| return p; | |||||
| return relativePositionToOtherComponent (0, relativePosition); | |||||
| } | } | ||||
| const Point<int> Component::globalPositionToRelative (const Point<int>& screenPosition) const | const Point<int> Component::globalPositionToRelative (const Point<int>& screenPosition) const | ||||
| @@ -823,29 +808,26 @@ const Point<int> Component::globalPositionToRelative (const Point<int>& screenPo | |||||
| const Point<int> Component::relativePositionToOtherComponent (const Component* const targetComponent, const Point<int>& positionRelativeToThis) const | const Point<int> Component::relativePositionToOtherComponent (const Component* const targetComponent, const Point<int>& positionRelativeToThis) const | ||||
| { | { | ||||
| Point<int> p (positionRelativeToThis); | Point<int> p (positionRelativeToThis); | ||||
| const Component* c = this; | |||||
| if (targetComponent != 0) | |||||
| do | |||||
| { | { | ||||
| const Component* c = this; | |||||
| if (c == targetComponent) | |||||
| return p; | |||||
| do | |||||
| if (c->flags.hasHeavyweightPeerFlag) | |||||
| { | { | ||||
| if (c == targetComponent) | |||||
| return p; | |||||
| if (c->flags.hasHeavyweightPeerFlag) | |||||
| { | |||||
| p = c->getPeer()->relativePositionToGlobal (p); | |||||
| break; | |||||
| } | |||||
| p += c->getPosition(); | |||||
| c = c->parentComponent_; | |||||
| p = c->getPeer()->relativePositionToGlobal (p); | |||||
| break; | |||||
| } | } | ||||
| while (c != 0); | |||||
| p = targetComponent->globalPositionToRelative (p); | |||||
| p += c->getPosition(); | |||||
| c = c->parentComponent_; | |||||
| } | } | ||||
| while (c != 0); | |||||
| if (targetComponent != 0) | |||||
| p = targetComponent->globalPositionToRelative (p); | |||||
| return p; | return p; | ||||
| } | } | ||||
| @@ -1365,9 +1347,12 @@ void Component::internalHierarchyChanged() | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void* Component::runModalLoopCallback (void* userData) | |||||
| namespace ComponentHelpers | |||||
| { | { | ||||
| return (void*) (pointer_sized_int) static_cast <Component*> (userData)->runModalLoop(); | |||||
| void* runModalLoopCallback (void* userData) | |||||
| { | |||||
| return (void*) (pointer_sized_int) static_cast <Component*> (userData)->runModalLoop(); | |||||
| } | |||||
| } | } | ||||
| int Component::runModalLoop() | int Component::runModalLoop() | ||||
| @@ -1376,7 +1361,7 @@ int Component::runModalLoop() | |||||
| { | { | ||||
| // use a callback so this can be called from non-gui threads | // use a callback so this can be called from non-gui threads | ||||
| return (int) (pointer_sized_int) MessageManager::getInstance() | return (int) (pointer_sized_int) MessageManager::getInstance() | ||||
| ->callFunctionOnMessageThread (&runModalLoopCallback, this); | |||||
| ->callFunctionOnMessageThread (&ComponentHelpers::runModalLoopCallback, this); | |||||
| } | } | ||||
| if (! isCurrentlyModal()) | if (! isCurrentlyModal()) | ||||
| @@ -1415,7 +1400,7 @@ void Component::exitModalState (const int returnValue) | |||||
| ModalComponentManager::getInstance()->endModal (this, returnValue); | ModalComponentManager::getInstance()->endModal (this, returnValue); | ||||
| flags.currentlyModalFlag = false; | flags.currentlyModalFlag = false; | ||||
| bringModalComponentToFront(); | |||||
| ModalComponentManager::getInstance()->bringModalComponentsToFront(); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -1467,34 +1452,6 @@ Component* JUCE_CALLTYPE Component::getCurrentlyModalComponent (int index) throw | |||||
| return ModalComponentManager::getInstance()->getModalComponent (index); | return ModalComponentManager::getInstance()->getModalComponent (index); | ||||
| } | } | ||||
| void Component::bringModalComponentToFront() | |||||
| { | |||||
| ComponentPeer* lastOne = 0; | |||||
| for (int i = 0; i < getNumCurrentlyModalComponents(); ++i) | |||||
| { | |||||
| Component* const c = getCurrentlyModalComponent (i); | |||||
| if (c == 0) | |||||
| break; | |||||
| ComponentPeer* peer = c->getPeer(); | |||||
| if (peer != 0 && peer != lastOne) | |||||
| { | |||||
| if (lastOne == 0) | |||||
| { | |||||
| peer->toFront (true); | |||||
| peer->grabFocus(); | |||||
| } | |||||
| else | |||||
| peer->toBehind (lastOne); | |||||
| lastOne = peer; | |||||
| } | |||||
| } | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void Component::setBroughtToFrontOnMouseClick (const bool shouldBeBroughtToFront) throw() | void Component::setBroughtToFrontOnMouseClick (const bool shouldBeBroughtToFront) throw() | ||||
| { | { | ||||
| @@ -2084,7 +2041,7 @@ void Component::removeComponentListener (ComponentListener* const listenerToRemo | |||||
| //============================================================================== | //============================================================================== | ||||
| void Component::inputAttemptWhenModal() | void Component::inputAttemptWhenModal() | ||||
| { | { | ||||
| bringModalComponentToFront(); | |||||
| ModalComponentManager::getInstance()->bringModalComponentsToFront(); | |||||
| getLookAndFeel().playAlertSound(); | getLookAndFeel().playAlertSound(); | ||||
| } | } | ||||
| @@ -2538,7 +2495,7 @@ void Component::internalBroughtToFront() | |||||
| Component* const cm = getCurrentlyModalComponent(); | Component* const cm = getCurrentlyModalComponent(); | ||||
| if (cm != 0 && cm->getTopLevelComponent() != getTopLevelComponent()) | if (cm != 0 && cm->getTopLevelComponent() != getTopLevelComponent()) | ||||
| bringModalComponentToFront(); | |||||
| ModalComponentManager::getInstance()->bringModalComponentsToFront(); | |||||
| } | } | ||||
| void Component::focusGained (FocusChangeType) | void Component::focusGained (FocusChangeType) | ||||
| @@ -333,20 +333,19 @@ public: | |||||
| const Rectangle<int> getScreenBounds() const; | const Rectangle<int> getScreenBounds() const; | ||||
| /** Converts a position relative to this component's top-left into a screen co-ordinate. | /** Converts a position relative to this component's top-left into a screen co-ordinate. | ||||
| @see globalPositionToRelative, relativePositionToOtherComponent | @see globalPositionToRelative, relativePositionToOtherComponent | ||||
| */ | */ | ||||
| const Point<int> relativePositionToGlobal (const Point<int>& relativePosition) const; | const Point<int> relativePositionToGlobal (const Point<int>& relativePosition) const; | ||||
| /** Converts a screen co-ordinate into a position relative to this component's top-left. | /** Converts a screen co-ordinate into a position relative to this component's top-left. | ||||
| @see relativePositionToGlobal, relativePositionToOtherComponent | @see relativePositionToGlobal, relativePositionToOtherComponent | ||||
| */ | */ | ||||
| const Point<int> globalPositionToRelative (const Point<int>& screenPosition) const; | const Point<int> globalPositionToRelative (const Point<int>& screenPosition) const; | ||||
| /** Converts a position relative to this component's top-left into a position | /** Converts a position relative to this component's top-left into a position | ||||
| relative to another component's top-left. | relative to another component's top-left. | ||||
| If the targetComponent parameter is null, the coordinate is converted to global screen | |||||
| coordinates. | |||||
| @see relativePositionToGlobal, globalPositionToRelative | @see relativePositionToGlobal, globalPositionToRelative | ||||
| */ | */ | ||||
| const Point<int> relativePositionToOtherComponent (const Component* targetComponent, | const Point<int> relativePositionToOtherComponent (const Component* targetComponent, | ||||
| @@ -1213,7 +1212,8 @@ public: | |||||
| if you want to force the system to check that the cursor being displayed is | if you want to force the system to check that the cursor being displayed is | ||||
| up-to-date (even if the mouse is just sitting there), call this method. | up-to-date (even if the mouse is just sitting there), call this method. | ||||
| This isn't needed if you're only using setMouseCursor(). | |||||
| (If you're changing the cursor using setMouseCursor(), you don't need to bother | |||||
| calling this). | |||||
| */ | */ | ||||
| void updateMouseCursor() const; | void updateMouseCursor() const; | ||||
| @@ -2068,8 +2068,6 @@ private: | |||||
| void grabFocusInternal (const FocusChangeType cause, bool canTryParent = true); | void grabFocusInternal (const FocusChangeType cause, bool canTryParent = true); | ||||
| static void giveAwayFocus(); | static void giveAwayFocus(); | ||||
| void sendEnablementChangeMessage(); | void sendEnablementChangeMessage(); | ||||
| static void* runModalLoopCallback (void*); | |||||
| static void bringModalComponentToFront(); | |||||
| void subtractObscuredRegions (RectangleList& result, const Point<int>& delta, | void subtractObscuredRegions (RectangleList& result, const Point<int>& delta, | ||||
| const Rectangle<int>& clipRect, const Component* const compToAvoid) const; | const Rectangle<int>& clipRect, const Component* const compToAvoid) const; | ||||
| void clipObscuredRegions (Graphics& g, const Rectangle<int>& clipRect, int deltaX, int deltaY) const; | void clipObscuredRegions (Graphics& g, const Rectangle<int>& clipRect, int deltaX, int deltaY) const; | ||||
| @@ -29,6 +29,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_Component.h" | #include "juce_Component.h" | ||||
| #include "juce_ModalComponentManager.h" | #include "juce_ModalComponentManager.h" | ||||
| #include "windows/juce_ComponentPeer.h" | |||||
| #include "../../events/juce_MessageManager.h" | #include "../../events/juce_MessageManager.h" | ||||
| #include "../../application/juce_Application.h" | #include "../../application/juce_Application.h" | ||||
| @@ -211,6 +212,34 @@ void ModalComponentManager::handleAsyncUpdate() | |||||
| } | } | ||||
| } | } | ||||
| void ModalComponentManager::bringModalComponentsToFront() | |||||
| { | |||||
| ComponentPeer* lastOne = 0; | |||||
| for (int i = 0; i < getNumModalComponents(); ++i) | |||||
| { | |||||
| Component* const c = getModalComponent (i); | |||||
| if (c == 0) | |||||
| break; | |||||
| ComponentPeer* peer = c->getPeer(); | |||||
| if (peer != 0 && peer != lastOne) | |||||
| { | |||||
| if (lastOne == 0) | |||||
| { | |||||
| peer->toFront (true); | |||||
| peer->grabFocus(); | |||||
| } | |||||
| else | |||||
| peer->toBehind (lastOne); | |||||
| lastOne = peer; | |||||
| } | |||||
| } | |||||
| } | |||||
| class ModalComponentManager::ReturnValueRetriever : public ModalComponentManager::Callback | class ModalComponentManager::ReturnValueRetriever : public ModalComponentManager::Callback | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -106,6 +106,9 @@ public: | |||||
| */ | */ | ||||
| void attachCallback (Component* component, Callback* callback); | void attachCallback (Component* component, Callback* callback); | ||||
| /** Brings any modal components to the front. */ | |||||
| void bringModalComponentsToFront(); | |||||
| /** Runs the event loop until the currently topmost modal component is dismissed, and | /** Runs the event loop until the currently topmost modal component is dismissed, and | ||||
| returns the exit code for that component. | returns the exit code for that component. | ||||
| */ | */ | ||||
| @@ -132,7 +132,7 @@ void TabbedComponent::clearTabs() | |||||
| for (int i = contentComponents.size(); --i >= 0;) | for (int i = contentComponents.size(); --i >= 0;) | ||||
| { | { | ||||
| Component::SafePointer<Component>& c = contentComponents.getReference (i); | |||||
| Component::SafePointer<Component>& c = *contentComponents.getUnchecked (i); | |||||
| if (c != 0 && (bool) c->getProperties() [deleteComponentId]) | if (c != 0 && (bool) c->getProperties() [deleteComponentId]) | ||||
| c.deleteAndZero(); | c.deleteAndZero(); | ||||
| @@ -147,7 +147,7 @@ void TabbedComponent::addTab (const String& tabName, | |||||
| const bool deleteComponentWhenNotNeeded, | const bool deleteComponentWhenNotNeeded, | ||||
| const int insertIndex) | const int insertIndex) | ||||
| { | { | ||||
| contentComponents.insert (insertIndex, contentComponent); | |||||
| contentComponents.insert (insertIndex, new Component::SafePointer<Component> (contentComponent)); | |||||
| if (contentComponent != 0) | if (contentComponent != 0) | ||||
| contentComponent->getProperties().set (deleteComponentId, deleteComponentWhenNotNeeded); | contentComponent->getProperties().set (deleteComponentId, deleteComponentWhenNotNeeded); | ||||
| @@ -162,12 +162,12 @@ void TabbedComponent::setTabName (const int tabIndex, const String& newName) | |||||
| void TabbedComponent::removeTab (const int tabIndex) | void TabbedComponent::removeTab (const int tabIndex) | ||||
| { | { | ||||
| if (tabIndex >= 0 && tabIndex < contentComponents.size()) | |||||
| { | |||||
| Component::SafePointer<Component>& c = contentComponents.getReference (tabIndex); | |||||
| Component::SafePointer<Component>* c = contentComponents [tabIndex]; | |||||
| if (c != 0 && (bool) c->getProperties() [deleteComponentId]) | |||||
| c.deleteAndZero(); | |||||
| if (c != 0) | |||||
| { | |||||
| if ((bool) ((*c)->getProperties() [deleteComponentId])) | |||||
| c->deleteAndZero(); | |||||
| contentComponents.remove (tabIndex); | contentComponents.remove (tabIndex); | ||||
| tabs->removeTab (tabIndex); | tabs->removeTab (tabIndex); | ||||
| @@ -186,7 +186,8 @@ const StringArray TabbedComponent::getTabNames() const | |||||
| Component* TabbedComponent::getTabContentComponent (const int tabIndex) const throw() | Component* TabbedComponent::getTabContentComponent (const int tabIndex) const throw() | ||||
| { | { | ||||
| return contentComponents [tabIndex]; | |||||
| Component::SafePointer<Component>* const c = contentComponents [tabIndex]; | |||||
| return c != 0 ? *c : 0; | |||||
| } | } | ||||
| const Colour TabbedComponent::getTabBackgroundColour (const int tabIndex) const throw() | const Colour TabbedComponent::getTabBackgroundColour (const int tabIndex) const throw() | ||||
| @@ -297,15 +298,15 @@ void TabbedComponent::resized() | |||||
| const Rectangle<int> bounds (indents.subtractedFrom (getLocalBounds())); | const Rectangle<int> bounds (indents.subtractedFrom (getLocalBounds())); | ||||
| for (int i = contentComponents.size(); --i >= 0;) | for (int i = contentComponents.size(); --i >= 0;) | ||||
| if (contentComponents.getReference (i) != 0) | |||||
| contentComponents.getReference (i)->setBounds (bounds); | |||||
| if (*contentComponents.getUnchecked (i) != 0) | |||||
| (*contentComponents.getUnchecked (i))->setBounds (bounds); | |||||
| } | } | ||||
| void TabbedComponent::lookAndFeelChanged() | void TabbedComponent::lookAndFeelChanged() | ||||
| { | { | ||||
| for (int i = contentComponents.size(); --i >= 0;) | for (int i = contentComponents.size(); --i >= 0;) | ||||
| if (contentComponents.getReference (i) != 0) | |||||
| contentComponents.getReference (i)->lookAndFeelChanged(); | |||||
| if (*contentComponents.getUnchecked (i) != 0) | |||||
| (*contentComponents.getUnchecked (i))->lookAndFeelChanged(); | |||||
| } | } | ||||
| void TabbedComponent::changeCallback (const int newCurrentTabIndex, | void TabbedComponent::changeCallback (const int newCurrentTabIndex, | ||||
| @@ -320,7 +321,7 @@ void TabbedComponent::changeCallback (const int newCurrentTabIndex, | |||||
| if (getCurrentTabIndex() >= 0) | if (getCurrentTabIndex() >= 0) | ||||
| { | { | ||||
| panelComponent = contentComponents [getCurrentTabIndex()]; | |||||
| panelComponent = getTabContentComponent (getCurrentTabIndex()); | |||||
| if (panelComponent != 0) | if (panelComponent != 0) | ||||
| { | { | ||||
| @@ -228,7 +228,7 @@ protected: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| Array <Component::SafePointer<Component> > contentComponents; | |||||
| OwnedArray <Component::SafePointer<Component> > contentComponents; | |||||
| Component::SafePointer<Component> panelComponent; | Component::SafePointer<Component> panelComponent; | ||||
| int tabDepth; | int tabDepth; | ||||
| int outlineThickness, edgeIndent; | int outlineThickness, edgeIndent; | ||||
| @@ -296,14 +296,15 @@ LookAndFeel::LookAndFeel() | |||||
| for (int i = 0; i < numElementsInArray (standardColours); i += 2) | for (int i = 0; i < numElementsInArray (standardColours); i += 2) | ||||
| setColour (standardColours [i], Colour (standardColours [i + 1])); | setColour (standardColours [i], Colour (standardColours [i + 1])); | ||||
| static String defaultSansName, defaultSerifName, defaultFixedName; | |||||
| static String defaultSansName, defaultSerifName, defaultFixedName, defaultFallback; | |||||
| if (defaultSansName.isEmpty()) | if (defaultSansName.isEmpty()) | ||||
| Font::getPlatformDefaultFontNames (defaultSansName, defaultSerifName, defaultFixedName); | |||||
| Font::getPlatformDefaultFontNames (defaultSansName, defaultSerifName, defaultFixedName, defaultFallback); | |||||
| defaultSans = defaultSansName; | defaultSans = defaultSansName; | ||||
| defaultSerif = defaultSerifName; | defaultSerif = defaultSerifName; | ||||
| defaultFixed = defaultFixedName; | defaultFixed = defaultFixedName; | ||||
| Font::setFallbackFontName (defaultFallback); | |||||
| } | } | ||||
| LookAndFeel::~LookAndFeel() | LookAndFeel::~LookAndFeel() | ||||
| @@ -246,10 +246,10 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| namespace PopupMenuSettings | namespace PopupMenuSettings | ||||
| { | { | ||||
| static const int scrollZone = 24; | |||||
| static const int borderSize = 2; | |||||
| static const int timerInterval = 50; | |||||
| static const int dismissCommandId = 0x6287345f; | |||||
| const int scrollZone = 24; | |||||
| const int borderSize = 2; | |||||
| const int timerInterval = 50; | |||||
| const int dismissCommandId = 0x6287345f; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -390,9 +390,8 @@ public: | |||||
| bool isScrollZoneActive (bool bottomOne) const | bool isScrollZoneActive (bool bottomOne) const | ||||
| { | { | ||||
| return isScrolling() | return isScrolling() | ||||
| && (bottomOne | |||||
| ? childYOffset < contentHeight - windowPos.getHeight() | |||||
| : childYOffset > 0); | |||||
| && (bottomOne ? childYOffset < contentHeight - windowPos.getHeight() | |||||
| : childYOffset > 0); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -453,25 +452,10 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void mouseMove (const MouseEvent&) | |||||
| { | |||||
| timerCallback(); | |||||
| } | |||||
| void mouseDown (const MouseEvent&) | |||||
| { | |||||
| timerCallback(); | |||||
| } | |||||
| void mouseDrag (const MouseEvent&) | |||||
| { | |||||
| timerCallback(); | |||||
| } | |||||
| void mouseUp (const MouseEvent&) | |||||
| { | |||||
| timerCallback(); | |||||
| } | |||||
| void mouseMove (const MouseEvent&) { timerCallback(); } | |||||
| void mouseDown (const MouseEvent&) { timerCallback(); } | |||||
| void mouseDrag (const MouseEvent&) { timerCallback(); } | |||||
| void mouseUp (const MouseEvent&) { timerCallback(); } | |||||
| void mouseWheelMove (const MouseEvent&, float /*amountX*/, float amountY) | void mouseWheelMove (const MouseEvent&, float /*amountX*/, float amountY) | ||||
| { | { | ||||
| @@ -1151,12 +1135,9 @@ private: | |||||
| } | } | ||||
| Path areaTowardsSubMenu; | Path areaTowardsSubMenu; | ||||
| areaTowardsSubMenu.addTriangle ((float) lastMouse.getX(), | |||||
| (float) lastMouse.getY(), | |||||
| subX, | |||||
| (float) activeSubMenu->getScreenY(), | |||||
| subX, | |||||
| (float) (activeSubMenu->getScreenY() + activeSubMenu->getHeight())); | |||||
| areaTowardsSubMenu.addTriangle ((float) lastMouse.getX(), (float) lastMouse.getY(), | |||||
| subX, (float) activeSubMenu->getScreenY(), | |||||
| subX, (float) (activeSubMenu->getScreenY() + activeSubMenu->getHeight())); | |||||
| isMovingTowardsMenu = areaTowardsSubMenu.contains ((float) globalMousePos.getX(), (float) globalMousePos.getY()); | isMovingTowardsMenu = areaTowardsSubMenu.contains ((float) globalMousePos.getX(), (float) globalMousePos.getY()); | ||||
| } | } | ||||
| @@ -1288,11 +1269,8 @@ void PopupMenu::addSeparatorIfPending() | |||||
| } | } | ||||
| } | } | ||||
| void PopupMenu::addItem (const int itemResultId, | |||||
| const String& itemText, | |||||
| const bool isActive, | |||||
| const bool isTicked, | |||||
| const Image& iconToUse) | |||||
| void PopupMenu::addItem (const int itemResultId, const String& itemText, | |||||
| const bool isActive, const bool isTicked, const Image& iconToUse) | |||||
| { | { | ||||
| jassert (itemResultId != 0); // 0 is used as a return value to indicate that the user | jassert (itemResultId != 0); // 0 is used as a return value to indicate that the user | ||||
| // didn't pick anything, so you shouldn't use it as the id | // didn't pick anything, so you shouldn't use it as the id | ||||
| @@ -1366,12 +1344,10 @@ void PopupMenu::addCustomItem (const int itemResultId, | |||||
| class NormalComponentWrapper : public PopupMenuCustomComponent | class NormalComponentWrapper : public PopupMenuCustomComponent | ||||
| { | { | ||||
| public: | public: | ||||
| NormalComponentWrapper (Component* const comp, | |||||
| const int w, const int h, | |||||
| NormalComponentWrapper (Component* const comp, const int w, const int h, | |||||
| const bool triggerMenuItemAutomaticallyWhenClicked) | const bool triggerMenuItemAutomaticallyWhenClicked) | ||||
| : PopupMenuCustomComponent (triggerMenuItemAutomaticallyWhenClicked), | : PopupMenuCustomComponent (triggerMenuItemAutomaticallyWhenClicked), | ||||
| width (w), | |||||
| height (h) | |||||
| width (w), height (h) | |||||
| { | { | ||||
| addAndMakeVisible (comp); | addAndMakeVisible (comp); | ||||
| } | } | ||||
| @@ -1405,8 +1381,7 @@ void PopupMenu::addCustomItem (const int itemResultId, | |||||
| const bool triggerMenuItemAutomaticallyWhenClicked) | const bool triggerMenuItemAutomaticallyWhenClicked) | ||||
| { | { | ||||
| addCustomItem (itemResultId, | addCustomItem (itemResultId, | ||||
| new NormalComponentWrapper (customComponent, | |||||
| idealWidth, idealHeight, | |||||
| new NormalComponentWrapper (customComponent, idealWidth, idealHeight, | |||||
| triggerMenuItemAutomaticallyWhenClicked)); | triggerMenuItemAutomaticallyWhenClicked)); | ||||
| } | } | ||||
| @@ -1481,8 +1456,6 @@ public: | |||||
| { | { | ||||
| } | } | ||||
| ~PopupMenuCompletionCallback() {} | |||||
| void modalStateFinished (int result) | void modalStateFinished (int result) | ||||
| { | { | ||||
| if (managerOfChosenCommand != 0 && result != 0) | if (managerOfChosenCommand != 0 && result != 0) | ||||
| @@ -1558,8 +1531,7 @@ int PopupMenu::showMenu (const Rectangle<int>& target, | |||||
| } | } | ||||
| int PopupMenu::show (const int itemIdThatMustBeVisible, | int PopupMenu::show (const int itemIdThatMustBeVisible, | ||||
| const int minimumWidth, | |||||
| const int maximumNumColumns, | |||||
| const int minimumWidth, const int maximumNumColumns, | |||||
| const int standardItemHeight, | const int standardItemHeight, | ||||
| ModalComponentManager::Callback* callback) | ModalComponentManager::Callback* callback) | ||||
| { | { | ||||
| @@ -1567,31 +1539,24 @@ int PopupMenu::show (const int itemIdThatMustBeVisible, | |||||
| return showAt (mousePos.getX(), mousePos.getY(), | return showAt (mousePos.getX(), mousePos.getY(), | ||||
| itemIdThatMustBeVisible, | itemIdThatMustBeVisible, | ||||
| minimumWidth, | |||||
| maximumNumColumns, | |||||
| standardItemHeight, | |||||
| callback); | |||||
| minimumWidth, maximumNumColumns, | |||||
| standardItemHeight, callback); | |||||
| } | } | ||||
| int PopupMenu::showAt (const int screenX, | |||||
| const int screenY, | |||||
| int PopupMenu::showAt (const int screenX, const int screenY, | |||||
| const int itemIdThatMustBeVisible, | const int itemIdThatMustBeVisible, | ||||
| const int minimumWidth, | |||||
| const int maximumNumColumns, | |||||
| const int minimumWidth, const int maximumNumColumns, | |||||
| const int standardItemHeight, | const int standardItemHeight, | ||||
| ModalComponentManager::Callback* callback) | ModalComponentManager::Callback* callback) | ||||
| { | { | ||||
| return showMenu (Rectangle<int> (screenX, screenY, 1, 1), | return showMenu (Rectangle<int> (screenX, screenY, 1, 1), | ||||
| itemIdThatMustBeVisible, | |||||
| minimumWidth, maximumNumColumns, | |||||
| standardItemHeight, | |||||
| false, 0, callback); | |||||
| itemIdThatMustBeVisible, minimumWidth, maximumNumColumns, | |||||
| standardItemHeight, false, 0, callback); | |||||
| } | } | ||||
| int PopupMenu::showAt (Component* componentToAttachTo, | int PopupMenu::showAt (Component* componentToAttachTo, | ||||
| const int itemIdThatMustBeVisible, | const int itemIdThatMustBeVisible, | ||||
| const int minimumWidth, | |||||
| const int maximumNumColumns, | |||||
| const int minimumWidth, const int maximumNumColumns, | |||||
| const int standardItemHeight, | const int standardItemHeight, | ||||
| ModalComponentManager::Callback* callback) | ModalComponentManager::Callback* callback) | ||||
| { | { | ||||
| @@ -1607,10 +1572,8 @@ int PopupMenu::showAt (Component* componentToAttachTo, | |||||
| else | else | ||||
| { | { | ||||
| return show (itemIdThatMustBeVisible, | return show (itemIdThatMustBeVisible, | ||||
| minimumWidth, | |||||
| maximumNumColumns, | |||||
| standardItemHeight, | |||||
| callback); | |||||
| minimumWidth, maximumNumColumns, | |||||
| standardItemHeight, callback); | |||||
| } | } | ||||
| } | } | ||||
| @@ -353,7 +353,7 @@ void ComponentPeer::handleFocusGain() | |||||
| if (! component->isCurrentlyBlockedByAnotherModalComponent()) | if (! component->isCurrentlyBlockedByAnotherModalComponent()) | ||||
| component->grabKeyboardFocus(); | component->grabKeyboardFocus(); | ||||
| else | else | ||||
| Component::bringModalComponentToFront(); | |||||
| ModalComponentManager::getInstance()->bringModalComponentsToFront(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -507,16 +507,9 @@ void ComponentPeer::handleFileDragDrop (const StringArray& files, const Point<in | |||||
| void ComponentPeer::handleUserClosingWindow() | void ComponentPeer::handleUserClosingWindow() | ||||
| { | { | ||||
| updateCurrentModifiers(); | updateCurrentModifiers(); | ||||
| component->userTriedToCloseWindow(); | component->userTriedToCloseWindow(); | ||||
| } | } | ||||
| //============================================================================== | |||||
| void ComponentPeer::bringModalComponentToFront() | |||||
| { | |||||
| Component::bringModalComponentToFront(); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void ComponentPeer::clearMaskedRegion() | void ComponentPeer::clearMaskedRegion() | ||||
| { | { | ||||
| @@ -344,8 +344,6 @@ public: | |||||
| */ | */ | ||||
| static bool isValidPeer (const ComponentPeer* peer) throw(); | static bool isValidPeer (const ComponentPeer* peer) throw(); | ||||
| //============================================================================== | |||||
| static void bringModalComponentToFront(); | |||||
| //============================================================================== | //============================================================================== | ||||
| virtual const StringArray getAvailableRenderingEngines(); | virtual const StringArray getAvailableRenderingEngines(); | ||||
| @@ -72,10 +72,6 @@ public: | |||||
| setAlwaysOnTop (true); // for a plugin, make it always-on-top because the host windows are often top-level | setAlwaysOnTop (true); // for a plugin, make it always-on-top because the host windows are often top-level | ||||
| } | } | ||||
| ~TempDialogWindow() | |||||
| { | |||||
| } | |||||
| void closeButtonPressed() | void closeButtonPressed() | ||||
| { | { | ||||
| setVisible (false); | setVisible (false); | ||||
| @@ -84,7 +80,6 @@ public: | |||||
| private: | private: | ||||
| TempDialogWindow (const TempDialogWindow&); | TempDialogWindow (const TempDialogWindow&); | ||||
| TempDialogWindow& operator= (const TempDialogWindow&); | TempDialogWindow& operator= (const TempDialogWindow&); | ||||
| }; | }; | ||||
| int DialogWindow::showModalDialog (const String& dialogTitle, | int DialogWindow::showModalDialog (const String& dialogTitle, | ||||
| @@ -38,14 +38,13 @@ BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| namespace FontValues | namespace FontValues | ||||
| { | { | ||||
| static float limitFontHeight (const float height) throw() | |||||
| float limitFontHeight (const float height) throw() | |||||
| { | { | ||||
| return jlimit (0.1f, 10000.0f, height); | return jlimit (0.1f, 10000.0f, height); | ||||
| } | } | ||||
| static const float defaultFontHeight = 14.0f; | |||||
| static String fallbackFont; | |||||
| const float defaultFontHeight = 14.0f; | |||||
| String fallbackFont; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -166,7 +166,7 @@ public: | |||||
| static const String getDefaultMonospacedFontName(); | static const String getDefaultMonospacedFontName(); | ||||
| /** Returns the typeface names of the default fonts on the current platform. */ | /** Returns the typeface names of the default fonts on the current platform. */ | ||||
| static void getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed); | |||||
| static void getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& defaultFallback); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the total height of this font. | /** Returns the total height of this font. | ||||
| @@ -36,7 +36,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| Typeface::Typeface (const String& name_) throw() | Typeface::Typeface (const String& name_) throw() | ||||
| : name (name_) | |||||
| : name (name_), isFallbackFont (false) | |||||
| { | { | ||||
| } | } | ||||
| @@ -44,6 +44,14 @@ Typeface::~Typeface() | |||||
| { | { | ||||
| } | } | ||||
| const Typeface::Ptr Typeface::getFallbackTypeface() | |||||
| { | |||||
| const Font fallbackFont (Font::getFallbackFontName(), 10, 0); | |||||
| Typeface* t = fallbackFont.getTypeface(); | |||||
| t->isFallbackFont = true; | |||||
| return t; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| class CustomTypeface::GlyphInfo | class CustomTypeface::GlyphInfo | ||||
| { | { | ||||
| @@ -220,7 +228,9 @@ CustomTypeface::GlyphInfo* CustomTypeface::findGlyphSubstituting (const juce_wch | |||||
| Typeface* const fallbackTypeface = fallbackFont.getTypeface(); | Typeface* const fallbackTypeface = fallbackFont.getTypeface(); | ||||
| if (fallbackTypeface != 0 && fallbackTypeface != this) | if (fallbackTypeface != 0 && fallbackTypeface != this) | ||||
| { | { | ||||
| //xxx | |||||
| Path path; | |||||
| fallbackTypeface->getOutlineForGlyph (character, path); | |||||
| addGlyph (character, path, fallbackTypeface->getStringWidth (String::charToString (character))); | |||||
| } | } | ||||
| if (glyph == 0) | if (glyph == 0) | ||||
| @@ -334,6 +344,14 @@ float CustomTypeface::getStringWidth (const String& text) | |||||
| { | { | ||||
| const GlyphInfo* const glyph = findGlyphSubstituting (*t++); | const GlyphInfo* const glyph = findGlyphSubstituting (*t++); | ||||
| if (glyph == 0 && ! isFallbackFont) | |||||
| { | |||||
| const Typeface::Ptr fallbackTypeface (Typeface::getFallbackTypeface()); | |||||
| if (fallbackTypeface != 0) | |||||
| x += fallbackTypeface->getStringWidth (String::charToString (*t)); | |||||
| } | |||||
| if (glyph != 0) | if (glyph != 0) | ||||
| x += glyph->getHorizontalSpacing (*t); | x += glyph->getHorizontalSpacing (*t); | ||||
| } | } | ||||
| @@ -350,7 +368,26 @@ void CustomTypeface::getGlyphPositions (const String& text, Array <int>& resultG | |||||
| while (*t != 0) | while (*t != 0) | ||||
| { | { | ||||
| const juce_wchar c = *t++; | const juce_wchar c = *t++; | ||||
| const GlyphInfo* const glyph = findGlyphSubstituting (c); | |||||
| const GlyphInfo* const glyph = findGlyph (c, true); | |||||
| if (glyph == 0 && ! isFallbackFont) | |||||
| { | |||||
| const Typeface::Ptr fallbackTypeface (Typeface::getFallbackTypeface()); | |||||
| if (fallbackTypeface != 0) | |||||
| { | |||||
| Array <int> subGlyphs; | |||||
| Array <float> subOffsets; | |||||
| fallbackTypeface->getGlyphPositions (String::charToString (c), subGlyphs, subOffsets); | |||||
| if (subGlyphs.size() > 0) | |||||
| { | |||||
| resultGlyphs.add (subGlyphs.getFirst()); | |||||
| x += subOffsets[1]; | |||||
| xOffsets.add (x); | |||||
| } | |||||
| } | |||||
| } | |||||
| if (glyph != 0) | if (glyph != 0) | ||||
| { | { | ||||
| @@ -363,7 +400,16 @@ void CustomTypeface::getGlyphPositions (const String& text, Array <int>& resultG | |||||
| bool CustomTypeface::getOutlineForGlyph (int glyphNumber, Path& path) | bool CustomTypeface::getOutlineForGlyph (int glyphNumber, Path& path) | ||||
| { | { | ||||
| const GlyphInfo* const glyph = findGlyphSubstituting ((juce_wchar) glyphNumber); | |||||
| const GlyphInfo* const glyph = findGlyph ((juce_wchar) glyphNumber, true); | |||||
| if (glyph == 0 && ! isFallbackFont) | |||||
| { | |||||
| const Typeface::Ptr fallbackTypeface (Typeface::getFallbackTypeface()); | |||||
| if (fallbackTypeface != 0) | |||||
| fallbackTypeface->getOutlineForGlyph (glyphNumber, path); | |||||
| } | |||||
| if (glyph != 0) | if (glyph != 0) | ||||
| { | { | ||||
| path = glyph->path; | path = glyph->path; | ||||
| @@ -111,9 +111,12 @@ public: | |||||
| protected: | protected: | ||||
| String name; | String name; | ||||
| bool isFallbackFont; | |||||
| explicit Typeface (const String& name) throw(); | explicit Typeface (const String& name) throw(); | ||||
| static const Ptr getFallbackTypeface(); | |||||
| private: | private: | ||||
| Typeface (const Typeface&); | Typeface (const Typeface&); | ||||
| Typeface& operator= (const Typeface&); | Typeface& operator= (const Typeface&); | ||||
| @@ -799,7 +799,7 @@ void juce_HandleProcessFocusChange() | |||||
| { | { | ||||
| currentlyFocusedPeer->handleFocusGain(); | currentlyFocusedPeer->handleFocusGain(); | ||||
| ComponentPeer::bringModalComponentToFront(); | |||||
| ModalComponentManager::getInstance()->bringModalComponentsToFront(); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -508,7 +508,7 @@ const StringArray Font::findAllTypefaceNames() | |||||
| return names; | return names; | ||||
| } | } | ||||
| void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) | |||||
| void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& defaultFallback) | |||||
| { | { | ||||
| #if JUCE_IOS | #if JUCE_IOS | ||||
| defaultSans = "Helvetica"; | defaultSans = "Helvetica"; | ||||
| @@ -519,6 +519,8 @@ void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSeri | |||||
| defaultSerif = "Times New Roman"; | defaultSerif = "Times New Roman"; | ||||
| defaultFixed = "Monaco"; | defaultFixed = "Monaco"; | ||||
| #endif | #endif | ||||
| defaultFallback = "Arial Unicode MS"; | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -1291,7 +1291,7 @@ void juce_HandleProcessFocusChange() | |||||
| { | { | ||||
| NSViewComponentPeer::currentlyFocusedPeer->handleFocusGain(); | NSViewComponentPeer::currentlyFocusedPeer->handleFocusGain(); | ||||
| ComponentPeer::bringModalComponentToFront(); | |||||
| ModalComponentManager::getInstance()->bringModalComponentsToFront(); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -104,7 +104,7 @@ const StringArray Font::findAllTypefaceNames() | |||||
| extern bool juce_IsRunningInWine(); | extern bool juce_IsRunningInWine(); | ||||
| void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) | |||||
| void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& defaultFallback) | |||||
| { | { | ||||
| if (juce_IsRunningInWine()) | if (juce_IsRunningInWine()) | ||||
| { | { | ||||
| @@ -115,9 +115,10 @@ void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSeri | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| defaultSans = "Verdana"; | |||||
| defaultSerif = "Times"; | |||||
| defaultFixed = "Lucida Console"; | |||||
| defaultSans = "Verdana"; | |||||
| defaultSerif = "Times"; | |||||
| defaultFixed = "Lucida Console"; | |||||
| defaultFallback = "Tahoma"; // (contains plenty of unicode characters) | |||||
| } | } | ||||
| } | } | ||||
| @@ -274,6 +275,10 @@ public: | |||||
| GLYPHMETRICS gm; | GLYPHMETRICS gm; | ||||
| // if this is the fallback font, skip checking for the glyph's existence. This is because | |||||
| // with fonts like Tahoma, GetGlyphIndices can say that a glyph doesn't exist, but it still | |||||
| // gets correctly created later on. | |||||
| if (! isFallbackFont) | |||||
| { | { | ||||
| const WCHAR charToTest[] = { (WCHAR) character, 0 }; | const WCHAR charToTest[] = { (WCHAR) character, 0 }; | ||||
| WORD index = 0; | WORD index = 0; | ||||